kevendeng 你好! 感谢您的再次帮助,我发现了一个问题, ipvsadm -ln查看异常节点的转发规则:

这个是指向master的内网地址的,不是服务器vpn地址, 请问需要如何解决?

    heming
    你所建立的VPN是否为整个集群所有节点共享的?
    如果是,将Service指向Master的VPN地址

    kubectl edit endpoints kubernetes

    将其中的内网地址修改为VPN地址

      heming
      是的,这应该是Endpoint Controller所控制的。

      尝试在Master节点上找到kubelet的启动参数配置文件,如果你是使用KubeKey安装的KS,这个文件应该位于/etc/systemd/system/kubelet.service.d/10-kubeadm.conf

      将其中的node-ip,目前应该是该节点的内网IP,修改为其在VPN中的IP,保存该文件,并重启kubelet与docker:

      systemctl daemon-reload
      systemctl restart kubelet
      systemctl restart docker

        kevendeng 好奇怪,我改了配置后,master的节点ip也变成VPN地址了, 但是修改kubectl edit endpoints kubernetes还是会变回来, ipvs还是把10.147.20.1 映射到 master内网ip, 我也重启了所有节点,还是这样…

          heming
          那或许这个endpoint对象是由另外的参数配置的,kubelet的node-ip参数仅仅是控制hostNetwork模式下pod的ip。

          我能想到的两个地方还有kube-apiserver与kube-controller-manager,你可以先尝试把kube-apiserver中对应的地址改为VPN的IP,该文件位于主节点的/etc/kubernetes/manifests/kube-apiserver.yaml下,可以直接使用搜索与替换,保存后kube-apiserver会自动重启。

            kevendeng 感谢dalao帮忙! 让我学到很多关于k8s网络的知识, 我总结了一下:

            首先是两个网络, 节点网络pod网络(10.233.0.0/18)( k8s要求节点网络中所有节点都是互通的,
            因为我是先在服务器内网部署k8s的, 所以主节点的ip就是它的内网ip, 节点网络就是服务器内网,
            后来我搭建vpn想将本地机器添加进集群, 于是就多了一个vpn网络和主节点的vpnIP,
            在我通过vpn在本地节点使用kubeadm join加入集群后,
            kubeadm帮我安装和配置work节点需要的pod,
            此处有误已由kevendeng在楼下补充:
            在kubeadm配置kube-proxy的时候应该是需要从apiserver获取主节点ip的, ( apiserver使用的主节点IP通过 --advertise-address 参数设置 (/etc/kubernetes/manifests/kube-apiserver.yaml

            于是就获取了主节点ip(内网ip)并设置进kube-proxy了,
            我的kube-proxy再设置ipvs, 将10.233.0.1映射到主节点内网ip而不是vpn ip,
            所以就导致本地节点的pod无法通过10.233.0.1去访问apiserver. ( 例如我的问题calico-node这个pod无法请求10.233.0.1:443 timeout.
            于是在@kevendeng dalao的指导下,
            我通过设置/etc/systemd/system/kubelet.service.d/10-kubeadm.conf和/etc/kubernetes/manifests/kube-apiserver.yaml将集群使用的节点网络从服务器内网切换成vpn就解决了.
            最好确定集群节点使用的是什么网络, 要添加节点时要将节点加入进这个网络, 而不是新建一个网络.

            在我理解的在pod网络中,不同节点的pod的通信路径:
            节点1-pod1, 节点2-pod2

            此处有误已由kevendeng在楼下补充:
            pod1要访问pod2:
            pod1 -> kube-proxy1 -> 节点2 -> kube-proxy2 -> pod2

            如有错误请指出,非常感谢!
            再次感谢@kevendeng dalao的帮助!!!

              heming
              不客气,每一次Debug让我自己对K8s的了解也多了一分。

              你的理解大体上是正确的,有一些细节错误,如:

              在kubeadm配置kube-proxy的时候应该是需要从apiserver获取主节点ip的, ( apiserver使用的主节点IP通过 –
              advertise-address 参数设置 (/etc/kubernetes/manifests/kube-apiserver.yaml
              于是就获取了主节点ip(内网ip)并设置进kube-proxy了,

              实际上,此Endpoint对象是由apiserver定期更新的。
              kubernetes Service IP 到 此Endpoint IP的IPVS转发规则是由kube-proxy观察到该对象后创建的。

              以及:

              pod1要访问pod2:
              pod1 -> kube-proxy1 -> 节点2 -> kube-proxy2 -> pod2

              这并不是全部情况。在K8s集群内部,主要有两个网段,一种是Pod,一种是Service,若Pod之间通过IP/(非Service)域名互相访问,并不会通过kube-proxy所设置的转发。

              这些概念,以及底层运行原理,需要对K8s的网络模型更加熟悉,K8s的官方文档是一个很好的参考资料。

              你提到的这一点:

              最好确定集群节点使用的是什么网络, 要添加节点时要将节点加入进这个网络, 而不是新建一个网络.

              确实应该这样做,网络规划应该在部署集群之前完成,如果不得不跨网络运行,VPN也应该在部署集群之前建立。

              以及:建议你为此贴的标题补充上更加详细的描述,如“K8s集群部署后,通过建立VPN网络加入外部节点”,以便其他遇到类似问题的同学搜索。

                heming 更改标题为「通过建立VPN网络向集群加入外部节点所遇到的问题

                kevendeng 你好, 我有一点不太明白,pod之间通过它们ip相互访问的话, 如果不转发, 如何跨节点访问?

                这并不是全部情况。在K8s集群内部,主要有两个网段,一种是Pod,一种是Service,若Pod之间通过IP/(非Service)域名互相访问,并不会通过kube-proxy所设置的转发。

                  heming
                  K8s要求不同容器,不同节点之间都能互相访问,但并不指定实现方式,不同的CNI插件实现各有不同,常见的如VXLAN或者BGP,具体内容可以学习下CNI相关知识。

                    6 天 后