各個證書的過期時間
/etc/kubernetes/pki/apiserver.crt #1年有效期
/etc/kubernetes/pki/front-proxy-ca.crt #10年有效期
/etc/kubernetes/pki/ca.crt #10年有效期
/etc/kubernetes/pki/apiserver-etcd-client.crt #1年有效期
/etc/kubernetes/pki/front-proxy-client.crt #1年有效期
/etc/kubernetes/pki/etcd/server.crt #1年有效期
/etc/kubernetes/pki/etcd/ca.crt #10年有效期
/etc/kubernetes/pki/etcd/peer.crt #1年有效期
/etc/kubernetes/pki/etcd/healthcheck-client.crt #1年有效期
/etc/kubernetes/pki/apiserver-kubelet-client.crt #1年有效期
可用於檢查證書過期時間:
方法1
kubeadm alpha certs check-expiration
方法2
openssl x509 -noout -dates -in /etc/kubernetes/pki/apiserver.crt
kubeadm alpha certs 命令詳解:
Available Commands:
certificate-key 生成證書和key
check-expiration 檢測證書過期時間
renew 續訂Kubernetes集羣的證書
kubeadm alpha certs命令僅支持v1.15及其以上的版本。
kubeadm alpha certs check-expiration
該命令顯示 /etc/kubernetes/pki 文件夾中的客戶端證書以及 kubeadm 使用的 KUBECONFIG 文件中嵌入的客戶端證書的到期時間/剩餘時間。
如果你運行了一個高可用的集羣,這個命令需要在所有控制面板節點上執行。
接下來我們來更新我們的集羣證書,下面的操作都是在 master 節點上進行,首先備份原有證書:
mkdir /etc/kubernetes.bak
cp -r /etc/kubernetes/pki/ /etc/kubernetes.bak
cp /etc/kubernetes/*.conf /etc/kubernetes.bak
然後備份 etcd 數據目錄:
cp -r /var/lib/etcd /var/lib/etcd.bak
用 Kubernetes 證書 API 更新證書
除了上述的一鍵手動更新證書之外,還可以使用 Kubernetes 證書 API 執行手動證書更新。對於線上環境我們可能並不會去冒險經常更新集羣或者去更新證書,這些畢竟是有風險的,所以我們希望生成的證書有效期足夠長,雖然從安全性角度來說不推薦這樣做,但是對於某些場景下一個足夠長的證書有效期也是非常有必要的。有很多管理員就是去手動更改 kubeadm 的源碼爲10年,然後重新編譯來創建集羣,這種方式雖然可以達到目的,但是不推薦使用這種方式,特別是當你想要更新集羣的時候,還得用新版本進行更新。其實 Kubernetes 提供了一種 API 的方式可以來幫助我們生成一個足夠長證書有效期。
要使用內置的 API 方式來簽名,首先我們需要配置 kube-controller-manager 組件的 --experimental-cluster-signing-duration 參數,將其調整爲10年,我們這裏是 kubeadm 安裝的集羣,所以直接修改靜態 Pod 的 yaml 文件即可:
vim /etc/kubernetes/manifests/kube-controller-manager.yaml
......
spec:
containers:
- command:
- kube-controller-manager
#設置證書有效期爲 10 年
- --experimental-cluster-signing-duration=87600h
- --client-ca-file=/etc/kubernetes/pki/ca.crt
......
修改完成後 kube-controller-manager 會自動重啓生效。然後我們需要使用下面的命令爲 Kubernetes 證書 API 創建一個證書籤名請求。如果您設置例如 cert-manager 等外部簽名者,則會自動批准證書籤名請求(CSRs)。否者,您必須使用 kubectl certificate 命令手動批准證書。以下 kubeadm 命令輸出要批准的證書名稱,然後等待批准發生:
kubeadm alpha certs renew all --use-api --config kubeadm.yaml &
輸出類似於以下內容:
[1] 2890
[certs] Certificate request "kubeadm-cert-kubernetes-admin-pn99f" created
#然後接下來我們需要去手動批准證書:
kubectl get csr
NAME AGE REQUESTOR CONDITION
kubeadm-cert-kubernetes-admin-pn99f 64s kubernetes-admin Pending
手動批准證書
kubectl certificate approve kubeadm-cert-kubernetes-admin-pn99f
certificatesigningrequest.certificates.k8s.io/kubeadm-cert-kubernetes-admin-pn99f approved
用同樣的方式爲處於 Pending 狀態的 csr 執行批准操作,直到所有的 csr 都批准完成爲止。最後所有的 csr 列表狀態如下所示:
kubectl get csr
NAME AGE REQUESTOR CONDITION
kubeadm-cert-front-proxy-client-llhrj 30s kubernetes-admin Approved,Issued
kubeadm-cert-kube-apiserver-2s6kf 2m43s kubernetes-admin Approved,Issued
kubeadm-cert-kube-apiserver-etcd-client-t9pkx 2m7s kubernetes-admin Approved,Issued
kubeadm-cert-kube-apiserver-kubelet-client-pjbjm 108s kubernetes-admin Approved,Issued
kubeadm-cert-kube-etcd-healthcheck-client-8dcn8 64s kubernetes-admin Approved,Issued
kubeadm-cert-kubernetes-admin-pn99f 4m29s kubernetes-admin Approved,Issued
kubeadm-cert-system:kube-controller-manager-mr86h 79s kubernetes-admin Approved,Issued
kubeadm-cert-system:kube-scheduler-t8lnw 17s kubernetes-admin Approved,Issued
kubeadm-cert-ydzs-master-cqh4s 52s kubernetes-admin Approved,Issued
kubeadm-cert-ydzs-master-lvbr5 41s kubernetes-admin Approved,Issued
批准完成後檢查證書的有效期:
kubeadm alpha certs check-expiration
CERTIFICATE EXPIRES RESIDUAL TIME EXTERNALLY MANAGED
admin.conf Nov 05, 2029 11:53 UTC 9y no
apiserver Nov 05, 2029 11:54 UTC 9y no
apiserver-etcd-client Nov 05, 2029 11:53 UTC 9y no
apiserver-kubelet-client Nov 05, 2029 11:54 UTC 9y no
controller-manager.conf Nov 05, 2029 11:54 UTC 9y no
etcd-healthcheck-client Nov 05, 2029 11:53 UTC 9y no
etcd-peer Nov 05, 2029 11:53 UTC 9y no
etcd-server Nov 05, 2029 11:54 UTC 9y no
front-proxy-client Nov 05, 2029 11:54 UTC 9y no
scheduler.conf Nov 05, 2029 11:53 UTC 9y no
我們可以看到已經延長小10年了,這是因爲 ca 證書的有效期只有10年。
但是現在我們還不能直接重啓控制面板的幾個組件,這是因爲使用 kubeadm 安裝的集羣對應的 etcd 默認是使用的 /etc/kubernetes/pki/etcd/ca.crt 這個證書進行前面的,而上面我們用命令 kubectl certificate approve 批准過後的證書是使用的默認的 /etc/kubernetes/pki/ca.crt 證書進行簽發的,所以我們需要替換 etcd 中的 ca 機構證書:
先拷貝靜態 Pod 資源清單
cp -r /etc/kubernetes/manifests/ /etc/kubernetes/manifests.bak
vi /etc/kubernetes/manifests/etcd.yaml
......
spec:
containers:
- command:
- etcd
# 修改爲 CA 文件
- --peer-trusted-ca-file=/etc/kubernetes/pki/ca.crt
- --trusted-ca-file=/etc/kubernetes/pki/ca.crt
......
volumeMounts:
- mountPath: /var/lib/etcd
name: etcd-data
- mountPath: /etc/kubernetes/pki # 更改證書目錄
name: etcd-certs
volumes:
- hostPath:
path: /etc/kubernetes/pki # 將 pki 目錄掛載到 etcd 中去
type: DirectoryOrCreate
name: etcd-certs
- hostPath:
path: /var/lib/etcd
type: DirectoryOrCreate
name: etcd-data
......
由於 kube-apiserver 要連接 etcd 集羣,所以也需要重新修改對應的 etcd ca 文件:
vim /etc/kubernetes/manifests/kube-apiserver.yaml
......
spec:
containers:
- command:
- kube-apiserver
# 將etcd ca文件修改爲默認的ca.crt文件
- --etcd-cafile=/etc/kubernetes/pki/ca.crt
......
除此之外還需要替換 requestheader-client-ca-file 文件,默認是 /etc/kubernetes/pki/front-proxy-ca.crt 文件,現在也需要替換成默認的 CA 文件,否則使用聚合 API,比如安裝了 metrics-server 後執行 kubectl top 命令就會報錯:
cp /etc/kubernetes/pki/ca.crt /etc/kubernetes/pki/front-proxy-ca.crt
cp /etc/kubernetes/pki/ca.key /etc/kubernetes/pki/front-proxy-ca.key
由於是靜態 Pod,修改完成後上面的組件都會自動重啓生效。由於我們當前版本的 kubelet 默認開啓了證書自動輪轉,所以 kubelet 的證書也不用再去管理了,這樣我就將證書更新成10有效期了。在操作之前一定要先對證書目錄進行備份,防止操作錯誤進行回滾。