🎯 MỤC TIÊU BÀI HỌC
Sau khi hoàn thành bài học này, bạn sẽ:
- ✅ Hiểu vấn đề LoadBalancer trong on-premises (không có cloud LB)
- ✅ Cài đặt MetalLB bằng Helm
- ✅ Cấu hình L2 mode với IPAddressPool
- ✅ Hiểu BGP mode cho datacenter lớn
- ✅ Expose services với type LoadBalancer
PHẦN 1: VẤN ĐỀ LOADBALANCER TRÊN ON-PREMISES
1.1. Cloud vs On-Premises
Cloud (AWS/GCP/Azure): ┌─────────┐ ┌──────────────────┐ ┌──────────────────┐ │ User │────►│ Cloud LB (ELB) │────►│ K8s Service │ │ │ │ (tự động tạo) │ │ type:LoadBalancer│ └─────────┘ └──────────────────┘ └──────────────────┘ ✅ Tự động provisioning ✅ External IP tự gánOn-Premises (KHÔNG có MetalLB): ┌─────────┐ ┌──────────────────┐ ┌──────────────────┐ │ User │────►│ ??? │────►│ K8s Service │ │ │ │ Không có LB! │ │ type:LoadBalancer│ └─────────┘ └──────────────────┘ │ ⚠️ PENDING... │ └──────────────────┘ ❌ External IP = <pending> ← Mãi mãi pending!
On-Premises (CÓ MetalLB): ┌─────────┐ ┌──────────────────┐ ┌──────────────────┐ │ User │────►│ MetalLB │────►│ K8s Service │ │ │ │ (announce IP) │ │ type:LoadBalancer│ └─────────┘ └──────────────────┘ │ ✅ 10.10.40.201 │ ✅ MetalLB gán IP └──────────────────┘
PHẦN 2: CÀI ĐẶT METALLB
2.1. Prerequisites
# MetalLB yêu cầu kube-proxy strictARP (đã cấu hình ở Bài 6): # Verify: kubectl get configmap kube-proxy -n kube-system -o yaml | grep strictARP # strictARP: true ← ✅ OKNếu đã xóa kube-proxy (dùng Cilium replacement):
→ Không cần verify, Cilium handle ARP
2.2. Install MetalLB bằng Helm
# Add MetalLB Helm repo: helm repo add metallb https://metallb.universe.tf helm repo updateInstall MetalLB:
helm install metallb metallb/metallb
--namespace metallb-system
--create-namespace
--set speaker.frr.enabled=trueVerify installation:
kubectl -n metallb-system get pods
NAME READY STATUS RESTARTS AGE
metallb-controller-xxxxx-xxxxx 1/1 Running 0 30s
metallb-speaker-xxxxx 4/4 Running 0 30s (DaemonSet)
metallb-speaker-xxxxx 4/4 Running 0 30s
metallb-speaker-xxxxx 4/4 Running 0 30s
...
PHẦN 3: CẤU HÌNH L2 MODE
3.1. IPAddressPool
# metallb-config.yaml: apiVersion: metallb.io/v1beta1 kind: IPAddressPool metadata: name: external-pool namespace: metallb-system spec: addresses: - 10.10.40.200-10.10.40.250 # 51 IPs cho services autoAssign: true # Tự động gán IP avoidBuggyIPs: true # Bỏ qua .0 và .255
apiVersion: metallb.io/v1beta1 kind: IPAddressPool metadata: name: internal-pool namespace: metallb-system spec: addresses: - 10.10.20.200-10.10.20.220 # Internal services autoAssign: false # Phải specify manually
apiVersion: metallb.io/v1beta1 kind: L2Advertisement metadata: name: l2-advertisement namespace: metallb-system spec: ipAddressPools: - external-pool - internal-pool nodeSelectors: - matchLabels: node-role.kubernetes.io/worker: "" # Chỉ announce từ worker nodes
kubectl apply -f metallb-config.yaml
# ipaddresspool.metallb.io/external-pool created
# ipaddresspool.metallb.io/internal-pool created
# l2advertisement.metallb.io/l2-advertisement created
3.2. L2 Mode hoạt động như thế nào?
L2 Mode (ARP/NDP): ┌─────────────┐ ┌─────────────────┐ │ Client │ ARP: Who has │ MetalLB │ │ (external) │ 10.10.40.201? │ Speaker │ │ │──────────────────►│ (trên worker1) │ │ │ │ "Tôi có!" │ │ │◄──────────────────│ ARP Reply │ │ │ └─────────────────┘ │ │ Traffic: │ │──────────────────► worker1 → kube-proxy/Cilium → Pod └─────────────┘
✅ Đơn giản, không cần router hỗ trợ ❌ Failover chậm hơn BGP (~10 giây) ❌ Một node handle tất cả traffic cho 1 IP (không true LB)
PHẦN 4: TEST LOADBALANCER SERVICE
4.1. Deploy test application
# Deploy nginx test: kubectl create deployment nginx-test --image=nginx:alpine --replicas=3Expose với type LoadBalancer:
kubectl expose deployment nginx-test
--port=80
--target-port=80
--type=LoadBalancerKiểm tra service:
kubectl get svc nginx-test
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-test LoadBalancer 10.96.xxx.xx 10.10.40.200 80:3xxxx/TCP 10s
↑ MetalLB assigned! ✅
4.2. Test access từ external
# Từ máy trong cùng network: curl http://10.10.40.200 # # #Welcome to nginx! # ... ← OK! ✅Kiểm tra MetalLB speaker IP assignment:
kubectl -n metallb-system get ipaddresspool
NAME AUTO ASSIGN AVOID BUGGY IPS ADDRESSES
external-pool true true 10.10.40.200-10.10.40.250
4.3. Specify IP cụ thể
# Service với IP cụ thể:
apiVersion: v1
kind: Service
metadata:
name: my-app
annotations:
metallb.universe.tf/address-pool: internal-pool # Chọn pool
spec:
type: LoadBalancer
loadBalancerIP: 10.10.20.210 # IP cụ thể
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
PHẦN 5: BGP MODE (DATACENTER LỚN)
5.1. Khi nào dùng BGP?
| Tiêu chí | L2 Mode | BGP Mode |
|---|---|---|
| Yêu cầu router | Không | Cần BGP-capable router |
| Failover | ~10 giây | ~3 giây |
| True load balancing | ❌ (1 node handle) | ✅ ECMP across nodes |
| Cross-subnet | ❌ Same L2 segment | ✅ Works across subnets |
| Complexity | Đơn giản | Cần router config |
| Best for | SMB, single rack | Large DC, multi-rack |
5.2. BGP Configuration Example
# metallb-bgp.yaml (chỉ dùng khi có BGP router): apiVersion: metallb.io/v1beta2 kind: BGPPeer metadata: name: tor-switch namespace: metallb-system spec: myASN: 64512 # K8s cluster ASN peerASN: 64501 # ToR switch ASN peerAddress: 10.10.20.1 # Router IP holdTime: 90s keepaliveTime: 30s nodeSelectors: - matchLabels: node-role.kubernetes.io/worker: ""
apiVersion: metallb.io/v1beta1 kind: BGPAdvertisement metadata: name: bgp-advertisement namespace: metallb-system spec: ipAddressPools: - external-pool localPref: 100 communities: - 64512:100
PHẦN 6: IP SHARING VÀ ADVANCED FEATURES
6.1. Shared IP (nhiều services dùng 1 IP)
# Nhiều services share cùng 1 external IP (khác port):
apiVersion: v1
kind: Service
metadata:
name: web-http
annotations:
metallb.universe.tf/allow-shared-ip: "shared-web"
spec:
type: LoadBalancer
loadBalancerIP: 10.10.40.210
selector:
app: web
ports:
- port: 80
---
apiVersion: v1
kind: Service
metadata:
name: web-https
annotations:
metallb.universe.tf/allow-shared-ip: "shared-web"
spec:
type: LoadBalancer
loadBalancerIP: 10.10.40.210 # Same IP!
selector:
app: web
ports:
- port: 443
6.2. Cleanup test
kubectl delete deployment nginx-test
kubectl delete svc nginx-test
💡 KEY TAKEAWAYS
- MetalLB giải quyết LoadBalancer cho on-premises — không cần cloud provider
- L2 Mode đơn giản, phù hợp single rack/small cluster
- BGP Mode cho datacenter lớn, multi-rack với ECMP true load balancing
- IPAddressPool quản lý dải IP, có thể tạo nhiều pools (external, internal)
- IP Sharing cho phép nhiều services dùng chung 1 external IP
- strictARP: true trong kube-proxy là requirement cho L2 mode
🎯 BÀI TẬP
Bài tập 1: Install MetalLB
- Cài MetalLB bằng Helm
- Tạo IPAddressPool với dải IP phù hợp lab
- Deploy service type LoadBalancer, verify external IP
Bài tập 2: Multiple pools
- Tạo 2 pools: external-pool và internal-pool
- Deploy 2 services, mỗi service dùng 1 pool khác nhau
- Test IP sharing với 2 services cùng IP khác port
📚 BÀI TIẾP THEO
Trong Bài 10: etcd — Vận hành, Backup và Disaster Recovery, chúng ta sẽ deep dive vào etcd operations, backup strategies, và restore procedure.