一、前言
前面三篇文章介紹了如何從零開始搭建一個基本的Kubernetes集群,本文將介紹一下如何搭建K8S的Dashboard。
簡單的說,K8S Dashboard是官方的一個基于WEB的用戶界面,專門用來管理K8S集群,并可展示集群的狀態。K8S集群安裝好后默認沒有包含Dashboard,我們需要額外創建它。
本人覺得Dashboard設計的還不錯,界面友好,功能也比較強大。如果你厭倦了命令行的操作,全程使用Dashboard也是可行的。
Dashboard的搭建過程中,會遇到一些坑。現在開始,咱們一步一步踩來,走你!
二、RABC簡介
還是那句話,官方文檔是最重要的參考資料:https://kubernetes.io/docs/tasks/access-application-cluster/web-ui-dashboard/
該文檔中,創建kubernetes-dashboard的命令為:
kubectl create -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml
當然,直接這樣創建的dashboard會有很多問題,參見:
Please note, this works only if the apiserver is set up to allow authentication with username and password. This is not currently the case with some setup tools (e.g.,
kubeadm
). Refer to the authentication admin documentation for information on how to configure authentication manually.
因為我們使用kubeadm搭建的集群會默認開啟RABC(角色訪問控制機制),所以我們必須要進行額外的設置。關于RABC的概念,網上資料很多,大家務必提前了解。這里簡要介紹一下幾個重要概念:
- RBAC
K8S 1.6引進,是讓用戶能夠訪問 k8S API 資源的授權方式【不授權就沒有資格訪問K8S的資源】 - 用戶
K8S有兩種用戶:User和Service Account。其中,User給人用,Service Account給進程用,讓進程有相關權限。如Dashboard就是一個進程,我們就可以創建一個Service Account給它 - 角色
Role是一系列權限的集合,例如一個Role可包含讀取和列出 Pod的權限【 ClusterRole 和 Role 類似,其權限范圍是整個集群】 - 角色綁定
RoleBinding把角色映射到用戶,從而讓這些用戶擁有該角色的權限【ClusterRoleBinding 和RoleBinding 類似,可讓用戶擁有 ClusterRole 的權限】 - Secret
Secret是一個包含少量敏感信息如密碼,令牌,或秘鑰的對象。把這些信息保存在 Secret對象中,可以在這些信息被使用時加以控制,并可以降低信息泄露的風險
如下圖,灰色是“角色”,藍色是“用戶”,綠色是“角色綁定”,黃色是該角色擁有的權限。簡言之 ,角色綁定將角色和用戶進行掛鉤:
三、官方kubernetes-dashboard.yaml簡介
很有必要介紹一下官方的kubernetes-dashboard.yaml,我們首先將其下載下來:
wget https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml
該文件分為以下幾部分:
- Dashboard Service
- Dashboard Deployment
- Dashboard Role
- RoleBinding
- Dashboard Service Account
- Dashboard Secret
這里,我們簡單的對各個部分的功能進行介紹:
Dashboard Role
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: kubernetes-dashboard-minimal
namespace: kube-system
rules:
# Allow Dashboard to create 'kubernetes-dashboard-key-holder' secret.
- apiGroups: [""]
resources: ["secrets"]
verbs: ["create"]
# Allow Dashboard to create 'kubernetes-dashboard-settings' config map.
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["create"]
# Allow Dashboard to get, update and delete Dashboard exclusive secrets.
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs"]
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 from heapster.
- apiGroups: [""]
resources: ["services"]
resourceNames: ["heapster"]
verbs: ["proxy"]
- apiGroups: [""]
resources: ["services/proxy"]
resourceNames: ["heapster", "http:heapster:", "https:heapster:"]
verbs: ["get"]
如上定義了Dashboard 的角色,其角色名稱為kubernetes-dashboard-minimal
,rules
中清晰的列出了其擁有的多個權限。通過名稱我們可以猜到,這個權限級別是比較低的。
ServiceAccount
kind: ServiceAccount
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kube-system
如上定義了Dashboard的用戶,其類型為ServiceAccount
,名稱為kubernetes-dashboard
。
RoleBinding
kind: RoleBinding
metadata:
name: kubernetes-dashboard-minimal
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: kubernetes-dashboard-minimal
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kube-system
如上定義了Dashboard的角色綁定,其名稱為kubernetes-dashboard-minimal
,roleRef中為被綁定的角色,也叫kubernetes-dashboard-minimal
,subjects
中為綁定的用戶:kubernetes-dashboard
。
Dashboard Secret
kind: Secret
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard-certs
namespace: kube-system
type: Opaque
Dashboard Deployment
kind: Deployment
apiVersion: apps/v1beta2
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kube-system
spec:
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
k8s-app: kubernetes-dashboard
template:
metadata:
labels:
k8s-app: kubernetes-dashboard
spec:
containers:
- name: kubernetes-dashboard
image: k8s.gcr.io/kubernetes-dashboard-amd64:v1.8.3
ports:
- containerPort: 8443
protocol: TCP
args:
- --auto-generate-certificates
# 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
volumes:
- name: kubernetes-dashboard-certs
secret:
secretName: kubernetes-dashboard-certs
- name: tmp-volume
emptyDir: {}
serviceAccountName: kubernetes-dashboard
# Comment the following tolerations if Dashboard must not be deployed on master
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
如上可以看到,Dashboard的Deployment指定了其使用的ServiceAccount是kubernetes-dashboard
。并且還將Secret kubernetes-dashboard-certs
通過volumes掛在到pod內部的/certs路徑。為何要掛載Secret ?原因是創建Secret 時會自動生成token。請注意參數--auto-generate-certificates
,其表示Dashboard會自動生成證書。
四、安裝Dashboard
1.導入鏡像
如果直接使用官方的kubernetes-dashboard.yaml創建Dashboard,你會踩到很多坑,首先是鏡像拉取會超時失敗。截止目前,Dashboard的最新版本是1.8.3,我已經將鏡像k8s.gcr.io#kubernetes-dashboard-amd64.tar
導出,提供給大家:
鏈接:https://pan.baidu.com/s/11AheivJxFzc4X6Q5_qCw8A
密碼:2zov
在所有節點上(因為你不知道K8S會將Dashboard的pod調度到哪個節點),使用如下命令導入鏡像:
docker load < k8s.gcr.io#kubernetes-dashboard-amd64.tar
導入成功后,執行docker images
可以看到Dashboard的版本是1.8.3:
2.創建Dashboard
導入鏡像后,使用之前下載的yaml文件即可創建Dashboard:
kubectl create -f kubernetes-dashboard.yaml
3.訪問Dashboard
根據官方文檔,目前訪問Dashboard有四種方式:
- NodePort
- API Server
- kubectl proxy
- Ingress
以上四種方式,我測試了前三種,目前只有NodePort和kubectl proxy可用,API Server暫時沒有解決。
使用NodePort
為kubernetes-dashboard.yaml添加Service后,就可以使用NodePort訪問Dashboard。在我們的物理機上,使用Chrome訪問https://192.168.56.101:32159/
,結果如下圖所示:
如上可以看到,這里提示了證書錯誤
NET::ERR_CERT_INVALID
,原因是由于物理機的瀏覽器證書不可用。但是,不要放棄,我們這里不打算使用物理機訪問瀏覽器,而使用Dashboard所在節點上的瀏覽器來訪問(即CentOS自帶的瀏覽器),這樣的證書應該是可行的(官方默認就是這種方式)。
由于之前建立虛擬機環境時,我們關閉了CentOS的圖形界面,這里我們為了訪問Dashboard臨時開啟,執行:systemctl set-default graphical.target
。重啟后,即可進入圖形界面。我們用Firefox訪問:https://192.168.56.101:32159/
,成功后出現如下界面:
需要注意的是,若提示“連接不安全”的警告時,點擊“高級”,點擊“添加例外”后即可:
使用API Server
在我們的物理機上,使用Chrome訪問地址:https://192.168.56.101:6443/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/
,返回如下錯誤:
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {
},
"status": "Failure",
"message": "services \"https:kubernetes-dashboard:\" is forbidden: User \"system:anonymous\" cannot get services/proxy in the namespace \"kube-system\"",
"reason": "Forbidden",
"details": {
"name": "https:kubernetes-dashboard:",
"kind": "services"
},
"code": 403
}
原因是由于kube-apiserver使用了TLS認證,而我們的真實物理機上的瀏覽器使用匿名證書(因為沒有可用的證書)去訪問Dashboard,導致授權失敗而不無法訪問。官方提供的解決方法是將kubelet的證書轉化為瀏覽器可用的證書,然后導入進瀏覽器。
Note: This way of accessing Dashboard is only possible if you choose to install your user certificates in the browser. In example certificates used by kubeconfig file to contact API Server can be used.
但是該方法目前似乎不適用于kubeadm方式安裝的集群,參見:https://github.com/opsnull/follow-me-install-kubernetes-cluster/issues/5
那如果使用節點自帶的Firefox呢?我們在Firefox中訪問:https://192.168.56.101:6443/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/
,仍然提示上面的錯誤:
看來,無論物理機還是K8S節點上的瀏覽器,都需要導入這個證書,暫時無解。
使用kubectl proxy
這里,我主要介紹一下最便捷的kubectl proxy
方式。在Master上執行kubecll proxy
,然后使用如下地址訪問Dashboard:
http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy
但限制就是必須在Master上訪問,這顯然是個坑,我們的目標是在我們真實的物理機上去訪問Master的Dashboard。
所以,在主節點上,我們執行kubectl proxy --address=192.168.56.101 --disable-filter=true
開啟代理。
其中:
-
address
表示外界可以使用192.168.56.101
來訪問Dashboard,我們也可以使用0.0.0.0
-
disable-filter=true
表示禁用請求過濾功能,否則我們的請求會被拒絕,并提示Forbidden (403) Unauthorized
。 - 我們也可以指定端口,具體請查看
kubectl proxy --help
如下圖所示,proxy默認對Master的8001端口進行監聽:
這樣,我們就可以使用如下地址訪問登錄界面:
http://192.168.56.101:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/#!/login
4.配置Dashboard
Dashboard的配置是難點,尤其是涉及到安全權限相關,相當復雜,坑也比較多。
進入Dashboard的登錄界面后,認證方式有Kubeconfig和令牌兩種方式(實際上還有賬號密碼的方式,默認不開啟不顯示)。看到Kubeconfig和令牌,估計頭都大了。是否有簡便的方法,讓我們能直接訪問Dashboard?當然有,選擇跳過,會出現如下頁面:
如上圖,很遺憾,我們看到了很多權限錯誤提示,主要是
system:serviceaccount:kube-system:kubernetes-dashboard
的權限不足引起的。
我們回想本文第三小節對kubernetes-dashboard.yaml的介紹,現在就理解了為什么其角色的名稱為kubernetes-dashboard-minimal
。一句話,這個Role的權限不夠!
因此,我們可以更改RoleBinding
修改為ClusterRoleBinding
,并且修改roleRef
中的kind
和name
,使用cluster-admin
這個非常牛逼的CusterRole(超級用戶權限,其擁有訪問kube-apiserver的所有權限)。如下:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: kubernetes-dashboard-minimal
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kube-system
修改后,重新創建kubernetes-dashboard.yaml
,Dashboard就可以擁有訪問整個K8S 集群API的權限。我們重新訪問Dashboard,如下圖所示:
如上,一切正常,請在界面上盡情的亂點吧。另外,如果有興趣,你還可以安裝Dashboard的Heapster插件,這里就不再介紹了。
八、廢話
到目前為止,我們的K8S的Dashboard就真正搭建完畢了,下一章節《從零開始搭建Kubernetes集群(五、搭建K8S Ingress)》,敬請期待。
本人水平有限,難免有錯誤或遺漏之處,望大家指正和諒解,歡迎評論留言。