"種草" kubernetes-dashboard
Kubernetes Dashboard 是通用的用於管理 Kubernetes 集羣的 WebUI面板
kubernetes-dashboard 代碼庫 readme 中對自己的介紹:
Kubernetes Dashboard is a general purpose, web-based UI for Kubernetes clusters. It allows users to manage applications running in the cluster and troubleshoot them, as well as manage the cluster itself.
通過這個面板, 可以讓我們非常直觀看到pod的狀態, 創建時間, 標籤, 運行在哪個結點等元數據
還能看到容器中定義的環境變量, 掛載的磁盤, liveness
和readiness
探針等信息
有了這個面板, 不光是pod, 可以對幾乎 kubernetes 中的任何資源(前提是當前用戶有足夠的權限) 查看和管理
再介紹一個這個面板我自己最常用的功能: 重啓pod
確實通過命令kubectl rollout restart -n prod deployment mysql-8-0
可以實現同樣的操作, 不過有了這個面板, 鼠標點點就能完成豈不美哉, 重啓前還會彈出確認框提示你是不是確定要重啓, 還貼心的把用於重啓命令給我們展示出來了, awesome! 再也不怕忘記命令每次都要去google一下文檔啦!
這個面板可以使用kubernetes的ServiceAccount來登錄鑑權, 對權限控制的粒度可以做到非常細緻, 別急, 往下看!
安裝部署dashboard
這份文件中, 首先定義了個Namespace
-> kubernetes-dashboard
, 然後的所有資源都在這個Namespace
下;
先看2個Deployment
的定義, 分別是kubernetes-dashboard
和dashboard-metrics-scraper
點擊展開 -> Deployment: 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
# 通過nginx-ingress暴露出去, 這裏不需要ssl了, 沒有這個標誌位會導致無法正常登錄
- --enable-insecure-login=true
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
點擊展開 -> Deployment: 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: {}
再看ServiceAccount
: kubernetes-dashboard
; 上面兩個Deployment
kubernetes-dashboard
和dashboard-metrics-scraper
中的容器都綁定到了這個ServiceAccount
點擊展開 ServiceAccount: kubernetes-dashboard
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
deployment.yaml
中還定義了ClusterRole
: kubernetes-dashboard
和Role
: kubernetes-dashboard
, ClusterRole
Role
中定義了面板所需的權限
ClusterRole和Role的定義
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"]
ClusterRole
, Role
與 前面提到的 ServiceAccount:kubernetes-dashboard
通過 ClusterRoleBinding
和 RoleBinding
綁定到了一起, 就是給 ServiceAccount:kubernetes-dashboard
授權, 讓它可以訪問集羣裏的資源
ClusterRoleBinding, RoleBinding 綁定 ServiceAccount 與 ClusterRole, Role
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
最後就是 Service
, ConfigMap
, 和幾個ssl相關的 Secret
, 幾個 Secret
的定義對我來說是不重要的, 因爲上面Deployment
容器的啓動命令裏, 我加上了 --enable-insecure-login=true
, 我在外部通過nginx-ingress暴露服務, 配置好了ingress的部分配置ssl, 所裏這裏就無所謂了
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
---
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: ConfigMap
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard-settings
namespace: 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
配置Ingress
, 向外暴露服務
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: kubernetes-dashboard
name: kubernetes-dashboard-ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/backend-protocol: http
spec:
ingressClassName:
tls:
- hosts:
- <這裏填域名>
secretName: <這裏填集羣內配置好的Secret證書>
rules:
- host: <這裏填域名>
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: kubernetes-dashboard
port:
number: 80
創建用於登錄面板的ServiceAccount
新建account.yaml
中定義ServiceAccount
並綁定到內置的ClusterRole
定義兩個 ServiceAccount
分別是 root
和 readonly
root
綁定到內置的ClusterRole
cluster-admin
readonly
綁定到內置的ClusterRole
view
kubectl get clusterrole
可以列表當前集羣中已存在的角色
apiVersion: v1
kind: ServiceAccount
metadata:
name: root
namespace: kubernetes-dashboard
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: readonly
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: root
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: root
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: readonly
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: view
subjects:
- kind: ServiceAccount
name: readonly
namespace: kubernetes-dashboard
kubectl apply -f account.yaml
應用後, root
和 readonly
就創建好了, 然後我們去生成 Token
輸入到面板的登錄界面中就可以登錄了
爲 root
生成有效期30天 Token
的命令 kubectl create token --namespace kubernetes-dashboard --duration 2592000s root
用 Token
登錄
權限控制
root 賬戶綁定的角色是內置的 cluster-admin
, 可以對集羣內的一切資源進行查看或修改, 刪除等操作
readonly 賬戶綁定的角色是內置的 view
, 擁有對集羣內大部分資源的只讀權限
也可以自己新建一個角色, 授予這個新角色某些指定權限, 例如下面的示例, 創建了一個名爲 test
的 ClusterRole
, 對pods有隻讀權限, 然後將這個角色與 ServiceAccount
綁定
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: test
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: root-to-test
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: test
subjects:
- kind: ServiceAccount
name: root
namespace: kubernetes-dashboard