이그레스 NAT 게이트웨이 구성

VMware용 GKE를 사용하면 소스 네트워크 주소 변환(SNAT)을 구성하여 사용자 클러스터의 특정 이그레스 트래픽에 예측 가능한 소스 IP 주소를 제공할 수 있습니다.

이 문서에서는 사용자 클러스터에 대해 이그레스 NAT 게이트웨이를 구성하는 방법을 설명합니다.

소개

때로는 사용자 클러스터에서 실행 중인 포드에서 조직 안이지만 클러스터 외부에서 실행 중인 구성요소에 패킷을 전송해야 하는 경우가 있습니다. 잘 알려진 소스 IP 주소 집합에 따라 수신 네트워크 트래픽을 필터링하도록 이러한 외부 구성요소를 설계해야 할 수 있습니다.

몇 가지 시나리오는 다음과 같습니다.

  • IP 주소만으로 액세스를 허용하는 데이터베이스 앞에 방화벽이 있습니다. 그리고 데이터베이스 방화벽을 관리하는 팀이 사용자 클러스터 관리팀과 다릅니다.

  • 사용자 클러스터의 워크로드가 인터넷을 통해 타사 API에 액세스해야 합니다. 보안상의 이유로 API 공급업체는 IP 주소를 ID로 사용하여 트래픽을 인증하고 권한을 부여합니다.

이그레스 NAT 게이트웨이를 사용하면 클러스터를 나가는 네트워크 트래픽에 사용되는 소스 IP 주소를 세밀하게 제어할 수 있습니다.

가격 책정

미리보기 중에는 이 기능 사용에 따른 비용이 청구되지 않습니다.

이그레스 NAT 게이트웨이 작동 방법

일반적으로 포드가 클러스터에서 패킷을 전송하면 포드가 실행 중인 노드의 IP 주소로 패킷이 SNAT 변환됩니다.

이그레스 NAT 게이트웨이가 배치되어 있으면 특정 아웃바운드 패킷을 전용 게이트웨이 노드로 먼저 전송하도록 지정할 수 있습니다. 게이트웨이 노드의 네트워크 인터페이스는 기본 IP 주소와 이그레스 소스 IP 주소의 두 가지 IP 주소로 구성됩니다.

이그레스 NAT 게이트웨이를 사용하도록 패킷이 선택된 경우, 패킷이 게이트웨이 노드에서 클러스터를 나가고, 네트워크 인터페이스에 구성된 이그레스 소스 IP 주소로 SNAT 변환됩니다.

다음 다이어그램은 패킷 흐름을 보여줍니다.

이그레스 NAT 게이트웨이가 있는 패킷 흐름

앞의 다이어그램은 포드에서 전송된 패킷의 흐름을 볼 수 있습니다.

  1. IP 주소가 192.168.1.1인 노드에서 IP 주소가 10.10.10.1인 포드가 아웃바운드 패킷을 생성합니다.

  2. 패킷이 이그레스 규칙과 일치하므로 패킷이 게이트웨이 노드로 전달됩니다.

  3. 게이트웨이 노드가 소스 IP 주소를 192.168.1.100으로 변경하고 패킷을 클러스터 외부로 전송합니다.

  4. 반환 트래픽이 대상 192.168.1.100이 있는 게이트웨이 노드로 다시 돌아갑니다.

  5. 게이트웨이 노드는 conntrack을 사용하여 대상 IP 주소를 10.10.10.1로 수정합니다.

  6. 패킷은 클러스터 내부 트래픽으로 취급되어 원래 노드로 전달되고 원래 포드로 돌아갑니다.

캐릭터

이 주제에서는 두 가지 캐릭터를 기준으로 설정합니다.

  • 클러스터 관리자. 이 캐릭터는 사용자 클러스터를 만들고 Anthos Network Gateway에서 사용할 유동 IP 주소를 지정합니다.

  • 개발자. 이 캐릭터는 사용자 클러스터에서 워크로드를 실행하고 이그레스 정책을 만듭니다.

이그레스 NAT 게이트웨이 사용 설정

이 섹션은 클러스터 관리자를 위해 작성되었습니다.

이그레스 NAT 게이트웨이를 구성하려면 사용자 클러스터 구성 파일에서 enableDataplaneV2advancedNetworking 필드를 사용하고 NetworkGatewayGroup 객체를 하나 이상 만듭니다.

클러스터 구성 파일에서 다음 필드를 true로 설정합니다.

enableDataplaneV2: true
...
advancedNetworking: true

사용자 클러스터를 만듭니다.

유동 IP 주소 지정

이 섹션은 클러스터 관리자를 위해 작성되었습니다.

이그레스 소스 주소로 사용할 IP 주소 집합을 선택하세요. 유동 IP 주소라고 하는 것은, Network Gateway Group은 이그레스 게이트웨이로 선택한 노드의 네트워크 인터페이스에 필요에 따라 IP 주소를 할당하기 때문입니다.

유동 IP 주소는 노드 IP 주소와 동일한 서브넷에 있어야 합니다.

유동 IP 주소 집합은 노드에 지정한 IP 주소 집합과 겹치지 않아야 합니다.

예를 들어 서브넷의 주소 범위가 192.168.1.0/24라고 가정해보세요. 그리고 노드에 192.168.1.1~192.168.1.99를 사용하도록 선택했습니다. 그러면 192.168.1.100~192.168.1.104를 유동 IP 주소로 사용할 수 있습니다.

NetworkGatewayGroup 객체 만들기

이 섹션은 클러스터 관리자를 위해 작성되었습니다.

다음은 NetworkGatewayGroup 객체의 매니페스트 예시입니다.

kind: NetworkGatewayGroup
apiVersion: networking.gke.io/v1
metadata:
  namespace: kube-system
  name: default
spec
  floatingIPs:
  - 192.168.1.100
  - 192.168.1.101
  - 192.168.1.102
  - 192.168.1.103
  - 192.168.1.104

floatingIPs 배열을 유동 IP 주소로 바꾸고 매니페스트를 my-ngg.yaml이라는 파일에 저장합니다.

NetworkGatewayGroup 객체를 만듭니다.

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG apply -f my-ngg.yaml

이그레스 NAT 정책 예시

이 섹션은 개발자를 위해 작성되었습니다.

다음은 EgressNatPolicy 커스텀 리소스의 예시입니다.

kind: EgressNATPolicy
apiVersion: networking.gke.io/v1
metadata:
  name: alice-paul
spec:
  sources:
  - namespaceSelector:
      matchLabels:
        user: alice
    podSelector:
      matchLabels:
        role: frontend
  - namespaceSelector:
      matchLabels:
        user: paul
    podSelector:
      matchLabels:
        role: frontend
  action: SNAT
  destinations:
  - cidr: 8.8.8.0/24
  gatewayRef:
    name: default
    namespace: kube-system

앞의 매니페스트에서 각 항목은 다음과 같습니다.

  • 다음 중 하나를 충족하는 포드는 이그레스 NAT 후보입니다.

    • 포드의 라벨이 role: frontend이고, 라벨이 user: alice인 네임스페이스에 포드가 있습니다.

    • 포드의 라벨이 role: frontend이고, 라벨이 user: paul인 네임스페이스에 포드가 있습니다.

  • 후보 pod에서 8.8.8.0/24 범위의 주소로 전송되는 트래픽이 이그레스 NAT 게이트웨이로 전송됩니다.

  • gatewayRef 섹션에 따라 이그레스 소스 IP 주소가 결정됩니다. EgressNATPolicy 커스텀 리소스는 gatewayRef.namegatewayRef.namespace 값을 사용해 NetworkGatewayGroup 객체를 찾습니다. 정책은 NetworkGatewayGroup의 유동 IP 주소 중 하나를 이그레스 트래픽의 소스 IP 주소로 사용합니다. 일치하는 NetworkGatewayGroup에 유동 IP 주소가 여러 개 있으면 정책은 floatingIPs 목록의 첫 번째 IP 주소를 사용하고 다른 IP 주소는 무시합니다. gatewayRef 섹션에 잘못된 필드가 있으면 EgressNATPolicy 객체를 적용할 수 없게 됩니다.

EgressNATPolicy 객체 만들기

자체 EgressNATPolicy 매니페스트를 만듭니다. metadata.name"my-policy"로 설정합니다. my-policy.yaml이라는 파일에 매니페스트를 저장합니다.

EgressNatPolicy 객체를 만듭니다.

kubectl apply --kubeconfig USER_CLUSTER_KUBECONFIG -f my-policy.yaml

이그레스 NAT 정책 정보 보기

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get egressnatpolicy my-policy --output yaml

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get networkgatewaygroup --namespace kube-system --output yaml

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG describe egressnatpolicy my-policy

작업 순서

이그레스 NAT 정책은 네트워크 정책 API와 호환됩니다. 네트워크 정책은 이그레스 NAT 정책 전에 평가됩니다. 네트워크 정책으로 패킷 삭제가 지시되면 이그레스 NAT 정책에 관계없이 패킷이 삭제됩니다.

여러 이그레스 정책

앞에서 설명한 대로 각 EgressNATPolicy는 gatewayRef.namegatewayRef.namespace와 일치하는 NetworkGatewayGroup의 floatingIPs 목록에서 첫 번째 IP 주소를 사용합니다. 여러 정책을 만들고 다른 IP 주소를 사용하려면 각각 여러 NetworkGatewayGroup 객체를 만들고 참조해야 합니다. 여러 정책을 만드는 경우 gatewayRef 객체는 각 정책에 대해 고유해야 합니다.

NetworkGatewayGroup 리소스에는 고유한 유동 IP 주소가 포함되어야 합니다. 여러 EgressNATPolicy 객체에서 같은 IP 주소를 사용하도록 구성하려면 두 객체 모두에 같은 gatewayRef.namegatewayRef.namespace를 사용합니다.

이그레스 정책 여러 개와 게이트웨이 객체 여러 개를 설정하려면 다음 안내를 따르세요.

  1. kube-system 네임스페이스에 게이트웨이 객체를 만들어 각 유동 IP 주소를 관리합니다. 일반적으로 올바른 이그레스 IP 주소가 할당되도록 하려면 각 이그레스 정책에 해당 게이트웨이 객체가 있어야 합니다.

    그런 다음 kubectl로 각 게이트웨이 객체를 확인하여 유동 IP 주소의 할당 상태를 가져옵니다.

    kind: NetworkGatewayGroup
    apiVersion: networking.gke.io/v1
    metadata:
      namespace: kube-system
      name: gateway1
    spec:
      floatingIPs:
      - 192.168.1.100
    status:
      ...
      floatingIPs:
        192.168.1.100: worker1
    ---
    kind: NetworkGatewayGroup
    apiVersion: networking.gke.io/v1
    metadata:
      namespace: kube-system
      name: gateway2
    spec:
      floatingIPs:
      - 192.168.1.101
    status:
      ...
      floatingIPs:
        192.168.1.101: worker2
    ---
    kind: NetworkGatewayGroup
    apiVersion: networking.gke.io/v1
    metadata:
      namespace: kube-system
      name: gateway3
    spec:
      floatingIPs:
      - 192.168.1.102
    status:
      ...
      floatingIPs:
        192.168.1.102: worker1
    
  2. 이전 단계에서 만든 gateway1과 같이 게이트웨이 객체를 참조하는 정책을 여러 개 만듭니다.

    kind: EgressNATPolicy
    apiVersion: networking.gke.io/v1
    metadata:
      name: egresspolicy1
    spec:
      ...
      gatewayRef:
        name: gateway1
        namespace: kube-system
    ---
    kind: EgressNATPolicy
    apiVersion: networking.gke.io/v1
    metadata:
      name: egresspolicy2
    spec:
      ...
      gatewayRef:
        name: gateway2
        namespace: kube-system
    ---
    kind: EgressNATPolicy
    apiVersion: networking.gke.io/v1
    metadata:
      name: egresspolicy3
    spec:
      ...
      gatewayRef:
        name: gateway3
        namespace: kube-system