Instructor Demo: Single Host Networks
In this demo, we'll illustrate:
- The networking stack created for the default Docker
natnetwork - Attaching containers to docker networks
- Inspecting networking metadata
- How network adapters appear in different network namespaces
Following Default Docker Networking
On a fresh node you haven't run any containers on yet, list your networks:
PS: node-1 Administrator> docker network ls NETWORK ID NAME DRIVER SCOPE 03f6ddacab50 nat nat local b0de36ba94f3 none null localGet some metadata about the
natnetwork, which is the default network containers attach to when doingdocker container run:PS: node-1 Administrator> docker network inspect natNotice the
IPAMsection:"IPAM": { "Driver": "windows", "Options": null, "Config": [ { "Subnet": "172.20.128.0/20", "Gateway": "172.20.128.1" } ] }Docker's IP address management driver assigns a subnet (
172.20.128.0/20in this case) to each nat network, and uses the first IP in that range as the network's gateway.Also note the
containerskey:"Containers": {}So far, no containers have been plugged into this network.
The
natDocker network is composed of a hyper-v virtual switch, and network address translation provided by WinNAT. List your virtual switches:PS: node-1 Administrator> Get-VMSwitch Name SwitchType NetAdapterInterfaceDescription ---- ---------- ------------------------------ nat InternalThe
Internaltype indicates that this switch isn't directly connected to a network adapter on the host. Get some metadata about your host's NAT service:PS node-1> Get-NetNat Name : H3acfc61d-0d8e-438c-8857-9c2b742707bf ExternalIPInterfaceAddressPrefix : InternalIPInterfaceAddressPrefix : 172.20.128.1/20 IcmpQueryTimeout : 30 TcpEstablishedConnectionTimeout : 1800 TcpTransientConnectionTimeout : 120 TcpFilteringBehavior : AddressDependentFiltering UdpFilteringBehavior : AddressDependentFiltering UdpIdleSessionTimeout : 120 UdpInboundRefresh : False Store : Local Active : TrueNotice this IP listed here matches the gateway presented by
docker network inspect nat.Next, have a look at what network adapters are present in the host's network namespace:
PS: node-1 Administrator> ipconfig /all Windows IP Configuration Host Name . . . . . . . . . . . . : node-0 Primary Dns Suffix . . . . . . . : Node Type . . . . . . . . . . . . : Hybrid IP Routing Enabled. . . . . . . . : No WINS Proxy Enabled. . . . . . . . : No DNS Suffix Search List. . . . . . : us-east-1.ec2-utilities.amazonaws.com ec2.internal Ethernet adapter vEthernet (HNS Internal NIC): Connection-specific DNS Suffix . : Description . . . . . . . . . . . : Hyper-V Virtual Ethernet Adapter Physical Address. . . . . . . . . : 00-15-5D-E6-0A-79 DHCP Enabled. . . . . . . . . . . : Yes Autoconfiguration Enabled . . . . : Yes Link-local IPv6 Address . . . . . : fe80::1074:1c58:105c:eca4%8(Preferred) IPv4 Address. . . . . . . . . . . : 172.20.128.1(Preferred) Subnet Mask . . . . . . . . . . . : 255.255.240.0 Default Gateway . . . . . . . . . : DHCPv6 IAID . . . . . . . . . . . : 184554845 DHCPv6 Client DUID. . . . . . . . : 00-01-00-01-22-DF-49-F3-0E-85-CC-1B-93-E6 DNS Servers . . . . . . . . . . . : fec0:0:0:ffff::1%1 fec0:0:0:ffff::2%1 fec0:0:0:ffff::3%1 NetBIOS over Tcpip. . . . . . . . : Enabled ...The Host Network Service (HNS) set up the virtual NIC (second block above) corresponding to your virtual switch and NAT when the Docker engine first started on this host.
Create a container attached to your nat network:
PS: node-1 Administrator> docker container run --name=c1 -dt microsoft/nanoserverHave a look at the network adapters created inside this container's network namespace:
PS: node-1 Administrator> docker container exec c1 ipconfig /all Windows IP Configuration Host Name . . . . . . . . . . . . : 42651ff618f8 Primary Dns Suffix . . . . . . . : Node Type . . . . . . . . . . . . : Hybrid IP Routing Enabled. . . . . . . . : No WINS Proxy Enabled. . . . . . . . : No DNS Suffix Search List. . . . . . : ec2.internal Ethernet adapter vEthernet (Container NIC c6951378): Connection-specific DNS Suffix . : ec2.internal Description . . . . . . . . . . . : Hyper-V Virtual Ethernet Adapter #2 Physical Address. . . . . . . . . : 00-15-5D-E6-06-12 DHCP Enabled. . . . . . . . . . . : No Autoconfiguration Enabled . . . . : Yes Link-local IPv6 Address . . . . . : fe80::50cc:78ae:aa3b:51fd%18(Preferred) IPv4 Address. . . . . . . . . . . : 172.20.136.208(Preferred) Subnet Mask . . . . . . . . . . . : 255.255.240.0 Default Gateway . . . . . . . . . : 172.20.128.1 DNS Servers . . . . . . . . . . . : 172.20.128.1 10.10.0.2 NetBIOS over Tcpip. . . . . . . . : DisabledThe Host Network Service creates and places a virtual NIC inside the container's network namespace upon container creation, assigning that container an IP address from the
natnetwork's subnet.Create another container, and ping one from the other by container name:
PS: node-1 Administrator> docker container run --name=c2 -dt microsoft/nanoserver PS: node-1 Administrator> docker container exec c1 ping c2 Pinging c2 [172.20.134.196] with 32 bytes of data: Reply from 172.20.134.196: bytes=32 time<1ms TTL=128 Reply from 172.20.134.196: bytes=32 time<1ms TTL=128 Reply from 172.20.134.196: bytes=32 time<1ms TTL=128 Reply from 172.20.134.196: bytes=32 time<1ms TTL=128 Ping statistics for 172.20.134.196: Packets: Sent = 4, Received = 4, Lost = 0 (0% loss), Approximate round trip times in milli-seconds: Minimum = 0ms, Maximum = 0ms, Average = 0msThe ping is successful; Docker uses DNS resolution so that our application logic (
ping c2in this case) doesn't need to do any explicit service discovery or networking lookups by hand; all that is provided by the Docker engine and Windows networking stack.Create one final container, but don't name it this time, and attempt to ping it from
c1like above:PS: node-1 Administrator> docker container run -dt microsoft/nanoserver PS: node-1 Administrator> docker container exec c1 ping <new container name> Ping request could not find host <new container name>. Please check the name and try again.Docker only provides DNS lookup for containers explicitly named with the
--nameflag.
Forwarding a Host Port to a Container
Start an
iiscontainer with a port exposure:PS: node-1 Administrator> docker container run -d -p 5000:80 --name iis microsoft/iisThis syntax asks docker to forward all traffic arriving on port 5000 of the host's network namespace to port 80 of the container's network namespace. Visit the
iislanding page at<node-1 public IP>:5000.List the NAT rules on your host:
PS: node-1 Administrator> Get-NetNatStaticMapping StaticMappingID : 0 NatName : H3acfc61d-0d8e-438c-8857-9c2b742707bf Protocol : TCP RemoteExternalIPAddressPrefix : 0.0.0.0/0 ExternalIPAddress : 0.0.0.0 ExternalPort : 5000 InternalIPAddress : 172.20.142.213 InternalPort : 80 InternalRoutingDomainId : {00000000-0000-0000-0000-000000000000} Active : TrueThere should be one similar to the above, with
ExternalPort: 5000,InternalPort: 80andInternalIPAddressmatching the IP of your iis container (trydocker container inspect <iis container ID>ordocker network inspect natto see that this IP corresponds to your iis container).Delete all you containers on this node to clean up:
PS: node-1 Administrator> docker container rm -f $(docker container ls -aq)
Conclusion
In this demo, we stepped through the basic behavior of docker software defined nat networks, and looked at the technology underpinning them such as virtual switches and virtual NICs. By default, all containers started on a host without any explicit networking configuration will be able to communicate across Docker's nat network, and in order for containers to resolve each other's name by DNS, they must also be explicitly named upon creation.