Services – LoadBalancer
1. Bài toán
Ứng dụng voting và result chạy trên cluster 4 node, dùng NodePort. Người dùng phải nhớ:
http://192.168.81.101:30035 http://192.168.81.102:30035
http://192.168.81.103:30035 http://192.168.81.104:30035
Họ chỉ muốn một URL như http://vote.example.com.
| Cách | Mô tả | Nhược điểm |
|---|---|---|
| Tự dựng LB | Thêm 1 VM chạy HAProxy/nginx, trỏ tới các IP-node:nodePort | Tự cấu hình, tự bảo trì, thêm node phải sửa tay |
| Cloud native LB | type: LoadBalancer – Kubernetes nhờ cloud tạo LB tự động | Chỉ chạy trên nền tảng hỗ trợ |
2. LoadBalancer = NodePort + LB
apiVersion: v1
kind: Service
metadata:
name: myapp-lb
spec:
type: LoadBalancer
selector:
app: myapp
ports:
- name: http
port: 80 # port trên load balancer
targetPort: 80
3. Môi trường không hỗ trợ (lab VMware/VirtualBox)
kubectl get svc myapp-lb
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
# myapp-lb LoadBalancer 10.96.40.12 <pending> 80:31234/TCP 2m
EXTERNAL-IP<pending>mãi vì không có cloud nào tạo LB.- Nhưng
31234là nodePort tự cấp →curl 192.168.81.102:31234vẫn chạy. Bằng chứng: LoadBalancer = NodePort + LB.
MetalLB cho lab
MetalLB đóng vai "cloud provider" trên mạng LAN, cấp IP từ một dải trống:
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: lab-pool
namespace: metallb-system
spec:
addresses:
- 192.168.81.200-192.168.81.210
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: lab-l2
namespace: metallb-system
Sau đó Service nhận EXTERNAL-IP như 192.168.81.200, và curl http://192.168.81.200 chạy được.
4. EKS
Trên EKS, AWS Load Balancer Controller đọc annotation để tạo NLB:
apiVersion: v1
kind: Service
metadata:
name: myapp-lb
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: external
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip # NLB gửi thẳng tới IP Pod (VPC CNI)
service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing # hoặc internal
spec:
type: LoadBalancer
selector:
app: myapp
ports:
- port: 80
targetPort: 80
loadBalancerSourceRanges: # chỉ cho các dải IP này truy cập (tùy chọn)
- 203.0.113.0/24
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
myapp-lb LoadBalancer 172.20.81.10 k8s-default-myapplb-ab12cd.elb.ap-southeast-1... 80:30512/TCP
- Với
nlb-target-type: ip, NLB bỏ qua nodePort, gửi thẳng tới IP Pod. Có thể đặtallocateLoadBalancerNodePorts: false. - Cluster cần IAM Role để controller được phép tạo LB.
💡 Production
Nhiều app web → dùng Ingress / Gateway API (1 LB cho nhiều app, định tuyến theo host/path) thay vì mỗi app một LB.
5. ExternalName
- Không chọn Pod, không có ClusterIP, không qua kube-proxy. Chỉ bảo CoreDNS trả về CNAME.
- Dùng khi app gọi dịch vụ bên ngoài (RDS, API đối tác) bằng một tên nội bộ ổn định.
apiVersion: v1
kind: Service
metadata:
name: my-db
spec:
type: ExternalName
externalName: mydb.abc123.ap-southeast-1.rds.amazonaws.com # phải là TÊN DNS, không phải IP
6. Tóm tắt các loại Service
| Loại | Truy cập từ | Dùng khi |
|---|---|---|
| ClusterIP | Trong cluster | Dịch vụ nội bộ (mặc định) |
| NodePort | <IP-node>:30000-32767 | Lab, on-prem, đích cho LB tự dựng |
| LoadBalancer | IP/DNS công khai | Production trên cloud |
| ExternalName | Trong cluster (CNAME) | Trỏ tới dịch vụ ngoài |
Headless (clusterIP: None) | DNS trả IP từng Pod | StatefulSet |