Memecahkan masalah workload yang di-deploy


Halaman ini menunjukkan cara menyelesaikan error pada workload yang di-deploy di Google Kubernetes Engine (GKE).

Untuk mendapatkan saran umum lainnya tentang cara memecahkan masalah aplikasi, lihat Memecahkan Masalah Aplikasi dalam dokumentasi Kubernetes.

Semua error: Periksa status Pod

Jika ada masalah dengan Pod workload, Kubernetes akan memperbarui status Pod dengan pesan error. Lihat error ini dengan memeriksa status Pod menggunakan Konsol Google Cloud atau alat command line kubectl.

Konsol

Lakukan langkah-langkah berikut:

  1. Di konsol Google Cloud, buka halaman Workload.

    Buka Workloads

  2. Pilih beban kerja yang ingin Anda selidiki. Tab Ringkasan menampilkan status beban kerja.

  3. Dari bagian Pod yang Dikelola, klik pesan status error.

kubectl

Untuk melihat semua Pod yang berjalan di cluster Anda, jalankan perintah berikut:

kubectl get pods

Outputnya mirip dengan hal berikut ini:

NAME       READY  STATUS             RESTARTS  AGE
POD_NAME   0/1    CrashLoopBackOff   23        8d

Potensi error tercantum di kolom Status.

Untuk mendapatkan informasi selengkapnya tentang Pod tertentu, jalankan perintah berikut:

kubectl describe pod POD_NAME

Ganti POD_NAME dengan nama Pod yang ingin Anda selidiki.

Dalam output, kolom Events menampilkan informasi selengkapnya tentang error.

Jika Anda menginginkan informasi selengkapnya, lihat log penampung:

kubectl logs POD_NAME

Log ini dapat membantu Anda mengidentifikasi apakah perintah atau kode dalam penampung menyebabkan Pod error.

Setelah mengidentifikasi error, gunakan bagian berikut untuk mencoba menyelesaikan masalah.

Error: CrashLoopBackOff

Status CrashLoopBackOff tidak berarti ada error tertentu, tetapi menunjukkan bahwa penampung berulang kali mengalami error setelah dimulai ulang. Saat container mengalami error atau keluar segera setelah dimulai (CrashLoop), Kubernetes akan mencoba memulai ulang container. Dengan setiap dimulai ulang yang gagal, penundaan (BackOff) sebelum upaya berikutnya akan meningkat secara eksponensial (10 dtk, 20 dtk, 40 dtk, dll.), hingga maksimum lima menit.

Bagian berikut membantu Anda mengidentifikasi penyebab penampung mungkin mengalami error.

Menggunakan playbook interaktif Crashlooping Pods

Mulai pecahkan masalah yang menyebabkan status CrashLoopBackOff menggunakan playbook interaktif di konsol Google Cloud:

  1. Buka playbook interaktif Crashlooping Pods:

    Buka Playbook

  2. Di menu drop-down Cluster, pilih cluster yang ingin Anda pecahkan masalahnya. Jika Anda tidak dapat menemukan cluster, masukkan nama cluster di kolom Filter .

  3. Di menu drop-down Namespace, pilih namespace yang ingin Anda pecahkan masalahnya. Jika Anda tidak dapat menemukan namespace, masukkan namespace di kolom Filter .

  4. Pelajari setiap bagian untuk membantu Anda mengidentifikasi penyebabnya:

    1. Mengidentifikasi Error Aplikasi
    2. Menyelidiki Masalah Kehabisan Memori
    3. Menyelidiki Gangguan Node
    4. Menyelidiki Kegagalan Pemeriksaan Keaktifan
    5. Menghubungkan Peristiwa Perubahan
  5. Opsional: Untuk mendapatkan notifikasi tentang error CrashLoopBackOff di masa mendatang, di bagian Tips Mitigasi di Masa Mendatang, pilih Buat Pemberitahuan.

Memeriksa log

Container mungkin mengalami error lagi karena berbagai alasan, dan memeriksa log Pod dapat membantu Anda memecahkan akar masalah.

Anda dapat memeriksa log dengan konsol Google Cloud atau alat command line kubectl.

Konsol

Lakukan langkah-langkah berikut:

  1. Buka halaman Workload di Konsol Google Cloud.

    Buka Workloads

  2. Pilih beban kerja yang ingin Anda selidiki. Tab Ringkasan menampilkan status beban kerja.

  3. Dari bagian Pod yang Dikelola, klik Pod yang bermasalah.

  4. Dari menu Pod, klik tab Log.

kubectl

  1. Lihat semua Pod yang berjalan di cluster Anda:

    kubectl get pods
    
  2. Pada output perintah sebelumnya, cari Pod dengan error CrashLoopBackOff di kolom Status.

  3. Dapatkan log Pod:

    kubectl logs POD_NAME
    

    Ganti POD_NAME dengan nama Pod yang bermasalah.

    Anda juga dapat meneruskan flag -p guna mendapatkan log untuk instance container Pod sebelumnya, jika ada.

Memeriksa kode keluar dari penampung yang mengalami error

Untuk lebih memahami penyebab error pada penampung, temukan kode keluar:

  1. Deskripsikan Pod:

    kubectl describe pod POD_NAME
    

    Ganti POD_NAME dengan nama Pod yang bermasalah.

  2. Tinjau nilai di kolom containers: CONTAINER_NAME: last state: exit code:

    • Jika exit code adalah 1, container mengalami error karena aplikasi mengalami error.
    • Jika exit code adalah 0, periksa berapa lama aplikasi Anda berjalan. Penampung berhenti saat proses utama aplikasi Anda berhenti. Jika aplikasi Anda menyelesaikan eksekusi dengan sangat cepat, penampung mungkin terus dimulai ulang. Jika Anda mengalami error ini, salah satu solusinya adalah menetapkan kolom restartPolicy ke OnFailure. Setelah Anda melakukan perubahan ini, aplikasi hanya dimulai ulang saat kode keluar bukan 0.

Menghubungkan ke penampung yang sedang berjalan

Untuk menjalankan perintah bash dari penampung sehingga Anda dapat menguji jaringan atau memeriksa apakah Anda memiliki akses ke file atau database yang digunakan oleh aplikasi, buka shell ke Pod:

kubectl exec -it POD_NAME -- /bin/bash

Jika ada lebih dari satu penampung di Pod Anda, tambahkan -c CONTAINER_NAME.

Error: ImagePullBackOff dan ErrImagePull

Status ImagePullBackOff atau ErrImagePull menunjukkan bahwa image yang digunakan oleh penampung tidak dapat dimuat dari registry image.

Anda dapat memastikan masalah ini menggunakan Konsol Google Cloud atau alat command line kubectl.

Konsol

Lakukan langkah-langkah berikut:

  1. Di konsol Google Cloud, buka halaman Workload.

    Buka Workloads

  2. Pilih beban kerja yang ingin Anda selidiki. Tab Ringkasan menampilkan status workload.

  3. Dari bagian Pod yang Dikelola, klik Pod yang bermasalah.

  4. Dari menu Pod, klik tab Peristiwa.

kubectl

Untuk mendapatkan informasi selengkapnya tentang image container Pod, jalankan perintah berikut:

kubectl describe pod POD_NAME

Masalah: Gambar tidak ditemukan

Jika gambar Anda tidak ditemukan, selesaikan langkah-langkah berikut:

  1. Pastikan nama gambar sudah benar.
  2. Pastikan tag untuk gambar sudah benar. (Coba :latest atau tanpa tag untuk mengambil image terbaru).
  3. Jika image memiliki jalur registry lengkap, pastikan image tersebut ada di registry Docker yang Anda gunakan. Jika Anda hanya memberikan nama image, periksa registry Docker Hub.
  4. Di cluster GKE Standard, coba ambil image Docker secara manual:

    1. Gunakan SSH untuk terhubung ke node:

      Misalnya, untuk menggunakan SSH guna terhubung ke VM, jalankan perintah berikut:

      gcloud compute ssh VM_NAME --zone=ZONE_NAME
      

      Ganti kode berikut:

    2. Buat file konfigurasi di /home/[USER]/.docker/config.json:

      docker-credential-gcr configure-docker
      

      Pastikan file konfigurasi di /home/[USER]/.docker/config.json menyertakan registry gambar di kolom credHelpers. Misalnya, file berikut menyertakan informasi autentikasi untuk image yang dihosting di asia.gcr.io, eu.gcr.io, gcr.io, marketplace.gcr.io, dan us.gcr.io:

      {
      "auths": {},
      "credHelpers": {
        "asia.gcr.io": "gcr",
        "eu.gcr.io": "gcr",
        "gcr.io": "gcr",
        "marketplace.gcr.io": "gcr",
        "us.gcr.io": "gcr"
      }
      }
      
    3. Coba ambil gambar:

      docker pull IMAGE_NAME
      

    Jika menarik gambar secara manual berhasil, Anda mungkin perlu menentukan ImagePullSecrets di Pod. Pod hanya dapat mereferensikan Secret pengambilan image dalam namespace-nya sendiri, sehingga proses ini perlu dilakukan satu kali per namespace.

Error: Izin ditolak

Jika menerima error "izin ditolak" atau "tidak ada akses pengambilan", pastikan Anda sudah login dan memiliki akses ke image tersebut. Coba salah satu metode berikut, bergantung pada registry tempat Anda menghosting gambar.

Artifact Registry

Jika image Anda berada di Artifact Registry, akun layanan node pool Anda memerlukan akses baca ke repositori yang berisi image tersebut.

Berikan peran artifactregistry.reader ke akun layanan:

gcloud artifacts repositories add-iam-policy-binding REPOSITORY_NAME \
    --location=REPOSITORY_LOCATION \
    --member=serviceAccount:SERVICE_ACCOUNT_EMAIL \
    --role="roles/artifactregistry.reader"

Ganti kode berikut:

  • REPOSITORY_NAME: nama repositori Artifact Registry Anda.
  • REPOSITORY_LOCATION: Region repositori Artifact Registry Anda.
  • SERVICE_ACCOUNT_EMAIL: alamat email akun layanan IAM yang dikaitkan dengan node pool Anda.

Container Registry

Jika image Anda ada di Container Registry, akun layanan node pool Anda memerlukan akses baca ke bucket Cloud Storage yang berisi image tersebut.

Berikan peran roles/storage.objectViewer ke akun layanan agar dapat membaca dari bucket:

gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME \
    --member=serviceAccount:SERVICE_ACCOUNT_EMAIL \
    --role=roles/storage.objectViewer

Ganti kode berikut:

  • SERVICE_ACCOUNT_EMAIL: email akun layanan yang dikaitkan dengan node pool Anda. Anda dapat mencantumkan semua akun layanan di project menggunakan gcloud iam service-accounts list.
  • BUCKET_NAME: nama bucket Cloud Storage yang berisi image Anda. Anda dapat mencantumkan semua bucket dalam project menggunakan gcloud storage ls.

Jika administrator registry Anda menyiapkan repositori gcr.io di Artifact Registry untuk menyimpan image bagi domain gcr.io, dan bukan di Container Registry, Anda harus memberikan akses baca ke Artifact Registry, bukan Container Registry.

Registry pribadi

Jika image berada di registry pribadi, Anda mungkin memerlukan kunci untuk mengakses image. Untuk informasi selengkapnya, lihat Menggunakan registry pribadi dalam dokumentasi Kubernetes.

Error 401 Tidak sah: Tidak dapat mengambil image dari repositori container registry pribadi

Error yang serupa dengan berikut mungkin terjadi saat Anda mengambil image dari repositori Container Registry pribadi:

gcr.io/PROJECT_ID/IMAGE:TAG: rpc error: code = Unknown desc = failed to pull and
unpack image gcr.io/PROJECT_ID/IMAGE:TAG: failed to resolve reference
gcr.io/PROJECT_ID/IMAGE]:TAG: unexpected status code [manifests 1.0]: 401 Unauthorized

Warning  Failed     3m39s (x4 over 5m12s)  kubelet            Error: ErrImagePull
Warning  Failed     3m9s (x6 over 5m12s)   kubelet            Error: ImagePullBackOff
Normal   BackOff    2s (x18 over 5m12s)    kubelet            Back-off pulling image

Untuk mengatasi error ini, selesaikan langkah-langkah berikut:

  1. Identifikasi node yang menjalankan Pod:

    kubectl describe pod POD_NAME | grep "Node:"
    
  2. Pastikan node yang Anda identifikasi di langkah sebelumnya memiliki cakupan penyimpanan:

    gcloud compute instances describe NODE_NAME \
        --zone=COMPUTE_ZONE --format="flattened(serviceAccounts[].scopes)"
    

    Cakupan akses node harus berisi minimal salah satu cakupan berikut:

    serviceAccounts[0].scopes[0]: https://www.googleapis.com/auth/devstorage.read_only
    serviceAccounts[0].scopes[0]: https://www.googleapis.com/auth/cloud-platform
    

    Jika node tidak berisi salah satu cakupan ini, buat ulang node pool.

  3. Buat ulang node pool tempat node tersebut berada dengan cakupan yang memadai. Anda tidak dapat mengubah node yang sudah ada, dan Anda harus membuat ulang node dengan cakupan yang benar.

    • Direkomendasikan: Buat node pool baru dengan cakupan gke-default:

      gcloud container node-pools create NODE_POOL_NAME \
          --cluster=CLUSTER_NAME \
          --zone=COMPUTE_ZONE \
          --scopes="gke-default"
      
    • Buat node pool baru dengan cakupan penyimpanan saja:

      gcloud container node-pools create NODE_POOL_NAME \
          --cluster=CLUSTER_NAME \
          --zone=COMPUTE_ZONE \
          --scopes="https://www.googleapis.com/auth/devstorage.read_only"
      

Error: Pod tidak dapat dijadwalkan

Status PodUnschedulable menunjukkan bahwa Pod Anda tidak dapat dijadwalkan karena resource tidak memadai atau adanya error konfigurasi.

Jika telah mengonfigurasi metrik bidang kontrol, Anda dapat menemukan informasi selengkapnya tentang error ini di metrik penjadwal dan metrik server API.

Menggunakan playbook interaktif Pod yang tidak dapat dijadwalkan

Anda dapat memecahkan masalah error PodUnschedulable menggunakan playbook interaktif di Konsol Google Cloud:

  1. Buka playbook interaktif Pod yang tidak dapat dijadwalkan:

    Buka Playbook

  2. Di menu drop-down Cluster, pilih cluster yang ingin Anda pecahkan masalahnya. Jika Anda tidak dapat menemukan cluster, masukkan nama cluster di kolom Filter .

  3. Di menu drop-down Namespace, pilih namespace yang ingin Anda pecahkan masalahnya. Jika Anda tidak dapat menemukan namespace, masukkan namespace di kolom Filter .

  4. Untuk membantu Anda mengidentifikasi penyebabnya, pelajari setiap bagian dalam playbook:

    1. Menyelidiki CPU dan Memori
    2. Menyelidiki Pod Maksimum per Node
    3. Menyelidiki Perilaku Autoscaler
    4. Menginvestigasi Mode Kegagalan Lainnya
    5. Menghubungkan Peristiwa Perubahan
  5. Opsional: Untuk mendapatkan notifikasi tentang error PodUnschedulable di masa mendatang, di bagian Tips Mitigasi di Masa Mendatang, pilih Buat Pemberitahuan .

Error: Resource tidak cukup

Anda mungkin mengalami error yang menunjukkan kurangnya CPU, memori, atau resource lainnya. Misalnya: No nodes are available that match all of the predicates: Insufficient cpu (2) yang menunjukkan bahwa, di dua node, tidak ada CPU yang cukup untuk memenuhi permintaan Pod.

Jika permintaan resource Pod Anda melebihi permintaan yang tersedia pada satu node dari setiap node pool yang memenuhi syarat, GKE tidak akan menjadwalkan Pod tersebut dan juga tidak akan memicu peningkatan skala untuk menambahkan node baru. Agar GKE dapat menjadwalkan Pod, Anda harus meminta lebih sedikit resource untuk Pod, atau membuat node pool baru dengan resource yang memadai.

Anda juga dapat mengaktifkan penyediaan otomatis node sehingga GKE dapat otomatis membuat node pool dengan node tempat Pod yang tidak terjadwal dapat dijalankan.

Permintaan CPU default adalah 100 m atau 10% dari CPU (atau satu core). Jika Anda ingin meminta lebih banyak atau lebih sedikit resource, tentukan nilai dalam spesifikasi Pod di bagian spec: containers: resources: requests.

Error: MatchNodeSelector

MatchNodeSelector menunjukkan bahwa tidak ada node yang cocok dengan pemilih label Pod.

Untuk memastikan hal ini, periksa label yang ditentukan dalam kolom nodeSelector spesifikasi Pod, pada bagian spec: nodeSelector.

Untuk melihat label pada node di cluster Anda, jalankan perintah berikut:

kubectl get nodes --show-labels

Untuk melampirkan label ke node, jalankan perintah berikut:

kubectl label nodes NODE_NAME LABEL_KEY=LABEL_VALUE

Ganti kode berikut:

  • NODE_NAME: node yang ingin Anda tambahi label.
  • LABEL_KEY: kunci label.
  • LABEL_VALUE: nilai label.

Untuk informasi selengkapnya, lihat Menetapkan Pod ke Node dalam dokumentasi Kubernetes.

Error: PodToleratesNodeTaints

PodToleratesNodeTaints menunjukkan bahwa Pod tidak dapat dijadwalkan ke node mana pun karena Pod tidak memiliki toleransi yang sesuai dengan taint node yang ada.

Untuk memastikan bahwa hal ini memang terjadi, jalankan perintah berikut:

kubectl describe nodes NODE_NAME

Di output, periksa kolom Taints, yang mencantumkan key-value pair dan dampak pada penjadwalan.

Jika dampak yang tercantum adalah NoSchedule, tidak ada Pod yang dapat dijadwalkan pada node tersebut kecuali jika memiliki tolerasi yang cocok.

Salah satu cara untuk mengatasi masalah ini adalah dengan menghapus taint. Misalnya, untuk menghapus kontaminasi NoSchedule, jalankan perintah berikut:

kubectl taint nodes NODE_NAME key:NoSchedule-

Error: PodFitsHostPorts

Error PodFitsHostPorts berarti node mencoba menggunakan port yang sudah digunakan.

Untuk mengatasi masalah ini, pertimbangkan untuk mengikuti praktik terbaik Kubernetes dan gunakan NodePort, bukan hostPort.

Jika Anda harus menggunakan hostPort, periksa manifes Pod dan pastikan semua Pod di node yang sama memiliki nilai unik yang ditentukan untuk hostPort.

Error: Tidak memiliki ketersediaan minimum

Jika node memiliki resource yang memadai, tetapi Anda masih melihat pesan Does not have minimum availability, periksa status Pod. Jika statusnya adalah status SchedulingDisabled atau Cordoned, node tidak dapat menjadwalkan Pod baru. Anda dapat memeriksa status node menggunakan Konsol Google Cloud atau alat command line kubectl.

Konsol

Lakukan langkah-langkah berikut:

  1. Buka halaman Google Kubernetes Engine di konsol Google Cloud.

    Buka Google Kubernetes Engine

  2. Pilih cluster yang ingin Anda selidiki. Tab Node menampilkan Node dan statusnya.

Untuk mengaktifkan penjadwalan di node, lakukan langkah-langkah berikut:

  1. Dari daftar, klik node yang ingin Anda selidiki.

  2. Dari bagian Node Details, klik Uncordon.

kubectl

Untuk mendapatkan status node, jalankan perintah berikut:

kubectl get nodes

Untuk mengaktifkan penjadwalan di node, jalankan:

kubectl uncordon NODE_NAME

Error: Batas Pod maksimum per node tercapai

Jika batas Maksimum Pod per node dicapai oleh semua node dalam cluster, Pod akan terjebak dalam status Tidak dapat dijadwalkan. Di bagian tab Peristiwa Pod, Anda akan melihat pesan yang menyertakan frasa Too many pods.

Untuk mengatasi error ini, selesaikan langkah-langkah berikut:

  1. Periksa konfigurasi Maximum pods per node dari tab Node pada detail cluster GKE di Konsol Google Cloud.

  2. Mendapatkan daftar node:

    kubectl get nodes
    
  3. Untuk setiap node, verifikasi jumlah Pod yang berjalan di node:

    kubectl get pods -o wide | grep NODE_NAME | wc -l
    
  4. Jika batas tercapai, tambahkan node pool baru atau tambahkan node lain ke node pool yang ada.

Masalah: Ukuran maksimum node pool tercapai dengan autoscaler cluster diaktifkan

Jika node pool telah mencapai ukuran maksimum sesuai dengan konfigurasi autoscaler cluster-nya, GKE tidak akan memicu peningkatan skala untuk Pod yang seharusnya dijadwalkan dengan node pool ini. Jika Anda menginginkan agar Pod dijadwalkan dengan node pool ini, ubah konfigurasi autoscaler cluster-nya.

Masalah: Ukuran maksimum node pool tercapai dengan autoscaler cluster dinonaktifkan

Jika node pool telah mencapai jumlah maksimum node, dan autoscaler cluster dinonaktifkan, GKE tidak dapat menjadwalkan Pod dengan node pool. Tingkatkan ukuran node pool atau aktifkan autoscaler cluster agar GKE dapat otomatis mengubah ukuran cluster Anda.

Error: PersistentVolumeClaims Dilepas

Unbound PersistentVolumeClaims menunjukkan bahwa Pod mereferensikan PersistentVolumeClaim yang telah dilepas. Error ini dapat terjadi jika PersistentVolume Anda gagal disediakan. Anda dapat memastikan bahwa penyediaan gagal dengan mendapatkan peristiwa untuk PersistentVolumeClaim dan memeriksanya untuk melihat apakah memang terjadi kegagalan.

Untuk mendapatkan peristiwa, jalankan perintah berikut:

kubectl describe pvc STATEFULSET_NAME-PVC_NAME-0

Ganti kode berikut:

  • STATEFULSET_NAME: nama objek StatefulSet.
  • PVC_NAME: nama objek PersistentVolumeClaim.

Hal ini juga dapat terjadi jika ada error konfigurasi selama pra-penyediaan PersistentVolume manual Anda dan dalam proses bindingnya ke PersistentVolumeClaim.

Untuk mengatasi error ini, coba lakukan pra-penyediaan volume lagi.

Error: Kuota tidak mencukupi

Pastikan project Anda memiliki kuota Compute Engine yang memadai untuk GKE guna meningkatkan skala cluster Anda. Jika GKE mencoba menambahkan node ke cluster Anda untuk menjadwalkan Pod, dan peningkatan skala melebihi kuota project yang tersedia, Anda akan menerima pesan error scale.up.error.quota.exceeded.

Untuk mempelajari lebih lanjut, lihat Error ScaleUp.

Masalah: API yang tidak digunakan lagi

Pastikan Anda tidak menggunakan API yang sudah tidak digunakan lagi dan dihapus dengan versi minor cluster Anda. Untuk mempelajari lebih lanjut, lihat penghentian penggunaan GKE.

Error: Tidak memiliki port kosong untuk port Pod yang diminta

Jika Anda melihat error yang mirip dengan yang berikut, Anda mungkin memiliki beberapa Pod di node yang sama dengan nilai yang sama yang ditentukan di kolom hostPort:

0/1 nodes are available: 1 node(s) didn't have free ports for the requested pod ports. preemption: 0/1 nodes are available: 1 No preemption victims found for incoming pod.

Mengikat Pod ke hostPort akan membatasi tempat GKE dapat menjadwalkan Pod karena setiap kombinasi hostIP, hostPort, dan protocol harus unik.

Untuk mengatasi masalah ini, pertimbangkan untuk mengikuti praktik terbaik Kubernetes dan menggunakan NodePort, bukan hostPort.

Jika Anda harus menggunakan hostPort, periksa manifes Pod dan pastikan semua Pod di node yang sama memiliki nilai unik yang ditentukan untuk hostPort.

Langkah selanjutnya

Jika Anda memerlukan bantuan tambahan, hubungi Cloud Customer Care.