GNU/Linux >> Linux Esercitazione >  >> Panels >> Docker

Come collegare i contenitori Docker

Quando si utilizza Docker per containerizzare le applicazioni, è prassi comune eseguire ciascun componente dell'applicazione in un container separato. Ad esempio, un sito Web potrebbe avere un server Web, un'applicazione e un database, ciascuno in esecuzione nel proprio contenitore.

Configurare i contenitori per comunicare tra loro e la macchina host può essere una sfida. Questa guida utilizzerà una semplice app di esempio per dimostrare le basi della comunicazione del container Docker. L'app sarà composta da un'app Node.js che legge i dati da un database PostgreSQL.

Prima di iniziare

Installa Docker CE

Avrai bisogno di un Linode con Docker CE installato per seguire i passaggi di questa guida.

Per installare Docker CE (Community Edition), segui le istruzioni all'interno di una delle guide seguenti:

  • Installazione e utilizzo di Docker su Ubuntu e Debian

  • Installazione e utilizzo di Docker su CentOS e Fedora

Per istruzioni complete su ancora più distribuzioni Linux, fai riferimento alla sezione Install Docker Engine della documentazione ufficiale di Docker.

Esempio di applicazione Node.js

L'app di esempio utilizzata in questa guida sarà una semplice app Node.js che leggerà "Hello world" da un database PostgreSQL e lo stamperà sulla console. In questa sezione creerai e testerai l'app sul tuo Linode senza utilizzare contenitori.

Installa e configura PostgreSQL

  1. Aggiorna il tuo sistema:

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

    sudo apt install postgresql postgresql-contrib
    
  3. Cambia il postgres password utente:

    sudo passwd postgres
    
  4. Imposta una password per postgres utente del database:

    su - postgres
    psql -d template1 -c "ALTER USER postgres WITH PASSWORD 'newpassword';"
    
  5. Crea un database per l'app di esempio e connettiti ad esso:

    createdb nodejs
    psql nodejs
    
  6. Aggiungi "Hello world" al database:

    nodejs=# CREATE TABLE hello (message varchar);
    nodejs=# INSERT INTO hello VALUES ('Hello world');
    nodejs=# \q
    
  7. Crea un dump del database per un uso successivo:

    pg_dumpall > backup.sql
    
  8. Esci come postgres Utente Linux:

    exit
    
  9. Copia il dump dei dati nella tua home directory:

    sudo cp /var/lib/postgresql/backup.sql ~/.
    
  10. Poiché ti connetterai a questo database da un container (che avrà un indirizzo IP diverso da locahost ), dovrai modificare il file di configurazione di PostgreSQL per consentire le connessioni da indirizzi remoti. Apri /etc/postgresql/9.5/main/postgresql.conf in un editor di testo. Decommenta il listen_addresses riga e impostarlo su '*':

    File:/ 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;
  11. Abilita e avvia il postgresql servizio:

    sudo systemctl enable postgresql
    sudo systemctl start postgresql
    

Crea un'app Hello World

  1. Installa Nodo e NPM:

    curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
    sudo apt-get install nodejs
    
  2. Passa alla directory home e crea una directory:

    cd
    mkdir app && cd app
    
  3. Usando un editor di testo, crea app.js e aggiungi il seguente contenuto:

    File:app .js
     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()
    })

    Questa app utilizza il pg Modulo NPM (node-postgres) per connettersi al database creato nella sezione precedente. Quindi interroga la tabella "hello" (che restituisce il messaggio "Hello world") e registra la risposta alla console. Sostituisci 'newpassword' con il postgres password utente del database che hai impostato nella sezione precedente.

    Nota Il pg modulo può anche utilizzare variabili di ambiente per configurare la connessione client. Questa è l'opzione consigliata per le app di produzione. Maggiori informazioni sulle variabili di ambiente nella documentazione di thenode-postgres.
  4. Installa il pg modulo:

    npm install pg
    
  5. Prova l'app:

    node app.js
    

    Se il database è configurato correttamente, sulla console verrà visualizzato "Hello world".

Collega il container all'host Docker

Questa sezione illustra un caso d'uso in cui l'app Node.js viene eseguita da un contenitore Docker e si connette a un database in esecuzione sull'host Docker.

Imposta il contenitore Docker

  1. Torna alla tua home directory:

    cd
    
  2. Crea un Dockerfile per eseguire l'app Node.js:

    File:Dockerfile
    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
  3. L'immagine creata da questo Dockerfile copierà l'app/ directory nella nuova immagine. Modifica app.js per consentire all'app di connettersi al database host invece di localhost :

    File:app /app.js
    1
    2
    3
    4
    5
    6
    7
    
    const client = new Client({
      user: 'postgres',
      host: 'database',
      database: 'nodejs',
      password: 'newpassword',
      port: 5432
    })
  4. Crea un'immagine dal Dockerfile:

    docker build -t node_image .
    

Collega il contenitore al database

  1. Docker imposta automaticamente una rete bridge predefinita , accessibile tramite la docker0 interfaccia di rete. Usa ifconfig o ip per visualizzare questa interfaccia:

    ifconfig docker0
    

    L'output sarà simile al seguente:

    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)
    L'indirizzo IP interno dell'host Docker (il tuo Linode) è 172.17.0.1.

  2. Consenti a PostgreSQL di accettare connessioni dall'interfaccia Docker. Apri /etc/postgresql/9.5/main/pg_hba.conf in un editor di testo e aggiungi la seguente riga:

    File:/ etc/postgresql/9.5/main/pg_hba.conf
    1
    
    host    all             postgres        172.17.0.0/16           password

    Poiché 172.17.0.1 è l'IP dell'host Docker, tutti i contenitori sull'host avranno un indirizzo IP nell'intervallo 172.17.0.0/16.

  3. Riavvia il database:

    sudo systemctl restart postgresql
    
  4. Avvia il contenitore:

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

    Il --add-host l'opzione definisce un database host, che punta all'indirizzo IP dell'host Docker. Dichiarazione del database host in fase di esecuzione, anziché codificare l'indirizzo IP nell'app, aiuta a mantenere il contenitore riutilizzabile.

  5. Dall'interno del contenitore, usa ping per testare la connessione al database ospite:

    docker exec -it node_container ping database
    
  6. A ogni container Docker viene assegnato anche il proprio indirizzo IP all'interno del blocco 172.17.0.0/16. Trova l'indirizzo IP di questo contenitore con ip :

    docker exec -it node_container ip addr show eth0
    

    Puoi testare questa connessione eseguendo il ping di questo indirizzo dall'host Docker.

  7. Esegui l'app:

    docker exec -it node_container node home/app.js
    

Se la configurazione è andata a buon fine, il programma dovrebbe visualizzare l'output della console "Hello world" come prima.

Collega due contenitori

In questa sezione, sia l'app che il database verranno eseguiti in contenitori separati. Puoi utilizzare l'immagine postgres ufficiale da Docker Hub e caricarla nel dump SQL creato in precedenza.

Attenzione Non archiviare i dati del database di produzione all'interno di un contenitore Docker. I contenitori devono essere trattati come entità effimere:se un contenitore si arresta in modo imprevisto o viene riavviato, tutti i dati nel database andranno persi.
  1. Arresta e rimuovi il contenitore Node.js:

    docker stop node_container
    docker rm node_container
    
  2. Tira il postgres immagine:

    docker pull postgres
    
  3. Assicurati che il tuo backup.sql il file si trova nella directory di lavoro corrente, quindi esegui postgres immagine:

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

    Il -v l'opzione monta la directory di lavoro corrente su /backup/ directory nel nuovo contenitore.

  4. Il nuovo contenitore avvierà automaticamente il database postgres e creerà l'utente postgres. Entra nel container e carica il dump SQL:

    docker exec -it pg_container bash
    cd backup
    psql -U postgres -f backup.sql postgres
    exit
    
  5. Eseguire nuovamente l'immagine del nodo. Questa volta, invece di --add-host , usa il --link opzione per connettere il container a pg_container:

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

    Questo collegherà il pg_container sotto il nome host database .

  6. Apri /etc/hosts in node_container per confermare che il collegamento è stato effettuato:

    docker exec -it node_container cat /etc/hosts
    

    Dovrebbe esserci una riga simile alla seguente:

    File:/ ecc/host
    172.17.0.2  database  pg_container

    Questo mostra che pg_container è stato assegnato all'indirizzo IP 172.17.0.2 ed è collegato a questo container tramite il nome host database , come previsto.

  7. Poiché l'app Node.js si aspetta ancora di connettersi a un database PostgreSQL sul database host, non sono necessarie ulteriori modifiche. Dovresti essere in grado di eseguire l'app come prima:

    docker exec -it node_container node home/app.js
    

Utilizzo di Docker Compose

Usando il --link o --host le opzioni ogni volta che avvii i contenitori possono essere ingombranti. Se il tuo server o uno qualsiasi dei contenitori si arresta in modo anomalo, devono essere ricollegati manualmente. Questa non è una situazione ideale per qualsiasi applicazione che richieda una disponibilità costante. Fortunatamente, Docker fornisce Docker Compose per gestire più contenitori e collegarli automaticamente insieme all'avvio. Questa sezione utilizzerà Docker Compose per riprodurre i risultati della sezione precedente.

Nota Per una spiegazione più completa di Docker Compose e come scrivere docker-compose.yml file di configurazione, consulta la nostra guida completa di Docker Compose.
  1. Installa 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. Nella stessa directory del tuo Dockerfile, crea un docker-compose.yml file con il seguente contenuto:

    File: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
    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: {}

    Quando esegui Docker Compose con questo file, verrà creato il pg_container e node_container dalla sezione precedente. Come prima, il contenitore del database utilizzerà l'immagine PostgreSQL ufficiale, mentre il contenitore dell'app verrà creato dal tuo Dockerfile. I links la voce ha la stessa funzione di --link opzione in run comando utilizzato in precedenza.

  3. Docker Compose ti consente anche di impostare i valori dell'ambiente, in modo da poter semplificare l'uso dell'app anziché avere i valori codificati. Modifica app.js per rimuovere questi valori:

    File:app .js
     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()
    })
  4. Rimuovi i contenitori precedenti:

    docker rm -f node_container pg_container
    
  5. Usa Docker Compose per visualizzare i contenitori:

    docker-compose up -d
    
  6. Carica i dati di esempio nel nuovo contenitore:

    docker cp backup.sql pg_container:/
    docker exec -it pg_container psql -U postgres -f backup.sql postgres
    
  7. Esegui app.js dal contenitore dell'app:

    docker exec -it node_container node home/app.js
    

L'app dovrebbe funzionare come prima.

Conclusione

Per impostazione predefinita, Docker assegna automaticamente un indirizzo IP a ciascun container e all'host Docker. Puoi connettere manualmente i servizi tra i container utilizzando questi indirizzi (supponendo che il tuo firewall consenta la connessione).

Tuttavia, Docker fornisce anche una serie di comodi wrapper attorno a queste connessioni per aiutarti a velocizzare e semplificare il processo di connessione. Puoi connettere il tuo host Docker a un container con un nome host univoco o collegare direttamente due container. L'uso di Docker Compose può semplificare ulteriormente questo processo consentendo di dichiarare le connessioni in docker-compose.yml file in modo che vengano stabiliti automaticamente quando vengono richiamati i contenitori.

Ci sono altre opzioni di connessione che non sono state trattate in questa guida. Ad esempio, puoi eseguire un container utilizzando --net="host" , che condividerà lo stack di rete del contenitore con l'host Docker:localhost sul contenitore punterà a localhost sull'host Docker. Puoi anche esporre le porte su ciascun container Docker o configurare la rete bridge predefinita per una maggiore flessibilità. Per una discussione più approfondita di queste opzioni, vedere i collegamenti nella sezione Ulteriori informazioni di seguito.

Maggiori informazioni

Si consiglia di consultare le seguenti risorse per ulteriori informazioni su questo argomento. Sebbene questi siano forniti nella speranza che possano essere utili, tieni presente che non possiamo garantire l'accuratezza o la tempestività dei materiali ospitati esternamente.

  • Docker:comprensione della comunicazione dei container
  • Contenitori di collegamento
  • Contenitori di collegamento

Docker
  1. Come aggiornare automaticamente i contenitori Docker in esecuzione

  2. Come esportare e importare contenitori Docker

  3. Come usare Docker Compose

  4. Come passare le variabili d'ambiente ai container Docker

  5. Come rimuovere tutti i contenitori Docker

Come eseguire i contenitori Docker

Come rimuovere i contenitori Docker

Come fermare i container Docker

Come rinominare o rinominare i contenitori Docker

Come gestire i container Docker

Come configurare gli spazi dei nomi di rete nei contenitori Docker