การลบสาขาฟีเจอร์ที่ล้าสมัยในคลัสเตอร์ Kubernetes

การลบสาขาฟีเจอร์ที่ล้าสมัยในคลัสเตอร์ Kubernetes

Hi! สาขาคุณลักษณะ (หรือที่เรียกว่าปรับใช้ดูตัวอย่าง ตรวจสอบแอป) - นี่คือเวลาที่ไม่เพียงแต่ปรับใช้สาขาหลักเท่านั้น แต่ยังรวมถึงแต่ละคำขอดึงไปยัง URL ที่ไม่ซ้ำกันด้วย คุณสามารถตรวจสอบว่าโค้ดทำงานในสภาพแวดล้อมการผลิตหรือไม่ โดยฟีเจอร์นี้สามารถแสดงให้โปรแกรมเมอร์หรือผู้เชี่ยวชาญด้านผลิตภัณฑ์คนอื่นเห็นได้ ในขณะที่คุณกำลังทำงานกับคำขอดึง แต่ละคอมมิตใหม่ การปรับใช้ปัจจุบันสำหรับโค้ดเก่าจะถูกลบ และการปรับใช้ใหม่สำหรับโค้ดใหม่จะถูกเผยแพร่ คำถามอาจเกิดขึ้นเมื่อคุณรวมคำขอดึงเข้ากับสาขาหลัก คุณไม่ต้องการสาขาฟีเจอร์อีกต่อไป แต่ทรัพยากร Kubernetes ยังอยู่ในคลัสเตอร์

ข้อมูลเพิ่มเติมเกี่ยวกับสาขาฟีเจอร์

วิธีหนึ่งในการสร้างฟีเจอร์แบรนช์ใน Kubernetes คือการใช้เนมสเปซ กล่าวโดยสรุป การกำหนดค่าการผลิตมีลักษณะดังนี้:

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

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

สำหรับสาขาฟีเจอร์ เนมสเปซจะถูกสร้างขึ้นพร้อมกับตัวระบุ (เช่น หมายเลขคำขอดึงข้อมูล) และคำนำหน้า/โพสต์ฟิกซ์บางประเภท (เช่น -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
...

โดยทั่วไปฉันเขียน ตัวดำเนินการ Kubernetes (แอปพลิเคชันที่สามารถเข้าถึงทรัพยากรคลัสเตอร์) ลิงค์ไปยังโครงการบน Github. จะลบเนมสเปซที่เป็นของสาขาคุณลักษณะเก่า ใน Kubernetes หากคุณลบเนมสเปซ ทรัพยากรอื่นๆ ในเนมสเปซนั้นจะถูกลบโดยอัตโนมัติด้วย

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

คุณสามารถอ่านเกี่ยวกับวิธีนำฟีเจอร์แบรนช์ไปใช้งานในคลัสเตอร์ได้ ที่นี่ и ที่นี่.

แรงจูงใจ

มาดูวงจรการร้องขอการดึงทั่วไปที่มีการบูรณาการอย่างต่อเนื่อง (continuous integration):

  1. เราผลักดันความมุ่งมั่นใหม่ไปที่สาขา
  2. บนบิลด์ linters และ/หรือการทดสอบจะถูกรัน
  3. การกำหนดค่าคำขอดึง Kubernetes ถูกสร้างขึ้นทันที (เช่น หมายเลขจะถูกแทรกลงในเทมเพลตที่เสร็จสมบูรณ์)
  4. เมื่อใช้ kubectl การกำหนดค่าจะถูกเพิ่มลงในคลัสเตอร์ (ปรับใช้)
  5. คำขอดึงถูกรวมเข้ากับสาขาหลัก

ในขณะที่คุณกำลังทำงานกับคำขอดึง แต่ละคอมมิตใหม่ การปรับใช้ปัจจุบันสำหรับโค้ดเก่าจะถูกลบ และการปรับใช้ใหม่สำหรับโค้ดใหม่จะถูกเผยแพร่ แต่เมื่อรวมคำขอดึงเข้ากับสาขาหลักแล้ว จะมีการสร้างเฉพาะสาขาหลักเท่านั้น ผลปรากฏว่าเราได้ลืมคำขอดึงไปแล้ว และทรัพยากร Kubernetes ยังคงอยู่ในคลัสเตอร์

วิธีการใช้

ติดตั้งโปรเจ็กต์ด้วยคำสั่งด้านล่าง:

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

สร้างไฟล์ที่มีเนื้อหาดังต่อไปนี้และติดตั้งผ่าน kubectl apply -f:

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

พารามิเตอร์ เนมสเปซSubstring จำเป็นในการกรองเนมสเปซสำหรับการดึงคำขอจากเนมสเปซอื่น ตัวอย่างเช่น หากคลัสเตอร์มีเนมสเปซต่อไปนี้: habr-back-end, habr-front-end, habr-back-end-pr-17, habr-back-end-pr-33จากนั้นผู้สมัครที่จะลบจะเป็น habr-back-end-pr-17, habr-back-end-pr-33.

พารามิเตอร์ afterDaysWithoutDeploy จำเป็นต้องลบเนมสเปซเก่า เช่น หากมีการสร้างเนมสเปซ 3 дня 1 час กลับ และพารามิเตอร์บ่งชี้ 3 дняเนมสเปซนี้จะถูกลบ นอกจากนี้ยังทำงานในทิศทางตรงกันข้ามหากมีการสร้างเนมสเปซ 2 дня 23 часа กลับ และพารามิเตอร์บ่งชี้ 3 дняเนมสเปซนี้จะไม่ถูกลบ

มีอีกหนึ่งพารามิเตอร์มีหน้าที่รับผิดชอบในการสแกนเนมสเปซทั้งหมดและตรวจสอบวันโดยไม่ต้องปรับใช้บ่อยแค่ไหน - ตรวจสอบทุกนาที. โดยค่าเริ่มต้นจะเท่ากัน 30 минутам.

Какэтоработает

ในทางปฏิบัติ คุณจะต้อง:

  1. นักเทียบท่า สำหรับการทำงานในสภาพแวดล้อมที่โดดเดี่ยว
  2. มินิคุเบะ จะเพิ่มคลัสเตอร์ Kubernetes ในเครื่อง
  3. Kubectl — อินเตอร์เฟสบรรทัดคำสั่งสำหรับการจัดการคลัสเตอร์

เราเพิ่มคลัสเตอร์ Kubernetes ภายในเครื่อง:

$ 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.

แสดง kubectl ใช้คลัสเตอร์ท้องถิ่นตามค่าเริ่มต้น:

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

ดาวน์โหลดการกำหนดค่าสำหรับสภาพแวดล้อมการใช้งานจริง:

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

เนื่องจากการกำหนดค่าการใช้งานจริงได้รับการกำหนดค่าให้ตรวจสอบเนมสเปซเก่า และคลัสเตอร์ที่เพิ่งยกใหม่ของเราไม่มี เราจึงจะแทนที่ตัวแปรสภาพแวดล้อม IS_DEBUG บน true. ด้วยค่านี้พารามิเตอร์ afterDaysWithoutDeploy ไม่ได้ถูกนำมาพิจารณาและเนมสเปซจะไม่ถูกตรวจสอบสำหรับวันที่ไม่มีการปรับใช้ เฉพาะสำหรับการเกิดขึ้นของสตริงย่อย (-pr-).

หากคุณอยู่บน Linux:

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

หากคุณอยู่บน macOS:

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

การติดตั้งโครงการ:

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

ตรวจสอบว่ามีทรัพยากรปรากฏในคลัสเตอร์ StaleFeatureBranch:

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

เราตรวจสอบว่ามีโอเปอเรเตอร์ปรากฏในคลัสเตอร์:

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

หากคุณดูบันทึก แสดงว่าพร้อมที่จะประมวลผลทรัพยากรแล้ว 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}

เราติดตั้งแบบสำเร็จรูป fixtures (การกำหนดค่าสำเร็จรูปสำหรับการสร้างแบบจำลองทรัพยากรคลัสเตอร์) สำหรับทรัพยากร StaleFeatureBranch:

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

การกำหนดค่าระบุให้ค้นหาเนมสเปซด้วยสตริงย่อย -pr- ครั้งหนึ่งใน 1 минуту.:

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

โอเปอเรเตอร์ตอบกลับและพร้อมที่จะตรวจสอบเนมสเปซแล้ว:

$ 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"}

ตั้ง fixturesซึ่งมีสองเนมสเปซ (project-pr-1, project-pr-2) และพวกเขา deployments, services, ingressและอื่นๆ:

$ 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

เราตรวจสอบว่าทรัพยากรทั้งหมดข้างต้นถูกสร้างขึ้นสำเร็จแล้ว:

$ 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
...

เนื่องจากเรารวม debug, เนมสเปซ project-pr-1 и project-pr-2ดังนั้นทรัพยากรอื่นๆ ทั้งหมดจะต้องถูกลบทันทีโดยไม่คำนึงถึงพารามิเตอร์ afterDaysWithoutDeploy. สามารถดูได้ในบันทึกของผู้ปฏิบัติงาน:

$ 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"}

หากคุณตรวจสอบความพร้อมใช้งานของทรัพยากร ทรัพยากรเหล่านั้นจะอยู่ในสถานะ Terminating (กระบวนการลบ) หรือถูกลบไปแล้ว (เอาต์พุตคำสั่งว่างเปล่า)

$ 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
...

คุณสามารถทำซ้ำขั้นตอนการสร้างได้ fixtures หลายครั้งและตรวจสอบให้แน่ใจว่าถูกลบออกภายในหนึ่งนาที

ทางเลือก

สิ่งที่สามารถทำได้แทนผู้ปฏิบัติงานที่ทำงานในคลัสเตอร์? มีหลายวิธีทั้งหมดนั้นไม่สมบูรณ์ (และข้อบกพร่องเป็นเรื่องส่วนตัว) และทุกคนตัดสินใจด้วยตัวเองว่าอะไรดีที่สุดสำหรับโครงการใดโครงการหนึ่ง:

  1. ลบสาขาคุณลักษณะในระหว่างการรวมระบบอย่างต่อเนื่องของสาขาหลัก

    • ในการดำเนินการนี้ คุณจำเป็นต้องทราบว่าคำขอดึงใดที่เกี่ยวข้องกับการคอมมิตที่กำลังถูกสร้างขึ้น เนื่องจากเนมสเปซสาขาฟีเจอร์มีตัวระบุคำขอดึง - หมายเลขหรือชื่อของสาขา จึงต้องระบุตัวระบุในการคอมมิตเสมอ
    • การสร้างสาขาหลักล้มเหลว ตัวอย่างเช่น คุณมีขั้นตอนต่อไปนี้: ดาวน์โหลดโปรเจ็กต์ รันการทดสอบ สร้างโปรเจ็กต์ เผยแพร่ ส่งการแจ้งเตือน ล้างสาขาฟีเจอร์ของคำขอดึงครั้งล่าสุด หากบิลด์ล้มเหลวเมื่อส่งการแจ้งเตือน คุณจะต้องลบทรัพยากรทั้งหมดในคลัสเตอร์ด้วยตนเอง
    • หากไม่มีบริบทที่เหมาะสม การลบสาขาคุณลักษณะในรุ่นหลักจะไม่ชัดเจน

  2. การใช้เว็บฮุค (ตัวอย่าง).

    • นี่อาจไม่ใช่แนวทางของคุณ ตัวอย่างเช่นใน เจนกิ้นส์ไปป์ไลน์ประเภทเดียวเท่านั้นที่รองรับความสามารถในการบันทึกการกำหนดค่าในซอร์สโค้ด เมื่อใช้ webhooks คุณต้องเขียนสคริปต์ของคุณเองเพื่อประมวลผล สคริปต์นี้จะต้องวางไว้ในอินเทอร์เฟซของ Jenkins ซึ่งยากต่อการบำรุงรักษา

  3. การเขียน ครอนจ็อบ และเพิ่มคลัสเตอร์ Kubernetes

    • ใช้เวลาในการเขียนและการสนับสนุน
    • ผู้ปฏิบัติงานทำงานในลักษณะเดียวกันอยู่แล้ว ได้รับการจัดทำเป็นเอกสารและรองรับ

ขอขอบคุณที่ให้ความสนใจบทความ ลิงก์ไปยังโครงการบน Github.

ที่มา: will.com

เพิ่มความคิดเห็น