kubeadm---修改apiserver證書有效期
源碼編譯自簽證書:
需要有go環境,從github源碼倉庫拉取k8s對應版本的源碼進行修改/編譯、覆蓋原來的kubeadm即可。
1.查詢證書可用時間
Kubernetes有兩種機制去創建證書,有一部分是1年的,有一部分是10年的
[root@k8s-master ~]# cd /etc/kubernetes/pki/
[root@k8s-master pki]# ls
apiserver.crt apiserver-etcd-client.key apiserver-kubelet-client.crt ca.crt etcd front-proxy-ca.key front-proxy-client.key sa.pub
apiserver-etcd-client.crt apiserver.key apiserver-kubelet-client.key ca.key front-proxy-ca.crt front-proxy-client.crt sa.key
[root@k8s-master pki]# openssl x509 -in apiserver.crt -text -noout |grep Not
Not Before: Apr 5 05:33:55 2021 GMT
Not After : Apr 5 05:33:55 2022 GMT
2.部署Go語言環境
Go中文社區:https://study.golang.com/dl
Go官網:https://golang.org/dl/
cd /opt/src wget https://studygolang.com/dl/golang/go1.16.3.linux-amd64.tar.gz tar zxvf go1.16.3.linux-amd64.tar.gz -C /usr/local/ echo "export PATH=$PATH:/usr/local/go/bin" >> /etc/profile source /etc/profile go version
3.下載源碼
cd /data && git clone https://github.com/kubernetes/kubernetes.git cd kubernetes git checkout -b remotes/origin/release-1.19.0 v1.19.0 #切換當前版本(分支)
4.修改 Kubeadm源碼包更新證書策略
vim staging/src/k8s.io/client-go/util/cert/cert.go # kubeadm 1.14 版本之前 vim cmd/kubeadm/app/util/pkiutil/pki_helpers.go # kubeadm 1.14 至今 const duration365d = time.Hour * 24 * 365 * 20 #在文件中添加一行 設置為20年 NotAfter: time.Now().Add(duration365d).UTC(), #替換 make WHAT=cmd/kubeadm GOFLAGS=-v #設置只編譯kubeadm cp _output/bin/kubeadm /root/kubeadm-new
5.更新 kubeadm
# 將kubeadm 進行替換 cp /usr/bin/kubeadm /usr/bin/kubeadm.old cp /root/kubeadm-new /usr/bin/kubeadm chmod a+x /usr/bin/kubeadm
6.更新各節點至Master節點
cp -r /etc/kubernetes/pki /etc/kubernetes/pki.old cd /etc/kubernetes/pki kubeadm alpha certs renew all --config=/root/kubeadm-config.yaml openssl x509 -in apiserver.crt -text -noout | grep Not
7.HA集群其余 master節點證書更新
#!/bin/bash masterNode="192.168.33.157 192.168.33.167" #for host in ${masterNode}; do # scp /etc/kubernetes/pki/{ca.crt,ca.key,sa.key,sa.pub,front-proxy-ca.crt,front-proxy-ca.key} # "${USER}"@$host:/etc/kubernetes/pki/ # scp /etc/kubernetes/pki/etcd/{ca.crt,ca.key} "root"@$host:/etc/kubernetes/pki/etcd # scp /etc/kubernetes/admin.conf "root"@$host:/etc/kubernetes/ #done for host in ${CONTROL_PLANE_IPS}; do scp /etc/kubernetes/pki/{ca.crt,ca.key,sa.key,sa.pub,front-proxy-ca.crt,front-proxy-ca.key} "${USER}"@$host:/root/pki/ scp /etc/kubernetes/pki/etcd/{ca.crt,ca.key} "root"@$host:/root/etcd scp /etc/kubernetes/admin.conf "root"@$host:/root/kubernetes/ done
手動更新續簽證書:
在操作之前一定要先對證書目錄進行備份,防止操作錯誤進行回滾。
由 kubeadm 生成的客戶端證書默認只有一年有效期,我們可以通過 check-expiration
命令來檢查證書是否過期:
$ kubeadm alpha certs check-expiration CERTIFICATE EXPIRES RESIDUAL TIME EXTERNALLY MANAGED admin.conf Nov 07, 2020 11:59 UTC 73d no apiserver Nov 07, 2020 11:59 UTC 73d no apiserver-etcd-client Nov 07, 2020 11:59 UTC 73d no apiserver-kubelet-client Nov 07, 2020 11:59 UTC 73d no controller-manager.conf Nov 07, 2020 11:59 UTC 73d no etcd-healthcheck-client Nov 07, 2020 11:59 UTC 73d no etcd-peer Nov 07, 2020 11:59 UTC 73d no etcd-server Nov 07, 2020 11:59 UTC 73d no front-proxy-client Nov 07, 2020 11:59 UTC 73d no scheduler.conf Nov 07, 2020 11:59 UTC 73d no
該命令顯示 /etc/kubernetes/pki
文件夾中的客戶端證書以及 kubeadm 使用的 KUBECONFIG
文件中嵌入的客戶端證書的到期時間/剩余時間。
注意: kubeadm
不能管理由外部 CA 簽名的證書,如果是外部得證書,需要自己手動去管理證書的更新。
另外需要說明的是上面的列表中沒有包含 kubelet.conf
,因為 kubeadm 將 kubelet 配置為自動更新證書。
另外 kubeadm 會在控制面板升級的時候自動更新所有證書,所以使用 kubeadm 搭建得集群最佳的做法是經常升級集群,這樣可以確保你的集群保持最新狀態並保持合理的安全性。但是對於實際的生產環境我們可能並不會去頻繁得升級集群,所以這個時候我們就需要去手動更新證書。
要手動更新證書也非常方便,我們只需要通過 kubeadm alpha certs renew
命令即可更新你的證書,這個命令用 CA(或者 front-proxy-CA )證書和存儲在 /etc/kubernetes/pki
中的密鑰執行更新。
注意: 如果你運行了一個高可用的集群,這個命令需要在所有控制面板節點上執行。
接下來我們來更新我們的集群證書,下面的操作都是在 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
接下來執行更新證書的命令:
$ kubeadm alpha certs renew all --config=kubeadm.yaml kubeadm alpha certs renew all --config=kubeadm.yaml certificate embedded in the kubeconfig file for the admin to use and for kubeadm itself renewed certificate for serving the Kubernetes API renewed certificate the apiserver uses to access etcd renewed certificate for the API server to connect to kubelet renewed certificate embedded in the kubeconfig file for the controller manager to use renewed certificate for liveness probes to healthcheck etcd renewed certificate for etcd nodes to communicate with each other renewed certificate for serving etcd renewed certificate for the front proxy client renewed certificate embedded in the kubeconfig file for the scheduler manager to use renewed
通過上面的命令證書就一鍵更新完成了,這個時候查看上面的證書可以看到過期時間已經是一年后的時間了:
$ kubeadm alpha certs check-expiration CERTIFICATE EXPIRES RESIDUAL TIME EXTERNALLY MANAGED admin.conf Aug 26, 2021 03:47 UTC 364d no apiserver Aug 26, 2021 03:47 UTC 364d no apiserver-etcd-client Aug 26, 2021 03:47 UTC 364d no apiserver-kubelet-client Aug 26, 2021 03:47 UTC 364d no controller-manager.conf Aug 26, 2021 03:47 UTC 364d no etcd-healthcheck-client Aug 26, 2021 03:47 UTC 364d no etcd-peer Aug 26, 2021 03:47 UTC 364d no etcd-server Aug 26, 2021 03:47 UTC 364d no front-proxy-client Aug 26, 2021 03:47 UTC 364d no scheduler.conf Aug 26, 2021 03:47 UTC 364d no
然后記得更新下 kubeconfig 文件:
$ kubeadm init phase kubeconfig all --config kubeadm.yaml [kubeconfig] Using kubeconfig folder "/etc/kubernetes" [kubeconfig] Using existing kubeconfig file: "/etc/kubernetes/admin.conf" [kubeconfig] Using existing kubeconfig file: "/etc/kubernetes/kubelet.conf" [kubeconfig] Using existing kubeconfig file: "/etc/kubernetes/controller-manager.conf" [kubeconfig] Using existing kubeconfig file: "/etc/kubernetes/scheduler.conf"
將新生成的 admin 配置文件覆蓋掉原本的 admin 文件:
$ mv $HOME/.kube/config $HOME/.kube/config.old $ cp -i /etc/kubernetes/admin.conf $HOME/.kube/config $ chown $(id -u):$(id -g) $HOME/.kube/config
完成后重啟 kube-apiserver、kube-controller、kube-scheduler、etcd 這4個容器即可,我們可以查看 apiserver 的證書的有效期來驗證是否更新成功:
$ docker restart `docker ps | grep etcd | awk '{ print $1 }'` $ docker restart `docker ps | grep kube-apiserver | awk '{ print $1 }'` $ docker restart `docker ps | grep kube-scheduler | awk '{ print $1 }'` $ docker restart `docker ps | grep kube-controller | awk '{ print $1 }'` systemctl restart kubelet $ echo | openssl s_client -showcerts -connect 127.0.0.1:6443 -servername api 2>/dev/null | openssl x509 -noout -enddate notAfter=Aug 26 03:47:23 2021 GMT
可以看到現在的有效期是一年過后的,證明已經更新成功了。