diff --git a/pkg/kubelet/container/BUILD b/pkg/kubelet/container/BUILD index 65d24fb61eb..4ca7352fb16 100644 --- a/pkg/kubelet/container/BUILD +++ b/pkg/kubelet/container/BUILD @@ -39,6 +39,7 @@ go_library( "//staging/src/k8s.io/cri-api/pkg/apis/runtime/v1alpha2:go_default_library", "//third_party/forked/golang/expansion:go_default_library", "//vendor/k8s.io/klog:go_default_library", + "//vendor/k8s.io/utils/net:go_default_library", ], ) diff --git a/pkg/kubelet/container/helpers.go b/pkg/kubelet/container/helpers.go index 67f4b4ec755..20d087ed45c 100644 --- a/pkg/kubelet/container/helpers.go +++ b/pkg/kubelet/container/helpers.go @@ -35,6 +35,7 @@ import ( "k8s.io/kubernetes/pkg/kubelet/util/format" hashutil "k8s.io/kubernetes/pkg/util/hash" "k8s.io/kubernetes/third_party/forked/golang/expansion" + utilsnet "k8s.io/utils/net" ) // HandlerRunner runs a lifecycle handler for a container. @@ -319,16 +320,28 @@ func MakePortMappings(container *v1.Container) (ports []PortMapping) { HostIP: p.HostIP, } + // We need to determine the address family this entry applies to. We do this to ensure + // duplicate containerPort / protocol rules work across different address families. + // https://github.com/kubernetes/kubernetes/issues/82373 + family := "any" + if p.HostIP != "" { + if utilsnet.IsIPv6String(p.HostIP) { + family = "v6" + } else { + family = "v4" + } + } + // We need to create some default port name if it's not specified, since - // this is necessary for rkt. - // http://issue.k8s.io/7710 + // this is necessary for the dockershim CNI driver. + // https://github.com/kubernetes/kubernetes/pull/82374#issuecomment-529496888 if p.Name == "" { - pm.Name = fmt.Sprintf("%s-%s:%d", container.Name, p.Protocol, p.ContainerPort) + pm.Name = fmt.Sprintf("%s-%s-%s:%d", container.Name, family, p.Protocol, p.ContainerPort) } else { pm.Name = fmt.Sprintf("%s-%s", container.Name, p.Name) } - // Protect against exposing the same protocol-port more than once in a container. + // Protect against a port name being used more than once in a container. if _, ok := names[pm.Name]; ok { klog.Warningf("Port name conflicted, %q is defined more than once", pm.Name) continue diff --git a/pkg/kubelet/container/helpers_test.go b/pkg/kubelet/container/helpers_test.go index f7844b0a005..180e8632936 100644 --- a/pkg/kubelet/container/helpers_test.go +++ b/pkg/kubelet/container/helpers_test.go @@ -558,13 +558,19 @@ func TestMakePortMappings(t *testing.T) { // Duplicated, should be ignored. port("foo", v1.ProtocolUDP, 888, 8888, ""), // Duplicated, should be ignored. - port("", v1.ProtocolTCP, 80, 8888, ""), + port("", v1.ProtocolTCP, 80, 8888, "127.0.0.1"), + // Duplicated with different address family, shouldn't be ignored + port("", v1.ProtocolTCP, 80, 8080, "::"), + // No address family specified + port("", v1.ProtocolTCP, 1234, 5678, ""), }, }, []PortMapping{ - portMapping("fooContainer-TCP:80", v1.ProtocolTCP, 80, 8080, "127.0.0.1"), - portMapping("fooContainer-TCP:443", v1.ProtocolTCP, 443, 4343, "192.168.0.1"), + portMapping("fooContainer-v4-TCP:80", v1.ProtocolTCP, 80, 8080, "127.0.0.1"), + portMapping("fooContainer-v4-TCP:443", v1.ProtocolTCP, 443, 4343, "192.168.0.1"), portMapping("fooContainer-foo", v1.ProtocolUDP, 555, 5555, ""), + portMapping("fooContainer-v6-TCP:80", v1.ProtocolTCP, 80, 8080, "::"), + portMapping("fooContainer-any-TCP:1234", v1.ProtocolTCP, 1234, 5678, ""), }, }, }