
This change adds support for IPv6 container/pod addresses to the CNI bridge plugin, both for dual-stack (IPv4 + IPv6) and for IPv6-only network configurations. The proposed changes support multiple IPv6 addresses on a container interface. If isGW is configured, the bridge will also be configured with gateway addresses for each IPv6 subnet. Please note that both the dual-stack functionality and support for multiple IPv6 container/gateway addresses depends upon containernetworking/cni PR 451 "ipam/host-local: support multiple IP ranges". This change could potentially be committed independently from this host-local plugin change, however the dual-stack and multiple IPv6 address functionality that is enabled by this change can't be exercised/tested until the host-local plugin change is committed. There are some IPv6 unit test cases that are currently commented out in the proposed changes because these test cases will fail without the prior commits of the multiple IP range host-local change. This pull request includes a temporary workaround for Kubernetes Issue #32291 (Container IPv6 address is marked as duplicate, or dadfailed). The problem is that kubelet enables hairpin mode on bridge veth interfaces. Hairpin mode causes the container/pod to see echos of its IPv6 neighbor solicitation packets, so that it declares duplicate address detection (DAD) failure. The long-term fix is to use enhanced-DAD when that feature is readily available in kernels. The short-term fix is to disable IPv6 DAD in the container. Unfortunately, this has to be done unconditionally (i.e. without a check for whether hairpin mode is enabled) because hairpin mode is turned on by kubelet after the CNI bridge plugin has completed cmdAdd processing. Disabling DAD should be okay if IPv6 addresses are guaranteed to be unique (which is the case for host-local IPAM plugin).
bridge plugin
Overview
With bridge plugin, all containers (on the same host) are plugged into a bridge (virtual switch) that resides in the host network namespace. The containers receive one end of the veth pair with the other end connected to the bridge. An IP address is only assigned to one end of the veth pair -- one residing in the container. The bridge itself can also be assigned an IP address, turning it into a gateway for the containers. Alternatively, the bridge can function purely in L2 mode and would need to be bridged to the host network interface (if other than container-to-container communication on the same host is desired).
The network configuration specifies the name of the bridge to be used. If the bridge is missing, the plugin will create one on first use and, if gateway mode is used, assign it an IP that was returned by IPAM plugin via the gateway field.
Example configuration
{
"name": "mynet",
"type": "bridge",
"bridge": "mynet0",
"isDefaultGateway": true,
"forceAddress": false,
"ipMasq": true,
"hairpinMode": true,
"ipam": {
"type": "host-local",
"subnet": "10.10.0.0/16"
}
}
Network configuration reference
name
(string, required): the name of the network.type
(string, required): "bridge".bridge
(string, optional): name of the bridge to use/create. Defaults to "cni0".isGateway
(boolean, optional): assign an IP address to the bridge. Defaults to false.isDefaultGateway
(boolean, optional): Sets isGateway to true and makes the assigned IP the default route. Defaults to false.forceAddress
(boolean, optional): Indicates if a new IP address should be set if the previous value has been changed. Defaults to false.ipMasq
(boolean, optional): set up IP Masquerade on the host for traffic originating from this network and destined outside of it. Defaults to false.mtu
(integer, optional): explicitly set MTU to the specified value. Defaults to the value chosen by the kernel.hairpinMode
(boolean, optional): set hairpin mode for interfaces on the bridge. Defaults to false.ipam
(dictionary, required): IPAM configuration to be used for this network.