导入集群时,cattle-cluster-agent
报错如下:
time="2022-06-28T08:00:28Z" level=error msg="Issuer of last certificate found in chain (CN=xmh-k8s-ca,OU=systemGroup,O=k8s,L=HD,ST=BJ,C=CN) does not match with CA certificate Issuer (CN=dynamiclistener-ca,O=dynamiclistener-org). Please check if the configured server certificate contains all needed intermediate certificates and make sure they are in the correct order (server certificate first, intermediates after)"
time="2022-06-28T08:00:28Z" level=fatal msg="Certificate chain is not complete, please check if all needed intermediate certificates are included in the server certificate (in the correct order) and if the cacerts setting in Rancher either contains the correct CA certificate (in the case of using self signed certificates) or is empty (in the case of using a certificate signed by a recognized CA). Certificate information is displayed above. error: Get \"https://rch.72.xmh\": x509: certificate signed by unknown authority"
最开始用kubeadm搭建了v1.21.2
的k8s,后来又搭建了v1.22.6
版本的k8s(也是用kubeadm),为了方便说明,下文以k8s21
和k8s22
指代。
在搭建k8s22
时用的是已有的tls证书,搭建之后还用同样的ca证书部署了cert-manager
(v1.7.1),并用同样的ca证书创建了ClusterIssuer
,然后部署rancher
(2.6.4)的时候,让cert-manager
给rancher
的ingress
颁发了证书。
背景交代完了,当我突发奇想,想把k8s21
统一让k8s22
管理时,问题出现了。
首先是把搭建k8s22
时的ca证书安装到k8s21
的每个node上,然后在k8s21
的管理节点上执行rancher页面上提示的命令成功,接下来就但是了——cattle-cluster-agent
出现了本文最开始的报错。
当时第一反应是ca证书只安装给node是不够的的,还得安装到需要它的pod,于是一顿操作把ca证书挂载到了pod的/etc/ssl/certs/xmh-k8s-ca.crt
路径下。具体步骤如下:
先把ca证书保存到configMap中
kubectl -n cattle-system create cm xmh-k8s-ca.pem --from-file=xmh-k8s-ca.crt
再把configMap挂载到deployment
# 有删减
apiVersion: apps/v1
kind: Deployment
metadata:
name: cattle-cluster-agent
namespace: cattle-system
spec:
template:
spec:
containers:
volumeMounts:
- mountPath: /etc/ssl/certs/xmh-k8s-ca.crt
name: xmh-k8s-ca
subPath: xmh-k8s-ca.crt
volumes:
- configMap:
name: xmh-k8s-ca.crt
name: xmh-k8s-ca
等pod起来之后看看状态,你猜怎么着我的老baby,这事要是这么简单就完了你就看不到这篇记录了,报错依旧,继续排查。
回想当时给ca证书安装到node时,执行了update-ca-trust
命令,那么安装到pod是不是挂载之后也需要执行呢?结果是update-ca-trust
命令不存在,但是有update-ca-certificates
,但是也报错了:p11-kit: couldn't remove file: /var/lib/ca-certificates/pem/xmh-k8s-ca.crt: Device or resource busy
这里执行的命令是
kubectl -n cattle-system logs -f cattle-cluster-agent-5fd7b889f6-w4zzr -c init-ca
,因为cluster-register
这个容器无处下手,想在初始化容器中调通了再想办法替换证书。
注意这个报错说的是/var/lib/ca-certificates/pem/xmh-k8s-ca.crt
,而我挂载的路径是/etc/ssl/certs/xmh-k8s-ca.crt
,说明ca证书是生效了的,那又是怎么回事呢?
在研究怎么给cluster-register
开刀的过程中,发现它镜像的entryPoint
是run.sh
,然后就看了一下run.sh
干了啥,你猜怎么着我的老baby,破案了啊!
run.sh
的最后有这么一段:
mkdir -p /etc/kubernetes/ssl/certs
mv $temp /etc/kubernetes/ssl/certs/serverca
chmod 755 /etc/kubernetes/ssl
chmod 700 /etc/kubernetes/ssl/certs
chmod 600 /etc/kubernetes/ssl/certs/serverca
mkdir -p /etc/docker/certs.d/$CATTLE_SERVER_HOSTNAME_WITH_PORT
cp /etc/kubernetes/ssl/certs/serverca /etc/docker/certs.d/$CATTLE_SERVER_HOSTNAME_WITH_PORT/ca.crt
发现新大陆了啊,/etc/kubernetes/ssl/certs
这个路径才是有用的啊,于是一顿操作又把ca证书的挂载点干到了这个路径下,你猜怎么着我的老baby,那个粘人的小报错还在屏幕上看着我……
所以说要克制不要激动,静下来仔细看看这个run.sh
,还有这么一段:
curl --insecure -s -fL $CATTLE_SERVER/v3/settings/cacerts | jq -r '.value | select(length > 0)' > $temp
原来这个$temp
是从rancher接口拿过来的啊,于是我想起了rancher全局配置的那个cert,在页面上看到这么句话:
让我删除?众所周知我是个谨慎的有点过头的人,删除是不可能删除的,哑巴治成聋子了可咋整,于是备份之后在api页面打算修改一下,于是看到了这样的response:
readOnly?逗我玩呢?前面说删了,后面说只读?有那么点“大夫说很严重,专家说没事”那味……
我觉得这个是rancher的锅了,于是去官方群艾特官方来解答,你猜怎么着我的老baby,在我尽可能详细的描述完问题并把官方的人艾特一遍之后,果然等到了来自路人甲的一图表情……
好吧自己动手丰衣足食,再来研究研究这个run.sh
,这次还真给我发现了点东西,在找rancher接口要证书之前,有这么一个判断:
if [ -n "$CATTLE_CA_CHECKSUM" ]; then
而cattle-cluster-agent
的环境变量中还真有这么一段:
- name: CATTLE_CA_CHECKSUM
value: 3e5c48a1953664eb7a9f5b452178684d71dd1569f881c8326adfeeb252f2a823
而且run.sh
中给/etc/kubernetes/ssl
和里面的文件做了一堆chmod
,说明这里面应该是有用的,那干脆直接点,把ca证书挂到/etc/kubernetes/ssl/certs/serverca
这个文件上。
于是修改了挂载点,并注释掉CATTLE_CA_CHECKSUM
这个环境变量,等待pod重启之后,你猜怎么着我的老baby……
收工!