给kubernetes cluster安装可视化界面dashboard
一 背景说明
这是一个跑在3台Linux服务器上的kubernetes cluster,1个master(172.16.11.106),2个worker node(172.16.11.148和172.16.11.161)。
OS信息:
[root@master-node ~]# cat /etc/redhat-release
CentOS Linux release 7.5.1804 (Core)
[root@master-node ~]# uname -rm
3.10.0-862.el7.x86_64 x86_64
[root@master-node ~]#
kubernetes信息:
[root@master-node ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master-node Ready control-plane,master 5d23h v1.22.3
node-1 Ready <none> 5d23h v1.22.3
node-2 Ready <none> 5d23h v1.22.3
[root@master-node ~]# kubectl version
Client Version: version.Info{Major:"1", Minor:"22", GitVersion:"v1.22.3", GitCommit:"c92036820499fedefec0f847e2054d824aea6cd1", GitTreeState:"clean", BuildDate:"2021-10-27T18:41:28Z", GoVersion:"go1.16.9", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"22", GitVersion:"v1.22.3", GitCommit:"c92036820499fedefec0f847e2054d824aea6cd1", GitTreeState:"clean", BuildDate:"2021-10-27T18:35:25Z", GoVersion:"go1.16.9", Compiler:"gc", Platform:"linux/amd64"}
[root@master-node ~]# kubeadm version
kubeadm version: &version.Info{Major:"1", Minor:"22", GitVersion:"v1.22.3", GitCommit:"c92036820499fedefec0f847e2054d824aea6cd1", GitTreeState:"clean", BuildDate:"2021-10-27T18:40:11Z", GoVersion:"go1.16.9", Compiler:"gc", Platform:"linux/amd64"}
[root@master-node ~]#
现在,考虑给这个kubernetes cluster配置1个可视化的图形管理界面dashboard。
二 安装流程
1 获取资源文件recommended.yaml
从kubernetes官网,或者GitHub上都有说明,如何安装配置dashboard。通过一个命令即可完成:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.4.0/aio/deploy/recommended.yaml
问题麻烦在文件https://raw.githubusercontent.com/kubernetes/dashboard/v2.4.0/aio/deploy/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:
containers:
- name: kubernetes-dashboard
image: kubernetesui/dashboard:v2.3.1
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
annotations:
seccomp.security.alpha.kubernetes.io/pod: 'runtime/default'
spec:
containers:
- name: dashboard-metrics-scraper
image: kubernetesui/metrics-scraper:v1.0.6
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 master上执行安装dashboard
[root@master-node ~]# kubectl apply -f dashboard.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
Warning: spec.template.metadata.annotations[seccomp.security.alpha.kubernetes.io/pod]: deprecated since v1.19; use the "seccompProfile" field instead
deployment.apps/dashboard-metrics-scraper created
[root@master-node ~]#
查看新创建的dashboard资源:
[root@master-node ~]# kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
default nginx-6799fc88d8-dg6d9 1/1 Running 0 6d
kube-system coredns-7f6cbbb7b8-mrsgg 1/1 Running 0 6d
kube-system coredns-7f6cbbb7b8-wvd4x 1/1 Running 0 6d
kube-system etcd-master-node 1/1 Running 0 6d
kube-system kube-apiserver-master-node 1/1 Running 0 6d
kube-system kube-controller-manager-master-node 1/1 Running 0 6d
kube-system kube-flannel-ds-ndp9g 1/1 Running 0 6d
kube-system kube-flannel-ds-nxjzc 1/1 Running 0 6d
kube-system kube-flannel-ds-v2d5t 1/1 Running 0 6d
kube-system kube-proxy-5wmch 1/1 Running 0 6d
kube-system kube-proxy-95l4w 1/1 Running 0 6d
kube-system kube-proxy-xq77j 1/1 Running 0 6d
kube-system kube-scheduler-master-node 1/1 Running 0 6d
kubernetes-dashboard dashboard-metrics-scraper-856586f554-l4bpm 1/1 Running 0 22s
kubernetes-dashboard kubernetes-dashboard-67484c44f6-xqftl 0/1 ContainerCreating 0 22s
[root@master-node ~]#
3修改kubernetes-dashboard的端口映射
修改之前:
[root@master-node ~]# kubectl get svc -A
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 6d
default nginx NodePort 10.108.50.59 <none> 80:30769/TCP 6d
kube-system kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 6d
kubernetes-dashboard dashboard-metrics-scraper ClusterIP 10.102.0.17 <none> 8000/TCP 9m7s
kubernetes-dashboard kubernetes-dashboard ClusterIP 10.97.131.98 <none> 443/TCP 9m7s
[root@master-node ~]#
看到资源kubernetes-dashboard的端口在443。
执行命令,进行修改:
[root@master-node ~]# kubectl edit svc kubernetes-dashboard -n kubernetes-dashboard
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
将其中的,type: ClusterIP修改成type: NodePort,保存退出即可。
修改之后:
[root@master-node ~]# kubectl get svc -A
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 6d
default nginx NodePort 10.108.50.59 <none> 80:30769/TCP 6d
kube-system kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 6d
kubernetes-dashboard dashboard-metrics-scraper ClusterIP 10.102.0.17 <none> 8000/TCP 15m
kubernetes-dashboard kubernetes-dashboard NodePort 10.97.131.98 <none> 443:30838/TCP 15m
[root@master-node ~]#
看到kubernetes-dashboard 服务暴露在端口30838。
Chrome浏览器访问:https://172.16.11.106:30838/ 弹出警告,修改浏览器安全级别即可。这里,直接用Firefox来访问:https://172.16.11.106:30838/
其实,此时可以通过该kubernetes cluster中的任意节点来访问这个dashboard:
$ telnet 172.16.11.106 30838
Trying 172.16.11.106...
Connected to 172.16.11.106.
Escape character is '^]'.
^]
telnet> quit
Connection closed.
asher at MacBook-Air-3 in ~
$ telnet 172.16.11.148 30838
Trying 172.16.11.148...
Connected to 172.16.11.148.
Escape character is '^]'.
^]
telnet> quit
Connection closed.
asher at MacBook-Air-3 in ~
$ telnet 172.16.11.161 30838
Trying 172.16.11.161...
Connected to 172.16.11.161.
Escape character is '^]'.
6通过yaml配置文件创建访问dashboard的用户:
#创建访问账号,准备一个yaml文件; vi dash.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kubernetes-dashboard
[root@master-node ~]# kubectl apply -f dash-user.yaml
serviceaccount/admin-user created
clusterrolebinding.rbac.authorization.k8s.io/admin-user created
[root@master-node ~]#
7创建访问token,master执行
[root@master-node ~]# kubectl -n kubernetes-dashboard get secret $(kubectl -n kubernetes-dashboard get sa/admin-user -o jsonpath="{.secrets[0].name}") -o go-template="{{.data.token | base64decode}}"
eyJhbGciOiJSUzI1NiIsImtpZCI6Imp3aEZfMTF2UVczM2xyOVZGNnZ6Wnc2RWFEVVk2czR2dTZWUkNNMXZGWWcifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi11c2VyLXRva2VuLWZwdHJrIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImFkbWluLXVzZXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiI4ZWM3ZjM4MS05MjZiLTQxYTUtOWVjNi1hNzYyMTMyNDhmZjIiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZXJuZXRlcy1kYXNoYm9hcmQ6YWRtaW4tdXNlciJ9.W-0gUXFsxGq0p9h33Lzsx-etr4Ywngz5LWs_Esa16tFGAF4IflL9M_V1o4lg-iMby8F3AGT4CSi8OApMHAIs2NXDiUCu-uBCh4MaMUhEppNR3S_Jd45JF6R6WaX-0tEtgo7-C2OB30dLKq31IUQeCsXvakj0TWiAzdgVkx09tC40RbTIx3917qJhe8xKrvmwUVpsiD6vCSyfHCy9cBp9GepHrku6ZJRyMLPgQxCjjQbWZc1JXerdXSvrK21OSf5FIWIv7VHt6Lv32z15EQjzRcXccIIw7yqb0q06GD0ZQ4WjZLw3akPcpJkIOlS5-kyyrdoOJrSBNIn-jWfwLhikIA
[root@master-node ~]#
8 登录dashboard
登录界面,输入上述令牌。
上述,6/7步骤,可以参考GitHub:https://github.com/kubernetes/dashboard
三小结
通过创建dashboard可以友好的通过图形界面对kubernetes cluster进行查看,管理。
一条评论
Pingback: