Kubernetes技术详解-从理论到实践-(10)-WebUI管理-Dashboard
1 Dashboard界面简介
Kubernetes Dashboard是K8s官方提供的Web UI,把kubectl的常用能力做成点击式页面,可以在Web界面很方便地查看集群、管理应用、查看日志、运行容器,无需命令行也能运维K8s。
Dashboard所有数据实时调用kube-apiserver REST接口,自身并无状态。可通过ServiceAccount + RBAC实现访问范围控制。
2 Dashboard安装及配置
Dashboard安装非常简单,从官方下载一个yaml文件,使用kubectl apply安装,暴露NodePort,创建管理员Token,就可以在浏览器登录了。
2.1 从官方下载recommended.yaml文件
下载官方资源清单文件
[root@master 10-dashboard]# wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml
下载的recommended.yaml资源清单文件的内容如下:
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: v1
kind: Namespace
metadata:
name: kubernetes-dashboard
---
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
---
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
ports:
- port: 443
targetPort: 8443
selector:
k8s-app: kubernetes-dashboard
---
apiVersion: v1
kind: Secret
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard-certs
namespace: kubernetes-dashboard
type: Opaque
---
apiVersion: v1
kind: Secret
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard-csrf
namespace: kubernetes-dashboard
type: Opaque
data:
csrf: ""
---
apiVersion: v1
kind: Secret
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard-key-holder
namespace: kubernetes-dashboard
type: Opaque
---
kind: ConfigMap
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard-settings
namespace: kubernetes-dashboard
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
rules:
# Allow Dashboard to get, update and delete Dashboard exclusive secrets.
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs", "kubernetes-dashboard-csrf"]
verbs: ["get", "update", "delete"]
# Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map.
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["kubernetes-dashboard-settings"]
verbs: ["get", "update"]
# Allow Dashboard to get metrics.
- apiGroups: [""]
resources: ["services"]
resourceNames: ["heapster", "dashboard-metrics-scraper"]
verbs: ["proxy"]
- apiGroups: [""]
resources: ["services/proxy"]
resourceNames: ["heapster", "http:heapster:", "https:heapster:", "dashboard-metrics-scraper", "http:dashboard-metrics-scraper"]
verbs: ["get"]
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
rules:
# Allow Metrics Scraper to get metrics from the Metrics server
- apiGroups: ["metrics.k8s.io"]
resources: ["pods", "nodes"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: kubernetes-dashboard
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: kubernetes-dashboard
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: kubernetes-dashboard
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kubernetes-dashboard
---
kind: Deployment
apiVersion: apps/v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
k8s-app: kubernetes-dashboard
template:
metadata:
labels:
k8s-app: kubernetes-dashboard
spec:
securityContext:
seccompProfile:
type: RuntimeDefault
containers:
- name: kubernetes-dashboard
image: kubernetesui/dashboard:v2.7.0
imagePullPolicy: Always
ports:
- containerPort: 8443
protocol: TCP
args:
- --auto-generate-certificates
- --namespace=kubernetes-dashboard
# Uncomment the following line to manually specify Kubernetes API server Host
# If not specified, Dashboard will attempt to auto discover the API server and connect
# to it. Uncomment only if the default does not work.
# - --apiserver-host=http://my-address:port
volumeMounts:
- name: kubernetes-dashboard-certs
mountPath: /certs
# Create on-disk volume to store exec logs
- mountPath: /tmp
name: tmp-volume
livenessProbe:
httpGet:
scheme: HTTPS
path: /
port: 8443
initialDelaySeconds: 30
timeoutSeconds: 30
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsUser: 1001
runAsGroup: 2001
volumes:
- name: kubernetes-dashboard-certs
secret:
secretName: kubernetes-dashboard-certs
- name: tmp-volume
emptyDir: {}
serviceAccountName: kubernetes-dashboard
nodeSelector:
"kubernetes.io/os": linux
# Comment the following tolerations if Dashboard must not be deployed on master
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
---
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: dashboard-metrics-scraper
name: dashboard-metrics-scraper
namespace: kubernetes-dashboard
spec:
ports:
- port: 8000
targetPort: 8000
selector:
k8s-app: dashboard-metrics-scraper
---
kind: Deployment
apiVersion: apps/v1
metadata:
labels:
k8s-app: dashboard-metrics-scraper
name: dashboard-metrics-scraper
namespace: kubernetes-dashboard
spec:
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
k8s-app: dashboard-metrics-scraper
template:
metadata:
labels:
k8s-app: dashboard-metrics-scraper
spec:
securityContext:
seccompProfile:
type: RuntimeDefault
containers:
- name: dashboard-metrics-scraper
image: kubernetesui/metrics-scraper:v1.0.8
ports:
- containerPort: 8000
protocol: TCP
livenessProbe:
httpGet:
scheme: HTTP
path: /
port: 8000
initialDelaySeconds: 30
timeoutSeconds: 30
volumeMounts:
- mountPath: /tmp
name: tmp-volume
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsUser: 1001
runAsGroup: 2001
serviceAccountName: kubernetes-dashboard
nodeSelector:
"kubernetes.io/os": linux
# Comment the following tolerations if Dashboard must not be deployed on master
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
volumes:
- name: tmp-volume
emptyDir: {}
2.2 安装Dashboard
recommended.yaml资源清单文件包含了RBAC、Secret、Deployment和Service等对象,需要kubernetesui/dashboard:v2.7.0和kubernetesui/metrics-scraper:v1.0.8这两个镜像(镜像文件在本文配套资料包中,如无法上网,可以下载资料包后使用docker load -i *.tgz离线安装这两个镜像)。
配套资料包地址:https://download.csdn.net/download/field1003/91965690
这里介绍两种安装方式:在线安装和离线安装。
2.2.1 在线安装
如果已经配置好网络,可以访问到github、dockerhub等网站,则可以通过以下命令安装Dashboard[root@master 10-dashboard] kubectl apply -f recommended.yaml
该命令将创建Dashboard所需资源对象,下载镜像文件。
经过一段漫长的等待,Dashboard就安装完成了,这时就可以进入下一阶段的创建管理员并获取Token了。
2.2.2 离线安装
如果镜像文件一直下载超时,可以考虑离线安装镜像文件,离线安装镜像文件时,需要下载与k3s相对应的镜像版本,否则容易出现兼容性问题。
本文k3s版本为1.29.6,与dashboard-v2.7.0、metrics-scraper-v1.0.8兼容。
(1) 离线导入镜像文件
本文配套资料包中,k8s-test/1-setup/images目录下,有metrics-scraper-v1.0.8.tar和dashboard-v2.7.0.tar两个文件,可以通过docker -i命令离线加载。
# 安装metrics-scraper
[root@master images]# docker load -i metrics-scraper-v1.0.8.tar
d01384fea991: Loading layer [==================================================>] 43.82MB/43.82MB
bcec7eb9e567: Loading layer [==================================================>] 3.584kB/3.584kB
Loaded image: kubernetesui/metrics-scraper:v1.0.8
# 安装dashboard
[root@master images]# docker load -i dashboard-v2.7.0.tar
bd8a70623766: Loading layer [==================================================>] 249.2MB/249.2MB
c88361932af5: Loading layer [==================================================>] 3.072kB/3.072kB
Loaded image: kubernetesui/dashboard:v2.7.0
[root@master images]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry.k8s.io/ingress-nginx/controller v1.12.0 a4a8af0db089 7 months ago 302MB
registry.k8s.io/ingress-nginx/kube-webhook-certgen v1.5.0 6595b1857d40 7 months ago 66.1MB
nginx 1.27.3 66f8bdd3810c 8 months ago 192MB
nginx 1.27.5 66f8bdd3810c 8 months ago 192MB
rancher/local-path-provisioner v0.0.27 c45111663115 14 months ago 49.3MB
rancher/klipper-helm v0.8.4-build20240523 0c1204a22f13 15 months ago 263MB
rancher/klipper-lb v0.4.7 edc812b8e25d 18 months ago 11.8MB
rancher/mirrored-library-traefik 2.10.7 ee69e8120b64 18 months ago 153MB
rancher/mirrored-metrics-server v0.7.0 b9a5a1927366 19 months ago 66.8MB
rancher/mirrored-library-busybox 1.36.1 65ad0d468eb1 2 years ago 4.26MB
rancher/mirrored-coredns-coredns 1.10.1 ead0a4a53df8 2 years ago 53.6MB
kubernetesui/dashboard v2.7.0 07655ddf2eeb 2 years ago 246MB
kubernetesui/metrics-scraper v1.0.8 115053965e86 3 years ago 43.8MB
busybox 1.34.1 beae173ccac6 3 years ago 1.24MB
rancher/mirrored-pause 3.6 6270bb605e12 3 years ago 683kB
k8s.gcr.io/sig-storage/nfs-subdir-external-provisioner v4.0.2 932b0bface75 4 years ago 43.8MB
(2) 创建资源对象
# 执行kubectl apply命令,创建资源对象
[root@master 10-dashboard]# kubectl apply -f recommended.yaml
namespace/kubernetes-dashboard created
serviceaccount/kubernetes-dashboard created
service/kubernetes-dashboard created
secret/kubernetes-dashboard-certs created
secret/kubernetes-dashboard-csrf created
secret/kubernetes-dashboard-key-holder created
configmap/kubernetes-dashboard-settings created
role.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrole.rbac.authorization.k8s.io/kubernetes-dashboard created
rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
deployment.apps/kubernetes-dashboard created
service/dashboard-metrics-scraper created
deployment.apps/dashboard-metrics-scraper created
# 查看kubernetes-dashboard命名空间下所有资源
# 发现dashboard这个Pod拉取镜像失败,我们之前已经安装过这个应用,理论上讲不应该出现这个错误
# 查看recommended.yaml文件,发现dashboard这个镜像的拉取策略为Always,无论本地是否存在,均从仓库拉取
[root@master 10-dashboard]# kubectl get all -n kubernetes-dashboard
NAME READY STATUS RESTARTS AGE
pod/dashboard-metrics-scraper-5657497c4c-88kgz 1/1 Running 0 35s
pod/kubernetes-dashboard-78f87ddfc-t8426 0/1 ErrImagePull 0 35s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/dashboard-metrics-scraper ClusterIP 10.43.252.114 <none> 8000/TCP 15s
service/kubernetes-dashboard ClusterIP 10.43.15.140 <none> 443/TCP 15s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/dashboard-metrics-scraper 1/1 1 1 35s
deployment.apps/kubernetes-dashboard 0/1 1 0 35s
NAME DESIRED CURRENT READY AGE
replicaset.apps/dashboard-metrics-scraper-5657497c4c 1 1 1 35s
replicaset.apps/kubernetes-dashboard-78f87ddfc 1 1 0 35s
# 可以手动修改recommanded.yaml文件,Always改为IfNotPresent。也可以使用kubectl patch命令快速修改。
[root@master 10-dashboard]# kubectl -n kubernetes-dashboard patch deployment kubernetes-dashboard --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/imagePullPolicy", "value": "IfNotPresent"}]'
deployment.apps/kubernetes-dashboard patched
# 打完patch后,所有镜像均正常运行
[root@master 10-dashboard]# kubectl get pod -n kubernetes-dashboard
NAME READY STATUS RESTARTS AGE
dashboard-metrics-scraper-5657497c4c-88kgz 1/1 Running 0 2m9s
kubernetes-dashboard-5b749d9495-44mbs 1/1 Running 0 12s
2.3 创建管理员并获取Token
新建ServiceAccount dashboard-admin,并将其与集群的cluster-admin绑定。
配置文件
[root@master 10-dashboard]# cat dashboard-admin-sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: dashboard-admin
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: dashboard-admin
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: dashboard-admin
namespace: kubernetes-dashboard
绑定
[root@master 10-dashboard]# kubectl apply -f dashboard-admin-sa.yaml
serviceaccount/dashboard-admin created
clusterrolebinding.rbac.authorization.k8s.io/dashboard-admin unchanged
[root@master 10-dashboard]#
获取Token
[root@master 10-dashboard]# kubectl -n kubernetes-dashboard create token dashboard-admin
eyJhbGciOiJSUzI1NiIsImtpZCI6IlVaeDdlWkZDck1GRzdubWswanBPRk95eE9Lc0xRdzZHeTNMSUZWNG13STAifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiLCJrM3MiXSwiZXhwIjoxNzU1NTM1NDk3LCJpYXQiOjE3NTU1MzE4OTcsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsInNlcnZpY2VhY2NvdW50Ijp7Im5hbWUiOiJkYXNoYm9hcmQtYWRtaW4iLCJ1aWQiOiIzZWJkN2FiOC05ODg4LTRhZDctOTg4YS04MDc2MDJiZGIwOGUifX0sIm5iZiI6MTc1NTUzMTg5Nywic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmVybmV0ZXMtZGFzaGJvYXJkOmRhc2hib2FyZC1hZG1pbiJ9.bZhYQYtUsbopQocQz0TBGXWCZM9NyvgF8GSrFg_LlOA5d99-YrCMj27VlmQ9MYVgYoYzTOjSQZ4MnpsbOZApGajeWJUtVcmxJFcErmHZy80zITxiuGsbIN2cWM5_8cBKqbT6Rl5J056pflp95eaYQ9lYr0qgtvoZLLFeDArkuvDMToh-y5_rXk8g_jLpEVg9EjUuGIJv2C9k-lOrpv1oPCSqAqqp6bhNOjVEEcorKJ6BhUtPKDuyKhW1unj_U8pQzgxj9farHA2jwNwhbYgeSFhiZJ6CUziVnP88-fZe_Zyre3bnUuMwG2shusGkQ3fq3uM-ySRq07u-VyD9haol1Q
2.4 暴露端口,集群外可访问
得到管理员Token,在集群内部,就可以通过ClusterIP访问Dashboard了。
[root@master 10-dashboard]# kubectl get svc -n kubernetes-dashboard
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
dashboard-metrics-scraper ClusterIP 10.43.252.114 <none> 8000/TCP 8m49s
kubernetes-dashboard ClusterIP 10.43.15.140 <none> 443/TCP 8m49s
如果我们想要在集群外部访问Dashboard,还需要将ClusterIP类型Service改为NodePort类型Service。
可以通过修改recommanded.yaml的Service对象,添加一个type: NodePort字段,由默认的ClusterIP改为NodePort。也可以通过kubectl patch快速修改。
# 通过kubectl patch将Service对象的type改为NodePort
[root@master 10-dashboard]# kubectl -n kubernetes-dashboard patch svc kubernetes-dashboard --type='json' -p='[{"op":"replace","path":"/spec/type","value":"NodePort"}]'
service/kubernetes-dashboard patched
# 查看Service,可以看到已经变成NodePort,对外暴露端口为10981
[root@master 10-dashboard]# kubectl get svc -n kubernetes-dashboard
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
dashboard-metrics-scraper ClusterIP 10.43.252.114 <none> 8000/TCP 19m
kubernetes-dashboard NodePort 10.43.15.140 <none> 443:10981/TCP 19m
2.5 小结
Dashboard安装非常简单,如果网络可达,一个命令即可安装完成,然后创建管理员及暴露端口就可以访问。如果网络不可达,则需要自己手动操作,下载镜像,修改配置文件等等。
如果是离线安装,可以提前将官方下载的recommended.yaml文件修改好,把第二步Deployment镜像下载策略改为IfNotPresent,把第四步Service类型改为NodePort,这样还可以省去暴露端口的步骤。两者对比如下:
[root@master 10-dashboard]# diff recommended.yaml recommended-offline.yaml
194c194
< imagePullPolicy: Always
---
> imagePullPolicy: IfNotPresent
246a247
> type: NodePort
249a251
> nodePort: 32000
3 访问Dashboard
(1) 查看Dashboard Service NodePort端口
# Dashboard对外暴露端口为10981
[root@master 10-dashboard]# kubectl get svc -n kubernetes-dashboard
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
dashboard-metrics-scraper ClusterIP 10.43.252.114 <none> 8000/TCP 22m
kubernetes-dashboard NodePort 10.43.15.140 <none> 443:10981/TCP 22m
(2) 集群外使用浏览器打开Dashboard地址https://192.168.88.132:10981
弹出风险提示。
点击 高级->接受风险并继续
(3) Token方式登录
Dashboard有两种登录方式:Token和Kubeconfig。
Token方式相对简单,只需要向输入框填入生成的Token即可访问。
Kubeconfig方式更加灵活,需要提供一个kubeconfig文件,让Dashboard自己从文件解析Token。
这里演示Token方法。
输入前面生成的Token,然后点击“登录”。
(4) 进入Dashboard管理界面
点击登录,即可进入Dashboard管理界面,左侧有工作负载、服务、配置和存储、集群及自定义资源等分类,点击即可查看对应资源对象详情,与kubectl命令行查看到的内容相同。
更多推荐


所有评论(0)