24.17. 리디렉션 모드에서 송신 라우터 Pod 배포

클러스터 관리자는 예약된 소스 IP 주소에서 지정된 대상 IP 주소로 트래픽을 리디렉션하도록 송신 라우터 포드를 배포할 수 있습니다.

송신 라우터 구현에서는 송신 라우터 CNI(Container Network Interface) 플러그인을 사용합니다.

24.17.1. 송신 라우터 사용자 정의 리소스

송신 라우터 사용자 정의 리소스에서 송신 라우터 Pod에 대한 구성을 정의합니다. 다음 YAML은 리디렉션 모드에서 송신 라우터 구성을 위한 필드를 설명합니다.

apiVersion: network.operator.openshift.io/v1
kind: EgressRouter
metadata:
  name: <egress_router_name>
  namespace: <namespace>  <.>
spec:
  addresses: [  <.>
    {
      ip: "<egress_router>",  <.>
      gateway: "<egress_gateway>"  <.>
    }
  ]
  mode: Redirect
  redirect: {
    redirectRules: [  <.>
      {
        destinationIP: "<egress_destination>",
        port: <egress_router_port>,
        targetPort: <target_port>,  <.>
        protocol: <network_protocol>  <.>
      },
      ...
    ],
    fallbackIP: "<egress_destination>" <.>
  }

<.> 선택 사항: namespace 필드는 송신 라우터를 생성할 네임스페이스를 지정합니다. 파일 또는 명령줄에 값을 지정하지 않으면 default 네임스페이스가 사용됩니다.

<.> address 필드는 보조 네트워크 인터페이스에서 구성할 IP 주소를 지정합니다.

<.> ip 필드는 노드가 송신 라우터 Pod와 함께 사용할 실제 네트워크에서 예약된 소스 IP 주소와 넷마스크를 지정합니다. CIDR 표기법을 사용하여 IP 주소와 넷마스크를 지정합니다.

<.> gateway 필드는 네트워크 게이트웨이의 IP 주소를 지정합니다.

<.> 선택 사항: redirectRules 필드는 송신 대상 IP 주소, 송신 라우터 포트 및 프로토콜의 조합을 지정합니다. 지정된 포트 및 프로토콜의 출력 라우터에 대한 수신 연결은 대상 IP 주소로 라우팅됩니다.

<.> 선택 사항: targetPort 필드는 대상 IP 주소에 네트워크 포트를 지정합니다. 이 필드를 지정하지 않으면 트래픽이 도달한 동일한 네트워크 포트로 라우팅됩니다.

<.> protocol 필드는 TCP, UDP 또는 SCTP를 지원합니다.

<.> 선택 사항: fallbackIP 필드는 대상 IP 주소를 지정합니다. 리디렉션 규칙을 지정하지 않으면 송신 라우터에서 모든 트래픽을 이 폴백 IP 주소로 보냅니다. 리디렉션 규칙을 지정하면 규칙에 정의되지 않은 네트워크 포트에 대한 모든 연결이 송신 라우터에서 이 대체 IP 주소로 전송됩니다. 이 필드를 지정하지 않으면 송신 라우터는 규칙에 정의되지 않은 네트워크 포트에 대한 연결을 거부합니다.

송신 라우터 사양의 예

apiVersion: network.operator.openshift.io/v1
kind: EgressRouter
metadata:
  name: egress-router-redirect
spec:
  networkInterface: {
    macvlan: {
      mode: "Bridge"
    }
  }
  addresses: [
    {
      ip: "192.168.12.99/24",
      gateway: "192.168.12.1"
    }
  ]
  mode: Redirect
  redirect: {
    redirectRules: [
      {
        destinationIP: "10.0.0.99",
        port: 80,
        protocol: UDP
      },
      {
        destinationIP: "203.0.113.26",
        port: 8080,
        targetPort: 80,
        protocol: TCP
      },
      {
        destinationIP: "203.0.113.27",
        port: 8443,
        targetPort: 443,
        protocol: TCP
      }
    ]
  }

24.17.2. 리디렉션 모드에서 송신 라우터 배포

송신 라우터 pod를 배포하여 자체 예약된 소스 IP 주소에서 하나 이상의 대상 IP 주소로 트래픽을 리디렉션할 수 있습니다.

송신 라우터 pod를 추가한 후 예약된 소스 IP 주소를 사용해야 하는 클라이언트 pod는 대상 IP에 직접 연결하는 대신 송신 라우터에 연결하도록 수정해야 합니다.

사전 요구 사항

  • OpenShift CLI(oc)를 설치합니다.
  • cluster-admin 권한이 있는 사용자로 로그인합니다.

프로세스

  1. 송신 라우터 정의를 생성합니다.
  2. 다른 포드에서 송신 라우터 pod의 IP 주소를 찾을 수 있도록 하려면 다음 예제와 같이 송신 라우터를 사용하는 서비스를 만듭니다.

    apiVersion: v1
    kind: Service
    metadata:
      name: egress-1
    spec:
      ports:
      - name: web-app
        protocol: TCP
        port: 8080
      type: ClusterIP
      selector:
        app: egress-router-cni <.>

    <.> 송신 라우터의 레이블을 지정합니다. 표시된 값은 Cluster Network Operator에서 추가하며 구성 불가능합니다.

    서비스를 생성한 후 포드가 서비스에 연결할 수 있습니다. 송신 라우터 pod는 트래픽을 대상 IP 주소의 해당 포트로 리디렉션합니다. 이 연결은 예약된 소스 IP 주소에서 시작됩니다.

검증

Cluster Network Operator가 송신 라우터를 시작했는지 확인하려면 다음 절차를 완료합니다.

  1. 송신 라우터에 대해 Operator가 생성한 네트워크 연결 정의를 확인합니다.

    $ oc get network-attachment-definition egress-router-cni-nad

    네트워크 연결 정의의 이름은 구성할 수 없습니다.

    출력 예

    NAME                    AGE
    egress-router-cni-nad   18m

  2. 송신 라우터 pod에 대한 배포를 확인합니다.

    $ oc get deployment egress-router-cni-deployment

    배포 이름은 구성할 수 없습니다.

    출력 예

    NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
    egress-router-cni-deployment   1/1     1            1           18m

  3. 송신 라우터 pod의 상태를 확인합니다.

    $ oc get pods -l app=egress-router-cni

    출력 예

    NAME                                            READY   STATUS    RESTARTS   AGE
    egress-router-cni-deployment-575465c75c-qkq6m   1/1     Running   0          18m

  4. 송신 라우터 pod의 로그 및 라우팅 테이블을 확인합니다.
  1. 송신 라우터 pod에 대한 노드 이름을 가져옵니다.

    $ POD_NODENAME=$(oc get pod -l app=egress-router-cni -o jsonpath="{.items[0].spec.nodeName}")
  2. 대상 노드에서 디버그 세션으로 들어갑니다. 이 단계는 < node_name>-debug라는 디버그 Pod를 인스턴스화합니다.

    $ oc debug node/$POD_NODENAME
  3. 디버그 쉘 내에서 /host 를 root 디렉터리로 설정합니다. 디버그 Pod는 Pod 내의 /host 에 호스트의 루트 파일 시스템을 마운트합니다. 루트 디렉토리를 /host 로 변경하면 호스트의 실행 경로에서 바이너리를 실행할 수 있습니다.

    # chroot /host
  4. chroot 환경 콘솔에서 송신 라우터 로그를 표시합니다.

    # cat /tmp/egress-router-log

    출력 예

    2021-04-26T12:27:20Z [debug] Called CNI ADD
    2021-04-26T12:27:20Z [debug] Gateway: 192.168.12.1
    2021-04-26T12:27:20Z [debug] IP Source Addresses: [192.168.12.99/24]
    2021-04-26T12:27:20Z [debug] IP Destinations: [80 UDP 10.0.0.99/30 8080 TCP 203.0.113.26/30 80 8443 TCP 203.0.113.27/30 443]
    2021-04-26T12:27:20Z [debug] Created macvlan interface
    2021-04-26T12:27:20Z [debug] Renamed macvlan to "net1"
    2021-04-26T12:27:20Z [debug] Adding route to gateway 192.168.12.1 on macvlan interface
    2021-04-26T12:27:20Z [debug] deleted default route {Ifindex: 3 Dst: <nil> Src: <nil> Gw: 10.128.10.1 Flags: [] Table: 254}
    2021-04-26T12:27:20Z [debug] Added new default route with gateway 192.168.12.1
    2021-04-26T12:27:20Z [debug] Added iptables rule: iptables -t nat PREROUTING -i eth0 -p UDP --dport 80 -j DNAT --to-destination 10.0.0.99
    2021-04-26T12:27:20Z [debug] Added iptables rule: iptables -t nat PREROUTING -i eth0 -p TCP --dport 8080 -j DNAT --to-destination 203.0.113.26:80
    2021-04-26T12:27:20Z [debug] Added iptables rule: iptables -t nat PREROUTING -i eth0 -p TCP --dport 8443 -j DNAT --to-destination 203.0.113.27:443
    2021-04-26T12:27:20Z [debug] Added iptables rule: iptables -t nat -o net1 -j SNAT --to-source 192.168.12.99

    로깅 파일 위치 및 로깅 수준은 이 프로세스에 설명된 대로 EgressRouter 오브젝트를 생성하여 송신 라우터를 시작할 때 구성 불가능합니다.

  5. chroot 환경 콘솔에서 컨테이너 ID를 가져옵니다.

    # crictl ps --name egress-router-cni-pod | awk '{print $1}'

    출력 예

    CONTAINER
    bac9fae69ddb6

  6. 컨테이너의 프로세스 ID를 확인합니다. 이 예에서 컨테이너 ID는 bac9fae69ddb6 입니다.

    # crictl inspect -o yaml bac9fae69ddb6 | grep 'pid:' | awk '{print $2}'

    출력 예

    68857

  7. 컨테이너의 네트워크 네임스페이스를 입력합니다.

    # nsenter -n -t 68857
  8. 라우팅 테이블을 표시합니다.

    # ip route

    다음 예제 출력에서 net1 네트워크 인터페이스가 기본 경로입니다. 클러스터 네트워크의 트래픽은 eth0 네트워크 인터페이스를 사용합니다. 192.168.12.0/24 네트워크의 트래픽은 net1 네트워크 인터페이스를 사용하며 예약된 소스 IP 주소 192.168.12.99 에서 시작됩니다. Pod는 다른 모든 트래픽을 IP 주소 192.168.12.1 의 게이트웨이로 라우팅합니다. 서비스 네트워크의 라우팅이 표시되지 않습니다.

    출력 예

    default via 192.168.12.1 dev net1
    10.128.10.0/23 dev eth0 proto kernel scope link src 10.128.10.18
    192.168.12.0/24 dev net1 proto kernel scope link src 192.168.12.99
    192.168.12.1 dev net1