GNU/Linux >> Tutoriales Linux >  >> Panels >> Docker

Cómo conectar contenedores Docker

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

  1. Actualice su sistema:

    sudo apt update && sudo apt upgrade
    
  2. Instalar PostGreSQL:

    sudo apt install postgresql postgresql-contrib
    
  3. Cambia el postgres contraseña del usuario:

    sudo passwd postgres
    
  4. Establecer una contraseña para postgres usuario de la base de datos:

    su - postgres
    psql -d template1 -c "ALTER USER postgres WITH PASSWORD 'newpassword';"
    
  5. Cree una base de datos para la aplicación de ejemplo y conéctese a ella:

    createdb nodejs
    psql nodejs
    
  6. Agregue "Hola mundo" a la base de datos:

    nodejs=# CREATE TABLE hello (message varchar);
    nodejs=# INSERT INTO hello VALUES ('Hello world');
    nodejs=# \q
    
  7. Cree un volcado de la base de datos para su uso posterior:

    pg_dumpall > backup.sql
    
  8. Cerrar sesión como postgres Usuario de Linux:

    exit
    
  9. Copie el volcado de datos a su directorio de inicio:

    sudo cp /var/lib/postgresql/backup.sql ~/.
    
  10. 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.conf en un editor de texto. Descomente las listen_addresses línea y configúrelo en '*':

    Archivo:/ etc/postgresql/9.5/main/postgresql.conf
  11. Habilite e inicie postgresql servicio:

    sudo systemctl enable postgresql
    sudo systemctl start postgresql
    
  12. Crea una aplicación Hello World

    1. Instalar Nodo y NPM:

      curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
      sudo apt-get install nodejs
      
    2. Navegue hasta el directorio de inicio y cree un directorio:

      cd
      mkdir app && cd app
      
    3. Usando un editor de texto, cree app.js y agregue el siguiente contenido:

      Archivo:aplicación .js
    1
    2
    3
    4
    5
    6
    7
    
    #------------------------------------------------------------------------------
    # CONNECTIONS AND AUTHENTICATION
    #------------------------------------------------------------------------------
    
    # - Connection Settings -
    
    listen_addresses = '*'                  # what IP address(es) to listen on;

    Esta aplicación utiliza el pg Mó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' con postgres contraseña de usuario de la base de datos que estableció en la sección anterior.

    Nota El pg El 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.
  13. Instale el pg módulo:

    npm install pg
    
  14. Prueba la aplicación:

    node app.js
    

    Si la base de datos está configurada correctamente, se mostrará "Hola mundo" en la consola.

  15. 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

    1. Regrese a su directorio de inicio:

      cd
      
    2. Cree un Dockerfile para ejecutar la aplicación Node.js:

      Archivo:Dockerfile
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    
    const { 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()
    })
  16. La imagen creada a partir de este Dockerfile copiará la app/ directorio a la nueva imagen. Editar app.js para permitir que la aplicación se conecte a la database host en lugar de localhost :

    Archivo:aplicación /app.js
  17. 1
    2
    3
    4
    5
    6
    7
    
    FROM 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/null
  18. Cree una imagen desde Dockerfile:

    docker build -t node_image .
    
  19. Conectar contenedor a base de datos

    1. Docker configura automáticamente una red puente predeterminada , al que se accede a través de docker0 interfaz de red. Usa ifconfig o ip para ver esta interfaz:

      ifconfig docker0
      

      El resultado será similar al siguiente:

      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)
      La dirección IP interna del host Docker (su Linode) es 172.17.0.1.

    2. Permita que PostgreSQL acepte conexiones desde la interfaz de Docker. Abra /etc/postgresql/9.5/main/pg_hba.conf en un editor de texto y agregue la siguiente línea:

      Archivo:/ etc/postgresql/9.5/main/pg_hba.conf
    1
    2
    3
    4
    5
    6
    7
    
    const client = new Client({
      user: 'postgres',
      host: 'database',
      database: 'nodejs',
      password: 'newpassword',
      port: 5432
    })

    Dado 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.

  20. Reinicie la base de datos:

    sudo systemctl restart postgresql
    
  21. Inicie el contenedor:

    docker run -d --add-host=database:172.17.0.1 --name node_container node_image
    

    El --add-host opción define una database host, que apunta a la dirección IP del host Docker. Declarando la database host en tiempo de ejecución, en lugar de codificar la dirección IP en la aplicación, ayuda a mantener el contenedor reutilizable.

  22. Desde dentro del contenedor, use ping para probar la conexión a la database anfitrión:

    docker exec -it node_container ping database
    
  23. A 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 eth0
    

    Puede probar esta conexión haciendo ping a esta dirección desde el host de Docker.

  24. Ejecute la aplicación:

    docker exec -it node_container node home/app.js
    
  25. Si 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.
    1. Detenga y elimine el contenedor Node.js:

      docker stop node_container
      docker rm node_container
      
    2. Tire del postgres imagen:

      docker pull postgres
      
    3. Asegúrese de que su backup.sql el archivo está en su directorio de trabajo actual, luego ejecute postgres imagen:

      docker run -d -v `pwd`:/backup/ --name pg_container postgres
      

      El -v La opción monta su directorio de trabajo actual en /backup/ directorio en el nuevo contenedor.

    4. 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
      
    5. Vuelva a ejecutar la imagen del nodo. Esta vez, en lugar de --add-host , use el --link opción para conectar el contenedor a pg_container:

      docker run -d --name node_container --link=pg_container:database node_image
      

      Esto vinculará el pg_container bajo el nombre de host database .

    6. Abra /etc/hosts en node_container para confirmar que se ha realizado el enlace:

      docker exec -it node_container cat /etc/hosts
      

      Debería haber una línea similar a la siguiente:

      Archivo:/ etc./hosts
      172.17.0.2  database  pg_container

      Esto muestra que pg_container se ha asignado a la dirección IP 172.17.0.2 y está vinculado a este contenedor a través del nombre de host database , como se esperaba.

    7. Dado que la aplicación Node.js aún espera conectarse a una base de datos PostgreSQL en la database host, 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 --link o --host Las 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.yml archivos de configuración, consulte nuestra guía completa de Docker Compose.
    1. 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
      
    2. En el mismo directorio que su Dockerfile, cree un docker-compose.yml archivo con el siguiente contenido:

      Archivo:docker -compose.yml
    1
    
    host    all             postgres        172.17.0.0/16           password

    Cuando ejecute Docker Compose con este archivo, creará el pg_container y node_container de 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. Los links la entrada cumple la misma función que --link opción en run comando usado anteriormente.

  26. 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.js para eliminar estos valores:

    Archivo:aplicación .js
  27.  1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    
    version: '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: {}
  28. Eliminar los contenedores anteriores:

    docker rm -f node_container pg_container
    
  29. Use Docker Compose para mostrar los contenedores:

    docker-compose up -d
    
  30. Cargue 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 postgres
    
  31. Ejecute app.js desde el contenedor de la aplicación:

    docker exec -it node_container node home/app.js
    
  32. La 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.yml para 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:localhost en el contenedor apuntará a localhost en 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
    1. Cómo actualizar automáticamente los contenedores Docker en ejecución

    2. Cómo exportar e importar contenedores Docker

    3. Cómo usar Docker Compose

    4. Cómo pasar variables de entorno a contenedores Docker

    5. Cómo listar 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

       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      
      const 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()
      })