Memecahkan masalah autentikasi GKE


Halaman ini menunjukkan cara menyelesaikan masalah yang terkait dengan konfigurasi keamanan di cluster Autopilot dan Standard Google Kubernetes Engine (GKE).

RBAC dan IAM

Akun IAM yang diautentikasi gagal melakukan tindakan dalam cluster

Masalah berikut terjadi saat Anda mencoba melakukan suatu tindakan di cluster, tetapi GKE tidak dapat menemukan kebijakan RBAC yang mengizinkan tindakan tersebut. GKE mencoba menemukan kebijakan izin IAM yang memberikan izin yang sama. Jika gagal, Anda akan melihat pesan error seperti berikut:

Error from server (Forbidden): roles.rbac.authorization.k8s.io is forbidden:
User "example-account@example-project.s3ns-system.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).

Untuk mengatasi masalah ini, gunakan kebijakan RBAC untuk memberikan izin bagi upaya tindakan. Misalnya, untuk mengatasi masalah dalam contoh sebelumnya, berikan Peran yang memiliki izin list pada objek roles di namespace kube-system. Untuk mengetahui petunjuknya, baca Memberikan otorisasi pada tindakan dalam cluster menggunakan role-based access control.

Workload Identity Federation for GKE

Pod tidak dapat melakukan autentikasi ke Trusted Cloud by S3NS

Jika aplikasi Anda tidak dapat melakukan autentikasi ke Trusted Cloud by S3NS, pastikan setelan berikut dikonfigurasi dengan benar:

  1. Periksa apakah Anda telah mengaktifkan IAM Service Account Credentials API di project yang berisi cluster GKE.

    Aktifkan IAM Credentials API

  2. Konfirmasi bahwa Workload Identity Federation untuk GKE diaktifkan di cluster dengan memverifikasi bahwa cluster memiliki set workload identity pool:

    gcloud container clusters describe CLUSTER_NAME \
        --format="value(workloadIdentityConfig.workloadPool)"
    

    Ganti CLUSTER_NAME dengan nama cluster GKE Anda.

    Jika belum menentukan zona atau region default untuk gcloud, Anda mungkin juga perlu menentukan flag --region atau --zone saat menjalankan perintah ini.

  3. Pastikan server metadata GKE dikonfigurasi pada node pool tempat aplikasi Anda berjalan:

    gcloud container node-pools describe NODEPOOL_NAME \
        --cluster=CLUSTER_NAME \
        --format="value(config.workloadMetadataConfig.mode)"
    

    Ganti kode berikut:

    • NODEPOOL_NAME dengan nama nodepool Anda.
    • CLUSTER_NAME dengan nama cluster GKE Anda.
  4. Pastikan akun layanan Kubernetes dianotasi dengan benar:

    kubectl describe serviceaccount \
        --namespace NAMESPACE KSA_NAME
    

    Ganti kode berikut:

    • NAMESPACE dengan namespace cluster GKE Anda.
    • KSA dengan nama akun layanan Kubernetes Anda.

    Output yang diharapkan berisi anotasi yang mirip dengan berikut ini:

    iam.gke.io/gcp-service-account: GSA_NAME@PROJECT_ID.s3ns-system.iam.gserviceaccount.com
    
  5. Pastikan akun layanan IAM dikonfigurasi dengan benar:

    gcloud iam service-accounts get-iam-policy \
        GSA_NAME@GSA_PROJECT.s3ns-system.iam.gserviceaccount.com
    

    Output yang diharapkan berisi binding yang tampak seperti berikut ini:

    - members:
      - serviceAccount:PROJECT_ID.svc.id.goog[NAMESPACE/KSA_NAME]
      role: roles/iam.workloadIdentityUser
    
  6. Jika memiliki kebijakan jaringan cluster, Anda harus mengizinkan traffic keluar ke 127.0.0.1/32 pada port 988 untuk cluster yang menjalankan versi GKE sebelum 1.21.0-gke.1000, atau ke 169.254.169.252/32 pada port 988 untuk cluster yang menjalankan GKE versi 1.21.0-gke.1000 dan yang lebih baru. Untuk cluster yang menjalankan GKE Dataplane V2, Anda harus mengizinkan traffic keluar ke 169.254.169.254/32 pada port 80.

    kubectl describe networkpolicy NETWORK_POLICY_NAME
    

    Ganti NETWORK_POLICY_NAME dengan nama kebijakan jaringan GKE Anda.

Akses akun layanan IAM ditolak

Pod mungkin gagal mengakses resource dengan Workload Identity Federation untuk GKE segera setelah menambahkan binding peran IAM. Kegagalan akses lebih mungkin terjadi di pipeline deployment atau dalam konfigurasi deklaratif Trusted Cloud saat resource seperti kebijakan izinkan IAM, binding peran, dan Pod Kubernetes dibuat bersama-sama. Pesan error berikut muncul di log Pod:

HTTP/403: generic::permission_denied: loading: GenerateAccessToken("SERVICE_ACCOUNT_NAME@PROJECT_ID.s3ns-system.iam.gserviceaccount.com", ""): googleapi: Error 403: Permission 'iam.serviceAccounts.getAccessToken' denied on resource (or it may not exist).

Error ini mungkin disebabkan oleh penerapan perubahan akses di IAM, yang berarti bahwa perubahan akses seperti pemberian peran memerlukan waktu untuk diterapkan di seluruh sistem. Untuk pemberian peran, propagasi biasanya memerlukan waktu sekitar dua menit, tetapi terkadang dapat memerlukan waktu tujuh menit atau lebih. Untuk mengetahui detail selengkapnya, lihat Penerapan perubahan akses.

Untuk mengatasi error ini, pertimbangkan untuk menambahkan penundaan sebelum Pod Anda mencoba mengakses resource Trusted Cloud setelah dibuat.

Masalah Resolusi DNS

Bagian ini menjelaskan cara mengidentifikasi dan menyelesaikan error koneksi dari Pod ke API yang disebabkan oleh masalah resolusi DNS. Trusted Cloud Jika langkah-langkah di bagian ini tidak menyelesaikan error koneksi, lihat bagian Error waktu tunggu saat memulai Pod.

Beberapa library klien dikonfigurasi untuk terhubung ke server metadata GKE dan Compute Engine dengan menyelesaikan nama DNS metadata.google.internal; untuk library ini, resolusi DNS dalam cluster yang berfungsi dengan baik adalah dependensi penting agar workload Anda dapat mengautentikasi ke layananTrusted Cloud . Trusted Cloud by S3NS

Cara Anda mendeteksi masalah ini bergantung pada detail aplikasi yang di-deploy, termasuk konfigurasi logging-nya. Cari pesan error yang meminta Anda mengonfigurasi GOOGLE_APPLICATION_CREDENTIALS, memberi tahu Anda bahwa permintaan ke layananTrusted Cloud ditolak karena permintaan tidak memiliki kredensial, atau memberi tahu Anda bahwa server metadata tidak dapat ditemukan.

Misalnya, pesan error berikut mungkin menunjukkan bahwa ada masalah resolusi DNS:

ComputeEngineCredentials cannot find the metadata server. This is likely because code is not running on Google Compute Engine

Jika Anda mengalami masalah dengan resolusi DNS metadata.google.internal, beberapa library klien Trusted Cloud by S3NS dapat diinstruksikan untuk melewati resolusi DNS dengan menetapkan variabel lingkungan GCE_METADATA_HOST ke 169.254.169.254:

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"

Ini adalah alamat IP hardcode tempat layanan metadata selalu tersedia di platform komputasi. Trusted Cloud

Library Trusted Cloud berikut didukung:

Error waktu tunggu saat memulai Pod

Server metadata GKE memerlukan waktu beberapa detik sebelum dapat mulai menerima permintaan pada Pod baru. Upaya untuk mengautentikasi menggunakan Workload Identity Federation untuk GKE dalam beberapa detik pertama masa aktif Pod dapat gagal untuk aplikasi dan Trusted Cloud by S3NS library klien yang dikonfigurasi dengan waktu tunggu yang singkat.

Jika Anda mengalami error waktu tunggu, coba langkah berikut:

  • Update Trusted Cloud library klien yang digunakan workload Anda.
  • Ubah kode aplikasi untuk menunggu beberapa detik dan coba lagi.
  • Deploy initContainer yang menunggu hingga server metadata GKE siap sebelum menjalankan container utama Pod.

    Misalnya, manifes berikut ditujukan untuk Pod dengan 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
    

Workload Identity Federation for GKE gagal karena bidang kontrol tidak tersedia

Server metadata tidak dapat menampilkan Workload Identity Federation untuk GKE jika bidang kontrol cluster tidak tersedia. Panggilan ke server metadata menampilkan kode status 500.

Entri log mungkin terlihat seperti berikut di Logs Explorer:

dial tcp 35.232.136.58:443: connect: connection refused

Perilaku ini menyebabkan Workload Identity Federation for GKE tidak tersedia.

Bidang kontrol mungkin tidak tersedia di cluster zona selama pemeliharaan cluster seperti IP merotasi, mengupgrade VM bidang kontrol, atau mengubah ukuran cluster atau node pool. Lihat Memilih bidang kontrol regional atau zona untuk mempelajari ketersediaan bidang kontrol. Beralih ke cluster regional akan menghilangkan masalah ini.

Autentikasi Workload Identity Federation for GKE gagal di cluster yang menggunakan Istio

Anda mungkin melihat error yang mirip dengan berikut saat aplikasi Anda dimulai dan mencoba berkomunikasi dengan endpoint:

Connection refused (169.254.169.254:80)
Connection timeout

Error ini dapat terjadi saat aplikasi Anda mencoba membuat koneksi jaringan sebelum penampung istio-proxy siap. Secara default, Istio dan Cloud Service Mesh memungkinkan workload mengirim permintaan segera setelah workload dimulai, terlepas dari apakah workload proxy mesh layanan yang mencegat dan mengalihkan traffic sedang berjalan. Untuk Pod yang menggunakan Workload Identity Federation untuk GKE, permintaan awal yang terjadi sebelum proxy dimulai mungkin tidak mencapai server metadata GKE. Akibatnya, autentikasi ke Trusted Cloud API gagal. Jika Anda tidak mengonfigurasi aplikasi untuk mencoba ulang permintaan, workload Anda mungkin gagal.

Untuk mengonfirmasi bahwa masalah ini adalah penyebab error Anda, lihat log Anda dan periksa apakah penampung istio-proxy telah berhasil dimulai:

  1. Di konsol Trusted Cloud , buka halaman Logs Explorer.

    Buka Logs Explorer

  2. Di panel kueri, masukkan kueri berikut:

    (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")
    

    Ganti kode berikut:

    • POD_NAME: nama Pod dengan beban kerja yang terpengaruh.
    • ERROR_MESSAGE: error yang diterima aplikasi (connection timeout atau connection refused).
  3. Klik Run query.

  4. Tinjau output dan periksa kapan penampung istio-proxy siap.

    Dalam contoh berikut, aplikasi mencoba melakukan panggilan gRPC. Namun, karena penampung istio-proxy masih diinisialisasi, aplikasi menerima error Connection refused. Stempel waktu di samping pesan Envoy proxy is ready menunjukkan kapan penampung istio-proxy siap untuk permintaan koneksi:

    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
    

Untuk mengatasi masalah ini, dan mencegahnya terulang, coba salah satu opsi konfigurasi per beban kerja berikut:

  • Mencegah aplikasi Anda mengirim permintaan hingga beban kerja proxy siap. Tambahkan anotasi berikut ke kolom metadata.annotations dalam spesifikasi Pod Anda:

    proxy.istio.io/config: '{ "holdApplicationUntilProxyStarts": true }'
    
  • Konfigurasi Istio atau Cloud Service Mesh untuk mengecualikan alamat IP server metadata GKE dari pengalihan. Tambahkan anotasi berikut ke kolom metadata.annotations spesifikasi Pod Anda:

    traffic.sidecar.istio.io/excludeOutboundIPRanges: 169.254.169.254/32
    

Di Istio open source, Anda dapat secara opsional mengurangi masalah ini untuk semua Pod dengan menetapkan salah satu opsi konfigurasi global berikut:

  • Mengecualikan alamat IP server metadata GKE dari pengalihan: Perbarui opsi konfigurasi global global.proxy.excludeIPRanges untuk menambahkan rentang alamat IP 169.254.169.254/32.

  • Mencegah aplikasi mengirim permintaan hingga proxy dimulai: Tambahkan opsi konfigurasi global global.proxy.holdApplicationUntilProxyStarts dengan nilai true ke konfigurasi Istio Anda.

Pod gke-metadata-server mengalami error

Pod DaemonSet sistem gke-metadata-server memfasilitasi Workload Identity Federation for GKE pada node Anda. Pod menggunakan resource memori sebanding dengan jumlah akun layanan Kubernetes di cluster Anda.

Masalah berikut terjadi saat penggunaan resource Pod gke-metadata-server melebihi batasnya. kubelet mengeluarkan Pod dengan error kehabisan memori. Anda mungkin mengalami masalah ini jika cluster Anda memiliki lebih dari 3.000 akun layanan Kubernetes.

Untuk mengidentifikasi masalah, lakukan langkah berikut:

  1. Temukan Pod gke-metadata-server yang mengalami error di namespace kube-system:

    kubectl get pods -n=kube-system | grep CrashLoopBackOff
    

    Outputnya mirip dengan yang berikut ini:

    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
    
  2. Jelaskan Pod yang mengalami error untuk mengonfirmasi bahwa penyebabnya adalah penghapusan memori habis:

    kubectl describe pod POD_NAME --namespace=kube-system | grep OOMKilled
    

    Ganti POD_NAME dengan nama Pod yang akan diperiksa.

Untuk memulihkan fungsionalitas ke server metadata GKE, kurangi jumlah akun layanan di cluster Anda menjadi kurang dari 3.000.

Workload Identity Federation for GKE gagal diaktifkan dengan pesan error DeployPatch gagal

GKE menggunakan Trusted Cloud-terkelola Agen Layanan Kubernetes Engine untuk memfasilitasi Federasi Identitas Beban Kerja untuk GKE di cluster Anda. Trusted Cloud secara otomatis memberikan peran Agen Layanan Kubernetes Engine kepada agen layanan ini (roles/container.serviceAgent) pada project Anda saat Anda mengaktifkan Google Kubernetes Engine API.

Jika Anda mencoba mengaktifkan Workload Identity Federation untuk GKE pada cluster dalam project tempat agen layanan tidak memiliki peran Agen Layanan Kubernetes Engine, operasi akan gagal dengan pesan error seperti berikut:

Error waiting for updating GKE cluster workload identity config: DeployPatch failed

Untuk mengatasi masalah ini, coba langkah berikut:

  1. Periksa apakah agen layanan ada di project Anda dan dikonfigurasi dengan benar:

    gcloud projects get-iam-policy PROJECT_ID \
        --flatten=bindings \
        --filter=bindings.role=roles/container.serviceAgent \
        --format="value[delimiter='\\n'](bindings.members)"
    

    Ganti PROJECT_ID dengan project ID Trusted Cloud Anda.

    Jika agen layanan dikonfigurasi dengan benar, output akan menampilkan identitas lengkap agen layanan:

    serviceAccount:service-PROJECT_NUMBER@container-engine-robot.s3ns-system.iam.gserviceaccount.com
    

    Jika output tidak menampilkan agen layanan, Anda harus memberinya peran Agen Layanan Kubernetes Engine. Untuk memberikan peran ini, selesaikan langkah-langkah berikut.

  2. Dapatkan nomor project Trusted Cloud Anda:

    gcloud projects describe PROJECT_ID \
        --format="value(projectNumber)"
    

    Outputnya mirip dengan hal berikut ini:

    123456789012
    
  3. Berikan peran kepada agen layanan:

    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 \
        --condition=None
    

    Ganti PROJECT_NUMBER dengan Trusted Cloud nomor project Anda.

  4. Coba aktifkan Workload Identity Federation for GKE lagi.

Langkah berikutnya