Kubernetes: kehidupan perapian

Catatan perev. : Artikel kecil (tapi luas!) Yang ditulis oleh Michael Hausenblas dari tim OpenShift di Red Hat ini sangat disukai kami sehingga ditambahkan ke basis pengetahuan internal Kubernet kami segera setelah ditemukan. Dan karena informasi yang disajikan di dalamnya jelas akan bermanfaat bagi komunitas TI berbahasa Rusia yang lebih luas, kami senang memposting terjemahannya.



Seperti yang Anda duga, judul publikasi ini adalah referensi untuk kartun Pixar 1998 "A Bug's Life" (di box office Rusia disebut "Adventures of Flick" atau "Life of a Serect " - sekitar. Terjemahan ) , Dan memang: antara ant- Kubernetes memiliki banyak kesamaan dengan pekerja dan perapian. Kami akan dengan hati-hati melihat siklus hidup penuh perapian dari sudut pandang praktis - khususnya, cara-cara di mana Anda dapat memengaruhi perilaku saat startup dan shutdown, serta pendekatan yang benar untuk memeriksa status aplikasi.

Terlepas dari apakah Anda membuat di bawah diri Anda sendiri atau, lebih baik, melalui pengontrol seperti Deployment , DaemonSet atau StatefulSet , di bawah dapat dalam salah satu dari fase berikut:

  • Tertunda : Server API membuat sumber daya pod dan menyimpannya di etcd, tetapi belum direncanakan, dan gambar wadahnya belum diterima dari registri;
  • Menjalankan (berfungsi): di bawah ditugaskan ke node dan semua wadah dibuat oleh kubelet ;
  • Berhasil (berhasil diselesaikan): operasi semua wadah perapian telah berhasil diselesaikan dan mereka tidak akan memulai kembali;
  • Gagal : semua wadah di perapian telah berhenti berfungsi dan setidaknya salah satu kontainer telah gagal;
  • Tidak dikenal : API Server tidak dapat menanyakan status perapian, biasanya karena kesalahan berinteraksi dengan kubelet .

Saat menjalankan kubectl get pod , perhatikan bahwa kolom STATUS dapat menampilkan pesan lain (kecuali lima) - misalnya, Init:0/1 atau CrashLoopBackOff . Ini karena fase hanya bagian dari keadaan umum perapian. Cara yang baik untuk mengetahui apa yang sebenarnya terjadi adalah menjalankan kubectl describe pod/$PODNAME dan lihat entri kubectl describe pod/$PODNAME Events: bawah ini. Dia menampilkan daftar tindakan yang relevan: bahwa gambar wadah diterima, sudah direncanakan, wadah berada dalam kondisi " tidak sehat" .

Sekarang lihat contoh spesifik dari siklus hidup perapian dari awal hingga selesai, seperti yang ditunjukkan pada diagram berikut:



Apa yang terjadi di sini? Langkah-langkahnya adalah sebagai berikut:

  1. Ini tidak diperlihatkan dalam diagram, tetapi pada mulanya wadah infra- khusus diluncurkan dan menyiapkan ruang nama tempat wadah-wadah lainnya bergabung.
  2. Wadah yang ditentukan pengguna pertama yang dimulai adalah wadah init ; dapat digunakan untuk tugas inisialisasi.
  3. Selanjutnya, wadah utama dan kait paska start diluncurkan secara bersamaan; dalam kasus kami, ini terjadi setelah 4 detik. Kait ditentukan untuk setiap wadah.
  4. Kemudian, pada detik ke-7, tes liness and readiness ikut berperan, sekali lagi untuk setiap wadah.
  5. Pada detik ke-11, ketika under terbunuh, hook pre-stop dipicu dan kontainer utama terbunuh setelah masa tenggang . Harap dicatat bahwa pada kenyataannya, proses penyelesaian pod agak lebih rumit.

Bagaimana saya sampai pada urutan di atas dan waktunya? Untuk melakukan ini, kami menggunakan Penyebaran berikut, yang dibuat khusus untuk melacak urutan peristiwa (itu tidak terlalu berguna dalam dirinya sendiri):

 kind: Deployment apiVersion: apps/v1beta1 metadata: name: loap spec: replicas: 1 template: metadata: labels: app: loap spec: initContainers: - name: init image: busybox command: ['sh', '-c', 'echo $(date +%s): INIT >> /loap/timing'] volumeMounts: - mountPath: /loap name: timing containers: - name: main image: busybox command: ['sh', '-c', 'echo $(date +%s): START >> /loap/timing; sleep 10; echo $(date +%s): END >> /loap/timing;'] volumeMounts: - mountPath: /loap name: timing livenessProbe: exec: command: ['sh', '-c', 'echo $(date +%s): LIVENESS >> /loap/timing'] readinessProbe: exec: command: ['sh', '-c', 'echo $(date +%s): READINESS >> /loap/timing'] lifecycle: postStart: exec: command: ['sh', '-c', 'echo $(date +%s): POST-START >> /loap/timing'] preStop: exec: command: ['sh', '-c', 'echo $(date +%s): PRE-HOOK >> /loap/timing'] volumes: - name: timing hostPath: path: /tmp/loap 

Perhatikan bahwa untuk mematikan paksa pod saat kontainer utama berfungsi, saya menjalankan perintah berikut:

 $ kubectl scale deployment loap --replicas=0 

Kami melihat urutan kejadian tertentu dalam aksi dan sekarang siap untuk melanjutkan - ke praktik di bidang manajemen siklus hidup perapian. Mereka adalah sebagai berikut:

  • Gunakan wadah init untuk mempersiapkan perapian untuk operasi normal. Misalnya, untuk mendapatkan data eksternal, buat tabel dalam database, atau untuk menunggu ketersediaan layanan yang menjadi sandarannya. Jika perlu, Anda dapat membuat banyak wadah init, dan semuanya harus berhasil diselesaikan sebelum wadah reguler diluncurkan.
  • Selalu tambahkan livenessProbe dan readinessProbe . Yang pertama digunakan oleh kubelet 'ohm untuk memahami apakah dan kapan harus memulai kembali wadah, dan penyebaran ' ohm untuk memutuskan apakah pembaruan bergulir berhasil. Yang kedua digunakan oleh layanan untuk memutuskan arah lalu lintas ke sub. Jika sampel-sampel ini tidak ditentukan, kubelet untuk keduanya mengasumsikan bahwa mereka berhasil diselesaikan. Ini mengarah pada dua konsekuensi: a) kebijakan restart tidak dapat diterapkan, b) wadah di perapian langsung menerima lalu lintas dari layanan yang mereka hadapi, dan bahkan jika mereka masih sibuk dengan proses startup.
  • Gunakan kait untuk menginisialisasi wadah dengan benar dan benar-benar menghancurkannya. Misalnya, ini berguna dalam hal berfungsinya aplikasi yang kode sumbernya tidak dapat Anda akses atau tidak dapat modifikasi, tetapi yang memerlukan beberapa inisialisasi atau persiapan penyelesaian - misalnya, membersihkan koneksi basis data. Perhatikan bahwa ketika menggunakan layanan , mematikan Server API, pengontrol titik akhir, dan proksi kubus mungkin memerlukan waktu (misalnya, menghapus entri yang sesuai dari iptables). Karenanya, menghentikan pekerjaan Anda di bawah dapat memengaruhi permintaan aplikasi. Seringkali, untuk mengatasi masalah ini, pengait sederhana dengan panggilan tidur sudah cukup.
  • Untuk kebutuhan debugging dan untuk memahami secara umum mengapa berhenti bekerja, aplikasi dapat menulis ke /dev/termination-log , dan Anda dapat melihat pesan menggunakan kubectl describe pod … Pengaturan default ini diubah melalui terminationMessagePath dan / atau menggunakan terminationMessagePolicy di sub spesifikasi - lihat referensi API untuk lebih jelasnya.

Publikasi ini tidak membahas inisialisasi (beberapa detail tentang mereka dapat ditemukan di akhir materi ini - sekitar Terjemahan. ) . Ini adalah konsep yang sama sekali baru yang diperkenalkan di Kubernetes 1.7. Initializers bekerja di dalam control plane (API Server) alih-alih berada dalam konteks kubelet , dan dapat digunakan untuk memperkaya perapian, misalnya, dengan wadah sespan atau menegakkan kebijakan keamanan. Selain itu, PodPreset tidak dipertimbangkan, yang di masa depan dapat diganti dengan konsep inisialisasi yang lebih fleksibel.

PS dari penerjemah


Baca juga di blog kami:

Source: https://habr.com/ru/post/id415393/


All Articles