Halaman ini membantu Anda menyelesaikan error 400, 401, 403, dan 404 yang mungkin Anda alami saat menggunakan Google Kubernetes Engine (GKE).
Masalah: Error autentikasi dan otorisasi
Saat menghubungkan ke cluster GKE, Anda dapat mengalami error autentikasi dan otorisasi dengan kode status HTTP 401 (Unauthorized)
. Masalah ini mungkin terjadi saat Anda mencoba menjalankan perintah kubectl
di cluster GKE dari lingkungan lokal.
Penyebab masalah ini mungkin salah satu dari berikut ini:
- Plugin autentikasi
gke-gcloud-auth-plugin
tidak diinstal atau dikonfigurasi dengan benar. - Anda tidak memiliki izin untuk terhubung ke server API cluster dan menjalankan perintah
kubectl
.
Untuk mendiagnosis penyebabnya, selesaikan langkah-langkah di bagian berikut:
Hubungkan ke cluster menggunakan curl
Untuk mendiagnosis penyebab error autentikasi dan otorisasi, hubungkan ke
cluster menggunakan curl
. Menggunakan curl
akan melewati alat command line kubectl
dan plugin gke-gcloud-auth-plugin
.
Menetapkan variabel lingkungan:
APISERVER=https://$(gcloud container clusters describe CLUSTER_NAME \ --location=COMPUTE_LOCATION --format "value(endpoint)") TOKEN=$(gcloud auth print-access-token)
Pastikan token akses Anda valid:
curl https://oauth2.googleapis.com/tokeninfo?access_token=$TOKEN
Jika Anda memiliki token akses yang valid, perintah ini akan mengirim permintaan ke server OAuth 2.0 Google dan server akan merespons dengan informasi tentang token tersebut.
Coba hubungkan ke endpoint API inti di server API:
# Get cluster CA certificate gcloud container clusters describe CLUSTER_NAME \ --location=COMPUTE_LOCATION \ --format "value(masterAuth.clusterCaCertificate)" | \ base64 -d > /tmp/ca.crt # Make API call with authentication and CA certificate curl -s -X GET "${APISERVER}/api/v1/namespaces" \ --header "Authorization: Bearer $TOKEN" \ --cacert /tmp/ca.crt
Jika perintah
curl
berhasil, Anda akan melihat daftar namespace. Lanjutkan untuk memeriksa apakah plugin menjadi penyebabnya menggunakan langkah-langkah di bagian Mengonfigurasi plugin di kubeconfig.Jika perintah
curl
gagal dengan output yang mirip dengan berikut ini, berarti Anda tidak memiliki izin yang benar untuk mengakses cluster:{ "kind": "Status", "apiVersion": "v1", "metadata": {}, "status": "Failure", "message": "Unauthorized", "reason": "Unauthorized", "code": 401 }
Untuk mengatasi masalah ini, hubungi administrator Anda untuk mendapatkan izin yang benar guna mengakses cluster.
Mengonfigurasi penggunaan plugin di kubeconfig
Jika Anda mendapatkan error autentikasi dan otorisasi saat menghubungkan ke cluster, tetapi dapat menghubungkan ke cluster menggunakan
curl
, pastikan Anda dapat mengakses cluster tanpa memerlukan plugin gke-gcloud-auth-plugin
.
Untuk mengatasi masalah ini, konfigurasi lingkungan lokal Anda agar mengabaikan biner gke-gcloud-auth-plugin
saat melakukan autentikasi ke cluster. Di klien Kubernetes yang menjalankan versi 1.25 dan yang lebih baru, biner gke-gcloud-auth-plugin
diperlukan, jadi Anda harus menggunakan versi 1.24 atau yang lebih lama untuk alat command line kubectl
.
Ikuti langkah-langkah berikut untuk mengakses cluster tanpa memerlukan plugin:
Instal alat command line
kubectl
dengan versi 1.24 atau yang lebih lama menggunakancurl
. Contoh berikut menginstal alat dengan versi 1.24:curl -LO https://dl.k8s.io/release/v1.24.0/bin/linux/amd64/kubectl
Buka file skrip startup shell Anda di editor teks. Misalnya, buka
.bashrc
untuk shell Bash:vi ~/.bashrc
Jika Anda menggunakan macOS, gunakan
~/.bash_profile
, bukan.bashrc
dalam petunjuk ini.Tambahkan baris berikut ke file skrip startup, lalu simpan:
export USE_GKE_GCLOUD_AUTH_PLUGIN=False
Jalankan skrip startup:
source ~/.bashrc
Dapatkan kredensial untuk cluster Anda, yang menyiapkan file
.kube/config
:gcloud container clusters get-credentials CLUSTER_NAME \ --location=COMPUTE_LOCATION
Ganti kode berikut:
CLUSTER_NAME
: nama cluster.COMPUTE_LOCATION
: lokasi Compute Engine.
Jalankan perintah
kubectl
. Contoh:kubectl cluster-info
Jika Anda mendapatkan error 401 atau error otorisasi serupa setelah menjalankan perintah ini, pastikan Anda memiliki izin yang benar, lalu jalankan kembali langkah yang menampilkan error.
Error 400: Node pool memerlukan pembuatan ulang
Error berikut dapat terjadi saat Anda mencoba melakukan tindakan yang membuat ulang panel kontrol dan node:
ERROR: (gcloud.container.clusters.update) ResponseError: code=400, message=Node pool "test-pool-1" requires recreation.
Misalnya, error ini dapat terjadi saat Anda menyelesaikan rotasi kredensial yang sedang berlangsung.
Di backend, node pool ditandai untuk dibuat ulang, tetapi operasi pembuatan ulang yang sebenarnya mungkin memerlukan waktu beberapa saat untuk dimulai. Oleh karena itu, operasi gagal karena GKE belum membuat ulang satu atau beberapa node pool di cluster Anda.
Untuk mengatasi masalah ini, pilih salah satu solusi berikut:
- Tunggu hingga pembuatan ulang selesai. Proses ini mungkin memerlukan waktu berjam-jam, berhari-hari, atau berminggu-minggu, bergantung pada faktor-faktor seperti masa pemeliharaan dan pengecualian yang ada.
Mulai pembuatan ulang node pool yang terpengaruh secara manual dengan memulai upgrade versi ke versi yang sama dengan panel kontrol.
Untuk memulai pembuatan ulang, jalankan perintah berikut:
gcloud container clusters upgrade CLUSTER_NAME \ --node-pool=POOL_NAME
Setelah upgrade selesai, coba lagi operasi.
Error 401: Tidak Sah
Mengidentifikasi cluster dengan akun layanan node yang tidak memiliki izin penting
Untuk mengidentifikasi cluster dengan akun layanan node yang tidak memiliki izin penting, gunakan rekomendasi GKE dari NODE_SA_MISSING_PERMISSIONS
subjenis pemberi rekomendasi:
- Gunakan Trusted Cloud console. Buka halaman Kubernetes clusters dan periksa rekomendasi Grant critical permissions di kolom Notifications untuk cluster tertentu.
Gunakan gcloud CLI atau Recommender API, dengan menentukan subjenis recommender
NODE_SA_MISSING_PERMISSIONS
.Untuk mengkueri rekomendasi, jalankan perintah berikut:
gcloud recommender recommendations list \ --recommender=google.container.DiagnosisRecommender \ --location LOCATION \ --project PROJECT_ID \ --format yaml \ --filter="recommenderSubtype:NODE_SA_MISSING_PERMISSIONS"
Perhatikan bahwa rekomendasi mungkin memerlukan waktu hingga 24 jam untuk muncul. Untuk mendapatkan petunjuk mendetail, lihat cara melihat insight dan rekomendasi.
Untuk menerapkan rekomendasi ini, berikan peran roles/container.defaultNodeServiceAccount
ke akun layanan node.
Anda dapat menjalankan skrip yang menelusuri node pool di cluster Standard
dan Autopilot project Anda untuk menemukan akun layanan node yang tidak memiliki izin
yang diperlukan untuk GKE. Skrip ini menggunakan gcloud CLI dan utilitas jq
. Untuk melihat skrip, luaskan bagian berikut:
Melihat skrip
#!/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.s3ns-system.iam.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.s3ns-system.iam.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
Mengidentifikasi akun layanan node yang tidak memiliki izin penting dalam cluster
GKE menggunakan akun layanan IAM yang terlampir ke node Anda untuk menjalankan tugas sistem seperti logging dan pemantauan. Setidaknya, akun layanan node ini harus memiliki peran
Kubernetes Engine Default Node Service Account
(roles/container.defaultNodeServiceAccount
) di project Anda. Secara default,
GKE menggunakan
akun layanan default Compute Engine,
yang otomatis dibuat di project Anda, sebagai akun layanan node.
Jika organisasi Anda menerapkan
batasan kebijakan organisasi iam.automaticIamGrantsForDefaultServiceAccounts
, akun layanan Compute Engine default di project Anda mungkin
tidak otomatis mendapatkan izin yang diperlukan untuk GKE.
-
Temukan nama akun layanan yang digunakan node Anda:
console
- Buka halaman cluster Kubernetes:
- Di daftar cluster, klik nama cluster yang ingin Anda periksa.
- Bergantung pada mode operasi cluster, lakukan salah satu hal berikut:
- Untuk cluster mode Autopilot, di bagian Security, temukan kolom Service account.
- Untuk cluster mode Standard, lakukan hal berikut:
- Klik tab Nodes.
- Di tabel Node pool, klik nama node pool. Halaman Node pool details akan terbuka.
- Di bagian Security, temukan kolom Service account.
Jika nilai di kolom Service account adalah
default
, node Anda akan menggunakan akun layanan default Compute Engine. Jika nilai di kolom ini bukandefault
, node Anda menggunakan akun layanan kustom. Untuk memberikan peran yang diperlukan ke akun layanan kustom, lihat Menggunakan akun layanan IAM dengan hak istimewa terendah.gcloud
Untuk cluster mode Autopilot, jalankan perintah berikut:
gcloud container clusters describe
CLUSTER_NAME
\ --location=LOCATION
\ --flatten=autoscaling.autoprovisioningNodePoolDefaults.serviceAccountUntuk cluster mode Standard, jalankan perintah berikut:
gcloud container clusters describe
CLUSTER_NAME
\ --location=LOCATION
\ --format="table(nodePools.name,nodePools.config.serviceAccount)"Jika outputnya adalah
default
, node Anda menggunakan akun layanan default Compute Engine. Jika outputnya bukandefault
, node Anda menggunakan akun layanan kustom. Untuk memberikan peran yang diperlukan ke akun layanan kustom, lihat Menggunakan akun layanan IAM dengan hak istimewa terendah. -
Untuk memberikan peran
roles/container.defaultNodeServiceAccount
ke akun layanan default Compute Engine, selesaikan langkah-langkah berikut:console
- Buka halaman Selamat Datang:
- Di kolom Project number, klik Copy to clipboard.
- Buka halaman IAM:
- Klik Berikan akses.
- Di kolom Akun utama baru, tentukan nilai berikut:
GantiPROJECT_NUMBER-compute@developer.s3ns-system.iam.gserviceaccount.com
PROJECT_NUMBER
dengan nomor project yang Anda salin. - Di menu Select a role, pilih peran Kubernetes Engine Default Node Service Account.
- Klik Simpan.
gcloud
- Temukan nomor project Trusted Cloud Anda:
gcloud projects describe PROJECT_ID \ --format="value(projectNumber)"
Ganti
PROJECT_ID
dengan project ID Anda.Outputnya mirip dengan hal berikut ini:
12345678901
- Berikan peran
roles/container.defaultNodeServiceAccount
ke akun layanan default Compute Engine:gcloud projects add-iam-policy-binding PROJECT_ID \ --member="serviceAccount:PROJECT_NUMBER-compute@developer.s3ns-system.iam.gserviceaccount.com" \ --role="roles/container.defaultNodeServiceAccount"
Ganti
PROJECT_NUMBER
dengan nomor project dari langkah sebelumnya.
Error 403: Izin tidak memadai
Error berikut terjadi saat Anda mencoba terhubung ke cluster GKE menggunakan gcloud container clusters get-credentials
, tetapi akun tersebut tidak memiliki izin untuk mengakses server Kubernetes API:
ERROR: (gcloud.container.clusters.get-credentials) ResponseError: code=403, message=Required "container.clusters.get" permission(s) for "projects/<your-project>/locations/<region>/clusters/<your-cluster>".
Untuk mengatasi masalah ini, selesaikan beberapa langkah berikut:
Identifikasi akun yang mengalami masalah akses:
gcloud auth list
Beri akses yang diperlukan ke akun menggunakan petunjuk di bagian Mengautentikasi ke server Kubernetes API.
Error 403: Anggaran coba lagi habis
Error berikut dapat terjadi saat Anda mencoba membuat cluster GKE:
Error: googleapi: Error 403: Retry budget exhausted: Google Compute Engine:
Required permission 'PERMISSION_NAME' for 'RESOURCE_NAME'.
Dalam pesan error ini, variabel berikut berlaku:
PERMISSION_NAME
: nama izin, seperticompute.regions.get
.RESOURCE_NAME
: jalur ke resource Trusted Cloud yang Anda coba akses, seperti region Compute Engine.
Error ini terjadi jika akun layanan IAM yang terlampir ke cluster tidak memiliki izin minimum yang diperlukan untuk membuat cluster.
Untuk menyelesaikan masalah ini, lakukan tindakan berikut:
- Buat atau ubah akun layanan IAM agar memiliki semua izin yang diperlukan untuk menjalankan cluster GKE. Untuk mengetahui petunjuknya, lihat Menggunakan akun layanan IAM dengan hak istimewa terendah.
- Tentukan akun layanan IAM yang diupdate dalam perintah pembuatan cluster Anda menggunakan flag
--service-account
. Untuk mengetahui petunjuknya, lihat Membuat cluster Autopilot.
Atau, hapus tanda --service-account
agar GKE menggunakan akun layanan default Compute Engine di project, yang memiliki izin yang diperlukan secara default.
Error 404: Resource tidak ditemukan
Jika Anda mendapatkan error 404, resource tidak ditemukan, saat memanggil perintah gcloud container
, selesaikan masalah dengan melakukan autentikasi ulang ke Google Cloud CLI:
gcloud auth login
Error 400/403: Izin edit untuk akun tidak ada
Error izin edit untuk akun tidak ada (error 400 atau 403), menunjukkan bahwa salah satu hal berikut telah dihapus atau diedit secara manual:
- Akun layanan default Compute Engine Anda.
- Agen Layanan Google API.
- Akun layanan yang terkait dengan GKE.
Saat Anda mengaktifkan Compute Engine atau GKE API, Trusted Cloud akan membuat akun layanan dan agen berikut:
- Akun layanan default Compute Engine di project Anda. GKE melampirkan akun layanan ini ke node secara default untuk tugas sistem seperti logging dan pemantauan.
- Agen Layanan Google API di project yang dikelola Google, dengan izin edit di project Anda.
- Agen layanan Google Kubernetes Engine dalam project yang dikelola Google, dengan peran Agen Layanan Kubernetes Engine di project Anda.
Pembuatan cluster dan semua pengelolaan akan gagal jika, kapan saja, seseorang mengedit izin tersebut, menghapus binding peran di project, menghapus akun layanan sepenuhnya, atau menonaktifkan API.
Memverifikasi izin untuk agen layanan GKE
Untuk memverifikasi apakah akun layanan Google Kubernetes Engine memiliki peran Kubernetes Engine Service Agent yang ditetapkan pada project, selesaikan langkah-langkah berikut:
Tentukan nama akun layanan Google Kubernetes Engine Anda. Semua akun layanan memiliki format berikut:
service-PROJECT_NUMBER@container-engine-robot.s3ns-system.iam.gserviceaccount.com
Ganti
PROJECT_NUMBER
dengan nomor project Anda.Pastikan akun layanan Google Kubernetes Engine Anda tidak memiliki peran Kubernetes Engine Service Agent yang ditetapkan pada project:
gcloud projects get-iam-policy PROJECT_ID
Ganti
PROJECT_ID
dengan project ID Anda.
Untuk memperbaiki masalah ini, jika seseorang menghapus peran Agen Layanan Kubernetes Engine dari akun layanan Google Kubernetes Engine Anda, tambahkan kembali peran tersebut. Jika tidak, gunakan petunjuk berikut untuk mengaktifkan kembali Kubernetes Engine API, yang akan memulihkan akun layanan dan izin Anda:
Konsol
Buka halaman APIs & Services di konsol Trusted Cloud .
Pilih project Anda.
Klik Aktifkan API dan Layanan.
Telusuri Kubernetes, lalu pilih API dari hasil penelusuran.
Klik Enable. Jika sebelumnya Anda telah mengaktifkan API, Anda harus menonaktifkannya terlebih dahulu, lalu mengaktifkannya kembali. Diperlukan waktu beberapa menit agar API dan layanan terkait diaktifkan.
gcloud
Jalankan perintah berikut di gcloud CLI:
PROJECT_NUMBER=$(gcloud projects describe "PROJECT_ID"
--format 'get(projectNumber)')
gcloud projects add-iam-policy-binding PROJECT_ID \
--member "serviceAccount:service-${PROJECT_NUMBER?}@container-engine-robot.s3ns-system.iam.gserviceaccount.com" \
--role roles/container.serviceAgent
Langkah berikutnya
Jika Anda tidak dapat menemukan solusi untuk masalah Anda dalam dokumentasi, lihat Mendapatkan dukungan untuk mendapatkan bantuan lebih lanjut, termasuk saran tentang topik berikut:
- Membuka kasus dukungan dengan menghubungi Layanan Pelanggan Cloud.
- Mendapatkan dukungan dari komunitas dengan
mengajukan pertanyaan di StackOverflow
dan menggunakan tag
google-kubernetes-engine
untuk menelusuri masalah serupa. Anda juga dapat bergabung ke#kubernetes-engine
channel Slack untuk mendapatkan dukungan komunitas lainnya. - Membuka bug atau permintaan fitur menggunakan issue tracker publik.