EC2 인스턴스에서 호스팅되는 ECS 태스크의 네트워킹 동작은 Task definition에 정의된 네트워크 모드에 따라 다르다.

Fargate의 ECS 태스크 네트워킹 동작은 기본적으로 private ip가 포함된 ENI가 제공된다.(awsvpc)

다른 네트워크 모드를 사용해야 할 특별한 필요가 있지 않는 한 awsvpc 네트워크 모드를 사용하는 것이 좋다.

더 자세히 살펴보자!


AWS ECS Task Network Mode

  • awsvpc: 태스크에 고유한 ENI(Elastic Network Interface)와 기본 private IPv4 주소 할당
    • 태스크에 EC2 인스턴스와 동일한 네트워킹 속성 적용
  • bridge: 태스크를 호스팅하는 각 EC2 인스턴스에서 실행되는 Docker의 기본 가상 네트워크를 이용
    • Docker의 기본 가상 네트워크
  • host: Docker의 기본 가상 네트워크를 우회하여 컨테이너 포트를 태스크를 호스팅하는 EC2 인스턴스의 ENI에 직접 매핑
    • 포트 매핑을 사용할 때 단일 EC2 인스턴스에서 동일 태스크에 대해 다중 인스턴스화 실행 불가능
  • none: 태스크에 외부 네트워크 연결 없음

Docker의 기본 네트워킹

  • Docker 컨테이너 및 서비스가 강력한 이유 중 하나: 함께 연결하거나 Docker가 아닌 워크로드에 연결 가능
    • 플랫폼에 구애받지 않음!
  • 네트워크 드라이버
    • https://docs.docker.com/network/ 
    • Docker의 네트워킹 하위 시스템은 드라이버를 사용하여 플러그 가능
    • bridge: 기본 네트워크 드라이버, 일반적으로 통신이 필요한 독립 실행형 컨테이너에서 애플리케이션 실행할 때
      • 동일한 Docker 호스트에서 통신하기 위해 여러 컨테이너가 필요할 때
    • host: 독립형 컨테이너의 경우 컨테이너와 Docker 호스트 간의 네트워크 격리를 제거하고 호스트의 네트워킹을 직접 사용
      • 네트워크 스택을 Docker 호스트에서 격리해서는 안되지만 컨테이너의 다른 측면을 격리하려는 경우
    • overlay: 여러 Docker 데몬을 함께 연결하고 스웜 서비스가 서로 통신할 수 있도록
      • 통신을 위해 서로 다른 Docker 호스트에서 실행되는 컨테이너가 필요하거나 Swarm 서비스를 사용하여 여러 애플리케이션이 함께 작동할 때
    • ipvlan: 사용자에게 IPv4 및 IPv6 주소 지정에 대한 완전한 제어 제공
    • macvlan: MAC 주소를 할당하여 네트워크에서 물리적 장치로 표시
      • VM 설정에서 마이그레이션하거나 컨테이너가 고유한 MAC 주소를 가진 네트워크의 물리적 호스트처럼 보일 때
    • none: 모든 네트워킹 비활성화
    • 네트워크 플러그인: Docker와 함께 타사 네트워크 플러그인을 설치하고 사용할 수 있음
      • Docker를 특수 네트워크 스택과 통합 가능

이제 ECS 태스크 네트워킹 하나씩 따져보자!

awsvpc 네트워크 모드

  • ECS 태스크에 EC2 인스턴스와 동일한 네트워킹 속성을 제공
  • 컨테이너 네트워킹을 간소화하고 컨테이너화된 애플리케이션이 서로, 그리고 VPC 내 다른 서비스와 통신하는 방식을 더 세부적으로 제어 가능
  • 태스크 내에서 더 세부적으로 보안 그룹 및 네트워크 모니터링 도구를 사용 가능하게 만들어 컨테이너의 보안을 강화
  • 각 태스크는 고유한 ENI를 받으므로 VPC Flow Log와 같은 기타 EC2 네트워킹 기능을 이용하여 태스크에서 주고받는 트래픽을 모니터링 가능
  • 같은 태스크에 속한 컨테이너는 localhost 인터페이스로 통신 가능
  • Task ENI
    • ECS의 완전 관리형 기능
    • ENI를 생성하고 지정된 보안 그룹이 있는 호스트 EC2 인스턴스에 연결
    • 기본적으로 private ip 할당, VPC가 듀얼 스택모드를 사용하도록 설정

 

  • EC2 인스턴스는 ENI에 할당, ENI는 호스트 수준에서 네트워크 통신에 사용되는 EC2 인스턴스의 IP 주소를 나타냄: 172.31.16.0
  • 각 태스크에는 해당 ENI 및 private ip 주소 있음: 172.31.16.1 / 172.31.16.2
  • 각 ENI는 분리되어 있으므로 각 컨테이너는 포트에 바인딩 가능 :80 → 포트 번호 추적할 필요 없음
  • 장점: 각 태스크에 트래픽을 허용하거나 거부하는 별도의 보안그룹
  • 단점: EC2 인스턴스에 연결할 수 있는 ENI 개수에는 한도가 있음 → Trunk ENI 기능 제공

  • 단점: 태스크에 별도의 IP 주소를 할당하면 보안 강화에 좋지만, IP 소진으로 이어질 수 있음
    • 특히 ENI 트렁킹을 사용하면 시작하는 각 EC2 인스턴스에는 두 개의 ip 주소 필요
    • → 호스트와 다른 IP 주소 공간에서 ENI를 사용하도록 VPC CNI 구성

 

bridge 네트워크 모드

  • 각 컨테이넌 인스턴스에서 실행되는 Docker의 기본 가상 네트워크 이용
  • bridge: 동일한 브리지 네트워크에 연결된 각 컨테이너가 서로 통신할 수 있도록 하는 내부 네트워크 네임스페이스
  • 동일한 브리지 네트워크에 연결되지 않은 컨테이너에서 격리 경계도 제공
  • 정적 또는 동적 포트 매핑을 사용하여 컨테이너의 포트를 EC2 호스트 포트와 매핑

  • 정적 포트 매핑 사용: 컨테이너 포트에 매핑할 호스트 포트를 명시적으로 정의 가능
    • 위 그림에서 컨테이너화된 응용 프로그램의 관점에서 포트의 인바운드 트래픽은 3000 포트
    • 트래픽 포트만 변경하려는 경우에 적합
    • 단점: 각 호스트에서 태스크의 인스턴스화를 하나 이상 실행할 수 없음(단일 컨테이너만 80 포트에 연결 가능)

  • 동적 포트 매핑 사용: 포트 매핑에 호스트 포트를 지정하지 않으면 Docker가 임시 포트 범위에서 사용되지 않는 임의의 포트를 선택해 컨테이너의 공용 호스트 포트로 할당하도록
    • 호스트에서 해당 컨테이너의 여러 복사본 실행 가능
    • 각 컨테이너는 호스트에 자체 포트 할당 가능
    • Task definition 과정에서 호스트 포트를 0번으로 설정
      • (에페메랄 포트 범위의 포트가 자동으로 할당, target group의 포트는 무시)
    • 단점: 사용되지 않는 임의의 포트에 할당될 수 있어 호스트 간에 광범위한 포트 범위를 열어야 함.
      • 특정 서비스가 다른 특정 서비스와만 통신할 수 있도록 특정 규칙을 만들기 어렵다.
  • Fargate 지원 안함.

 

host 네트워크 모드

  • 컨테이너가 실행 중인 EC2 인스턴스 호스트에 직접 연결됨.
  • 각 컨테이너는 이를 호스팅하는 EC2 인스턴스의 IP 주소를 통해 트래픽을 수신
  • ECS에서 지원되는 가장 기본적인 네트워크 모드

  • 단점: 각 호스트에서 태스크의 인스턴스화를 하나 이상 실행할 수 없음
    • 첫 번째 태스크만 EC2 인스턴스의 필수 포트에 바인딩할 수 있기 때문
    • 특정 포트 번호에서 수신 대기해야하는 경우 포트 번호를 직접 다시 매핑 불가능
    • → 응용 프로그램 구성을 변경하여 포트 충돌을 관리해야함.
  • Fargate 지원 안함.

사실 저 위의 내용이 크게 와닿진 않는다..😥

전체적인 ECS 네트워킹 과정(?)을 훑어보면, https://docs.aws.amazon.com/ko_kr/AmazonECS/latest/bestpracticesguide/networking.html

1. 인터넷에 연결하기: 대부분의 컨테이너화된 응용 프로그램에는 인터넷에 대한 아웃바운드 액세스가 필요한 일부 구성 요소 있음.(퍼블릭 서브넷 + igw / 프라이빗 서브넷 + ngw)

2. 인터넷에서 인바운드 연결 수신: 퍼블릭 IP 주소 사용 / ALB / NLB / API Gateway HTTP API

3. 네트워크 모드 선택: 인바운드 및 아웃바운드 네트워크 연결을 설계하기 위해선 다른 수준의 네트워킹을 고려해야함

"여러 컨테이너를 단일 호스트에 압축" → 동일한 호스트에서 실행중인 컨테이너를 네트워크화하는 방법을 선택

(awsvpc / bridge / host)

 

그냥 단순히 생각을 해보면.. 컨테이너의 네트워크 관리를 어떻게 할건지의 느낌인 것 같은데 

포트 매핑에 있어서 어떻게 할 건지.. (호스트 포트 / 컨테이너 포트) 포트 번호 선택의 문제인 듯?

(호스트 포트를 지정할 경우 각 호스트에서 태스크의 인스턴스화를 하나 이상 실행할 수 없음!)

awsvpc로 하면 알아서 관리해주는 거고, bridge로 하면 사용자가 매핑을 하는 느낌..

 

❗ 어렵다 어려워! ❗

+ Recent posts