이 페이지에서는 Google Kubernetes Engine(GKE) Autopilot 및 Standard 클러스터의 보안 구성과 관련된 문제를 해결하는 방법을 설명합니다.
RBAC 및 IAM
인증된 IAM 계정이 클러스터 내 작업을 수행하지 못함
다음 문제는 클러스터에서 작업을 수행하려고 하는데 GKE에서 작업을 승인하는 RBAC 정책을 찾을 수 없을 때 발생합니다. GKE는 동일한 권한을 부여하는 IAM 허용 정책을 찾으려고 시도합니다. 이 작업이 실패하면 다음과 유사한 오류 메시지가 표시됩니다.
Error from server (Forbidden): roles.rbac.authorization.k8s.io is forbidden:
User "example-account@example-project.iam.gserviceaccount.com" cannot list resource "roles" in
API group "rbac.authorization.k8s.io" in the namespace "kube-system": requires
one of ["container.roles.list"] permission(s).
이 문제를 해결하려면 RBAC 정책을 사용하여 시도한 작업에 대한 권한을 부여합니다. 예를 들어 이전 샘플의 문제를 해결하려면 kube-system
네임스페이스의 roles
객체에서 list
권한이 있는 역할을 부여합니다. 자세한 내용은 역할 기반 액세스 제어를 사용한 클러스터의 작업 승인을 참조하세요.
GKE용 워크로드 아이덴티티 제휴
포드가 Google Cloud에 인증할 수 없음
애플리케이션이 Google Cloud에 인증할 수 없으면 다음 설정이 올바르게 구성되었는지 확인합니다.
GKE 클러스터가 포함된 프로젝트에서 IAM Service Account Credentials API를 사용 설정했는지 확인합니다.
워크로드 아이덴티티 풀이 설정되어 있는지 확인하여 클러스터에서 GKE용 워크로드 아이덴티티 제휴가 사용 설정되었는지 확인합니다.
gcloud container clusters describe CLUSTER_NAME \ --format="value(workloadIdentityConfig.workloadPool)"
CLUSTER_NAME
을 GKE 클러스터 이름으로 바꿉니다.gcloud
의 기본 영역 또는 리전을 아직 지정하지 않았으면 이 명령어를 실행할 때--region
또는--zone
플래그를 지정해야 할 수도 있습니다.애플리케이션이 실행 중인 노드 풀에서 GKE 메타데이터 서버가 구성되었는지 확인합니다.
gcloud container node-pools describe NODEPOOL_NAME \ --cluster=CLUSTER_NAME \ --format="value(config.workloadMetadataConfig.mode)"
다음을 바꿉니다.
NODEPOOL_NAME
을 노드 풀 이름으로 바꿉니다.CLUSTER_NAME
을 GKE 클러스터 이름으로 바꿉니다.
Kubernetes 서비스 계정이 올바르게 주석 처리되었는지 확인합니다.
kubectl describe serviceaccount \ --namespace NAMESPACE KSA_NAME
다음을 바꿉니다.
NAMESPACE
를 GKE 클러스터의 네임스페이스로 바꿉니다.KSA
를 Kubernetes 서비스 계정의 이름으로 바꿉니다.
예상 출력에는 다음과 비슷한 주석이 포함됩니다.
iam.gke.io/gcp-service-account: GSA_NAME@PROJECT_ID.iam.gserviceaccount.com
IAM 서비스 계정이 올바르게 구성되어 있는지 확인합니다.
gcloud iam service-accounts get-iam-policy \ GSA_NAME@GSA_PROJECT.iam.gserviceaccount.com
예상 출력에 다음과 유사한 바인딩이 포함됩니다.
- members: - serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE/KSA_NAME] role: roles/iam.workloadIdentityUser
클러스터 네트워크 정책이 있는 경우 1.21.0-gke.1000 이전 GKE 버전을 실행하는 클러스터에 대해서는 포트
988
에서127.0.0.1/32
로의 이그레스를 허용했고 GKE 버전 1.21.0-gke.1000 이상을 실행하는 클러스터에 대해서는 포트988
에서169.254.169.252/32
로의 이그레스를 허용해야 합니다. GKE Dataplane V2를 실행하는 클러스터의 경우 포트80
의169.254.169.254/32
로 이그레스를 허용해야 합니다.kubectl describe networkpolicy NETWORK_POLICY_NAME
NETWORK_POLICY_NAME
을 GKE 네트워크 정책 이름으로 바꿉니다.
IAM 서비스 계정 액세스가 거부됨
IAM 역할 바인딩을 추가한 직후 포드가 GKE용 워크로드 아이덴티티 제휴로 리소스에 액세스하지 못할 수 있습니다. 액세스 실패는 IAM 허용 정책, 역할 바인딩, Kubernetes 포드와 같은 리소스가 함께 생성되는 배포 파이프라인이나 선언적 Google Cloud 구성에서 발생할 가능성이 더 높습니다. 포드 로그에 다음 오류 메시지가 표시됩니다.
HTTP/403: generic::permission_denied: loading: GenerateAccessToken("SERVICE_ACCOUNT_NAME@PROJECT_ID.iam.gserviceaccount.com", ""): googleapi: Error 403: Permission 'iam.serviceAccounts.getAccessToken' denied on resource (or it may not exist).
이 오류는 IAM의 액세스 변경 전파로 인해 발생할 수 있습니다. 즉, 역할 부여와 같은 액세스 변경사항이 시스템 전체에 전파되는 데 시간이 걸립니다. 역할 부여의 경우 일반적으로 전파되는 데 2분 정도 걸리지만 7분 이상 걸릴 수도 있습니다. 자세한 내용은 액세스 변경 전파를 참조하세요.
이 오류를 해결하려면 포드가 생성된 후 Google Cloud 리소스에 액세스하려고 시도하기 전에 지연 시간을 추가하는 것이 좋습니다.
DNS 변환 문제
이 섹션에서는 DNS 변환 문제로 인해 포드에서 Google Cloud API로의 연결 오류를 식별하고 해결하는 방법을 설명합니다. 이 섹션의 단계로 연결 오류가 해결되지 않으면 포드 시작 시 제한 시간 오류 섹션을 참조하세요.
일부 Google Cloud 클라이언트 라이브러리는 DNS 이름 metadata.google.internal
을 변환하여 GKE 및 Compute Engine 메타데이터 서버에 연결되도록 구성되어 있습니다. 이러한 라이브러리의 경우 정상 클러스터 내 DNS 변환은 워크로드가Google Cloud 서비스에 인증하는 데 중요한 종속 항목입니다.
이 문제를 감지하는 방법은 로깅 구성을 포함하여 배포된 애플리케이션의 세부정보에 따라 달라집니다. GOOGLE_APPLICATION_CREDENTIALS
를 구성하라는 오류 메시지, 요청에 사용자 인증 정보가 없어Google Cloud 서비스에 대한 요청이 거부되었다는 오류 메시지, 메타데이터 서버를 찾을 수 없다는 오류 메시지를 찾습니다.
예를 들어 다음 오류 메시지는 DNS 변환 문제가 있음을 나타낼 수 있습니다.
ComputeEngineCredentials cannot find the metadata server. This is likely because code is not running on Google Compute Engine
metadata.google.internal
의 DNS 변환 문제가 발생하면 환경 변수 GCE_METADATA_HOST
를 169.254.169.254
로 설정하여 일부 Google Cloud 클라이언트 라이브러리에 DNS 변환을 건너뛰라고 지시할 수 있습니다.
apiVersion: v1
kind: Pod
metadata:
name: example-pod
namespace: default
spec:
containers:
- image: debian
name: main
command: ["sleep", "infinity"]
env:
- name: GCE_METADATA_HOST
value: "169.254.169.254"
이는 Google Cloud 컴퓨팅 플랫폼에서 메타데이터 서비스를 항상 사용할 수 있는 하드 코딩된 IP 주소입니다.
다음 Google Cloud 라이브러리가 지원됩니다.
포드 시작 시 제한 시간 오류
GKE 메타데이터 서버가 새 포드에서 요청을 수락하려면 몇 초가 걸려야 합니다. 포드 수명의 첫 몇 초 내에 GKE용 워크로드 아이덴티티 제휴를 사용하여 인증을 시도할 경우 짧은 제한 시간 동안 구성된 애플리케이션과 Google Cloud 클라이언트 라이브러리에서 인증이 실패할 수 있습니다.
제한 시간 오류가 발생하면 다음을 시도합니다.
- 워크로드에서 사용하는 Google Cloud 클라이언트 라이브러리를 업데이트합니다.
- 애플리케이션 코드를 변경하고 몇 초 후에 다시 시도합니다.
포드의 기본 컨테이너를 실행하기 전에 GKE 메타데이터 서버를 사용할 수 있을 때까지 기다리는 initContainer를 배포합니다.
예를 들어 다음 매니페스트는
initContainer
가 있는 포드를 위한 것입니다.apiVersion: v1 kind: Pod metadata: name: pod-with-initcontainer spec: serviceAccountName: KSA_NAME initContainers: - image: gcr.io/google.com/cloudsdktool/cloud-sdk:alpine name: workload-identity-initcontainer command: - '/bin/bash' - '-c' - | curl -sS -H 'Metadata-Flavor: Google' 'http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token' --retry 30 --retry-connrefused --retry-max-time 60 --connect-timeout 3 --fail --retry-all-errors > /dev/null && exit 0 || echo 'Retry limit exceeded. Failed to wait for metadata server to be available. Check if the gke-metadata-server Pod in the kube-system namespace is healthy.' >&2; exit 1 containers: - image: gcr.io/your-project/your-image name: your-main-application-container
컨트롤 플레인 사용 불가로 인한 GKE용 워크로드 아이덴티티 제휴 실패
클러스터 컨트롤 플레인을 사용할 수 없으면 메타데이터 서버가 GKE용 워크로드 아이덴티티 제휴를 반환할 수 없습니다. 메타데이터 서버를 호출하면 상태 코드 500이 반환됩니다.
로그 항목은 로그 탐색기에서 다음과 비슷하게 표시될 수 있습니다.
dial tcp 35.232.136.58:443: connect: connection refused
이 동작으로 인해 GKE용 워크로드 아이덴티티 제휴를 사용할 수 없습니다.
IP 순환, 컨트롤 플레인 VM 업그레이드, 클러스터 또는 노드 풀 크기 조정과 같이 클러스터 유지보수 중에는 영역 클러스터에서 컨트롤 플레인을 사용하지 못할 수 있습니다. 컨트롤 플레인 가용성에 대한 자세한 내용은 리전 또는 영역별 컨트롤 플레인 선택을 참조하세요. 리전 클러스터로 전환하면 이 문제가 사라집니다.
Istio를 사용하는 클러스터에서 GKE용 워크로드 아이덴티티 제휴 인증 실패
애플리케이션이 시작되고 엔드포인트와 통신하려고 할 때 다음과 비슷한 오류가 표시될 수 있습니다.
Connection refused (169.254.169.254:80)
Connection timeout
이러한 오류는 istio-proxy
컨테이너가 준비되기 전에 애플리케이션에서 네트워크 연결을 시도할 때 발생할 수 있습니다. 기본적으로 Istio 및 Cloud Service Mesh는 트래픽을 가로채고 리디렉션하는 서비스 메시 프록시 워크로드 실행 여부와 관계없이 워크로드가 시작되는 즉시 요청을 보낼 수 있도록 허용합니다. GKE용 워크로드 아이덴티티 제휴를 사용하는 포드의 경우 프록시가 시작되기 전에 발생하는 이러한 초기 요청이 GKE 메타데이터 서버에 도달하지 않을 수 있습니다. 이로 인해 Google Cloud API에 대한 인증이 실패합니다.
애플리케이션에서 요청을 재시도하도록 구성하지 않으면 워크로드가 실패할 수 있습니다.
이 문제가 오류의 원인인지 확인하려면 로그를 보고 istio-proxy
컨테이너가 성공적으로 시작되었는지 확인합니다.
Google Cloud 콘솔에서 로그 탐색기 페이지로 이동합니다.
쿼리 창에 다음 쿼리를 입력합니다.
(resource.type="k8s_container" resource.labels.pod_name="POD_NAME" textPayload:"Envoy proxy is ready" OR textPayload:"ERROR_MESSAGE") OR (resource.type="k8s_pod" logName:"events" jsonPayload.involvedObject.name="POD_NAME")
다음을 바꿉니다.
POD_NAME
: 영향을 받는 워크로드가 있는 포드의 이름ERROR_MESSAGE
: 애플리케이션에서 수신한 오류(connection timeout
또는connection refused
)
쿼리 실행을 클릭합니다.
출력을 검토하고
istio-proxy
컨테이너가 준비된 시점을 확인합니다.다음 예시에서는 애플리케이션이 gRPC 호출을 시도했습니다. 하지만
istio-proxy
컨테이너가 계속 초기화되고 있었으므로 애플리케이션에Connection refused
오류가 발생했습니다.Envoy proxy is ready
메시지 옆의 타임스탬프는istio-proxy
컨테이너에서 연결 요청 준비가 된 시점을 나타냅니다.2024-11-11T18:37:03Z started container istio-init 2024-11-11T18:37:12Z started container gcs-fetch 2024-11-11T18:37:42Z Initializing environment 2024-11-11T18:37:55Z Started container istio-proxy 2024-11-11T18:38:06Z StatusCode="Unavailable", Detail="Error starting gRPC call. HttpRequestException: Connection refused (169.254.169.254:80) 2024-11-11T18:38:13Z Envoy proxy is ready
이 문제를 해결하고 재발을 방지하려면 다음 워크로드별 구성 옵션 중 하나를 사용해 보세요.
프록시 워크로드가 준비될 때까지 애플리케이션에서 요청을 보내지 못하게 합니다. 다음 주석을 포드 사양의
metadata.annotations
필드에 추가합니다.proxy.istio.io/config: '{ "holdApplicationUntilProxyStarts": true }'
GKE 메타데이터 서버의 IP 주소가 리디렉션에서 제외되도록 Istio 또는 Cloud Service Mesh를 구성합니다. 다음 주석을 포드 사양의
metadata.annotations
필드에 추가합니다.traffic.sidecar.istio.io/excludeOutboundIPRanges: 169.254.169.254/32
오픈소스 Istio에서는 다음 전역 구성 옵션 중 하나를 설정하여 모든 포드에서 이 문제를 선택적으로 완화할 수 있습니다.
리디렉션에서 GKE 메타데이터 서버 IP 주소 제외:
169.254.169.254/32
IP 주소 범위가 추가되도록global.proxy.excludeIPRanges
전역 구성 옵션을 업데이트합니다.프록시가 시작할 때까지 애플리케이션에서 요청을 보내지 못하도록 방지: 값이
true
인global.proxy.holdApplicationUntilProxyStarts
전역 구성 옵션을 Istio 구성에 추가합니다.
gke-metadata-server
포드가 비정상 종료됨
gke-metadata-server
시스템 DaemonSet 포드는 노드에서 GKE용 워크로드 아이덴티티 제휴를 용이하게 합니다. 포드는 클러스터의 Kubernetes 서비스 계정 수에 비례하는 메모리 리소스를 사용합니다.
다음 문제는 gke-metadata-server
포드의 리소스 사용량이 한도를 초과하면 발생합니다. kubelet은 메모리 부족 오류가 있는 포드를 제거합니다.
클러스터에 3,000개가 넘는 Kubernetes 서비스 계정이 있으면 이 문제가 발생할 수 있습니다.
문제를 식별하려면 다음을 수행합니다.
kube-system
네임스페이스에서 비정상 종료gke-metadata-server
포드를 찾습니다.kubectl get pods -n=kube-system | grep CrashLoopBackOff
출력은 다음과 비슷합니다.
NAMESPACE NAME READY STATUS RESTARTS AGE kube-system gke-metadata-server-8sm2l 0/1 CrashLoopBackOff 194 16h kube-system gke-metadata-server-hfs6l 0/1 CrashLoopBackOff 1369 111d kube-system gke-metadata-server-hvtzn 0/1 CrashLoopBackOff 669 111d kube-system gke-metadata-server-swhbb 0/1 CrashLoopBackOff 30 136m kube-system gke-metadata-server-x4bl4 0/1 CrashLoopBackOff 7 15m
비정상 종료 포드를 설명하여 메모리 부족 제거가 원인임을 확인합니다.
kubectl describe pod POD_NAME --namespace=kube-system | grep OOMKilled
POD_NAME
을 확인할 포드 이름으로 바꿉니다.
GKE 메타데이터 서버로 기능을 복원하려면 클러스터의 서비스 계정 수를 3,000개 미만으로 줄입니다.
DeployPatch 실패 오류 메시지와 함께 GKE용 워크로드 아이덴티티 제휴 사용 설정 실패
GKE는 Google Cloud관리형 Kubernetes Engine 서비스 에이전트를 사용하여 클러스터에서 GKE용 워크로드 아이덴티티 제휴를 용이하게 합니다. Google Kubernetes Engine API를 사용 설정하면 Google Cloud 에서 이 서비스 에이전트에 프로젝트에 대한 Kubernetes Engine 서비스 에이전트 역할(roles/container.serviceAgent
)을 자동으로 부여합니다.
서비스 에이전트에 Kubernetes Engine 서비스 에이전트 역할이 없는 프로젝트의 클러스터에서 GKE용 워크로드 아이덴티티 제휴를 사용 설정하려고 하면 다음과 유사한 오류 메시지가 표시되면서 작업이 실패합니다.
Error waiting for updating GKE cluster workload identity config: DeployPatch failed
이 문제를 해결하려면 다음을 단계를 시도해 보세요.
프로젝트에 서비스 에이전트가 있고 올바르게 구성되었는지 확인합니다.
gcloud projects get-iam-policy PROJECT_ID \ --flatten=bindings \ --filter=bindings.role=roles/container.serviceAgent \ --format="value[delimiter='\\n'](bindings.members)"
PROJECT_ID
를 Google Cloud프로젝트 ID로 바꿉니다.서비스 에이전트가 올바르게 구성되었으면 출력에 서비스 에이전트의 전체 ID가 표시됩니다.
serviceAccount:service-PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com
출력에 서비스 에이전트가 표시되지 않으면 Kubernetes Engine 서비스 에이전트 역할을 부여해야 합니다. 이 역할을 부여하려면 다음 단계를 완료하세요.
Google Cloud 프로젝트 번호를 가져옵니다.
gcloud projects describe PROJECT_ID \ --format="value(projectNumber)"
출력은 다음과 비슷합니다.
123456789012
서비스 에이전트에 역할을 부여합니다.
gcloud projects add-iam-policy-binding PROJECT_ID \ --member=serviceAccount:service-PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com \ --role=roles/container.serviceAgent \ --condition=None
여기에서
PROJECT_NUMBER
를 Google Cloud프로젝트 번호로 바꿉니다.GKE용 워크로드 아이덴티티 제휴를 다시 사용 설정합니다.
다음 단계
문서에서 문제 해결 방법을 찾을 수 없으면 지원 받기를 참조하여 다음 주제에 대한 조언을 포함한 추가 도움을 요청하세요.
- Cloud Customer Care에 문의하여 지원 케이스를 엽니다.
- StackOverflow에서 질문하고
google-kubernetes-engine
태그를 사용하여 유사한 문제를 검색해 커뮤니티의 지원을 받습니다.#kubernetes-engine
Slack 채널에 가입하여 더 많은 커뮤니티 지원을 받을 수도 있습니다. - 공개 Issue Tracker를 사용하여 버그나 기능 요청을 엽니다.