서비스 조정 설정


이 페이지에서는 포드에 서비스 조정을 설정하는 방법을 보여줍니다.

서비스 조정의 작동 방식을 이해하려면 서비스 조정 작동 방식을 참조하세요.

요구사항

  • GKE 버전 1.30 이상

제한사항

  • ServiceFunctionChain에는 최대 1개의 서비스 함수가 포함될 수 있습니다.
  • 최대 100개 노드와 10개의 ServiceFunctionChainTrafficSelector 쌍을 사용하는 것이 좋습니다.
  • GKE 서비스 조정은 Container-Optimized OS 노드 이미지를 실행하는 노드에서만 사용할 수 있습니다.
  • GKE 서비스 조정은 이그레스 및 대상 IP 주소만 지원합니다.
  • 서비스 조정은 프리픽스 길이가 동일한 여러 트래픽 선택기가 동일한 주제에 적용될 때 발생하는 충돌을 처리하지 않습니다. 충돌을 피하려면 겹치지 않는 IP 주소 범위와 명확하게 정의된 선택 기준을 사용하여 트래픽 선택기를 사전에 설계합니다.

서비스 조정 구현

GKE 서비스 조정을 사용하면 클러스터 내에서 네트워크 트래픽의 흐름을 맞춤설정하고 제어할 수 있습니다. 이 섹션에서는 웹 게이트웨이 예시를 사용하여 서비스 조정을 구현하는 방법을 보여줍니다.

최종 사용자 클라이언트 기기에서 인터넷으로의 트래픽을 보호하는 웹 게이트웨이를 만들려는 사용 사례를 생각해 보세요. VPN 종료자는 보안 터널을 사용해서 관리형 게이트웨이로 트래픽을 유도합니다. 최종 사용자 트래픽은 방화벽으로 리디렉션된 다음 프록시로 리디렉션됩니다. 프록시는 트래픽에 소스 네트워크 주소 변환(SNAT)을 수행하여 원래 소스 주소를 마스킹한 후 인터넷에 전송합니다.

GKE 서비스 조정을 구현하려면 다음 안내를 따르세요.

  1. MTU가 8896인 VPC를 만듭니다.
  2. GKE 클러스터를 만듭니다.
  3. 서비스 함수 포드 및 서비스를 만듭니다.
  4. ServiceFunctionChain을 만듭니다.
  5. ServiceFunctionChain을 참조하는 TrafficSelector 리소스를 만듭니다.

시작하기 전에

시작하기 전에 다음 태스크를 수행했는지 확인합니다.

  • Google Kubernetes Engine API를 사용 설정합니다.
  • Google Kubernetes Engine API 사용 설정
  • 이 태스크에 Google Cloud CLI를 사용하려면 gcloud CLI를 설치한 후 초기화합니다. 이전에 gcloud CLI를 설치한 경우 gcloud components update를 실행하여 최신 버전을 가져옵니다.

가격 책정

다음 Network Function Optimizer(NFO) 기능은 GKE Enterprise에서 사용 설정된 프로젝트에 포함된 클러스터에서만 지원됩니다.

Google Kubernetes Engine(GKE) Enterprise 버전 사용 설정 시 적용되는 요금을 알아보려면 GKE Enterprise 가격 책정을 참조하세요.

VPC 준비

VPC를 준비합니다. 서비스 조정은 캡슐화를 사용하여 트래픽을 적절한 서비스 함수로 리디렉션합니다. 캡슐화에는 각 패킷에 추가 헤더가 추가되므로 패킷 크기가 증가합니다. 서비스 조정에는 VPC에서 특별한 구성이 필요하지 않습니다. VPC를 준비할 때는 MTU 크기를 결정할 때 캡슐화 오버헤드를 고려하는 것이 좋습니다. 자세한 내용은 지정된 MTU로 VPC 네트워크를 참조하세요.

다음 명령어는 VPC에서 mtu 크기를 설정합니다.

gcloud compute networks create VPC_NETWORK_NAME --mtu=8896

VPC_NETWORK_NAME을 서브넷이 포함된 VPC 네트워크의 이름으로 바꿉니다.

GKE 클러스터 만들기

GKE에서 서비스 조정을 구현하는 데 필요한 고급 네트워크 라우팅 및 IP 주소 관리 기능을 사용 설정하려면 다음과 같이 GKE Dataplane V2가 사용 설정된 GKE 클러스터를 create.

gcloud container clusters create CLUSTER_NAME \
    --network VPC_NAME \
    --release-channel RELEASE_CHANNEL \
    --cluster-version CLUSTER_VERSION \
    --enable-dataplane-v2 \
    --enable-ip-alias

다음을 바꿉니다.

  • CLUSTER_NAME: 클러스터의 이름입니다.
  • VPC_NAME: 클러스터를 연결할 VPC의 이름입니다.
  • RELEASE_CHANNEL: 출시 채널의 이름
  • VERSION: GKE 버전이며 1.30 이상이어야 합니다. --release-channel 플래그를 사용하여 출시 채널을 선택할 수도 있습니다. 출시 채널은 기본 버전이 1.30 이상이어야 합니다.

ServiceFunction 포드 만들기

서비스 체인을 설정하려면 클러스터 내에 VPN 종결자 포드 및 필요한 서비스 함수 포드를 배포합니다. 포드는 네트워크 기능을 수행하는 컨테이너화된 애플리케이션을 캡슐화합니다.

VPN 종결자 포드는 종종 체인에서 첫 번째 서비스 함수로, VPN을 통해 클러스터에 들어오는 트래픽을 종료합니다. 그런 다음 최종 대상에 도달하기 전에 추가 처리를 위해 방화벽 및 부하 분산과 같은 다른 서비스 함수에 지시합니다.

다음 예시 구성 파일에서는 클러스터 내에서 네트워크 트래픽 관리에 필요한 다음 세 가지 구성요소를 정의합니다.

  • VPN 포드: 클러스터 내에 가상 사설망(VPN) 엔드포인트를 설정하여 클러스터와 외부 네트워크 간에 안전하고 암호화된 통신을 사용 설정합니다.
  • 방화벽 배포: 보안 및 부하 분산을 제공하는 방화벽 포드의 여러 복제본을 배포합니다.
  • 프록시 DaemonSet: 클러스터의 모든 노드에 프록시 포드를 배포하여 네트워크 트래픽이 방화벽과 같은 다른 서비스로 전달되기 전에 로컬에서 처리될 수 있도록 합니다.

다음 샘플 매니페스트를 service_function.yaml로 저장합니다.

apiVersion: v1
kind: Pod
  name: vpn
  namespace: vpn
  labels:
    app: vpn
spec:
  containers:
  -   name: vpn
    image: openvpn
    ports:
    -   containerPort: 51820
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: firewall
  namespace: firewall
spec:
  replicas: 3
  selector:
    matchLabels:
      app: firewall
  template:
    metadata:
      labels:
        app: firewall
    spec:
      containers:
      -   name: firewall
        image: firewall
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: proxy
  namespace: proxy
spec:
  selector:
    matchLabels:
      app: proxy
  template:
    metadata:
      labels:
        app: proxy
    spec:
      containers:
      -   name: proxy
        image: proxy

매니페스트를 적용합니다.

kubectl apply -f service_function.yaml

ServiceFunctionChains 만들기

트래픽이 통과하는 네트워크 함수의 시퀀스를 정의하려면 방화벽, 프록시, 부하 분산기와 같은 각 함수가 특정 작업을 수행한 후 다음으로 트래픽을 전달하는 파이프라인을 만듭니다.

다음 샘플 매니페스트를 ServiceFunctionChain.yaml로 저장합니다.

apiVersion: networking.gke.io/v1
kind: ServiceFunctionChain
metadata:
  name: firewall
spec:
  sessionAffinity:
    clientIpNoDestination:
      timeoutSeconds: 3600 # 1hr
  serviceFunctions:
  -   name: firewall
    namespace: firewall
    podSelector:
      matchLabels:
        app: firewall
---
apiVersion: networking.gke.io/v1
kind: ServiceFunctionChain
metadata:
  name: proxy
spec:
  sessionAffinity:
    clientIpNoDestination: {}
  serviceFunctions:
  -   name: proxy
    namespace: proxy
    podSelector:
      matchLabels:
        app: proxy

매니페스트를 적용합니다.

kubectl apply -f ServiceFunctionChain.yaml

서비스 함수는 serviceFunctions 필드를 사용하여 ServiceFunctionChain 내에서 인라인으로 정의됩니다. 서비스 함수는 엔드포인트 선택기입니다.

TrafficSelector 리소스 만들기

서비스 조정을 위해 선택된 트래픽과 그 위치를 정의하려면 선택한 트래픽에 적용할 ServiceFunctionChains를 참조하는 TrafficSelector 리소스를 만듭니다.

다음 샘플 매니페스트를 TrafficSelector.yaml로 저장합니다.

apiVersion: networking.gke.io/v1
kind: TrafficSelector
metadata:
  name: vpn-to-firewall
spec:
  serviceFunctionChain: firewall
  subject:
    pods:
      namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: vpn
      podSelector:
        matchLabels:
          app: vpn
  egress:
    to:
      ipBlock:
        cidr: 0.0.0.0/0
    ports:
    -   allPorts:
        protocol: UDP
    -   allPorts:
        protocol: TCP
---
apiVersion: networking.gke.io/v1
kind: TrafficSelector
metadata:
  name: firewall-to-proxy
spec:
  serviceFunctionChain: proxy
  subject:
    pods:
      namespaceSelector:
        kubernetes.io/metadata.name: firewall
      podSelector:
        app: firewall
  egress:
    to:
      ipBlock:
        cidr: 0.0.0.0/0
    ports:
    -   allPorts:
        protocol: UDP
    -   allPorts:
        protocol: TCP

매니페스트를 적용합니다.

kubectl apply -f TrafficSelector.yaml

서비스 조정 문제 해결

이 섹션에서는 GKE 서비스 조정과 관련된 문제를 해결하는 방법을 보여줍니다.

네트워크 트래픽이 전달되지 않음

다음 작업을 수행하여 문제를 디버깅할 수 있습니다.

1단계: servicePathIdServiceFunctionChain에 설정되어 있는지 확인하기

servicePathIdServiceFunctionChain에 설정되어 있는지 확인합니다. 모든 ServiceFunctionChain 객체에는 다음 예시와 같이 고유한 servicePathId가 할당됩니다.

apiVersion: networking.gke.io/v1
kind: ServiceFunctionChain
metadata:
  name: firewall
spec:
  serviceFunctions:
  - name: firewall
    namespace: firewall
    podSelector:
      matchLabels:
        app: firewal
status:
  servicePathId: 1

2단계: 서비스 함수별로 Kubernetes 서비스가 생성되었는지 확인

ClusterIP 서비스는 각 서비스 함수에 대해 자동으로 생성됩니다. kubectl을 사용하여 서비스 목록을 확인할 수 있습니다.

kubectl get svc -A -l networking.gke.io/managed-by=service-steering-controller.gke.io

3단계: 각 서비스 함수에 대해 서비스 IP 주소를 저장하기 위해 각 노드에 bpf 맵 항목이 생성되었는지 확인

각 서비스 함수에 대해 서비스 IP 주소를 저장하기 위해 각 노드에 bpf 맵 항목이 생성됩니다.

anetd 포드의 이름을 가져옵니다.

kubectl get pods -n kube-system -o wide -l k8s-app=cilium

anetd와 비슷한 포드 이름을 기록합니다.

다음 명령어를 실행합니다.

kubectl -n kube-system exec -it ANETD-POD-NAME -- cilium bpf sfcpath list

ANETD-POD-NAMEanetd 포드의 이름으로 바꿉니다.

출력은 다음과 비슷합니다.

PATH     SERVICE FUNCTION ADDRESS
(1, 1)   10.4.10.124

4단계: bpf 맵 항목이 sfcselect 맵에 생성되었는지 확인

노드에서 TrafficSelector에 의해 선택된 포드가 있는 경우 bpf 맵 항목이 sfcselect 맵에 생성됩니다. 다음 예시는 엔드포인트(포드) 3783의 모든 포트에서 대상 IP 주소 10.0.2.12로의 TCP/UDP 트래픽이 ServiceFunctionChain으로 조정되는 것을 보여줍니다.

다음 명령어를 실행합니다.

kubectl -n kube-system exec -it ANETD-POD-NAME -- cilium bpf sfcselect list

ANETD-POD-NAME을 클러스터에 있는 anetd 포드의 실제 이름으로 바꿉니다.

출력은 다음과 비슷합니다.

SELECTOR                            PATH
3783, egress, 0/TCP, 10.0.2.12/32   /32 (1, 1)
3783, egress, 0/UDP, 10.0.2.12/32   /32 (1, 1)

5단계: 포트 7081에서 tcpdump를 사용하여 네트워크 트래픽 캡처 및 분석하기

서비스 조정은 UDP 포트 7081에서 Geneve 캡슐화를 수행합니다. 관련 노드에서 tcpdump를 사용하여 트래픽 흐름을 분석하고 문제가 발생할 수 있는 위치를 정확히 파악할 수 있습니다.

다음 단계