对于跨云服务商进行k8s集群, 其中遇到了一些网络相关的问题, 比如

  1. 集群采用的是内网IP的方式构建的, 如何能够在另一台服务器中加入集群, 他们的IP是不互通的;
  2. 加入集群后, 网络插件却不能正常工作, 应该如何处理?

这些问题 一直困扰了很久, 多番查阅资料后有了一些解决方案, 这里进行相关的一些记录

最终解决方案: 给外网IP配置虚拟网卡
以下方法仅供参考, 虽然能成功, 但是配置复杂, 且很多地方会存在小问题并不好用

集群采用的是内网IP的方式构建的, 如何能够在另一台服务器中加入集群

请点击: kubeadm创建单个节点的方法
在通过kubeadm创建集群时, 一般我们指定的apiserver-advertise-address均是云服务器的内网IP, 比如:

kubeadm init \
--apiserver-advertise-address=10.0.16.7 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.20.0 \
--service-cidr=10.1.0.0/16 \
--pod-network-cidr=10.244.0.0/16

创建成功后, 会提示加入集群的命令:

kubeadm join 10.0.16.7:6443 --token iszdrw.jfui56nuckwk5ox4 \
--discovery-token-ca-cert-hash sha256:0396d14ed025cacc620368efb12d62ff2c9e532a63391958eb185e151d1df913

而对于另一台云服务器来说, 10.0.16.7这个地址是不可达的; 因此无法进行集群添加操作;

那如何解决这个问题呢?
我想到一下两种方式:

  1. 将集群的api server地址变为公网IP;
  2. 配置路由转发

对于方法1, 经过尝试, 我放弃了…, 因为变更后创建集群失败; 查阅了一些资料: 说是需要在创建过程中, 快速修改/etc/kubenetes/manifests/kube-apiserver.yaml文件, 将其中的IP修改成公网IP, 或者是为公网IP配置虚拟网卡(未尝试); 对于个人来说, 修改相关的安装文件且还要看时机的方式实在是不靠谱; 可能我还未领悟到这种方式的精髓, 但是算了吧, 不是我喜欢的style.

对于第二中方式, 相对就比较简单了, 且独立性高;
对于从服务器请求主服务器时:

  1. 在从服务器上的配置: 将主服务器的内网OUTPUT流量转发到主服务器的外网OUTPUT上;
  2. 在主服务器上的配置: 将主服务器外网OUTPUT流量转发到主服务器内网OUTPUT上;

对于主服务器请求从服务器时:

  1. 在主服务器上的配置: 将从服务器的内网OUTPUT流量转发到从服务器的外网OUTPUT上;
  2. 在从服务器上的配置: 将从服务器的外网OUTPUT流量转发到从服务器的内网OUTPUT上;

通过以上方式就完成了服务器内网IP的通信; 具体命令如下:

# 从节点配置
iptables -t nat -A OUTPUT -d 主节点内网IP -j DNAT --to-destination 主节点外网IP
iptables -t nat -A OUTPUT -d 从节点外网IP -j DNAT --to-destination 从节点内网IP

# 主节点配置
iptables -t nat -A OUTPUT -d 主节点外网IP -j DNAT --to-destination 主节点内网IP
iptables -t nat -A OUTPUT -d 从节点内网IP -j DNAT --to-destination 从节点外网IP

完成配置后, 网络已经通畅, 那么直接调用相关的加入集群命令即可:

kubeadm join 10.0.16.7:6443 --token iszdrw.jfui56nuckwk5ox4 \
--discovery-token-ca-cert-hash sha256:0396d14ed025cacc620368efb12d62ff2c9e532a63391958eb185e151d1df913

加入集群后, 网络插件却不能正常工作, 应该如何处理?

对于这个问题, 我开始是怀疑是插件的问题, 我先后尝试了weaveflannel, 结果都是如此;
现象:
始终存在一个网络插件的容器会启动不起来, 通过kubectl logs pod/weave-xxx -n kube-system -c weave 查看, 总是提示:

FATA: 2021/12/28 09:32:09.745861 [kube-peers] Could not get peers: Get "https://172.1.0.1:443/api/v1/nodes": dial tcp 172.1.0.1:443: i/o timeout
Failed to get peers

超时…那估计就是网络问题了; 正常情况肯定是能正常访问了; 容器是部署在从节点上的, 那么我们需要去看下从节点的iptables了, 下面提取相关的一些链路跳转:

> iptables-save
# 从服务器上自主配置的转发规则
-A OUTPUT -d 121.43.144.10/32 -j DNAT --to-destination 172.26.45.223
-A OUTPUT -d 10.0.16.7/32 -j DNAT --to-destination 101.43.30.250
# 网络插件创建的相关规则
-A PREROUTING -m comment --comment "kubernetes service portals" -j KUBE-SERVICES
-A OUTPUT -m comment --comment "kubernetes service portals" -j KUBE-SERVICES
-A KUBE-SEP-DFOBGGADT3452T2Z -s 10.0.16.7/32 -m comment --comment "default/kubernetes:https" -j KUBE-MARK-MASQ
-A KUBE-SEP-DFOBGGADT3452T2Z -p tcp -m comment --comment "default/kubernetes:https" -m tcp -j DNAT --to-destination 10.0.16.7:6443
-A KUBE-SERVICES -d 172.1.0.1/32 -p tcp -m comment --comment "default/kubernetes:https cluster IP" -m tcp --dport 443 -j KUBE-SVC-NPX46M4PTMTKRN6Y
-A KUBE-SVC-NPX46M4PTMTKRN6Y -m comment --comment "default/kubernetes:https" -j KUBE-SEP-DFOBGGADT3452T2Z

可以看到OUTPUT流量最终转发到了 10.0.16.7:6443上面, 而这个IP是主节点的内网IP;
这条链路到此已经结束, 和我们自主在从节点上配置的OUTPUT是独立的两条链路(这个点我开始以为会接着走自主配置链路, 事实上并不会),
因此网络依然是不通畅的;
所以, 我们就只有想办法把这条链路打通即可, 目前我还没有找到可以软配置的方式进行开放, 只想到一种比较粗暴的方式来实现:
那就是: KUBE-SEP-DFOBGGADT3452T2Zto-destination修改为主节点的 [外网IP:端口]

> iptables -t nat -nvL --line-numbers
Chain KUBE-SEP-DFOBGGADT3452T2Z (1 references)
num   pkts bytes target     prot opt in     out     source               destination         
1        0     0 KUBE-MARK-MASQ  all  --  *      *       10.0.16.7            0.0.0.0/0            /* default/kubernetes:https */
2       69  4140 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/kubernetes:https */ tcp to:10.0.16.7:6443

# 根据行号删除对应的行
> iptables -t nat -D KUBE-SEP-DFOBGGADT3452T2Z 2
# 添加新的规则
iptables -t nat -A KUBE-SEP-DFOBGGADT3452T2Z -p tcp -m comment --comment "default/kubernetes:https" -m tcp -j DNAT --to-destination 101.43.30.251:6443

最后手动去将退出的weave容器启动起来即可

root@ali-jp:~# docker ps -a |grep weave
fc4e8023ad4a   df29c0a4002c                                        "/home/weave/launch.…"   5 minutes ago    Exited (1) 4 minutes ago              k8s_weave_weave-net-2ssvw_kube-system_a6e6fa25-8f1
root@ali-jp:~# docker start fc4e8023ad4a
fc4e8023ad4a

再去kubelet中查看所有容器, 已经正常启动了;
这个问题目前还没有发现更好的解决方案;
如果你有, 希望能告知我, 十分感谢…

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐