1
0
Fork 0
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:
Arnaud Porterie 2015-04-20 15:50:35 -07:00
commit 9838242db1
5 changed files with 80 additions and 13 deletions

View file

@ -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.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.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.StringVar(&config.GraphDriver, []string{"s", "-storage-driver"}, "", "Storage driver to use")
flag.StringVar(&config.ExecDriver, []string{"e", "-exec-driver"}, "native", "Exec driver to use")

View file

@ -77,8 +77,10 @@ var (
bridgeIface string
bridgeIPv4Network *net.IPNet
gatewayIPv4 net.IP
bridgeIPv6Addr net.IP
globalIPv6Network *net.IPNet
gatewayIPv6 net.IP
portMapper *portmapper.PortMapper
once sync.Once
@ -103,6 +105,8 @@ type Config struct {
IP string
FixedCIDR string
FixedCIDRv6 string
DefaultGatewayIPv4 string
DefaultGatewayIPv6 string
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 != "" {
_, subnet, err := net.ParseCIDR(config.FixedCIDRv6)
if err != nil {
@ -289,6 +299,12 @@ func InitDriver(config *Config) error {
return err
}
globalIPv6Network = subnet
if gateway, err := requestDefaultGateway(config.DefaultGatewayIPv6, globalIPv6Network); err != nil {
return err
} else {
gatewayIPv6 = gateway
}
}
// Block BridgeIP in IP allocator
@ -473,6 +489,24 @@ func setupIPv6Bridge(bridgeIPv6 string) error {
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 {
kv, err := kernel.GetKernelVersion()
// Only set the bridge's mac address if the kernel version is > 3.3
@ -522,10 +556,12 @@ func linkLocalIPv6FromMac(mac string) (string, error) {
// Allocate a network interface
func Allocate(id, requestedMac, requestedIP, requestedIPv6 string) (*network.Settings, error) {
var (
ip net.IP
mac net.HardwareAddr
err error
globalIPv6 net.IP
ip net.IP
mac net.HardwareAddr
err error
globalIPv6 net.IP
defaultGWIPv4 net.IP
defaultGWIPv6 net.IP
)
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()
if gatewayIPv4 != nil {
defaultGWIPv4 = gatewayIPv4
} else {
defaultGWIPv4 = bridgeIPv4Network.IP
}
if gatewayIPv6 != nil {
defaultGWIPv6 = gatewayIPv6
} else {
defaultGWIPv6 = bridgeIPv6Addr
}
// If linklocal IPv6
localIPv6Net, err := linkLocalIPv6FromMac(mac.String())
if err != nil {
@ -569,7 +617,7 @@ func Allocate(id, requestedMac, requestedIP, requestedIPv6 string) (*network.Set
networkSettings := &network.Settings{
IPAddress: ip.String(),
Gateway: bridgeIPv4Network.IP.String(),
Gateway: defaultGWIPv4.String(),
MacAddress: mac.String(),
Bridge: bridgeIface,
IPPrefixLen: maskSize,
@ -580,7 +628,7 @@ func Allocate(id, requestedMac, requestedIP, requestedIPv6 string) (*network.Set
networkSettings.GlobalIPv6Address = globalIPv6.String()
maskV6Size, _ := globalIPv6Network.Mask.Size()
networkSettings.GlobalIPv6PrefixLen = maskV6Size
networkSettings.IPv6Gateway = bridgeIPv6Addr.String()
networkSettings.IPv6Gateway = defaultGWIPv6.String()
}
currentInterfaces.Set(id, &networkInterface{

View file

@ -41,6 +41,12 @@ To see the man page for a command run **man docker <command>**.
**-d**, **--daemon**=*true*|*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**=""
Force Docker to use specific DNS servers

View file

@ -56,6 +56,12 @@ server when it starts up, and cannot be changed once it is running:
* `--bip=CIDR` — see
[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
[Customizing docker0](#docker0)
@ -499,7 +505,9 @@ want to configure `eth0` via Router Advertisements you should set:
![](/article-img/ipv6_basic_host_config.svg)
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"
@ -865,12 +873,13 @@ The steps with which Docker configures a container are:
parameter or generate a random one.
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
the IP address that the Docker host owns on the bridge. The MAC
address is generated from the IP address unless otherwise specified.
This prevents ARP cache invalidation problems, when a new container
comes up with an IP used in the past by another container with another
MAC.
bridge's range of network addresses. The default route is set to the
IP address passed to the Docker daemon using the `--default-gateway`
option if specified, otherwise to the IP address that the Docker host
owns on the bridge. The MAC address is generated from the IP address
unless otherwise specified. This prevents ARP cache invalidation
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`
(virtual) network card and will find itself able to communicate with

View file

@ -145,6 +145,8 @@ expect an integer, and they can only be specified once.
--bip="" Specify network bridge IP
-D, --debug=false Enable debug 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-search=[] DNS search domains to use
-e, --exec-driver="native" Exec driver to use