Google Kubernetes Engine (GKE)의 로깅 파이프라인에 문제가 있으면 클러스터 로그가 Cloud Logging에 표시되지 않아 모니터링 및 디버깅 작업이 방해될 수 있습니다.
이 문서를 사용하여 GKE 로깅 파이프라인에 영향을 미치는 일반적인 문제를 진단하고 해결하세요. API 및 기능 사용 설정, 클러스터 및 노드 구성, 권한, 리소스 할당량과 같은 주요 영역을 검토하여 로깅 파이프라인 문제 해결에 관한 안내를 확인하세요.
이 정보는 클러스터 관측 가능성을 유지관리하는 플랫폼 관리자 및 운영자와 Cloud Logging을 사용하여 GKE 작업을 문제 해결하는 모든 사용자에게 중요합니다. Google Cloud 콘텐츠에서 참조하는 일반적인 역할과 예시 태스크에 대한 자세한 내용은 일반 GKE 사용자 역할 및 태스크를 참고하세요.
로그를 사용하여 워크로드와 클러스터 문제를 해결하는 방법에 대한 자세한 내용은 Cloud Logging으로 기록 분석 실행을 참고하세요.
Cloud Logging의 클러스터 로그 누락
프로젝트에 로깅이 사용 설정되었는지 확인
사용 설정된 서비스 나열:
gcloud services list --enabled --filter="NAME=logging.googleapis.com"
다음 출력은 프로젝트에 로깅이 사용 설정되었음을 나타냅니다.
NAME TITLE logging.googleapis.com Cloud Logging API
선택사항: 로그 뷰어의 로그를 확인하여 API를 중지한 사용자와 API를 중지한 시기를 확인합니다.
protoPayload.methodName="google.api.serviceusage.v1.ServiceUsage.DisableService" protoPayload.response.services="logging.googleapis.com"
로깅이 중지되었다면 로깅을 사용 설정합니다.
gcloud services enable logging.googleapis.com
클러스터에 로깅이 사용 설정되었는지 확인
클러스터를 나열합니다.
gcloud container clusters list \ --project=PROJECT_ID \ '--format=value(name,loggingConfig.componentConfig.enableComponents)' \ --sort-by=name | column -t
다음을 바꿉니다.
PROJECT_ID
: Google Cloud 프로젝트 ID입니다.
출력은 다음과 비슷합니다.
cluster-1 SYSTEM_COMPONENTS cluster-2 SYSTEM_COMPONENTS;WORKLOADS cluster-3
클러스터 값이 비어 있으면 로깅이 중지됩니다. 예를 들어 이 출력의
cluster-3
에서는 로깅이 중지되어 있습니다.NONE
으로 설정된 경우 클러스터 로깅을 사용 설정합니다.gcloud container clusters update CLUSTER_NAME \ --logging=SYSTEM,WORKLOAD \ --location=COMPUTE_LOCATION
다음을 바꿉니다.
CLUSTER_NAME
: 클러스터 이름COMPUTE_LOCATION
: 클러스터의 Compute Engine 위치
프로젝트와 클러스터에서 로깅을 사용 설정했는지 확인한 후 Gemini Cloud Assist 조사를 사용하여 로그에 대한 추가 통계를 얻고 문제를 해결하는 것이 좋습니다. 로그 탐색기를 사용하여 조사를 시작하는 다양한 방법에 대한 자세한 내용은 Gemini 문서의 Gemini Cloud Assist 조사로 문제 해결을 참고하세요.
노드 풀의 노드에 Cloud Logging 액세스 범위가 있는지 확인
Cloud Logging에 로그를 쓰려면 노드에 다음 범위 중 하나가 필요합니다.
https://www.googleapis.com/auth/logging.write
https://www.googleapis.com/auth/cloud-platform
https://www.googleapis.com/auth/logging.admin
클러스터의 각 노드 풀에서 구성된 범위를 확인합니다.
gcloud container node-pools list --cluster=CLUSTER_NAME \ --format="table(name,config.oauthScopes)" \ --location COMPUTE_LOCATION
다음을 바꿉니다.
CLUSTER_NAME
: 클러스터 이름COMPUTE_LOCATION
: 클러스터의 Compute Engine 위치
이전 노드 풀에서 새로 생성된 노드 풀로 워크로드를 마이그레이션하고 진행 상황을 모니터링합니다.
올바른 로깅 범위로 새 노드 풀을 만듭니다.
gcloud container node-pools create NODE_POOL_NAME \ --cluster=CLUSTER_NAME \ --location=COMPUTE_LOCATION \ --scopes="gke-default"
다음을 바꿉니다.
CLUSTER_NAME
: 클러스터 이름COMPUTE_LOCATION
: 클러스터의 Compute Engine 위치
GKE 기본 노드 서비스 에이전트에 필요한 권한이 있는지 확인
Kubernetes 버전 1.33 이상을 사용하는 GKE 클러스터의 경우 service-PROJECT_NUMBER@gcp-sa-gkenode.iam.gserviceaccount.com
형식의 GKE 기본 노드 서비스 에이전트에 프로젝트의 Kubernetes 기본 노드 서비스 에이전트 역할이 부여되어야 합니다. 이 서비스 에이전트는 모든 Google Kubernetes Engine 노드 시스템 워크로드에서 Cloud Logging으로 로그를 내보내는 데 사용됩니다. 오류 400/403: 계정에 수정 권한 없음의 안내에 따라 서비스 에이전트에 기본 권한이 있는지 확인합니다.
중요한 권한이 없는 노드 서비스 계정이 있는 클러스터 식별
중요한 권한이 없는 노드 서비스 계정이 있는 클러스터를 식별하려면 NODE_SA_MISSING_PERMISSIONS
추천자 하위유형의 GKE 추천을 사용하세요.
- Google Cloud 콘솔을 사용합니다. Kubernetes 클러스터 페이지로 이동합니다. 특정 클러스터의 알림 열에서 중요한 권한 부여 추천을 확인합니다.
NODE_SA_MISSING_PERMISSIONS
추천자 하위 유형을 지정하여 gcloud CLI 또는 Recommender API를 사용합니다.이 추천을 쿼리하려면 다음 명령어를 실행하세요.
gcloud recommender recommendations list \ --recommender=google.container.DiagnosisRecommender \ --location LOCATION \ --project PROJECT_ID \ --format yaml \ --filter="recommenderSubtype:NODE_SA_MISSING_PERMISSIONS"
이 권장사항을 구현하려면 노드의 서비스 계정에 roles/container.defaultNodeServiceAccount
역할을 부여하세요.
프로젝트의 Standard 및 Autopilot 클러스터에서 GKE에 필요한 권한이 없는 노드 서비스 계정을 검색하는 스크립트를 실행할 수 있습니다. 이 스크립트는 gcloud CLI와 jq
유틸리티를 사용합니다. 스크립트를 보려면 다음 섹션을 펼치세요.
스크립트 보기
#!/bin/bash
# Set your project ID
project_id=PROJECT_ID
project_number=$(gcloud projects describe "$project_id" --format="value(projectNumber)")
declare -a all_service_accounts
declare -a sa_missing_permissions
# Function to check if a service account has a specific permission
# $1: project_id
# $2: service_account
# $3: permission
service_account_has_permission() {
local project_id="$1"
local service_account="$2"
local permission="$3"
local roles=$(gcloud projects get-iam-policy "$project_id" \
--flatten="bindings[].members" \
--format="table[no-heading](bindings.role)" \
--filter="bindings.members:\"$service_account\"")
for role in $roles; do
if role_has_permission "$role" "$permission"; then
echo "Yes" # Has permission
return
fi
done
echo "No" # Does not have permission
}
# Function to check if a role has the specific permission
# $1: role
# $2: permission
role_has_permission() {
local role="$1"
local permission="$2"
gcloud iam roles describe "$role" --format="json" | \
jq -r ".includedPermissions" | \
grep -q "$permission"
}
# Function to add $1 into the service account array all_service_accounts
# $1: service account
add_service_account() {
local service_account="$1"
all_service_accounts+=( ${service_account} )
}
# Function to add service accounts into the global array all_service_accounts for a Standard GKE cluster
# $1: project_id
# $2: location
# $3: cluster_name
add_service_accounts_for_standard() {
local project_id="$1"
local cluster_location="$2"
local cluster_name="$3"
while read nodepool; do
nodepool_name=$(echo "$nodepool" | awk '{print $1}')
if [[ "$nodepool_name" == "" ]]; then
# skip the empty line which is from running `gcloud container node-pools list` in GCP console
continue
fi
while read nodepool_details; do
service_account=$(echo "$nodepool_details" | awk '{print $1}')
if [[ "$service_account" == "default" ]]; then
service_account="${project_number}-compute@developer.gserviceaccount.com"
fi
if [[ -n "$service_account" ]]; then
printf "%-60s| %-40s| %-40s| %-10s| %-20s\n" $service_account $project_id $cluster_name $cluster_location $nodepool_name
add_service_account "${service_account}"
else
echo "cannot find service account for node pool $project_id\t$cluster_name\t$cluster_location\t$nodepool_details"
fi
done <<< "$(gcloud container node-pools describe "$nodepool_name" --cluster "$cluster_name" --zone "$cluster_location" --project "$project_id" --format="table[no-heading](config.serviceAccount)")"
done <<< "$(gcloud container node-pools list --cluster "$cluster_name" --zone "$cluster_location" --project "$project_id" --format="table[no-heading](name)")"
}
# Function to add service accounts into the global array all_service_accounts for an Autopilot GKE cluster
# Autopilot cluster only has one node service account.
# $1: project_id
# $2: location
# $3: cluster_name
add_service_account_for_autopilot(){
local project_id="$1"
local cluster_location="$2"
local cluster_name="$3"
while read service_account; do
if [[ "$service_account" == "default" ]]; then
service_account="${project_number}-compute@developer.gserviceaccount.com"
fi
if [[ -n "$service_account" ]]; then
printf "%-60s| %-40s| %-40s| %-10s| %-20s\n" $service_account $project_id $cluster_name $cluster_location $nodepool_name
add_service_account "${service_account}"
else
echo "cannot find service account" for cluster "$project_id\t$cluster_name\t$cluster_location\t"
fi
done <<< "$(gcloud container clusters describe "$cluster_name" --location "$cluster_location" --project "$project_id" --format="table[no-heading](autoscaling.autoprovisioningNodePoolDefaults.serviceAccount)")"
}
# Function to check whether the cluster is an Autopilot cluster or not
# $1: project_id
# $2: location
# $3: cluster_name
is_autopilot_cluster() {
local project_id="$1"
local cluster_location="$2"
local cluster_name="$3"
autopilot=$(gcloud container clusters describe "$cluster_name" --location "$cluster_location" --format="table[no-heading](autopilot.enabled)")
echo "$autopilot"
}
echo "--- 1. List all service accounts in all GKE node pools"
printf "%-60s| %-40s| %-40s| %-10s| %-20s\n" "service_account" "project_id" "cluster_name" "cluster_location" "nodepool_name"
while read cluster; do
cluster_name=$(echo "$cluster" | awk '{print $1}')
cluster_location=$(echo "$cluster" | awk '{print $2}')
# how to find a cluster is a Standard cluster or an Autopilot cluster
autopilot=$(is_autopilot_cluster "$project_id" "$cluster_location" "$cluster_name")
if [[ "$autopilot" == "True" ]]; then
add_service_account_for_autopilot "$project_id" "$cluster_location" "$cluster_name"
else
add_service_accounts_for_standard "$project_id" "$cluster_location" "$cluster_name"
fi
done <<< "$(gcloud container clusters list --project "$project_id" --format="value(name,location)")"
echo "--- 2. Check if service accounts have permissions"
unique_service_accounts=($(echo "${all_service_accounts[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' '))
echo "Service accounts: ${unique_service_accounts[@]}"
printf "%-60s| %-40s| %-40s| %-20s\n" "service_account" "has_logging_permission" "has_monitoring_permission" "has_performance_hpa_metric_write_permission"
for sa in "${unique_service_accounts[@]}"; do
logging_permission=$(service_account_has_permission "$project_id" "$sa" "logging.logEntries.create")
time_series_create_permission=$(service_account_has_permission "$project_id" "$sa" "monitoring.timeSeries.create")
metric_descriptors_create_permission=$(service_account_has_permission "$project_id" "$sa" "monitoring.metricDescriptors.create")
if [[ "$time_series_create_permission" == "No" || "$metric_descriptors_create_permission" == "No" ]]; then
monitoring_permission="No"
else
monitoring_permission="Yes"
fi
performance_hpa_metric_write_permission=$(service_account_has_permission "$project_id" "$sa" "autoscaling.sites.writeMetrics")
printf "%-60s| %-40s| %-40s| %-20s\n" $sa $logging_permission $monitoring_permission $performance_hpa_metric_write_permission
if [[ "$logging_permission" == "No" || "$monitoring_permission" == "No" || "$performance_hpa_metric_write_permission" == "No" ]]; then
sa_missing_permissions+=( ${sa} )
fi
done
echo "--- 3. List all service accounts that don't have the above permissions"
if [[ "${#sa_missing_permissions[@]}" -gt 0 ]]; then
printf "Grant roles/container.defaultNodeServiceAccount to the following service accounts: %s\n" "${sa_missing_permissions[@]}"
else
echo "All service accounts have the above permissions"
fi
클러스터에서 중요한 권한이 없는 노드 서비스 계정 식별
GKE는 노드에 연결된 IAM 서비스 계정을 사용하여 로깅 및 모니터링과 같은 시스템 태스크를 실행합니다. 적어도 이러한 노드 서비스 계정에는 프로젝트에 대한 Kubernetes Engine 기본 노드 서비스 계정(roles/container.defaultNodeServiceAccount
) 역할이 있어야 합니다. 기본적으로 GKE는 프로젝트에 자동으로 생성되는 Compute Engine 기본 서비스 계정을 노드 서비스 계정으로 사용합니다.
조직에서 iam.automaticIamGrantsForDefaultServiceAccounts
조직 정책 제약조건을 적용하는 경우 프로젝트의 기본 Compute Engine 서비스 계정에 GKE에 필요한 권한이 자동으로 부여되지 않을 수 있습니다.
로깅 권한이 누락되었는지 확인하려면 클러스터의 로깅에서
401
오류를 확인하세요.[[ $(kubectl logs -l k8s-app=fluentbit-gke -n kube-system -c fluentbit-gke | grep -cw "Received 401") -gt 0 ]] && echo "true" || echo "false"
출력이
true
이면 시스템 워크로드에401
오류가 발생한 것으로, 이는 권한이 부족함을 나타냅니다. 출력이false
인 경우 나머지 단계를 건너뛰고 다른 문제 해결 절차를 시도하세요.누락된 모든 중요 권한을 확인하려면 스크립트를 확인하세요.
-
노드에서 사용하는 서비스 계정의 이름을 찾습니다.
콘솔
- Kubernetes 클러스터 페이지로 이동합니다.
- 클러스터 목록에서 조사할 클러스터 이름을 클릭합니다.
- 작업의 클러스터 모드에 따라 다음 중 하나를 수행합니다.
- Autopilot 모드 클러스터의 경우 보안 섹션에서 서비스 계정 필드를 찾습니다.
- Standard 모드 클러스터의 경우 다음을 실행합니다.
- 노드 탭을 클릭합니다.
- 노드 풀 표에서 노드 풀 이름을 클릭합니다. 노드 풀 세부정보 페이지가 열립니다.
- 보안 섹션에서 서비스 계정 필드를 찾습니다.
서비스 계정 필드의 값이
default
이면 노드가 Compute Engine 기본 서비스 계정을 사용합니다. 이 필드의 값이default
이 아닌 경우 노드에서 커스텀 서비스 계정을 사용합니다. 커스텀 서비스 계정에 필요한 역할을 부여하려면 최소 권한 IAM 서비스 계정 사용을 참고하세요.gcloud
Autopilot 모드 클러스터의 경우 다음 명령어를 실행합니다.
gcloud container clusters describe
CLUSTER_NAME
\ --location=LOCATION
\ --flatten=autoscaling.autoprovisioningNodePoolDefaults.serviceAccountStandard 모드 클러스터의 경우 다음 명령어를 실행합니다.
gcloud container clusters describe
CLUSTER_NAME
\ --location=LOCATION
\ --format="table(nodePools.name,nodePools.config.serviceAccount)"출력이
default
이면 노드에서 Compute Engine 기본 서비스 계정을 사용합니다. 출력이default
이 아닌 경우 노드에서 커스텀 서비스 계정을 사용합니다. 커스텀 서비스 계정에 필요한 역할을 부여하려면 최소 권한 IAM 서비스 계정 사용을 참고하세요. -
Compute Engine 기본 서비스 계정에
roles/container.defaultNodeServiceAccount
역할을 부여하려면 다음 단계를 완료합니다.콘솔
- 시작 페이지로 이동합니다.
- 프로젝트 번호 필드에서 클립보드에 복사를 클릭합니다.
- IAM 페이지로 이동합니다.
- 액세스 권한 부여를 클릭합니다.
- 새 주 구성원 필드에 다음 값을 지정합니다.
PROJECT_NUMBER-compute@developer.gserviceaccount.com
PROJECT_NUMBER
를 복사한 프로젝트 번호로 바꿉니다. - 역할 선택 메뉴에서 Kubernetes Engine 기본 노드 서비스 계정 역할을 선택합니다.
- 저장을 클릭합니다.
gcloud
- Google Cloud 프로젝트 번호를 찾습니다.
gcloud projects describe PROJECT_ID \ --format="value(projectNumber)"
PROJECT_ID
를 프로젝트 ID로 바꿉니다.출력은 다음과 비슷합니다.
12345678901
- Compute Engine 기본 서비스 계정에
roles/container.defaultNodeServiceAccount
역할을 부여합니다.gcloud projects add-iam-policy-binding PROJECT_ID \ --member="serviceAccount:PROJECT_NUMBER-compute@developer.gserviceaccount.com" \ --role="roles/container.defaultNodeServiceAccount"
PROJECT_NUMBER
를 이전 단계의 프로젝트 번호로 바꿉니다.
- 노드 서비스 계정에 필요한 권한이 있는지 확인합니다. 스크립트 를 확인합니다.
GKE 노드 서비스 계정에 없는 권한을 식별하는 스크립트
프로젝트의 Standard 및 Autopilot 클러스터에서 GKE에 필요한 권한이 없는 노드 서비스 계정을 검색하는 스크립트를 실행할 수 있습니다. 이 스크립트는 gcloud CLI와 jq
유틸리티를 사용합니다. 스크립트를 보려면 다음 섹션을 펼치세요.
스크립트 보기
#!/bin/bash
# Set your project ID
project_id=PROJECT_ID
project_number=$(gcloud projects describe "$project_id" --format="value(projectNumber)")
declare -a all_service_accounts
declare -a sa_missing_permissions
# Function to check if a service account has a specific permission
# $1: project_id
# $2: service_account
# $3: permission
service_account_has_permission() {
local project_id="$1"
local service_account="$2"
local permission="$3"
local roles=$(gcloud projects get-iam-policy "$project_id" \
--flatten="bindings[].members" \
--format="table[no-heading](bindings.role)" \
--filter="bindings.members:\"$service_account\"")
for role in $roles; do
if role_has_permission "$role" "$permission"; then
echo "Yes" # Has permission
return
fi
done
echo "No" # Does not have permission
}
# Function to check if a role has the specific permission
# $1: role
# $2: permission
role_has_permission() {
local role="$1"
local permission="$2"
gcloud iam roles describe "$role" --format="json" | \
jq -r ".includedPermissions" | \
grep -q "$permission"
}
# Function to add $1 into the service account array all_service_accounts
# $1: service account
add_service_account() {
local service_account="$1"
all_service_accounts+=( ${service_account} )
}
# Function to add service accounts into the global array all_service_accounts for a Standard GKE cluster
# $1: project_id
# $2: location
# $3: cluster_name
add_service_accounts_for_standard() {
local project_id="$1"
local cluster_location="$2"
local cluster_name="$3"
while read nodepool; do
nodepool_name=$(echo "$nodepool" | awk '{print $1}')
if [[ "$nodepool_name" == "" ]]; then
# skip the empty line which is from running `gcloud container node-pools list` in GCP console
continue
fi
while read nodepool_details; do
service_account=$(echo "$nodepool_details" | awk '{print $1}')
if [[ "$service_account" == "default" ]]; then
service_account="${project_number}-compute@developer.gserviceaccount.com"
fi
if [[ -n "$service_account" ]]; then
printf "%-60s| %-40s| %-40s| %-10s| %-20s\n" $service_account $project_id $cluster_name $cluster_location $nodepool_name
add_service_account "${service_account}"
else
echo "cannot find service account for node pool $project_id\t$cluster_name\t$cluster_location\t$nodepool_details"
fi
done <<< "$(gcloud container node-pools describe "$nodepool_name" --cluster "$cluster_name" --zone "$cluster_location" --project "$project_id" --format="table[no-heading](config.serviceAccount)")"
done <<< "$(gcloud container node-pools list --cluster "$cluster_name" --zone "$cluster_location" --project "$project_id" --format="table[no-heading](name)")"
}
# Function to add service accounts into the global array all_service_accounts for an Autopilot GKE cluster
# Autopilot cluster only has one node service account.
# $1: project_id
# $2: location
# $3: cluster_name
add_service_account_for_autopilot(){
local project_id="$1"
local cluster_location="$2"
local cluster_name="$3"
while read service_account; do
if [[ "$service_account" == "default" ]]; then
service_account="${project_number}-compute@developer.gserviceaccount.com"
fi
if [[ -n "$service_account" ]]; then
printf "%-60s| %-40s| %-40s| %-10s| %-20s\n" $service_account $project_id $cluster_name $cluster_location $nodepool_name
add_service_account "${service_account}"
else
echo "cannot find service account" for cluster "$project_id\t$cluster_name\t$cluster_location\t"
fi
done <<< "$(gcloud container clusters describe "$cluster_name" --location "$cluster_location" --project "$project_id" --format="table[no-heading](autoscaling.autoprovisioningNodePoolDefaults.serviceAccount)")"
}
# Function to check whether the cluster is an Autopilot cluster or not
# $1: project_id
# $2: location
# $3: cluster_name
is_autopilot_cluster() {
local project_id="$1"
local cluster_location="$2"
local cluster_name="$3"
autopilot=$(gcloud container clusters describe "$cluster_name" --location "$cluster_location" --format="table[no-heading](autopilot.enabled)")
echo "$autopilot"
}
echo "--- 1. List all service accounts in all GKE node pools"
printf "%-60s| %-40s| %-40s| %-10s| %-20s\n" "service_account" "project_id" "cluster_name" "cluster_location" "nodepool_name"
while read cluster; do
cluster_name=$(echo "$cluster" | awk '{print $1}')
cluster_location=$(echo "$cluster" | awk '{print $2}')
# how to find a cluster is a Standard cluster or an Autopilot cluster
autopilot=$(is_autopilot_cluster "$project_id" "$cluster_location" "$cluster_name")
if [[ "$autopilot" == "True" ]]; then
add_service_account_for_autopilot "$project_id" "$cluster_location" "$cluster_name"
else
add_service_accounts_for_standard "$project_id" "$cluster_location" "$cluster_name"
fi
done <<< "$(gcloud container clusters list --project "$project_id" --format="value(name,location)")"
echo "--- 2. Check if service accounts have permissions"
unique_service_accounts=($(echo "${all_service_accounts[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' '))
echo "Service accounts: ${unique_service_accounts[@]}"
printf "%-60s| %-40s| %-40s| %-20s\n" "service_account" "has_logging_permission" "has_monitoring_permission" "has_performance_hpa_metric_write_permission"
for sa in "${unique_service_accounts[@]}"; do
logging_permission=$(service_account_has_permission "$project_id" "$sa" "logging.logEntries.create")
time_series_create_permission=$(service_account_has_permission "$project_id" "$sa" "monitoring.timeSeries.create")
metric_descriptors_create_permission=$(service_account_has_permission "$project_id" "$sa" "monitoring.metricDescriptors.create")
if [[ "$time_series_create_permission" == "No" || "$metric_descriptors_create_permission" == "No" ]]; then
monitoring_permission="No"
else
monitoring_permission="Yes"
fi
performance_hpa_metric_write_permission=$(service_account_has_permission "$project_id" "$sa" "autoscaling.sites.writeMetrics")
printf "%-60s| %-40s| %-40s| %-20s\n" $sa $logging_permission $monitoring_permission $performance_hpa_metric_write_permission
if [[ "$logging_permission" == "No" || "$monitoring_permission" == "No" || "$performance_hpa_metric_write_permission" == "No" ]]; then
sa_missing_permissions+=( ${sa} )
fi
done
echo "--- 3. List all service accounts that don't have the above permissions"
if [[ "${#sa_missing_permissions[@]}" -gt 0 ]]; then
printf "Grant roles/container.defaultNodeServiceAccount to the following service accounts: %s\n" "${sa_missing_permissions[@]}"
else
echo "All service accounts have the above permissions"
fi
Cloud Logging 쓰기 API 할당량에 도달하지 않았는지 확인
Cloud Logging의 API 쓰기 할당량에 도달하지 않았는지 확인합니다.
Google Cloud 콘솔에서 할당량 페이지로 이동합니다.
'Cloud Logging API'를 기준으로 테이블을 필터링합니다.
할당량에 도달하지 않았는지 확인합니다.
gcpdiag
로 GKE 로깅 문제 디버깅
GKE 클러스터에서 로그가 누락되거나 불완전한 경우 gcpdiag
도구를 사용하여 문제를 해결합니다.
gcpdiag
는 오픈소스 도구입니다. 공식적으로 지원되는 Google Cloud 제품이 아닙니다.
gcpdiag
도구를 사용하여 Google Cloud프로젝트 문제를 식별하고 해결할 수 있습니다. 자세한 내용은 GitHub의 gcpdiag 프로젝트를 참조하세요.
- 프로젝트 수준 로깅: GKE 클러스터가 있는 Google Cloud 프로젝트에 Cloud Logging API가 사용 설정되었는지 확인합니다.
- 클러스터 수준 로깅: 로깅이 GKE 클러스터 구성 내에서 명시적으로 사용 설정되었는지 확인합니다.
- 노드 풀 권한: 로그 데이터를 전송할 수 있도록 클러스터의 노드 풀 내 노드에 'Cloud Logging 쓰기' 범위가 사용 설정되어 있는지 확인합니다.
- 서비스 계정 권한: 노드 풀에서 사용하는 서비스 계정에 Cloud Logging과 상호작용하는 데 필요한 IAM 권한이 있는지 확인합니다. 특히 일반적으로 'roles/logging.logWriter' 역할이 필요합니다.
- Cloud Logging API 쓰기 할당량: Cloud Logging API 쓰기 할당량이 지정된 기간 내에 초과되지 않았는지 확인합니다.
Docker
Docker 컨테이너에서 gcpdiag
를 시작하는 래퍼를 사용하여 gcpdiag
를 실행할 수 있습니다. Docker 또는 Podman이 설치되어 있어야 합니다.
- 로컬 워크스테이션에서 다음 명령어를 복사하고 실행합니다.
curl https://gcpdiag.dev/gcpdiag.sh >gcpdiag && chmod +x gcpdiag
-
gcpdiag
명령어를 실행합니다../gcpdiag runbook gke/logs \ --parameter project_id=PROJECT_ID \ --parameter name=GKE_NAME \ --parameter location=LOCATION
이 런북에 사용 가능한 파라미터를 봅니다.
다음을 바꿉니다.
- PROJECT_ID: 리소스가 포함된 프로젝트의 ID입니다.
- GKE_NAME: GKE 클러스터 이름입니다.
- LOCATION: GKE 클러스터의 영역이나 리전입니다.
유용한 플래그:
--universe-domain
: 해당되는 경우 리소스를 호스팅하는 신뢰할 수 있는 파트너 Sovereign Cloud 도메인--parameter
또는-p
: 런북 파라미터
모든 gcpdiag
도구 플래그의 목록과 설명은 gcpdiag
사용 안내를 참조하세요.
다음 단계
문서에서 문제 해결 방법을 찾을 수 없으면 지원 받기를 참조하여 다음 주제에 대한 조언을 포함한 추가 도움을 요청하세요.
- Cloud Customer Care에 문의하여 지원 케이스를 엽니다.
- StackOverflow에서 질문하고
google-kubernetes-engine
태그를 사용하여 유사한 문제를 검색해 커뮤니티의 지원을 받습니다.#kubernetes-engine
Slack 채널에 가입하여 더 많은 커뮤니티 지원을 받을 수도 있습니다. - 공개 Issue Tracker를 사용하여 버그나 기능 요청을 엽니다.