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
可以看到现在的有效期是一年过后的,证明已经更新成功了。