Docker oferă posibilitatea de a împacheta și rula o aplicație într-un mediu izolat, numit container.

Știu la ce s-ar putea să te gândești – hai, nu un alt post care să explice ce este Docker, este peste tot în zilele noastre!

Cum sa obtineti o adresa IP a containerului Docker

Dar nu vă faceți griji, omitem acea introducere de bază. Publicul țintă pentru acest articol ar trebui să aibă deja o înțelegere de bază a ceea ce sunt Docker și containere.

Dar v-ați întrebat vreodată cum să obțineți o adresă IP a containerului Docker?

Rețeaua Docker a explicat

În primul rând, să înțelegem cum funcționează rețeaua Docker. Pentru aceasta ne vom concentra asupra valorii implicite bridge reţea. Când utilizați Docker, dacă nu specificați un driver, acesta este tipul de rețea pe care îl utilizați.

Cum sa obtineti o adresa IP a containerului Docker
Rețea Docker de la: înțelegere-docker-rețea-drivere-cazuri-de-utilizare

bridge rețeaua funcționează ca o rețea privată internă a gazdei, astfel încât containerele de pe ea să poată comunica. Accesul extern se acordă prin expunerea porturilor la containere.

Rețelele Bridge sunt utilizate atunci când aplicațiile dvs. rulează în containere independente care trebuie să comunice.

În imaginea de mai sus db și web pot comunica între ei pe o rețea pod creată de utilizator numită mybridge.

Dacă nu ați adăugat niciodată o rețea în Docker, ar trebui să vedeți ceva similar cu acesta:

$ docker network ls

NETWORK ID          NAME                  DRIVER              SCOPE
c3cd46f397ce        bridge                bridge              local
ad4e4c24568e        host                  host                local
1c69593fc6ac        none                  null                local

Implicit bridge este listată rețeaua, împreună cu host și none. Îi vom ignora pe ceilalți doi și vom folosi bridge atunci când ajungem la exemple.

Adresa IP a containerului Docker

În mod implicit, containerului i se atribuie o adresă IP pentru fiecare rețea Docker la care se conectează. Și fiecare rețea este creată cu o mască de subrețea implicită, folosind-o ca un pool ulterior pentru a oferi adresele IP.

De obicei, Docker folosește valoarea implicită 172.17. 0,0 / 16 subrețea pentru rețeaua de containere.

Acum, pentru a o înțelege mai bine, vom executa un caz de utilizare real.

desen

Exemplu Docker

Pentru a ilustra acest lucru, vom folosi un mediu Hive și Hadoop, care conține 5 containere Docker.

Verificați docker-compose.yml fișier pe care urmează să îl executăm:

version: "3"

services:
  namenode:
    image: bde2020/hadoop-namenode:2.0.0-hadoop2.7.4-java8
    volumes:
      - namenode:/hadoop/dfs/name
    environment:
      - CLUSTER_NAME=test
    env_file:
      - ./hadoop-hive.env
    ports:
      - "50070:50070"
  datanode:
    image: bde2020/hadoop-datanode:2.0.0-hadoop2.7.4-java8
    volumes:
      - datanode:/hadoop/dfs/data
    env_file:
      - ./hadoop-hive.env
    environment:
      SERVICE_PRECONDITION: "namenode:50070"
    ports:
      - "50075:50075"
  hive-server:
    image: bde2020/hive:2.3.2-postgresql-metastore
    env_file:
      - ./hadoop-hive.env
    environment:
      HIVE_CORE_CONF_javax_jdo_option_ConnectionURL: "jdbc:postgresql://hive-metastore/metastore"
      SERVICE_PRECONDITION: "hive-metastore:9083"
    ports:
      - "10000:10000"
  hive-metastore:
    image: bde2020/hive:2.3.2-postgresql-metastore
    env_file:
      - ./hadoop-hive.env
    command: /opt/hive/bin/hive --service metastore
    environment:
      SERVICE_PRECONDITION: "namenode:50070 datanode:50075 hive-metastore-postgresql:5432"
    ports:
      - "9083:9083"
  hive-metastore-postgresql:
    image: bde2020/hive-metastore-postgresql:2.3.0

volumes:
  namenode:
  datanode:

Din docker-stup GitHub

Nimeni nu vrea să citească un IMENS fișier de configurare, nu? Iată deci o imagine:

1611890708 636 Cum sa obtineti o adresa IP a containerului Docker

Mult mai bine! Acum să pornim aceste containere:

docker-compose up -d

Putem vedea 5 containere:

$ docker ps --format 
"table {{.ID}}t{{.Status}}t{{.Names}}"

CONTAINER ID        STATUS                   NAMES
158741ba0339        Up 1 minutes             dockerhive_hive-metastore-postgresql
607b00c25f29        Up 1 minutes             dockerhive_namenode
2a2247e49046        Up 1 minutes             dockerhive_hive-metastore
7f653d83f5d0        Up 1 minutes (healthy)   dockerhive_hive-server
75000c343eb7        Up 1 minutes (healthy)   dockerhive_datanode

În continuare, să verificăm rețelele noastre Docker:

$ docker network ls

NETWORK ID          NAME                  DRIVER              SCOPE
c3cd46f397ce        bridge                bridge              local
9f6bc3c15568        docker-hive_default   bridge              local
ad4e4c24568e        host                  host                local
1c69593fc6ac        none                  null                local

Stai puțin … există o nouă rețea numită docker-hive_default!

În mod implicit, docker compose configurează o singură rețea pentru aplicația dvs. Și rețeaua aplicației dvs. primește un nume bazat pe „numele proiectului”, provenit din numele directorului în care trăiește.

Deci, deoarece directorul nostru este numit docker-hive, acest lucru explică noua rețea.

În continuare câteva exemple despre cum să obțineți adresa IP Docker.

Cum să obțineți o adresă IP a containerului Docker – exemple

Și acum, că am atenția voastră, vom dezvălui misterul.

desen

1. Folosind Docker Inspect

Docker inspect este o modalitate excelentă de a prelua informații de nivel scăzut despre obiectele Docker. Puteți alege orice câmp din JSON returnat într-un mod destul de simplu.

Deci, îl vom folosi pentru a obține adresa IP de la dockerhive_datanode?

$ docker inspect -f 
'{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' 
75000c343eb7

172.18.0.5

Nu ai spus că Docker folosește valoarea implicită 172.17. 0,0 / 16 subrețea pentru rețeaua de containere? De ce este adresa IP returnată: 172.18.0.5 în afara ei?

1611890708 82 Cum sa obtineti o adresa IP a containerului Docker
Imagine creată pe adresa-IP-în-cidr-interval

Pentru a răspunde că trebuie să ne uităm la setările noastre de rețea:

$ docker network inspect -f 
'{{range .IPAM.Config}}{{.Subnet}}{{end}}'  9f6bc3c15568

172.18.0.0/16

Am executat acest exemplu într-o mașină virtuală Compute Engine și, în acest test, rețelei de andocare i s-a atribuit o subrețea diferită: 172.18.0.0/16. Asta o explică!

În plus, putem căuta și toate adresele IP din interiorul docker-hive_default reţea.

Deci, nu este nevoie să căutăm în mod individual IP-ul fiecărui container:

$ docker network inspect -f 
'{{json .Containers}}' 9f6bc3c15568 | 
jq '.[] | .Name + ":" + .IPv4Address'

"dockerhive_hive-metastore-postgresql:172.18.0.6/16"
"dockerhive_hive-metastore:172.18.0.2/16"
"dockerhive_namenode:172.18.0.3/16"
"dockerhive_datanode:172.18.0.5/16"
"dockerhive_hive-server:172.18.0.4/16"

desen

Dacă nu ai observat, am folosit jq ajuta la analiza Containers obiect hartă.

2. Folosind Docker exec

În exemplul următor vom lucra cu dockerhive_namenode.

$ docker exec dockerhive_namenode cat /etc/hosts

127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.18.0.3      607b00c25f29

3. În interiorul containerului Docker

$ docker exec -it dockerhive_namenode /bin/bash

# running inside the dockerhive_namenode container
ip -4 -o address

7: eth0    inet 172.18.0.3/16 brd 172.18.255.255 scope global eth0

Putem găsi chiar și adresele IP ale altor containere care se află în interiorul unui container din aceeași rețea:

Nod de date

# running inside the dockerhive_namenode container
ping dockerhive_datanode

PING dockerhive_datanode (172.18.0.5): 56 data bytes
64 bytes from 172.18.0.5: icmp_seq=0 ttl=64 time=0.092 ms

Hast mestastore

# running inside the dockerhive_namenode container
ping dockerhive_hive-metastore

PING dockerhive_hive-metastore_1 (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: icmp_seq=0 ttl=64 time=0.087 ms

Server Hive

# running inside the container
ping dockerhive_hive-server

PING dockerhive_hive-server (172.18.0.4): 56 data bytes
64 bytes from 172.18.0.4: icmp_seq=0 ttl=64 time=0.172 ms

Învelire

Toate exemplele au fost executate într-o distribuție Linux Compute Engine VM. Dacă le executați în medii MacOS sau Windows, exemplele de comenzi s-ar putea schimba puțin.

De asemenea, rețineți că acele adrese IP din exemplele date sunt interne pentru eșantion docker-hive_default reţea. Deci, dacă aveți un caz de utilizare pentru a vă conecta la aceste containere extern, ar trebui să utilizați IP-ul extern al mașinii gazdă (presupunând că expuneți corect porturile containerelor).

Sau dacă utilizați kubernetes, de exemplu, pentru a vă gestiona containerele Docker, lăsați-l să gestioneze adresele IP pentru dvs. kubernetes-expose-external-IP-address ?

* Ilustrații din icons8.com de Murat Kalkavan.