Docker Swarm의 오버레이 네트워크 DNS는 호스트 이름을 컨테이너의 실제 IP보다 한 숫자 낮은 IP 주소로 지속적으로 확인합니다.

Docker Swarm의 오버레이 네트워크 DNS는 호스트 이름을 컨테이너의 실제 IP보다 한 숫자 낮은 IP 주소로 지속적으로 확인합니다.

Docker Swarm에 재현 가능한 매우 이상한 문제가 있습니다. Docker Swarm을 통해 4개의 LXD 컨테이너에 Dgraph 서버 클러스터를 배포하려고 합니다. 맥락에 따라 Dgraph Zero는 제어 서버이고 각 Dgraph Alpha 서버는 리프팅을 수행하며 실행 시 Zero 서버에 연결해야 합니다. Ratel은 데이터베이스 쿼리 및 변이를 위한 웹 UI 서버일 뿐입니다. 지형은 다음과 같습니다.

  • 호스트: KDE Neon 워크스테이션
    • LXD 컨테이너: 0
      • 도커 노드: dg-zero
        • 도커 컨테이너: dgraph_zero
        • 도커 컨테이너: dgraph_ratel
    • LXD 컨테이너: alpha1
      • 도커 노드: dg-alpha1
        • 도커 컨테이너: dgraph_alpha1
    • LXD 컨테이너: alpha2
      • 도커 노드: dg-alpha2
        • 도커 컨테이너: dgraph_alpha2
    • LXD 컨테이너: alpha3
      • 도커 노드: dg-alpha3
        • 도커 컨테이너: dgraph_alpha3

docker stack deploy이들은 모두 다음 docker-compose.yml 구성을 사용하여 떼로 배포됩니다 .

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로 확인되지 않기 때문에 서로 통신할 수 없다는 것입니다.

현재 실행 중인 떼가 있고 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다른 세 컨테이너에서 호스트 이름이 확인되는 IP 주소보다 1이 더 큽니다. 올바른 IP 주소를 사용하여 서로 내 모든 컨테이너를 핑할 수 있지만 스웜 생성 전에 다른 컨테이너의 주소가 무엇인지 모르고 서버 클러스터와 통신하도록 구성해야 하기 때문에 호스트 이름을 사용해야 합니다. 서로.

방화벽 규칙이 없습니다. 내 LXD 컨테이너는 모두 통신할 수 있습니다. 모든 LXD 컨테이너 IP 주소는 Docker 네트워크 구성에 피어로 나열됩니다. 관련이 있는지 없는지는 모르겠지만 포트를 게시했는데도 호스트 컨테이너에서 내 서비스에 연결할 수 없습니다. 가능하다면 제가 찾은 추가 정보를 제공할 수 있지만 지금은 생략하겠습니다.

내 떼가 올바른 호스트 이름을 올바른 컨테이너로 확인하지 못하는 이유를 어떻게 알 수 있나요?

Docker 버전은 공식 저장소의 19.03.5입니다. LXD 컨테이너는 Ubuntu LXD 이미지 서버의 공식 18.04 클라우드 컨테이너입니다. 호스트는 Ubuntu 18.04 기반의 KDE Neon입니다.

관련 정보