DockerコンテナのIPアドレスを取得する方法-例を使用して説明

Dockerは、コンテナーと呼ばれる緩く分離された環境でアプリケーションをパッケージ化して実行する機能を提供します。

私はあなたが何を考えているのか知っています-Dockerが何であるかを説明する別の投稿ではなく、最近どこにでもあります!

ただし、心配しないでください。基本的な紹介はスキップします。この記事の対象読者は、Dockerとコンテナーが何であるかについての基本的な理解をすでに持っているはずです。

しかし、DockerコンテナのIPアドレスを取得する方法を考えたことはありますか?

Dockerネットワークの説明

まず、Dockerネットワークがどのように機能するかを理解しましょう。そのために、デフォルトbridgeネットワークに焦点を当てます。Dockerを使用している場合、ドライバーを指定しないと、これが使用しているネットワークのタイプになります。

bridgeネットワークは、その上にコンテナが通信できるようにホストに内部のプライベートネットワークとして機能します。外部アクセスは、ポートをコンテナに公開することで許可されます。

ブリッジネットワークは、通信が必要なスタンドアロンコンテナでアプリケーションを実行するときに使用されます。

上の図dbwebは、と呼ばれるユーザー作成のブリッジネットワーク上で相互に通信できますmybridge

Dockerにネットワークを追加したことがない場合は、次のようなものが表示されます。

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

デフォルトbridgeネットワークは、hostおよびとともにリストされていますnone。他の2つは無視bridgeし、例に到達したらネットワークを使用します。

DockerコンテナのIPアドレス

デフォルトでは、コンテナには、接続するすべてのDockerネットワークのIPアドレスが割り当てられます。また、各ネットワークはデフォルトのサブネットマスクを使用して作成され、後でIPアドレスを提供するためのプールとして使用されます。

通常、Dockerはデフォルトの172.17を使用しますコンテナネットワーク用の0.0 / 16サブネット。

これをよりよく理解するために、実際のユースケースを実行します。

図

Dockerの例

これを説明するために、5つのDockerコンテナを含むHiveおよびHadoop環境を使用します。

docker-compose.yml実行しようとしているファイルを確認してください。

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: 

ドッキングウィンドウ、ハイブのGitHub

巨大な設定ファイルを読みたくない人はいませんよね?だからここに写真があります:

ずっといい!それでは、これらのコンテナを起動しましょう。

docker-compose up -d 

5つのコンテナを見ることができます:

$ 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

次に、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

ちょっと待ってください...という新しいネットワークがありますdocker-hive_default

デフォルトでは、dockercomposeはアプリに単一のネットワークをセットアップします。また、アプリのネットワークには、アプリが存在するディレクトリの名前に由来する「プロジェクト名」に基づいた名前が付けられています。

ディレクトリに名前が付けられているdocker-hiveので、これは新しいネットワークを説明しています。

次に、DockerIPアドレスを取得する方法に関するいくつかの例。

DockerコンテナのIPアドレスを取得する方法-例

そして今、私はあなたの注意を引いたので、私たちは謎を明らかにするつもりです。

図

1. DockerInspectを使用する

Docker inspectは、Dockerオブジェクトに関する低レベルの情報を取得するための優れた方法です。返されたJSONから、かなり簡単な方法で任意のフィールドを選択できます。

それでは、それを使用してdockerhive_datanode?からIPアドレスを取得しますか?

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

Didn't you say that Docker uses the default 172.17. 0.0/16 subnet for container networking? Why is the returned IP Address: 172.18.0.5  outside it?

To answer that we have to look at our network settings:

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

We executed this example in a Compute Engine VM, and in this test, the docker network was assigned a different subnet: 172.18.0.0/16. That explains it!

Furthermore, we can also lookup all IP Addresses inside the docker-hive_default network.

So we don't need to look up each Container's IP individually:

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

If you didn't notice, we used jq help to parse the Containers map object.

2. Using Docker exec

In the following example we will work with the 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. Inside the 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

同じネットワーク内のコンテナ内にある他のコンテナのIPアドレスを見つけることもできます。

データノード

# 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

ハイブメスタストア

# 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

ハイブサーバー

# 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

要約

すべての例は、LinuxディストリビューションのCompute EngineVMで実行されました。macOSまたはWindows環境で実行すると、サンプルコマンドが少し変わる場合があります。

また、示されている例のIPアドレスは、サンプルdocker-hive_defaultネットワークの内部にあることにも注意してください。したがって、これらのコンテナに外部から接続するユースケースがある場合は、ホストマシンの外部IPを使用する必要があります(コンテナのポートを正しく公開していると仮定します)。

または、たとえばkubernetesを使用してDockerコンテナを管理している場合は、kubernetes-expose-external-ip-address?のIPアドレスを処理させます。

* MuratKalkavanによるicons8.comからのイラスト。