Menghapus cabang fitur yang sudah ketinggalan zaman di cluster Kubernetes

Menghapus cabang fitur yang sudah ketinggalan zaman di cluster Kubernetes

Hi! Cabang fitur (alias menyebarkan pratinjau, meninjau aplikasi) - ini adalah saat tidak hanya cabang master disebarkan, tetapi juga setiap permintaan tarik ke URL unik. Anda dapat memeriksa apakah kode berfungsi di lingkungan produksi; fitur tersebut dapat ditampilkan kepada pemrogram lain atau spesialis produk. Saat Anda mengerjakan permintaan tarik, setiap penerapan penerapan baru saat ini untuk kode lama akan dihapus, dan penerapan baru untuk kode baru akan diluncurkan. Pertanyaan mungkin muncul ketika Anda menggabungkan permintaan tarik ke dalam cabang master. Anda tidak lagi memerlukan cabang fitur, namun sumber daya Kubernetes masih berada di cluster.

Lebih lanjut tentang cabang fitur

Salah satu pendekatan untuk membuat cabang fitur di Kubernetes adalah dengan menggunakan namespace. Singkatnya, konfigurasi produksinya terlihat seperti ini:

kind: Namespace
apiVersion: v1
metadata:
  name: habr-back-end
...

kind: Deployment
apiVersion: apps/v1
metadata:
  namespace: habr-back-end
spec:
  replicas: 3
...

Untuk cabang fitur, namespace dibuat dengan pengidentifikasinya (misalnya, nomor permintaan penarikan) dan beberapa jenis awalan/postfix (misalnya, -pr-):

kind: Namespace
apiVersion: v1
metadata:
  name: habr-back-end-pr-17
...

kind: Deployment
apiVersion: apps/v1
metadata:
  namespace: habr-back-end-pr-17
spec:
  replicas: 1
...

Secara umum, saya menulis Operator Kubernetes (aplikasi yang memiliki akses ke sumber daya cluster), tautan ke proyek di Github. Ini menghapus namespace milik cabang fitur lama. Di Kubernetes, jika Anda menghapus namespace, sumber daya lain di namespace tersebut juga akan terhapus secara otomatis.

$ kubectl get pods --all-namespaces | grep -e "-pr-"
NAMESPACE            ... AGE
habr-back-end-pr-264 ... 4d8h
habr-back-end-pr-265 ... 5d7h

Anda dapat membaca tentang cara mengimplementasikan cabang fitur ke dalam sebuah cluster di sini ΠΈ di sini.

Motivasi

Mari kita lihat siklus hidup permintaan tarik dengan integrasi berkelanjutan (continuous integration):

  1. Kami mendorong komitmen baru ke cabang.
  2. Pada build, linter dan/atau pengujian dijalankan.
  3. Konfigurasi permintaan tarik Kubernetes dibuat dengan cepat (misalnya, nomornya dimasukkan ke dalam templat yang sudah jadi).
  4. Menggunakan kubectl apply, konfigurasi ditambahkan ke cluster (deploy).
  5. Permintaan tarik digabungkan ke dalam cabang master.

Saat Anda mengerjakan permintaan tarik, setiap penerapan penerapan baru saat ini untuk kode lama akan dihapus, dan penerapan baru untuk kode baru akan diluncurkan. Namun ketika permintaan tarik digabungkan ke dalam cabang master, hanya cabang master yang akan dibangun. Akibatnya, ternyata kita sudah melupakan pull request tersebut, dan resource Kubernetes-nya masih ada di cluster.

Cara penggunaannya

Instal proyek dengan perintah di bawah ini:

$ kubectl apply -f https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/configs/production.yml

Buat file dengan konten berikut dan instal melalui kubectl apply -f:

apiVersion: feature-branch.dmytrostriletskyi.com/v1
kind: StaleFeatureBranch
metadata:
  name: stale-feature-branch
spec:
  namespaceSubstring: -pr-
  afterDaysWithoutDeploy: 3

Parameter namespaceSubstring diperlukan untuk memfilter namespace untuk permintaan tarik dari namespace lain. Misalnya, jika klaster memiliki namespace berikut: habr-back-end, habr-front-end, habr-back-end-pr-17, habr-back-end-pr-33, maka calon yang akan dihapus adalah habr-back-end-pr-17, habr-back-end-pr-33.

Parameter afterDaysWithoutDeploy diperlukan untuk menghapus namespace lama. Misalnya, jika namespace dibuat 3 дня 1 час kembali, dan parameter menunjukkan 3 дня, namespace ini akan dihapus. Ini juga bekerja dalam arah yang berlawanan jika namespace dibuat 2 дня 23 часа kembali, dan parameter menunjukkan 3 дня, namespace ini tidak akan dihapus.

Ada satu parameter lagi, yang bertanggung jawab atas seberapa sering memindai semua namespace dan memeriksa hari-hari tanpa penerapan - periksaSetiapMenit. Secara default itu sama 30 ΠΌΠΈΠ½ΡƒΡ‚Π°ΠΌ.

Bagaimana itu bekerja

Dalam praktiknya, Anda memerlukan:

  1. Buruh pelabuhan untuk bekerja di lingkungan yang terisolasi.
  2. Minikube akan meningkatkan cluster Kubernetes secara lokal.
  3. kubectl β€” antarmuka baris perintah untuk manajemen cluster.

Kami mengembangkan cluster Kubernetes secara lokal:

$ minikube start --vm-driver=docker
minikube v1.11.0 on Darwin 10.15.5
Using the docker driver based on existing profile.
Starting control plane node minikube in cluster minikube.

Kami menunjukkan kubectl gunakan cluster lokal secara default:

$ kubectl config use-context minikube
Switched to context "minikube".

Unduh konfigurasi untuk lingkungan produksi:

$ curl https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/configs/production.yml > stale-feature-branch-production-configs.yml

Karena konfigurasi produksi dikonfigurasi untuk memeriksa namespace lama, dan cluster kami yang baru dibuat tidak memilikinya, kami akan mengganti variabel lingkungan IS_DEBUG pada true. Dengan nilai ini parameternya afterDaysWithoutDeploy tidak diperhitungkan dan namespace tidak diperiksa selama berhari-hari tanpa penerapan, hanya untuk kemunculan substring (-pr-).

Jika Anda aktif Linux:

$ sed -i 's|false|true|g' stale-feature-branch-production-configs.yml

Jika Anda aktif macOS:

$ sed -i "" 's|false|true|g' stale-feature-branch-production-configs.yml

Menginstal proyek:

$ kubectl apply -f stale-feature-branch-production-configs.yml

Memeriksa apakah sumber daya telah muncul di cluster StaleFeatureBranch:

$ kubectl api-resources | grep stalefeaturebranches
NAME                 ... APIGROUP                             ... KIND
stalefeaturebranches ... feature-branch.dmytrostriletskyi.com ... StaleFeatureBranch

Kami memeriksa apakah operator telah muncul di cluster:

$ kubectl get pods --namespace stale-feature-branch-operator
NAME                                           ... STATUS  ... AGE
stale-feature-branch-operator-6bfbfd4df8-m7sch ... Running ... 38s

Jika Anda melihat lognya, ia siap memproses sumber daya StaleFeatureBranch:

$ kubectl logs stale-feature-branch-operator-6bfbfd4df8-m7sch -n stale-feature-branch-operator
... "msg":"Operator Version: 0.0.1"}
...
... "msg":"Starting EventSource", ... , "source":"kind source: /, Kind="}
... "msg":"Starting Controller", ...}
... "msg":"Starting workers", ..., "worker count":1}

Kami menginstal yang sudah jadi fixtures (konfigurasi siap pakai untuk memodelkan sumber daya cluster) untuk suatu sumber daya StaleFeatureBranch:

$ kubectl apply -f https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/fixtures/stale-feature-branch.yml

Konfigurasi menunjukkan untuk mencari namespace dengan substring -pr- sekali masuk 1 ΠΌΠΈΠ½ΡƒΡ‚Ρƒ.:

apiVersion: feature-branch.dmytrostriletskyi.com/v1
kind: StaleFeatureBranch
metadata:
  name: stale-feature-branch
spec:
  namespaceSubstring: -pr-
  afterDaysWithoutDeploy: 1 
  checkEveryMinutes: 1

Operator telah merespons dan siap memeriksa namespace:

$ kubectl logs stale-feature-branch-operator-6bfbfd4df8-m7sch -n stale-feature-branch-operator
... "msg":"Stale feature branch is being processing.","namespaceSubstring":"-pr-","afterDaysWithoutDeploy":1,"checkEveryMinutes":1,"isDebug":"true"}

Mengatur fixtures, berisi dua namespace (project-pr-1, project-pr-2) dan mereka deployments, services, ingress, dan seterusnya:

$ kubectl apply -f https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/fixtures/first-feature-branch.yml -f https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/fixtures/second-feature-branch.yml
...
namespace/project-pr-1 created
deployment.apps/project-pr-1 created
service/project-pr-1 created
horizontalpodautoscaler.autoscaling/project-pr-1 created
secret/project-pr-1 created
configmap/project-pr-1 created
ingress.extensions/project-pr-1 created
namespace/project-pr-2 created
deployment.apps/project-pr-2 created
service/project-pr-2 created
horizontalpodautoscaler.autoscaling/project-pr-2 created
secret/project-pr-2 created
configmap/project-pr-2 created
ingress.extensions/project-pr-2 created

Kami memeriksa apakah semua sumber daya di atas telah berhasil dibuat:

$ kubectl get namespace,pods,deployment,service,horizontalpodautoscaler,configmap,ingress -n project-pr-1 && kubectl get namespace,pods,deployment,service,horizontalpodautoscaler,configmap,ingress -n project-pr-2
...
NAME                              ... READY ... STATUS  ... AGE
pod/project-pr-1-848d5fdff6-rpmzw ... 1/1   ... Running ... 67s

NAME                         ... READY ... AVAILABLE ... AGE
deployment.apps/project-pr-1 ... 1/1   ... 1         ... 67s
...

Sejak kami menyertakannya debug, ruang nama project-pr-1 ΠΈ project-pr-2, oleh karena itu semua sumber daya lainnya harus segera dihapus tanpa memperhitungkan parameternya afterDaysWithoutDeploy. Ini dapat dilihat di log operator:

$ kubectl logs stale-feature-branch-operator-6bfbfd4df8-m7sch -n stale-feature-branch-operator
... "msg":"Namespace should be deleted due to debug mode is enabled.","namespaceName":"project-pr-1"}
... "msg":"Namespace is being processing.","namespaceName":"project-pr-1","namespaceCreationTimestamp":"2020-06-16 18:43:58 +0300 EEST"}
... "msg":"Namespace has been deleted.","namespaceName":"project-pr-1"}
... "msg":"Namespace should be deleted due to debug mode is enabled.","namespaceName":"project-pr-2"}
... "msg":"Namespace is being processing.","namespaceName":"project-pr-2","namespaceCreationTimestamp":"2020-06-16 18:43:58 +0300 EEST"}
... "msg":"Namespace has been deleted.","namespaceName":"project-pr-2"}

Jika Anda memeriksa ketersediaan sumber daya, mereka akan berada dalam status Terminating (proses penghapusan) atau sudah dihapus (output perintah kosong).

$ kubectl get namespace,pods,deployment,service,horizontalpodautoscaler,configmap,ingress -n project-pr-1 && kubectl get namespace,pods,deployment,service,horizontalpodautoscaler,configmap,ingress -n project-pr-2
...

Anda dapat mengulangi proses pembuatannya fixtures beberapa kali dan pastikan semuanya dihapus dalam satu menit.

Alternatif

Apa yang bisa dilakukan selain operator yang bekerja di cluster? Ada beberapa pendekatan, semuanya tidak sempurna (dan kekurangannya bersifat subjektif), dan setiap orang memutuskan sendiri apa yang terbaik untuk proyek tertentu:

  1. Hapus cabang fitur selama pembangunan integrasi berkelanjutan dari cabang master.

    • Untuk melakukan ini, Anda perlu mengetahui pull request mana yang terkait dengan commit yang sedang dibangun. Karena namespace cabang fitur berisi pengidentifikasi permintaan tarik - nomornya, atau nama cabang, pengidentifikasi harus selalu ditentukan dalam penerapan.
    • Pembangunan cabang master gagal. Misalnya, Anda memiliki tahapan berikut: mengunduh proyek, menjalankan pengujian, membangun proyek, membuat rilis, mengirim pemberitahuan, menghapus cabang fitur dari permintaan penarikan terakhir. Jika build gagal saat mengirim notifikasi, Anda harus menghapus semua sumber daya di cluster secara manual.
    • Tanpa konteks yang tepat, penghapusan cabang fitur di build master tidak akan terlihat jelas.

  2. Menggunakan webhook (contoh).

    • Ini mungkin bukan pendekatan Anda. Misalnya, di Jenkins, hanya satu jenis saluran yang mendukung kemampuan untuk menyimpan konfigurasinya dalam kode sumber. Saat menggunakan webhook, Anda perlu menulis skrip Anda sendiri untuk memprosesnya. Skrip ini harus ditempatkan di antarmuka Jenkins, yang sulit dipelihara.

  3. Untuk menulis pekerjaan cron dan menambahkan cluster Kubernetes.

    • Menghabiskan waktu untuk menulis dan memberikan dukungan.
    • Operator sudah bekerja dengan gaya serupa, didokumentasikan dan didukung.

Terima kasih atas perhatian Anda pada artikel tersebut. Tautan ke proyek di Github.

Sumber: www.habr.com

Tambah komentar