Google Kubernetes Engine(GKE)의 인그레스에서 문제가 발생하면 외부 또는 내부 트래픽이 서비스에 도달하지 못할 수 있습니다.
이 문서에서는 인그레스 클래스, 고정 IP 주석, 인증서 키 크기, 네트워크 등급과의 상호작용과 관련된 오류의 해결 방법을 설명합니다.
이 정보는 GKE에서 인그레스를 사용하여 노출된 애플리케이션을 배포하고 관리하는 플랫폼 관리자, 운영자, 애플리케이션 개발자를 대상으로 합니다. Google Cloud 콘텐츠에서 참조하는 일반적인 역할과 예시 태스크에 대한 자세한 내용은 일반 GKE 사용자 역할 및 태스크를 참조하세요.
잘못된 인그레스 클래스 주석
증상
인그레스를 만들 때 다음 오류가 표시될 수 있습니다.
Missing one or more resources. If resource creation takes longer than expected, you might have an invalid configuration.
가능한 원인
인그레스를 만들 때 매니페스트에서 인그레스 클래스를 잘못 구성했을 수 있습니다.
해결 방법
인그레스 클래스를 지정하려면 kubernetes.io/ingress.class 주석을 사용해야 합니다. spec.ingressClassName을 사용하여 GKE 인그레스를 지정할 수 없습니다.
- 내부 애플리케이션 부하 분산기를 배포하려면
kubernetes.io/ingress.class: gce-internal주석을 사용하세요. - 외부 애플리케이션 부하 분산기를 배포하려면
kubernetes.io/ingress.class: gce주석을 사용하세요.
고정 IP 주소의 주석이 잘못됨
증상
고정 IP 주소를 사용하도록 외부 인그레스를 구성할 때 다음과 같은 오류가 표시될 수 있습니다.
Error syncing to GCP: error running load balancer syncing routine: loadbalancer <Name of load balancer> does not exist: the given static IP name <Static IP> doesn't translate to an existing static IP.
가능한 원인
- 인그레스를 배포하기 전에 고정 외부 IP 주소를 만들지 않았습니다.
- 부하 분산기 유형에 올바른 주석을 사용하고 있지 않습니다.
해결 방법
외부 인그레스를 구성하는 경우 다음 안내를 따르세요.
- 인그레스를 배포하기 전에 고정 외부 IP 주소를 예약하세요.
- 인그레스 리소스에
kubernetes.io/ingress.global-static-ip-name주석을 사용합니다.
내부 인그레스를 구성하는 경우 다음 안내를 따르세요.
- 인그레스를 배포하기 전에 리전 고정 내부 IP 주소를 예약합니다.
- 인그레스 리소스에
kubernetes.io/ingress.regional-static-ip-name주석을 사용합니다.
고정 IP 주소를 이미 사용 중임
증상
내부 또는 외부 인그레스 리소스를 프로비저닝하기 위해 고정 IP 주소를 지정할 때 다음과 같은 오류가 표시될 수 있습니다.
Error syncing to GCP: error running load balancer syncing
routine: loadbalancer <LB name> does not exist:
googleapi: Error 409: IP_IN_USE_BY_ANOTHER_RESOURCE - IP ''<IP address>'' is already being used by another resource.
가능한 원인
이 고정 IP 주소를 이미 다른 리소스에서 사용 중입니다.
HTTP를 중지하고 Google 관리 인증서를 사용할 때 발생하는 오류
증상
Google 관리형 SSL 인증서를 구성하고 인그레스에서 HTTP 트래픽을 중지하면 다음 오류가 표시됩니다.
Error syncing to GCP: error running load balancer syncing
routine: loadbalancer <Load Balancer name> does not exist:
googleapi: Error 404: The resource ''projects/<Project>/global/sslPolicies/<Policy name>' was not found, notFound
가능한 원인
인그레스를 구성할 때 다음 주석을 함께 사용할 수 없습니다.
networking.gke.io/managed-certificates(Google 관리형 인증서를 인그레스에 연결)kubernetes.io/ingress.allow-http: false(HTTP 트래픽 중지)
해결 방법
외부 애플리케이션 부하 분산기가 완전히 프로그래밍된 후에만 HTTP 트래픽을 중지합니다. 인그레스를 업데이트하고 매니페스트에 주석 kubernetes.io/ingress.allow-http: false을 추가할 수 있습니다.
내부 인그레스에 프록시 전용 서브넷이 누락됨
증상
내부 애플리케이션 부하 분산기용 인그레스를 배포할 때 다음 오류가 표시될 수 있습니다.
Error syncing to GCP: error running load balancer syncing routine:
loadbalancer <LB name> does not exist: googleapi: Error 400: Invalid value for field 'resource.target': 'https://www.googleapis.com/compute/v1/projects/<Project ID>/regions/<Region>/targetHttpsProxies/<Target proxy>'.
An active proxy-only subnetwork is required in the same region and VPC as
the forwarding rule.
가능한 원인
인그레스 리소스를 만들기 전에 프록시 전용 서브넷을 만들지 않았습니다. 내부 애플리케이션 부하 분산기에는 프록시 전용 서브넷이 필요합니다.
해결 방법
내부 인그레스를 배포하기 전에 프록시 전용 서브넷을 만듭니다.
SSL 인증서 키가 너무 큼
증상
부하 분산기의 SSL 인증서 키 크기가 너무 크면 다음 오류가 표시될 수 있습니다.
Error syncing to GCP: error running load balancer syncing routine: loadbalancer gky76k70-load-test-trillian-api-ingress-fliismmb does not exist: Cert creation failures - k8s2-cr-gky76k70-znz6o1pfu3tfrguy-f9be3a4abbe573f7 Error:googleapi: Error 400: The SSL key is too large., sslCertificateKeyTooLarge
가능한 원인
Google Cloud 에서는 SSL 인증서 키가 2,048비트로 제한됩니다.
해결 방법
SSL 인증서 키의 크기를 2,048비트 이하로 줄입니다.
표준 등급에서 인그레스를 만드는 중에 발생하는 오류
증상
프로젝트 기본 네트워크 등급이 표준으로 설정된 프로젝트에 인그레스를 배포하면 다음 오류 메시지가 표시됩니다.
Error syncing to GCP: error running load balancer syncing routine: load balancer <LB Name> does not exist: googleapi: Error 400: STANDARD network tier (the project''s default network tier) is not supported: STANDARD network tier is not supported for global forwarding rule., badRequest
해결 방법
프로젝트 기본 네트워크 등급을 프리미엄으로 구성합니다.
k8s-ingress-svc-acct-permission-check-probe에 '찾을 수 없음' 오류가 예상됨
인그레스 컨트롤러는 Google Cloud 프로젝트에서 테스트 리소스를 가져와서 서비스 계정 권한을 주기적으로 확인합니다. 이것은 이름이 k8s-ingress-svc-acct-permission-check-probe인(존재하지 않는) 전역 BackendService의 GET로 표시됩니다. 이 리소스는 일반적으로 존재하지 않으므로, GET 요청이 '찾을 수 없음'을 반환합니다. 이는 예상된 상황이며, 컨트롤러가 승인 문제로 인해 API 호출이 거부되지 않았는지 확인합니다. 동일한 이름으로 BackendService를 만들면 '찾을 수 없음'을 반환하는 대신 GET이 성공합니다.
컨테이너 기반 부하 분산 사용 시 오류
다음 기법을 사용하여 네트워킹 구성을 확인하세요. 다음 섹션에서는 컨테이너 기반 부하 분산과 관련된 구체적인 문제를 해결하는 방법을 설명합니다.
네트워크 엔드포인트 그룹을 나열하는 방법은 부하 분산 문서를 참조하세요.
서비스의
neg-status주석에서 서비스에 해당하는 NEG의 이름과 영역을 확인할 수 있습니다. 다음을 사용하여 서비스 사양을 가져옵니다.kubectl get svc SVC_NAME -o yamlmetadata:annotations:cloud.google.com/neg-status주석에는 서비스의 해당 NEG 이름과 NEG 영역이 있습니다.다음 명령어를 사용하여 NEG에 해당하는 백엔드 서비스의 상태를 확인할 수 있습니다.
gcloud compute backend-services --project PROJECT_NAME \ get-health BACKEND_SERVICE_NAME --global백엔드 서비스 이름은 NEG 이름과 동일합니다.
서비스의 이벤트 로그를 인쇄하려면 다음 명령어를 실행합니다.
kubectl describe svc SERVICE_NAME서비스의 이름 문자열에는 해당 GKE 서비스의 이름과 네임스페이스가 포함됩니다.
별칭 IP로 클러스터를 만들 수 없음
- 증상
별칭 IP를 사용하여 클러스터를 만들려고 할 때 다음과 같은 오류가 나타날 수 있습니다.
ResponseError: code=400, message=IP aliases cannot be used with a legacy network.- 가능한 원인
이전 네트워크도 사용하는 별칭 IP로 클러스터를 만들려고 하면 이 오류가 발생합니다.
- 해결 방법
별칭 IP와 기존 네트워크가 동시에 사용 설정된 상태로 클러스터를 만들지 않아야 합니다. 별칭 IP 사용에 대한 자세한 내용은 VPC 기반 클러스터 만들기를 참조하세요.
트래픽이 엔드포인트에 도달하지 않음
- 증상
- 502/503 오류가 표시되거나 연결이 거부됩니다.
- 가능한 원인
새 엔드포인트는 일반적으로 부하 분산기에 연결한 후에 도달 가능합니다. 단, 엔드포인트가 상태 확인에 응답해야 합니다. 트래픽이 엔드포인트에 도달할 수 없으면 502 오류가 발생하거나 연결이 거부될 수 있습니다.
502 오류 및 연결 거부는
SIGTERM을 처리하지 않는 컨테이너로 인해 발생할 수도 있습니다. 컨테이너가 명시적으로SIGTERM을 처리하지 않으면 즉시 종료되고 요청 처리가 중지됩니다. 부하 분산기는 수신 트래픽을 종료된 컨테이너에 계속 전송하므로 오류가 발생합니다.컨테이너 기반 부하 분산기에는 백엔드 엔드포인트가 하나만 있습니다. 순차적 업데이트 중에 이전 엔드포인트는 새 엔드포인트가 프로그래밍되기 전에 디프로그래밍됩니다.
컨테이너 기반 부하 분산기가 프로비저닝된 후 백엔드 포드가 새로운 영역에 처음으로 배포됩니다. 부하 분산기 인프라는 영역에 최소 하나 이상의 엔드포인트가 있는 경우 한 영역에서 프로그래밍됩니다. 새 엔드포인트가 영역에 추가되면 부하 분산기 인프라가 프로그래밍되어 서비스가 중단됩니다.
- 해결 방법
SIGTERM을 처리하고 종료 유예 기간(기본적으로 30초) 동안 요청에 계속 응답하도록 컨테이너를 구성합니다.SIGTERM을 수신할 때 상태 확인을 실패하도록 포드를 구성합니다. 그러면 엔드포인트 디프로그래밍이 진행되는 동안 부하 분산기가 포드로 트래픽 전송을 중지합니다.애플리케이션이 정상적으로 종료되지 않고
SIGTERM수신 시 요청에 응답하지 않으면 엔드포인트의 디프로그래밍이 진행되는 동안 사전 중지 후크를 사용하여SIGTERM을 처리하고 트래픽을 계속 처리할 수 있습니다.lifecycle: preStop: exec: # if SIGTERM triggers a quick exit; keep serving traffic instead command: ["sleep","60"]포드 종료 문서를 참조하세요.
부하 분산기 백엔드에 인스턴스가 한 개만 있다면 새 인스턴스가 완전히 프로그래밍되기 전에 유일한 인스턴스가 손상되지 않도록 출시 전략을 구성하세요.
Deployment워크로드에서 관리하는 애플리케이션 포드의 경우,0과 동일한maxUnavailable매개변수를 사용하여 롤아웃 전략을 구성하면 됩니다.strategy: rollingUpdate: maxSurge: 1 maxUnavailable: 0엔드포인트에 도달하지 않는 트래픽 문제를 해결하려면 방화벽 규칙이
130.211.0.0/22및35.191.0.0/16범위에서 엔드포인트로 들어오는 TCP 트래픽을 허용하는지 확인합니다. 자세한 내용은 Cloud Load Balancing 문서의 상태 점검 추가를 참조하세요.프로젝트의 백엔드 서비스를 확인합니다. 관련 백엔드 서비스의 이름 문자열에는 해당 GKE 서비스의 이름 및 네임스페이스가 포함됩니다.
gcloud compute backend-services list백엔드 서비스에서 백엔드 상태를 검색합니다.
gcloud compute backend-services get-health BACKEND_SERVICE_NAME모든 백엔드가 비정상이라면 방화벽, 인그레스 또는 서비스가 잘못 구성되었을 수 있습니다.
일부 백엔드가 잠깐 동안 비정상이라면 네트워크 프로그래밍 지연 시간이 원인일 수 있습니다.
일부 백엔드가 백엔드 서비스 목록에 나타나지 않으면 프로그래밍 지연 시간이 원인일 수 있습니다. 이것은 다음 명령어를 실행하여 확인할 수 있습니다. 여기서
NEG_NAME는 백엔드 서비스의 이름입니다. (NEG와 백엔드 서비스는 이름이 같습니다).gcloud compute network-endpoint-groups list-network-endpoints NEG_NAME예상되는 모든 엔드포인트가 NEG에 있는지 확인하세요.
컨테이너 기반 부하 분산기에서 소수의 백엔드 (예: 포드 1개)가 선택된 경우 복제본 수를 늘리고 GKE 클러스터가 사용하는 모든 영역에 백엔드 포드를 배포하는 것이 좋습니다. 이렇게 하면 기본 부하 분산기 인프라가 완전히 프로그래밍됩니다. 그렇지 않으면 백엔드 포드를 단일 영역으로 제한하는 것이 좋습니다.
엔드포인트에 대한 네트워크 정책을 구성하는 경우 프록시 전용 서브넷의 인그레스가 허용되는지 확인합니다.
출시 중단
- 증상
- 업데이트된 배포 롤아웃이 중단되고 최신 복제본 수가 선택한 복제본 수와 일치하지 않습니다.
- 가능한 원인
배포 상태 확인이 실패합니다. 컨테이너 이미지가 손상되었거나 상태 확인이 잘못 구성되었을 수 있습니다. Pod의 순차적 교체는 새로 시작된 Pod가 Pod 준비 게이트를 통과할 때까지 대기합니다. 이는 Pod가 부하 분산기 상태 확인에 응답하는 경우에만 발생합니다. Pod가 응답하지 않거나 상태 확인이 잘못 구성된 경우 준비 게이트 조건을 충족할 수 없으며 롤아웃을 계속할 수 없습니다.
kubectl1.13 이상을 사용하는 경우 다음 명령어를 사용하여 포드의 준비 게이트 상태를 확인할 수 있습니다.kubectl get pod POD_NAME -o wideREADINESS GATES열을 확인합니다.kubectl1.12 이하에는 이 열이 존재하지 않습니다.READY상태로 표시된 포드에서는 준비 게이트가 실패했을 수 있습니다. 이를 확인하려면 다음 명령어를 사용합니다.kubectl get pod POD_NAME -o yaml준비 게이트와 해당 상태가 출력에 나열됩니다.
- 해결 방법
배포 포드 사양의 컨테이너 이미지가 제대로 작동하고 있고 상태 확인에 응답할 수 있는지 확인합니다. 상태 확인이 올바르게 구성되어 있는지 확인합니다.
성능 저하 모드 오류
- 증상
GKE 버전 1.29.2-gke.1643000부터는 NEG가 업데이트될 때 로그 탐색기에서 서비스에 대한 다음과 같은 경고가 표시될 수 있습니다.
Entering degraded mode for NEG <service-namespace>/<service-name>-<neg-name>... due to sync err: endpoint has missing nodeName field- 가능한 원인
이러한 경고는
EndpointSlice객체를 기반으로 NEG 업데이트 중 GKE에서 엔드포인트 구성 오류가 감지되어 성능 저하 모드라고 부르는 보다 심도 깊은 계산 프로세스가 트리거되었음을 나타냅니다. GKE는 구성 오류를 수정하거나 NEG 업데이트에서 잘못된 엔드포인트를 제외하는 방식으로 최선에 따라 NEG 업데이트를 계속합니다.일반적인 오류는 다음과 같습니다.
endpoint has missing pod/nodeName fieldendpoint corresponds to an non-existing pod/nodeendpoint information for attach/detach operation is incorrect
- 해결 방법
일반적으로 이러한 이벤트는 일시적인 상태로 인해 발생하며 자체적으로 해결됩니다. 그러나 커스텀
EndpointSlice객체에서 구성 오류로 인해 발생한 이벤트는 해결되지 않은 상태로 유지됩니다. 구성 오류를 이해하기 위해서는 서비스에 해당하는EndpointSlice객체를 검사합니다.kubectl get endpointslice -l kubernetes.io/service-name=<service-name>이벤트의 오류를 기준으로 각 엔드포인트를 검증합니다.
이 문제를 해결하려면
EndpointSlice객체를 수동으로 수정해야 합니다. 이 업데이트는 NEG가 다시 업데이트되도록 트리거합니다. 구성 오류가 더 이상 없으면 다음과 비슷한 출력이 표시됩니다.NEG <service-namespace>/<service-name>-<neg-name>... is no longer in degraded mode
Google 관리 SSL 인증서 사용 시 오류
이 섹션에서는 Google 관리 인증서로 문제를 해결하는 방법에 대한 정보를 제공합니다.
ManagedCertificate 및 인그레스 리소스의 이벤트 확인
허용된 인증서 수를 초과하면 TooManyCertificates 이유가 있는 이벤트가 ManagedCertificate에 추가됩니다. 다음 명령어를 사용하여 ManagedCertificate 객체의 이벤트를 확인할 수 있습니다.
kubectl describe managedcertificate CERTIFICATE_NAME
CERTIFICATE_NAME을 ManagedCertificate의 이름으로 바꿉니다.
존재하지 않는 ManagedCertificate를 인그레스에 연결하면 MissingCertificate 이유가 포함된 이벤트가 인그레스에 추가됩니다. 다음 명령어를 사용하여 인그레스의 이벤트를 확인할 수 있습니다.
kubectl describe ingress INGRESS_NAME
INGRESS_NAME을 인그레스의 이름으로 바꿉니다.
도메인이 여러 부하 분산기의 IP 주소로 확인될 경우 관리형 인증서가 프로비저닝되지 않음
도메인이 여러 부하 분산기(여러 인그레스 객체)의 IP 주소로 확인되면 ManagedCertificate 객체 한 개를 만들고 모든 인그레스 객체에 연결해야 합니다. 대신 여러 ManagedCertificate 객체를 만들고 개별 인그레스에 각각 연결하면 인증 기관이 도메인의 소유권을 확인하지 못하고 일부 인증서가 프로비저닝되지 않을 수 있습니다. 확인을 성공하려면 도메인이 확인되는 모든 IP 주소 아래에 인증서가 표시되어야 합니다.
특히 도메인이 다른 인그레스 객체로 구성된 IPv4 및 IPv6 주소로 확인되면 ManagedCertificate 객체 한 개를 만들고 두 인그레스 모두에 연결해야 합니다.
Google 관리 인증서와 인그레스 간의 통신 중단
관리형 인증서는 ingress.gcp.kubernetes.io/pre-shared-cert 주석을 사용하여 인그레스와 통신합니다. 예를 들어 다음 경우에는 이 통신을 중단할 수 있습니다.
ingress.gcp.kubernetes.io/pre-shared-cert주석을 삭제하는 자동화 프로세스를 실행합니다.- 인그레스 스냅샷을 저장한 후 스냅샷에서 인그레스를 삭제하고 복원합니다. 그동안
ingress.gcp.kubernetes.io/pre-shared-cert주석에 나열된SslCertificate리소스가 삭제되었을 수 있습니다. 인그레스에 연결된 인증서가 없으면 인그레스가 작동하지 않습니다.
Google 관리 인증서와 인그레스 간의 통신이 중단된 경우 ingress.gcp.kubernetes.io/pre-shared-cert 주석의 콘텐츠를 삭제하고 시스템이 조정될 때까지 기다립니다. 반복을 방지하려면 주석이 의도치 않게 수정되거나 삭제되지 않도록 해야 합니다.
Google 관리 인증서를 만들 때 검증 오류
ManagedCertificate 정의는 ManagedCertificate 객체가 생성되기 전에 검증됩니다. 검증이 실패하면 ManagedCertificate 객체가 생성되지 않고 오류 메시지가 출력됩니다. 아래에서는 여러 오류 메시지와 원인을 설명합니다.
spec.domains in body should have at most 100 items
ManagedCertificate 매니페스트가 spec.domains 필드에 도메인을 100개 넘게 나열합니다. Google 관리 인증서는 도메인을 최대 100개까지만 지원합니다.
spec.domains in body should match '^(([a-zA-Z0-9]+|[a-zA-Z0-9][-a-zA-Z0-9]*[a-zA-Z0-9])\.)+[a-zA-Z][-a-zA-Z0-9]*[a-zA-Z0-9]\.?$'
spec.domains 필드에 지정한 도메인 이름 또는 와일드 카드 도메인 이름이 잘못되었습니다. ManagedCertificate 객체는 와일드 카드 도메인(예: *.example.com)을 지원하지 않습니다.
spec.domains in body should be at most 63 chars long
지정한 도메인 이름이 너무 깁니다. Google 관리 인증서에서 지원하는 도메인 이름은 최대 63자입니다.
Google 관리형 인증서 수동 업데이트
새 도메인의 인증서가 프로비저닝될 때까지 이전 도메인의 인증서가 계속 작동하도록 인증서를 수동으로 업데이트하려면 다음 단계를 따르세요.
- 새 도메인에 대한
ManagedCertificate을 만듭니다. - 쉼표로 구분된 목록을 사용하여
ManagedCertificate이름을 인그레스의networking.gke.io/managed-certificates주석에 추가합니다. 이전 인증서 이름을 삭제하지 마세요. ManagedCertificate이 활성 상태가 될 때까지 기다립니다.- 인그레스에서 이전 인증서를 분리하고 삭제합니다.
ManagedCertificate를 만들면 Google Cloud 에서 Google 관리 SSL 인증서를 만듭니다. 이 인증서를 업데이트할 수 없습니다. ManagedCertificate를 업데이트하면 Google Cloud 에서 Google 관리 SSL 인증서를 삭제하고 다시 만듭니다.
GKE 클러스터의 HTTPS 암호화된 인그레스를 제공하려면 보안 인그레스 예시를 참조하세요.
다음 단계
문서에서 문제 해결 방법을 찾을 수 없으면 지원 받기를 참조하여 다음 주제에 대한 조언을 포함한 추가 도움을 요청하세요.
- Cloud Customer Care에 문의하여 지원 케이스를 엽니다.
- StackOverflow에서 질문하고
google-kubernetes-engine태그를 사용하여 유사한 문제를 검색해 커뮤니티의 지원을 받습니다.#kubernetes-engineSlack 채널에 가입하여 더 많은 커뮤니티 지원을 받을 수도 있습니다. - 공개 Issue Tracker를 사용하여 문제나 기능 요청을 엽니다.