2 つの Docker コンテナがあります。1 つは「バックエンド」、もう 1 つは「コネクタ」です。
コネクタのネットワーク タイプを「ホスト」に設定する必要があります (udp マルチキャストを受信するには、ssdp/mdns パケット)。
ただし、コンテナ名を IP アドレスに解決できるように、docker dns システムも使用できる必要があります。
これどうやってするの?
docker-compose.yml
:
version: "3"
services:
database:
image: mongo
container_name: database
hostname: database
ports:
- "27017:27017"
backend:
image: "project/backend:latest"
container_name: backend
hostname: backend
environment:
- NODE_ENV=production
- DATABASE_HOST=database
ports:
- "8080:8080"
depends_on:
- database
tty: true
connector:
image: "project/connector:latest"
container_name: connector
hostname: connector
ports:
- "1900:1900/udp"
environment:
- NODE_ENV=production
- BACKEND_HOST=backend
depends_on:
- backend
network_mode: host
tty: true
で実行するとdocker compose up
、コネクタ コンテナーで "EAI_AGAIN" エラーが発生します。
connector | Error: getaddrinfo EAI_AGAIN backend
connector | at GetAddrInfoReqWrap.onlookup [as oncomplete] (node:dns:109:26) {
connector | errno: -3001,
connector | code: 'EAI_AGAIN',
connector | syscall: 'getaddrinfo',
connector | hostname: 'backend'
connector | }
つまり、node.js アプリはホスト名「backend」を解決できません。ネットワークが「host」に設定されているため、これは驚くことではありません。
「コネクタ」コンテナのネットワークを「ホスト」に設定しながら、他のコンテナ名を解決できるようにするにはどうすればよいでしょうか?
答え1
Docker macvlan は、選択したホスト ネットワーク インターフェイスにソフトウェア スイッチ (ブリッジ) を設定します。これは、ホストと同じインターフェイス、または異なるネットワークの異なるインターフェイスまたはサブインターフェイスにすることができます。
この macvlan docker ネットワークにコンテナを割り当てると、コンテナに一意のレイヤー 2 アドレスが作成され、macvlan の親インターフェイスにルートがある任意のレイヤー 3 IP アドレスを使用できるようになります。これにより、コンテナ ホスト ネットワーク機能 (mdns ネットワーク検出など) も提供されます。
macvlan ネットワークに割り当てられたコンテナは、compose ファイル内の他の docker ネットワークに同時に割り当てられ、docker のネットワーク内の他のコンテナと通信できます。スタックの残りの部分が消費するデータの入力としてのみ、macvlan インターフェイスを使用します。
このように行う場合の欠点と考慮事項:
Macvlan 構成は、物理的な名前付きインターフェイスを指す必要があります。また、ブリッジする実際のレイヤー 2 ネットワークに接続する必要があります。Docker 環境に macvlan を導入すると、移植性が低下します。
macvlan インターフェースが DHCP に参加するための適切な方法はありません。Docker に macvlan ネットワークのコンテナに自動的に割り当てる範囲を指定するか、各コンテナに静的 IP を個別に割り当てることができます。競合を避けるために、これらの IP を DHCP スコープから削除してください。