影响

  • 既有服务仍会正常运行;
  • 无法在集群上进行CRUD操作(x509: certificate has expired or is not yet valid);

    问题起源

  • 集群使用kubeadm(1.9.4)安装,其创建的apiserver、controller-manager、kubelet等证书默认只有一年的有效期。官方推荐一年之内至少用kubeadm upgrade更新一次kubernetes系统,更新时也会自动更新证书。不过,在生产环境或者无法连接外网的环境频繁更新kubernetes不太现实。

  • 使用kubeadm alpha phase里的certs和kubeconfig命令。PS: k8s 1.9默认启用了kubelet client证书的自动轮换。

    认识证书

    image.png
证书 说明 是否更新
front-proxy-client.key/front-proxy-client.crt 代理端使用的客户端证书, 用作代用户与kube-apiserver认证
apiserver.key/apiserver.crt kube-apiserver组件持有的服务端证书
apiserver-kubelet-client.key/apiserver-kubelet-client.crt kubelet 组件持有的客户端证书
sa.key/sa.pub kube-proxy/kube-dns/flannel等pod直接使用service account与kube-apiserver进行认证。 service account的密钥是以rsa密钥对形式生成,所以没有过期时间。
如无必要,千万不要生成重新生成sa密钥。因为sa密钥关联到一切系统pod内的进程访问api server时的认证。
如果更新了sa,则需要先重新生成这些pod加截的token,再删除这些pod之后,重新加载token文件。
ca.crt/ca.key 集群根证书 建议不要重新生成ca证书,因为更新了ca证书,集群节点就需要手工操作,才能让集群正常(会涉及重新join)
front-proxy-ca.key/front-proxy-ca.crt 汇聚层(aggregator)根证书 不更新

Prometheus告警

默认告警规则中已存在类似告警,运维同学应重视。
image.png

查看证书有效期

  1. openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -text |grep ' Not '
  2. find /etc/kubernetes/pki/ -type f -name "*.crt" -print|egrep -v 'ca.crt$'|xargs -L 1 -t -i bash -c 'openssl x509 -noout -text -in {}|grep After'

更新证书

NOTE:在多个master均需执行;将advertiseAddress和nodeName替换为相应的值;

1. 获取集群配置

  1. sudo kubeadm config view > cluster.yaml

2. 备份证书和配置

  1. cd /etc/kubernetes
  2. sudo mkdir ./pki_bak
  3. sudo mkdir ./conf_bak
  4. sudo mv pki/apiserver.crt ./pki_bak/
  5. sudo mv pki/apiserver.key ./pki_bak/
  6. sudo mv pki/front-proxy-client.* ./pki_bak/
  7. sudo mv pki/apiserver-kubelet-client.* ./pki_bak/
  8. sudo mv ./admin.conf ./conf_bak/
  9. sudo mv ./kubelet.conf ./conf_bak/
  10. sudo mv ./controller-manager.conf ./conf_bak/
  11. sudo mv ./scheduler.conf ./conf_bak/

3. 制作新证书

使用如下命令时,由于网络环境会报错

  1. sudo kubeadm alpha phase certs apiserver --apiserver-advertise-address ${MASTER_API_SERVER_IP}
  2. unable to get URL "https://dl.k8s.io/release/stable-1.9.txt": connection timed out

故使用集群当前配置制作证书

  1. sudo kubeadm alpha phase certs apiserver --config cluster.yaml
  2. sudo kubeadm alpha phase certs apiserver-kubelet-client --config cluster.yaml
  3. sudo kubeadm alpha phase certs front-proxy-client --config cluster.yaml

4. 制作新配置文件

  1. sudo kubeadm alpha phase kubeconfig all --config cluster.yaml

5. 确认kubectl正在查找正确的配置文件路径

  1. sudo mv $HOME/.kube/config $HOME/.kube/config.old
  2. sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  3. sudo chown $(id -u):$(id -g) $HOME/.kube/config
  4. sudo chmod 777 $HOME/.kube/config

6. 重启容器

  1. docker restart kube-apiserver/kube-controller/kube-scheduler

参阅