title: 更新k8s集群证书有效期 #标题tags: k8s #标签
categories: k8s # 分类
date: 2021-04-22

大多数文档,都推荐使用kubeadm来部署k8s集群,但是这种方式与二进制相比而言,有个弊端,就是大多数默认的证书有效期时间只有1年,最好是在初始化集群时,调整下证书有效期(可参考博文部署k8s集群)所以需要考虑证书升级的问题,此文档采用K8s 1.18.3版本,不保证其他版本也适用,建议自行测试。

在操作之前一定要先对证书目录进行备份,防止操作错误进行回滚。此文档记录下两种更新集群证书的方式。

手动更新证书

由 kubeadm 生成的客户端证书默认只有一年有效期,我们可以通过 check-expiration 命令来检查证书是否过期:

  1. $ kubeadm alpha certs check-expiration
  2. [check-expiration] Reading configuration from the cluster...
  3. [check-expiration] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'
  4. CERTIFICATE EXPIRES RESIDUAL TIME CERTIFICATE AUTHORITY EXTERNALLY MANAGED
  5. admin.conf Jul 19, 2021 09:11 UTC 319d no
  6. apiserver Jul 19, 2021 09:11 UTC 319d ca no
  7. apiserver-etcd-client Jul 19, 2021 09:11 UTC 319d etcd-ca no
  8. apiserver-kubelet-client Jul 19, 2021 09:11 UTC 319d ca no
  9. controller-manager.conf Jul 19, 2021 09:11 UTC 319d no
  10. etcd-healthcheck-client Jul 19, 2021 09:11 UTC 319d etcd-ca no
  11. etcd-peer Jul 19, 2021 09:11 UTC 319d etcd-ca no
  12. etcd-server Jul 19, 2021 09:11 UTC 319d etcd-ca no
  13. front-proxy-client Jul 19, 2021 09:11 UTC 319d front-proxy-ca no
  14. scheduler.conf Jul 19, 2021 09:11 UTC 319d no
  15. CERTIFICATE AUTHORITY EXPIRES RESIDUAL TIME EXTERNALLY MANAGED
  16. ca Jul 17, 2030 09:11 UTC 9y no
  17. etcd-ca Jul 17, 2030 09:11 UTC 9y no
  18. front-proxy-ca Jul 17, 2030 09:11 UTC 9y no
  19. # 由上述输出,可以看到,多数证书的到期时间为 Jul 19, 2021 09:11,有效期还有319天
  20. # 还有三个证书的到期时间是 Jul 17, 2030 09:11,有效期还有9年

上述指令显示/etc/kubernetes/pki目录下的客户端证书及kubeadm 使用的 KUBECONFIG 文件中嵌入的客户端证书的到期时间/剩余时间。

———————————————————————我是分割线————————————————————————————-

补充问题:如果你的集群证书已过期,重启了kubelet又导致了你的apiserver挂了,6443端口已经不在监听,此时你基本无法对集群进行任何操作,包括查询,此时怎么办?

解决:
将你的master所在节点的宿主机时间修改为你证书有效期内的某一天,重启kubelet,搞定,6443成功监听,继续更换证书操作,更换成功后,将时间校准即可。

———————————————————————我是分割线————————————————————————————-

注意:kubeadm 不能管理由外部 CA 签名的证书,如果是外部的证书,需要自己手动去管理证书的更新。

另外需要说明的是上面的列表中没有包含 kubelet.conf,因为 kubeadm 将 kubelet 配置为自动更新证书。

另外 kubeadm 会在master节点升级的时候自动更新所有证书,所以使用 kubeadm 搭建的集群最佳的做法是经常升级集群,这样可以确保你的集群保持最新状态并保持合理的安全性。但是对于实际的生产环境我们可能并不会去频繁的升级集群,所以这个时候我们就需要去手动更新证书。

要手动更新证书也非常方便,我们只需要通过 kubeadm alpha certs renew 命令即可更新你的证书,这个命令用 CA(或者 front-proxy-CA )证书和存储在 /etc/kubernetes/pki 中的密钥执行更新。

注意:如果你运行了一个高可用的集群,你需要将第一台master更新的证书copy到其他master节点。

接下来更新集群证书,下面的操作都是在 master 节点上进行:

备份原有数据

  1. $ kubeadm config view > /root/kubeadm.yaml # 生成集群配置的yaml文件
  2. $ cat kubeadm.yaml # 文件内容如下
  3. apiServer:
  4. extraArgs:
  5. authorization-mode: Node,RBAC
  6. timeoutForControlPlane: 4m0s
  7. apiVersion: kubeadm.k8s.io/v1beta2
  8. certificatesDir: /etc/kubernetes/pki
  9. clusterName: kubernetes
  10. controlPlaneEndpoint: apiserver.demo:6443
  11. controllerManager: {}
  12. dns:
  13. type: CoreDNS
  14. etcd:
  15. local:
  16. dataDir: /var/lib/etcd
  17. imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers
  18. kind: ClusterConfiguration
  19. kubernetesVersion: v1.18.3
  20. networking:
  21. dnsDomain: cluster.local
  22. podSubnet: 10.100.0.1/16
  23. serviceSubnet: 10.96.0.0/16
  24. scheduler: {}
  25. # 备份原有证书
  26. $ mkdir /data/backup -p
  27. $ cp -rp /etc/kubernetes /data/backup/kubernetes_$(date +%F)
  28. $ ls /data/backup/kubernetes_$(date +%F) # 确认备份数据
  29. admin.conf controller-manager.conf kubelet.conf manifests pki scheduler.conf

更新证书

  1. $ kubeadm alpha certs renew all --config=/root/kubeadm.yaml # 更新现有证书
  2. W0904 06:22:46.595339 27700 configset.go:202] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io]
  3. certificate embedded in the kubeconfig file for the admin to use and for kubeadm itself renewed
  4. certificate for serving the Kubernetes API renewed
  5. certificate the apiserver uses to access etcd renewed
  6. certificate for the API server to connect to kubelet renewed
  7. certificate embedded in the kubeconfig file for the controller manager to use renewed
  8. certificate for liveness probes to healthcheck etcd renewed
  9. certificate for etcd nodes to communicate with each other renewed
  10. certificate for serving etcd renewed
  11. certificate for the front proxy client renewed
  12. certificate embedded in the kubeconfig file for the scheduler manager to use renewed

通过上面的命令证书就一键更新完成了,这个时候查看上面的证书可以看到过期时间已经是一年后的时间了:

  1. $ kubeadm alpha certs check-expiration # 查看证书有效期

输出如下:

更新k8s集群证书有效期 - 图1

更新kubeconfig文件

  1. $ rm -f /etc/kubernetes/*.conf
  2. $ kubeadm init phase kubeconfig all --config /root/kubeadm.yaml # 重新生成kubeconfig文件
  3. W0904 06:24:59.387870 29610 configset.go:202] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io]
  4. [kubeconfig] Using kubeconfig folder "/etc/kubernetes"
  5. [kubeconfig] Writing "admin.conf" kubeconfig file
  6. [kubeconfig] Writing "kubelet.conf" kubeconfig file
  7. [kubeconfig] Writing "controller-manager.conf" kubeconfig file
  8. [kubeconfig] Writing "scheduler.conf" kubeconfig file

重启相关pod

在所有Master上执行重启kube-apiserver、kube-controller、kube-scheduler、etcd这4个容器,以便使证书生效。

  1. $ docker ps |egrep "k8s_kube-apiserver|k8s_kube-controller-manager|k8s_kube-scheduler|k8s_etcd_etcd" | awk '{print $1}' | xargs docker rm -f

替换admin文件

  1. $ mv ~/.kube/config{,.old}
  2. $ cp -i /etc/kubernetes/admin.conf ~/.kube/config
  3. $ chown $(id -u):$(id -g) ~/.kube/config

确认指令正常

至此,证书更新就完成了,执行以下指令,可以确认指令是否可以正常执行

  1. $ kubectl get pods -A -o wide

输出如下:

更新k8s集群证书有效期 - 图2

源码编译kubeadm修改证书时间

备份集群配置

  1. $ kubeadm config view > kubeadm-cluster.yaml # 备份
  2. $ kubectl version # 确定其版本
  3. Client Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.3", GitCommit:"2e7996e3e2712684bc73f0dec0200d64eec7fe40", GitTreeState:"clean", BuildDate:"2020-05-20T12:52:00Z", GoVersion:"go1.13.9", Compiler:"gc", Platform:"linux/amd64"}
  4. # 我这里的版本是18.3

修改kubeadm源码并编译

  1. $ wget https://github.com/kubernetes/kubernetes/archive/v1.18.3.tar.gz
  2. $ tar zxf v1.18.3.tar.gz

修改CA证书时间

  1. $ vim kubernetes-1.18.3/staging/src/k8s.io/client-go/util/cert/cert.go
  2. # 跳转至66行,将10修改为100(是将十年的ca证书修改为100年)
  3. 65 NotBefore: now.UTC(),
  4. 66 NotAfter: now.Add(duration365d * 100).UTC(),

具体位置如下:

更新k8s集群证书有效期 - 图3

修改其他证书有效期

  1. $ vim kubernetes-1.18.3/cmd/kubeadm/app/constants/constants.go
  2. # 跳转至49行,修改如下(追加 * 100):
  3. CertificateValidity = time.Hour * 24 * 365 * 100

具体位置如下:

更新k8s集群证书有效期 - 图4

编译kubeadm

可以采用容器运行一个go环境,如果你的宿主机有go环境,则用宿主机进行编译即可。

  1. $ wget https://dl.google.com/go/go1.13.9.linux-amd64.tar.gz
  2. $ tar zxf go1.13.9.linux-amd64.tar.gz -C /opt/
  3. $ cat >> /etc/profile << EOF
  4. export GOROOT=/opt/go
  5. export PATH=\$PATH:\$GOROOT/bin
  6. EOF
  7. $ source /etc/profile
  8. $ go version # 确认版本信息
  9. go version go1.13.9 linux/amd64
  10. $ cd kubernetes-1.18.3/ # 进入kubeadm源码目录
  11. $ make all WHAT=cmd/kubeadm GOFLAGS=-v

执行上述命令后,等待1~2分钟,输入如下:

更新k8s集群证书有效期 - 图5

替换kubeadm指令

  1. $ mv /usr/bin/kubeadm{,.bak}
  2. $ cp _output/local/bin/linux/amd64/kubeadm /usr/bin/

更新集群证书

  1. $ kubeadm config view > kubeadm-cluster.yaml
  2. # 如果有多个master节点,请将 kubeadm-cluster.yaml 文件和编译后的kubeadm指令发送至其他master节点
  3. # 更新证书(若有多个master,则需要在所有master上执行)
  4. $ kubeadm alpha certs renew all --config=kubeadm-cluster.yaml
  5. W0904 07:23:15.938694 59308 configset.go:202] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io]
  6. certificate embedded in the kubeconfig file for the admin to use and for kubeadm itself renewed
  7. certificate for serving the Kubernetes API renewed
  8. certificate the apiserver uses to access etcd renewed
  9. certificate for the API server to connect to kubelet renewed
  10. certificate embedded in the kubeconfig file for the controller manager to use renewed
  11. certificate for liveness probes to healthcheck etcd renewed
  12. certificate for etcd nodes to communicate with each other renewed
  13. certificate for serving etcd renewed
  14. certificate for the front proxy client renewed
  15. certificate embedded in the kubeconfig file for the scheduler manager to use renewed

更新kubeconfig文件

  1. $ rm -f /etc/kubernetes/*.conf
  2. $ kubeadm init phase kubeconfig all --config kubeadm-cluster.yaml
  3. W0904 07:25:41.882636 61426 configset.go:202] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io]
  4. [kubeconfig] Using kubeconfig folder "/etc/kubernetes"
  5. [kubeconfig] Writing "admin.conf" kubeconfig file
  6. [kubeconfig] Writing "kubelet.conf" kubeconfig file
  7. [kubeconfig] Writing "controller-manager.conf" kubeconfig file
  8. [kubeconfig] Writing "scheduler.conf" kubeconfig file

重启相关pod

在所有Master上执行重启kube-apiserver、kube-controller、kube-scheduler、etcd这4个容器,以便使证书生效。

  1. $ docker ps |egrep "k8s_kube-apiserver|k8s_kube-controller-manager|k8s_kube-scheduler|k8s_etcd_etcd" | awk '{print $1}' | xargs docker restart

替换admin文件

  1. $ mv ~/.kube/config{,.old}
  2. $ cp -i /etc/kubernetes/admin.conf ~/.kube/config
  3. $ chown $(id -u):$(id -g) ~/.kube/config

确认指令正常

至此,证书更新就完成了,执行以下指令,可以确认指令是否可以正常执行

  1. $ kubectl get pods -A -o wide

查看证书有效期

  1. $ kubeadm alpha certs check-expiration

输出如下:

更新k8s集群证书有效期 - 图6