0、导
通常情况下,我们的 kubernetes 集群是内网环境,如果希望通过本地访问这个集群,怎么办呢?
使用kubeadm初始化的集群会为管理员生成一个kubeconfig文件,如果把它下载下来,再远程端主机直接使用可不可以?答案是不行,因为这个集群是内网集群,Kubeconfig文件中kube-apiserver的地址是内网 IP。所以无法访问到。
那么我把内网ip改成 kube-apiserver公网 IP是不是就可以了呢?经过实验发现也是不可以的,会报出认证无法通过的错误
Unable to connect to the server: x509: certificate is valid for ... , not ....
。为什么认证无法通过?这要回顾kubernetes服务端认证的流程: 任意一个客户端想访问kube-apiserver时,要拿服务器证书进行解析,去看kube-apiserver都有哪些别名,再把客户端访问kube-apiserver时所采用的 IP 或者 域名和别名 相比较,看是否已经涵盖在别名里面了。如果涵盖进去,就认为这个server是可认证的。由于现在已经部署出来的集群中,Kubeadm生成 APIServer证书时没有把公网 IP写到证书里,所以导致用公网 IP访问不通过验证。默认情况下已经签发的证书表明,可访问的是 k8s集群监听的内网IP、kubernetes、kubernetes.default kubernetes.default.svc、kubernetes.default.svc.cluster.local,但不包含集群的外网IP
解决方案很简单,把需要用到的公网 IP 签到API Server证书里面就可以了,既可以通过命令行方式完成写入,参数名称是
--apiserver-cert-extra-sans
,也可以通过kubeadm的yaml资源清单写入,资源清单中这个选项叫apiServerCertSANs
。只要把需要的公网 IP 签到kube-apiserver的证书中,再启动这个集群的时候,外部就可以通过集群的公网IP + 端口 与kube-apiserver进行认证了。
需要注意的是,如果是在生产环境使用该方法请仔细思考,谨慎处理。因为修改过程需要重启 kube-apiserver
。如果集群非高可用形式,重启kube-apiserver可能会导致服务有一定中断时间,最好在业务低峰时操作。如果是高可用形式,逐一重复执行签公网IP到kube-apiserver证书的操作并重启kube-apiserver即可。
1、实际处理
1.1 查看kube-apiserver的证书包含的IP
# cd /etc/kubernetes/pki/
# openssl x509 -noout -text -in apiserver.crt | grep -C 2 DNS
TLS Web Server Authentication
X509v3 Subject Alternative Name:
DNS:k8s-master-01, DNS:kubernetes, DNS:kubernetes.default, DNS:kubernetes.default.svc, DNS:kubernetes.default.svc.cluster.local, IP Address:10.96.0.1, IP Address:192.168.1.31
Signature Algorithm: sha256WithRSAEncryption
15:6d:23:c3:17:a3:0b:b3:79:a7:f3:09:1d:3f:f4:8e:19:e4:
1.2 备份老的kube-apiserver证书
# cd /etc/kubernetes/pki
# mv /etc/kubernetes/pki/apiserver.crt /etc/kubernetes/pki/apiserver.crt.bak
# mv /etc/kubernetes/pki/apiserver.key /etc/kubernetes/pki/apiserver.key.bak
1.3 查看kube-apiserver的监听地址
记住kube-apiserver的监听地址
#cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep "advertise-address="
1.4 通过kubeadm命令行参数–apiserver-cert-extra-sans添加公网IP到kube-apiserver
// 原来的advertise address可能是一个内部解析,可能是一个虚拟的内部ip,也可能是一个一个具体的节点ip,视自身情况而定
# kubeadm init phase certs apiserver --apiserver-advertise-address ${原来的advertise address} --apiserver-cert-extra-sans ${master的外网ip}
1.5 刷新admin.conf kubeconfig文件
// admin.conf 默认会保存在 /etc/kubernetes/下
# kubeadm alpha certs renew admin.conf
1.6 重启kube-apiserver
# docker ps | grep apiserver
# docker rm -f ****
// kubelet会立刻拉起一个新的apiserver,重新查看apiserver状态
#docker ps | grep apiserver
1.7 替换用户.kube目录下的kubecofig文件并完成验证
kubectl使用的配置文件名称是自己在bash或zsh、sh中定义的,这里是config文件
# cp /etc/kubernetes/admin.conf /root/.kube/config
# kubectl get node
1.8 查看新证书的有效期
# kubeadm alpha certs check-expiration
[check-expiration] Reading configuration from the cluster...
[check-expiration] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'
CERTIFICATE EXPIRES RESIDUAL TIME CERTIFICATE AUTHORITY EXTERNALLY MANAGED
admin.conf May 31, 2023 10:34 UTC 364d no
apiserver May 31, 2023 10:34 UTC 364d ca no
apiserver-etcd-client May 28, 2032 08:37 UTC 9y etcd-ca no
apiserver-kubelet-client May 28, 2032 08:37 UTC 9y ca no
controller-manager.conf May 28, 2032 08:37 UTC 9y no
etcd-healthcheck-client May 28, 2032 08:37 UTC 9y etcd-ca no
etcd-peer May 28, 2032 08:37 UTC 9y etcd-ca no
etcd-server May 28, 2032 08:37 UTC 9y etcd-ca no
front-proxy-client May 28, 2032 08:37 UTC 9y front-proxy-ca no
scheduler.conf May 28, 2032 08:37 UTC 9y no
CERTIFICATE AUTHORITY EXPIRES RESIDUAL TIME EXTERNALLY MANAGED
ca Oct 29, 2121 01:55 UTC 99y no
etcd-ca Oct 29, 2121 01:55 UTC 99y no
front-proxy-ca Oct 29, 2121 01:55 UTC 99y no
由上边的返回结果可以看到新生成的admin.conf\apiserver的证书都是一年期的,所以要记得手动更新他们