Prompt dan konteks
Satu pasukan platform mendapati bahawa kontena kelompok seorang penyewa boleh menghimpit perkhidmatan dalam talian semasa waktu puncak. Nod menggunakan cgroup v2, tetapi pasukan tersebut hanya menetapkan satu had memori dan tidak dapat membezakan antara tebus guna (reclaim), pendikit (throttling), dan penamatan (termination). Reka bentuk dasar memori berlapis dengan sempadan perlindungan, pemantauan peristiwa, dan undur balik.
Perkara yang diuji oleh penemu duga
- Sama ada anda memisahkan perlindungan memory.min/low daripada tebus guna/pendikit memory.high dan penguatkuasaan memory.max.
- Sama ada anda memahami memory.events hierarki dan memory.events.local setempat.
- Sama ada anda mengendalikan pembunuhan kumpulan OOM, cgroup anak, lonjakan (bursts), dan komit lebih (overcommit).
- Sama ada anda boleh menghubungkan fail kernel dengan orkestrasi, amaran, dan latih tubi.
Soalan penjelasan untuk ditanya terlebih dahulu
- Adakah anda melindungi beban kerja kritikal, mengehadkan penyewa, atau melindungi keseluruhan nod?
- Adakah beban kerja tersebut sensitif terhadap kependaman, berorientasikan kelompok, atau selamat untuk ditebus guna dan dicuba semula?
- Apakah hierarki cgroup, dan adakah kumpulan induk mengandungi sidecar?
- Adakah Kubernetes mengurus beban kerja tersebut, dan bagaimanakah requests serta limits dipetakan ke cgroup v2?
- Patutkah OOM membunuh satu proses, keseluruhan cgroup, atau menyebabkan pengawal membina semula kontena?
Rangka jawapan 30 saat
Gunakan memory.min dan memory.low untuk tahap perlindungan, memory.high sebagai sempadan awal tebus guna dan pendikit, dan memory.max sebagai had keras muktamad. memory.oom.group menentukan sama ada pengendalian OOM adalah untuk seluruh kumpulan. Peruntukkan belanjawan daripada nod ke penyewa dan ke beban kerja, pantau memory.current, memory.events, dan PSI, serta sahkan dengan kenari, ujian tekanan, dan undur balik. Dalam Kubernetes, baca fail cgroup sebenar selepas persembahan (rendering) dan bukannya mempercayai YAML semata-mata.
Jawapan mendalam langkah demi langkah
Langkah 1: Bina model semantik
memory.min ialah sempadan perlindungan keras yang penggunaannya hanya ditebus guna di bawah tekanan yang kuat; memory.low ialah perlindungan usaha terbaik yang boleh ditebus guna di bawah tekanan yang teruk. memory.high mencetuskan tebus guna dan pendikit tetapi tidak memanggil pembunuh OOM secara langsung. memory.max ialah had yang tidak boleh dilangkaui yang boleh memasuki OOM cgroup apabila tebus guna tidak dapat memenuhinya.
Langkah 2: Peruntukkan belanjawan induk dan anak
Rizabkan kapasiti nod untuk sistem dan perkhidmatan kritikal, tetapkan siling kepada setiap induk penyewa, kemudian tetapkan kumpulan anak untuk beban kerja dalam talian, kelompok, dan sidecar. Perlindungan anak tidak boleh melebihi belanjawan tersedia induk secara tanpa syarat. Rekodkan penggunaan semasa, peristiwa, dan versi dasar bagi setiap tahap. Tinggalkan ruang lega di bawah high untuk lonjakan supaya lonjakan singkat tidak menjadi OOM max serta-merta.
Langkah 3: Pilih hubungan high-ke-max
memory.high membolehkan kernel menggunakan tebus guna dan pendikit terlebih dahulu; aplikasi boleh menjadi perlahan selepas memerhatikan kependaman, pemprosesan (throughput), dan peristiwa. memory.max ialah injap keselamatan muktamad dan harus mencerminkan kebolehrecairan (recoverability). Nilai high yang terlalu rendah menyebabkan pendikit kronik, manakala max yang terlalu tinggi memindahkan tekanan kepada induk atau nod. Tentukur kedua-duanya dengan ujian beban.
Langkah 4: Tentukan dasar kumpulan OOM
Bagi proses yang digandingkan secara rapat, memory.oom.group=1 menjadikan pengendalian OOM untuk seluruh kumpulan supaya proses pembantu tidak tertinggal selepas hanya proses utama dimatikan. Tugas kelompok bebas mungkin lebih suka satu proses keluar dan barisan giliran mencubanya semula. Rekodkan sebab keluar, mula semula, dan kerja yang belum selesai bagi mana-mana pilihan; OOM bukanlah percubaan semula yang tidak kelihatan.
Langkah 5: Pantau memory.events
memory.events adalah secara hierarki, jadi peristiwa anak boleh muncul dalam induk; memory.events.local hanya melaporkan peristiwa setempat. Pantau delta untuk high, max, oom, dan oom_kill, yang dikaitkan dengan memory.current, set kerja, PSI, kependaman, dan usia barisan giliran. Huraikan kekunci dan bukannya bergantung pada susunan fail kerana kekunci baharu mungkin muncul.
Langkah 6: Petakan dasar ke orkestrasi
Pada Kubernetes, periksa requests, limits, QoS, dan mod cgroup nod secara bersama. Selepas persembahan, masuk ke dalam kontena dan baca /sys/fs/cgroup untuk mengesahkan nilai sebenar dan memastikan masa jalan (runtime) tidak membatalkannya. Periksa perakaunan sidecar, init container, dan kongsi emptyDir; anak boleh kelihatan sihat semasa induknya mencapai high atau max.
Langkah 7: Latih tubi, lepas, dan undur balik
Pada kenari nod tunggal, turunkan high secara beransur-ansur dan perhatikan tebus guna serta pendikit, kemudian uji penamatan max dan oom.group. Berikan amaran secara berasingan untuk high yang berterusan, max pertama, dan oom_kill sebenar. Terbitkan dasar berversi dengan versi terdahulu dan snapshot peristiwa. Undur balik belanjawan terlebih dahulu, kemudian selaraskan tugas yang dimatikan dan percubaan semula barisan giliran supaya tiada tekanan tertinggal pada nod.
Contoh jawapan berkualiti tinggi
Gunakan min dan low untuk perlindungan, high untuk tebus guna dan pendikit yang boleh diperhatikan, serta max sebagai sempadan keras muktamad. Peruntukkan belanjawan nod, penyewa, dan beban kerja melalui hierarki induk-anak, kemudian pilih oom.group berdasarkan kebolehrecairan. Pantau memory.events hierarki berbanding setempat dengan PSI, kependaman, usia barisan giliran, dan mula semula. Dalam Kubernetes, sahkan fail cgroup yang dipersembahkan. Lancarkan dengan kenari dan latih tubi tekanan, serta kekalkan dasar undur balik berversi.
Kesilapan lazim
- Menganggap memory.high sebagai had OOM serta-merta.
- Menganggap memory.low sebagai jaminan yang tidak boleh dimungkiri.
- Mempercayai YAML kontena tanpa membaca fail cgroup masa jalan.
- Mencampurkan peristiwa hierarki induk dengan peristiwa setempat.
- Memulakan semula selepas OOM tanpa menyemak keidempotanan, kerja separa, dan ribut percubaan semula (retry storms).
Soalan susulan dan jawapan
Soalan susulan 1: Apakah yang berlaku selepas memory.high dilangkaui?
Kernel mengenakan tekanan tebus guna dan pendikit. Proses boleh diteruskan tetapi kependaman mungkin meningkat. Ia bukan suis pembunuh OOM; kaitkan pembilang high dengan PSI dan kependaman perkhidmatan.
Soalan susulan 2: Mengapa perlu mengekalkan memory.max jika high wujud?
High membolehkan beban kerja mengalah di bawah tekanan, manakala max menghadkan pertumbuhan yang tidak boleh ditebus guna dan melindungi induk atau nod. Max mesti direka bentuk dengan mengambil kira kebolehrecairan dan dasar mula semula.
Soalan susulan 3: Mengapa memory.events boleh kelihatan seperti mengira peristiwa dua kali?
memory.events induk merangkumi peristiwa sub-pokok secara lalai, manakala memory.events.local adalah setempat kepada cgroup tersebut. Pilih satu tahap bagi setiap amaran dan nyahduplikasi mengikut hierarki.
Soalan susulan 4: Bilakah memory.oom.group patut didayakan?
Dayakannya apabila proses dalam satu cgroup mesti hidup dan dimulakan semula bersama-sama. Tugas bebas boleh keluar secara individu. Mana-mana pilihan memerlukan ujian pembersihan, percubaan semula, dan kebolehcerapan.
Soalan susulan 5: Bagaimanakah anda membuktikan bahawa pemetaan Kubernetes adalah betul?
Pada nod sasaran, baca memory.min, memory.low, memory.high, memory.max, dan peristiwa untuk cgroup kontena. Bandingkan fail-fail tersebut dengan requests, limits, QoS, dan tetapan masa jalan yang dipersembahkan, kemudian jalankan latih tubi tekanan.