diff --git a/plugins/meta/portmap/portmap_iptables.go b/plugins/meta/portmap/portmap_iptables.go index 07d6c4209..e976b8455 100644 --- a/plugins/meta/portmap/portmap_iptables.go +++ b/plugins/meta/portmap/portmap_iptables.go @@ -164,11 +164,15 @@ func genToplevelDnatChain() chain { // genDnatChain creates the per-container chain. // Conditions are any static entry conditions for the chain. +// Entry rules are prepended within CNI-HOSTPORT-DNAT so that the most recent +// container using a host port wins without moving CNI-HOSTPORT-DNAT ahead of +// Kubernetes service rules in PREROUTING/OUTPUT. func genDnatChain(netName, containerID string) chain { return chain{ - table: "nat", - name: utils.MustFormatChainNameWithPrefix(netName, containerID, "DN-"), - entryChains: []string{TopLevelDNATChainName}, + table: "nat", + name: utils.MustFormatChainNameWithPrefix(netName, containerID, "DN-"), + entryChains: []string{TopLevelDNATChainName}, + prependEntry: true, } } diff --git a/plugins/meta/portmap/portmap_iptables_test.go b/plugins/meta/portmap/portmap_iptables_test.go index bc9bbf223..9ba240789 100644 --- a/plugins/meta/portmap/portmap_iptables_test.go +++ b/plugins/meta/portmap/portmap_iptables_test.go @@ -38,9 +38,10 @@ var _ = Describe("portmapping configuration (iptables)", func() { ch := genDnatChain(netName, containerID) Expect(ch).To(Equal(chain{ - table: "nat", - name: "CNI-DN-bfd599665540dd91d5d28", - entryChains: []string{TopLevelDNATChainName}, + table: "nat", + name: "CNI-DN-bfd599665540dd91d5d28", + entryChains: []string{TopLevelDNATChainName}, + prependEntry: true, })) configBytes := []byte(fmt.Sprintf(`{ "name": "test", @@ -69,9 +70,10 @@ var _ = Describe("portmapping configuration (iptables)", func() { ch = genDnatChain(conf.Name, containerID) Expect(ch).To(Equal(chain{ - table: "nat", - name: "CNI-DN-67e92b96e692a494b6b85", - entryChains: []string{"CNI-HOSTPORT-DNAT"}, + table: "nat", + name: "CNI-DN-67e92b96e692a494b6b85", + entryChains: []string{"CNI-HOSTPORT-DNAT"}, + prependEntry: true, })) n, err := types.ParseCIDR("10.0.0.2/24") @@ -171,9 +173,10 @@ var _ = Describe("portmapping configuration (iptables)", func() { ch := genDnatChain(netName, containerID) Expect(ch).To(Equal(chain{ - table: "nat", - name: "CNI-DN-bfd599665540dd91d5d28", - entryChains: []string{TopLevelDNATChainName}, + table: "nat", + name: "CNI-DN-bfd599665540dd91d5d28", + entryChains: []string{TopLevelDNATChainName}, + prependEntry: true, })) configBytes := []byte(fmt.Sprintf(`{ "name": "test",