เราจะใช้ Gitlab CI และ GitOps แบบแมนนวลเพื่อนำไปใช้และปรับใช้ Canary ใน Kubernetes
บทความจากซีรี่ส์นี้:
- (บทความนี้)
การปรับใช้ Canary โดยใช้ ArgoCI - การปรับใช้ Canary โดยใช้ Istio
- การปรับใช้ Canary โดยใช้ Jenkins-X Istio Flagger
เราจะดำเนินการปรับใช้ Canary ด้วยตนเองผ่าน GitOps และสร้าง/แก้ไขทรัพยากร Kubernetes หลัก บทความนี้มีจุดประสงค์เพื่อการแนะนำเป็นหลัก เกี่ยวกับวิธีการปรับใช้ใน Kubernetes Canary เนื่องจากมีวิธีการอัตโนมัติที่มีประสิทธิภาพมากกว่าซึ่งเราจะพิจารณาในบทความต่อไปนี้
การปรับใช้นกขมิ้น
ด้วยกลยุทธ์ Canary การอัปเดตจะมีผลกับผู้ใช้เพียงบางส่วนเท่านั้น ผ่านการตรวจสอบ ข้อมูลบันทึก การทดสอบด้วยตนเอง หรือช่องทางแสดงความคิดเห็นอื่นๆ รุ่นจะได้รับการทดสอบก่อนที่จะเผยแพร่ให้กับผู้ใช้ทุกคน
การปรับใช้ Kubernetes (การอัปเดตแบบต่อเนื่อง)
กลยุทธ์เริ่มต้นสำหรับการปรับใช้ Kubernetes คือการอัปเดตแบบต่อเนื่อง โดยที่พ็อดจำนวนหนึ่งจะเปิดตัวพร้อมกับอิมเมจเวอร์ชันใหม่ หากสร้างขึ้นโดยไม่มีปัญหา พ็อดที่มีอิมเมจเวอร์ชันเก่าจะถูกยกเลิก และพ็อดใหม่จะถูกสร้างขึ้นพร้อมกัน
GitOps
เราใช้ GitOps ในตัวอย่างนี้เนื่องจากเรา:
- ใช้ Git เป็นแหล่งความจริงแหล่งเดียว
- เราใช้ Git Operations สำหรับการสร้างและการปรับใช้ (ไม่จำเป็นต้องใช้คำสั่งอื่นนอกจากแท็ก git/merge)
ตัวอย่าง
ลองใช้แนวทางปฏิบัติที่ดี - เพื่อให้มีพื้นที่เก็บข้อมูลหนึ่งแห่งสำหรับโค้ดแอปพลิเคชันและอีกแห่งสำหรับโครงสร้างพื้นฐาน
พื้นที่เก็บข้อมูลแอปพลิเคชัน
นี่เป็น Python+Flask API ที่เรียบง่ายมากซึ่งส่งคืนการตอบกลับเป็น JSON เราจะสร้างแพ็คเกจผ่าน GitlabCI และผลักดันผลลัพธ์ไปยัง Gitlab Registry ในรีจิสทรี เรามีเวอร์ชันเผยแพร่ที่แตกต่างกันสองเวอร์ชัน:
wuestkamp/k8s-deployment-example-app:v1
wuestkamp/k8s-deployment-example-app:v2
ข้อแตกต่างเพียงอย่างเดียวคือการเปลี่ยนแปลงในไฟล์ JSON ที่ส่งคืน เราใช้แอปพลิเคชันนี้เพื่อให้เห็นภาพได้ง่ายที่สุดเท่าที่จะเป็นไปได้ว่าเรากำลังสื่อสารด้วยเวอร์ชันใด
พื้นที่เก็บข้อมูลโครงสร้างพื้นฐาน
ในหัวผักกาดนี้เราจะปรับใช้ผ่าน GitlabCI ไปยัง Kubernetes .gitlab-ci.yml
มีลักษณะเช่นนี้:
image: traherom/kustomize-docker
before_script:
- printenv
- kubectl version
stages:
- deploy
deploy test:
stage: deploy
before_script:
- echo $KUBECONFIG
script:
- kubectl get all
- kubectl apply -f i/k8s
only:
- master
หากต้องการรันด้วยตัวเองคุณจะต้องมีคลัสเตอร์ คุณสามารถใช้ Gcloud:
gcloud container clusters create canary --num-nodes 3 --zone europe-west3-b
gcloud compute firewall-rules create incoming-80 --allow tcp:80
คุณต้องแยก KUBECONFIG
ใน GitlabCI ซึ่งจะมีการกำหนดค่าสำหรับการเข้าถึง kubectl
ไปยังคลัสเตอร์ของคุณ
คุณสามารถอ่านเกี่ยวกับวิธีรับข้อมูลรับรองสำหรับคลัสเตอร์ (Gcloud)
โครงสร้างพื้นฐาน Yaml
ในพื้นที่เก็บข้อมูลโครงสร้างพื้นฐานเรามีบริการ:
apiVersion: v1
kind: Service
metadata:
labels:
id: app
name: app
spec:
ports:
- port: 80
protocol: TCP
targetPort: 5000
selector:
id: app
type: LoadBalancer
และปรับใช้ใน deploy.yaml
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
replicas: 10
selector:
matchLabels:
id: app
type: main
template:
metadata:
labels:
id: app
type: main
spec:
containers:
- image: registry.gitlab.com/wuestkamp/k8s-deployment-example-app:v1
name: app
resources:
limits:
cpu: 100m
memory: 100Mi
และมีการปรับใช้อีกครั้งใน deploy-canary.yaml
:
kind: Deployment
metadata:
name: app-canary
spec:
replicas: 0
selector:
matchLabels:
id: app
type: canary
template:
metadata:
labels:
id: app
type: canary
spec:
containers:
- image: registry.gitlab.com/wuestkamp/k8s-deployment-example-app:v2
name: app
resources:
limits:
cpu: 100m
memory: 100Mi
โปรดทราบว่า app-deploy ยังไม่มีการกำหนดแบบจำลองใดๆ
ดำเนินการปรับใช้เบื้องต้น
หากต้องการเริ่มการปรับใช้ครั้งแรก คุณสามารถเริ่มไปป์ไลน์ GitlabCI ด้วยตนเองบนสาขาหลักได้ หลังจากนั้น kubectl
ควรส่งออกสิ่งต่อไปนี้:
ที่เราเห็น app
การปรับใช้ด้วย 10 เรพลิกาและ app-canary ด้วย 0 นอกจากนี้ยังมี LoadBalancer ที่เราสามารถเข้าถึงได้ผ่าน curl
ผ่าน IP ภายนอก:
while true; do curl -s 35.198.149.232 | grep label; sleep 0.1; done
เราเห็นว่าแอปพลิเคชันทดสอบของเราส่งคืนเฉพาะ "v1"
กำลังดำเนินการปรับใช้ Canary
ขั้นตอนที่ 1: เปิดตัวเวอร์ชันใหม่สำหรับผู้ใช้บางราย
เราตั้งค่าจำนวนเรพลิกาเป็น 1 ในไฟล์ release-canary.yaml และอิมเมจเวอร์ชันใหม่:
kind: Deployment
metadata:
name: app-canary
spec:
replicas: 1
selector:
matchLabels:
id: app
type: canary
template:
metadata:
labels:
id: app
type: canary
spec:
containers:
- image: registry.gitlab.com/wuestkamp/k8s-deployment-example-app:v2
name: app
resources:
limits:
cpu: 100m
memory: 100Mi
ในไฟล์ deploy.yaml
เราเปลี่ยนจำนวนเรพลิกาเป็น 9:
kind: Deployment
metadata:
name: app
spec:
replicas: 9
selector:
matchLabels:
id: app
...
เราส่งการเปลี่ยนแปลงเหล่านี้ไปยังพื้นที่เก็บข้อมูลซึ่งจะเริ่มการปรับใช้ (ผ่าน GitlabCI) และเห็นผลลัพธ์:
บริการของเราจะชี้ไปที่การปรับใช้ทั้งสองแบบ เนื่องจากทั้งสองมีตัวเลือกแอป เนื่องจากการสุ่มเริ่มต้นของ Kubernetes เราควรเห็นการตอบสนองที่แตกต่างกันสำหรับคำขอประมาณ 10%:
สถานะปัจจุบันของแอปพลิเคชันของเรา (GitOps ที่นำมาจาก Git เป็นแหล่งที่มาของความจริงเดียว) คือการมีอยู่ของการปรับใช้สองรายการพร้อมเรพลิกาที่ใช้งานอยู่ หนึ่งรายการสำหรับแต่ละเวอร์ชัน
ผู้ใช้ประมาณ 10% คุ้นเคยกับเวอร์ชันใหม่และทดสอบโดยไม่ได้ตั้งใจ ตอนนี้เป็นเวลาที่จะตรวจสอบข้อผิดพลาดในบันทึกและการตรวจสอบข้อมูลเพื่อค้นหาปัญหา
ขั้นตอนที่ 2: เปิดตัวเวอร์ชันใหม่ให้กับผู้ใช้ทุกคน
เราตัดสินใจว่าทุกอย่างเป็นไปด้วยดี และตอนนี้เราจำเป็นต้องเปิดตัวเวอร์ชันใหม่ให้กับผู้ใช้ทุกคน ในการดำเนินการนี้ เราเพียงแค่อัปเดต deploy.yaml
การติดตั้งอิมเมจเวอร์ชันใหม่และจำนวนเรพลิกาเท่ากับ 10 ใน deploy-canary.yaml
เรากำหนดจำนวนเรพลิกากลับเป็น 0 หลังจากการปรับใช้ ผลลัพธ์จะเป็นดังนี้:
ข้อสรุปถึง
สำหรับฉัน การเรียกใช้การปรับใช้ด้วยตนเองด้วยวิธีนี้ช่วยให้เข้าใจว่าสามารถกำหนดค่าโดยใช้ k8 ได้ง่ายเพียงใด เนื่องจาก Kubernetes อนุญาตให้คุณอัปเดตทุกอย่างผ่าน API ขั้นตอนเหล่านี้จึงสามารถดำเนินการอัตโนมัติผ่านสคริปต์ได้
อีกสิ่งหนึ่งที่ต้องดำเนินการคือจุดเริ่มต้นของผู้ทดสอบ (LoadBalancer หรือผ่าน Ingress) ซึ่งสามารถเข้าถึงได้เฉพาะเวอร์ชันใหม่เท่านั้น สามารถใช้สำหรับการเรียกดูด้วยตนเอง
ในบทความต่อๆ ไป เราจะตรวจสอบโซลูชันอัตโนมัติอื่นๆ ที่ใช้สิ่งที่เราทำเกือบทั้งหมด
อ่านบทความอื่น ๆ ในบล็อกของเราด้วย:
การโยกย้ายจาก ClickHouse โดยไม่ได้รับอนุญาตไปยัง ClickHouse ที่ได้รับอนุญาตนำไปสู่อะไร? การสร้างโมดูลแบบไดนามิกสำหรับ Nginx อัปเดต nxs-build-tools - ตัวช่วยในการสร้างแพ็คเกจ deb และ rpm ข้อมูลเบื้องต้นเกี่ยวกับการอนุญาต Kubernetes ของ Hashicorp Consul สิ่งที่เราต้องเผชิญกับเมื่อใช้ยูทิลิตี้ Csync2 บอทโทรเลขสำหรับ Redmine วิธีทำให้ชีวิตง่ายขึ้นสำหรับตัวคุณเองและผู้อื่น
ที่มา: will.com