mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #9381 from lebauce/default-gateway
Proposal: Allow specifying a default gateway for bridge networking
This commit is contained in:
commit
9838242db1
5 changed files with 80 additions and 13 deletions
|
@ -58,6 +58,8 @@ func (config *Config) InstallFlags() {
|
||||||
flag.StringVar(&config.Bridge.Iface, []string{"b", "-bridge"}, "", "Attach containers to a network bridge")
|
flag.StringVar(&config.Bridge.Iface, []string{"b", "-bridge"}, "", "Attach containers to a network bridge")
|
||||||
flag.StringVar(&config.Bridge.FixedCIDR, []string{"-fixed-cidr"}, "", "IPv4 subnet for fixed IPs")
|
flag.StringVar(&config.Bridge.FixedCIDR, []string{"-fixed-cidr"}, "", "IPv4 subnet for fixed IPs")
|
||||||
flag.StringVar(&config.Bridge.FixedCIDRv6, []string{"-fixed-cidr-v6"}, "", "IPv6 subnet for fixed IPs")
|
flag.StringVar(&config.Bridge.FixedCIDRv6, []string{"-fixed-cidr-v6"}, "", "IPv6 subnet for fixed IPs")
|
||||||
|
flag.StringVar(&config.Bridge.DefaultGatewayIPv4, []string{"-default-gateway"}, "", "Container default gateway IPv4 address")
|
||||||
|
flag.StringVar(&config.Bridge.DefaultGatewayIPv6, []string{"-default-gateway-v6"}, "", "Container default gateway IPv6 address")
|
||||||
flag.BoolVar(&config.Bridge.InterContainerCommunication, []string{"#icc", "-icc"}, true, "Enable inter-container communication")
|
flag.BoolVar(&config.Bridge.InterContainerCommunication, []string{"#icc", "-icc"}, true, "Enable inter-container communication")
|
||||||
flag.StringVar(&config.GraphDriver, []string{"s", "-storage-driver"}, "", "Storage driver to use")
|
flag.StringVar(&config.GraphDriver, []string{"s", "-storage-driver"}, "", "Storage driver to use")
|
||||||
flag.StringVar(&config.ExecDriver, []string{"e", "-exec-driver"}, "native", "Exec driver to use")
|
flag.StringVar(&config.ExecDriver, []string{"e", "-exec-driver"}, "native", "Exec driver to use")
|
||||||
|
|
|
@ -77,8 +77,10 @@ var (
|
||||||
|
|
||||||
bridgeIface string
|
bridgeIface string
|
||||||
bridgeIPv4Network *net.IPNet
|
bridgeIPv4Network *net.IPNet
|
||||||
|
gatewayIPv4 net.IP
|
||||||
bridgeIPv6Addr net.IP
|
bridgeIPv6Addr net.IP
|
||||||
globalIPv6Network *net.IPNet
|
globalIPv6Network *net.IPNet
|
||||||
|
gatewayIPv6 net.IP
|
||||||
portMapper *portmapper.PortMapper
|
portMapper *portmapper.PortMapper
|
||||||
once sync.Once
|
once sync.Once
|
||||||
|
|
||||||
|
@ -103,6 +105,8 @@ type Config struct {
|
||||||
IP string
|
IP string
|
||||||
FixedCIDR string
|
FixedCIDR string
|
||||||
FixedCIDRv6 string
|
FixedCIDRv6 string
|
||||||
|
DefaultGatewayIPv4 string
|
||||||
|
DefaultGatewayIPv6 string
|
||||||
InterContainerCommunication bool
|
InterContainerCommunication bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,6 +282,12 @@ func InitDriver(config *Config) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if gateway, err := requestDefaultGateway(config.DefaultGatewayIPv4, bridgeIPv4Network); err != nil {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
gatewayIPv4 = gateway
|
||||||
|
}
|
||||||
|
|
||||||
if config.FixedCIDRv6 != "" {
|
if config.FixedCIDRv6 != "" {
|
||||||
_, subnet, err := net.ParseCIDR(config.FixedCIDRv6)
|
_, subnet, err := net.ParseCIDR(config.FixedCIDRv6)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -289,6 +299,12 @@ func InitDriver(config *Config) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
globalIPv6Network = subnet
|
globalIPv6Network = subnet
|
||||||
|
|
||||||
|
if gateway, err := requestDefaultGateway(config.DefaultGatewayIPv6, globalIPv6Network); err != nil {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
gatewayIPv6 = gateway
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Block BridgeIP in IP allocator
|
// Block BridgeIP in IP allocator
|
||||||
|
@ -473,6 +489,24 @@ func setupIPv6Bridge(bridgeIPv6 string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func requestDefaultGateway(requestedGateway string, network *net.IPNet) (gateway net.IP, err error) {
|
||||||
|
if requestedGateway != "" {
|
||||||
|
gateway = net.ParseIP(requestedGateway)
|
||||||
|
|
||||||
|
if gateway == nil {
|
||||||
|
return nil, fmt.Errorf("Bad parameter: invalid gateway ip %s", requestedGateway)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !network.Contains(gateway) {
|
||||||
|
return nil, fmt.Errorf("Gateway ip %s must be part of the network %s", requestedGateway, network.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
ipAllocator.RequestIP(network, gateway)
|
||||||
|
}
|
||||||
|
|
||||||
|
return gateway, nil
|
||||||
|
}
|
||||||
|
|
||||||
func createBridgeIface(name string) error {
|
func createBridgeIface(name string) error {
|
||||||
kv, err := kernel.GetKernelVersion()
|
kv, err := kernel.GetKernelVersion()
|
||||||
// Only set the bridge's mac address if the kernel version is > 3.3
|
// Only set the bridge's mac address if the kernel version is > 3.3
|
||||||
|
@ -526,6 +560,8 @@ func Allocate(id, requestedMac, requestedIP, requestedIPv6 string) (*network.Set
|
||||||
mac net.HardwareAddr
|
mac net.HardwareAddr
|
||||||
err error
|
err error
|
||||||
globalIPv6 net.IP
|
globalIPv6 net.IP
|
||||||
|
defaultGWIPv4 net.IP
|
||||||
|
defaultGWIPv6 net.IP
|
||||||
)
|
)
|
||||||
|
|
||||||
ip, err = ipAllocator.RequestIP(bridgeIPv4Network, net.ParseIP(requestedIP))
|
ip, err = ipAllocator.RequestIP(bridgeIPv4Network, net.ParseIP(requestedIP))
|
||||||
|
@ -560,6 +596,18 @@ func Allocate(id, requestedMac, requestedIP, requestedIPv6 string) (*network.Set
|
||||||
|
|
||||||
maskSize, _ := bridgeIPv4Network.Mask.Size()
|
maskSize, _ := bridgeIPv4Network.Mask.Size()
|
||||||
|
|
||||||
|
if gatewayIPv4 != nil {
|
||||||
|
defaultGWIPv4 = gatewayIPv4
|
||||||
|
} else {
|
||||||
|
defaultGWIPv4 = bridgeIPv4Network.IP
|
||||||
|
}
|
||||||
|
|
||||||
|
if gatewayIPv6 != nil {
|
||||||
|
defaultGWIPv6 = gatewayIPv6
|
||||||
|
} else {
|
||||||
|
defaultGWIPv6 = bridgeIPv6Addr
|
||||||
|
}
|
||||||
|
|
||||||
// If linklocal IPv6
|
// If linklocal IPv6
|
||||||
localIPv6Net, err := linkLocalIPv6FromMac(mac.String())
|
localIPv6Net, err := linkLocalIPv6FromMac(mac.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -569,7 +617,7 @@ func Allocate(id, requestedMac, requestedIP, requestedIPv6 string) (*network.Set
|
||||||
|
|
||||||
networkSettings := &network.Settings{
|
networkSettings := &network.Settings{
|
||||||
IPAddress: ip.String(),
|
IPAddress: ip.String(),
|
||||||
Gateway: bridgeIPv4Network.IP.String(),
|
Gateway: defaultGWIPv4.String(),
|
||||||
MacAddress: mac.String(),
|
MacAddress: mac.String(),
|
||||||
Bridge: bridgeIface,
|
Bridge: bridgeIface,
|
||||||
IPPrefixLen: maskSize,
|
IPPrefixLen: maskSize,
|
||||||
|
@ -580,7 +628,7 @@ func Allocate(id, requestedMac, requestedIP, requestedIPv6 string) (*network.Set
|
||||||
networkSettings.GlobalIPv6Address = globalIPv6.String()
|
networkSettings.GlobalIPv6Address = globalIPv6.String()
|
||||||
maskV6Size, _ := globalIPv6Network.Mask.Size()
|
maskV6Size, _ := globalIPv6Network.Mask.Size()
|
||||||
networkSettings.GlobalIPv6PrefixLen = maskV6Size
|
networkSettings.GlobalIPv6PrefixLen = maskV6Size
|
||||||
networkSettings.IPv6Gateway = bridgeIPv6Addr.String()
|
networkSettings.IPv6Gateway = defaultGWIPv6.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
currentInterfaces.Set(id, &networkInterface{
|
currentInterfaces.Set(id, &networkInterface{
|
||||||
|
|
|
@ -41,6 +41,12 @@ To see the man page for a command run **man docker <command>**.
|
||||||
**-d**, **--daemon**=*true*|*false*
|
**-d**, **--daemon**=*true*|*false*
|
||||||
Enable daemon mode. Default is false.
|
Enable daemon mode. Default is false.
|
||||||
|
|
||||||
|
**--default-gateway**=""
|
||||||
|
IPv4 address of the container default gateway; this address must be part of the bridge subnet (which is defined by \-b or \--bip)
|
||||||
|
|
||||||
|
**--default-gateway-v6**=""
|
||||||
|
IPv6 address of the container default gateway
|
||||||
|
|
||||||
**--dns**=""
|
**--dns**=""
|
||||||
Force Docker to use specific DNS servers
|
Force Docker to use specific DNS servers
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,12 @@ server when it starts up, and cannot be changed once it is running:
|
||||||
* `--bip=CIDR` — see
|
* `--bip=CIDR` — see
|
||||||
[Customizing docker0](#docker0)
|
[Customizing docker0](#docker0)
|
||||||
|
|
||||||
|
* `--default-gateway=IP_ADDRESS` — see
|
||||||
|
[How Docker networks a container](#container-networking)
|
||||||
|
|
||||||
|
* `--default-gateway-v6=IP_ADDRESS` — see
|
||||||
|
[IPv6](#ipv6)
|
||||||
|
|
||||||
* `--fixed-cidr` — see
|
* `--fixed-cidr` — see
|
||||||
[Customizing docker0](#docker0)
|
[Customizing docker0](#docker0)
|
||||||
|
|
||||||
|
@ -499,7 +505,9 @@ want to configure `eth0` via Router Advertisements you should set:
|
||||||
![](/article-img/ipv6_basic_host_config.svg)
|
![](/article-img/ipv6_basic_host_config.svg)
|
||||||
|
|
||||||
Every new container will get an IPv6 address from the defined subnet. Further
|
Every new container will get an IPv6 address from the defined subnet. Further
|
||||||
a default route will be added via the gateway `fe80::1` on `eth0`:
|
a default route will be added on `eth0` in the container via the address
|
||||||
|
specified by the daemon option `--default-gateway-v6` if present, otherwise
|
||||||
|
via `fe80::1`:
|
||||||
|
|
||||||
docker run -it ubuntu bash -c "ip -6 addr show dev eth0; ip -6 route show"
|
docker run -it ubuntu bash -c "ip -6 addr show dev eth0; ip -6 route show"
|
||||||
|
|
||||||
|
@ -865,12 +873,13 @@ The steps with which Docker configures a container are:
|
||||||
parameter or generate a random one.
|
parameter or generate a random one.
|
||||||
|
|
||||||
5. Give the container's `eth0` a new IP address from within the
|
5. Give the container's `eth0` a new IP address from within the
|
||||||
bridge's range of network addresses, and set its default route to
|
bridge's range of network addresses. The default route is set to the
|
||||||
the IP address that the Docker host owns on the bridge. The MAC
|
IP address passed to the Docker daemon using the `--default-gateway`
|
||||||
address is generated from the IP address unless otherwise specified.
|
option if specified, otherwise to the IP address that the Docker host
|
||||||
This prevents ARP cache invalidation problems, when a new container
|
owns on the bridge. The MAC address is generated from the IP address
|
||||||
comes up with an IP used in the past by another container with another
|
unless otherwise specified. This prevents ARP cache invalidation
|
||||||
MAC.
|
problems, when a new container comes up with an IP used in the past by
|
||||||
|
another container with another MAC.
|
||||||
|
|
||||||
With these steps complete, the container now possesses an `eth0`
|
With these steps complete, the container now possesses an `eth0`
|
||||||
(virtual) network card and will find itself able to communicate with
|
(virtual) network card and will find itself able to communicate with
|
||||||
|
|
|
@ -145,6 +145,8 @@ expect an integer, and they can only be specified once.
|
||||||
--bip="" Specify network bridge IP
|
--bip="" Specify network bridge IP
|
||||||
-D, --debug=false Enable debug mode
|
-D, --debug=false Enable debug mode
|
||||||
-d, --daemon=false Enable daemon mode
|
-d, --daemon=false Enable daemon mode
|
||||||
|
--default-gateway="" Container default gateway IPv4 address
|
||||||
|
--default-gateway-v6="" Container default gateway IPv6 address
|
||||||
--dns=[] DNS server to use
|
--dns=[] DNS server to use
|
||||||
--dns-search=[] DNS search domains to use
|
--dns-search=[] DNS search domains to use
|
||||||
-e, --exec-driver="native" Exec driver to use
|
-e, --exec-driver="native" Exec driver to use
|
||||||
|
|
Loading…
Reference in a new issue