Kubernets Apiserver IP 段变更后的故障处理

集群Service IP 段变更后(从 10.96.0.0/16 变为 10.17.0.0/16),导致 kubernetes.default.svc 的ClusterIP IP (10.96.0.1)和段范围不一样,对于这个情况,需要重建该 svc。

重建方法很简单,删除该 Service,集群会自动创建一个新的,ClusterIP 为 10.17.0.1 的 service。但是如果你和我一样直接这样操作,那大概率会遇到和我一样的坑。

这个是 集群内的服务访问apiserver 的主要方式。这个时候,几乎集群内需要和 apiserver 交互的功能和服务都不能正常使用。因为它们还是要和以前的 Service IP 进行通讯。

比如 calico-node 就开始出现问题、如创建销毁 pod的过程 要和calico-node通讯。一连串地炸了。

重建 apiserver 和 calico-node 后,发现 calico-node 起不来,发现它还是连接到老的 ClusterIP,于是修改它的环境变量指定正确的 Apiserver IP。

可以通过加入环境变量到 calico-node demonset 中,指定 IP 和端口

1
2
3
KUBERNETES_SERVICE_HOST:是k8s的kubernetes服务的serviceIP
KUBERNETES_SERVICE_PORT: 是k8s的kubernetes服务的端口号
KUBERNETES_SERVICE_PORT_HTTPS:是k8s的kubernetes服务的https端口号

于是编辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
kubectl edit daemonset calico-node -n kube-system
# 发现存在以下映射自 configmap 的环境变量kubernetes-services-endpoint,但是 configmap 并不存在
- configMapRef:
name: kubernetes-services-endpoint
# 我就没直接加到demonset里面,创建了对应的configmap
# 创建 ep.yaml 内容如下
apiVersion: v1
data:
KUBERNETES_SERVICE_HOST: 10.1.15.121
KUBERNETES_SERVICE_PORT: "6443"
KUBERNETES_SERVICE_PORT_HTTPS: "6443"
kind: ConfigMap
metadata:
name: kubernetes-services-endpoint
namespace: kube-system

kubectl apply -f ep.yaml

提交后calico-node 能顺利起来了,但是其它服务还是有问题。

上面 10.1.15.121 是我的 apiserver master 的 IP,为什么不写集群内的 Service ClusterIP 呢?当时改过为正确的新 IP,但是还是无法启动,因为证书里没含有新的集群 IP,然后就写这个了。证书当时每个 master 的 api 和负载均衡的域名都加进去了。

它正常后,pod 创建是没问题了,但是一些核心的服务还是有问题的。因为通过 Service 拿到的新 IP 10.17.0.1 不在 apiserver 的证书里面。

查看证书 SANs 命令

1
for i in $(find /etc/kubernetes/pki -type f -name "*.crt");do echo ${i} && openssl x509 -in ${i} -text | grep 'DNS:';done

于是到这一步就需要重新生成集群证书并把新 IP 加进去了。

以下是基于集群是 kubeadm 安装的前提

  1. 编辑 cm 加入

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    kubectl edit cm -n kube-system kubeadm-config
    ClusterConfiguration: |
    apiServer:
    certSANs:
    - 127.0.0.1
    - apiserver.cluster.local
    - 10.103.97.2
    - 10.1.15.121
    - 10.1.15.122
    - 10.1.15.123
    - 10.17.0.1
  2. 备份和删除本地证书

    1
    2
    3
    cp -r /etc/kubernetes /etc/kubernetes-bak
    rm -rf /etc/kubernetes/pki/{apiserver*,front-proxy-client*}
    rm -rf /etc/kubernetes/pki/etcd/{healthcheck*,peer*,server*}
  3. 生成新的证书

    1
    kubeadm init phase certs all --config kubeadmin-config.yaml
  4. 在每个 master node 重复 2~3 步骤

  5. 完成后,重建 apiserver 后 集群就正常了

总结

换 IP 段后,要及时生成新的 apiserver 的 Service ClusterIP 到证书 SANs 里。然后再重建 kubernetes.default.svc 。最后我把 kubernetes-services-endpoint configmap 的 IP 改为正确的 Service cluster IP 并重建了 calico-node。

关注公众号 尹安灿