Memecahkan masalah peristiwa OOM


Halaman ini membantu Anda memecahkan masalah dan menyelesaikan peristiwa Kehabisan Memori (OOM) di Google Kubernetes Engine (GKE). Pelajari cara mengidentifikasi penyebab umum peristiwa OOM, membedakan kejadian tingkat container dan tingkat node, serta menerapkan solusi.

Halaman ini ditujukan untuk Developer aplikasi yang ingin memverifikasi bahwa aplikasi mereka berhasil di-deploy dan untuk Admin serta operator platform yang ingin memahami penyebab utama peristiwa kehabisan memori dan memverifikasi konfigurasi platform. Untuk mengetahui informasi selengkapnya tentang peran umum dan contoh tugas yang kami rujuk dalam konten, lihat Peran dan tugas pengguna GKE Enterprise umum. Google Cloud

Penyebab umum peristiwa OOM

Peristiwa OOM biasanya terjadi selama lonjakan beban atau traffic, saat penggunaan memori aplikasi meningkat dan mencapai batas memori yang dikonfigurasi untuk penampung.

Skenario berikut dapat menyebabkan peristiwa OOM:

  • Batas memori tidak mencukupi: setelan resources.limits.memory dalam manifest Pod terlalu rendah untuk permintaan memori puncak atau umum aplikasi.
  • Permintaan atau batas memori yang tidak ditentukan: jika resources.limits.memory dan resources.requests.memory tidak ditentukan, penggunaan memori penampung tidak terbatas.
  • Beban tinggi atau lonjakan beban: lonjakan beban yang tiba-tiba dan ekstrem dapat membebani sumber daya sistem, termasuk memori, meskipun batas biasanya memadai.
  • Kebocoran memori: aplikasi mungkin memiliki kerusakan kode yang menyebabkan aplikasi gagal melepaskan memori dengan benar.

Peristiwa OOM dapat memicu kegagalan berjenjang, karena lebih sedikit penampung yang tersisa untuk menangani traffic, sehingga meningkatkan beban pada penampung yang tersisa. Kemudian, container ini juga dapat dihentikan.

Cara Kubernetes menangani peristiwa OOM

OOM Killer Linux menangani setiap peristiwa OOM. OOM Killer adalah proses kernel yang diaktifkan saat sistem hampir kehabisan memori. Tujuannya adalah untuk mencegah total sistem error dengan menghentikan proses secara strategis untuk mengosongkan resource. Kernel menggunakan sistem penilaian untuk memilih proses mana yang akan dihentikan, dengan tujuan untuk menjaga stabilitas sistem dan meminimalkan kehilangan data.

Di lingkungan Kubernetes, OOM Killer beroperasi pada dua cakupan yang berbeda: grup kontrol (cgroup), yang memengaruhi satu container; dan sistem, yang memengaruhi seluruh node.

Penghentian karena kehabisan memori tingkat penampung

Penghentian OOM tingkat container terjadi saat container mencoba melebihi batas memori yang telah ditentukan sebelumnya. Kubernetes menetapkan setiap container ke cgroup tertentu dengan batas memori tetap. Saat penggunaan memori penampung mencapai batas ini, kernel akan mencoba mengklaim kembali memori dalam cgroup tersebut terlebih dahulu. Jika kernel tidak dapat merebut kembali memori yang cukup dengan menggunakan proses ini, cgroup OOM Killer akan dipanggil. Proses ini menghentikan proses dalam cgroup tertentu untuk menerapkan batas resource.

Jika proses utama dalam container dihentikan dengan cara ini, Kubernetes akan mengamati peristiwa tersebut dan menandai status container sebagai OOMKilled. restartPolicy yang dikonfigurasi Pod kemudian menentukan hasilnya:

  • Always atau OnFailure: penampung dimulai ulang.
  • Never: penampung tidak dimulai ulang dan tetap dalam status dihentikan.

Dengan mengisolasi kegagalan pada container yang bermasalah, OOM Killer mencegah satu Pod yang rusak membuat error pada seluruh node.

Pengaruh versi cgroup terhadap perilaku OOM Killer

Perilaku penghentian OOM dapat sangat berbeda antara versi cgroup. Jika Anda tidak yakin versi cgroup yang Anda gunakan, periksa mode cgroup node cluster.

  • Di cgroup v1, peristiwa kehabisan memori (OOM) dalam cgroup memori container dapat menyebabkan perilaku yang tidak dapat diprediksi. OOM Killer dapat menghentikan proses apa pun dalam cgroup tersebut, termasuk proses turunan yang bukan proses utama (PID 1) penampung.

    Perilaku ini menimbulkan tantangan yang signifikan bagi Kubernetes. Karena Kubernetes terutama memantau kesehatan proses container utama, Kubernetes tetap tidak mengetahui penghapusan OOM "parsial" ini. Proses penampung utama dapat terus berjalan, meskipun proses turunan penting telah dihentikan. Perilaku ini dapat menyebabkan kegagalan aplikasi yang tidak terlihat jelas oleh Kubernetes atau operator, tetapi masih terlihat di log sistem node (journalctl).

  • cgroup v2 menawarkan perilaku OOM Killer yang lebih dapat diprediksi.

    Untuk membantu menjamin integritas workload di lingkungan cgroup v2, OOM killer mencegah penghentian sebagian dan memastikan salah satu dari dua hasil: baik semua tugas yang termasuk dalam cgroup tersebut dan turunannya dihentikan (membuat kegagalan terlihat oleh Kubernetes), atau saat workload tidak memiliki tugas yang menggunakan terlalu banyak memori, workload dibiarkan tidak tersentuh dan terus berjalan tanpa penghentian proses internal yang tidak terduga.

    Untuk skenario saat Anda menginginkan perilaku cgroup v1 untuk menghentikan satu proses, kubelet menyediakan tanda singleProcessOOMKill untuk cgroup v2. Dengan tanda ini, Anda dapat mengontrol secara lebih terperinci, sehingga memungkinkan penghentian setiap proses selama peristiwa OOM, bukan seluruh cgroup.

Penghentian karena kehabisan memori (OOM) tingkat sistem

Penonaktifan OOM tingkat sistem adalah peristiwa yang lebih serius yang terjadi saat seluruh node, bukan hanya satu penampung, kehabisan memori yang tersedia. Peristiwa ini dapat terjadi jika penggunaan memori gabungan dari semua proses (termasuk semua Pod dan daemon sistem) melebihi kapasitas node.

Jika node ini kehabisan memori, OOM Killer global akan menilai semua proses di node dan menghentikan proses untuk mendapatkan kembali memori bagi seluruh sistem. Proses yang dipilih biasanya adalah proses yang berumur singkat dan menggunakan sejumlah besar memori.

Untuk mencegah situasi OOM parah, Kubernetes menggunakan pengusiran karena tekanan node untuk mengelola resource node. Proses ini melibatkan pengusiran Pod yang kurang penting dari node saat resource, seperti memori atau ruang disk, hampir habis. Penghentian OOM tingkat sistem menunjukkan bahwa proses penghapusan ini tidak dapat mengosongkan memori dengan cukup cepat untuk mencegah masalah.

Jika OOM Killer menghentikan proses penampung, efeknya biasanya identik dengan penghentian yang dipicu cgroup: penampung ditandai OOMKilled dan dimulai ulang berdasarkan kebijakannya. Namun, jika proses sistem penting dihentikan (yang jarang terjadi), node itu sendiri dapat menjadi tidak stabil.

Menyelidiki peristiwa OOM

Bagian berikut membantu Anda mendeteksi dan mengonfirmasi peristiwa OOM, dimulai dengan alat Kubernetes yang paling sederhana dan beralih ke analisis log yang lebih mendetail.

Periksa status Pod untuk peristiwa OOM yang terlihat

Langkah pertama dalam mengonfirmasi peristiwa OOM adalah memeriksa apakah Kubernetes mengamati peristiwa OOM. Kubernetes mengamati peristiwa saat proses utama kontainer dihentikan, yang merupakan perilaku standar di lingkungan cgroup v2.

  • Periksa status Pod:

    kubectl describe pod POD_NAME
    

    Ganti POD_NAME dengan nama Pod yang ingin Anda selidiki.

    Jika peristiwa OOM yang terlihat terjadi, output-nya akan mirip dengan berikut ini:

    ...
      Last State:     Terminated
        Reason:       OOMKilled
        Exit Code:    137
        Started:      Tue, 13 May 2025 19:05:28 +0000
        Finished:     Tue, 13 May 2025 19:05:30 +0000
    ...
    

Jika Anda melihat OOMKilled di kolom Reason, Anda telah mengonfirmasi peristiwa. Exit Code 137 juga menunjukkan penghentian karena kehabisan memori. Jika kolom Reason memiliki nilai yang berbeda, atau Pod masih berjalan meskipun ada error aplikasi, lanjutkan ke bagian berikutnya untuk penyelidikan lebih lanjut.

Menelusuri log untuk peristiwa OOM yang tidak terlihat

Penghentian karena kehabisan memori "tidak terlihat" oleh Kubernetes jika proses turunan dihentikan, tetapi proses container utama terus berjalan (skenario umum di lingkungan cgroup v1). Anda harus menelusuri log node untuk menemukan bukti peristiwa ini.

Untuk menemukan proses penonaktifan karena kehabisan memori yang tidak terlihat, gunakan Logs Explorer:

  1. Di konsol Google Cloud , buka Logs Explorer.

    Buka Logs Explorer

  2. Di panel kueri, masukkan salah satu kueri berikut:

    • Jika Anda sudah memiliki Pod yang menurut Anda mengalami peristiwa OOM, kueri Pod tertentu tersebut:

      resource.type="k8s_node"
      jsonPayload.MESSAGE:(("POD_NAME" AND "ContainerDied") OR "TaskOOM event")
      resource.labels.cluster_name="CLUSTER_NAME"
      

      Ganti kode berikut:

      • POD_NAME: nama Pod yang ingin Anda kueri.
      • CLUSTER_NAME: nama cluster tempat Pod berada.
    • Untuk mengetahui Pod atau node mana yang mengalami peristiwa OOM, kueri semua workload GKE:

      resource.type="k8s_node"
      jsonPayload.MESSAGE:("ContainerDied" OR "TaskOOM event")
      resource.labels.cluster_name="CLUSTER_NAME"
      
  3. Klik Run query.

  4. Dalam output, temukan peristiwa OOM dengan menelusuri entri log yang berisi string TaskOOM.

  5. Opsional: Jika Anda menelusuri peristiwa OOM untuk semua beban kerja GKE dan ingin mengidentifikasi Pod tertentu yang mengalami peristiwa OOM, selesaikan langkah-langkah berikut:

    1. Untuk setiap peristiwa, catat ID penampung yang terkait dengannya.
    2. Identifikasi penghentian container dengan mencari entri log yang berisi string ContainerDied, dan yang terjadi tak lama setelah peristiwa OOM. Cocokkan ID penampung dari peristiwa OOM dengan baris ContainerDied yang sesuai.

    3. Setelah Anda mencocokkan container IDs, baris ContainerDied biasanya menyertakan nama Pod yang terkait dengan container yang gagal. Pod ini terpengaruh oleh peristiwa OOM.

Menggunakan journalctl untuk informasi real-time

Jika Anda perlu melakukan analisis real-time pada sistem, gunakan perintah journalctl.

  1. Hubungkan ke node menggunakan SSH:

    gcloud compute ssh NODE_NAME --location ZONE
    

    Ganti kode berikut:

    • NODE_NAME: nama node yang ingin Anda periksa.
    • ZONE: zona Compute Engine tempat node Anda berada.
  2. Di shell, jelajahi pesan kernel dari jurnal sistem node:

    journalctl -k
    
  3. Analisis output untuk membedakan jenis peristiwa:

    • Penghentian tingkat penampung: entri log berisi istilah seperti memory cgroup, mem_cgroup, atau memcg, yang menunjukkan bahwa batas cgroup diterapkan.
    • Penonaktifan tingkat sistem: entri log adalah pesan umum seperti Out of memory: Killed process... tanpa menyebutkan cgroup.

Menyelesaikan peristiwa OOM

Untuk mengatasi peristiwa OOM, coba solusi berikut:

  • Meningkatkan batas memori: ini adalah solusi yang paling langsung. Edit manifes Pod untuk memberikan nilai resources.limits.memory yang lebih tinggi yang mengakomodasi penggunaan puncak aplikasi. Untuk mengetahui informasi selengkapnya tentang cara menetapkan batas, lihat Pengelolaan Resource untuk Pod dan Container dalam dokumentasi Kubernetes.
  • Tambahkan atau sesuaikan permintaan memori: di manifes Pod, pastikan kolom resources.requests.memory ditetapkan ke nilai yang realistis untuk penggunaan umum. Setelan ini membantu Kubernetes menjadwalkan Pod ke node dengan memori yang cukup.
  • Menskalakan workload secara horizontal: untuk mendistribusikan beban traffic dan mengurangi tekanan memori pada satu Pod, tambah jumlah replika. Agar Kubernetes secara proaktif menskalakan workload, pertimbangkan untuk mengaktifkan penskalaan otomatis Pod horizontal.
  • Menskalakan node secara vertikal: jika banyak Pod di node mendekati batasnya, node itu sendiri mungkin terlalu kecil. Untuk meningkatkan ukuran node, migrasikan workload Anda ke node pool dengan memori yang lebih besar. Agar Kubernetes secara proaktif menskalakan node, pertimbangkan untuk mengaktifkan penskalaan otomatis Pod vertikal.
  • Mengoptimalkan aplikasi Anda: tinjau aplikasi Anda untuk mengidentifikasi dan mengatasi kebocoran memori serta mengoptimalkan kode yang menggunakan sejumlah besar memori selama lonjakan traffic.
  • Hapus beban kerja yang bermasalah: sebagai upaya terakhir untuk beban kerja non-kritis, hapus Pod untuk segera mengurangi tekanan pada cluster.

Langkah berikutnya