heming
从路由表及kube-proxy的日志来看,它已经处于正常运行状态了,现在还有什么问题?

heming
现在kube-proxy已经正常运行了,应该检查calico的日志,理论上它应该可以通过10.233.0.1访问到kube-apiserver了。

    kevendeng 你好, calico 还是无法使用

    那个异常节点和calico的pod不能访问https://10.233.0.1:443, 但是都能访问https://主节点IP:6443, kube-proxy日志也没有异常信息,甚至日志从启动以来就没变化, 请问是什么原因会造成这种结果呢?

      heming
      10.233.0.1是K8s集群的虚拟Service IP,指向主节点的真实IP,而这个映射关系是由kube-proxy通过创建ipvs转发规则实现的。

      执行命令 ipvsadm -ln | grep 10.233.0.1 检查是否有从 10.233.0.1:443主节点IP:6443 的映射,若没有此规则,说明kube-proxy仍未正常工作,需要再次检查其日志是否有异常。

        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 天 后