Ingress configuration on Google Cloud


이 페이지에서는 Google Cloud에서 Kubernetes 인그레스를 통해 지원되고 구성 가능한 항목을 포괄적으로 간략하게 설명합니다.

기능 비교

다음 표에는 Google Cloud에서 인그레스에 지원되는 기능이 나와 있습니다. 이 기능의 가용성, 일반 안정화 버전(GA) 또는 베타도 표시됩니다.

인그레스 클래스 외부 인그레스 내부 인그레스 멀티 클러스터 인그레스
인그레스 컨트롤러 Google 호스팅 인그레스 컨트롤러 GKE 인그레스 컨트롤러
Google Cloud 부하 분산기 유형 외부 HTTP(S) 부하 분산기 내부 HTTP(S) 부하 분산기 외부 HTTP(S) 부하 분산기
클러스터 범위 단일 클러스터 단일 클러스터 멀티 클러스터
부하 분산기 범위 전역 리전 전역
환경 지원 GKE GKE GKE
공유 VPC 지원 GA GA GA
서비스 주석
컨테이너 기반 부하 분산(NEG) GA GA GA
부하 분산기에서 백엔드로의 HTTPS GA GA GA
HTTP/2 GA GA
TLS 전용
GA
인그레스 주석
고정 IP 주소 GA GA GA
Kubernetes 보안 비밀 기반 인증서 GA GA GA
자체 관리형 SSL 인증서 GA GA GA
Google 관리 SSL 인증서 GA GA
FrontendConfig
SSL 정책 GA GA
HTTP-HTTPS 간 리디렉션 GA
1.17.13-gke.2600+GA
GA
BackendConfig
백엔드 서비스 제한 시간 GA GA GA
Cloud CDN GA GA
연결 드레이닝 제한 시간 GA GA GA
커스텀 부하 분산기 상태 확인 구성 GA GA GA
Google Cloud Armor 보안 정책 GA
1.19.10-gke.700G
GA
HTTP 액세스 로깅 구성 GA GA GA
IAP(Identity-Aware Proxy) GA GA GA
세션 어피니티 GA GA GA
사용자 정의 요청 헤더 GA GA
커스텀 응답 헤더 GA GA

B이 기능은 지정된 버전부터 베타 버전으로 제공됩니다. 나열된 버전이 없는 기능은 사용 가능한 모든 GKE 및 GKE Enterprise 버전에서 지원됩니다.

G이 기능은 지정된 버전부터 정식 버전으로 지원됩니다.

기본 컨트롤러를 사용한 인그레스 구성

Google Cloud SDK 또는 Google Cloud Console을 사용하여 LoadBalancer 기능을 수동으로 구성할 수 없습니다. BackendConfig 또는 FrontendConfig Kubernetes 리소스를 사용해야 합니다.

기본 컨트롤러를 사용하여 인그레스를 만들 때 인그레스 객체에 주석을 사용하여 부하 분산기 유형(외부 애플리케이션 부하 분산기 또는 내부 애플리케이션 부하 분산기)을 선택할 수 있습니다. GKE에서 영역 NEG를 만들지 또는 각 서비스 객체에 주석을 사용하여 인스턴스 그룹을 사용할지 여부를 선택할 수 있습니다.

FrontendConfig 및 BackendConfig 커스텀 리소스 정의(CRD)를 사용하면 부하 분산기를 추가로 맞춤설정할 수 있습니다. 이 CRD를 사용하면 주석보다 더욱 구조화된 방식으로 추가적인 부하 분산기 기능을 계층화하여 정의할 수 있습니다. 인그레스(및 이 CRD)를 사용하려면 HTTP 부하 분산 부가기능을 사용 설정해야 합니다. GKE 클러스터에는 기본적으로 HTTP 부하 분산이 사용 설정되어 있으며 사용 중지하면 안 됩니다.

FrontendConfig는 인그레스 객체에서 참조되며 외부 인그레스에만 사용할 수 있습니다. BackendConfig는 서비스 객체에서 참조됩니다. 일관적인 구성으로 인해 여러 서비스 또는 인그레스 객체에서 같은 CRD를 참조할 수 있습니다. FrontendConfig CRD와 BackendConfig CRD는 해당하는 인그레스 및 서비스 리소스와 동일한 수명 주기를 공유하며 종종 함께 배포됩니다.

아래 다이어그램은 다음이 어떻게 참조되는지 보여줍니다.

  • 인그레스 또는 MultiClusterIngress 객체의 주석은 FrontendConfig CRD를 참조합니다. FrontendConfig CRD는 Google Cloud SSL 정책을 참조합니다.

  • 서비스 또는 MultiClusterService 객체의 주석은 BackendConfig CRD를 참조합니다. BackendConfig CRD는 해당 백엔드 서비스의 상태 확인용 커스텀 설정을 지정합니다.

BackendConfig 및 FrontendConfig 개요
그림: BackendConfig 및 FrontendConfig 개요

FrontendConfig를 인그레스와 연결

FrontendConfig는 외부 인그레스에만 사용할 수 있습니다.

FrontendConfig를 인그레스 또는 MultiClusterIngress와 연결할 수 있습니다.

인그레스

networking.gke.io/v1beta1.FrontendConfig 주석을 사용합니다.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    networking.gke.io/v1beta1.FrontendConfig: "FRONTENDCONFIG_NAME"
...

FRONTENDCONFIG_NAME을 FrontendConfig 이름으로 바꿉니다.

MultiClusterIngress

networking.gke.io/frontend-config 주석을 사용합니다.

apiVersion: networking.gke.io/v1
kind: MultiClusterIngress
metadata:
  annotations:
    networking.gke.io/frontend-config: "FRONTENDCONFIG_NAME"
...

FRONTENDCONFIG_NAME을 FrontendConfig 이름으로 바꿉니다.

BackendConfig를 인그레스와 연결

cloud.google.com/backend-config 또는 beta.cloud.google.com/backend-config 주석을 사용하여 BackendConfig 이름을 지정할 수 있습니다.

모든 서비스 포트에 동일한 BackendConfig

모든 포트에 동일한 BackendConfig를 사용하려면 주석에서 default 키를 사용합니다. 인그레스 컨트롤러는 서비스의 포트 중 하나를 참조하기 위해 부하 분산기 백엔드 서비스를 만들 때마다 동일한 BackendConfig를 사용합니다.

인그레스 및 MultiClusterIngress 리소스 모두에 default 키를 사용할 수 있습니다.
apiVersion: v1
kind: Service
metadata:
  annotations:
    cloud.google.com/backend-config: '{"default": "my-backendconfig"}'
...

서비스 포트별 고유 BackendConfig

인그레스 및 MultiClusterIngress 모두 포트 이름 또는 번호와 일치하는 키를 사용해서 하나 이상의 포트에 대해 커스텀 BackendConfig를 지정할 수 있습니다. 인그레스 컨트롤러는 참조된 서비스 포트의 부하 분산기 백엔드 서비스를 만들 때 특정 BackendConfig를 사용합니다.

GKE 1.16-gke.3 이상

apiVersion: v1
kind: Service
metadata:
  annotations:
    cloud.google.com/backend-config: '{"ports": {
    "SERVICE_REFERENCE_A":"BACKENDCONFIG_REFERENCE_A",
    "SERVICE_REFERENCE_B":"BACKENDCONFIG_REFERENCE_B"
    }}'
spec:
  ports:
  - name: PORT_NAME_1
    port: PORT_NUMBER_1
    protocol: TCP
    targetPort: 50000
  - name: PORT_NAME_2
    port: PORT_NUMBER_2
    protocol: TCP
    targetPort: 8080
...

지원되는 모든 버전

apiVersion: v1
kind: Service
metadata:
  annotations:
    cloud.google.com/backend-config: '{"ports": {
      PORT_NAME_1:"BACKENDCONFIG_REFERENCE_A",
      PORT_NAME_2:"BACKENDCONFIG_REFERENCE_B"
    }}'
spec:
  ports:
  - name: PORT_NAME_1
    port: PORT_NUMBER_1
    protocol: TCP
    targetPort: 50000
  - name: PORT_NAME_2
    port: PORT_NUMBER_2
    protocol: TCP
    targetPort: 8080
...

다음을 바꿉니다.

  • BACKENDCONFIG_REFERENCE_A: 기존 BackendConfig의 이름입니다.
  • BACKENDCONFIG_REFERENCE_B: 기존 BackendConfig의 이름입니다.
  • SERVICE_REFERENCE_A: PORT_NUMBER_1 또는 PORT_NAME_1 값을 사용합니다. 이는 서비스의 BackendConfig 주석이 포트 이름(spec.ports[].name) 또는 포트 번호(spec.ports[].port)를 참조할 수 있기 때문입니다.
  • SERVICE_REFERENCE_B: PORT_NUMBER_2 또는 PORT_NAME_2 값을 사용합니다. 이는 서비스의 BackendConfig 주석이 포트 이름(spec.ports[].name) 또는 포트 번호(spec.ports[].port)를 참조할 수 있기 때문입니다.

서비스 포트를 번호로 참조하는 경우 targetPort 값 대신 port 값을 사용해야 합니다. 여기에 사용되는 포트 번호는 BackendConfig 바인딩 전용입니다. 부하 분산기가 트래픽이나 상태 확인 프로브를 보내는 포트를 제어하지 않습니다.

  • 컨테이너 기반 부하 분산을 사용하는 경우 부하 분산기는 참조된 서비스 포트의 targetPort(제공 포드의 containerPort와 일치해야 함)에 있는 네트워크 엔드포인트 그룹(포드 IP 주소와 일치)의 엔드포인트로 트래픽을 전송합니다. 그렇지 않으면 부하 분산기는 참조된 서비스 포트의 nodePort에 있는 노드의 IP 주소로 트래픽을 전송합니다.

  • BackendConfig를 사용하여 커스텀 부하 분산기 상태 점검을 제공할 때 부하 분산기의 상태 점검에 사용하는 포트 번호는 서비스의 spec.ports[].port 번호와 다를 수 있습니다. 상태 점검의 포트 번호에 대한 자세한 내용은 커스텀 상태 점검 구성을 참조하세요.

FrontendConfig 매개변수를 통한 인그레스 기능 구성

다음 섹션에서는 특정 인그레스 기능을 사용 설정하도록 FrontendConfig를 설정하는 방법을 보여줍니다.

SSL 정책

SSL 정책을 사용하면 부하 분산기가 클라이언트의 HTTPS 트래픽을 종료하는 데 사용하는 TLS 버전과 암호화 집합을 지정할 수 있습니다. 먼저 GKE 외부에서 SSL 정책을 만들어야 합니다. 만든 후에는 FrontendConfig CRD에서 이를 참조할 수 있습니다.

FrontendConfig의 sslPolicy 필드는 GKE 클러스터와 동일한 Google Cloud 프로젝트의 SSL 정책 이름을 참조합니다. 인그레스에서 외부 HTTP(S) 부하 분산기용으로 만든 대상 HTTPS 프록시에 SSL 정책을 연결합니다. 동일한 FrontendConfig 리소스와 SSL 정책은 여러 인그레스 리소스에서 참조할 수 있습니다. 참조되는 SSL 정책이 변경되면 인그레스에 의해 생성된 외부 HTTP 부하 분산기를 구동하는 Google 프런트엔드(GFE)에 변경사항이 전파됩니다.

다음 FrontendConfig 매니페스트는 gke-ingress-ssl-policy라는 SSL 정책을 사용 설정합니다.

apiVersion: networking.gke.io/v1beta1
kind: FrontendConfig
metadata:
  name: my-frontend-config
spec:
  sslPolicy: gke-ingress-ssl-policy

HTTP-HTTPS 간 리디렉션

외부 HTTP 부하 분산기는 암호화되지 않은 HTTP 요청을 동일한 IP 주소를 사용하는 HTTPS 부하 분산기로 리디렉션할 수 있습니다. HTTP에서 HTTPS로 리디렉션을 사용 설정한 인그레스를 만들면 두 부하 분산기 모두 자동으로 생성됩니다. 포트 80에서 인그레스의 외부 IP 주소에 대한 요청은 포트 443에서 동일한 외부 IP 주소로 자동 리디렉션됩니다. 이 기능은 Cloud Load Balancing에서 제공하는 HTTP에서 HTTPS로 리디렉션을 기반으로 합니다.

HTTP에서 HTTPS로 리디렉션을 지원하려면 HTTP와 HTTPS 트래픽을 모두 제공하도록 인그레스를 구성해야 합니다. HTTP 또는 HTTPS를 사용 중지하면 리디렉션이 작동하지 않습니다.

HTTP에서 HTTPS로 리디렉션은 FrontendConfig 커스텀 리소스의 redirectToHttps 필드를 통해 구성됩니다. 리디렉션은 전체 인그레스 리소스에 사용 설정되므로 인그레스에서 참조하는 모든 서비스에 HTTPS 리디렉션이 사용 설정됩니다.

다음 FrontendConfig 매니페스트는 HTTP에서 HTTPS로 리디렉션을 사용 설정합니다. HTTPS 리디렉션을 사용 설정하려면 spec.redirectToHttps.enabled 필드를 true로 설정합니다. spec.responseCodeName 필드는 선택사항입니다. 생략된 경우 301 Moved Permanently 리디렉션이 사용됩니다.

apiVersion: networking.gke.io/v1beta1
kind: FrontendConfig
metadata:
  name: my-frontend-config
spec:
  redirectToHttps:
    enabled: true
    responseCodeName: RESPONSE_CODE

RESPONSE_CODE를 다음 중 하나로 바꿉니다.

  • MOVED_PERMANENTLY_DEFAULT 301 리디렉션 응답 코드를 반환합니다(responseCodeName가 지정되지 않은 경우 기본값).
  • FOUND 302 리디렉션 응답 코드를 반환합니다.
  • SEE_OTHER 303 리디렉션 응답 코드를 반환합니다.
  • TEMPORARY_REDIRECT 307 리디렉션 응답 코드를 반환합니다.
  • PERMANENT_REDIRECT 308 리디렉션 응답 코드를 반환합니다.

리디렉션이 사용 설정되면 인그레스 컨트롤러는 다음 다이어그램과 같이 부하 분산기를 만듭니다.

전달 규칙, 대상 HTTP 프록시, 백엔드 서비스를 사용하는 완전한 HTTPS 부하 분산기로 리디렉션되는 URL 맵으로 구성된 리디렉션 전용 외부 HTTP 부하 분산기

리디렉션이 작동하는지 확인하려면 curl 명령어를 사용하세요.

curl http://IP_ADDRESS

IP_ADDRESS를 인그레스의 IP 주소로 바꿉니다.

응답에는 구성한 리디렉션 응답 코드가 표시됩니다. 예를 들어 다음은 301: MovedPermanently 리디렉션으로 구성된 FrontendConfig에 대한 예시입니다.

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="https://35.244.160.59/">here</A>.</BODY></HTML>

BackendConfig 매개변수를 통한 인그레스 기능 구성

다음 섹션에서는 특정 인그레스 기능을 사용 설정하도록 BackendConfig를 설정하는 방법을 보여줍니다. BackendConfig 리소스 변경사항은 지속적으로 조정되므로 BackendConfig 변경사항을 반영하기 위해 인그레스를 삭제한 후 다시 만들 필요가 없습니다.

BackendConfig 제한사항에 대한 자세한 내용은 제한사항 섹션을 참조하세요.

백엔드 서비스 제한 시간

BackendConfig를 사용하여 백엔드 서비스 제한 시간을 초 단위로 설정할 수 있습니다. 값을 지정하지 않을 경우 기본값은 30초입니다.

다음 BackendConfig 매니페스트는 제한 시간을 40초로 지정합니다.

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: my-backendconfig
spec:
  timeoutSec: 40

Cloud CDN

BackendConfig를 사용하여 Cloud CDN을 사용 설정할 수 있습니다.

다음 BackendConfig 매니페스트는 Cloud CDN을 사용 설정할 때 사용할 수 있는 모든 필드를 보여줍니다.

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: my-backendconfig
spec:
  cdn:
    enabled: CDN_ENABLED
    cachePolicy:
      includeHost: INCLUDE_HOST
      includeProtocol: INCLUDE_PROTOCOL
      includeQueryString: INCLUDE_QUERY_STRING
      queryStringBlacklist: QUERY_STRING_DENYLIST
      queryStringWhitelist: QUERY_STRING_ALLOWLIST
    cacheMode: CACHE_MODE
    clientTtl: CLIENT_TTL
    defaultTtl: DEFAULT_TTL
    maxTtl: MAX_TTL
    negativeCaching: NEGATIVE_CACHING
    negativeCachingPolicy:
      code: NEGATIVE_CACHING_CODE
      ttl: NEGATIVE_CACHING_TTL
    requestCoalescing: REQ_COALESCING
    serveWhileStale: SERVE_WHILE_STALE
    signedUrlCacheMaxAgeSec: SIGNED_MAX_AGE
    signedUrlKeys:
      keyName: KEY_NAME
      keyValue: KEY_VALUE
      secretName: SECRET_NAME

다음을 바꿉니다.

  • CDN_ENABLED: true로 설정하면 이 인그레스 백엔드에 Cloud CDN이 사용 설정됩니다.
  • INCLUDE_HOST: true로 설정하면 서로 다른 호스트에 대한 요청이 개별적으로 캐시됩니다.
  • INCLUDE_PROTOCOL: true로 설정하면 HTTP 및 HTTPS 요청이 개별적으로 캐시됩니다.
  • INCLUDE_QUERY_STRING: true로 설정하면 쿼리 문자열 매개변수는 queryStringBlacklist 또는 queryStringWhitelist에 따라 캐시 키에 포함됩니다. 어느 것도 설정되지 않으면 전체 쿼리 문자열이 포함됩니다. false로 설정하면 전체 쿼리 문자열이 캐시 키에서 제외됩니다.
  • QUERY_STRING_DENYLIST: 캐시 키에서 제외할 쿼리 문자열 매개변수의 이름으로 문자열 배열을 지정합니다. 다른 모든 매개변수가 포함됩니다. queryStringBlacklist 또는 queryStringWhitelist 중 하나를 지정할 수 있지만 둘 다 지정할 수 없습니다.
  • QUERY_STRING_ALLOWLIST: 캐시 키에 포함할 쿼리 문자열 매개변수의 이름으로 문자열 배열을 지정합니다. 다른 모든 매개변수는 제외됩니다. queryStringBlacklist 또는 queryStringWhitelist 중 하나를 지정할 수 있지만 둘 다 지정할 수 없습니다.

다음 필드는 GKE 인그레스를 사용하는 GKE 버전 1.23.3-gke.900 이상에서만 지원됩니다. 멀티 클러스터 인그레스 사용은 지원되지 않습니다.

  • CACHE_MODE: 캐시 모드입니다.
  • CLIENT_TTL, DEFAULT_TTL, MAX_TTL: TTL 구성 자세한 내용은 TTL 설정 및 재정의 사용을 참조하세요.
  • NEGATIVE_CACHING: true로 설정하면 음성 캐싱이 사용 설정됩니다. 자세한 내용은 음성 캐싱 사용을 참조하세요.
  • NEGATIVE_CACHING_CODENEGATIVE_CACHING_TTL: 음성 캐싱 구성입니다. 자세한 내용은 음성 캐싱 사용을 참조하세요.
  • REQ_COALESCING: true로 설정하면 축소가 사용 설정됩니다. 자세한 내용은 요청 축소(병합)를 참조하세요.
  • SERVE_WHILE_STALE: 응답이 만료된 후 Cloud CDN이 비활성 버전을 계속 제공하는 시간(초)입니다. 자세한 내용은 비활성 콘텐츠 제공을 참조하세요.
  • SIGNED_MAX_AGE: 응답을 캐시할 수 있는 최대 시간(초)입니다. 자세한 내용은 원하는 경우 최대 캐시 시간 맞춤설정을 참조하세요.
  • KEY_NAME, KEY_VALUE, SECRET_NAME: 서명된 URL 키 구성입니다. 자세한 내용은 서명된 요청 키 만들기를 참조하세요.

다음 섹션을 펼치면 인그레스를 통해 Cloud CDN을 배포한 후 애플리케이션 콘텐츠가 캐시되는지 검사하는 예시를 볼 수 있습니다.

연결 드레이닝 제한 시간

BackendConfig를 사용하여 연결 드레이닝 제한 시간을 구성할 수 있습니다. 연결 드레이닝 제한 시간은 연결이 드레이닝될 때까지 기다리는 시간(초)입니다. 지정된 제한 시간 동안 삭제된 백엔드에 대한 기존 요청에 완료할 시간이 제공됩니다. 부하 분산기는 새로운 요청을 삭제된 백엔드에 보내지 않습니다. 제한 시간에 도달하면 백엔드에 남아있는 모든 연결이 닫힙니다. 제한 시간을 0~3600초로 지정할 수 있습니다. 기본값은 0이며 이 경우 연결 드레이닝이 중지됩니다.

다음 BackendConfig 매니페스트는 연결 드레이닝 제한 시간을 60초로 지정합니다.

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: my-backendconfig
spec:
  connectionDraining:
    drainingTimeoutSec: 60

커스텀 상태 확인 구성

인그레스를 통해 배포할 때 GKE는 Google Cloud 부하 분산기 상태 확인을 다양한 방법으로 구성할 수 있습니다. GKE 인그레스가 상태 확인을 배포하는 방법에 대한 자세한 내용은 인그레스 상태 확인을 참조하세요.

BackendConfig를 사용하면 부하 분산기 상태 점검 설정을 정확하게 제어할 수 있습니다.

재사용 가능한 템플릿과 동일한 BackendConfig를 참조하도록 여러 GKE 서비스를 구성할 수 있습니다. healthCheck 매개변수의 경우 각 GKE 서비스에 해당하는 백엔드 서비스마다 고유한 Google Cloud 상태 점검이 생성됩니다.

다음 BackendConfig 매니페스트는 BackendConfig 상태 확인을 구성할 때 사용할 수 있는 모든 필드를 보여줍니다.

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: my-backendconfig
spec:
  healthCheck:
    checkIntervalSec: INTERVAL
    timeoutSec: TIMEOUT
    healthyThreshold: HEALTH_THRESHOLD
    unhealthyThreshold: UNHEALTHY_THRESHOLD
    type: PROTOCOL
    requestPath: PATH
    port: PORT

다음을 바꿉니다.

  • INTERVAL: 각 상태 확인 프로버에 check-interval을 초 단위로 지정합니다. 이 값은 한 프로버에서 확인을 시작한 후 다음 번에 확인을 시작할 때까지 걸리는 시간입니다. 이 매개변수를 생략하면 Google Cloud 기본값인 5초가 사용됩니다. 자세한 구현 내용은 여러 프로브 및 빈도를 참조하세요.
  • TIMEOUT: Google Cloud가 프로브에 대한 응답을 기다리는 시간을 지정합니다. TIMEOUT 값은 INTERVAL 이하여야 합니다. 단위는 초입니다. 각 프로브에는 프로브 시간 초과 전에 HTTP 200 (OK) 응답 코드가 전송되어야 합니다.
  • HEALTH_THRESHOLDUNHEALTHY_THRESHOLD: 프로버 최소 한 개 이상에서 상태가 정상에서 비정상으로 또는 그 반대로 변경되기 위해 성공 또는 실패해야 하는 순차적인 연결 시도 수를 지정합니다. 이러한 매개변수 중 하나를 생략하면 Google Cloud에서 기본값 2를 사용합니다.
  • PROTOCOL: 프로브 시스템에서 상태 확인에 사용되는 프로토콜을 지정합니다. BackendConfig는 HTTP, HTTPS 또는 HTTP2 프로토콜을 사용한 상태 확인 생성만 지원합니다. 자세한 내용은 HTTP, HTTPS, HTTP/2의 성공 기준을 참조하세요. 이 매개변수를 생략할 수 없습니다.
  • PATH: HTTP, HTTPS 또는 HTTP2 상태 확인에 프로브 시스템을 연결할 request-path를 지정합니다. 이 매개변수를 생략하면 Google Cloud에서 기본값 /를 사용합니다.
  • PORT: BackendConfig는 포트 번호를 사용하여 부하 분산기 상태 점검 포트만 지정합니다. 이 매개변수를 생략하면 Google Cloud에서 기본값 80을 사용합니다.

    • 컨테이너 기본 부하 분산을 사용할 때는 서비스의 targetPort에서 containerPort를 참조하는지에 관계없이 제공 포드의 containerPort와 일치하는 포트를 선택해야 합니다. 부하 분산기가 프로브를 포드의 IP 주소로 직접 전달하므로 서비스의 targetPort에서 참조되는 containerPort의 제약을 받지 않습니다. 상태 점검 프로브 시스템은 지정된 포트에서 제공 포드의 IP 주소에 연결합니다.

    • 인스턴스 그룹 백엔드의 경우 서비스에서 노출하는 nodePort와 일치하는 포트를 선택해야 합니다. 그러면 상태 점검 프로브 시스템이 해당 포트의 각 노드에 연결됩니다.

커스텀 HTTP 상태 점검을 사용하여 GKE 인그레스를 설정하려면 커스텀 HTTP 상태 점검으로 GKE 인그레스를 참조하세요.

Google Cloud Armor 인그레스 보안 정책

Google Cloud Armor 보안 정책을 사용하면 웹 기반 공격으로부터 부하 분산 애플리케이션을 보호할 수 있습니다. Google Cloud Armor 보안 정책을 구성한 후에는 BackendConfig를 사용하여 이를 참조할 수 있습니다.

BackendConfig에 보안 정책 이름을 추가합니다. 다음 BackendConfig 매니페스트는 example-security-policy라는 보안 정책을 지정합니다.

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  namespace: cloud-armor-how-to
  name: my-backendconfig
spec:
  securityPolicy:
    name: "example-security-policy"

두 가지 정보 소스

GKE를 통해 구성되었지만 기본 Compute Engine BackendService API를 사용하여 적용할 보안 정책을 직접 수정할 수 있습니다. 이렇게 하면 GKE와 Compute Engine이라는 두 가지 정보 소스가 생성됩니다. BackendConfig 내의 securityPolicy 필드에 대한 응답의 GKE 인그레스 컨트롤러 동작은 아래 표에 설명되어 있습니다. 충돌 및 예기치 않은 동작을 방지하려면 사용할 보안 정책을 관리하는 데 GKE BackendConfig를 사용하는 것이 좋습니다.

BackendConfig 필드 동작
spec.securityPolicy.name CloudArmorPolicyName GKE 인그레스 컨트롤러는 CloudArmorPolicyName이라는 Google Cloud Armor 정책을 부하 분산기로 설정합니다. GKE 인그레스 컨트롤러는 이전에 설정된 정책을 덮어씁니다.
spec.securityPolicy.name 빈 문자열("") GKE 인그레스 컨트롤러는 부하 분산기에서 구성된 Google Cloud Armor 정책을 모두 삭제합니다.
spec.securityPolicy nil GKE 인그레스 컨트롤러는 Google Cloud 콘솔, gcloud CLI 또는 Terraform을 사용하여 Compute Engine API를 통해 구성된 BackendService 객체의 구성 집합을 사용합니다.

Google Cloud Armor 보호로 GKE 인그레스를 설정하려면 Google Cloud Armor가 사용 설정된 인그레스를 참조하세요.

HTTP 액세스 로깅

인그레스는 클라이언트의 모든 HTTP 요청을 Cloud Logging에 로깅할 수 있습니다. BackendConfig를 사용하여 액세스 로깅을 사용 설정하거나 중지하고 액세스 로깅 샘플링 레이트를 설정할 수 있습니다.

액세스 로깅을 구성하려면 BackendConfig의 logging 필드를 사용합니다. logging을 생략하면 액세스 로깅이 기본 동작으로 설정됩니다. 이는 GKE 버전에 따라 달라집니다.

다음 필드를 구성할 수 있습니다.

  • enable: true로 설정하면 이 인그레스에 액세스 로깅이 사용 설정되며 Cloud Logging에 로그가 제공됩니다. 그렇지 않으면 이 인그레스에 액세스 로깅이 중지됩니다.
  • sampleRate: 0.0~1.0 범위의 값을 지정합니다. 이때 0.0은 패킷이 로깅되지 않음을 의미하고 1.0은 패킷 모두가 로깅됨을 의미합니다. 이 필드는 enabletrue로 설정된 경우에만 관련이 있습니다. sampleRate는 선택적 필드이지만 구성되는 경우 enable: true를 설정해야 합니다. 그렇지 않으면 enable: false로 해석됩니다.

다음 BackendConfig는 액세스 로깅을 사용 설정하고 지정된 인그레스 리소스의 샘플링 레이트를 HTTP 요청의 50%로 설정합니다.

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: my-backendconfig
spec:
  logging:
    enable: true
    sampleRate: 0.5

IAP(Identity-Aware Proxy)

IAP(Identity-Aware Proxy)용 BackendConfig를 구성하려면 BackendConfig의 iap 블록에 enabled 값과 secretName 값을 지정해야 합니다. 이러한 값을 지정하려면 compute.backendServices.update 권한이 있어야 합니다.

다음 BackendConfig 매니페스트는 IAP(Identity-Aware Proxy)를 사용 설정합니다.

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name:  my-backendconfig
spec:
  iap:
    enabled: true
    oauthclientCredentials:
      secretName: my-secret

Google 관리 OAuth 클라이언트에서 IAP 사용 설정

GKE 1.29.2-gke.1035000부터는 BackendConfig를 사용하여 Google 관리 OAuth 클라이언트를 사용하도록 IAP를 구성할 수 있습니다. Google OAuth 클라이언트 또는 커스텀 OAuth 클라이언트를 사용할지 결정하려면 IAP 문서에서 커스텀 OAuth 구성을 사용하는 경우를 참조하세요.

Google 관리 OAuth 클라이언트로 IAP를 사용 설정하려면 BackendConfig에 OAuthCredentials를 제공하지 마세요. OAuthCredentials를 사용하여 IAP를 이미 구성한 사용자의 경우 Google 관리 OAuth 클라이언트를 사용하도록 전환할 마이그레이션 경로가 없으면 백엔드를 다시 만들어야 합니다(인그레스에서 해당 서비스를 삭제한 후 다시 연결). 다운타임이 발생할 수 있으므로 유지보수 기간 중에 작업을 수행하는 것이 좋습니다. Google 관리형 OAuthClient에서 OAuthCredentials로, 반대 마이그레이션 경로로 전환할 수 있습니다.

다음 BackendConfig 매니페스트는 Google 관리형 OAuth 클라이언트에서 IAP(Identity-Aware Proxy)를 사용 설정합니다.

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name:  my-backendconfig
spec:
  iap:
    enabled: true

자세한 안내는 IAP 문서의 GKE에 IAP 사용 설정을 참조하세요.

내부 인그레스를 사용하는 IAP(Identity-Aware Proxy)

IAP용 내부 인그레스를 구성하려면 프리미엄 등급을 사용해야 합니다. 프리미엄 등급을 사용하지 않으면 IAP(Identity-Aware Proxy)를 사용하여 내부 애플리케이션 부하 분산기를 보거나 만들 수 없습니다. IAP에 내부 인그레스를 사용하려면 BeyondCorp Enterprise 구독도 있어야 합니다.

IAP(Identity-Aware Proxy) 기반 인증으로 보안 GKE 인그레스를 설정하려면 IAP 사용 인그레스를 참조하세요.

세션 어피니티

BackendConfig를 사용하여 세션 어피니티를 클라이언트 IP나 생성된 쿠키로 설정할 수 있습니다.

클라이언트 IP 어피니티

BackendConfig를 사용하여 클라이언트 IP 어피니티를 설정하려면 다음 예시와 같이 affinityType"CLIENT_IP"로 설정합니다.

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: my-backendconfig
spec:
  sessionAffinity:
    affinityType: "CLIENT_IP"

BackendConfig를 사용하여 생성된 쿠키 어피니티를 설정하려면 BackendConfig 매니페스트에서 affinityTypeGENERATED_COOKIE로 설정합니다. 또한 affinityCookieTtlSec을 사용하여 쿠키가 활성 상태로 유지되는 기간을 설정할 수 있습니다.

다음 매니페스트는 어피니티 유형을 생성된 쿠키로 설정하고 쿠키에 TTL 50초를 제공합니다.

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: my-backendconfig
spec:
  sessionAffinity:
    affinityType: "GENERATED_COOKIE"
    affinityCookieTtlSec: 50

사용자 정의 요청 헤더

BackendConfig를 사용하여 사용자 정의 요청 헤더를 구성할 수 있습니다. 부하 분산기는 지정된 헤더를 백엔드로 전달하는 요청에 추가합니다.

사용자 정의 요청 헤더를 사용 설정하려면 BackendConfig 리소스의 customRequestHeaders 속성에 헤더 목록을 지정합니다. 각 헤더를 header-name:header-value 문자열로 지정합니다.

다음 BackendConfig 매니페스트는 요청 헤더 세 개를 추가합니다.

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: my-backendconfig
spec:
  customRequestHeaders:
    headers:
    - "X-Client-Region:{client_region}"
    - "X-Client-City:{client_city}"
    - "X-Client-CityLatLong:{client_city_lat_long}"

커스텀 응답 헤더

커스텀 응답 헤더를 사용 설정하려면 BackendConfig 리소스의 customResponseHeaders 속성에 헤더 목록을 지정합니다. 각 헤더를 header-name:header-value 문자열로 지정합니다.

다음 BackendConfig 매니페스트는 HTTP Strict Transport Security(HSTS) 응답 헤더를 추가하는 예시입니다.

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: my-backendconfig
spec:
  customResponseHeaders:
    headers:
    - "Strict-Transport-Security: max-age=28800; includeSubDomains"

연습: 백엔드 서비스를 사용한 인그레스 제한 시간 설정

다음 연습에서는 BackendConfig 리소스로 인그레스에 제한 시간과 연결 드레이닝을 구성하는 데 필요한 단계를 보여줍니다.

인그레스의 백엔드 속성을 구성하려면 다음 태스크를 완료합니다.

  1. 배포를 만듭니다.
  2. BackendConfig를 만듭니다.
  3. 서비스를 만들고 포트 중 하나를 BackendConfig에 연결합니다.
  4. 인그레스를 만들고 (서비스, 포트) 쌍과 연결합니다.
  5. 백엔드 서비스 속성의 유효성을 검사합니다.
  6. 삭제합니다.

배포 만들기

BackendConfig와 서비스를 만들기 전에 배포를 만들어야 합니다.

다음은 my-deployment.yaml이라는 배포의 매니페스트 예시입니다.

# my-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  selector:
    matchLabels:
      purpose: bsc-config-demo
  replicas: 2
  template:
    metadata:
      labels:
        purpose: bsc-config-demo
    spec:
      containers:
      - name: hello-app-container
        image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0

다음 명령어를 실행하여 배포를 만듭니다.

kubectl apply -f my-deployment.yaml

BackendConfig 만들기

BackendConfig를 사용하여 사용하려는 인그레스 기능을 지정합니다.

my-backendconfig.yaml이라는 이 BackendConfig 매니페스트는 다음을 지정합니다.

  • 제한 시간 40초
  • 연결 드레이닝 제한시간 60초
# my-backendconfig.yaml
apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: my-backendconfig
spec:
  timeoutSec: 40
  connectionDraining:
    drainingTimeoutSec: 60

다음 명령어를 실행하여 BackendConfig를 만듭니다.

kubectl apply -f my-backendconfig.yaml

서비스 만들기

BackendConfig는 서비스에 포트가 여러 개 있더라도 서비스-포트 조합 하나에 일치합니다. 각 포트를 BackendConfig CRD 하나와 연결할 수 있습니다. 서비스 포트가 인그레스에서 참조되는 경우와 서비스 포트가 BackendConfig와 연결되는 경우 HTTP(S) 부하 분산 백엔드 서비스는 BackendConfig에서 해당 구성을 사용합니다.

다음은 my-service.yaml이라는 서비스 매니페스트의 예시입니다.

# my-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: my-service
  labels:
    purpose: bsc-config-demo
  annotations:
    cloud.google.com/backend-config: '{"ports": {"80":"my-backendconfig"}}'
    cloud.google.com/neg: '{"ingress": true}'
spec:
  type: ClusterIP
  selector:
    purpose: bsc-config-demo
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8080

cloud.google.com/backend-config 주석은 포트와 BackendConfig 객체 사이의 매핑을 지정합니다. my-service.yaml 파일은 다음과 같습니다.

  • purpose: bsc-config-demo 라벨이 있는 모든 pod가 서비스의 구성원입니다.
  • 서비스의 TCP 포트 80이 my-backendconfig라는 BackendConfig와 연결됩니다. cloud.google.com/backend-config 주석에 이 항목이 지정되어 있습니다.
  • 서비스의 포트 80에 전송된 요청은 포트 8080의 구성원 pod 중 하나로 전달됩니다.

서비스를 만들려면 다음 명령어를 실행합니다.

kubectl apply -f my-service.yaml

인그레스 만들기

다음은 my-ingress.yaml.이라는 인그레스 매니페스트입니다. 이 예시에서 들어오는 요청은 my-service라는 서비스의 포트 80으로 라우팅됩니다.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
spec:
  rules:
  - http:
      paths:
      - path: /*
        pathType: ImplementationSpecific
        backend:
          service:
            name: my-service
            port:
              number: 80

인그레스를 만들려면 다음 명령어를 실행합니다.

kubectl apply -f my-ingress.yaml

인그레스 컨트롤러에서 외부 애플리케이션 부하 분산기와 연결된 백엔드 서비스를 구성할 때까지 몇 분 정도 기다립니다. 이 작업이 완료되면 제한 시간 40초, 연결 드레이닝 제한 시간 60초를 사용하도록 인그레스가 구성됩니다.

백엔드 서비스 속성 유효성 검사

BackendConfig를 통해 올바른 부하 분산기 설정이 적용되었는지 검사할 수 있습니다. 이렇게 하려면 인그레스에서 배포한 백엔드 서비스를 파악하고 해당 설정이 배포 매니페스트와 일치하는지 검사합니다.

먼저 my-ingress 리소스를 설명하고 인그레스와 연결된 백엔드 서비스를 나열하는 주석을 필터링합니다. 예를 들면 다음과 같습니다.

kubectl describe ingress my-ingress | grep ingress.kubernetes.io/backends

다음과 비슷한 출력이 표시됩니다.

ingress.kubernetes.io/backends: '{"k8s1-27fde173-default-my-service-80-8d4ca500":"HEALTHY","k8s1-27fde173-kube-system-default-http-backend-80-18dfe76c":"HEALTHY"}

출력에는 백엔드 서비스에 대한 정보가 제공됩니다. 예를 들어 이 주석에는 백엔드 서비스 두 개가 포함되어 있습니다.

  • "k8s1-27fde173-default-my-service-80-8d4ca500":"HEALTHY"my-service Kubernetes 서비스에 연결된 백엔드 서비스에 대한 정보를 제공합니다.
    • k8s1-27fde173은 클러스터를 설명하는 데 사용되는 해시입니다.
    • default는 Kubernetes 네임스페이스입니다.
    • HEALTHY는 백엔드가 정상임을 나타냅니다.
  • "k8s1-27fde173-kube-system-default-http-backend-80-18dfe76c":"HEALTHY"기본 백엔드(404-server)에 연결된 백엔드 서비스에 대한 정보를 제공합니다.
    • k8s1-27fde173은 클러스터를 설명하는 데 사용되는 해시입니다.
    • kube-system은 네임스페이스입니다.
    • default-http-backend는 Kubernetes 서비스 이름입니다.
    • 80은 호스트 포트입니다.
    • HEALTHY는 백엔드가 정상임을 나타냅니다.

다음으로 gcloud를 사용하여 my-service와 연결된 백엔드 서비스를 검사합니다. "drainingTimeoutSec""timeoutSec"을 필터링하여 Google Cloud 부하 분산기 제어 영역에서 설정되어 있는지 확인합니다. 예를 들면 다음과 같습니다.

# Optionally, set a variable
export BES=k8s1-27fde173-default-my-service-80-8d4ca500

# Filter for drainingTimeoutSec and timeoutSec
gcloud compute backend-services describe ${BES} --global | grep -e "drainingTimeoutSec" -e "timeoutSec"

출력:

  drainingTimeoutSec: 60
  timeoutSec: 40

출력에서 drainingTimeoutSectimeoutSec을 확인하면 값이 BackendConfig를 통해 올바르게 설정되었는지 확인할 수 있습니다.

삭제

계정에서 원치 않는 비용이 발생하지 않도록 하려면 이 연습용으로 만든 Kubernetes 객체를 삭제합니다.

kubectl delete ingress my-ingress
kubectl delete service my-service
kubectl delete backendconfig my-backendconfig
kubectl delete deployment my-deployment

BackendConfig 제한사항

BackendConfig에는 다음과 같은 제한사항이 있습니다.

  • 여러 인그레스 객체가 (서비스, 포트)를 참조하더라도 (서비스, 포트) 쌍 하나만 BackendConfig를 한 개만 사용할 수 있습니다. 즉, 동일한 (서비스, 포트)를 참조하는 모든 인그레스 객체는 Google Cloud Armor, Cloud IAP, Cloud CDN의 동일한 구성을 사용해야 합니다.
  • 동일한 HTTP(S) 부하 분산 백엔드 서비스에는 IAP 및 Cloud CDN을 사용 설정할 수 없습니다. 즉, 동일한 BackendConfig에서 IAP 및 Cloud CDN을 모두 구성할 수 없습니다.
  • BackendConfig와의 상호작용하려면 kubectl 1.7 이상을 사용해야 합니다.

FrontendConfig 또는 BackendConfig에 지정된 구성 삭제

인그레스 기능을 취소하려면 FrontendConfig CRD나 BackendConfig CRD에서 기능 구성을 명시적으로 중지해야 합니다. 인그레스 컨트롤러는 이러한 CRD에 지정된 구성만 조정합니다.

이전에 사용 설정된 구성을 삭제하거나 중지하려면 필드 유형에 따라 필드 값을 빈 문자열("") 또는 불리언 값 false로 설정합니다.

다음 BackendConfig 매니페스트는 Google Cloud Armor 보안 정책과 Cloud CDN을 중지합니다.

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: my-backendconfig
spec:
  cdn:
    enabled: false
  securityPolicy:
    name: ""

FrontendConfig 또는 BackendConfig 삭제

FrontendConfig

FrontendConfig를 삭제하려면 다음 단계를 따르세요.

  1. 인그레스 매니페스트의 networking.gke.io/v1beta1.FrontendConfig 주석에서 FrontendConfig 이름을 삭제합니다.

  2. 변경된 인그레스 매니페스트를 클러스터에 적용합니다. 예를 들어 kubectl apply를 사용합니다.

  3. FrontendConfig를 삭제합니다. 예를 들어 kubectl delete frontendconfig config my-frontendconfig를 사용합니다.

BackendConfig

BackedConfig를 삭제하려면 다음 단계를 따르세요.

  1. 서비스 매니페스트에 있는 cloud.google.com/backend-config 주석에서 BackendConfig 이름을 삭제합니다.

  2. 변경된 서비스 매니페스트를 클러스터에 적용합니다. 예를 들어 kubectl apply를 사용합니다.

  3. BackendConfig를 삭제합니다. 예를 들어 kubectl delete backendconfig my-backendconfig를 사용합니다.

문제 해결

인그레스 진단 도구를 사용하여 일반적인 구성 오류를 감지할 수 있습니다. 또한 모든 상태 확인이 올바르게 구성되었는지 확인해야 합니다.

BackendConfig를 찾을 수 없음

이 오류는 서비스 포트의 BackendConfig가 서비스 주석에 지정되었지만 실제 BackendConfig 리소스를 찾을 수 없을 때 발생합니다.

Kubernetes 이벤트를 평가하려면 다음 명령어를 실행합니다.

kubectl get event

다음 출력 예시는 BackendConfig를 찾을 수 없음을 나타냅니다.

KIND    ... SOURCE
Ingress ... loadbalancer-controller

MESSAGE
Error during sync: error getting BackendConfig for port 80 on service "default/my-service":
no BackendConfig for service port exists

이 문제를 해결하려면 잘못된 네임스페이스에 BackendConfig 리소스를 생성하지 않았거나 서비스 주석에서 참조 철자를 잘못 쓰지 않았는지 확인합니다.

인그레스 보안 정책을 찾을 수 없음

인그레스 객체가 생성된 다음 보안 정책이 LoadBalancer 서비스와 올바르게 연결되지 않은 경우, Kubernetes 이벤트에서 구성 실수가 있는지 확인합니다. BackendConfig에서 존재하지 않는 보안 정책을 지정하면 경고 이벤트가 주기적으로 발생합니다.

Kubernetes 이벤트를 평가하려면 다음 명령어를 실행합니다.

kubectl get event

다음 출력 예시는 보안 정책을 찾을 수 없음을 나타냅니다.

KIND    ... SOURCE
Ingress ... loadbalancer-controller

MESSAGE
Error during sync: The given security policy "my-policy" does not exist.

이 문제를 해결하려면 BackendConfig에서 올바른 보안 정책 이름을 지정합니다.

GKE에서 워크로드 확장 중에 NEG로 500 시리즈 오류 해결

증상

부하 분산에 GKE 프로비저닝 NEG를 사용하면 워크로드 축소 중에 서비스에 502 또는 503 오류가 발생할 수 있습니다. 기존 연결이 종료되기 전에 포드가 종료되면 502 오류가 발생하고 트래픽이 삭제된 포드로 전달되면 503 오류가 발생합니다.

이 문제는 게이트웨이, 인그레스, 독립형 NEG를 포함하여 NEG를 사용하는 GKE 관리형 부하 분산 제품을 사용하는 경우 클러스터에 영향을 줄 수 있습니다. 워크로드를 자주 확장하면 클러스터가 영향을 받을 위험이 커집니다.

진단:

엔드포인트를 드레이닝하지 않고 Kubernetes에서 포드를 삭제하고 먼저 NEG에서 제거하면 500 시리즈 오류가 발생합니다. 포드 종료 중에 문제가 발생하지 않도록 하려면 작업 순서를 고려해야 합니다. 다음 이미지에서는 BackendService Drain Timeout이 설정되지 않았을 때와 BackendConfig를 사용하여 BackendService Drain Timeout이 설정되었을 때의 시나리오를 보여줍니다.

시나리오 1: BackendService Drain Timeout이 설정되지 않음

다음 이미지는 BackendService Drain Timeout이 설정되지 않은 시나리오를 보여줍니다.

BackendService 드레이닝 제한 시간이 설정되지 않음

시나리오 2: BackendService Drain Timeout이 설정됨

다음 이미지는 BackendService Drain Timeout이 설정된 시나리오를 보여줍니다.

BackendService 드레이닝 제한 시간이 설정됨

500 시리즈 오류가 발생하는 정확한 시간은 다음 요인에 따라 달라집니다.

  • NEG API 분리 지연 시간: NEG API 분리 지연 시간은 Google Cloud에서 분리 작업이 완료되는 데 걸리는 현재 시간을 나타냅니다. 이는 부하 분산기 유형 및 특정 영역 등 Kubernetes 외부의 다양한 요인에 영향을 받습니다.

  • 드레이닝 지연 시간: 드레이닝 지연 시간은 부하 분산기가 시스템의 특정 부분에서 트래픽을 다른 곳으로 전달하기 시작하는 데 걸리는 시간을 나타냅니다. 드레이닝이 시작되면 부하 분산기가 엔드포인트에 새 요청을 더 이상 전송하지 않지만, 드레이닝 트리거에 대한 지연 시간(드레이닝 지연 시간)이 여전히 남아 있습니다. 이로 인해 포드가 더 이상 존재하지 않으면 임시 503 오류가 발생할 수 있습니다.

  • 상태 점검 구성: 분리 작업이 완료되지 않더라도 부하 분산기가 엔드포인트에 요청 전송을 중지하도록 신호를 보낼 수 있으므로 보다 민감한 상태 점검 임곗값은 503 오류 기간을 완화합니다.

  • 종료 유예 기간: 종료 유예 기간은 포드가 종료되기까지 주어지는 최대 시간을 결정합니다. 하지만 종료 유예 기간이 완료되기 전에 포드가 종료될 수 있습니다. 포드가 이 기간보다 오래 걸리면 이 기간이 끝날 때 포드가 강제로 종료됩니다. 이는 포드의 설정이며 워크로드 정의에서 구성해야 합니다.

잠재적인 해결 방법:

이러한 5XX 오류를 방지하려면 다음 설정을 적용하세요. 제한 시간 값은 제안적이며, 특정 애플리케이션에 맞게 조정해야 할 수도 있습니다. 다음 섹션에서는 맞춤설정 프로세스를 안내합니다.

다음 이미지는 preStopHook를 사용하여 포드를 활성 상태로 유지하는 방법을 보여줍니다.

BackendService 드레이닝 제한 시간이 설정됨

500 시리즈 오류를 방지하려면 다음 단계를 수행합니다.

  1. 서비스의 BackendService Drain Timeout을 1분으로 설정합니다.

  2. 포드에서 terminationGracePeriod를 확장합니다.

    포드의 terminationGracePeriodSeconds를 3.5분으로 설정합니다. 권장 설정과 함께 사용하면 포드의 엔드포인트가 NEG에서 삭제된 후 포드가 30~45초 동안 단계적으로 종료되도록 합니다. 단계적 종료에 더 많은 시간이 필요한 경우 유예 기간을 연장하거나 제한 시간 맞춤설정 섹션에 설명된 안내를 따를 수 있습니다.

    다음 BackendConfig 매니페스트는 연결 드레이닝 제한 시간을 210초(3.5분)로 지정합니다.

    apiVersion: v1
    kind: BackendConfig
    metadata:
      name: my-backendconfig
    spec:
      terminationGracePeriodSeconds: 210
      containers:
      - name: my-app
        image: my-app-image:latest
        ports:
        - containerPort: 80
    
  3. 모든 컨테이너에 preStopHook를 적용합니다.

    포드의 엔드포인트가 부하 분산기에서 드레이닝되고 엔드포인트가 NEG에서 삭제되는 동안 포드가 120초 동안 활성 상태로 유지되는 preStopHook를 적용합니다.

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-pod
    spec:
      containers:
      - name: my-app
        # Container configuration details...
        lifecycle:
          preStop:
            exec:
              command: ["/bin/sh", "-c", "sleep 120s"]
    

제한 시간 맞춤설정

포드 연속성을 보장하고 500 시리즈 오류를 방지하기 위해서는 NEG에서 엔드포인트가 삭제될 때까지 포드가 활성 상태여야 합니다. 특히 502 및 503 오류를 방지하려면 제한 시간과 preStopHook의 조합을 구현하는 것이 좋습니다.

종료 프로세스 중 포드를 더 오래 활성 상태로 유지하려면 preStopHook를 포드에 추가합니다. 포드가 종료되도록 신호를 받기 전에 preStopHook를 실행하여 해당 엔드포인트가 NEG에서 삭제될 때까지 포드를 계속 유지하는 데 preStopHook를 사용할 수 있습니다.

종료 프로세스 중에 포드가 활성 상태로 유지되는 기간을 확장하려면 다음과 같이 포드 구성에 preStopHook를 삽입합니다.

spec:
  containers:
  - name: my-app
    ...
    lifecycle:
      preStopHook:
        exec:
          command: ["/bin/sh", "-c", "sleep <latency time>"]

제한 시간 및 관련 설정을 구성하여 워크로드 축소 중에 포드의 단계적 종료를 관리할 수 있습니다. 특정 사용 사례에 따라 제한 시간을 조정할 수 있습니다. 더 긴 제한 시간으로 시작하고 필요에 따라 기간을 줄이는 것이 좋습니다. 다음과 같은 방법으로 제한 시간 관련 매개변수와 preStopHook를 구성하여 제한 시간을 맞춤설정할 수 있습니다.

백엔드 서비스 드레이닝 제한 시간

Backend Service Drain Timeout 매개변수는 기본적으로 설정 해제되며 효과가 없습니다. Backend Service Drain Timeout 매개변수를 설정하고 활성화하면 부하 분산기가 엔드포인트에 대한 새 요청 라우팅을 중지하고 기존 연결을 종료하기 전에 제한 시간을 기다립니다.

인그레스와 함께 BackendConfig를 사용하고, 게이트웨이와 GCPBackendPolicy를 사용하거나 독립형 NEG와 함께 BackendService에서 수동으로 Backend Service Drain Timeout 매개변수를 설정할 수 있습니다. 제한 시간은 요청을 처리하는 데 걸리는 시간보다 1.5~2배 더 길어야 합니다. 이렇게 하면 드레이닝이 시작되기 직전에 요청이 수신되면 제한 시간이 끝나기 전에 완료됩니다. Backend Service Drain Timeout 매개변수를 0보다 큰 값으로 설정하면 삭제가 예약된 엔드포인트로 새 요청이 전송되지 않으므로 503 오류가 완화됩니다. 이 제한 시간을 적용하려면 드레이닝이 진행되는 동안 포드가 활성 상태를 유지하도록 preStopHook와 함께 사용해야 합니다. 이 조합을 사용하지 않으면 완료되지 않은 기존 요청에 502 오류가 수신됩니다.

preStopHook 시간

preStopHook는 포드가 종료되기 전에 NEG에서 적절한 연결 드레이닝과 엔드포인트 삭제를 수행할 수 있도록 드레이닝 지연 시간과 백엔드 서비스 드레이닝 제한 시간 모두에 대해 포드 종료를 충분히 지연시켜야 합니다.

최적의 결과를 얻으려면 preStopHook 실행 시간이 Backend Service Drain Timeout 및 드레이닝 지연 시간의 합계보다 작거나 같아야 합니다.

다음 수식을 사용하여 계산할 수 있습니다.

preStopHook >= Backend Service Drain Timeout + Drain Latency

드레이닝 지연 시간은 1분으로 설정하는 것이 좋습니다. 오류가 500개 지속되면 총 발생 기간을 추정하고 해당 시간을 지연 시간에 두 배로 추가합니다. 그러면 포드가 서비스에서 삭제되기 전에 정상적으로 드레이닝할 수 있는 충분한 시간이 확보됩니다. 특정 사용 사례에 너무 길면 이 값을 조정할 수 있습니다.

또는 포드의 삭제 타임스탬프와 Cloud 감사 로그의 NEG에서 엔드포인트가 삭제된 타임스탬프를 검사하여 타이밍을 예측할 수 있습니다.

종료 유예 기간 매개변수

preStopHook가 완료되고 포드가 단계적 종료를 완료할 수 있도록 terminationGracePeriod 매개변수를 구성해야 합니다.

기본적으로 terminationGracePeriod를 명시적으로 설정하지 않으면 30초입니다. 다음 수식을 사용하여 최적의 terminationGracePeriod를 계산할 수 있습니다.

terminationGracePeriod >= preStopHook Time + Pod shutdown time

다음과 같이 포드 구성 내에서 terminationGracePeriod를 정의합니다.

  spec:
    terminationGracePeriodSeconds: <terminationGracePeriod>
    containers:
    - name: my-app
      ...
    ...

내부 인그레스 리소스를 만들 때 NEG를 찾을 수 없음

GKE에서 내부 인그레스를 만들 때 다음 오류가 발생할 수 있습니다.

Error syncing: error running backend syncing routine: googleapi: Error 404: The resource 'projects/PROJECT_ID/zones/ZONE/networkEndpointGroups/NEG' was not found, notFound

내부 애플리케이션 부하 분산기용 인그레스에 백엔드로 네트워크 엔드포인트 그룹(NEG)이 필요하기 때문에 이 오류가 발생합니다.

네트워크 정책이 사용 설정된 공유 VPC 환경 또는 클러스터에서 서비스 매니페스트에 cloud.google.com/neg: '{"ingress": true}' 주석을 추가합니다.

504 게이트웨이 시간 초과: 업스트림 요청 시간 제한

GKE의 내부 인그레스에서 서비스에 액세스할 때 다음 오류가 발생할 수 있습니다.

HTTP/1.1 504 Gateway Timeout
content-length: 24
content-type: text/plain

upsteam request timeout

이 오류는 내부 애플리케이션 부하 분산기로 전송된 트래픽이 프록시 전용 서브넷 범위의 Envoy 프록시에서 프록시되기 때문에 발생합니다.

프록시 전용 서브넷 범위로부터 트래픽을 허용하려면 서비스의 targetPort방화벽 규칙을 만듭니다.

오류 400: 'resource.target' 필드 값이 잘못됨

GKE의 내부 인그레스에서 서비스에 액세스할 때 다음 오류가 발생할 수 있습니다.

Error syncing:LB_NAME does not exist: googleapi: Error 400: Invalid value for field 'resource.target': 'https://www.googleapis.com/compute/v1/projects/PROJECT_NAME/regions/REGION_NAME/targetHttpProxies/LB_NAME. A reserved and active subnetwork is required in the same region and VPC as the forwarding rule.

이 문제를 해결하려면 프록시 전용 서브넷을 생성합니다.

동기화 중 오류: 부하 분산기 동기화 루틴 실행 중 오류: loadbalancer가 존재하지 않음

GKE 제어 영역이 업그레이드되거나 인그레스 객체를 수정할 때 다음 오류 중 하나가 발생할 수 있습니다.

"Error during sync: error running load balancer syncing routine: loadbalancer
INGRESS_NAME does not exist: invalid ingress frontend configuration, please
check your usage of the 'kubernetes.io/ingress.allow-http' annotation."

또는

Error during sync: error running load balancer syncing routine: loadbalancer LOAD_BALANCER_NAME does not exist:
googleapi: Error 400: Invalid value for field 'resource.IPAddress':'INGRESS_VIP'. Specified IP address is in-use and would result in a conflict., invalid

이 문제를 해결하려면 다음 단계를 시도해 보세요.

  • 인그레스 매니페스트의 tls 섹션에 hosts 필드를 추가한 후 인그레스를 삭제합니다. GKE가 사용되지 않는 인그레스 리소스를 삭제할 때까지 5분 정도 기다립니다. 그런 다음 인그레스를 다시 만듭니다. 자세한 내용은 인그레스 객체의 호스트 필드를 참조하세요.
  • 인그레스의 변경사항을 되돌립니다. 그런 다음 주석 또는 Kubernetes 보안 비밀을 사용하여 인증서를 추가합니다.

알려진 문제

V1 인그레스 이름 지정 스키마에 따라 HTTPS 리디렉션을 사용 설정할 수 없음

GKE 버전 1.16.8-gke.12 이하에서 생성된 GKE 인그레스 리소스에 HTTPS 리디렉션을 사용 설정할 수 없습니다. HTTPS 리디렉션을 사용 설정하려면 먼저 인그레스를 다시 만들어야 합니다. 그렇지 않으면 오류 이벤트가 생성되고 인그레스가 동기화되지 않습니다.

오류 이벤트 메시지는 다음과 비슷합니다.

Error syncing: error running load balancer syncing routine: loadbalancer lb-name does not exist: ensureRedirectUrlMap() = error: cannot enable HTTPS Redirects with the V1 Ingress naming scheme. Please recreate your ingress to use the newest naming scheme.

BackendConfig에서 Google Cloud Armor 보안 정책 필드가 삭제됨

해당 서비스에서 활성 Google Cloud Armor 보안 정책을 삭제하는 v1beta1 API를 사용하여 BackendConfig 리소스를 업데이트할 때 알려진 문제가 있습니다. 이 문제는 다음 GKE 버전에 영향을 줍니다.

  • 1.18.19-gke.1400 to 1.18.20-gke.5099
  • 1.19.10-gke.700 to 1.19.14-gke.299
  • 1.20.6-gke.700 to 1.20.9-gke.899

BackendConfig를 통해 인그레스 게이트웨이에서 Google Cloud Armor를 구성하지 않으면 이 문제가 클러스터에 영향을 주지 않습니다.

BackendConfig를 통해 Google Cloud Armor를 구성하는 GKE 클러스터의 경우 v1 API를 사용하여 BackendConfig 리소스만 업데이트하는 것이 좋습니다. v1beta1 BackendConfig 리소스를 사용하여 클러스터에 BackendConfig를 적용하면 참조하는 서비스에서 Google Cloud Armor 보안 정책이 삭제됩니다.

이 문제를 완화하려면 v1 BackendConfig API를 사용하여 BackendConfig만 업데이트합니다. v1 BackendConfig에서는 v1beta1과 동일한 모든 필드를 지원하고 브레이킹 체인지를 만들지 않으므로 API 필드를 투명하게 업데이트할 수 있습니다. 활성 BackendConfig 매니페스트의 apiVersion 필드를 cloud.google.com/v1로 바꾸고 cloud.google.com/v1beta1를 사용하지 마세요. 다음 샘플 매니페스트에서는 v1 API를 사용하는 BackendConfig 리소스를 설명합니다.

  apiVersion: cloud.google.com/v1
  kind: BackendConfig
  metadata:
    name: my-backend-config
  spec:
    securityPolicy:
      name: "ca-how-to-security-policy"

BackendConfig 리소스를 정기적으로 업데이트하는 CI/CD 시스템 또는 도구가 있는 경우 해당 시스템에서 cloud.google.com/v1 API 그룹을 사용하도록 유의하세요.

BackendConfig가 이미 v1beta1 API로 업데이트되었으면 Google Cloud Armor 보안 정책이 삭제되었을 수 있습니다. 다음 명령어를 실행하면 삭제되었는지 확인할 수 있습니다.

kubectl get backendconfigs -A -o json | jq -r '.items[] | select(.spec.securityPolicy == {}) | .metadata | "\(.namespace)/\(.name)"'

응답에서 출력을 반환하는 경우 이 문제가 클러스터에 영향을 미칩니다. 이 명령어 출력에서 문제가 영향을 미치는 BackendConfig 리소스(<namespace>/<name>) 목록을 반환합니다. 출력이 비어 있으면 문제가 발생한 후 BackendConfig가 v1beta1 API를 통해 업데이트되지 않습니다. 이후 BackendConfig 업데이트 시에는 v1만 사용해야 합니다.

Google Cloud Armor 보안 정책이 삭제된 경우 다음 Logging 쿼리를 사용하여 삭제 시점을 확인할 수 있습니다.

resource.type="gce_backend_service"
protoPayload.methodName="v1.compute.backendServices.setSecurityPolicy"
protoPayload.authenticationInfo.principalEmail:"container-engine-robot.iam.gserviceaccount.com"
protoPayload.response.status = "RUNNING"
NOT protoPayload.authorizationInfo.permission:"compute.securityPolicies.use"

영향을 받은 클러스터가 있으면 v1 API를 사용하는 BackendConfig 리소스 업데이트를 푸시하여 문제를 해결할 수 있습니다.

이 문제를 패치하고 v1beta1 BackendConfig 리소스를 안전하게 사용할 수 있게 해주는 다음 업데이트된 버전 중 하나로 GKE 제어 영역을 업그레이드합니다.

  • 1.18.20-gke.5100 이상
  • 1.19.14-gke.300 이상
  • 1.20.9-gke.900 이상

다음 단계