[kubernetes]-Pod无法通过 Service IP 访问自身

Pod 无法通过 Service IP 访问自身

同样的镜像 在自己环境可以跑起来,放到朋友rancher搭建的环境里就出现了pod的cluster ip+ port可以访问,但是通过service ip+port就无法访问的情况。 后来通过修改svc 模式 cluster ip 到load balance解决。具体出现这个问题的原因,没有去查证。朋友的环境是一主一从,具体环境已经无法验证了。看到这个issue,现象比较相似 记录一下 方便后续自己出现问题的排查。

以下是借鉴的案例

  • 网络环境:Calico CNI
  • kube-proxy 模式:ipvs

具体问题描述就是,当 Pod 通过自身 Service IP 访问的时候,如果 kube-proxy 刚好调度的实例是 Pod 自身的话,这个时候就出现无法访问的问题。

排查过程网上搜索的资料都是指向 kubelet --hairpin-mode 配置(https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/troubleshooting-kubeadm/#pods-are-not-accessible-via-their-service-ip
),确认了一下集群中这块配置使用的是默认的配置,默认配置是 promiscuous-bridge,如果 kubenet 没有开启的话会自动切换配置为 hairpin-veth 模式。以下是默认配置下,kubelet 的启动日志:

Hairpin mode set to "promiscuous-bridge" but kubenet is not enabled, falling back to "hairpin-veth"
Hairpin mode set to "hairpin-veth"

发现不是 kubenet 之后,切换为 hairpin-veth。觉得问题还是出在 kube-proxy 这块,当前使用的是 ipvs 模式,查看 kube-proxy 启动日志之后,发现一些错误的日志:

Failed to retrieve node info: nodes "xxxxxxx" not found
server_others.go:189] Using ipvs Proxier.
invalid nodeIP, initializing kube-proxy with 127.0.0.1 as nodeIP

使用默认主机名作为节点,但是并没有找到该节点(集群环境统一使用节点 IP 注册的),然后 kube-proxy 又设置 127.0.0.1 作为 nodeIP。怀疑问题出在这一块,通过 --hostname-overwrite 配置实际节点 IP 之后,发现 Pod 通过 Service IP 访问自身恢复正常了。


实际看代码解读:

    nodeIP := net.ParseIP(config.BindAddress)
    if nodeIP.IsUnspecified() {
        nodeIP = utilnode.GetNodeIP(client, hostname)
        if nodeIP == nil {
            return nil, fmt.Errorf("unable to get node IP for hostname %s", hostname)
        }
    }
// IsUnspecified reports whether ip is an unspecified address, either
// the IPv4 address "0.0.0.0" or the IPv6 address "::".
func (ip IP) IsUnspecified() bool {
    return ip.Equal(IPv4zero) || ip.Equal(IPv6unspecified)
}

先通过 BindAddress 获取节点 IP,如果是未指定的值 (0.0.0.0 || :😃 则根据主机名获取节点 IP。

// GetNodeIP returns the ip of node with the provided hostname
// If required, wait for the node to be defined.
func GetNodeIP(client clientset.Interface, hostname string) net.IP {
    var nodeIP net.IP
    backoff := wait.Backoff{
        Steps:    5,
        Duration: 1 * time.Second,
        Factor:   2.0,
        Jitter:   0.2,
    }

    err := wait.ExponentialBackoff(backoff, func() (bool, error) {
        node, err := client.CoreV1().Nodes().Get(hostname, metav1.GetOptions{})
        if err != nil {
            klog.Errorf("Failed to retrieve node info: %v", err)
            return false, nil
        }
        nodeIP, err = GetNodeHostIP(node)
        if err != nil {
            klog.Errorf("Failed to retrieve node IP: %v", err)
            return false, err
        }
        return true, nil
    })
    if err == nil {
        klog.Infof("Successfully retrieved node IP: %v", nodeIP)
    }
    return nodeIP
}

如果还是获取不到,则设置 127.0.0.1 为节点 IP

    if nodeIP == nil {
        klog.Warning("invalid nodeIP, initializing kube-proxy with 127.0.0.1 as nodeIP")
        nodeIP = net.ParseIP("127.0.0.1")
    }

因此上文只要设置 --bind-address 项应该也是生效的,实测是正常的。不过当前只是把问题解决了,为何 nodeIP 正确获取之后,之前的问题就解决了?答案是未知的… 类似的问题 kubernetes/kubernetes#57518

https://github.com/opskumu/issues/issues/23#issuecomment-547280434

https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/troubleshooting-kubeadm/#pods-are-not-accessible-via-their-service-ip

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Kubernetes中的Pod是最小的可部署单元,它可以包含一个或多个容器。ServicePod的抽象,它为一组Pod提供一个统一的入口,以便其他应用程序可以访问这些Pod。下面是Pod和容器的Service的基本原理和操作: 1. Pod和容器的Service基本原理: - Pod和容器的ServiceKubernetes中的两个概念,Pod是最小的可部署单元,容器是运行在Pod中的应用程序。 - ServicePod的抽象,为一组Pod提供一个统一的入口,以便其他应用程序可以访问这些PodService有一个虚拟IP地址和一个端口号,用于将请求路由到后端Pod。 - Service的基本原理是通过标签选择器来选择一组Pod,这些Pod可以通过Service的虚拟IP地址和端口号来访问。当请求到达Service时,它会将请求路由到后端Pod中的一个或多个容器。 2. Pod和容器的Service基本操作: - 创建Pod:使用Kubernetes中的Pod对象创建一个或多个Pod。 - 添加标签:为Pod添加标签,这样Service可以使用标签选择器来选择Pod。 - 创建Service:使用Kubernetes中的Service对象创建一个Service,指定它的虚拟IP地址和端口号,并指定标签选择器来选择后端Pod。 - 测试Service:使用Service的虚拟IP地址和端口号测试Service是否正常工作。可以使用Kubernetes中的kubectl命令行工具来测试Service。 - 扩展Pod:可以使用Kubernetes中的ReplicaSet或Deployment对象来扩展Pod。当Pod扩展时,Service会自动将请求路由到新的Pod中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爷来辣

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值