BLUE-GREEN DEPLOYMENT TRÊN KUBERNETES

Lời đầu Blue-green deployment là một chiến lược triển khai sản phẩm dịch vụ trong đó bạn tạo ra hai môi trường giống hệt nhau. Một môi trường sẽ chạy sản phẩm phiên bản hiện tại (thường gọi là blue) trong khi môi trường còn lại (green) chạy thử nghiệm phiên bản mới hơn. Sau

Lời đầu

Blue-green deployment là một chiến lược triển khai sản phẩm dịch vụ trong đó bạn tạo ra hai môi trường giống hệt nhau. Một môi trường sẽ chạy sản phẩm phiên bản hiện tại (thường gọi là blue) trong khi môi trường còn lại (green) chạy thử nghiệm phiên bản mới hơn.

Sau khi thử nghiệm xong xuôi, truy cập từ bên ngoài của người dùng sẽ được điều hướng trực tiếp sang môi trường green, lúc này green trở thành phiên bản chính thức (production) thay thế blue.

Ưu điểm của chiến lược này là tăng tính sẵn có cũng như giảm rủi ro khi triển khai sản phẩm dịch vụ.

Song song với đó thì chiến lược này cũng có một vài nhược điểm, có thể kể đến:

  • Tiêu tốn nhiều tài nguyên do cần duy trì 2 môi trường cùng lúc khi triển khai
  • Blue-green deployment đòi hỏi các service trên cả 2 môi trường sử dụng chung database, trong trường hợp code mới có tác động thay đổi cấu trúc database, cần xây dựng chiến lược đồng bộ sao cho cả hai môi trường có thể chạy cùng lúc mà không gặp sự cố. Với vấn đề này, ta có thể sử dụng liquibase để xây dựng giải pháp

Áp dụng Blue-green deploymen trên kubernetes

Tại sao lại là kubernetes?

Ngoài việc là một công cụ điều phối container cực kì hữu dụng, Kubernetes còn hỗ trợ nhiều mô hình kiến trúc mà developer/operator có thể tái sử dụng thông qua việc sử dụng manifest files, hay helm chart. Nhờ vậy ta có thể dễ dàng nhân bản một môi trường thứ hai mà không tốn nhiều công sức.

Cùng với đó, Kubernetes cung cấp một giải pháp Load balancing chất lượng: Ingress. Ta có thể sử dụng Ingress để switch hai môi trường blue/green bằng cách điều hướng truy cập người dùng thông quan các route rule.

Có thể nói Kubernetes là một nền tảng cực kỳ phù hợp để áp dụng chiến lược blue-green deployment.

Tiến hành thử nghiệm

Trong phần này, mình sẽ áp dụng chiến lược blue-green deployment cho app trên kubernetes. Để đơn giản hóa vấn đề (nhất là những vấn đề liên quan đến mount storage), mình sử dụng kubernetes có 1 node master duy nhất.

Setup môi trường

Khởi tạo app

Đầu tiên, mình sẽ cần khởi tạo 2 app BLUE, GREEN.

Tạo BLUE app với manifest file

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: blue
  name: blue
spec:
  replicas: 1
  selector:
    matchLabels:
      app: blue
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: blue
    spec:
      containers:
      - image: nginx
        name: nginx
        resources: {}
        volumeMounts:
          - mountPath: /usr/share/nginx/html
            name: test-volume
      volumes:
      - name: test-volume
        hostPath:
          path: /data/blue-nginx/
status: {}

Ở đây, mình mount thư mục html của nginx container tới thư mục /data/blue-nginx/ trên kubernetes node . Các file trong thư mục này sẽ được tạo ở phần sau

Expose BLUE app (hay nói cách khác là tạo service cho BLUE app)

$ kubectl expose deployment blue --port=8081 --target-port=80 --name=blueapp

Tương tự với GREEN app, mình có manifest file

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: green
  name: green
spec:
  replicas: 1
  selector:
    matchLabels:
      app: green
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: green
    spec:
      containers:
      - image: nginx
        name: nginx
        resources: {}
        volumeMounts:
          - mountPath: /usr/share/nginx/html
            name: test-volume
      volumes:
      - name: test-volume
        hostPath:
          path: /data/green-nginx/
status: {}

Expose GREEN app (hay tạo service cho GREEN app)

$ kubectl expose deployment green --port=8081 --target-port=80 --name=greenapp

Tạo file /data/blue-nginx/index.html trên kubernetes node với nội dung

Blue app!

Tương tự với file /data/blue-nginx/index.html

Green app!

Tạo ingress rule

Nếu chưa rõ về Ingress, bạn có thể tham khảo bài viết này.

Note: để ingress rule có thể hoạt động, bạn cần cài đặt phần mềm implement Ingress Controller (xem chi tiết tại link).

Trong ví dụ này, ta sẽ sử dụng HAProxy Ingress Controller.

Tạo ingress rule

kubectl create ingress blue-green 
--annotation kubernetes.io/ingress.class=haproxy 
--rule="blue.green.app/=blueapp:8081" 
--rule="test-blue.green.app/=greenapp:8081"

Rule này sẽ forward

  • Các request có host blue.green.app tới service blueapp port 8081
  • Các request có host test-blue.green.app tới service greenapp port 8081

Ở đây mình sử dụng 2 host: blue.green.app cho phiên bản chính thức và test-blue.green.app cho phiên bản thử nghiệm.

Để sử dụng đc 2 host này thì cần add host.

blue.green.app 127.0.0.1
test-blue.green.app 127.0.0.1
# lưu ý thay thế 127.0.0.1 với IP kubernetes node tương ứng

Xác nhận app hoạt động ổn

$ curl http://blue.green.app
$ curl http://test-blue.green.app

Nều cài đặt thành công, bạn sẽ thấy kết quả trả về lần lượt là

Blue app!
Green app!

Triển khai blue-green

Bài toán ở đây là ta sẽ áp dụng blue-green deployment với các điều kiện:

  • Đầu vào: image phiên bản mới
  • Các bước cần thực hiện:
    • cập nhật image lên môi trường test
    • tiến hành kiểm thử
    • switch môi trường kiểm thử với môi trường prod
  • Đầu ra: người dùng truy cập được app phiên bản mới trên môi trường prod

Lưu ý: ở đây môi trường prod không cố định phải là blue app, môi trường kiểm thử cũng ko nhất thiết là green app, chúng sẽ thay đổi sau mỗi lần thực hiện switch.

  1. Cập nhật image cho môi trường test

Xây dựng script để cập nhật image cho app trên môi trường test (app có thể là blue hoặc green tùy từng thời điểm).
Mình sử dụng thông tin của ingress để trích xuất tên service/app đang chạy trên môi trường test.

CURRENT_TEST_SVC=$(kubectl get ingress blue-green -o=jsonpath="
{.spec.rules[1].http.paths[0].backend.service.name}")
CURRENT_TEST_DEPLOYMENT=$(kubectl get svc $CURRENT_TEST_SVC -o=jsonpath="
{.spec.selector.app}")
kubectl set image deployment $CURRENT_TEST_DEPLOYMENT nginx=nginx:latest

Với tên app có được, mình tiến hành cập nhật image với câu lệnh

$ kubectl set image deployment ...
  1. Tiến hành kiểm thử

Thông thường ở bước này, khi áp dụng cho các sản phẩm thực sự, ta sẽ tiến hành chạy automation test script. Nếu pass, tiến hành tiếp bước 3, còn không thì rollback.

  1. Switch môi trường kiểm thử với môi trường prod

Tương tự như bước 1, ở đây mình dùng script để lấy thông tin các app đang chạy trên prod, test.
Sau đó sẽ khởi tạo lại ingress blue-green với rule mới để switch app cho 2 môi trường.

TMP=$(kubectl get ingress blue-green)
RESULT=$?
# if ingress not exist, exit
if [ $RESULT != 0 ]; then
	echo "Fail to switch env! Ingress not exist"
	exit
fi
# get the current prod, test env
CURRENT_PROD=$(kubectl get ingress blue-green -o=jsonpath="{.spec.rules[0].http.paths[0].backend.service.name}")
CURRENT_TEST=$(kubectl get ingress blue-green -o=jsonpath="{.spec.rules[1].http.paths[0].backend.service.name}")
echo "switching from "  $CURRENT_PROD " to "  $CURRENT_TEST " ..."
PROD_RULE="blue.green.app/="$CURRENT_TEST":8081"
TEST_RULE="test-blue.green.app/="$CURRENT_PROD":8081"
# recreate ingress with new rules
kubectl delete ingress blue-green
kubectl create ingress blue-green 
	--annotation kubernetes.io/ingress.class=haproxy 
	--rule=$PROD_RULE 
	--rule=$TEST_RULE

Sau khi chạy script này, bạn có thể verify lại xem liệu 2 môi trường đã được switch chưa với câu lệnh

$ curl http://blue.green.app
$ curl http://test-blue.green.app

Lời kết

Trong bài viết này, mình đã chia sẻ về blue-green deployment, cũng như cách thức áp dụng blue-green deployment cho các app chạy trên kubernetes.

Hi vọng kiến thức sẽ hữu ích !

Cảm ơn mọi người đã dành thời gian theo dõi!

Tham khảo

https://www.haproxy.com/blog/rolling-updates-and-blue-green-deployments-with-kubernetes-and-haproxy/

Nguồn: viblo.asia

Bài viết liên quan

WebP là gì? Hướng dẫn cách để chuyển hình ảnh jpg, png qua webp

WebP là gì? WebP là một định dạng ảnh hiện đại, được phát triển bởi Google

Điểm khác biệt giữa IPv4 và IPv6 là gì?

IPv4 và IPv6 là hai phiên bản của hệ thống địa chỉ Giao thức Internet (IP). IP l

Check nameservers của tên miền xem website trỏ đúng chưa

Tìm hiểu cách check nameservers của tên miền để xác định tên miền đó đang dùn

Mình đang dùng Google Domains để check tên miền hàng ngày

Từ khi thông báo dịch vụ Google Domains bỏ mác Beta, mình mới để ý và bắt đầ