Triển khai Load Balancing trên Kubernetes sử dụng HA Proxy và Nginx Ingress
Apr 28, 2025
date
Apr 29, 2025
slug
trien-khai-load-balancing-tren-kubernetes-su-dung-ha-proxy-va-nginx-ingress
status
Published
tags
kubernetes
summary
Sử dụng HAProxy để phân phối lưu lượng vào cluster và Nginx Ingress để định tuyến tới các dịch vụ nội bộ.
type
Post
Giới thiệu
Khi triển khai K8S on premise, để các ứng dụng có thể truy cập từ bên ngoài, một cách phổ biến là expose service bằng NodePort type, cho phép bạn truy cập qua địa chỉ IP của node và một port trong khoảng từ 30000 đến 32767. Tuy nhiên, NodePort có một số hạn chế như số lượng port bị giới hạn, gây khó khăn khi có nhiều service; đồng thời, đường dẫn truy cập (ví dụ: http://node_ip:port) trông không chuyên nghiệp so với tên miền chuẩn như git.example.com.
Ngoài ra, khi sử dụng NodePort type thì entry point sẽ là địa chỉ IP của node. Trong trường hợp có nhiều node, để đảm bảo các request được chia đều tới các node, bạn cần cấu hình load balancing để thực hiện nhiệm vụ đó. Thông thường ta sẽ sử dụng HA Proxy hoặc Nginx để cấu hình, Trong bài hướng dẫn này, chúng ta sẽ sử dụng HAProxy trên một server riêng biệt để làm load balancer, kết hợp với Nginx Ingress Controller để quản lý định tuyến request trong cluster và Cert-Manager để tự động hóa cấu hình SSL. Hướng dẫn cấu hình High Availability (HA) cho HAProxy sẽ được trình bày trong một bài viết riêng.
Yêu cầu
- Đã cài đặt K8S Cluster.
- Một server riêng để cài đặt HA Proxy (trong bài thực hành sử dụng Ubuntu 22.04, 1GB ram, 1 cpu, 10GB SSD)
- Có hiểu biết về Load Balance HA Proxy, Ingress, Nginx và một số workload trong K8S.
Trong phần hướng dẫn này, mình đã cài đặt K8S Cluster với 2 worker với IP lần lượt là 100.64.0.1, 100.64.0.2 và load balancer server với IP 100.64.0.4.
Mô hình

Trong đó:
Client: người dùng gửi request https đến hệ thống
Load Balancer (HAProxy):
- Nhận traffic từ client qua HTTPS.
- Không giải mã SSL → chỉ chuyển tiếp request đến Ingress Controller, sử dụng mode tcp trong HAProxy → TCP passthrough.
- Client → HA Proxy: HTTPS, HA Proxy → Ingress Controller: HTTPS (giữ nguyên vẹn gói tin).
Ingress Controller Service:
- Là một pod trong cluster.
- Xử lý SSL Termination: nhận HTTPS từ LB → giải mã ra HTTP.
- Đọc domain/path trong request → áp dụng Ingress Rules để route.
Ingress Rule:
Thực hiện routing theo quy định:
- Theo domain (ví dụ: hello.manhtx.click)
- Theo path (ví dụ: /login, /shop)
Cert Manager:
- Tự động tạo SSL cert (qua Let's Encrypt, Self Sign, …).
- Gắn cert vào đúng Ingress (bằng cách quản lý Secret).
- Gia hạn chứng chỉ tự động.
Service:
- Là Kubernetes Service route request đến đúng Pod backend (Deployment).
- Mỗi Service có thể đại diện cho một microservice khác nhau.
Deployment:
- Các Pod chạy ứng dụng backend thật sự.
- Mỗi Deployment có nhiều Pod, quản lý tự động bởi Kubernetes.
Luồng xử lý yêu cầu
- Client gửi request:
hello.manhtx.click
- HAProxy Load Balancer:
- Nhận gói HTTPS.
- Dùng mode tcp, truyền thẳng đến Ingress Controller (không giải mã).
- Ingress Controller Service:
- Terminate SSL (giải mã HTTPS → HTTP).
- Đọc domain hello.manhtx.click, path /cart.
- So khớp với Ingress Rule.
- Ingress Rule chọn đúng Service (ví dụ: service-cart).
- Service route đến đúng Pod trong Deployment để xử lý.
Hướng dẫn cấu hình
Cài đặt Nginx Ingress
Trong hướng dẫn này mình sẽ sử dụng helm để cài nginx ingress lên k8s cluster, ngoài ra bạn có thể cài trực tiếp bằng file manifest (phần cài helm các bạn có thể xem các bài hướng dẫn khác nhé):
- Tạo namespace để dễ dàng hơn trong việc quản lý các resource
- Thêm repo của ingress-nginx
- Tải về chart và file cấu hình
values.yaml
.
Sau đó bạn sẽ thấy thư mục có sẵn file
values.yaml
. Bạn nên copy ra 1 file mới và update value trong file đó.- Chỉnh sửa file
values.new.yaml
copy từ values.yaml
- Tìm đến controller block, do cluster đang cài on premise, cập nhật lại service type từ LoadBalancer (chỉ support cho cloud provider) sang NodePort để có thể truy cập vào nginx ingress qua IP của node.

- Chỉ định port cho cần expose với http chạy port 31080 và https chạy port 31443

- Chạy lệnh sau để cài ingress nginx lên cluster với file values mới
- Sau khi chạy xong, kiểm tra các resource được tạo ra

Ta thấy đã có service type là NodePort đang expose 2 port 31080 với 31443 ra ngoài.
Cài đặt Cert Manager
Ta cũng dùng helm để cài đặt
- Thêm Helm repo của Jetstack
- Cài đặt cert manager
- Kiểm tra các resouce được khởi tạo

Cài đặt HA Proxy
- Cập nhật hệ thống
- Cài đặt HA Proxy
- Kiểm tra phiên bản
Hiện tại mình đang sử dụng phiên bản 2.4.24-0ubuntu0.22.04.2

- Cấu hình HA Proxy
- Sử dụng cấu hình sau
Hãy thay thế IP và port đúng với cấu hình của bạn, nếu server của bạn có cấu hình firewall thì hãy mở các port này ra tránh trường hợp không kết nối đươc nhé.
- Kiểm tra cấu hình
- Khởi động lại dịch vụ HAProxy
- Kiểm tra trạng thái
- Kiểm tra xem HA Proxy đã chuyển tiếp request với nginx ingress chưa, nếu trỏ về trang 404 Not Found của Nginx thì chính xác
- Cũng có thể kiểm tra trên trình duyệt

Như thế ta đã cấu hình xong HA Proxy để chuyển tiếp request về các worker node.
Triển khai ứng dụng
Sau khi đã cấu hình xong, ta sẽ triển khai demo 1 ứng dụng nhỏ để xem cài đặt của chúng ta hoạt động đúng không.
- Đầu tiên, tạo 1 ClusterIssuer sử dụng self-signed certificate (do đang dựng lab ở local) với file selfsigned-issuer.yaml có nội dung sau:
- Apply file
- Kiểm tra ClusterIssuer được tạo chưa
Nếu cột
READY
là True
thì issuer đã sẵn sàng dùng.- Tạo file demo_app.yaml với nội dung sau
- Apply file
- Cấu hình domain để trỏ về load balancer IP hoặc bạn có thể config local dns trong /etc/hosts.

Sau khi cấu hình xong, ta có thể truy cập bằng domain đã config trước đó.

Hai pod nếu được deploy ở các worker node khác nhau, HA Proxy sẽ tự động điều hướng các request lần lượt vào các pod theo đúng thuật toán roundrobin đươc cấu hình trong HA Proxy.