Introducció

Linux és un sistema operatiu que permet aïllar un procés de tots els recursos del sistema: cpu, memoria, sistema de fitxers, etc.

A diferència de les màquines virtuals que necessiten un Hypervisor, ls contenidors s’executen directament en el sistema operatiu i fan servir capacitats que proporciona directament el kernel de linux.

Arrenca una màquina virtual Ubuntu amb WSL.

Instal.la docker:

$ sudo apt update
$ sudo apt -y install docker.io

Per defecte, l'ordre docker només la pot executar usuari root o per un usuari del grup docker que es crea automàticament durant el procés d'instal·lació.

Afegeix el teu usuari al grup docker:

$ sudo usermod -aG docker ${USER}
$ su - ${USER}
$ grep ^docker /etc/group

Executar un contenidor és molt fàcil:

$ docker run hello-world

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
c1ec31eb5944: Pull complete 
Digest: sha256:d000bc569937abbe195e20322a0bde6b2922d805332fd6d8a68b19f524b7d21d
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

Pots veure que docker baixa la imatge hello-world i executa un contenidor amb aquesta imatge.

Recorda que pots fer servir la tecla tab per autocompletar les comandes docker!

Contenidor

A diferència de les màquines virtuals, els contenidors Docker no utilitzen cap virtualització de maquinari.

Cada contenidor s’executa en un espai aïllat, però tots comparteixen el mateix sistema operatiu.

A continuació anem a verificar aquesta afirmació amb el servidor web Nginx!

Verifica que no s'està executant cap procés nginx:

$ ps aux | grep nginx

Instal.la nginx amb apt:

$ sudo apt install -y nginx

Pots veure que el servidor web és accessible a http://localhost:

$ curl http://localhost

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
</html>

També que s'estan executant 5 processos nginx, 1 master i 4 workers:

$ ps aux | grep nginx

root        3968  0.0  0.1  55236 12124 ?        S    08:00   0:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
www-data    3970  0.0  0.0  55872  5640 ?        S    08:00   0:00 nginx: worker process
www-data    3971  0.0  0.0  55872  5640 ?        S    08:00   0:00 nginx: worker process
www-data    3972  0.0  0.0  55872  5640 ?        S    08:00   0:00 nginx: worker process
www-data    3973  0.0  0.0  55872  5640 ?        S    08:00   0:00 nginx: worker process
david       5544  0.0  0.0   4028  2084 pts/0    S+   08:04   0:00 grep --color=auto nginx

El número de processos worker variará en funció del número de nuclis de processament del processador.

Elimina nginx i verifica que ja no hi ha cap procés "nginx":

$ sudo apt remove -y nginx && sudo apt -y autoremove
...
$ ps aux | grep nginx

A continuació executarem un servidor nginx mitjançant un contenidor:

$ docker run --rm -d --name web_server nginx

Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
b0a0cf830b12: Already exists
...
e58cbd904f7f: Pull complete
Digest: sha256:32e76d4f34f80e479964a0fbd4c5b4f6967b5322c8d004e9cf0cb81c93510766
Status: Downloaded newer image for nginx:latest
778210860be3a1c03acb99113a11059cf117e260c7c7c0b0dd5f24a84ca86fdf

Les opcions que hem fet servir amb docker run són:

  • --rm: quan es pari el contenidor, el contenidor s’esborrarà
  • -d: que el contenidor s’executi en segon plà
  • --name web_server: li posem un nom al contenidor

Amb la comanda docker ps pots veure tots els contenidors que estan en execució:

$ docker ps

CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS     NAMES
25f7cafa90c9   nginx     "/docker-entrypoint.…"   1 minutes ago   Up 1 minutes   80/tcp    web_server

Pots veure que s’han arrencat 5 processos nginx en el meu sistema operatiu (no hi ha cap virtualització):

$ ps aux | grep nginx

root        2823  0.0  0.0  11400  7440 ?        Ss   00:03   0:00 nginx: master process nginx -g daemon off;
systemd+    2866  0.0  0.0  11864  2796 ?        S    00:03   0:00 nginx: worker process
systemd+    2867  0.0  0.0  11864  2796 ?        S    00:03   0:00 nginx: worker process
systemd+    2868  0.0  0.0  11864  2796 ?        S    00:03   0:00 nginx: worker process
systemd+    2869  0.0  0.0  11864  2796 ?        S    00:03   0:00 nginx: worker process
david       4328  0.0  0.0   4028  2100 pts/0    S+   00:09   0:00 grep --color=auto nginx

I pots veure que el servidor web no és accessible a http://localhost:

$ curl http://localhost

curl: (7) Failed to connect to localhost port 80 after 0 ms: Connection refused

Anem a mirar amb Nmap que no estigui escoltant a un altre port:

$ sudo apt install -y nmap
$ nmap -p- localhost

Nmap scan report for localhost (127.0.0.1)
PORT      STATE SERVICE
34091/tcp open  unknown
42843/tcp open  unknown

$ curl localhost:34091

Forbidden.

Espai aïllat

Un contenidor s'executa en un espai aïllat que més endavant veurem com es pot anar obrint.

De moment entrarem "dins" del contenidor per poder veure el sistema operatiu tal com el veuen els processos que s'estan executant dins el contenidor.

Amb aquesta comanda exeutem (exec) bash en el contenidor amb nom web_server en una sessió interactiva (-it):

$ docker exec -it web_server bash

Dins del contenidor pots veure que el sevidor web és accesible:

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

Canvia el contingut de la pàgina d'inici perquè sigui més curta i personal:

$ echo "Hola mon!" > usr/share/nginx/html/index.html

$ curl localhost

Hola mon!

Surt del contenidor i verifica que el fitxer usr/share/nginx/html/index.html s'ha modificat:

$ cat usr/share/nginx/html/index.html

more: cannot open usr/share/nginx/html/index.html: No such file or directory

El fitxer no existeix! Que ha passat?

Tornem a entrar dins el contenidor, potser s'ha esborrat ...

$ docker exec -it web_server bash

$ cat usr/share/nginx/html/index.html

Hola mon!

Pots veure que el fitxer existeix dins el contenidor, però no fora del contenidor.

I també que la vida del fitxers creats o modificats dins el contenidor està lligat a la vida del contenidor.

Crea un nou fitxer, surt del contenidor, para el contenidor (s'eliminarà perquè l'hem creat amb l'opció --rm) i torna a crear-lo de nou per veure que tots els canvis han desaparegut:

$ echo "Plou i fa sol ..." > plou.txt
$ cat plou.txt
Plou i fas sol ...

$ exit
$ docker stop web_server
$ docker run --rm -d --name web_server nginx
$ docker exec -it web_server bash

$ cat plou.txt
cat: plou.txt: No such file or directory

$ cat /usr/share/nginx/html/index.html | head -n 5
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>

PID Namespace

Dins del contenidor anem a veure tots els procesos que s'estan executant:

$ ps
bash: ps: command not found

Resulta que el el contenidor no pot accedir a l'executable ps del sistema de fitxers del sistema operatiu!

Doncs haurem d'instal.lar el paquet procps dins el contenidor:

root@6b9c24819095:/# apt update
root@6b9c24819095:/# apt install -y procps

Dins el contenidor sudo no funciona perquè quan entres al contenidor ets l'usuari root, però només dins el contenidor.

Ja podem veure quins processos estan en execució:

$ ps aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.0  0.0  11400  7108 ?        Ss   06:43   0:00 nginx: master process nginx -g daemon off;
nginx         29  0.0  0.0  11864  2760 ?        S    06:43   0:00 nginx: worker process
nginx         30  0.0  0.0  11864  2760 ?        S    06:43   0:00 nginx: worker process
nginx         31  0.0  0.0  11864  2760 ?        S    06:43   0:00 nginx: worker process
nginx         32  0.0  0.0  11864  2760 ?        S    06:43   0:00 nginx: worker process
root          33  0.0  0.0   4188  3484 pts/0    Ss+  06:43   0:00 bash
root          47  0.0  0.0   4188  3396 pts/1    Ss   11:17   0:00 bash
root         243  0.0  0.0   8112  4116 pts/1    R+   11:23   0:00 ps aux

Pots veure que dins el contenidor només s'estan executant els processos nginx i els de la sessió.

A més, el PID dels processos nginx no coincideixen amb els que haviem vist abans fora del processador.

I encara més sospitós, el procés amb el PID 1, el primer en executar-se en arrancar el sistema operatiu és el nginx master!

Sortim del contenidor amb l'ordre exit i tornem a mirar des de fora del contenidor quins són els processos nginx que estan en execució:

$ ps aux | grep nginx
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root       26783  0.0  0.0  11400  7108 ?        Ss   08:43   0:00 nginx: master process nginx -g daemon off;
systemd+   26835  0.0  0.0  11864  2760 ?        S    08:43   0:00 nginx: worker process
systemd+   26836  0.0  0.0  11864  2760 ?        S    08:43   0:00 nginx: worker process
systemd+   26837  0.0  0.0  11864  2760 ?        S    08:43   0:00 nginx: worker process
systemd+   26838  0.0  0.0  11864  2760 ?        S    08:43   0:00 nginx: worker process
david     137704  0.0  0.0   4028  2104 pts/5    S+   13:33   0:00 grep --color=auto nginx

Encara que el PID (i el USER) sigui diferent en tot el demés sembla que són els mateixos processos.

El COMMAND és el mateix, els valors VSZ (Virtual Memory Size) i RSS (Resident Set Size) són iguals, l' START coincideix, etc.

Però en informàtica s’aprén provant coses i experimentant, i la manera més fàcil d'estar segurs és eliminar un procés a veure que passa.

Elimina el procés 26838:

$ sudo ps kill 26838

Si ara mirem els processos que s'executen dins el contenidor veurás que el procés 32 també s'ha eliminat, i ha aparegut un procés que abans no estava, el 250:

$ docker exec web_server ps aux
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.0  0.0  11400  7508 ?        Ss   06:43   0:00 nginx: master process nginx -g daemon off;
nginx         29  0.0  0.0  11864  2760 ?        S    06:43   0:00 nginx: worker process
nginx         30  0.0  0.0  11864  2760 ?        S    06:43   0:00 nginx: worker process
nginx         31  0.0  0.0  11864  2760 ?        S    06:43   0:00 nginx: worker process
nginx        250  0.0  0.0  11864  2760 ?        S    19:57   0:00 nginx: worker process
root         257  100  0.0   8112  4048 ?        Rs   19:57   0:00 ps aux

Aquest cop no hem iniciat una sessió interactiva sinó que ens hem limitat a executar la comanda dins de l'espai del contenidor.

Com hem dit abans, nginx és un servidor web que executa un master procés, que s’encarrega d’executar dos o més worker procés que gestionen les sol.licitus web.

Si un worker process deixa de funcionar o ha de canviar la configuració, el master process executarà altres worker process.

Per estar segurs elimina tots els worker process de nginx, pero ara desde el mateix contenidor:

$ docker exec web_server pkill -u nginx
$ docker exec web_server ps aux

USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root           1  0.0  0.0  11400  7508 ?        Ss   06:43   0:00 nginx: master process nginx -g daemon off;
nginx        288  0.0  0.0  11864  2760 ?        S    20:06   0:00 nginx: worker process
nginx        289  0.0  0.0  11864  2760 ?        S    20:06   0:00 nginx: worker process
nginx        290  0.0  0.0  11864  2760 ?        S    20:06   0:00 nginx: worker process
nginx        291  0.0  0.0  11864  2760 ?        S    20:06   0:00 nginx: worker process
root         292 33.3  0.0   8112  4020 ?        Rs   20:06   0:00 ps aux

Desde fora del contenidor també podem veure que s'han crear processos nginx worker nous:

$ ps aux | grep nginx
root       26783  0.0  0.0  11400  7508 ?        Ss   08:43   0:00 nginx: master process nginx -g daemon off;
systemd+  321410  0.0  0.0  11864  2760 ?        S    22:06   0:00 nginx: worker process
systemd+  321411  0.0  0.0  11864  2760 ?        S    22:06   0:00 nginx: worker process
systemd+  321412  0.0  0.0  11864  2760 ?        S    22:06   0:00 nginx: worker process
systemd+  321413  0.0  0.0  11864  2760 ?        S    22:06   0:00 nginx: worker process
david     322652  0.0  0.0   4028  2172 pts/5    S+   22:09   0:00 grep --color=auto nginx

I per acabar de confirmar el que ja sabem anem a matar el procés amb el PID 1 del contenidor desde fora del contenidor:

$ sudo kill 26783
$ ps aux | grep nginx

david     323593  0.0  0.0   4028  2016 pts/5    S+   22:11   0:00 grep --color=auto nginx

Pots veure que tots els processos nginx han desaparegut!

També en el contenidor?

$ docker exec web_server ps aux
Error response from daemon: No such container: web_server

El contenidor ha deixat d'existir!

Si matem el próces amb PID 1 és el que passa.

Pots confirmar amb l'ordre docker ps que ho hi ha cap contenidor amb el nom web_server:

$ docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

Activitats

1.- Instal.la el servidor web Apache amb apt, crea de nou el contenidor web_server i verifica que desde dins el contenidor no pots matar el procés apache.

$ sudo apt install -y apache2
...

2.- Elimina el servidor apache, crea un nou contenidor web_apache amb la imatge httpd2 i verifica que desde el contenidor web_server no pots matar al contenidor web_apache i al revés tampoc.

$ sudo apt remove -y apache2
$ docker run --rm -d --name web_apache httpd
...

3.- Explica els resultats obtinguts.

Només puc matar un procés si tinc el seu PID, però dins del contenidor ...

TODO Acabar de revisar i completar

Control de contenidors

Creació i posada en marxa d'un nou contenidor

Un contenidor es crea a partir d’una imatge.

Per defecte aquesta imatge es descarrega de Docker Hub.

Per exemple, aquí tens la informació de nginx: nginx - Official Image | Docker Hub

Quan executes aquesta ordre, docker baixa la imatge especificada (si no la té guardada), i instal.la i inicia un contenidor amb nginx:

$ docker run --detach --name web nginx
93628c5fa9c805d741ab9193693e0acae8079b2f55eb32302752119e17c62b25

Pots veure que el contenidor retorna un hash criptogràfic (Criptografia) que és l’identificador del contenidor.

Cada vegada que executes docker run i crees un contenidor nou, aquest nou contenidor obtindrà un identificador únic.

Encara que l’identificador únic és molt útil molts cops volem poder anomenar un contenidor per un nom concret.

Per això passem el flag --name web

Com que volem que el contenidor s’executi en segon pla passem també el flag -d ( o --detach)

Pots comprovar que hi ha un contenidor en execució anomenat web executant-se al port 80/tcp amb l’ordre docker ps:

$ docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS     NAMES
93628c5fa9c8   nginx     "/docker-entrypoint.…"   9 minutes ago   Up 9 minutes   80/tcp    web

Execució de contenidors interactius

Si vols executar un contenidor de manera interactiva has d’utilitzar el flag -it:

$ docker run -it fedora:40 bash

Enlloc de -it també pots escriure --interactive --tty, però -it és molt més curt.

El flag --interactive diu a Docker que mantingui el flux d'entrada estàndard (stdin) obert per al contenidor encara que no hi hagi cap terminal connectat.

El flag --tty indica a Docker que assigni un terminal virtual per al contenidor, que us permetrà passar senyals al contenidor. Això és normalment el que voleu d'un programa interactiu de línia d'ordres.

Normalment utilitzem els dos flags quan executem un programa interactiu, com ara un shell.

També has especificat el programa que s'executarà dins del contenidor. En aquest cas, has executat un programa shell anomenat bash.

Pots executar qualsevol programa que estigui disponible dins del contenidor.

systemd

Com que estás en un contenidor fedora, encara que estiguis en un sistema operatiu ubuntu les coses són diferents.

Per exemple ja no tens apt:

$ apt -y update
bash: apt: command not found

En fedora és dnf:

$ dnf -y update
...

Pots instal.lar un servidor Nginx amb el paquet rpm de Fedora 40 en un sistema operatiu Ubuntu!

$ dnf install -y nginx

Un contenidor no és una màquina virtual, i no puc arrencar nginx amb systemctl:

$ systemctl status nginx
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down

En un contenidor el procés amb PID 1 no és init sinó el que ve per defecte en el contenidor o el que tu dius al contenidor que executi, en el nostre cas bash.

$ dnf install -y procps
$ ps
    PID TTY          TIME CMD
      1 pts/0    00:00:00 bash
    239 pts/0    00:00:00 ps

Solució? Arrencar nginx manualment:

$ nginx
$ curl localhost
<!doctype html>
<html>
  <head>
    <meta charset='utf-8'>
...

Amb l’ordre exit pots sortir del contenidor.

Al sortir del contenidor aquest s'atura.

Llistar, aturar, reiniciar i visualitzar la sortida dels contenidors

El primer que has de fer per provar la vostra configuració actual és comprovar quins contenidors s'estan executant actualment mitjançant l'ordre docker ps:

L'execució de l'ordre mostra la informació següent sobre cada contenidor en execució:

  • L'identificador del contenidor
  • La imatge utilitzada
  • L'ordre executada al contenidor
  • El temps des que es va crear el contenidor
  • La durada que el contenidor ha estat en funcionament
  • Els ports de xarxa exposats pel contenidor
  • El nom del contenidor
$ docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
93628c5fa9c8   nginx     "/docker-entrypoint.…"   33 minutes ago   Up 33 minutes   80/tcp    web

Logs

Si vols veure el log d’un contenidor ho pots fer amb l’ordre docker logs indicant el nom o el id del contenidor:

docker logs web
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
...

Qualsevol cosa que el programa escriu a stdout o stderr s'enregistrarà en aquest registre.

El problema d'aquest és que el registre mai es gira ni es trunca per defecte, de manera que les dades escrites al registre d'un contenidor es mantindran i creixeran mentre el contenidor existeixi.

Si un contenidor ha d’estar molt temps funcionant és convenient utilitzar un volum pels logs (a Emmagatzematge s'explica que és un volum).

Amb l'ordre docker logs pots utilizar el flag --follow o -f, que et mostra els registres i després continua mirant i actualitzant la pantalla amb els canvis al registre a mesura que es produeixen.

Stop

L'ordre docker stop indica al programa amb PID 1 del contenidor que s'aturi.

$ docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
93628c5fa9c8   nginx     "/docker-entrypoint.…"   38 minutes ago   Up 38 minutes   80/tcp    web
isard@ubuntu:~/site$ docker stop web
web
isard@ubuntu:~/site$ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

Estat del contenidor

Un contenidor Docker es pot trobar en un d'aquests estats:

Per començar elimina tots els contenidors:

$ docker rm -vf $(docker ps -a -q)
09298a8329b7
138d1486c45e
93628c5fa9c8
e7faec8ed4ae
aafbf01a964b
c9945771bffe
597d2a64ca8a

A continuació crea un contenidor:

$ docker create --name web nginx
ed309de86bc707305da5973516dd131002701ca071162c1cdef834568a6c12be

$ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

💡 El contenidor que hem creat no apareix a la llista de contenidors perquè per defecte docker ps només mostra contenidors que estan executant-se.

Per veure tots els contenidors (inclosos els que hi estan en estat creat) utilitza l'opció -a:

$ docker ps -a
CONTAINER ID   IMAGE     COMMAND                  CREATED              STATUS    PORTS     NAMES
ed309de86bc7   nginx     "/docker-entrypoint.…"   About a minute ago   Created             web

Pots arrencar un contenidor aturat amb l'ordre docker start:

$ docker start web
web

$ docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS     NAMES
ed309de86bc7   nginx     "/docker-entrypoint.…"   2 minutes ago   Up 3 seconds   80/tcp    web

Si vols crear i arrencar un contenidor amb una sola ordre pots executar docker run com has estat fent fins ara.

remove

La facilitat de esborrar tot de manera molt fàcil és un dels motius importants pels quals es fa servir docker.

Un contenidor està confinat, només has d'identificar el contenidor que vols aturar i/o eliminar.

💡 Recorda que per enumerar tots els contenidors del teu ordinador has d’executar l'ordre docker ps -a:

$ docker ps -a --format "table {{.ID}}\t{{.Names}}\t{{.Status}}" 
CONTAINER ID   NAMES     STATUS
ed309de86bc7   web       Up 3 minutes

Ja pots eliminar el contenidor indicant el nom (si en té) o l'ID (només cal els primers digits):

$ docker rm ed309
Error response from daemon: You cannot remove a running container ed309de86bc707305da5973516dd131002701ca071162c1cdef834568a6c12be. Stop the container before attempting removal or force remove

💡 Per a eliminar un contenidor aquest ha d'estat aturat (els processos que s’executen dins el contenidor han d’estar aturats).

  1. Pots executar l' ordre docker stop que envia una senyal SIG_HUP perquè els processos en execució tinguin temps per realitzar tasques de finalització i neteja.

El temps estàndard màxim d’aturada és de 30 segons.

$ docker stop ed309
ed309
$ docker rm ed309
ed309
  1. Pots executar l’ordre docker rm -f.

En aquest cas s’envia un senyal SIG_KILL que finalitza immediatament els processos en execució.

Es pot produir una corrupció de fitxers o no terminar correctament una connexió web.

Eliminació automàtica

Si vols executar un contenidor que s'elimini de manera automàtica quan s'atura pots utilitzar el flag --rm.

Per exemple, si no tinc instal.lat nmap i vull escanejar una xarxa sense tenir que instal.lar nmap (veure Nmap), podem executar nmap mitjançant un contenidor.

$ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

$ docker run --rm jonlabelle/nmap www.google.es
...
Starting Nmap 7.95 ( https://nmap.org ) at 2024-06-04 14:45 UTC
...
PORT    STATE SERVICE
80/tcp  open  http
443/tcp open  https

$ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

Si vols eliminar tots els contenidors pots executar aquesta comanda:

$ docker rm -vf $(docker ps -a -q)

"docker rm" requires at least 1 argument.
...

Si no hi ha cap contenidor dóna error (cap problema).

Reinici automàtic dels contenidors

Una estratègia bàsica per recuperar-se d'errors temporals és reiniciar automàticament un procés quan aquest finalitza de manera inesperada.

Quan crees un contenidor pots utilitzar l’opció --restart per dir a docker que ha de fer quan s’atura un contenidor.

Si executo aquest contenidor l’únic que fa és imprimir la data i s’atura:

$ docker run busybox date
Tue Jun  4 14:48:52 UTC 2024

$ docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED          STATUS                      PORTS     NAMES
6e6986ff0fbd   busybox   "date"    24 seconds ago   Exited (0) 23 seconds ago             nifty_kilby

Si vull que mai s’aturi puc utilitzar l’opció --restart always:

$ docker run --restart always busybox date
Tue Jun  4 14:51:06 UTC 2024

En principi sembla que no hi ha diferència, excepte que si mires els contenidor que estan actius pots veure que segueix actiu perquè docker no para de torna a arrencar-lo:

$ docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED              STATUS                          PORTS     NAMES
e79582dbf0db   busybox   "date"    About a minute ago   Restarting (0) 28 seconds ago             amazing_galois

Altre cosa és que ja no pugui enviar la data al terminal.

Per saber totes les opcions mira Running containers

Variables d'entorn

Les variables d'entorn són parells clau/valor que es posen a disposició dels programes a través del seu context d'execució.

Et permet canviar la configuració d'un programa sense modificar cap fitxer ni canviar l'ordre utilitzada per iniciar el programa.

Si vols passar una variable d’entorn a un contenidor pots utilitzar l’opció --env:

$ docker run --rm -it --env NAME=david --env PASSWORD=password busybox sh
... $ echo $NAME
    david
    $ echo $PASSWORD
    password
    $ exit
$

Activitat

La distribució Ubuntu fa servir el kernel Linux i afegeix una sèrie de fitxers i llibreries per crear una distribució concreta.

Anem a veure com era Ubuntu 14.04:

$ docker run -it --name ubuntu_14 ubuntu:14.04 /bin/bash

Aquesta comanda baixa una imatge ubuntu:14.04, arrenca un contenidor, dins del contenidor executa la comanda /bin/bash i obre un terminal amb una sessió interactiva amb el contenidor (es semblant a un ssh).

Instal.la el servidor apache, verifica que funciona i mira quina era l’última versió que es podia instal.lar a Ubuntu 14.04.

... $ apt-get update
    $ apt-get install -y apache2
    $ service apache2 start
    $ service apache2 status
    $ apache2 -v
    Server version: Apache/2.4.7 (Ubuntu)
    Server built:   Apr  3 2019 18:04:25

Des de dins del contenidor et pots connectar al servidor apache:

... $ apt-get install -y curl
    $ curl localhost

    $ apt-get install -y lynx
    $ lynx localhost

Però que passa en el host, fora del contenidor?

Obre una altre sessió interactiva amb la màquina virtual i verifica que el contenidor està actiu:

$ docker ps
CONTAINER ID   IMAGE      	COMMAND   	CREATED      	STATUS      	PORTS 	NAMES
6e16afa03b61   ubuntu:14.04   "/bin/bash"   37 seconds ago   Up 36 seconds         	ubuntu_14

Si fem un curl a localhost no obtenim cap resposta:

$ curl localhost
curl: (7) Failed to connect to localhost port 80 after 0 ms: Connection refused

El servidor apache del contenidor no està escoltant al nostre localhost, sinó en un altre localhost.

A Xarxa veurem com funciona el confinament de xarxa.

Podem verificar que el servidor Apache no està instal.lat fora del contenidor:

$ apache2
bash: apache2: command not found

Quam hem instal.lat apache, s’ha descarregat un conjunt de fitxers que s’han superposat als fitxers existents mitjançant una capacitat dels Linux que és diu UnionFS.

A Emmagatzematge veurem com funciona el confinament de fitxers.

Si fas un ps pots verificar que apache2 s’està executant:

$ ps aux | grep apache
root   	15571  0.0  0.0  71340  4332 ?    	Ss   17:46   0:00 /usr/sbin/apache2 -k start
33     	15574  0.0  0.0 360504  4044 ?    	Sl   17:46   0:00 /usr/sbin/apache2 -k start
33     	15575  0.0  0.0 360504  4044 ?    	Sl   17:46   0:00 /usr/sbin/apache2 -k start

Un contenidor no és una màquina virtual, el que fa Linux és aïllar els processos del host dels processos del contenidor.

Executa ps dins el contenidor i verifica que el contenidor no tè accés al processos del host:

... $ ps aux
    USER     	PID %CPU %MEM	VSZ   RSS TTY  	STAT START   TIME COMMAND
    root       	1  0.0  0.0  18188  3280 pts/0	Ss   16:04   0:00 /bin/bash
    root     	738  0.0  0.0  71340  4332 ?    	Ss   16:46   0:00 /usr/sbin/apache2 -k start
    www-data 	741  0.0  0.0 360504  4044 ?    	Sl   16:46   0:00 /usr/sbin/apache2 -k start
    www-data 	742  0.0  0.0 360504  4044 ?    	Sl   16:46   0:00 /usr/sbin/apache2 -k start
    root     	803  0.0  0.0  15584  2216 pts/0	R+   16:50   0:00 ps aux

A més pots veure que el PID dels tres processos apache no coincideix encara que són els mateixos processos.

Elimina un procés al contenidor i verifica que també s’elimina al host