Sådan får du en Docker Container IP-adresse - forklaret med eksempler

Docker giver mulighed for at pakke og køre et program i et løst isoleret miljø kaldet en container.

Jeg ved, hvad du måske tænker - kom igen, ikke et andet indlæg, der forklarer, hvad Docker er, det er overalt i disse dage!

Men rolig, vi springer over den grundlæggende introduktion. Målgruppen for denne artikel skal allerede have en grundlæggende forståelse af, hvad Docker og containere er.

Men har du nogensinde spekuleret på, hvordan du får en Docker Container IP-adresse?

Docker-netværk forklaret

Lad os først forstå, hvordan Docker-netværket fungerer. Til det vil vi fokusere på standardnetværket bridge. Når du bruger Docker, er det den type netværk, du bruger, hvis du ikke angiver en driver.

Den bridgenetværket fungerer som et privat netværk internt til værten, så containere på den kan kommunikere. Ekstern adgang gives ved at eksponere havne for containere.

Bridge-netværk bruges, når dine applikationer kører i enkeltstående containere, der skal kommunikere.

På billedet ovenfor dbog webkan kommunikere med hinanden på et brugeroprettet bronetværk kaldet mybridge.

Hvis du aldrig har tilføjet et netværk i Docker, skal du se noget lignende:

$ docker network ls NETWORK ID NAME DRIVER SCOPE c3cd46f397ce bridge bridge local ad4e4c24568e host host local 1c69593fc6ac none null local

Standardnetværket bridgevises sammen med hostog none. Vi vil ignorere de to andre og bruge bridgenetværket, når vi kommer til eksemplerne.

Docker Container IP-adresse

Containeren tildeles som standard en IP-adresse til hvert Docker-netværk, den opretter forbindelse til. Og hvert netværk oprettes med en standard undernetmaske, der bruger den som en pool senere for at give IP-adresserne væk.

Normalt bruger Docker standard 172.17. 0,0 / 16 undernet til containernetværk.

Nu for bedre at forstå det, vil vi udføre en reel brugssag.

tegning

Docker-eksempel

For at illustrere dette bruger vi et Hive- og Hadoop-miljø, der indeholder 5 Docker-containere.

Tjek den docker-compose.ymlfil, vi skal udføre:

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: 

Fra docker-bikube GitHub

Ingen ønsker at læse en Kæmpe konfigurationsfil, ikke? Så her er et billede:

Meget bedre! Lad os nu starte disse containere:

docker-compose up -d 

Vi kan se 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

Lad os derefter kontrollere vores Docker-netværk:

$ 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

Vent et øjeblik ... der hedder et nyt netværk docker-hive_default!

Som standard konfigurerer docker compose et enkelt netværk til din app. Og din apps netværk får et navn baseret på "projektnavnet", der stammer fra navnet på den mappe, den bor i.

Så da vores katalog er navngivet docker-hive, forklarer dette det nye netværk.

Dernæst nogle eksempler på, hvordan du får Docker IP-adresse.

Sådan får du en Docker Container IP-adresse - eksempler

Og nu hvor jeg har fået din opmærksomhed, vil vi afsløre mysteriet.

tegning

1. Brug af Docker Inspect

Docker-inspektion er en fantastisk måde at hente oplysninger på lavt niveau om Docker-objekter på. Du kan vælge et hvilket som helst felt fra den returnerede JSON på en ret ligetil måde.

Så skal vi bruge den til at hente IP-adressen fra dockerhive_datanode?

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

Sagde du ikke, at Docker bruger standard 172.17. 0,0 / 16 undernet til containernetværk? Hvorfor er den returnerede IP-adresse: 172.18.0.5  uden for den?

For at svare på det skal vi se på vores netværksindstillinger:

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

Vi udførte dette eksempel i en Compute Engine VM, og i denne test fik docker-netværket et andet undernet: 172.18.0.0/16 . Det forklarer det!

Desuden kan vi også slå alle IP-adresser op i docker-hive_defaultnetværket.

Så vi behøver ikke slå hver container IP op individuelt:

$ 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"
tegning

Hvis du ikke bemærkede det, brugte vi jq- hjælp til at analysere kortobjektetContainers .

2. Brug af Docker exec

I det følgende eksempel arbejder vi med 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. Inde i Docker Container

$ 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

Vi kan endda finde andre containers IP-adresser, der er inde i en container i det samme netværk:

Dataknude

# 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

Hive 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

Hive-server

# 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

Pak ind

Alle eksempler blev udført i en Linux-distribution Compute Engine VM. Hvis du udfører dem i macOS- eller Windows-miljøer, kan prøvekommandoerne muligvis ændre sig lidt.

Husk også, at disse IP-adresser i de givne eksempler er interne i eksempelnetværket docker-hive_default. Så hvis du har en brugssag til at oprette forbindelse til disse containere eksternt, skal du bruge værtsmaskinens eksterne IP (forudsat at du udsætter containerportene korrekt).

Eller hvis du f.eks. Bruger kubernetes til at styre dine Docker-containere, så lad det håndtere IP-adresserne for dig kubernetes-expose-external-ip-address?

* Illustrationer fra icons8.com af Murat Kalkavan.