Routing Traffic to Docker Services
By the end of this exercise, you should be able to:
- Route traffic to a Docker service from within the swarm using dnsrr DNS lookups
- Route traffic to a Docker service from outside the swarm using host port publishing
Configuring an Internally Routable Service
Create an overlay network
my_overlay, or use the one you created in the last exercise.Create a service out of the
training/whoami-windows:latestimage; containers created from this image will respond with their container ID when receiving a web request on their port 5000.PS: node-0 Administrator> docker service create --name whoami ` --replicas=4 --network my_overlay ` --endpoint-mode dnsrr ` training/whoami-windows:latestCreate another service attached to the same network, which we'll use to attempt to communicate with your first service:
PS: node-0 Administrator> docker service create --name pinger ` --network my_overlay --replicas=4 ` microsoft/nanoserver ping 8.8.8.8 -tLaunch a powershell in one of your
pingercontainers (it doesn't matter which one or on which node). Then, probe DNS resolution for yourwhoamiservice:PS: node-0 Administrator> docker container exec -it <container ID> powershell PS C:\> Resolve-DnsName -Name whoami Name Type TTL Section IPAddress ---- ---- --- ------- --------- whoami A 600 Answer 10.0.0.29 whoami A 600 Answer 10.0.0.31 whoami A 600 Answer 10.0.0.30 whoami A 600 Answer 10.0.0.27By launching the
whoamiservice with the flag--endpoint-mode dnsrr, a DNS lookup on the service namewhoamireturns all the A-records corresponding to that service name, one for each replica of that service.Try contacting a few of your
whoamicontainers using the IPs you found above:PS C:\> (Invoke-WebRequest http://<container IP>:5000).Content I am 02FF20A20861Try doing the same to resolve the DNS entry
pinger:PS C:\> Resolve-DnsName -Name pinger Name Type TTL Section IPAddress ---- ---- --- ------- --------- pinger A 600 Answer 10.0.0.32The
pingerservice wasn't started with the--endpoint-mode dnsrrflag, so its DNS resolution defaults tovip, or the Virtual IP of the service as a whole (not of individual containers like we got for thewhoamiservice). On Windows Server 1709+ (semi-annual Server channel), requests to a virtual IP such as this get load balanced by Docker to the containers managed by that service; this functionality is not available in Windows Server 2016, but is expected in Windows Server 2019.Exit your container, and use
docker service inspect pingerto confirm the single IP the DNS entrypingerresolved to is the virtual IP of the pinger service, and usedocker container inspecton yourwhoamicontainers to confirm their IPs match the IPs returned in the DNS lookup above.
Configuring an Externally Routable Service
Start a service using host mode port publishing:
PS: node-0 Administrator> docker service create --name iis --replicas=4 ` --publish mode=host,target=80 ` microsoft/iisThis will map port 80 inside each container managed by this service onto a random available port on the host, so traffic from the outside network can be forwarded to your containerized application.
Do
docker container lson a node that has one of theseiiscontainers running on it. Under thePORTScolumn in the resulting table, you should see something like0.0.0.0:20931->80/tcp; in this case, Docker is forwarding traffic from the host port's 20931 to the container's port 80. Try visiting the iis landing page in your browser at: , and confirm that your containerized website is reachable.
Cleaning up
Remove all existing services, in preparation for future exercises:
PS: node-0 Administrator> docker service rm $(docker service ls -q)
Conclusion
In this exercise, we've explored the two main ways traffic gets routed to containerized applications on Windows: internal to the cluster, dnsrr routing resolves service names to a list of IPs of corresponding containers; it's up to you to load balance across these, and periodically check whether the list has changes (due to rescheduled containers or rescaled services). External to the cluster, host mode publishing maps a random host port onto a specified container port; it's up to you to then point your load balancer at the hosts and ports your application is running on.