.問題起源
kubeadm 是 kubernetes 提供的一個初始化集群的工具,使用起來非常方便。但是它創建的apiserver、controller-manager等證書默認只有一年的有效期,同時kubelet 證書也只有一年有效期,一年之后 kubernetes 將停止服務。
官方推薦一年之內至少用 kubeadm upgrade 更新一次 kubernetes 系統,更新時也會自動更新證書。不過,在產線環境或者無法連接外網的環境頻繁更新 kubernetes 不太現實。
我們可以在過期之前或之后,使用kubeadm alpha phase里的certs和kubeconfig命令,同時配合kubelet證書自動輪換機制來解決這個問題。
.認識認書
使用kubeadm創建完Kubernetes集群后, 默認會在/etc/kubernetes/pki目錄下存放集群中需要用到的證書文件, 整體結構如下圖所示:
Kubernetes 集群根證書
/etc/kubernetes/pki/ca.crt
/etc/kubernetes/pki/ca.key
由此根證書簽發的證書有:
1,kube-apiserver 組件持有的服務端證書
/etc/kubernetes/pki/apiserver.crt
/etc/kubernetes/pki/apiserver.key
2,kubelet 組件持有的客戶端證書
/etc/kubernetes/pki/apiserver-kubelet-client.crt
/etc/kubernetes/pki/apiserver-kubelet-client.key
kubelet 上一般不會明確指定服務端證書, 而是只指定 ca 根證書, 讓 kubelet 根據本地主機信息自動生成服務端證書並保存到配置的cert-dir文件夾中。
匯聚層(aggregator)證書
/etc/kubernetes/pki/front-proxy-ca.crt
/etc/kubernetes/pki/front-proxy-ca.key
由此根證書簽發的證書只有一組:
1,代理端使用的客戶端證書, 用作代用戶與 kube-apiserver 認證
/etc/kubernetes/pki/front-proxy-client.crt
/etc/kubernetes/pki/front-proxy-client.key
etcd 集群根證書
/etc/kubernetes/pki/etcd/ca.crt
/etc/kubernetes/pki/etcd/ca.key
由此根證書簽發機構簽發的證書有:
1,etcd server 持有的服務端證書
/etc/kubernetes/pki/etcd/server.crt
/etc/kubernetes/pki/etcd/server.key
2,peer 集群中節點互相通信使用的客戶端證書
/etc/kubernetes/pki/etcd/peer.crt
/etc/kubernetes/pki/etcd/peer.key
3,pod 中定義 Liveness 探針使用的客戶端證書
/etc/kubernetes/pki/etcd/healthcheck-client.crt
/etc/kubernetes/pki/etcd/healthcheck-client.key
4,配置在 kube-apiserver 中用來與 etcd server 做雙向認證的客戶端證書
/etc/kubernetes/pki/apiserver-etcd-client.crt
/etc/kubernetes/pki/apiserver-etcd-client.key
Serveice Account秘鑰
這組的密鑰對兒僅提供給 kube-controller-manager 使用. kube-controller-manager 通過 sa.key 對 token 進行簽名, master 節點通過公鑰 sa.pub 進行簽名的驗證.
API Server的authenticating環節支持多種身份校驗方式:client cert、bearer token、static password auth等,這些方式中有一種方式通過authenticating(Kubernetes API Server會逐個方式嘗試),那么身份校驗就會通過。一旦API Server發現client發起的request使用的是service account token的方式,API Server就會自動采用signed bearer token方式進行身份校驗。而request就會使用攜帶的service account token參與驗證。該token是API Server在創建service account時用API server啟動參數:–service-account-key-file的值簽署(sign)生成的。如果–service-account-key-file未傳入任何值,那么將默認使用–tls-private-key-file的值,即API Server的私鑰(server.key)。
通過authenticating后,API Server將根據Pod username所在的group:system:serviceaccounts和system:serviceaccounts:(NAMESPACE)的權限對其進行authority 和admission control兩個環節的處理。在這兩個環節中,cluster管理員可以對service account的權限進行細化設置。
/etc/kubernetes/pki/sa.key
/etc/kubernetes/pki/sa.pub
kubeadm 創建的集群, kube-proxy ,flannel,coreDNS是以 pod 形式運行的, 在 pod 中, 直接使用 service account 與 kube-apiserver 進行認證, 此時就不需要再單獨為 kube-proxy 創建證書
.Kubeadm本地讀取集群配置
正如默認的kubeadm 安裝k8s集群時,會從外網拉取鏡像。在kubeadm命令升級master證書時,它也會默認從網上讀取一個stable.txt的文件。由於公司實際情況,這個問題得解決掉。
解決這個問題的辦法,就是生成一個集群配置的yaml文件,然后,在運行命令時指定這個Yaml文件即可。
如何生居一個集群配置的yaml文件呢?命令如下:
kubeadm config view > cluster.yaml
其內容如下:
.重新生成master證書
一旦證書過期,使用kubectl時會出現如下提示:
Unable to connect to the server: x509: certificate has expired or is not yet valid
在此,我們使用kubeadm alpha phase certs系統命令,重新生成證書。
建議不要重新生成ca證書,因為更新了ca證書,集群節點就需要手工操作,才能讓集群正常(會涉及重新join)。
操作之前,先將/etc/kubernetes/pki下的證書文件,mv到其它文件夾,作個臨時備份,不要刪除。
kubeadm alpha phase certs etcd-healthcheck-client --config cluster.yaml
kubeadm alpha phase certs etcd-peer --config cluster.yaml
kubeadm alpha phase certs etcd-server --config cluster.yaml
kubeadm alpha phase certs front-proxy-client--config cluster.yaml
kubeadm alpha phase certs apiserver-etcd-client --config cluster.yaml
kubeadm alpha phase certs apiserver-kubelet-client --config cluster.yaml
kubeadm alpha phase certs apiserver --config cluster.yaml
kubeadm alpha phase certs sa --config cluster.yaml
.重新生成kubeconfig配置文件
在生成這些新的證書文件之后,再需要kubeadm alpha phase config命令,重新生成新的kubeconfig文件。
操作之前,先將/etc/kubernetes/下的kubeconfig,mv到其它文件夾,作個臨時備份,不要刪除。
kubeadm alpha phase kubeconfig all --config cluster.yaml
所有的kubeconfig重新生成以后,替換到kubectl使用的config文件之后(默認位置為~.kube/config),即可正常操作kubectl命令了。
.Kubelet證書自動輪換
kubelet證書分為server和client兩種, k8s 1.10默認啟用了client證書的自動輪換,但server證書自動輪換需要用戶開啟。
.Service Account密鑰更新
由於service account的密鑰是以rsa密鑰對形式生成,所以沒有過期時間。
如無必要,千萬不要生成重新生成sa密鑰。因為sa密鑰關聯到一切系統pod內的進程訪問api server時的認證。
如果更新了sa,則需要先重新生成這些pod加截的token,再刪除這些pod之后,重新加載token文件。
經過測試,這些系統級pod包括但不限於kube-proxy,flannel,kubenetes-dashboard, kube-stat-metricst等所有用到sa認證的pod。