내부 애플리케이션 부하 분산기에 대한 인그레스 구성


이 페이지에서는 Google Kubernetes Engine(GKE)에서 내부 애플리케이션 부하 분산기를 위해 인그레스를 설정하고 사용하는 방법을 설명합니다. 인그레스는 GKE 인그레스 컨트롤러를 통해 내부 부하 분산을 위한 기본 지원을 제공합니다.

내부 부하 분산기용 인그레스에서 지원되는 기능에 대한 자세한 내용은 인그레스 기능을 참조하세요. 또한 내부 애플리케이션 부하 분산기용 인그레스에서 내부 애플리케이션 부하 분산기용 인그레스 작동 방식을 자세히 알아볼 수 있습니다.

시작하기 전에

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

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

요구사항

내부 애플리케이션 부하 분산기의 인그레스에는 다음 요구사항이 있습니다.

  • 클러스터는 1.16.5-gke.10 이상의 GKE 버전을 사용해야 합니다.
  • 클러스터는 VPC 기반이어야 합니다.
  • 클러스터에 HttpLoadBalancing 부가기능이 사용 설정되어 있어야 합니다. 이 부가기능은 기본적으로 사용 설정되어 있습니다. 중지하면 안 됩니다.
  • 네트워크 엔드포인트 그룹(NEG)을 서비스의 백엔드로 사용해야 합니다.

내부 애플리케이션 부하 분산기용 인그레스 배포

다음 연습에서는 내부 애플리케이션 부하 분산기에 인그레스를 배포하는 방법을 보여줍니다.

  1. 개발 환경 준비
  2. 클러스터 만들기
  3. 애플리케이션 배포
  4. 서비스 배포
  5. 인그레스 배포
  6. 배포 검사
  7. 인그레스 리소스 삭제

개발 환경 준비

Kubernetes Ingress API를 통해 부하 분산기 리소스를 배포하려면 먼저 부하 분산기 프록시를 지정된 리전에 배포할 수 있도록 네트워킹 환경을 준비해야 합니다.

프록시 전용 서브넷을 만듭니다.

gcloud compute networks subnets create proxy-only-subnet \
    --purpose=REGIONAL_MANAGED_PROXY \
    --role=ACTIVE \
    --region=COMPUTE_REGION \
    --network=NETWORK_NAME \
    --range=10.129.0.0/23

다음을 바꿉니다.

  • COMPUTE_REGION: Compute Engine 리전입니다.
  • NETWORK_NAME: 서브넷의 네트워크 이름입니다.

자세한 내용은 프록시 전용 서브넷 구성을 참조하세요.

방화벽 규칙 만들기

인그레스 컨트롤러는 프록시-서브넷에서 부하 분산기 프록시의 연결을 허용하는 방화벽 규칙을 만들지 않습니다. 이 방화벽 규칙을 수동으로 만들어야 합니다. 하지만 인그레스 컨트롤러는 Google Cloud 상태 점검에 인그레스를 허용하는 방화벽 규칙을 만듭니다.

프록시 전용 서브넷의 부하 분산기 프록시에서 포드 리슨 포트로의 연결을 허용하는 방화벽 규칙을 만듭니다.

gcloud compute firewall-rules create allow-proxy-connection \
    --allow=TCP:CONTAINER_PORT \
    --source-ranges=10.129.0.0/23 \
    --network=NETWORK_NAME

CONTAINER_PORT를 포드가 리슨 중인 포트 값(예: 9376)으로 바꿉니다.

클러스터 만들기

이 섹션에서는 내부 애플리케이션 부하 분산기를 위한 인그레스에 사용할 수 있는 VPC 기반 클러스터를 만듭니다. Google Cloud CLI 또는 Google Cloud 콘솔을 사용하여 이 클러스터를 만들 수 있습니다.

gcloud

프록시 전용 서브넷과 동일한 네트워크에 클러스터를 만듭니다.

gcloud container clusters create-auto CLUSTER_NAME \
    --location=COMPUTE_LOCATION \
    --network=NETWORK_NAME

다음을 바꿉니다.

  • CLUSTER_NAME: 클러스터 이름입니다.
  • COMPUTE_LOCATION: 클러스터의 Compute Engine 위치입니다. 이전 섹션에서 만든 프록시-서브넷과 같은 위치를 사용해야 합니다.

Console

  1. Google Cloud 콘솔에서 Google Kubernetes Engine 페이지로 이동합니다.

    Google Kubernetes Engine으로 이동

  2. 만들기를 클릭합니다.

  3. Autopilot 섹션에서 구성을 클릭합니다.

  4. 클러스터 기본사항 섹션에서 다음을 완료합니다.

    1. 클러스터의 이름을 입력합니다.
    2. 위치 유형에서 클러스터의 Compute Engine 리전을 선택합니다. 이전 섹션에서 만든 프록시-서브넷과 같은 리전을 사용해야 합니다.
  5. 탐색창에서 네트워킹을 클릭합니다.

  6. 네트워크 목록에서 클러스터를 만들 네트워크를 선택합니다. 이 네트워크는 프록시-서브넷과 동일한 VPC 네트워크에 있어야 합니다.

  7. 노드 서브넷 목록에서 앞에서 만든 프록시-서브넷을 선택합니다.

  8. 만들기를 클릭합니다.

웹 애플리케이션 배포

이 섹션에서는 배포를 만듭니다.

배포를 만들려면 다음 안내를 따르세요.

  1. 다음 샘플 매니페스트를 web-deployment.yaml로 저장합니다.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: hostname
      name: hostname-server
    spec:
      selector:
        matchLabels:
          app: hostname
      minReadySeconds: 60
      replicas: 3
      template:
        metadata:
          labels:
            app: hostname
        spec:
          containers:
          - image: registry.k8s.io/serve_hostname:v1.4
            name: hostname-server
            ports:
            - containerPort: 9376
              protocol: TCP
          terminationGracePeriodSeconds: 90
    

    이 매니페스트는 포트 9376에서 HTTPS 서버를 리슨하는 배포를 설명합니다. 또한 이 배포는 애플리케이션에 대한 포드를 관리합니다. 각 포드는 애플리케이션 서버의 호스트 이름을 응답으로 반환하는 HTTPS 서버에 하나의 애플리케이션 컨테이너를 실행합니다. 포드의 기본 호스트 이름은 포드의 이름입니다. 또한 컨테이너는 단계적 종료를 처리합니다.

  2. 클러스터에 매니페스트를 적용합니다.

    kubectl apply -f web-deployment.yaml
    

서비스를 네트워크 엔드포인트 그룹(NEG)으로 배포

이 섹션에서는 서비스 리소스를 만듭니다. 서비스는 인그레스 컨트롤러가 백엔드 엔드포인트로 프로그래밍할 수 있도록 해당 라벨로 백엔드 컨테이너를 선택합니다. 내부 애플리케이션 부하 분산기의 인그레스를 사용하려면 NEG를 백엔드로 사용해야 합니다. 이 기능은 인스턴스 그룹을 백엔드로 지원하지 않습니다. NEG 백엔드가 필요하기 때문에 인그레스를 통해 노출되는 서비스를 배포할 때 다음 NEG 주석이 필요합니다.

annotations:
  cloud.google.com/neg: '{"ingress": true}'

다음 조건이 모두 충족되면 서비스가 cloud.google.com/neg: '{"ingress": true}'로 자동으로 주석 처리됩니다.

  • VPC 기반 클러스터를 사용 중입니다.
  • 공유 VPC를 사용 중이 아닙니다.
  • GKE 네트워크 정책을 사용 중이 아닙니다.

이름이 neg-annotation.config.common-webhooks.networking.gke.ioMutatingWebhookConfiguration을 사용하여 주석이 자동으로 추가됩니다. 다음 명령어를 사용하여 MutatingWebhookConfiguration이 있는지 확인할 수 있습니다.

kubectl get mutatingwebhookconfigurations

NEG를 사용하면 인그레스 컨트롤러가 컨테이너 기반 부하 분산을 수행할 수 있습니다. 트래픽은 노드 IP 또는 kube-proxy 네트워킹을 횡단하지 않고 인그레스 프록시에서 포드 IP로 직접 부하 분산됩니다. 또한 포드 준비 게이트가 구현되어 Kubernetes 준비 및 활성 확인뿐만 아니라 부하 분산기의 관점에서 포드의 상태를 확인합니다. 포드 준비 게이트는 포드 시작, 포드 손실 또는 노드 손실과 같은 수명 주기 이벤트 중에 트래픽이 삭제되지 않도록 합니다.

NEG 주석을 포함하지 않으면 인그레스 객체에서 경고가 표시되고, 내부 애플리케이션 부하 분산기를 구성할 수 없게 됩니다. NEG 주석이 포함되지 않은 경우, Kubernetes 이벤트는 인그레스에서 생성됩니다. 다음은 이벤트 메시지의 예시입니다.

Message
-------
error while evaluating the ingress spec: could not find port "8080" in service "default/no-neg-svc"

NEG는 인그레스가 서비스를 참조할 때까지 생성되지 않습니다. NEG는 인그레스 및 해당 참조 서비스가 모두 존재할 때까지 Compute Engine에 표시되지 않습니다. NEG는 영역별 리소스이며, 멀티 영역 클러스터의 경우 영역 및 서비스를 기준으로 생성됩니다.

서비스를 만드는 방법은 다음과 같습니다.

  1. 다음 샘플 매니페스트를 web-service.yaml로 저장합니다.

    apiVersion: v1
    kind: Service
    metadata:
      name: hostname
      namespace: default
      annotations:
        cloud.google.com/neg: '{"ingress": true}'
    spec:
      ports:
      - name: host1
        port: 80
        protocol: TCP
        targetPort: 9376
      selector:
        app: hostname
      type: ClusterIP
    
  2. 클러스터에 매니페스트를 적용합니다.

    kubectl apply -f web-service.yaml
    

인그레스 배포

이 섹션에서는 인그레스 컨트롤러를 통해 Compute Engine 부하 분산기 배포를 트리거하는 인그레스 리소스를 만듭니다. 내부 애플리케이션 부하 분산기의 인그레스를 사용하려면 다음 주석이 필요합니다.

annotations:
    kubernetes.io/ingress.class: "gce-internal"

ingressClassName 필드를 사용하여 GKE 인그레스를 지정할 수 없습니다. kubernetes.io/ingress.class 주석을 사용해야 합니다. 자세한 내용은 GKE 인그레스 컨트롤러 동작을 참조하세요.

인그레스를 만들려면 다음 안내를 따르세요.

  1. 다음 샘플 매니페스트를 internal-ingress.yaml로 저장합니다.

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: ilb-demo-ingress
      namespace: default
      annotations:
        kubernetes.io/ingress.class: "gce-internal"
    spec:
      defaultBackend:
        service:
          name: hostname
          port:
            number: 80
    
  2. 클러스터에 매니페스트를 적용합니다.

    kubectl apply -f internal-ingress.yaml
    

성공적인 인그레스 배포 검증

이 섹션에서는 배포가 성공했는지 확인합니다.

인그레스 리소스가 완전히 프로비저닝되려면 몇 분 정도 걸릴 수 있습니다. 이 기간 동안 인그레스 컨트롤러는 전달 규칙, 백엔드 서비스, URL 맵, NEG와 같은 항목들을 만듭니다.

이전 섹션에서 만든 인그레스 리소스의 상태를 검색하려면 다음 명령어를 실행합니다.

kubectl get ingress ilb-demo-ingress

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

NAME               HOSTS    ADDRESS            PORTS     AGE
ilb-demo-ingress   *        10.128.0.58        80        59s

ADDRESS 필드가 채워지면 인그레스가 준비됩니다. 이 필드에 사용된 RFC 1918 주소는 VPC 안의 내부 IP를 나타냅니다.

내부 애플리케이션 부하 분산기는 리전 부하 분산기이므로 가상 IP(VIP)는 동일한 리전 및 VPC 내의 클라이언트에서만 액세스할 수 있습니다. 부하 분산기 VIP를 검색한 후 도구(예: curl)를 사용하여 VPC 내에서 VIP에 대한 HTTP GET 호출을 수행할 수 있습니다.

HTTP GET 호출을 수행하려면 다음 단계를 완료하세요.

  1. VPC 내에서 인그레스 VIP에 연결하려면 클러스터와 동일한 리전 및 네트워크 내에서 VM을 배포합니다.

    gcloud compute instances create l7-ilb-client \
        --image-family=debian-10 \
        --image-project=debian-cloud \
        --network=NETWORK_NAME \
        --subnet=SUBNET_NAME \
        --zone=COMPUTE_ZONE \
        --tags=allow-ssh
    

    다음을 바꿉니다.

    • SUBNET_NAME: 네트워크의 서브넷 이름입니다.
    • COMPUTE_ZONE: 리전의 Compute Engine 영역입니다.

    인스턴스를 만드는 방법에 대한 자세한 내용은 VM 인스턴스 만들기 및 시작을 참조하세요.

  2. VM 내에서 내부 VIP에 액세스하려면 curl을 사용합니다.

    1. 이전 단계에서 만든 VM에 SSH를 사용합니다.

      gcloud compute ssh l7-ilb-client \
          --zone=COMPUTE_ZONE
      
    2. curl을 사용하여 내부 애플리케이션 VIP에 액세스합니다.

      curl 10.128.0.58
      hostname-server-6696cf5fc8-z4788
      

      백엔드 컨테이너 중 하나의 호스트 이름과 성공한 HTTP 응답은 전체 부하 분산 경로가 올바르게 작동함을 나타냅니다.

인그레스 리소스 삭제

인그레스 및 서비스 리소스를 삭제하면 이와 연결된 Compute Engine 부하 분산기 리소스도 삭제됩니다. 리소스 누출을 방지하기 위해서는 더 이상 필요하지 않을 때 인그레스 리소스가 삭제되었는지 확인합니다. 클러스터를 삭제하기 전에 인그레스 및 서비스 리소스 또한 삭제해야 하며, 그렇지 않으면 Compute Engine 부하 분산 리소스가 분리됩니다.

인그레스를 삭제하려면 다음 단계를 완료하세요.

  1. 인그레스를 삭제합니다. 예를 들어 이 페이지에서 만든 인그레스를 삭제하려면 다음 명령어를 실행합니다.

    kubectl delete ingress ilb-demo-ingress
    

    인그레스를 삭제하면 이 인그레스 리소스와 연결된 전달 규칙, 백엔드 서비스, URL 맵이 삭제됩니다.

  2. 서비스 삭제 예를 들어 이 페이지에서 만든 서비스를 삭제하려면 다음 명령어를 실행합니다.

    kubectl delete service hostname
    

    서비스를 삭제하면 서비스와 연결된 NEG가 삭제됩니다.

GKE에 애플리케이션을 배포하고 비공개 부하 분산 IP 주소로 애플리케이션을 노출하려면 기본 내부 인그레스를 참조하세요.

고정 IP 주소

내부 인그레스 리소스는 고정 IP 주소와 임시 IP 주소를 모두 지원합니다. IP 주소를 지정하지 않으면 사용 가능한 IP 주소가 GKE 노드 서브넷에서 자동으로 할당됩니다. 하지만 인그레스 리소스는 내부 프록시 사용에만 사용되는 프록시 전용 서브넷의 IP 주소를 프로비저닝하지 않습니다. 이러한 임시 IP 주소는 내부 인그레스 리소스의 수명 주기 동안만 인그레스에 할당됩니다. 인그레스를 삭제하고 동일한 매니페스트 파일에서 새 인그레스를 만드는 경우, 동일한 외부 IP 주소를 얻게 된다고 보장할 수 없습니다.

내부 인그레스 리소스의 수명 주기와는 독립적인 영구 IP 주소를 설정하려면 리전 고정 내부 IP 주소를 예약해야 합니다. 그런 다음 인그레스 리소스에서 kubernetes.io/ingress.regional-static-ip-name 주석을 사용하여 고정 IP 주소를 지정할 수 있습니다.

다음 예시는 이 주석을 추가하는 방법을 보여줍니다.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    kubernetes.io/ingress.regional-static-ip-name: STATIC_IP_NAME
    kubernetes.io/ingress.class: "gce-internal"

STATIC_IP_NAME을 다음 기준을 충족하는 고정 IP 이름으로 바꿉니다.

  • 인그레스를 배포하기 전에 고정 IP 주소를 만듭니다. 부하 분산기는 고정 IP가 존재할 때까지 배포되지 않으며 존재하지 않는 IP 주소 리소스를 참조할 경우 고정 IP가 생성되지 않습니다. 기존 인그레스에서 임시 IP 주소 대신 고정 IP 주소를 사용하도록 수정하면 GKE가 부하 분산기의 전달 규칙을 다시 만들 때 부하 분산기의 IP 주소를 변경할 수 있습니다.
  • 고정 IP는 공유 VPC의 서비스 프로젝트에 배포된 인그레스에 대해 서비스 프로젝트에 예약됩니다.
  • IP 주소 대신 Google Cloud IP 주소 리소스를 이름으로 참조합니다.
  • IP 주소는 GKE 클러스터와 동일한 리전의 서브넷에 있어야 합니다. 리전 내에서 사용 가능한 모든 비공개 서브넷을 사용할 수 있습니다(프록시 전용 서브넷은 예외). 서로 다른 인그레스 리소스는 다른 서브넷 주소를 가질 수도 있습니다.

클라이언트와 부하 분산기 간 HTTPS

내부 부하 분산용 인그레스는 클라이언트에 대한 TLS 인증서 제공을 지원합니다. Kubernetes 보안 비밀 또는 Google Cloud에서 미리 공유된 리전별 SSL 인증서를 통해 TLS 인증서를 제공할 수 있습니다. 또한 인그레스 리소스별로 여러 인증서를 지정할 수도 있습니다. HTTPS 및 HTTP 동시 사용은 GKE 1.25+에서 지원됩니다. 이 기능을 사용 설정하려면 PURPOSE=SHARED_LOADBALANCER_VIP를 사용해서 고정 IP 주소를 만들고 인그레스에서 이를 구성해야 합니다. 고정 IP 주소가 제공되지 않았으면 HTTPS 트래픽만 허용되고 HTTP 사용 중지 안내를 따라야 합니다.

다음 단계에서는 Google Cloud에서 인증서를 만들고 HTTPS 및 HTTP 트래픽 모두 인그레스를 통해 내부 클라이언트에 제공하는 방법을 설명합니다.

  1. 리전별 인증서를 만듭니다.

    gcloud compute ssl-certificates create CERT_NAME \
        --certificate CERT_FILE_PATH \
        --private-key KEY_FILE_PATH \
        --region COMPUTE_REGION
    

    다음을 바꿉니다.

    • CERT_NAME: 선택한 인증서의 이름입니다.
    • CERT_FILE_PATH: 자체 관리형 인증서를 만들 수 있는 로컬 인증서 파일 경로입니다. 인증서는 PEM 형식이어야 합니다.
    • KEY_FILE_PATH: 로컬 비공개 키 파일의 경로입니다. 비공개 키는 PEM 형식이어야 하며 RSA 또는 ECDSA 암호화를 사용해야 합니다.
    • COMPUTE_REGION: 인증서의 Compute Engine 리전입니다.
  2. 고정 IP 주소 지정에 따라 고정 IP 주소를 예약하고 적용합니다.

  3. 다음 샘플 매니페스트를 ingress-pre-shared-cert.yaml로 저장합니다.

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: ilb-demo-ing
      namespace: default
      annotations:
        ingress.gcp.kubernetes.io/pre-shared-cert: "CERT_NAME"
        kubernetes.io/ingress.regional-static-ip-name: STATIC_IP_NAME
        kubernetes.io/ingress.class: "gce-internal"
    spec:
      rules:
      - host: DOMAIN
        http:
          paths:
          - pathType: ImplementationSpecific
            backend:
              service:
                name: SERVICE_NAME
                port:
                  number: 80
    

    다음을 바꿉니다.

    • DOMAIN: 도메인입니다.
    • CERT_NAME: 이전 섹션에서 만든 인증서의 이름입니다.
    • SERVICE_NAME: 서비스 이름입니다.
  4. 클러스터에 매니페스트를 적용합니다.

    kubectl apply -f ingress-pre-shared-cert.yaml
    

부하 분산기와 애플리케이션 간 HTTPS

애플리케이션이 GKE 포드에서 실행되고 HTTPS 요청을 수신할 수 있으면 애플리케이션으로 요청을 전달할 때 HTTPS를 사용하도록 부하 분산기를 구성할 수 있습니다. 자세한 내용은 부하 분산기와 애플리케이션 간 HTTPS(TLS)를 참조하세요.

공유 VPC

NEG 주석을 수동으로 추가

인그레스 리소스를 배포하는 GKE가 공유 VPC 서비스 프로젝트에 있는 경우 서비스에 주석 삽입을 담당하는 MutatingWebhookConfiguration이 설치되지 않았기 때문에 서비스에 cloud.google.com/neg: '{"ingress": true}' 주석이 자동 주석 처리되지 않습니다.

NEG 주석을 내부 애플리케이션 부하 분산기의 인그레스를 통해 노출되는 서비스 매니페스트에 추가해야 합니다.

VPC 방화벽 규칙

인그레스 리소스를 배포하는 GKE 클러스터가 공유 VPC 서비스 프로젝트에 있고 GKE 제어 영역에서 호스트 프로젝트의 방화벽 리소스를 관리하도록 하려면 서비스 프로젝트의 GKE 서비스 계정에 공유 VPC가 있는 클러스터의 방화벽 리소스 관리에 따라 호스트 프로젝트의 적절한 IAM 권한이 부여되어야 합니다. 이렇게 하면 인그레스 컨트롤러가 Google Cloud 상태 점검에 대한 인그레스 트래픽을 허용하는 방화벽 규칙을 만들 수 있습니다.

다음은 인그레스 리소스 로그에 존재할 수 있는 이벤트의 예시입니다. 이 오류는 권한이 올바르게 구성되지 않은 경우 인그레스 컨트롤러가 Google Cloud 상태 확인에 대한 인그레스 트래픽을 허용하는 방화벽 규칙을 만들 수 없는 경우에 발생합니다.

Firewall change required by security admin: `gcloud compute firewall-rules update <RULE_NAME> --description "GCE L7 firewall rule" --allow tcp:<PORT> --source-ranges 130.211.0.0/22,35.191.0.0/16 --target-tags <TARGET_TAG> --project <HOST_PROJECT>

호스트 프로젝트에서 방화벽 규칙을 수동으로 프로비저닝하려는 경우 인그레스 리소스에 networking.gke.io/suppress-firewall-xpn-error: "true" 주석을 추가하여 firewallXPNError 이벤트를 숨길 수 있습니다.

내부 인그레스 주석 요약

다음 표에서는 내부 애플리케이션 부하 분산기의 인그레스 및 인그레스 리소스를 만들 때 추가할 수 있는 주석을 보여줍니다.

인그레스 주석

주석 설명
kubernetes.io/ingress.class 내부 인그레스의 경우 "gce-internal"로 설정할 수 있습니다. 클래스가 지정되지 않았으면 기본적으로 인그레스 리소스가 외부 인그레스로 해석됩니다. 자세한 내용은 GKE 인그레스 컨트롤러 동작을 참조하세요.
kubernetes.io/ingress.allow-http 클라이언트와 HTTP(S) 부하 분산기 간에 HTTP 트래픽을 허용할 수 있습니다. 가능한 값은 truefalse입니다. 기본값은 true입니다. 자세한 내용은 HTTP 사용 중지를 참조하세요.
ingress.gcp.kubernetes.io/pre-shared-cert Google Cloud 프로젝트에 인증서와 키를 업로드할 수 있습니다. 이 주석을 사용하여 인증서와 키를 참조합니다. 자세한 내용은 외부 애플리케이션 부하 분산기에서 여러 SSL 인증서 사용을 참조하세요.
networking.gke.io/suppress-firewall-xpn-error

GLBC 1.4 이상에서는 firewallXPNError 이벤트가 발생하지 않도록 할 수 있습니다. 인그레스 부하 분산기의 경우 Kubernetes가 권한 부족으로 인해 방화벽 규칙을 변경할 수 없으면 몇 분 간격으로 firewallXPNError 이벤트가 발생합니다.

networking.gke.io/suppress-firewall-xpn-error: "true" 주석을 인그레스 리소스에 추가합니다. 기본값은 false입니다. 이 주석을 삭제하면 이벤트가 다시 발생합니다.

kubernetes.io/ingress.regional-static-ip-name 고정 IP 주소를 지정하여 내부 인그레스 리소스를 프로비저닝할 수 있습니다. 자세한 내용은 고정 IP 주소 지정을 참조하세요.
주석 설명
cloud.google.com/backend-config 이 주석을 사용하여 servicePort와 연결된 백엔드 서비스를 구성합니다. 자세한 내용은 인그레스 구성을 참조하세요.
cloud.google.com/neg 이 주석을 사용하여 부하 분산기에서 네트워크 엔드포인트 그룹을 사용하도록 지정합니다. 자세한 내용은 컨테이너 기반 부하 분산 사용을 참조하세요.

문제 해결

인그레스 상태를 파악하고 관찰하기 위해서는 일반적으로 연관된 리소스를 조사하는 과정이 필요합니다. 자주 발생하는 문제 유형에는 올바르게 생성되지 않은 부하 분산 리소스, 백엔드에 연결되지 않는 트래픽, 정상 상태로 표시되지 않는 백엔드가 있습니다.

일반적인 문제 해결 단계는 다음과 같습니다.

  • 클라이언트 트래픽이 부하 분산기와 동일한 리전 및 VPC 내에서 시작되는지 확인합니다.
  • 포드와 백엔드가 정상 상태인지 확인합니다.
  • 방화벽 규칙으로 차단되지 않았는지 확인하기 위해 VIP에 대한 트래픽 경로를 확인하고 Compute Engine 상태를 검사합니다.
  • 인그레스 리소스 이벤트에 오류가 있는지 확인합니다.
  • 인그레스 리소스 상태를 기술하여 Compute Engine 리소스에 대한 매핑을 확인합니다.
  • Compute Engine 부하 분산 리소스가 있는지, 올바른 구성이 있으며, 오류가 보고되지 않았는지 검증합니다.

인그레스 이벤트 필터링

다음 쿼리는 클러스터에 있는 모든 인그레스 이벤트에서 오류를 필터링합니다.

kubectl get events --all-namespaces --field-selector involvedObject.kind=Ingress

객체 또는 객체 이름으로 필터링할 수도 있습니다.

kubectl get events --field-selector involvedObject.kind=Ingress,involvedObject.name=hostname-internal-ingress

다음 오류에서는 인그레스에서 참조되는 서비스가 존재하지 않는 것을 확인할 수 있습니다.

LAST SEEN   TYPE      REASON      OBJECT                              MESSAGE
0s          Warning   Translate   ingress/hostname-internal-ingress   error while evaluating the ingress spec: could not find service "default/hostname-invalid"

Compute Engine 부하 분산기 리소스 검사

다음 명령어는 인그레스 컨트롤러가 생성한 Compute Engine 리소스에 대한 매핑을 볼 수 있도록 인그레스 리소스의 전체 출력을 표시합니다.

kubectl get ing INGRESS_FILENAME -o yaml

INGRESS_FILENAME을 인그레스 리소스의 파일 이름으로 바꿉니다.

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

apiVersion: v1
items:
- apiVersion: networking.k8s.io/v1
  kind: Ingress
  metadata:
    annotations:
      ingress.kubernetes.io/backends: '{"k8s1-241a2b5c-default-hostname-80-29269aa5":"HEALTHY"}'
      ingress.kubernetes.io/forwarding-rule: k8s-fw-default-ilb-demo-ingress--241a2b5c94b353ec
      ingress.kubernetes.io/target-proxy: k8s-tp-default-ilb-demo-ingress--241a2b5c94b353ec
      ingress.kubernetes.io/url-map: k8s-um-default-ilb-demo-ingress--241a2b5c94b353ec
      kubectl.kubernetes.io/last-applied-configuration: |
       {"apiVersion":"networking.k8s.io/v1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"gce-internal"},"name":"ilb-demo-ingress","namespace":"default"},"spec":{"defaultBackend":{"service":{"name":"hostname"},"port":{"number":80}}}}
      kubernetes.io/ingress.class: gce-internal
    creationTimestamp: "2019-10-15T02:16:18Z"
    finalizers:
    - networking.gke.io/ingress-finalizer
    generation: 1
    name: ilb-demo-ingress
    namespace: default
    resourceVersion: "1538072"
    selfLink: /apis/networking.k8s.io/v1/namespaces/default/ingresses/ilb-demo-ingress
    uid: 0ef024fe-6aea-4ee0-85f6-c2578f554975
  spec:
    defaultBackend:
      service:
        name: hostname
        port:
          number: 80
  status:
    loadBalancer:
      ingress:
      - ip: 10.128.0.127
kind: List
metadata:
  resourceVersion: ""
  selfLink: ""

ingress.kubernetes.io/backends 주석에는 백엔드 및 해당 상태가 나열됩니다. 백엔드가 HEALTHY로 나열되는지 확인합니다.

인그레스로 생성된 Compute Engine 리소스를 직접 쿼리하여 해당 상태 및 구성을 확인할 수 있습니다. 이러한 쿼리를 실행하면 문제를 해결하는 데에도 유용할 수 있습니다.

모든 Compute Engine 전달 규칙을 나열하려면 다음 안내를 따르세요.

gcloud compute forwarding-rules list

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

NAME                                                        REGION       IP_ADDRESS      IP_PROTOCOL  TARGET
k8s-fw-default-hostname-internal-ingress--42084f6a534c335b  REGION_NAME  10.128.15.225   TCP          REGION_NAME/targetHttpProxies/k8s-tp-default-hostname-internal-ingress--42084f6a534c335b

백엔드 서비스의 상태를 나열하려면 먼저 백엔드 서비스를 나열하고 검사하려는 백엔드 서비스의 이름을 복사합니다.

gcloud compute backend-services list

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

NAME                                         BACKENDS                                                                       PROTOCOL
k8s1-42084f6a-default-hostname-80-98cbc1c1   REGION_NAME/networkEndpointGroups/k8s1-42084f6a-default-hostname-80-98cbc1c1 HTTP

이제 백엔드 서비스 이름을 사용하여 상태를 쿼리할 수 있습니다.

gcloud compute backend-services get-health k8s1-42084f6a-default-hostname-80-98cbc1c1 \
    --region COMPUTE_REGION

COMPUTE_REGION을 백엔드 서비스의 Compute Engine 리전으로 바꿉니다.

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

backend: https://www.googleapis.com/compute/v1/projects/user1-243723/zones/ZONE_NAME/networkEndpointGroups/k8s1-42084f6a-default-hostname-80-98cbc1c1
status:
  healthStatus:
  - healthState: HEALTHY

다음 단계