Comandos básicos de Docker

El otro día vimos como instalar un cluster de docker con swarm. Mas adelante veremos como se monta un cluster de Docker con Kubernettes. Tanto Swarm como Kubernettes son orquestadores de docker y para entender como funcionan antes debemos entender como usar Docker a pelo.

Docker puede funcionar perfectamente en una sola máquina y no es necesario montar un cluster, para tenerlo a mano, pego en modo resumen la parte de instalación de docker del anterior post (instalación en Debian):

root@docker-master:~# apt update && apt -y upgrade && apt -y dist-upgrade
root@docker-master:~# apt-get remove docker docker-engine docker.io containerd runc
root@docker-master:~# apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
root@docker-master:~# curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
root@docker-master:~# apt-key fingerprint 0EBFCD88
root@docker-master:~# add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"
root@docker-master:~# apt update
root@docker-master:~# apt-get install docker-ce docker-ce-cli containerd.io

Una vez instalado Docker, voy a explicar de que va ésto.

Docker es un software de virtualización. La virtualización nace en AIX, el sistema operativo de los mainframes de IBM. La virtualización nace de la necesidad de correr otros sistemas operativos dentro de un sistema operativo. A lo largo de los años y a medida que los servidores y ordenadores de sobremesa han sido mas potentes, han ido apareciendo muchos programas y métodos de virtualización.
Por un lado tenemos los sistemas de virtualización de un sistema operativo entero como podrían ser VirtualBox, VMWare, KVM, Xen, etc. y mas adelante salieron otros sistemas que compartían el núcleo del sistema operativo (kernel) con el host.
Con Docker, tenemos una siguiente evolución, la “virtualización por capas”. Cuando en una máquina virtual con KVM o con LXC tenemos que instalar aplicaciones, en Docker añadimos éstas aplicaciones en capas. Cuando desplegamos un contenedor de docker, las aplicaciones ya están preparadas y desplegadas para su funcionamiento, cosa que ahorra mucho tiempo de instalación y de resolución de fallos, ya que el fabricante, desarrollador o empaquetador nos ha preparado el entorno para que al arrancar el contenedor ya esté la aplicación lista para su uso. La buena práctica de Docker es destinar un servicio por contenedor (microservicios), por ejemplo en un wordpress, un contenedor para la base de datos y otro para el servidor web con los ficheros de la instalación de wordpress.

Mi infraestructura actual se basa en clústers de proxmox corriendo contenedores LXC y máquinas virtuales KVM. En las máquinas virtuales KVM cuando queremos instalar un sistema operativo lo haríamos tal como lo haríamos con un ordenador normal y corriente (iso y seguir los pasos de instalación). En LXC disponemos de unos templates que nos descargamos y luego desplegamos, éstos templates contienen sistemas operativos ya preparados para su uso y sólo tenemos que instalar las aplicaciones que necesitemos. Hay algunos templates ya vienen preparados con aplicaciones. Con LXC nos ahorramos el paso de la instalación pero no nos ahorramos el paso de la configuración. Docker pretende ahorrarnos también el paso de la configuración y permitir así despliegues aún más ágiles.

¿Cómo funciona Docker?
Básicamente nos descargamos una imagen “precocinada” del repositorio de Docker DockerHub y la desplegamos en nuestra máquina.
A continuación vemos un conjunto de comandos que debemos aprender si queremos trabajar con Docker. En algunos manuales que he leído para entender docker el orden de los comandos que se enseñan es otro y personalmente me llevaba a cierta confusión, así que aquí propongo la mía :P

Primero de todo mencionar que todos los ficheros que se generen con Docker van a ir almacenados a /var/lib/docker

root@docker-master:~# ls /var/lib/docker/
builder   containers  network	plugins   swarm  trust
buildkit  image       overlay2	runtimes  tmp	 volumes

Buscar imagenes en el repositorio de dockerhub

root@docker-master:~# docker search debian
NAME                                               DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
ubuntu                                             Ubuntu is a Debian-based Linux operating sys…   11483               [OK]                
debian                                             Debian is a Linux distribution that's compos…   3644                [OK]                
arm32v7/debian                                     Debian is a Linux distribution that's compos…   66                                      
itscaro/debian-ssh                                 debian:jessie                                   28                                      [OK]
arm64v8/debian                                     Debian is a Linux distribution that's compos…   23                                      
samueldebruyn/debian-git                           a minimal docker container with debian and g…   22                                      [OK]
multiarch/debian-debootstrap                       multiarch ports of debian-debootstrap           13                                      
i386/debian                                        Debian is a Linux distribution that's compos…   11                                      
eboraas/debian                                     Debian base images, for all currently-availa…   8                                       [OK]
vergissberlin/debian-development                   Docker debian image to use for development, …   6                                       [OK]
smartentry/debian                                  debian with smartentry                          5                                       [OK]
amd64/debian                                       Debian is a Linux distribution that's compos…   4                                       
ppc64le/debian                                     Debian is a Linux distribution that's compos…   4                                       
vicamo/debian                                      Debian docker images for all versions/archit…   3                                       
arm32v5/debian                                     Debian is a Linux distribution that's compos…   2                                       
vpgrp/debian                                       Docker images of Debian.                        2                                       
s390x/debian                                       Debian is a Linux distribution that's compos…   2                                       
spritsail/debian-builder                           A Docker image based on debian:slim ideal fo…   1                                       [OK]
dockershelf/debian                                 Repository for docker images of Debian. Test…   1                                       [OK]
holgerimbery/debian                                debian multiarch docker base image              1                                       
fleshgrinder/debian                                Debian base images for production and multis…   0                                       [OK]
jdub/debian-sources-resource                       Concourse CI resource to check for updated D…   0                                       [OK]
1and1internet/debian-9-nginx-php-7.2-wordpress-4   debian-9-nginx-php-7.2-wordpress-4              0                                       [OK]
casept/debian-amd64                                A debian image built from scratch. Mostly fo…   0                                       
mdoerges/debian-buster-nginx                       Debian Buster with Nginx                        0                                       

Descargar una imagen del repositorio dockerhub

root@docker-master:~# docker pull debian
Using default tag: latest
latest: Pulling from library/debian
e4c3d3e4f7b0: Pull complete 
Digest: sha256:8414aa82208bc4c2761dc149df67e25c6b8a9380e5d8c4e7b5c84ca2d04bb244
Status: Downloaded newer image for debian:latest
docker.io/library/debian:latest
root@docker-master:~# docker pull wynemo/python38
Using default tag: latest
latest: Pulling from wynemo/python38
afb6ec6fdc1c: Pull complete 
2cf47e503ea9: Pull complete 
d7b3e3d1255f: Pull complete 
e7661b83ac73: Pull complete 
aab48912491a: Pull complete 
960d5d303907: Pull complete 
8c6ab51d1b47: Pull complete 
6a6d63bba2c3: Pull complete 
Digest: sha256:60c3f28d6634cf4408712c87f02e52c2e354d070993647a064ef75c98af7f66a
Status: Downloaded newer image for wynemo/python38:latest
docker.io/wynemo/python38:latest

Ver imagenes montadas/descargadas en nuestra máquina

root@docker-master:~# docker images
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
debian                   latest              1510e8501783        3 weeks ago         114MB
portainer/portainer-ce                 a0a227bf03dd        2 months ago        196MB
portainer/agent                        6b367a5c4fe3        2 months ago        89.8MB
wynemo/python38          latest              3200f7c701d5        5 months ago        391MB

Ver datos de la imagen
Aquí nos podemos hacer una idea de como se va a construir ésta imagen, variables de entorno, configuración de puertos, etc.

root@docker-master:~# docker inspect debian

Ver datos de un contenedor contenedor

root@docker-master:~# docker inspect portainer_portainer.1.o2v7ve9123h9c2wcta0paqmi2

Lanzar un contenedor de Docker a partir de una imagen descargada

root@docker-master:~# docker run -dtiP --name contenedor debian
76ec0cdbabcb5b894dabc5e02068e0db620d1ed957b07802904297515efa3eb7

root@docker-master:~# docker run -dti -p 8080:80 --name wp wordpress
babc1e111bb3c05f66138ac68f669d5abb049eab4166d75b2e22e46fd437ec91

Opciones disponibles

-d -> dettach -> correr en background
-t terminal -> habilitar el acceso con terminal al contenedor
-i interactive -> permitir interactuar con el contenedor
--name nombrecontenedor -> nombre del contenedor, si no se define esta opción pone un nombre aleatorio
-e VAR=valuevar -> definir valores de las variables de entorno definidas en el Dockerfile
-P -> publish all, expone los puertos tal como están definidos en la imagen con un puerto aleatorio (30.000 al 32.800)
-p 8080:80 -> mapea el puerto 80 del contenedor al puerto 8080 del host
--rm -> cuando se pare el contenedor que se borre automáticamente
--restart=always -> si se para el contenedor vuelve a ponerlo en marcha
-v /voldatos:/var/lib/mysql -> monta el directorio /voldatos del host en /var/lib/mysql del contenedor

Otros ejemplos

docker run -dti nginx
docker run -dti --name frontal-nginx nginx
docker run -dtiP -v /voldatos:/var/lib/mysql
docker run -dti -p80:80 -v /voldatos:/var/lib/mysql
docker run -dti --name nomct -e VAR=valuevar 

Cuando mapeamos puertos estamos haciendo uso de iptables

root@docker-master:~# iptables -t nat -L DOCKER -v -n
Chain DOCKER (2 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 RETURN     all  --  docker_gwbridge *       0.0.0.0/0            0.0.0.0/0           
    0     0 RETURN     all  --  docker0 *       0.0.0.0/0            0.0.0.0/0           
    0     0 DNAT       tcp  --  !docker0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:8080 to:172.17.0.3:80

Cuando usamos NAT, por defecto la red interna de Docker es 172.17.0.0/16

Ver contenedores

Ver contenedores activos

root@docker-master:~# docker ps
CONTAINER ID        IMAGE                           COMMAND                  CREATED             STATUS              PORTS                  NAMES
babc1e111bb3        wordpress                       "docker-entrypoint.s…"   2 minutes ago       Up 2 minutes        0.0.0.0:8080->80/tcp   wp
76ec0cdbabcb        debian                          "bash"                   12 minutes ago      Up 12 minutes                              contenedor
19f3f9919ee0        portainer/agent:latest          "./agent"                4 days ago          Up 4 days                                  portainer_agent.nty1ejqatx2fsgpb6veclsqi9.s16d83o5fylxptyw6m40txmmp
de837dc53a72        portainer/portainer-ce:latest   "/portainer -H tcp:/…"   4 days ago          Up 4 days           8000/tcp, 9000/tcp     portainer_portainer.1.o2v7ve9123h9c2wcta0paqmi2

Ver todos los contenedores

root@docker-master:~# docker ps -a
CONTAINER ID        IMAGE                           COMMAND                  CREATED             STATUS                  PORTS                  NAMES
babc1e111bb3        wordpress                       "docker-entrypoint.s…"   2 minutes ago       Up 2 minutes            0.0.0.0:8080->80/tcp   wp
76ec0cdbabcb        debian                          "bash"                   12 minutes ago      Up 12 minutes                                  contenedor
19f3f9919ee0        portainer/agent:latest          "./agent"                4 days ago          Up 4 days                                      portainer_agent.nty1ejqatx2fsgpb6veclsqi9.s16d83o5fylxptyw6m40txmmp
de837dc53a72        portainer/portainer-ce:latest   "/portainer -H tcp:/…"   4 days ago          Up 4 days               8000/tcp, 9000/tcp     portainer_portainer.1.o2v7ve9123h9c2wcta0paqmi2
3e43aa6c7ba3        portainer/portainer-ce:latest   "/portainer -H tcp:/…"   4 days ago          Exited (1) 4 days ago                          portainer_portainer.1.ifij1hvkc6u3dnzs5s3lia0kh
b2bce3f683e6        portainer/portainer-ce:latest   "/portainer -H tcp:/…"   4 days ago          Exited (1) 4 days ago                          portainer_portainer.1.d1wnwcnm7e6anc4dt429jfyp9
39f260ff1a59        portainer/portainer-ce:latest   "/portainer -H tcp:/…"   4 days ago          Exited (1) 4 days ago                          portainer_portainer.1.ag2ovmy1e7q11k47zm2870fmv
d9fc2e2938b6        portainer/portainer-ce:latest   "/portainer -H tcp:/…"   4 days ago          Exited (1) 4 days ago                          portainer_portainer.1.q99tmtqpgxffnfv03v46spxui

Ver el último contenedor creado

root@docker-master:~# docker ps -l
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
babc1e111bb3        wordpress           "docker-entrypoint.s…"   2 minutes ago       Up 2 minutes        0.0.0.0:8080->80/tcp   wp

Entrar en un contenedor

root@docker-master:~# docker exec -ti contenedor /bin/bash
root@76ec0cdbabcb:/# cat /etc/os-release 
PRETTY_NAME="Debian GNU/Linux 10 (buster)"
NAME="Debian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

Otros comandos

docker rm ctname/ctid -> borrar contenedor (usar -f para borrarlo incluso si está encendido)
docker rmi imgname -> borrar imagen (creada con el dockerfile o descargada con docker pull)
docker stop ct -> parar contenedor
docker start ct -> arrancar contenedor
docker pause ct -> pausar contenedor
docker unpause ct -> despausar contenedor
docker logs ct -> ver los logs de la aplicación que corre dentro del contenedor
docker attach ct -> similar a exec -ti
docker stats ct -> ver las estadísticas de consumo del contenedor

docker stop $(docker ps -a -q) -> parar todos los contenedores
docker rm $(docker ps -a -q) -> borrar todos los contenedores

Poner límites y configurar un contenedor

root@docker-master:~# docker update --help

Usage:	docker update [OPTIONS] CONTAINER [CONTAINER...]

Update configuration of one or more containers

Options:
      --blkio-weight uint16        Block IO (relative weight), between 10 and 1000, or 0 to disable (default 0)
      --cpu-period int             Limit CPU CFS (Completely Fair Scheduler) period
      --cpu-quota int              Limit CPU CFS (Completely Fair Scheduler) quota
      --cpu-rt-period int          Limit the CPU real-time period in microseconds
      --cpu-rt-runtime int         Limit the CPU real-time runtime in microseconds
  -c, --cpu-shares int             CPU shares (relative weight)
      --cpus decimal               Number of CPUs
      --cpuset-cpus string         CPUs in which to allow execution (0-3, 0,1)
      --cpuset-mems string         MEMs in which to allow execution (0-3, 0,1)
      --kernel-memory bytes        Kernel memory limit
  -m, --memory bytes               Memory limit
      --memory-reservation bytes   Memory soft limit
      --memory-swap bytes          Swap limit equal to memory plus swap: '-1' to enable unlimited swap
      --pids-limit int             Tune container pids limit (set -1 for unlimited)
      --restart string             Restart policy to apply when a container exits

Ejemplo

# limitar el contenidor a 100Mb  i swap desactivada
root@docker-master:~# docker update -m 100M --memory-swap -1 ct

root@docker-master:~# docker stats contenedor
CONTAINER ID        NAME                CPU %               MEM USAGE / LIMIT   MEM %               NET I/O             BLOCK I/O           PIDS
76ec0cdbabcb        contenedor          0.00%               1.664MiB / 100MiB   1.66%               1.52kB / 0B         0B / 0B             1

En docker se recomienda desactivar la swap. En kubernettes es obligatorio.

Copias de seguridad (imágenes)

docker save -o httpd.tar httpd -> poner una imagen a un fichero
docker load -i httpd.tar -> restaurar una imagen desde un fichero

Convertir contenedores a imágenes (no recomendable)
No se recomienda porque la forma correcta es la de desplegar contenedores personalizados mediante los Docker file

docker commit -m "Comentario imagen" ct nombreimagen

Cambiar el nombre a la imagen

docker tag nombreimagen nombreimagen:0.1

Publicar una imagen en Docker Hub
Para publicar una imagen en Docker Hub es obligatorio que tenga el siguiente formato

usuariodedockerhub/imagen:version

docker tag imagen usuariodedockerhub/imagen
docker login
cat /root/.docker/config.json
docker push usuariodedockerhub/imagen
docker logout
docker search usuariodockerhub

Es posible conectar una cuenta de github a la de dockerhub para hacer desarrollo contínuo (wildfly)
Es posible trabajar con un repositorio local (docker registry konradkleine/docker-registry-frontend)

Con ésto tendríamos lo básico para trabajar con Docker. Lo siguiente será construir nuestras propias imágenes con Dockerfile y despliegue de varios contenedores con docker-compose. Ésto lo dejamos para otro post :)

Deixa un comentari

L'adreça electrònica no es publicarà. Els camps necessaris estan marcats amb *

Aquest lloc utilitza Akismet per reduir els comentaris brossa. Apreneu com es processen les dades dels comentaris.