Docker Swarm のオーバーレイ ネットワーク DNS は、ホスト名をコンテナの実際の IP より 1 つ小さい IP アドレスに一貫して解決します。

Docker Swarm のオーバーレイ ネットワーク DNS は、ホスト名をコンテナの実際の IP より 1 つ小さい IP アドレスに一貫して解決します。

Docker Swarm で非常に奇妙で再現可能な問題が発生しています。4 つの LXD コンテナにまたがる Docker Swarm 経由で Dgraph サーバー クラスターを展開しようとしています。コンテキストとして、Dgraph Zero は制御サーバーであり、各 Dgraph Alpha サーバーが作業を行い、起動時に Zero サーバーに接続する必要があります。Ratel は、データベース クエリとミューテーション用の Web UI サーバーにすぎません。トポグラフィーは次のようになります。

  • ホスト: KDE Neon ワークステーション
    • LXDコンテナ: ゼロ
      • Docker ノード: dg-zero
        • Dockerコンテナ: dgraph_zero
        • Docker コンテナ: dgraph_ratel
    • LXD コンテナ: alpha1
      • Docker ノード: dg-alpha1
        • Docker コンテナ: dgraph_alpha1
    • LXD コンテナ: alpha2
      • Docker ノード: dg-alpha2
        • Docker コンテナ: dgraph_alpha2
    • LXD コンテナ: alpha3
      • Docker ノード: dg-alpha3
        • Docker コンテナ: dgraph_alpha3

docker stack deployこれらはすべて、次の docker-compose.yml 構成を使用してswarm としてデプロイされます。

version: "3"
networks:
  dgraph:
services:
  zero:
    image: dgraph/dgraph:latest
    hostname: "zero"
    volumes:
      - data-volume:/dgraph
    ports:
      - "5080:5080"
      - "6080:6080"
    networks:
      - dgraph
    deploy:
      placement:
        constraints:
          - node.hostname == dg-zero
    command: dgraph zero --my=zero:5080 --replicas 3 --bindall=true
  alpha1:
    image: dgraph/dgraph:latest
    hostname: "alpha1"
    volumes:
      - data-volume:/dgraph
    ports:
      - "8080:8080"
      - "9080:9080"
    networks:
      - dgraph
    deploy:
      placement:
        constraints:
          - node.hostname == dg-alpha1
    command: dgraph alpha --my=alpha1:7080 --lru_mb=1024 --zero=zero:5080 --bindall=true
  alpha2:
    image: dgraph/dgraph:latest
    hostname: "alpha2"
    volumes:
      - data-volume:/dgraph
    ports:
      - "8081:8081"
      - "9081:9081"
    networks:
      - dgraph
    deploy:
      placement:
        constraints:
          - node.hostname == dg-alpha2
    command: dgraph alpha --my=alpha2:7081 --lru_mb=1024 --zero=zero:5080 -o 1 --bindall=true
  alpha3:
    image: dgraph/dgraph:latest
    hostname: "alpha3"
    volumes:
      - data-volume:/dgraph
    ports:
      - "8082:8082"
      - "9082:9082"
    networks:
      - dgraph
    deploy:
      placement:
        constraints:
          - node.hostname == dg-alpha3
    command: dgraph alpha --my=alpha3:7082 --lru_mb=1024 --zero=zero:5080 -o 2 --bindall=true
  ratel:
    image: dgraph/dgraph:latest
    hostname: "ratel"
    ports:
      - "8000:8000"
    networks:
      - dgraph
    command: dgraph-ratel
volumes:
  data-volume:

すべてのサービスは正しくデプロイされ、実行されています。問題は、ホスト名が正しい IP に解決されないため、サービスが相互に通信できないことです。

現在、swarm を実行しており、docker container inspect実行中の Zero コンテナで実行すると、ネットワーク構成について次の出力が表示されます。

"NetworkSettings": {
            "Bridge": "",
            "SandboxID": "4548013a15833d086b281a8c2dd61ced6ea5c92f815a305f7337effe9b04a13a",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "8080/tcp": null,
                "9080/tcp": null
            },
            "SandboxKey": "/var/run/docker/netns/4548013a1583",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "",
            "Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "",
            "IPPrefixLen": 0,
            "IPv6Gateway": "",
            "MacAddress": "",
            "Networks": {
                "dgraph_dgraph": {
                    "IPAMConfig": {
                        "IPv4Address": "10.0.9.3"
                    },
                    "Links": null,
                    "Aliases": [
                        "8b48711ab0cd"
                    ],
                    "NetworkID": "lve3kr9vm42rwu1nci897zey7",
                    "EndpointID": "056ae62475da805ec212d9ec2b2e4a5c9e09e2405c15ad6e8b298e90669b512d",
                    "Gateway": "",
                    "IPAddress": "10.0.9.3",
                    "IPPrefixLen": 24,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:0a:00:09:03",
                    "DriverOpts": null
                },
                "ingress": {
                    "IPAMConfig": {
                        "IPv4Address": "10.0.0.157"
                    },
                    "Links": null,
                    "Aliases": [
                        "8b48711ab0cd"
                    ],
                    "NetworkID": "vjhpbsc1766lbvtu169fmh81l",
                    "EndpointID": "29bbc4de97e98b2e05a46dd42020dd1fbb75ff07d8c08a00b8ba6f2f4e00ec2a",
                    "Gateway": "",
                    "IPAddress": "10.0.0.157",
                    "IPPrefixLen": 24,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:0a:00:00:9d",
                    "DriverOpts": null
                }
            }
        }

ご覧のとおり、私の Zero コンテナの IP アドレスは 10.0.9.3 です。ただし、いずれかの Alpha コンテナのシェルにログインして実行すると、ping zero10.0.9.2 に ping しようとします。これは、スタックを破棄して再デプロイすることで一貫して再現できます。私の Zero コンテナの IP アドレスの最後のオクテットは、zero他の 3 つのコンテナでホスト名が解決される IP アドレスより常に 1 大きくなります。正しい IP アドレスを使用して、すべてのコンテナを相互に ping できますが、スウォームの作成前に他のコンテナのアドレスがわからないため、ホスト名を使用する必要があります。また、サーバー クラスターが相互に通信できるように構成する必要があります。

ファイアウォール ルールは設定されていません。LXD コンテナーはすべて通信できます。すべての LXD コンテナー IP アドレスは、Docker ネットワーク構成でピアとしてリストされています。関連があるかどうかはわかりませんが、ポートを公開したにもかかわらず、ホスト コンテナーからサービスにアクセスできません。関連している可能性がある場合は、見つけた詳細情報を提供できますが、今のところは省略します。

Swarm が正しいホスト名を正しいコンテナに解決できない理由をどうやって調べればよいですか?

Docker のバージョンは公式リポジトリの 19.03.5 です。LXD コンテナーは、Ubuntu の LXD イメージ サーバーからの公式 18.04 クラウド コンテナーです。ホストは Ubuntu 18.04 に基づく KDE Neon です。

関連情報