Amazon ECS Linux 태스크에 Docker 가상 네트워크 사용하기

Amazon ECS Linux 태스크에 Docker 가상 네트워크 사용하기

bridge 네트워크 모드는 Amazon EC2 인스턴스에 호스팅된 Amazon ECS 태스크에만 지원돼요. bridge 모드에서는 가상 네트워크 브리지를 사용해 호스트와 컨테이너의 네트워킹 사이에 레이어를 만듭니다. 이렇게 하면 호스트 포트를 컨테이너 포트로 다시 매핑하는 포트 매핑을 만들 수 있어요. 매핑은 정적(static)이거나 동적(dynamic)일 수 있습니다.

출처: 문서

본문

정적 포트 매핑을 사용하면 컨테이너 포트에 매핑할 호스트 포트를 명시적으로 정의할 수 있어요. 앞선 예시를 사용하면, 호스트의 포트 80이 컨테이너의 포트 3000에 매핑됩니다. 컨테이너화된 애플리케이션과 통신하려면 Amazon EC2 인스턴스의 IP 주소로 포트 80에 트래픽을 보내요. 컨테이너화된 애플리케이션의 관점에서는 포트 3000에서 인바운드 트래픽을 받는 것으로 보입니다. 트래픽 포트만 변경하려면 정적 포트 매핑이 적합해요. 하지만 이 방식은 host 네트워크 모드를 사용할 때와 같은 단점이 있습니다. 각 호스트에서 태스크의 단일 인스턴스만 실행할 수 있어요. 정적 포트 매핑은 단일 컨테이너만 포트 80에 매핑할 수 있기 때문입니다. 이 문제를 해결하려면 아래 다이어그램처럼 bridge 네트워크 모드를 동적 포트 매핑과 함께 사용하는 것을 고려하세요.

포트 매핑에서 호스트 포트를 지정하지 않으면 Docker가 임시 포트 범위(ephemeral port range)에서 무작위로 사용하지 않는 포트를 골라 컨테이너의 공개 호스트 포트로 할당할 수 있어요. 예를 들어, 컨테이너에서 포트 3000으로 수신 대기하는 Node.js 애플리케이션이 Amazon EC2 호스트에서 47760 같은 무작위의 높은 포트를 할당받을 수 있습니다. 이렇게 하면 호스트에서 그 컨테이너의 여러 복사본을 실행할 수 있어요. 게다가 각 컨테이너는 호스트에서 자신만의 포트를 할당받을 수 있습니다. 각 컨테이너 복사본은 포트 3000에서 트래픽을 받아요. 그러나 이런 컨테이너에 트래픽을 보내는 클라이언트는 무작위로 할당된 호스트 포트를 사용합니다.

Amazon ECS는 각 태스크에 무작위로 할당된 포트를 추적할 수 있게 도와줘요. 로드 밸런서 대상 그룹과 AWS Cloud Map 서비스 검색을 자동으로 업데이트해 태스크 IP 주소와 포트 목록을 갖게 함으로써 이 작업을 수행합니다. 이 덕분에 동적 포트를 사용하는 bridge 모드 서비스를 더 쉽게 사용할 수 있어요.

하지만 bridge 네트워크 모드의 단점 중 하나는 서비스 간 통신을 잠그기 어렵다는 점이에요. 서비스가 무작위로 사용하지 않는 포트에 할당될 수 있기 때문에, 호스트 간에 넓은 포트 범위를 열어야 합니다. 그러나 특정 서비스가 다른 특정 서비스와만 통신할 수 있도록 구체적인 규칙을 만드는 것은 쉽지 않아요. 서비스에는 보안 그룹 네트워킹 규칙에 사용할 특정 포트가 없기 때문입니다.

IPv6 전용 워크로드를 위한 bridge 네트워킹 모드 구성

IPv6 통신용 bridge 모드를 구성하려면 Docker 데몬 설정을 업데이트해야 해요. /etc/docker/daemon.json을 다음과 같이 업데이트합니다:

{
  "ipv6": true,
  "fixed-cidr-v6": "2001:db8:1::/64",
  "ip6tables": true,
  "experimental": true
}

Docker 데몬 설정을 업데이트한 후에는 데몬을 다시 시작해야 해요.

참고: 데몬을 업데이트하고 다시 시작하면 Docker가 인스턴스에서 IPv6 포워딩을 활성화하는데, 이로 인해 Amazon Linux 2 AMI를 사용하는 인스턴스에서 기본 라우트가 유실될 수 있어요. 이를 피하려면 다음 명령으로 서브넷의 IPv6 게이트웨이를 통한 기본 라우트를 추가하세요:

ip route add default via FE80:EC2::1 dev eth0 metric 100