Containers en Linux

20 marzo 2019
Josep Ma Solanes 0

Si bien hace tiempo escribí una entrada sobre los containers en las versiones tempranas de Windows Server 2016, que hay que revisar debido a los cambios producidos, en esta entrada hacemos el salto a los containers en Linux.

El objetivo de esta entrada es poner en práctica los conceptos de los containers en Linux desplegando un entorno de blogs de WordPress por lo que dispondremos de:

  • Un servidor de bases de datos MariaDB donde alojar las bases de datos de los blogs WordPress.
  • A la vez este servidor hará de servidor de containers en Linux. Instalando la versión de la comunidad de Dockers.
  • También hará de servidor de directorios persistentes en los containers, concretamente para el directorio de configuración de sites y para los propios sites. Y al que se pueda llegar desde la red con el protocolo CIFS para poder modificar los archivos de los sitios web. Al modificar estos archivos, los containers que ofrecen el servicio se tienen que actualizar automáticamente.
  • Tener un container en Linux, basado en Ubuntu Server, con el Apache corriente que servirá de imagen para desplegar los diferentes sitios web.
  • Container en Linux para cada sitio web. Dos en concreto.

Y todo esto desde un Microsoft Windows 10. Empezamos.

Lo primero que necesitamos es tener un sistema operatiu Linux. Para este artículo he optado por la instalación de Ubuntu Server 1810 en una máquina virtual, que podéis encontrar en este enlace.

Con el sistema operativo Ubuntu Server en funcionamiento podéis continuar con:

Instalación del entorno de containers en Linux con Docker

Llegados a este punto, desplegamos el entorno de containers con Linux en el servidor Ubuntu Server que hemos preparado. Preparamos lo mismo para incorporar el repositorio de Docker:

sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common -y

Añadir la clave del repositorio de Docker:

sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

Comprobar que se ha dado de alta la clave de Docker en el repositorio:

sudo apt-key fingerprint 0EBFCD88

Añadir el repositorio estable de Docker en la base de datos de catálogos:

sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

Actualizar la lista del repositorio y proceder con la instalación de los paquetes de Docker de la edición de la comunidad:

sudo apt-get update && sudo apt-get install docker-ce docker-ce-cli containerd.io -y

Comprobar que se ha creado una nueva red «virtual» con identificador 172.17.0.0/16. Hay que tenerlo en cuenta para abrir el cortafuegos hacia el servidor de MariaDB y servidor de archivos NFS para los containers que tengan que acceder.

ifconfig

Probar que el entorno de containers funciona ejecutando, el como no, ¡Hola mundo!:

sudo docker run hello-world

Para no tener que elevar siempre los privilegios para las operaciones con Docker, añadir el usuario con el que se trabaje en el grupo de seguridad Docker. Recordar que hay que cerrar la sesión para aplicar los cambios:

usermod -G docker operador

Comprobar las imágenes Docker que tenemos disponibles sobre el servidor de containers con Linux:

docker images

Cargar la imagen de Ubuntu como container. Primero la buscamos en el repositorio:

docker search ubuntu

Identificar la que nos interesa, en mi caso, la última versión oficial y procedo a descargarla:

docker pull ubuntu:latest

Volver a comprobar que ya tenemos la imagen de container Ubuntu disponible:

docker images

Operaciones básicas de los containers en Linux

Cargar la imagen de Ubuntu como container. Primero la buscamos en el repositorio. Eso se puede hacer vía navegador en la dirección https://hub.docker.com o bien desde la consola de comandos con:

docker search ubuntu

Identificar la que nos interesa, en mi caso, la última versión oficial. Procedo a descargarla:

docker pull ubuntu:latest

Volver a comprobar que ya tenemos la imagen de container Ubuntu disponible:

docker images

Para visualizar los containers en Linux creados y su estado, utilizar el comando:

docker ps -a

Aunque actualmente no hay ningún container creado. El listado sale en blanco.

Proceder a la creaación de uno de los primeros containers en Linux (llamado primer_container) ejecutando el siguiente comando de forma interactiva:

docker run --name primer_container -it ubuntu:latest

Se nos devuelve un nuevo símbolo de comandos. ¡Ahora mismo estamos dentro de un container!

Para salir del entorno de comandos del container, escribir:

exit

Podemos comprobar los containers en Linux que tenemos creados y si están en ejecución con el comando:

docker ps -a

Al haber salido del símbolo de comandos del container, se puede ver por la columna de STATUS que todos los containers están parados.

Para volver a arrancar el container, pero sin acceder a él, se utiliza el comando, cambiando el nombre containerid por el identificador o nombre del container:

docker start containerid

Si lo probáis con el container acabado de crear, al ejecutar el comando de comprobación de containers, podéis ver como el container se está ejecutando. Eso sí, sin ningún símbolo de comandos, porque no hemos entrado en su entorno:

docker ps -a

Para acceder dentro del entorno de ejecución del container, se utiliza el comando exec, indicando la forma para poder actuar de forma interactiva con el container (-it) y ejecutando un símbolo de comandos (/bin/bash):

docker exec -it containerid /bin/bash

Se puede aprovechar para actualizar los paquetes del sistema operativo Ubuntu Server y salir del container:

apt-get update
apt-get upgrade
exit

Tenemos el container actualizado, pero recuerdo que los containers son efímeros, cuando se destruya o se quiera crear un nuevo container a partir de la imagen de Ubuntu, este no estará actualizado. Por lo tanto, ¿como creamos una nueva imagen de Ubuntu Server actualizado?

Paramos el container para crear una imagen del mismo:

docker stop containerid

Creamos una nueva imagen del container indicando el containerid y el nombre que se le quiere dar a la imagen, seguido de la versión. Por ejemplo, ubuntu:20190316

docker commit containerid ubuntu:20190316

Si listamos las imágenes de containers se visualiza la nueva imagen:

Volver a desplegar un nuevo container con el sistema operativo actualizado es tan sencillo como:

docker run --name segon_container ubuntu:20190316

Ya no nos interesa un container concreto que se ha creado y lo quiero destruir:

docker rm containerid

Y si también quiero destruir la propia imagen, siempre que no haya una dependencia de containers:

docker rmi nom_imatge_container

Se puede obtener la información de configuración del propio container con el comando:

docker inspect containerid

Para copiar archivos hacia dentro del container de forma local tenemos el comando:

docker cp origen containerid:/desti

Por otra parte, para copiar archivos desde el container hacia fuera utilizamos:

docker cp containerid:/origen /desti

Conexión de red en los containers en Linux

Tenemos containers en Linux creados y ejecutándose de forma local, pero el objetivo es que estos containers se comuniquen con otros o nos podamos comunicar con ellos desde la red.

Para hacerlo, lo primero que tenemos que averiguar son las conexiones de red que el anfitrión de containers tiene disponible para estos. Ejecutar el comando:

docker network list

En la foto anterior podemos ver tres identificadores de red con tres controladores (drivers) de diferentes funciones:

  • bridge. Proporciona un entorno de red tipo NAT hacia la red externa. No hay problema de conflictos de IP porque se enmascara por la IP pública del anfitrión de containers. La red que se crea aquí, normalmente, acostumbra a ser del tipo 172.17.0.0./16. Por lo tanto, en cada anfitrión caben muchos containers.
  • host. Sólo para la comunicación con el anfitrión de containers, no tiene acceso a la red externa.
  • none. Más claro imposible, simplemente no hay comunicaciones externas.

Como resumen, lo más habitual será utilizar el bridge para enmascarar los puertos locales del equipo anfitrión con los diferentes containers. Ojo que eso quiere decir que no se pueden duplicar puertos en la misma IP. No puedo tener dos puertos locales TCP 80 en dos containers diferentes, por ejemplo.

¿Pero como asociamos el puerto TCP 4022, por ejemplo, del equipo local con el puerto 22 del container? Con el parámetro -p puerto_anfitrión:puerto_container al crear el propio container:

docker create --name containerid -it --network bridge -p 4022:22 ubuntu:20190316 

Al arrancar el container, y si visualizamos el estado de ejecución, se ve el enlace de estos puertos.

¡Atención! antes que probéis la conexión anterior sabed que os dará un error. ¿Por qué? Pues porque el container de Ubuntu no dispone del servidor de SSH por defecto. Lo podéis habilitar accediendo dentro del container:

docker exec -it containerid /bin/bash

Dentro del container, instalar el servidor SSH y el editor VI o NANO para poder modificar archivos:

apt-get install openssh-server vim

Para arrancar el servicio de SSH. Que habrá que hacerlo siempre que arrancamos el container, ya que no existe el Systemctl para iniciar automáticamente servicios. Si se quisiera arrancar siempre por defecto hay que crear un container específico indicando que se inicie de forma automática esta aplicación:

service ssh start

Para la conexión externa con usuario root, editar el archivo /etc/ssh/sshd_config añadiendo la siguiente línea:

PermitRootLogin yes

Reiniciar el servicio de SSH para aplicar los cambios.

service ssh restart

Para mayor seguridad, también se puede crear un usuario adicional al root y, con el entorno sudo, ejecutar los permisos elevados o acceder al usuario root (habiendo cambiado su contraseña por una de conocida por nosotros):

apt-get install sudo
adduser operador sudo
passwd root

Siempre y cuando tengáis el cortafuegos del anfitrión que permita las conexiones de red, ya se puede acceder desde fuera del entorno de containers.


¿Te ha gustado el artículo? Lo puedes compartir en las redes sociales. También puedes dejar tu opinión, comentario o sugerencia. ¡Gracias!

Similar Posts by The Author: