Mengupgrade cluster Kubernetes tanpa downtime

Mengupgrade cluster Kubernetes tanpa downtime

Proses peningkatan untuk cluster Kubernetes Anda

Pada titik tertentu, saat menggunakan cluster Kubernetes, ada kebutuhan untuk memperbarui node yang sedang berjalan. Ini mungkin termasuk pembaruan paket, pembaruan kernel, atau penerapan image mesin virtual baru. Dalam terminologi Kubernetes hal ini disebut "Gangguan Sukarela".

Posting ini adalah bagian dari seri 4 posting:

  1. posting ini.
  2. Mematikan pod di cluster Kubernetes dengan benar
  3. Tertundanya penghentian sebuah pod ketika pod tersebut dihapus
  4. Cara Menghindari Downtime Cluster Kubernetes Menggunakan PodDisruptionBudgets

(kira-kira Harapkan terjemahan artikel lainnya dalam seri ini dalam waktu dekat)

Pada artikel ini, kami akan menjelaskan semua alat yang disediakan Kubernetes untuk mencapai zero downtime pada node yang berjalan di cluster Anda.

Mendefinisikan masalah

Kami akan mengambil pendekatan yang naif pada awalnya, mengidentifikasi masalah dan menilai potensi risiko dari pendekatan ini, dan membangun pengetahuan untuk memecahkan setiap masalah yang kami temui sepanjang siklus. Hasilnya adalah konfigurasi yang menggunakan lifecycle hook, pemeriksaan kesiapan, dan anggaran gangguan Pod untuk mencapai sasaran zero downtime kami.

Untuk memulai perjalanan kita, mari kita ambil contoh konkrit. Katakanlah kita memiliki cluster Kubernetes yang terdiri dari dua node, di mana sebuah aplikasi berjalan dengan dua pod yang terletak di belakang Service:

Mengupgrade cluster Kubernetes tanpa downtime

Mari kita mulai dengan dua pod dengan Nginx dan Service yang berjalan di dua node cluster Kubernetes kita.

Kami ingin memperbarui versi kernel dari dua node pekerja di cluster kami. Bagaimana kita melakukan ini? Solusi sederhananya adalah dengan mem-boot node baru dengan konfigurasi yang diperbarui dan kemudian mematikan node lama saat memulai node baru. Meskipun cara ini berhasil, akan ada beberapa masalah dengan pendekatan ini:

  • Saat Anda mematikan node lama, pod yang berjalan di dalamnya juga akan dimatikan. Bagaimana jika pod perlu dibersihkan agar dapat dimatikan dengan baik? Sistem virtualisasi yang Anda gunakan mungkin tidak menunggu hingga proses pembersihan selesai.
  • Bagaimana jika Anda mematikan semua node secara bersamaan? Anda akan mendapatkan waktu henti yang layak saat pod berpindah ke node baru.

Kita memerlukan cara untuk memigrasikan pod dengan baik dari node lama sambil memastikan bahwa tidak ada proses pekerja yang berjalan saat kita melakukan perubahan pada node. Atau ketika kita melakukan penggantian cluster secara menyeluruh, seperti pada contoh (yaitu, kita mengganti image VM), kita ingin mentransfer aplikasi yang sedang berjalan dari node lama ke node baru. Dalam kedua kasus tersebut, kami ingin mencegah penjadwalan pod baru pada node lama, dan kemudian mengeluarkan semua pod yang berjalan dari node tersebut. Untuk mencapai tujuan tersebut kita dapat menggunakan perintah kubectl drain.

Mendistribusikan ulang semua pod dari sebuah node

Operasi pengurasan memungkinkan Anda mendistribusikan ulang semua pod dari sebuah node. Selama eksekusi pengurasan, node ditandai sebagai tidak dapat dijadwalkan (flag NoSchedule). Hal ini mencegah munculnya pod baru di dalamnya. Kemudian drain mulai mengeluarkan pod dari node, mematikan container yang sedang berjalan di node, mengirimkan sinyal TERM wadah di dalam pod.

Meskipun kubectl drain akan melakukan pekerjaan yang baik dalam mengeluarkan pod, ada dua faktor lain yang dapat menyebabkan operasi pengurasan gagal:

  • Permohonan Anda harus dapat diakhiri dengan baik setelah diserahkan TERM sinyal. Saat pod dikeluarkan, Kubernetes mengirimkan sinyal TERM kontainer-kontainer tersebut dan menunggu hingga kontainer-kontainer tersebut berhenti selama jangka waktu tertentu, setelah itu, jika kontainer-kontainer tersebut tidak berhenti, maka kontainer-kontainer tersebut akan dihentikan secara paksa. Bagaimanapun, jika container Anda tidak menerima sinyal dengan benar, Anda masih dapat mematikan pod secara tidak benar jika pod tersebut sedang berjalan (misalnya, transaksi database sedang berlangsung).
  • Anda kehilangan semua pod yang berisi aplikasi Anda. Ini mungkin tidak tersedia ketika kontainer baru diluncurkan pada node baru, atau jika pod Anda di-deploy tanpa pengontrol, pod tersebut mungkin tidak dapat dimulai ulang sama sekali.

Menghindari waktu henti

Untuk meminimalkan waktu henti akibat gangguan yang disengaja, misalnya dari operasi pengurasan pada sebuah node, Kubernetes menyediakan opsi penanganan kegagalan berikut:

Di seri selanjutnya, kita akan menggunakan fitur Kubernetes ini untuk mengurangi dampak migrasi pod. Agar lebih mudah mengikuti gagasan utama, kita akan menggunakan contoh di atas dengan konfigurasi sumber daya berikut:

---
apiVersion: apps/v1
kind: Deployment
metadata:
 name: nginx-deployment
 labels:
   app: nginx
spec:
 replicas: 2
 selector:
   matchLabels:
     app: nginx
 template:
   metadata:
     labels:
       app: nginx
   spec:
     containers:
     - name: nginx
       image: nginx:1.15
       ports:
       - containerPort: 80
---
kind: Service
apiVersion: v1
metadata:
 name: nginx-service
spec:
 selector:
   app: nginx
 ports:
 - protocol: TCP
   targetPort: 80
   port: 80

Konfigurasi ini adalah contoh minimal Deployment, yang mengelola pod nginx di cluster. Selain itu, konfigurasi menjelaskan sumber daya Service, yang dapat digunakan untuk mengakses pod nginx dalam sebuah cluster.

Sepanjang siklus, kami akan memperluas konfigurasi ini secara berulang sehingga pada akhirnya mencakup semua kemampuan yang disediakan Kubernetes untuk mengurangi waktu henti.

Untuk versi pembaruan klaster Kubernetes yang diterapkan dan diuji sepenuhnya agar tidak terjadi downtime di AWS dan seterusnya, kunjungi Gruntwork.io.

Baca juga artikel lainnya di blog kami:

Sumber: www.habr.com

Tambah komentar