添加公网 IP 到 kubernetes 的 apiserver

添加公网 IP 到 kubernetes 的 apiserver

Scroll Down

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的证书都是一年期的,所以要记得手动更新他们