7 min read

Docker Networking Demystified Part 4: Service Discovery and Ingress.

Learn about allowing access to your containers using Docker Swarm, Service Discovery and Ingress.

Learn about allowing access to your containers using Docker Swarm, Service Discovery and Ingress.

📰
Docker Networking Demystified Series:
- Part 1: Introduction to Container Networking
- Part 2: Single Host Bridge Networks
- Part 3: Multi-Host Overlay Networks
- Part 4: Service Discovery and Ingress

As per Merriam-Webster, ingress is the act of entering. Within the context of a dockerized world, ingress, then, refers to the ability of a Docker Swarm (and its composite clusters) to allow external traffic to successfully reach a container (or containers).

However, before we can talk about ingress, we have to understand the Service Discovery mechanism built into Docker.

What is Service discovery ?

As per wikipedia, Service discovery is the process of automatically detecting devices and services on a computer network. This reduces the need for manual configuration by users and administrators.

Service discovery or container discovery can be difficult. Containers for a service come up, die, get re-spun, go through rolling updates, or patch management more often than we realize. In an environment as volatile as the one described here, the IP address to a container can keep changing and if someone/something is not making sure to update them periodically, you can expect 404's galore.

Service discovery: Basic flow

For containers to be registered, they should be launched with --name or --network-alias flags

Docker Registry uses DNS technology for service name resolution. Every time a new container is created (as a result of an update to the business logic inside the container or if the container was re-spawned after a crash), the name of the container and its IP is added to the register.

If any container is looking for another container (or service), it will look for the target container (or services) IP based on its name by querying the Registry, receiving a response and making the connection.

Putting our money where our mouths are.

For our hands-on work, I will use 3 EC2 instances:

3 EC2 nodes for our Swarm.
📢
If you haven't, please read Part 3: Multi-Host Overlay Networks for a basic understanding of Overlays, which are an important part of the whole Service Discovery and Consumption process.
Create a Swarm.

Follow the instructions provided by docker swarm for adding nodes to the cluster.

📢
Read Part 3: Multi-Host Overlay Network for a quick and easy way to create a Swarm (or cluster of containers).

Create an attachable Overlay network (and I will name this network my-overlay):

Confirm that the Swarm did indeed get created:

We can see three nodes have been added to the Swarm.

With the Overlay ready, add a service with 3 replicas to it. The replicas will be spread out, one to each node.

Confirm there are indeed 3 replicas on the Swarm:

docker service list will display all the replicas available on the Swarm.

As mentioned earlier, the creation of these 3 service replicas MUST have resulted in 3 IPs (one for each service replica) mapped to their names in Dockers Registry.

By running docker network inspect my-overlay on each of the 3 nodes, we can get their name and IP (as its been recorded in the Registry):

Control Plane's Name and IP.
Worker Node 1's Name and IP.
Worker Node 2's Name and IP.

To test Service discovery, we will add a stand-alone container to my-overlay on Control Panel and attempt to access the service/container on one of the nodes:

📢
The container service-discoverer was launched on Control Panel and therefore, by association between the node and the my-overlay Overlay, will be considered a resident of my-overlay.
Add a stand-alone container to my-overlay

To test name resolution, attach to service-discoverer and ping containers on Worker Node 1 and Worker Node 2 by using their names:

Worker Node 1's deployed service is easily accessible through use of its name.
Ditto for Worker Node 2.

However, the act of pinging single containers by their names is not feasible, especially when there are many replicas in a service and each replica has the kind of long names that Worker Node 1 and Worker Node 2 have. Additionally, if for some reason, the container on either of Worker Node 1 or Worker Node 2 dies, a new one may be spun up, which will have its own IP address (and cryptic name).

Ping-test the service name as opposed to the service name of each of the replicas.

Pinging the service by name removes the need for us to know each replicas name and IP.
📢
Each container has a file /etc/resolv.conf and inside this file, the IP of the Registry is documented:
The nameserver entry is the IP for Dockers Registry.

Finally, ingress networking.

In Part 3: Multi-Host Overlay Network, it was mentioned that an Overlay network called ingress, along with a Bridge called docker_gwbridge, is created automatically when we create a Docker Swarm.

Notice the 2 underlined network names: ingress and docker_gwbridge

The ingress will span EVERY node/container in the Swarm by default (yup, no discrimination here).

Lets inspect the ingress network quickly:

Notice the ingress-sbox container which is part of the ingress Overlay.
📢
What's the deal with these ingress-sbox containers?

Every ingress network will, as mentioned, create a docker_gwbridge. In addition, each ingress network will also have a container called ingress-sbox which is a part of the routing mechanism in an ingress Overlay.

For purposes of ingress, whenever a packet comes to the cluster, the ingress-sbox along with the docker_gwbridge container will make sure the packet is received by a container in the Swarm.

Visually, the network is configured as shown:

🚨
In Part 3: Multi-Host Overlay Network, it was mentioned that the default ingress that comes as a result of the Swarm being activated SHOULD not be used for user app deployments.

Eating our own dog food, let the ingress Overlay be for traffic ingestion and create a new Overlay for app deployment.

Create a new Overlay and call it my-prod-apps.

The my-prod-apps Overlay will be used for app deployment.

Visually, the layout is:

The ingress-sbox container has a link to both ingress and my-prod-apps

Deploy a replica of 3 services on my-prod-apps:

Check the services were deployed properly:

We can see 3/3 for ingress-test.

Display some information about the services as well:

Use docker service ps ingress-test.

Test ingress to confirm the plumbing is all in place.

Open a browser window and type the public IP of ANY one of the EC2 instances followed by port 5000. The web-page inside the App containers will be displayed.

Change the public IP and replace it with the public IP of each of the 2 remaining EC2 instances (followed by 5000).

So what really happened?

When the <public IP>:5000 was called in the browser address bar, a request was sent to the server hosting the containers/services.

  1. The traffic was passed onto the docker_gwbridge on one of the nodes (in our image, we assume its Worker Node 2 but could have been any one of the three).

2. From the docker_dwbridge, traffic was sent to ingress-sbox which pushed....

3. ... it to the ingress Overlay which carried the traffic all the way to the App on one of the nodes.

📰
In summary, we learnt about:
- Service Discovery
- ingress Overlay
- User-defined Overlays
- docker_gwbridge and its role in routing traffice
- ingress-sbox and its role in routing traffic

I write to remember and if in the process, I can help someone learn about Containers, Orchestration (Docker Compose, Kubernetes), GitOps, DevSecOps, VR/AR, Architecture, and Data Management, that is just icing on the cake.