Memecahkan masalah keamanan cluster


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 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.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

Pod tidak dapat melakukan autentikasi ke Google Cloud

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

  1. Pastikan Anda telah mengaktifkan IAM Service Account Credentials API pada project yang berisi cluster GKE.

    Aktifkan IAM Credentials API

  2. Pastikan Workload Identity diaktifkan pada cluster dengan memverifikasi bahwa cluster memiliki set workload identity pool:

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

    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)"
    
  4. Pastikan akun layanan Kubernetes dianotasi dengan benar:

    kubectl describe serviceaccount \
        --namespace NAMESPACE KSA_NAME
    

    Output-nya berisi anotasi yang tampak seperti berikut ini:

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

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

    Outputnya 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, pastikan Anda 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, pastikan Anda mengizinkan traffic keluar ke 169.254.169.254/32 pada port 80.

    kubectl describe networkpolicy NETWORK_POLICY_NAME
    

Error waktu tunggu saat memulai Pod

Server metadata GKE memerlukan waktu beberapa detik sebelum dapat mulai menerima permintaan pada Pod baru. Oleh karena itu, upaya untuk mengautentikasi menggunakan Workload Identity dalam beberapa detik pertama masa aktif Pod dapat gagal untuk aplikasi dan library klien Google Cloud yang dikonfigurasi dengan waktu tunggu yang singkat.

Jika Anda mengalami error waktu tunggu, coba langkah berikut:

  • Update library klien Google Cloud 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 gagal karena bidang kontrol tidak tersedia

Server metadata tidak dapat menampilkan Workload Identity 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

Hal ini akan menyebabkan ketidaktersediaan Workload Identity yang diperkirakan.

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

Workload Identity gagal

Jika server metadata GKE diblokir karena alasan apa pun, Workload Identity akan gagal.

Jika menggunakan Istio, Anda harus menambahkan anotasi tingkat aplikasi berikut ke semua workload yang menggunakan Workload Identity:

"traffic.sidecar.istio.io/excludeOutboundIPRanges=169.254.169.254/32"

Sebagai alternatif, Anda dapat mengubah kunci Istio ConfigMap global.proxy.excludeIPRanges untuk melakukan hal yang sama.

Pod gke-metadata-server mengalami error

Sistem gke-metadata-server DaemonSet Pod memfasilitasi Workload Identity 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 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
    

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

Workload Identity gagal diaktifkan dengan pesan error DeployPatch gagal

GKE menggunakan Agen Layanan Kubernetes Engine yang dikelola Google Cloud untuk memfasilitasi Workload Identity di cluster Anda. Google Cloud secara otomatis memberikan peran Agen Layanan Kubernetes Engine kepada agen layanan ini (roles/container.serviceAgent) pada project Anda saat mengaktifkan Google Kubernetes Engine API.

Jika Anda mencoba mengaktifkan Workload Identity pada cluster dalam project tempat agen layanan tidak memiliki peran Agen Layanan Kubernetes Engine, operasinya 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 Google Cloud Anda.

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

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

    Jika output tidak menampilkan agen layanan, Anda harus memberinya peran Agen Layanan Kubernetes Engine.

  2. Dapatkan nomor project Google Cloud Anda:

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

    Outputnya mirip dengan yang 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.iam.gserviceaccount.com \
        --role=roles/container.serviceAgent \
        --condition=None
    

    Ganti PROJECT_NUMBER dengan nomor project Google Cloud Anda.

Coba aktifkan Workload Identity lagi.