Al usar Docker para contener sus aplicaciones, es una práctica común ejecutar cada componente de la aplicación en un contenedor separado. Por ejemplo, un sitio web puede tener un servidor web, una aplicación y una base de datos, cada uno ejecutándose en su propio contenedor.
Configurar los contenedores para que se comuniquen entre sí y con la máquina host puede ser un desafío. Esta guía usará una aplicación de ejemplo simple para demostrar los conceptos básicos de la comunicación del contenedor Docker. La aplicación consistirá en una aplicación Node.js que lee datos de una base de datos PostgreSQL.
Antes de comenzar
Instalar Docker CE
Necesitará un Linode con Docker CE instalado para seguir los pasos de esta guía.
Para instalar Docker CE (Community Edition), siga las instrucciones de una de las siguientes guías:
-
Instalación y uso de Docker en Ubuntu y Debian
-
Instalación y uso de Docker en CentOS y Fedora
Para obtener instrucciones completas sobre aún más distribuciones de Linux, consulte la sección Instalar el motor Docker de la documentación oficial de Docker.
Ejemplo de aplicación Node.js
La aplicación de ejemplo utilizada en esta guía será una aplicación simple de Node.js que leerá "Hola mundo" desde una base de datos de PostgreSQL y lo imprimirá en la consola. En esta sección, construirá y probará la aplicación en su Linode sin usar contenedores.
Instalar y configurar PostgreSQL
-
Actualice su sistema:
sudo apt update && sudo apt upgrade -
Instalar PostGreSQL:
sudo apt install postgresql postgresql-contrib -
Cambia el
postgrescontraseña del usuario:sudo passwd postgres -
Establecer una contraseña para
postgresusuario de la base de datos:su - postgres psql -d template1 -c "ALTER USER postgres WITH PASSWORD 'newpassword';" -
Cree una base de datos para la aplicación de ejemplo y conéctese a ella:
createdb nodejs psql nodejs -
Agregue "Hola mundo" a la base de datos:
nodejs=# CREATE TABLE hello (message varchar); nodejs=# INSERT INTO hello VALUES ('Hello world'); nodejs=# \q -
Cree un volcado de la base de datos para su uso posterior:
pg_dumpall > backup.sql -
Cerrar sesión como
postgresUsuario de Linux:exit -
Copie el volcado de datos a su directorio de inicio:
sudo cp /var/lib/postgresql/backup.sql ~/. -
Dado que se conectará a esta base de datos desde un contenedor (que tendrá una dirección IP distinta de
locahost), deberá editar el archivo de configuración de PostgreSQL para permitir conexiones desde direcciones remotas. Abra/etc/postgresql/9.5/main/postgresql.confen un editor de texto. Descomente laslisten_addresseslínea y configúrelo en '*':- Archivo:/ etc/postgresql/9.5/main/postgresql.conf
1 2 3 4 5 6 7#------------------------------------------------------------------------------ # CONNECTIONS AND AUTHENTICATION #------------------------------------------------------------------------------ # - Connection Settings - listen_addresses = '*' # what IP address(es) to listen on;Habilite e inicie
postgresqlservicio:sudo systemctl enable postgresql sudo systemctl start postgresqlCrea una aplicación Hello World
-
Instalar Nodo y NPM:
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash - sudo apt-get install nodejs -
Navegue hasta el directorio de inicio y cree un directorio:
cd mkdir app && cd app -
Usando un editor de texto, cree
app.jsy agregue el siguiente contenido:- Archivo:aplicación .js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16const { Client } = require('pg') const client = new Client({ user: 'postgres', host: 'localhost', database: 'nodejs', password: 'newpassword', port: 5432 }) client.connect() client.query('SELECT * FROM hello', (err, res) => { console.log(res.rows[0].message) client.end() })Esta aplicación utiliza el
pgMódulo NPM (node-postgres) para conectarse a la base de datos creada en el apartado anterior. Luego consulta la tabla 'hola' (que devuelve el mensaje "Hola mundo") y registra la respuesta en la consola. Reemplazar'newpassword'conpostgrescontraseña de usuario de la base de datos que estableció en la sección anterior.Nota El
pgEl módulo también puede usar variables de entorno para configurar la conexión del cliente. Esta es la opción recomendada para aplicaciones de producción. Lea más sobre las variables de entorno en la documentación de node-postgres.Instale el
pgmódulo:npm install pgPrueba la aplicación:
node app.jsSi la base de datos está configurada correctamente, se mostrará "Hola mundo" en la consola.
Conectar contenedor a Docker Host
Esta sección ilustra un caso de uso en el que la aplicación Node.js se ejecuta desde un contenedor de Docker y se conecta a una base de datos que se ejecuta en el host de Docker.
Configurar contenedor Docker
-
Regrese a su directorio de inicio:
cd -
Cree un Dockerfile para ejecutar la aplicación Node.js:
- Archivo:Dockerfile
1 2 3 4 5 6 7FROM debian RUN apt update -y && apt install -y gnupg curl RUN curl -sL https://deb.nodesource.com/setup_8.x | bash - && apt install -y nodejs COPY app/ /home/ ENTRYPOINT tail -F /dev/nullLa imagen creada a partir de este Dockerfile copiará la
app/directorio a la nueva imagen. Editarapp.jspara permitir que la aplicación se conecte a ladatabasehost en lugar delocalhost:- Archivo:aplicación /app.js
1 2 3 4 5 6 7const client = new Client({ user: 'postgres', host: 'database', database: 'nodejs', password: 'newpassword', port: 5432 })Cree una imagen desde Dockerfile:
docker build -t node_image .Conectar contenedor a base de datos
-
Docker configura automáticamente una red puente predeterminada , al que se accede a través de
docker0interfaz de red. Usaifconfigoippara ver esta interfaz:ifconfig docker0El resultado será similar al siguiente:
La dirección IP interna del host Docker (su Linode) es 172.17.0.1.docker0 Link encap:Ethernet HWaddr 02:42:1e:e8:39:54 inet addr:172.17.0.1 Bcast:0.0.0.0 Mask:255.255.0.0 inet6 addr: fe80::42:1eff:fee8:3954/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:3848 errors:0 dropped:0 overruns:0 frame:0 TX packets:5084 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:246416 (246.4 KB) TX bytes:94809688 (94.8 MB) -
Permita que PostgreSQL acepte conexiones desde la interfaz de Docker. Abra
/etc/postgresql/9.5/main/pg_hba.confen un editor de texto y agregue la siguiente línea:- Archivo:/ etc/postgresql/9.5/main/pg_hba.conf
1host all postgres 172.17.0.0/16 passwordDado que 172.17.0.1 es la IP del host Docker, todos los contenedores en el host tendrán una dirección IP en el rango 172.17.0.0/16.
Reinicie la base de datos:
sudo systemctl restart postgresqlInicie el contenedor:
docker run -d --add-host=database:172.17.0.1 --name node_container node_imageEl
--add-hostopción define unadatabasehost, que apunta a la dirección IP del host Docker. Declarando ladatabasehost en tiempo de ejecución, en lugar de codificar la dirección IP en la aplicación, ayuda a mantener el contenedor reutilizable.Desde dentro del contenedor, use
pingpara probar la conexión a ladatabaseanfitrión:docker exec -it node_container ping databaseA cada contenedor de Docker también se le asigna su propia dirección IP desde el bloque 172.17.0.0/16. Encuentre la dirección IP de este contenedor con
ip:docker exec -it node_container ip addr show eth0Puede probar esta conexión haciendo ping a esta dirección desde el host de Docker.
Ejecute la aplicación:
docker exec -it node_container node home/app.jsSi la configuración fue exitosa, el programa debería mostrar la salida de la consola "Hello world" como antes.
Conectar dos contenedores
En esta sección, tanto la aplicación como la base de datos se ejecutarán en contenedores separados. Puede usar la imagen oficial de postgres de Docker Hub y cargarla en el volcado de SQL creado anteriormente.
Precaución No debe almacenar datos de la base de datos de producción dentro de un contenedor Docker. Los contenedores deben tratarse como entidades efímeras:si un contenedor falla inesperadamente o se reinicia, se perderán todos los datos de la base de datos.
-
Detenga y elimine el contenedor Node.js:
docker stop node_container docker rm node_container -
Tire del
postgresimagen:docker pull postgres -
Asegúrese de que su
backup.sqlel archivo está en su directorio de trabajo actual, luego ejecutepostgresimagen:docker run -d -v `pwd`:/backup/ --name pg_container postgresEl
-vLa opción monta su directorio de trabajo actual en/backup/directorio en el nuevo contenedor. -
El nuevo contenedor iniciará automáticamente la base de datos de postgres y creará el usuario de postgres. Ingrese al contenedor y cargue el volcado de SQL:
docker exec -it pg_container bash cd backup psql -U postgres -f backup.sql postgres exit -
Vuelva a ejecutar la imagen del nodo. Esta vez, en lugar de
--add-host, use el--linkopción para conectar el contenedor a pg_container:docker run -d --name node_container --link=pg_container:database node_imageEsto vinculará el
pg_containerbajo el nombre de hostdatabase. -
Abra
/etc/hostsen node_container para confirmar que se ha realizado el enlace:docker exec -it node_container cat /etc/hostsDebería haber una línea similar a la siguiente:
- Archivo:/ etc./hosts
172.17.0.2 database pg_container
Esto muestra que
pg_containerse ha asignado a la dirección IP 172.17.0.2 y está vinculado a este contenedor a través del nombre de hostdatabase, como se esperaba. -
Dado que la aplicación Node.js aún espera conectarse a una base de datos PostgreSQL en la
databasehost, no es necesario realizar más cambios. Debería poder ejecutar la aplicación como antes:docker exec -it node_container node home/app.js
Usando Docker Compose
Usando el
--linko--hostLas opciones cada vez que lanza sus contenedores pueden ser engorrosas. Si su servidor o cualquiera de los contenedores falla, deben volver a conectarse manualmente. Esta no es una situación ideal para cualquier aplicación que requiera disponibilidad constante. Afortunadamente, Docker proporciona Docker Compose para administrar múltiples contenedores y vincularlos automáticamente cuando se lanzan. Esta sección utilizará Docker Compose para reproducir los resultados de la sección anterior.Nota Para obtener una explicación más completa de Docker Compose y cómo escribir
docker-compose.ymlarchivos de configuración, consulte nuestra guía completa de Docker Compose.-
Instalar Docker Compose:
sudo curl -L https://github.com/docker/compose/releases/download/1.17.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose -
En el mismo directorio que su Dockerfile, cree un
docker-compose.ymlarchivo con el siguiente contenido:- Archivo:docker -compose.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25version: '3' services: database: image: postgres container_name: pg_container volumes: - pgdata:/var/lib/postgresql/data app: build: . container_name: node_container links: - database environment: - PGPASSWORD=newpassword - PGUSER=postgres - PGDATABASE=nodejs - PGHOST=database - PGPORT=5432 depends_on: - database volumes: pgdata: {}Cuando ejecute Docker Compose con este archivo, creará el
pg_containerynode_containerde la sección anterior. Como antes, el contenedor de la base de datos utilizará la imagen oficial de PostgreSQL, mientras que el contenedor de la aplicación se creará a partir de su Dockerfile. Loslinksla entrada cumple la misma función que--linkopción enruncomando usado anteriormente.Docker Compose también le permite configurar valores de entorno, por lo que puede simplificar la aplicación para usarlos en lugar de tener los valores codificados. Editar
app.jspara eliminar estos valores:- Archivo:aplicación .js
1 2 3 4 5 6 7 8 9 10 11const express = require('express') const { Client } = require('pg') const client = new Client() client.connect() client.query('SELECT * FROM hello', (err, res) => { console.log(res.rows[0].message) client.end() })Eliminar los contenedores anteriores:
docker rm -f node_container pg_containerUse Docker Compose para mostrar los contenedores:
docker-compose up -dCargue los datos de ejemplo en el nuevo contenedor:
docker cp backup.sql pg_container:/ docker exec -it pg_container psql -U postgres -f backup.sql postgresEjecute
app.jsdesde el contenedor de la aplicación:docker exec -it node_container node home/app.jsLa aplicación debería funcionar como antes.
Conclusión
De forma predeterminada, Docker asigna automáticamente una dirección IP a cada contenedor y al host de Docker. Puede conectar manualmente servicios entre contenedores usando estas direcciones (suponiendo que su firewall permita la conexión).
Sin embargo, Docker también proporciona varios envoltorios convenientes alrededor de estas conexiones para ayudarlo a acelerar y simplificar el proceso de conexión. Puede conectar su host Docker a un contenedor con un nombre de host único o vincular directamente dos contenedores. El uso de Docker Compose puede simplificar este proceso aún más al permitirle declarar conexiones en
docker-compose.ymlpara que se establezcan automáticamente cuando se muestren los contenedores.Hay otras opciones de conexión que no se trataron en esta guía. Por ejemplo, puede ejecutar un contenedor usando
--net="host", que compartirá la pila de red de ese contenedor con el host de Docker:localhosten el contenedor apuntará alocalhosten el host de Docker. También puede exponer puertos en cada contenedor de Docker o configurar la red de puente predeterminada para obtener más flexibilidad. Para obtener una discusión más detallada de estas opciones, consulte los enlaces en la sección Más información a continuación.Más información
Es posible que desee consultar los siguientes recursos para obtener información adicional sobre este tema. Si bien estos se proporcionan con la esperanza de que sean útiles, tenga en cuenta que no podemos garantizar la precisión o la puntualidad de los materiales alojados externamente.
- Docker:comprensión de la comunicación de contenedores
- Contenedores de enlace
- Conexiones de contenedores
Docker Cómo ejecutar contenedores Docker
Cómo eliminar contenedores Docker
Cómo detener los contenedores de Docker
Cómo nombrar o renombrar contenedores Docker
Cómo gestionar contenedores Docker
Cómo configurar espacios de nombres de red en contenedores Docker