Files
container.training/slides/containers/Container_Networking_Basics.md
2022-12-12 13:43:01 +01:00

6.9 KiB

class: title

Container networking basics

A dense graph network


Objectives

We will now run network services (accepting requests) in containers.

At the end of this section, you will be able to:

  • Run a network service in a container.

  • Connect to that network service.

  • Find a container's IP address.


Running a very simple service

  • We need something small, simple, easy to configure

    (or, even better, that doesn't require any configuration at all)

  • Let's use the official NGINX image (named nginx)

  • It runs a static web server listening on port 80

  • It serves a default "Welcome to nginx!" page


Running an NGINX server

$ docker run -d -P nginx
66b1ce719198711292c8f34f84a7b68c3876cf9f67015e752b94e189d35a204e
  • Docker will automatically pull the nginx image from the Docker Hub

  • -d / --detach tells Docker to run it in the background

  • P / --publish-all tells Docker to publish all ports

    (publish = make them reachable from other computers)

  • ...OK, how do we connect to our web server now?


Finding our web server port

  • First, we need to find the port number used by Docker

    (the NGINX container listens on port 80, but this port will be mapped)

  • We can use docker ps:

    $ docker ps
    CONTAINER ID  IMAGE  ...  PORTS                  ...
    e40ffb406c9e  nginx  ...  0.0.0.0:`12345`->80/tcp  ...
    
  • This means:

    port 12345 on the Docker host is mapped to port 80 in the container

  • Now we need to connect to the Docker host!


Finding the address of the Docker host

  • When running Docker on your Linux workstation:

    use localhost, or any IP address of your machine

  • When running Docker on a remote Linux server:

    use any IP address of the remote machine

  • When running Docker Desktop on Mac or Windows:

    use localhost

  • In other scenarios (docker-machine, local VM...):

    use the IP address of the Docker VM


Connecting to our web server (GUI)

Point your browser to the IP address of your Docker host, on the port shown by docker ps for container port 80.

Screenshot


Connecting to our web server (CLI)

You can also use curl directly from the Docker host.

Make sure to use the right port number if it is different from the example below:

$ curl localhost:12345
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...

How does Docker know which port to map?

  • There is metadata in the image telling "this image has something on port 80".

  • We can see that metadata with docker inspect:

$ docker inspect --format '{{.Config.ExposedPorts}}' nginx
map[80/tcp:{}]
  • This metadata was set in the Dockerfile, with the EXPOSE keyword.

  • We can see that with docker history:

$ docker history nginx
IMAGE               CREATED             CREATED BY
7f70b30f2cc6        11 days ago         /bin/sh -c #(nop)  CMD ["nginx" "-g" "…
<missing>           11 days ago         /bin/sh -c #(nop)  STOPSIGNAL [SIGTERM]
<missing>           11 days ago         /bin/sh -c #(nop)  EXPOSE 80/tcp

Why can't we just connect to port 80?

  • Our Docker host has only one port 80

  • Therefore, we can only have one container at a time on port 80

  • Therefore, if multiple containers want port 80, only one can get it

  • By default, containers do not get "their" port number, but a random one

    (not "random" as "crypto random", but as "it depends on various factors")

  • We'll see later how to force a port number (including port 80!)


class: extra-details

Using multiple IP addresses

Hey, my network-fu is strong, and I have questions...

  • Can I publish one container on 127.0.0.2:80, and another on 127.0.0.3:80?

  • My machine has multiple (public) IP addresses, let's say A.A.A.A and B.B.B.B.
    Can I have one container on A.A.A.A:80 and another on B.B.B.B:80?

  • I have a whole IPV4 subnet, can I allocate it to my containers?

  • What about IPV6?

You can do all these things when running Docker directly on Linux.

(On other platforms, generally not, but there are some exceptions.)


Finding the web server port in a script

Parsing the output of docker ps would be painful.

There is a command to help us:

$ docker port <containerID> 80
0.0.0.0:12345

Manual allocation of port numbers

If you want to set port numbers yourself, no problem:

$ docker run -d -p 80:80 nginx
$ docker run -d -p 8000:80 nginx
$ docker run -d -p 8080:80 -p 8888:80 nginx
  • We are running three NGINX web servers.
  • The first one is exposed on port 80.
  • The second one is exposed on port 8000.
  • The third one is exposed on ports 8080 and 8888.

Note: the convention is port-on-host:port-on-container.


Plumbing containers into your infrastructure

There are many ways to integrate containers in your network.

  • Start the container, letting Docker allocate a public port for it.
    Then retrieve that port number and feed it to your configuration.

  • Pick a fixed port number in advance, when you generate your configuration.
    Then start your container by setting the port numbers manually.

  • Use an orchestrator like Kubernetes or Swarm.
    The orchestrator will provide its own networking facilities.

Orchestrators typically provide mechanisms to enable direct container-to-container communication across hosts, and publishing/load balancing for inbound traffic.


Finding the container's IP address

We can use the docker inspect command to find the IP address of the container.

$ docker inspect --format '{{ .NetworkSettings.IPAddress }}' <yourContainerID>
172.17.0.3
  • docker inspect is an advanced command, that can retrieve a ton of information about our containers.

  • Here, we provide it with a format string to extract exactly the private IP address of the container.


Pinging our container

Let's try to ping our container from another container.

docker run alpine ping `<ipaddress>`
PING 172.17.0.X (172.17.0.X): 56 data bytes
64 bytes from 172.17.0.X: seq=0 ttl=64 time=0.106 ms
64 bytes from 172.17.0.X: seq=1 ttl=64 time=0.250 ms
64 bytes from 172.17.0.X: seq=2 ttl=64 time=0.188 ms

When running on Linux, we can even ping that IP address directly!

(And connect to a container's ports even if they aren't published.)


How often do we use -p and -P ?

  • When running a stack of containers, we will often use Compose

  • Compose will take care of exposing containers

    (through a ports: section in the docker-compose.yml file)

  • It is, however, fairly common to use docker run -P for a quick test

  • Or docker run -p ... when an image doesn't EXPOSE a port correctly


Section summary

We've learned how to:

  • Expose a network port.

  • Connect to an application running in a container.

  • Find a container's IP address.

???

:EN:- Exposing single containers :FR:- Exposer un conteneur isolé