Try   HackMD

Lab 7 - Docker - Basic handling of containers and of networking

tags: LAB

Podeis utilizar Docker en vuestra maquina instalandolo siguendo las indicaciones que están aqui: https://docs.docker.com/get-docker/

O utilizar la maquina virtual que està en Poliformat/RSE: Recursos/Laboratorio/código practicas laboratorio

O online: https://labs.play-with-docker.com/#

Introduction

Docker is an open platform for developing, shipping, and running applications. Docker enables you to separate your applications from your infrastructure so you can deliver software quickly.

For example, the following command runs an Ubuntu container, attaches interactively ('-i') to your local command-line session ('-t'), and runs /bin/bash.

​​​​$ docker run -i -t ubuntu /bin/bash

When you run this command, the following happens:

​​​​$ docker run -i -t ubuntu /bin/bash
​​​​Unable to find image 'ubuntu:latest' locally
​​​​latest: Pulling from library/ubuntu
​​​​7ddbc47eeb70: Pull complete 
​​​​c1bbdc448b72: Pull complete 
​​​​8c3b70e39044: Pull complete 
​​​​45d437916d57: Pull complete 
​​​​Digest: sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d
​​​​Status: Downloaded newer image for ubuntu:latest
​​​​root@9306f9cd711c:/# 
  1. If you do not have the ubuntu image locally, Docker pulls it from your configured registry, as though you had run docker pull ubuntu manually.
  2. Docker creates a new container, as though you had run a docker container create command manually.
  3. Docker allocates a read-write filesystem to the container, as its final layer. This allows a running container to create or modify files and directories in its local filesystem.
  4. Docker creates a network interface to connect the container to the default network, since you did not specify any networking options. This includes assigning an IP address to the container. By default, containers can connect to external networks using the host machine’s network connection.
  5. Docker starts the container and executes /bin/bash. Because the container is running interactively and attached to your terminal (due to the -i and -t flags), you can provide input using your keyboard while the output is logged to your terminal.
  6. When you type exit to terminate the /bin/bash command, the container stops but is not removed. You can start it again or remove it.

1.- Realiza las siguientes tareas desde un terminal:

  • crea dos contenedores detached interactivos de una imagen de ubuntu y llamalos ubu1 y ubu2
  • entra en ubu1 y crea un fichero con nombre test1 (pon alguna linea de texto, el contenido no importa). Sal de este contenedor con exit
  • entra en ubu2 y crea un fichero con nombre test2 (pon alguna linea de texto, el contenido no importa). Sal de este contenedor con 'CTRL+p CTRL+q'
  • usando docker exec ejecuta la orden ls -l en ambos contendedores. Explica la diferencia del resultado y como has procedido.

Para los comandos puedes utilizar como referencia el Seminario de Docker

Copia la secuencia de comandos utilizados y sus resultados en el documento a entregar

Networking with standalone containers

Networking overview

One of the reasons Docker containers and services are so powerful is that you can connect them together, or connect them to non-Docker workloads. Docker containers and services do not even need to be aware that they are deployed on Docker, or whether their peers are also Docker workloads or not. Whether your Docker hosts run Linux, Windows, or a mix of the two, you can use Docker to manage them in a platform-agnostic way.

This lab sessison introduces some basic Docker networking concepts and prepares you to design and deploy your applications to take full advantage of these capabilities.

Network drivers

Docker’s networking subsystem is pluggable, using drivers. Several drivers exist by default, and provide core networking functionality:

  • bridge: The default network driver. If you don’t specify a driver, this is the type of network you are creating. Bridge networks are usually used when your applications run in standalone containers that need to communicate.
  • host: For standalone containers, remove network isolation between the container and the Docker host, and use the host’s networking directly.
  • overlay: Overlay networks connect multiple Docker daemons together and enable swarm services to communicate with each other. You can also use overlay networks to facilitate communication between a swarm service and a standalone container, or between two standalone containers on different Docker daemons.
  • macvlan: Macvlan networks allow you to assign a MAC address to a container, making it appear as a physical device on your network. The Docker daemon routes traffic to containers by their MAC addresses. Using the macvlan driver is sometimes the best choice when dealing with legacy applications that expect to be directly connected to the physical network, rather than routed through the Docker host’s network stack.
  • none: For this container, disable all networking. Usually used in conjunction with a custom network driver.
  • Network plugins: You can install and use third-party network plugins with Docker. These plugins are available from Docker Hub or from third-party vendors.

Networking with standalone containers

This section includes two different steps:

  1. Use the default bridge network demonstrates how to use the default bridge network that Docker sets up for you automatically. This network is not the best choice for production systems.

  2. Use user-defined bridge networks shows how to create and use your own custom bridge networks, to connect containers running on the same Docker host. This is recommended for standalone containers running in production.

STEP 1: Use of the default bridge network

In this example, you have to start two different alpine containers on the same host and do some tests to understand how they communicate with each other.

FYI: alpine Linux is an independent, non-commercial, general purpose Linux distribution designed for users who appreciate security, simplicity and resource efficiency. This makes it smaller and more resource efficient than traditional GNU/Linux distributions. A container requires no more than 8 MB and a minimal installation to disk requires around 130 MB of storage.

Open a terminal window. List current networks before you do anything else. Here’s what you should see if you’ve never added a network or initialized a swarm on this Docker daemon. You may see different networks, but you should at least see these (the network IDs will be different):

$ docker network ls

NETWORK ID          NAME                DRIVER              SCOPE
17e324f45964        bridge              bridge              local
6ed54d316334        host                host                local
7092879f2cc8        none                null                local

The default bridge network is listed, along with host and none. The latter two are not fully-fledged networks, but are used to start a container connected directly to the Docker daemon host’s networking stack, or to start a container with no network devices.

Connect two containers to the bridge network.

Start two alpine containers running ash, which is Alpine’s default shell rather than bash. The -dit flags mean to start the container detached (in the background), interactive (with the ability to type into it), and with a TTY (so you can see the input and output). Since you are starting it detached, you won’t be connected to the container right away. Instead, the container’s ID will be printed. Because you have not specified any --network flags, the containers connect to the default bridge network.

$ docker run -dit --name alpine1 alpine ash
$ docker run -dit --name alpine2 alpine ash

2.- ¿Que diferencias has observado entre la ejecucion de un comando y la otra? ¿A que se debe?

Detalla la respuesta en el documento a entregar.

Check that both containers are actually started:

$ docker container ls

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
602dbf1edc81        alpine              "ash"               4 seconds ago       Up 3 seconds                            alpine2
da33b7aa74b0        alpine              "ash"               17 seconds ago      Up 16 seconds                           alpine1

Inspect the bridge network to see what containers are connected to it:

$ docker network inspect bridge

3.- ¿Que direccion IP tiene asignado el gateway entre el Docker host y la red? ¿Que direccion IP tienen los containers 'alpine1' y 'alpine2'?

Detalla la respuesta en el documento a entregar.

The containers are running in the background. Use the docker attach command to connect to 'alpine1'.

$ docker attach alpine1
/ #

The prompt changes to # to indicate that you are the root user within the container. Use the ip addr show command to show the network interfaces for 'alpine1' as they look from within the container:

# ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
27: eth0@if28: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:2/64 scope link
       valid_lft forever preferred_lft forever

The first interface is the loopback device. Ignore it for now. Notice that the second interface has the IP address 172.17.0.2, which is the same address shown for 'alpine1' in the previous step.

From within alpine1, make sure you can connect to the internet by pinging google.com. The -c 2 flag limits the command to two ping attempts.

# ping -c 2 google.com

PING google.com (172.217.3.174): 56 data bytes
64 bytes from 172.217.3.174: seq=0 ttl=41 time=9.841 ms
64 bytes from 172.217.3.174: seq=1 ttl=41 time=9.897 ms

--- google.com ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 9.841/9.869/9.897 ms

Now try to ping the second container. First, ping it by its IP address, 172.17.0.3:

# ping -c 2 172.17.0.3
PING 172.17.0.3 (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.086 ms
64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.094 ms

--- 172.17.0.3 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.086/0.090/0.094 ms

This succeeds. Next, try pinging the 'alpine2' container by container name this will fail. We will see later why.

# ping -c 2 alpine2
ping: bad address 'alpine2'

Detach from alpine1 without stopping it by using the detach sequence, CTRL+p CTRL+q (hold down CTRL and type p followed by q).

Stop and remove both containers.

$ docker container stop alpine1 alpine2
$ docker container rm alpine1 alpine2

STEP 2: Use user-defined bridge networks

In this section, we you will again use two alpine containers, but you will attach them to a user-defined network called 'alpine-net'. These containers will not be connected to the default bridge network at all. We will then start a third alpine container connected to the bridge network but not connected to 'alpine-net', and a fourth alpine container connected to both networks.

Creating the 'alpine-net' network.
The --driver bridge flag is not necessary since it is the default option; is used in this example just to show how to specify it.

$ docker network create --driver bridge alpine-net

List Docker’s networks:

$ docker network ls

NETWORK ID          NAME                DRIVER              SCOPE
e9261a8c9a19        alpine-net          bridge              local
17e324f45964        bridge              bridge              local
6ed54d316334        host                host                local
7092879f2cc8        none                null                local

4.- Determina la IP de la red 'alpine-net' y si tiene containers conectados usando la orden 'inspect' que has utilizado anteriormente. ¿Que direccion tiene el bridge de default?

Detalla la respuesta y como la has obtenido en el documento a entregar.

Create your four containers. Notice the --network flags. You can only connect to one network during the docker run command, so you need to use docker network connect afterward to connect 'alpine4' to the bridge network as well.

$ docker run -dit --name alpine1 --network alpine-net alpine ash
$ docker run -dit --name alpine2 --network alpine-net alpine ash
$ docker run -dit --name alpine3 alpine ash
$ docker run -dit --name alpine4 --network alpine-net alpine ash
$ docker network connect bridge alpine4

5.- Dibuja la red implementada, te servirà como referencia.

Apunta el resultado en el documento a entregar.

Verify that all containers are running:

$ docker container ls

CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS               NAMES
156849ccd902        alpine              "ash"               41 seconds ago       Up 41 seconds                           alpine4
fa1340b8d83e        alpine              "ash"               51 seconds ago       Up 51 seconds                           alpine3
a535d969081e        alpine              "ash"               About a minute ago   Up About a minute                       alpine2
0a02c449a6e9        alpine              "ash"               About a minute ago   Up About a minute                       alpine1

Inspect the bridge network and the alpine-net network again:

$ docker network inspect bridge

You will see that containers 'alpine3' and 'alpine4' are connected to the bridge network.

$ docker network inspect alpine-net

Which shows that containers 'alpine1', 'alpine2', and 'alpine4' are connected to the alpine-net network.

On user-defined networks like alpine-net, containers can both communicate by IP address, and can also resolve a container name to an IP address. This capability is called automatic service discovery.

6.- Conectate a 'alpine1' y usando 'ping' comprueba que es posible resolver automaticamente las direcciones de 'alpine2' and 'alpine4' a direccione IP.

Detalla la respuesta y como la has obtenido en el documento a entregar

From 'alpine1', you should not be able to connect to 'alpine3' at all, since it is not on the ''alpine-net'' network.

# ping -c 2 alpine3
ping: bad address 'alpine3'

Not only that, but you can’t connect to 'alpine3' from 'alpine1' by its IP address either.

7.- Determina la IP de 'alpine3' e intenta hacerle un ping. ¿Que resultado obtienes?

Detalla la respuesta y como la has obtenido en el documento a entregar.

Detach from 'alpine1' using the detach sequence, (CTRL+p CTRL+q).

Remember that 'alpine4' is connected to both the default bridge network and 'alpine-net'. It should be able to reach all of the other containers. However, you will need to address alpine3 by its IP address. Attach to it and run the tests.

8.- Conectate a 'alpine4' e intenta hacer 'ping' a las otras maquinas. ¿Puedes alcanzar todas? ¿Con su IP o con su nombre?

Detalla la respuesta y como la has obtenido en el documento a entregar.

9.- Como prueba final, comprueba de que todos los contenedores se puedan conectar a Internet haciendo ping a google.com. Ya estás conectado a alpine4, así que comienza intentando desde allí. A continuación, desconectate de 'alpine4' y conéctate a 'alpine3' (que solo está conectado a la red del bridge) e intenta nuevamente. Finalmente, conéctate a 'alpine1' (que solo está conectado a la red 'alpine-net') e intenta nuevamente.

Detalla la respuesta y como la has obtenido en el documento a entregar.