Giới thiệu
Hướng dẫn triển khai A/B Testing Deployment lên Kubernetes với HAProxy.
A/B Testing Deployment là cách triển khai hai phiên bản của ứng dụng cùng một lúc, và ta có thể điều hướng người dùng vào phiên bản nào theo ý muốn. Ứng dụng trong việc khi ta triển khai phiên bản mới của ứng dụng và chỉ muốn một lượng người dùng nhất định truy cập được phiên bản mới, còn lại truy cập phiên bản cũ.
Trong bài này ta triển khai hai trang web đơn giản và dùng HAProxy để điều hướng người dùng theo tỉ lệ 80/20.
Các bước thực hiện:
- Dùng Deployment để triển khai hai trang web
- Viết cấu hình HAPorxy để chia lưu lượng theo tỉ lệ 80/20
- Dùng Deployment để triển HAProxy
Triển khai ứng dụng
Tạo một tệp tin tên là app-v1.yaml
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app-v1
labels:
app: my-app
spec:
selector:
matchLabels:
app: my-app
version: v1.0.0
template:
metadata:
labels:
app: my-app
version: v1.0.0
spec:
containers:
- name: my-app
image: argoproj/rollouts-demo:green
ports:
- name: http
containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: my-app-v1
spec:
selector:
app: my-app
version: v1.0.0
ports:
- port: 8080
targetPort: http
name: http
Tạo ứng dụng:
kubectl apply -f app-v1.yaml
Truy cập ứng dụng với port-forward
:
kubectl port-forward svc/my-app-v1 8080:8080
Mở browser và truy cập hai địa chỉ localhost:8080
, ta sẽ thấy UI như bên dưới.
Tiếp theo ta triển khai ứng dụng v2, tạo tệp tin tên là app-v2.yaml
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app-v2
labels:
app: my-app
spec:
selector:
matchLabels:
app: my-app
version: v2.0.0
template:
metadata:
labels:
app: my-app
version: v2.0.0
spec:
containers:
- name: my-app
image: argoproj/rollouts-demo:blue
ports:
- name: http
containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: my-app-v2
spec:
selector:
app: my-app
version: v2.0.0
ports:
- port: 8080
targetPort: http
name: http
Tạo ứng dụng v2:
kubectl apply -f app-v1.yaml
Bây giờ ta nhận được yêu cầu là điều hướng 80% người dùng vào trang web v1 và 20% người dùng vào trang web v2.
Cấu hình HAProxy
Trong bài bài ta dùng HAProxy để thực hiện, tệp tin cấu hình của HAProxy:
defaults
mode http
timeout client 10s
timeout connect 5s
timeout server 10s
timeout http-request 10s
frontend listen
bind *:8080
use_backend v1 if { req.cook(SITEID) -m beg my-app-v1 }
use_backend v2 if { req.cook(SITEID) -m beg my-app-v2 }
default_backend ab-backend
backend v1
server backend-01 my-app-v1:8080
backend v2
server backend-02 my-app-v2:8080
backend ab-backend
balance roundrobin
cookie SITEID insert indirect nocache maxlife 24h
server backend-01 my-app-v1:8080 weight 80 cookie my-app-v1
server backend-02 my-app-v2:8080 weight 20 cookie my-app-v2
Logic như sau, ta khai báo 3 backend là v1, v2 và ab-backend:
backend v1
server backend-01 my-app-v1:8080
backend v2
server backend-02 my-app-v2:8080
backend ab-backend
...
Ở mục đầu vào, ta kiểm tra nếu request của người dùng có Cookie là SITEID với giá trị my-app-v1
thì ta điều hướng tới v1, nếu có giá trị là my-app-v2
thì ta điều hướng tới v2, còn không thì mặc định nhảy vào ab-backend:
use_backend v1 if { req.cook(SITEID) -m beg my-app-v1 }
use_backend v2 if { req.cook(SITEID) -m beg my-app-v2 }
default_backend ab-backend
Khi người dùng lần đầu tiên truy cập chắc chắn sẽ đi vào ab-backend, trong đó ta thực hiện cấu hình 80% request đi vào my-app-v1 và 20% request đi vào my-app-v2, sau đó ta đánh cookie cho người dùng để lần sau người dùng truy cập sẽ đi vào đúng v1 hoặc v2 dựa theo cookie.
cookie SITEID insert indirect nocache maxlife 24h
server backend-01 my-app-v1:8080 weight 80 cookie my-app-v1
server backend-02 my-app-v2:8080 weight 20 cookie my-app-v2
Triển khai HAProxy
Tạo tệp tin ConfigMap để chứa cấu hình của HAProxy, tệp tin cm.yaml
:
kind: ConfigMap
apiVersion: v1
metadata:
name: haproxy-config
data:
haproxy.cfg: |
defaults
mode http
timeout client 10s
timeout connect 5s
timeout server 10s
timeout http-request 10s
frontend listen
bind *:8080
use_backend v1 if { req.cook(SITEID) -m beg my-app-v1 }
use_backend v2 if { req.cook(SITEID) -m beg my-app-v2 }
default_backend ab-backend
backend v1
server backend-01 my-app-v1:8080
backend v2
server backend-02 my-app-v2:8080
backend ab-backend
balance roundrobin
cookie SITEID insert indirect nocache maxlife 24h
server backend-01 my-app-v1:8080 weight 80 cookie my-app-v1
server backend-02 my-app-v2:8080 weight 20 cookie my-app-v2
Tạo tệp tin Deployment cho HAProxy, tệp tin deployment.yaml
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: haproxy
spec:
selector:
matchLabels:
app: haproxy
template:
metadata:
labels:
app: haproxy
spec:
containers:
- name: haproxy
image: haproxy:2.9-alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
volumeMounts:
- name: haproxy-config
mountPath: /usr/local/etc/haproxy
volumes:
- name: haproxy-config
configMap:
name: haproxy-config
---
apiVersion: v1
kind: Service
metadata:
name: haproxy
spec:
type: ClusterIP
selector:
app: haproxy
ports:
- name: haproxy
port: 80
targetPort: 8080
Triển khai:
kubectl apply -f cm.yaml -f deployment.yaml
Truy cập HAProxy:
kubectl port-forward svc/haproxy 3000:80
Mở trình duyệt với địa chỉ localhost:3000
và kiểm tra. Bấm qua phần Cookies ta thấy giá trị cookie của v1.
Mở vài trình duyệt ẩn danh và truy cập vài lần sẽ thấy được v2.
Để kiểm tra dễ hơn ta có thể chuyển tỉ lệ sang 50/50. Nếu cần Public ra ngoài bạn có thể dùng Ingress và trỏ tới HAProxy Service.
Kết luận
HAProxy là cách phổ biến để ta triển khai A/B Testing. Ngoài ra bạn có thể dùng Nginx, Istio để thay thế.
Nếu bài viết có gì sai hoặc cần cập nhật thì liên hệ Admin.
Tham gia nhóm chat của DevOps VN tại Telegram.
Kém tiếng Anh và cần nâng cao trình độ giao tiếp: Tại sao bạn học không hiệu quả?