背景:
之前在阿里云主机上使用kubeadm安装的kubernates(版本号为:1.8.3),使用了一年以后,突然出现问题。
问题状态为不管使用kubectl 的什么指令,都报出以下的异常:
Unable to connect to the server: x509: certificate has expired or is not yet valid
通过异常关键字查询,最后定位是默认安装中,kubenates的apiserver与kubelet的访问授信证书是一年,官方的说法是通过这种方式,让用户不断的升级版本。现在这套环境上跑着用户的生产环境,不可能去做升级或是重装的事情,这个影响太大了,所以需要在不重装kubernates的前提上,把这个问题解决掉。
思路
方案1
源码去掉证书判定逻辑,重新编译
这个方式没有验证,但需要下载对应版本的源码,重新编译相应组件。这个方式如果是与原作者的k8s版本一致可以试一下,或是对go语言熟悉的用户可以找对应的处理逻辑代码进行修改。
方案2
重新生成证书
其中有位大胡子说:
备注:因为内容太多,这里没有办法截图完整方案,可以通过链接自己查看。大概意思就是说他是1.8以下版本的k8s集群环境,按照以下步骤可以解决问题。并且有多人回复说按照大胡子的方式处理已经成功解决问题。
楼下出现一个小人说:
大概意思就是说他是非集群的环境,按照大胡子的1-6步损伤也成功了。
解决
有了上面的方案做参照,就有了自己的思路。基于本人的实际情况。还是考虑使用方案2的方式来解决,只是根据自己的情况对步骤进行裁减,最后问题得到了解决。下面将环境,处理步骤以操作过程中出现的问题叙述如下:
环境
在阿里云的云主机上使用kubeadm安装的1.8.3版本的单结点的kubernates。
处理步骤
备份证书
sudo mv /etc/kubernetes/pki/apiserver.key /etc/kubernetes/pki/apiserver.key.old
sudo mv /etc/kubernetes/pki/apiserver.crt /etc/kubernetes/pki/apiserver.crt.old
sudo mv /etc/kubernetes/pki/apiserver-kubelet-client.crt /etc/kubernetes/pki/apiserver-kubelet-client.crt.old
sudo mv /etc/kubernetes/pki/apiserver-kubelet-client.key /etc/kubernetes/pki/apiserver-kubelet-client.key.old
sudo mv /etc/kubernetes/pki/front-proxy-client.crt /etc/kubernetes/pki/front-proxy-client.crt.old
sudo mv /etc/kubernetes/pki/front-proxy-client.key /etc/kubernetes/pki/front-proxy-client.key.old
产生新的证书
sudo kubeadm alpha phase certs apiserver --apiserver-advertise-address 127.0.0.1
sudo kubeadm alpha phase certs apiserver-kubelet-client
sudo kubeadm alpha phase certs front-proxy-client
备份老的配置文件
sudo mv /etc/kubernetes/admin.conf /etc/kubernetes/admin.conf.old
sudo mv /etc/kubernetes/kubelet.conf /etc/kubernetes/kubelet.conf.old
sudo mv /etc/kubernetes/controller-manager.conf /etc/kubernetes/controller-manager.conf.old
sudo mv /etc/kubernetes/scheduler.conf /etc/kubernetes/scheduler.conf.old
产生新的配置文件
sudo kubeadm alpha phase kubeconfig all --apiserver-advertise-address 127.0.0.1
确认kubectl正在查找正确的配置文件路径
mv $HOME/.kube/config $HOME/.kube/config.old
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
sudo chmod 777 $HOME/.kube/config
export KUBECONFIG=$HOME/.kube/config
重启kube-apiserver,kube-controller-manager, kube-scheduler
通过docker ps找到kube-apiserver,kube-controller-manager, kube-scheduler容器,然后指令杀掉容器,让他重新加载。
下面以kube-apiserver为例:
docker ps | grep ${keyword}
docker kill -s HUP ${容器ID}
及
备注:
在生成证书时会莫名的访问google的网址,因为google已经被封了,所以会报超时。第一次出现这个异常的时候都快绝望了。
这是因为在kubeadm命令升级master证书时,它也会默认从网上读取一个stable.txt的文件。解决这个问题的办法,就是生成一个集群配置的yaml文件,然后,在运行命令时指定这个Yaml文件即可。
kubeadm config view > cluster.yaml
注:如果已经无法使用该指令生成cluster.yaml文件的情况下,应该可以随便找个文件也是可以的,应该是kubeadm需要一个salt来生成证书信息,这个salt就是这个文件信息。
我的cluster.yaml文件如下:
api:
advertiseAddress: 172.19.197.5
bindPort: 6443
authorizationModes:
- Node
- RBAC
certificatesDir: /etc/kubernetes/pki
cloudProvider: ""
etcd:
caFile: ""
certFile: ""
dataDir: /var/lib/etcd
endpoints: null
image: ""
keyFile: ""
imageRepository: gcr.io/google_containers
kubernetesVersion: v1.8.3
networking:
dnsDomain: cluster.local
podSubnet: 10.244.0.0/16
serviceSubnet: 10.96.0.0/12
nodeName: kubernetes.localdomain
token: ""
tokenTTL: 24h0m0s
unifiedControlPlaneImage: ""
然后在上面的kubeadm alpha phase指令中,都添加config参数,指定生成证书的盐值。如:
sudo kubeadm alpha phase certs apiserver --config /root/cluster.yaml
sudo kubeadm alpha phase certs apiserver-kubelet-client --config /root/cluster.yaml
sudo kubeadm alpha phase certs front-proxy-client --config /root/cluster.yaml
sudo kubeadm alpha phase kubeconfig all --config /root/cluster.yaml