大纲
本次测试使用的k8s集群使用 kubeadm创建单master节点 并且 版本为17 操作系统ubuntu18
k8s集群之间的访问会使用到证书,如果使用kubeadm搭建的集群,默认CA证书的有效期为10年,其他组件访问证书的有效期为1年。如果过期后没有更新证书可能会引起k8s集群的不可用
例如使用 kubeadm certs check-expiration命令可以查看当前集群证书情况
注意k8s-17 certs命令还是实验性功能 需要 指定alpha
kubeadm alpha certs check-expiration
证书替换的整体流程如下
注意测试前最好先备份相关证书和配置
1 master节点 /etc/kubernetes文件夹中的 admin.conf ,controller-manager.conf, kubelet.conf ,scheduler.conf 和 pki文件夹中所有证书
2 node节点 /etc/kubernetes文件夹的 kubelet.conf 和 pki文件夹中所有证书
使用 kubeadm alpha certs check-expiration 查看当前证书情况
kubeadm alpha certs check-expiration
手动修改系统时间让证书过期注意需要先关闭ntp (所有节点都执行此命令包括master节点)
timedatectl set-ntp false 关闭ntp (timedatectl set-ntp true 开启ntp)
date -s 04/27/2024 修改系统时间 2024年4月27日
执行kubectl 命令可以看到提示证书过期
使用 kubeadm alpha certs renew all 可以更新所有组件证书
kubeadm alpha certs renew all
执行kubectl get nodes 访问成功
所以 kubeadm alpha certs renew all执行完成后 已经替换了 /root/.kube/config 文件中的证书 进入查看 确实已经自动更新了 (如果没有更新需要手动将admin.conf 替换 config)
cat /root/.kube/config
echo LS0tLS1CRUdJ省略 | base64 -d > c.crt
cfssl certinfo -cert c.crt
证书时间确实更新了1年
关于cfssl的使用可以参考 《使用cfssl为程序添加https证书》
此时执行部署一个nginx pods 发现无法部署
上一步中可以看到kubectl 命令(查询操作)可以使用了,但是部署一个pod确失败了(没有任何响应)!
原因如下:
kubeadm alpha certs renew all命令更新了客户端证书即/root/.kube/config中的证书
访问k8s-apiserver(查询操作)可以通过验证(因为根证书没有变,客户端证书可以通过验证)
但是k8s组件还未重启,内部调用使用的证书还是老证书,所以需要重启k8s组件
关于 /root/.kube/config可以参考 《快速上手k8s权限管理 立即掌握User Role RoleBinding kubeconfig 实战教程》
进入master节点的 /etc/kubernetes/manifests/ 文件夹 稍微修改一下所有组件的配置文件,(配置文件修改后会自动重启组件)
例如修改下timeoutSeconds
然后再重启所有节点的 kubelet.service
systemctl restart kubelet.service
journalctl -fu kubelet
重启后发现kubelet 客户端证书过期
1518 bootstrap.go:265] part of the existing bootstrap client certificate is expired: 2024-02-23 08:13:25 +0000 UTC
1518 server.go:273] failed to run Kubelet: unable to load bootstrap kubeconfig: stat /etc/kubernetes/bootstrap-kubelet.conf: no such file or directory
查看api-server日志也可以看到TLS 握手失败
I0427 00:51:31.877435 1 log.go:172] http: TLS handshake error from 192.168.0.124:56108: EOF
I0427 00:52:22.075177 1 log.go:172] http: TLS handshake error from 192.168.0.124:42214: EOF
I0427 00:53:45.493054 1 log.go:172] http: TLS handshake error from 192.168.0.160:35706: EOF
进入各个节点的 /var/lib/kubelet/pki文件夹 查看kubelet的证书 发现还是老证书 由此可以证明 kubeadm alpha certs renew all命令不会更新kubelet证书
所以此时k8s集群还是不可用状态
这里可以使用admin.conf中的证书信息替换 所有节点的中kubelet.conf 证书信息
即admin.conf中的client-certificate-data 与 client-key-data
替换kubelet.conf client-certificate 与 client-key
kubelet.conf 原始配置
kubelet.conf 替换后
所有节点替换完成后 可以看到 /var/lib/kubelet/pki 文件夹下生成了新的kubelet-client证书
此时再恢复kubelet.conf 中的原始配置即可 (不恢复也可以正常使用)
注意由于改了本地时间所以 使用docker pull 镜像时会出现证书过期 (这个证书和k8s证书无关)
Error response from daemon: Get https://registry-1.docker.io/v2/: x509: certificate has expired or is not yet valid
所以要测试k8s集群是否正常使用只有使用节点本地存在的镜像
创建一个dp.yaml 部署文件 内容如下
注意:imagePullPolicy: Never 镜像拉取策略使用Never 不拉取镜像使用本地镜像
测试部署Pod 访问接口成功
创建service
外网访问Pod 成功