Chuyển tới nội dung chính

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áchMô tảNhược điểm
Tự dựng LBThêm 1 VM chạy HAProxy/nginx, trỏ tới các IP-node:nodePortTự cấu hình, tự bảo trì, thêm node phải sửa tay
Cloud native LBtype: LoadBalancer – Kubernetes nhờ cloud tạo LB tự độngChỉ 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 31234 là nodePort tự cấp → curl 192.168.81.102:31234 vẫ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ể đặt allocateLoadBalancerNodePorts: 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ạiTruy cập từDùng khi
ClusterIPTrong clusterDịch vụ nội bộ (mặc định)
NodePort<IP-node>:30000-32767Lab, on-prem, đích cho LB tự dựng
LoadBalancerIP/DNS công khaiProduction trên cloud
ExternalNameTrong cluster (CNAME)Trỏ tới dịch vụ ngoài
Headless (clusterIP: None)DNS trả IP từng PodStatefulSet