포드에 대한 다중 네트워크 인터페이스 구성

이 문서에서는 포드에 대한 다중 네트워크 인터페이스인 멀티 NIC를 제공하도록 베어메탈용 GKE를 구성하는 방법을 설명합니다. 포드에 대한 멀티 NIC 기능은 데이터 영역 트래픽에서 제어 영역 트래픽을 분리하는 데 도움을 주고, 영역 간 격리를 생성합니다. 추가 네트워크 인터페이스는 또한 포드에 대한 멀티캐스트 기능을 사용 설정합니다. 포드에 대한 멀티 NIC는 사용자 클러스터, 하이브리드 클러스터 및 독립형 클러스터에서 지원됩니다. 관리자 유형의 클러스터에는 허용되지 않습니다.

네트워크 영역 격리는 광역 통신망의 소프트웨어 정의 네트워킹(SD-WAN), 클라우드 접근 보안 브로커(CASB), 차세대 방화벽(NG-FW)와 같은 네트워크 기능 가상화(NFV)를 사용하는 시스템에 중요합니다. 이러한 유형의 NFV에서는 컨테이너로 실행되면서 관리 및 데이터 영역을 구분하기 위해 여러 인터페이스에 대한 액세스가 필요합니다.

다중 네트워크 인터페이스 구성은 성능 이점을 제공할 수 있는 네트워크 인터페이스와 노드 풀 연결을 지원합니다. 클러스터에는 노드 유형이 혼합되어 있을 수 있습니다. 고성능 머신을 하나의 노드 풀로 그룹화할 때는 트래픽 흐름을 향상시키기 위해 노드 풀에 추가 인터페이스를 추가할 수 있습니다.

다중 네트워크 인터페이스 설정

일반적으로 포드에 대해 다중 네트워크 인터페이스를 설정하는 단계는 다음 3가지입니다.

  1. 클러스터 커스텀 리소스의 multipleNetworkInterfaces 필드로 클러스터에 대해 멀티 NIC를 사용 설정합니다.

  2. NetworkAttachmentDefinition 커스텀 리소스로 네트워크 인터페이스를 지정합니다.

  3. k8s.v1.cni.cncf.io/networks 주석을 사용하여 포드에 네트워크 인터페이스를 지정합니다.

네트워킹 요구사항에 가장 적합한 방식으로 멀티 NIC 기능을 구성하고 사용할 수 있도록 추가 정보가 제공됩니다.

멀티 NIC 사용 설정

multipleNetworkInterfaces 필드를 클러스터 커스텀 리소스의 clusterNetwork 섹션에 추가하고 true로 설정하여 포드에 대해 멀티 NIC를 사용 설정합니다.

  ...
  clusterNetwork:
    multipleNetworkInterfaces: true
    pods:
      cidrBlocks:
      - 192.168.0.0/16
    services:
      cidrBlocks:
      - 10.96.0.0/20
  ...

네트워크 인터페이스 지정

NetworkAttachmentDefinition 커스텀 리소스를 사용하여 추가 네트워크 인터페이스를 지정합니다. NetworkAttachmentDefinition 커스텀 리소스는 포드에 사용할 수 있는 네트워크에 해당합니다. 다음 예시와 같이 클러스터 구성 내에서 커스텀 리소스를 지정하거나 NetworkAttachmentDefinition 커스텀 리소스를 직접 만들 수 있습니다.

---
apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
  name: my-cluster
  namespace: cluster-my-cluster
spec:
    type: user
    clusterNetwork:
      multipleNetworkInterfaces: true
...
---
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: gke-network-1
  namespace: cluster-my-cluster
spec:
  config: '{
  "cniVersion":"0.3.0",
  "type": "ipvlan",
  "master": "enp2342",  # defines the node interface that this pod interface would
                         map to.
  "mode": "l2",
  "ipam": {
    "type": "whereabouts",
    "range": "172.120.0.0/24"
  }
}'
---
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: gke-network-2
  namespace: cluster-my-cluster
spec:
  config: '{
  "cniVersion":"0.3.0",
  "type": "macvlan",
  "mode": "bridge",
  "master": "vlan102",
  "ipam": {
    "type": "static",
    "addresses": [
      {
        "address": "10.10.0.1/24",
        "gateway": "10.10.0.254"
      }
    ],
    "routes": [
      { "dst": "192.168.0.0/16", "gw": "10.10.5.1" }
    ]
  }
}'

클러스터 구성 파일에서 NetworkAttachmentDefinition 커스텀 리소스를 지정하면 베어메탈용 GKE는 이 이름을 사용하여 클러스터 생성 후 NetworkAttachmentDefinition 커스텀 리소스를 제어합니다. 베어메탈용 GKE는 클러스터 네임스페이스 내의 이 커스텀 리소스를 정보 소스로 처리하고 이를 대상 클러스터의 default 네임스페이스로 조정합니다.

다음 다이어그램은 베어메탈용 GKE가 클러스터별 네임스페이스의 NetworkAttachmentDefinition 커스텀 리소스를 default 네임스페이스로 조정하는 방법을 보여줍니다.

NetworkAttachmentDefinition 조정

선택사항이지만 클러스터를 만드는 동안 NetworkAttachmentDefinition 커스텀 리소스를 지정하는 것이 좋습니다. 사용자 클러스터는 이후 관리자 클러스터에서 NetworkAttachmentDefinition 커스텀 리소스를 제어할 수 있기 때문에 클러스터를 만드는 동안 커스텀 리소스를 지정할 때 가장 효과적입니다.

클러스터를 만드는 동안 NetworkAttachmentDefinition 커스텀 리소스를 지정하지 않을 경우에는 기존 대상 클러스터에 직접 NetworkAttachmentDefinition 커스텀 리소스를 추가할 수 있습니다. 베어메탈용 GKE는 클러스터 네임스페이스에 정의된 NetworkAttachmentDefinition 커스텀 리소스를 조정합니다. 삭제 시에도 조정이 수행됩니다. NetworkAttachmentDefinition 커스텀 리소스를 클러스터 네임스페이스에서 삭제하면 베어메탈용 GKE가 대상 클러스터에서 커스텀 리소스를 삭제합니다.

포드에 네트워크 인터페이스 할당

k8s.v1.cni.cncf.io/networks 주석을 사용하여 하나 이상의 네트워크 인터페이스를 포드에 할당합니다. 각 네트워크 인터페이스는 네임스페이스와 NetworkAttachmentDefinition 커스텀 리소스 이름을 슬래시(/)로 구분하여 지정합니다.

---
apiVersion: v1
kind: Pod
metadata:
  name: samplepod
  annotations:
    k8s.v1.cni.cncf.io/networks: NAMESPACE/NAD_NAME
spec:
  containers:
  ...

다음을 바꿉니다.

  • NAMESPACE: 네임스페이스입니다. 기본 네임스페이스에 표준인 default를 사용합니다. 예외는 보안 문제를 참조하세요.
  • NAD_NAME: NetworkAttachmentDefinition 커스텀 리소스의 이름입니다.

쉼표로 구분된 목록을 사용하여 여러 네트워크 인터페이스를 지정합니다.

다음 예시에서는 두 개의 네트워크 인터페이스가 samplepod 포드에 할당됩니다. 네트워크 인터페이스는 대상 클러스터의 기본 네임스페이스에 있는 두 개의 NetworkAttachmentDefinition 커스텀 리소스(gke-network-1gke-network-2)의 이름으로 지정됩니다.

---
apiVersion: v1
kind: Pod
metadata:
  name: samplepod
  annotations:
    k8s.v1.cni.cncf.io/networks: default/gke-network-1,default/gke-network-2
spec:
  containers:
  ...

네트워크 인터페이스를 NodePool로 제한

k8s.v1.cni.cncf.io/nodeSelector 주석을 사용하여 NetworkAttachmentDefinition 커스텀 리소스가 유효한 노드 풀을 지정합니다. 베어메탈용 GKE는 이 커스텀 리소스를 참조하는 모든 포드를 특정 노드에 강제로 배포합니다. 다음 예시에서 베어메탈용 GKE는 gke-network-1 네트워크 인터페이스가 할당된 모든 포드를 multinicNP NodePool에 강제로 배포합니다. 이에 따라 베어메탈용 GKE는 NodePool에 baremetal.cluster.gke.io/node-pool 라벨을 지정합니다.

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  annotations:
    k8s.v1.cni.cncf.io/nodeSelector: baremetal.cluster.gke.io/node-pool=multinicNP
  name: gke-network-1
spec:
...

표준 라벨만 사용하도록 제한되지는 않습니다. 이러한 노드에 커스텀 라벨을 적용하여 클러스터 노드에서 자신의 고유한 커스텀 풀을 만들 수 있습니다. kubectl label nodes 명령어를 사용하여 커스텀 라벨을 적용합니다.

kubectl label nodes NODE_NAME LABEL_KEY=LABEL_VALUE

다음을 바꿉니다.

  • NODE_NAME: 라벨을 지정하려는 노드의 이름입니다.
  • LABEL_KEY: 라벨에 사용할 키입니다.
  • LABEL_VALUE: 라벨 이름입니다.

노드에 라벨이 지정된 후 해당 노드에 baremetal.cluster.gke.io/label-taint-no-sync 주석을 적용하여 베어메탈용 GKE가 라벨을 조정하지 못하도록 합니다. kubectl get nodes --show-labels 명령어를 사용하여 노드에 라벨이 지정되었는지 확인합니다.

보안 문제

NetworkAttachmentDefinition 커스텀 리소스는 네트워크에 대해 전체 액세스 권한을 제공합니다. 따라서 클러스터 관리자는 다른 사용자에게 만들기, 업데이트, 삭제 액세스 권한을 제공할 때 주의해야 합니다. 지정된 NetworkAttachmentDefinition 커스텀 리소스를 격리해야 할 경우 해당 네임스페이스의 포드만 액세스할 수 있는 기본값이 아닌 네임스페이스에 배치할 수 있습니다. 클러스터 구성 파일에 지정된 NetworkAttachmentDefinition 커스텀 리소스를 조정하도록 항상 기본 네임스페이스에 배치됩니다.

다음 다이어그램에서 default 네임스페이스의 포드는 privileged 네임스페이스의 네트워크 인터페이스에 액세스할 수 없습니다.

네임스페이스를 사용하여 네트워크 트래픽 격리

지원되는 CNI 플러그인

이 섹션에서는 베어메탈용 GKE에 대해 멀티 NIC 기능이 지원하는 CNI 플러그인의 목록을 확인할 수 있습니다. NetworkAttachmentDefinition 커스텀 리소스를 지정할 때는 다음 플러그인만 사용하세요.

인터페이스 생성:

  • ipvlan
  • macvlan
  • bridge
  • sriov

메타 플러그인:

  • portmap
  • sbr
  • tuning

IPAM 플러그인:

  • host-local
  • static
  • whereabouts

경로 구성

하나 이상의 NetworkAttachmentDefinition 커스텀 리소스가 지정된 포드에 다중 네트워크 인터페이스가 포함됩니다. 기본적으로 이 상황에서 라우팅 테이블은 지정된 NetworkAttachmentDefinition 커스텀 리소스에서만 로컬로 제공되는 추가 인터페이스로 확장됩니다. 기본 게이트웨이는 포드의 마스터/기본 인터페이스 eth0을 사용하도록 구성됩니다.

다음 CNI 플러그인을 사용하여 이 동작을 수정할 수 있습니다.

  • sbr
  • static
  • whereabouts

예를 들어 기본 게이트웨이, 기본 인터페이스를 통해 모든 트래픽이 이동하도록 해야 할 수 있습니다. 하지만 일부 트래픽은 기본값이 아닌 인터페이스 중 하나를 통해 전송됩니다. 두 인터페이스 유형 모두 동일한 엔드포인트를 사용할 수 있기 때문에 대상 IP(일반 라우팅)를 기반으로 트래픽을 구분하기 어려울 수 있습니다. 이 경우에는 소스 기반 라우팅(SBR)이 도움이 될 수 있습니다.

SBR 플러그인

sbr 플러그인은 애플리케이션이 라우팅 결정을 제어할 수 있게 해줍니다. 애플리케이션은 설정된 연결의 소스 IP 주소로 사용되는 항목을 제어합니다. 애플리케이션이 해당 소스 IP에 대해 NetworkAttachmentDefinition 커스텀 리소스의 IP 주소를 사용하도록 선택하면 추가 라우팅 테이블 sbr의 패킷 배치가 설정됩니다. sbr 라우팅 테이블은 NetworkAttachmentDefinition 커스텀 리소스의 인터페이스를 기본 게이트웨이로 설정합니다. 테이블 내의 기본 게이트웨이 IP는 whereabouts 또는 static 플러그인 내의 gateway 필드로 제어됩니다. sbr 플러그인을 연결된 플러그인으로 제공합니다. 사용 정보를 포함하여 sbr 플러그인에 대한 자세한 내용은 소스 기반 라우팅 플러그인을 참조하세요.

다음 예시에서는 whereabouts에 설정된 "gateway":"21.0.111.254"ipvlan 다음에 연결된 플러그인으로 설정된 sbr을 보여줍니다.

# ip route
default via 192.168.0.64 dev eth0  mtu 1500
192.168.0.64 dev eth0 scope link
# ip route list table 100
default via 21.0.111.254 dev net1
21.0.104.0/21 dev net1 proto kernel scope link src 21.0.111.1

정적 및 whereabouts 플러그인

whereabouts 플러그인은 기본적으로 static 플러그인의 확장이며, 두 플러그인 모두 라우팅 구성을 공유합니다. 구성 예시는 고정 IP 주소 관리 플러그인을 참조하세요. 포드의 라우팅 테이블에 추가할 게이트웨이 및 경로를 정의할 수 있습니다. 하지만 이 방법으로는 포드의 기본 게이트웨이를 수정할 수 없습니다.

다음 예시에서는 NetworkAttachmentDefinition 커스텀 리소스에서 "routes": [{ "dst": "172.31.0.0/16" }] 추가를 보여줍니다.

# ip route
default via 192.168.0.64 dev eth0  mtu 1500
172.31.0.0/16 via 21.0.111.254 dev net1
21.0.104.0/21 dev net1 proto kernel scope link src 21.0.111.1
192.168.0.64 dev eth0 scope link

구성 예

이 섹션에서는 멀티 NIC 기능으로 지원되는 몇 가지 공통적인 네트워크 구성을 보여줍니다.

다중 포드에 사용되는 단일 네트워크 연결

다중 포드에 사용되는 단일 네트워크 연결

단일 포드에 사용되는 다중 네트워크 연결

단일 포드에 사용되는 다중 네트워크 연결

단일 포드에 사용되는 동일한 인터페이스를 가리키는 다중 네트워크 연결

단일 포드에 사용되는 동일한 인터페이스를 가리키는 다중 네트워크 연결

단일 포드에 여러 번 사용되는 동일한 네트워크 연결

단일 포드에 여러 번 사용되는 동일한 네트워크 연결

문제 해결

추가 네트워크 인터페이스가 잘못 구성되어 있으면 지정된 포드가 시작되지 않습니다. 이 섹션에서는 멀티 NIC 기능으로 문제 해결 정보를 찾는 방법을 보여줍니다.

포드 이벤트 확인

Multus는 Kubernetes 포드 이벤트를 통해 오류를 보고합니다. 다음 kubectl describe 명령어를 사용하여 지정된 포드의 이벤트를 확인합니다.

kubectl describe pod POD_NAME

로그 확인

각 노드에 대해 다음 위치에서 Whereabouts 및 Multus 로그를 찾을 수 있습니다.

  • /var/log/whereabouts.log
  • /var/log/multus.log

포드 인터페이스 검토

kubectl exec 명령어를 사용하여 포드 인터페이스를 확인합니다. NetworkAttachmentDefinition 커스텀 리소스가 성공적으로 적용되면 포드 인터페이스는 다음 출력과 같이 표시됩니다.

$ kubectl exec samplepod-5c6df74f66-5jgxs -- ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: net1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default
    link/ether 00:50:56:82:3e:f0 brd ff:ff:ff:ff:ff:ff
    inet 21.0.103.112/21 scope global net1
       valid_lft forever preferred_lft forever
38: eth0@if39: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 36:23:79:a9:26:b3 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.2.191/32 scope global eth0
       valid_lft forever preferred_lft forever

포드 상태 가져오기

kubectl get을 사용하여 지정된 포드에 대해 네트워크 상태를 검색합니다.

kubectl get pods POD_NAME -oyaml

다음은 다중 네트워크의 포드 상태를 보여주는 샘플 출력입니다.

apiVersion: v1
kind: Pod
metadata:
  annotations:
    k8s.v1.cni.cncf.io/network-status: |-
      [{
          "name": "",
          "interface": "eth0",
          "ips": [
              "192.168.1.88"
          ],
          "mac": "36:0e:29:e7:42:ad",
          "default": true,
          "dns": {}
      },{
          "name": "default/gke-network-1",
          "interface": "net1",
          "ips": [
              "21.0.111.1"
          ],
          "mac": "00:50:56:82:a7:ab",
          "dns": {}
      }]
    k8s.v1.cni.cncf.io/networks: gke-network-1