Kubectl 端口转发不适用于与 socat 绑定的 IPv6

Kubectl port-forwarding not working for IPv6 binding with socat

我试图理解为什么这个特定的 socat 命令在我 运行 只有 IPv6 的 Kubernetes 集群中不起作用。

集群构建在 AWS 之上,带有 Calico CNI 和 containerd。使用 kubeadm 和 Kubernetes 1.21 配置。

我有 运行 以下 socat 命令绑定到环回接口 ::1,

kubectl --context=$CLUSTER1 run --image=alpine/socat socat -- tcp6-listen:15000,bind=\[::1\],fork,reuseaddr /dev/null

然后我尝试 port-forwardcurl15000 端口,

kubectl --context=$CLUSTER1 port-forward pod/socat 35000:15000 --address=::1
curl -ivg http://localhost:35000

我收到错误,

Forwarding from [::1]:35000 -> 15000
Handling connection for 35000
E0830 17:09:59.604799   79802 portforward.go:400] an error occurred forwarding 35000 -> 15000: error forwarding port 15000 to pod a8ba619774234e73f4c1b4fe4ff47193af835cffc56cb6ad1a8f91e745ac74e9, uid : failed to execute portforward in network namespace "/var/run/netns/cni-8bade2c1-28c9-6776-5326-f10d55fd0ff9": failed to dial 15000: dial tcp4 127.0.0.1:15000: connect: connection refused

它正在听 15000 作为,

Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 ::1:15000               :::*                    LISTEN      1/socat

但是,如果我 运行 以下它工作正常,

kubectl --context=$CLUSTER1 run --image=alpine/socat socat -- tcp6-listen:15000,bind=\[::\],fork,reuseaddr /dev/null

不确定我是否理解为什么 port-forward 会因环回接口绑定 ::1 而失败,但不会因 catch all :: 而失败。有人可以解释一下吗?

对于那些 运行 与您的 IPv6 only Kubernetes 集群有类似问题的人来说,这是我到目前为止调查发现的内容。

背景: 看来这是一个与IPv6和CRI相关的通用问题。 我在我的设置中 运行 containerdcontainerd 版本 1.5.0-1.5.2 添加了两个 PR (don't use socat for port forwarding and use happy-eyeballs for port-forwarding) 修复了一些问题IPv6 端口转发。

潜在修复: 进一步引入 containerd 版本 1.5.2(作为 Ubuntu 20.04 LTS 的一部分)我也得到了端口转发时出现错误 IPv4: dial tcp4 127.0.0.1:15021: connect: connection refused IPv6 dial tcp6: address localhost: no suitable address found。这是由解析 localhost 时的 DNS 问题引起的。因此,我使用以下命令在主机中添加 localhost 以解析为 ::1

sed -i 's/::1 ip6-localhost ip6-loopback/::1 localhost ip6-localhost ip6-loopback/' /etc/hosts

我认为这里的重点是检查容器运行时以确保支持 IPv6(tcp6 绑定)。