1. Giới Thiệu về Services
Service trong Kubernetes là một đối tượng trừu tượng hóa giúp định tuyến lưu lượng mạng đến các Pods, đảm bảo rằng các Pods có thể giao tiếp với nhau một cách ổn định và đáng tin cậy. Services cung cấp các cách khác nhau để expose ứng dụng trong và ngoài cluster, đồng thời quản lý việc load balancing và discovery.
Trong bài viết này, chúng ta sẽ khám phá cách kết nối ứng dụng với Services, cách sử dụng Source IP để duy trì thông tin khách hàng, và hiểu rõ về Termination Behavior của Pods và Endpoints.
2. Kết Nối Ứng Dụng với Services
2.1. Hiểu Về Các Loại Service
Kubernetes hỗ trợ bốn loại Service chính, mỗi loại phù hợp với các nhu cầu khác nhau:
- ClusterIP: Service chỉ có thể truy cập từ bên trong cluster. Đây là loại Service mặc định.
- NodePort: Expose Service qua một cổng trên mỗi Node, cho phép truy cập từ bên ngoài cluster thông qua địa chỉ IP của Node.
- LoadBalancer: Tích hợp với các nhà cung cấp đám mây để tạo một load balancer bên ngoài, phân phối lưu lượng đến các Pods.
- ExternalName: Map Service đến một tên DNS bên ngoài cluster.
2.2. Tạo và Cấu Hình Service
Dưới đây là cách tạo một Service đơn giản cho một ứng dụng đang chạy trong Kubernetes:
Ví dụ: Tạo Service loại ClusterIP cho Deployment NGINX
- Tạo Deployment NGINX
# nginx-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.19 ports: - containerPort: 80
Áp dụng Deployment:
kubectl apply -f nginx-deployment.yaml
- Tạo Service ClusterIP
# nginx-service.yaml apiVersion: v1 kind: Service metadata: name: nginx-service spec: selector: app: nginx ports: - protocol: TCP port: 80 targetPort: 80 type: ClusterIP
Áp dụng Service:
kubectl apply -f nginx-service.yaml
Kiểm Tra Service:
kubectl get services
Kết Quả:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 10m nginx-service ClusterIP 10.96.224.101 <none> 80/TCP 5m
2.3. Sử Dụng Labels và Selectors
Labels và Selectors là cách Kubernetes xác định và liên kết các Services với các Pods.
- Labels: Các cặp key-value được gán cho Pods để phân loại và tổ chức tài nguyên.
- Selectors: Các điều kiện được sử dụng bởi Service để chọn các Pods phù hợp dựa trên labels.
Ví Dụ:
Trong file nginx-deployment.yaml
, chúng ta đã gán label app: nginx
cho các Pods. Service nginx-service
sử dụng selector app: nginx
để chọn các Pods này.
3. Sử Dụng Source IP trong Services
3.1. Preserve Source IP
Trong một số trường hợp, việc duy trì Source IP của client là quan trọng để thực hiện các chính sách bảo mật, logging, hoặc các chức năng khác dựa trên địa chỉ IP gốc.
- ClusterIP và NodePort: Mặc định, Kubernetes sử dụng iptables hoặc ipvs để load balance, thường thay đổi Source IP thành IP của Node hoặc Cluster.
- LoadBalancer với
externalTrafficPolicy: Local
: Giữ Source IP gốc của client bằng cách tránh NAT.
Ví Dụ: Tạo Service LoadBalancer với Preserve Source IP
# nginx-loadbalancer-service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-loadbalancer
spec:
type: LoadBalancer
externalTrafficPolicy: Local
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
Áp dụng Service:
kubectl apply -f nginx-loadbalancer-service.yaml
Giải Thích:
externalTrafficPolicy: Local
: Bảo toàn Source IP bằng cách không thực hiện NAT. Lưu ý rằng nếu một Node không có Pods phù hợp, nó sẽ không nhận được lưu lượng đó.
3.2. Cấu Hình externalTrafficPolicy
- Cluster (mặc định): Kubernetes thực hiện NAT, Source IP gốc không được giữ lại.
- Local: Kubernetes không thực hiện NAT nếu Node có Pods phù hợp, giữ Source IP gốc.
Ví Dụ: Cập Nhật Service NodePort với externalTrafficPolicy: Local
# nginx-nodeport-service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-nodeport
spec:
type: NodePort
externalTrafficPolicy: Local
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30080
Áp dụng Service:
kubectl apply -f nginx-nodeport-service.yaml
Lưu Ý:
- Khi sử dụng
externalTrafficPolicy: Local
, đảm bảo rằng mỗi Node có ít nhất một Pod phù hợp để tránh mất mát lưu lượng. - Source IP gốc được giữ lại, giúp ích cho các ứng dụng cần thông tin IP của client.
4. Hiểu Về Termination Behavior cho Pods và Endpoints
4.1. Graceful Termination của Pods
Kubernetes đảm bảo rằng Pods được dừng một cách nhẹ nhàng để tránh mất dữ liệu hoặc gián đoạn dịch vụ. Khi một Pod bị xóa, Kubernetes thực hiện các bước sau:
- Gửi tín hiệu SIGTERM đến tất cả các container trong Pod.
- Thực hiện preStop hooks nếu có.
- Chờ trong khoảng thời gian được định nghĩa bởi
terminationGracePeriodSeconds
(mặc định là 30 giây). - Gửi tín hiệu SIGKILL để buộc dừng Pod nếu chưa dừng trong thời gian chờ.
Ví Dụ: Đặt terminationGracePeriodSeconds
cho Deployment
# nginx-deployment.yaml (cập nhật thêm terminationGracePeriodSeconds)
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
terminationGracePeriodSeconds: 60
containers:
- name: nginx
image: nginx:1.19
ports:
- containerPort: 80
Áp dụng cập nhật:
kubectl apply -f nginx-deployment.yaml
4.2. Cập Nhật Endpoints
Khi một Pod bị xóa hoặc thêm vào, các Endpoints của Service cũng được cập nhật tương ứng. Điều này đảm bảo rằng Service luôn biết chính xác các Pods đang hoạt động để định tuyến lưu lượng.
Kiểm Tra Endpoints của Service:
kubectl get endpoints nginx-service
Kết Quả Ví Dụ:
NAME ENDPOINTS AGE
nginx-service 10.244.1.5:80,10.244.1.6:80,10.244.1.7:80 10m
4.3. Sử Dụng Finalizers và PreStop Hooks
- Finalizers: Giúp đảm bảo rằng các hành động tùy chỉnh được thực hiện trước khi Pod bị xóa hoàn toàn.
- PreStop Hooks: Cho phép chạy các lệnh trước khi container bị dừng, hữu ích cho việc đóng kết nối hoặc ghi log.
Ví Dụ: Sử Dụng PreStop Hook trong Deployment
# nginx-deployment.yaml (cập nhật thêm preStop hook)
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
terminationGracePeriodSeconds: 60
containers:
- name: nginx
image: nginx:1.19
ports:
- containerPort: 80
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "echo PreStop Hook executed"]
Áp dụng cập nhật:
kubectl apply -f nginx-deployment.yaml
5. Best Practices cho Services
5.1. Thiết Kế Network Chính Xác
- Định Nghĩa Labels Chính Xác: Đảm bảo rằng labels và selectors được định nghĩa rõ ràng để Service có thể chọn đúng Pods.
- Sử Dụng Headless Services cho Stateful Applications: Giúp Pods có thể giao tiếp trực tiếp với nhau thông qua DNS.
5.2. Bảo Mật Services
- Sử Dụng Network Policies: Kiểm soát lưu lượng đến và đi từ các Services và Pods.
- Giới Hạn Quyền Truy Cập: Sử dụng các công cụ bảo mật như RBAC để hạn chế quyền truy cập vào Services.
5.3. Giám Sát và Logging
- Theo Dõi Lưu Lượng Mạng: Sử dụng Prometheus và Grafana để giám sát lưu lượng mạng qua các Services.
- Quản Lý Logs: Thu thập và phân tích logs từ các Services để phát hiện và xử lý sự cố kịp thời.
6. Giám Sát và Quản Lý Services
6.1. Sử Dụng Prometheus và Grafana
- Prometheus: Thu thập metrics về hiệu suất và trạng thái của các Services và Pods.
- Grafana: Trực quan hóa dữ liệu từ Prometheus thông qua các dashboard tùy chỉnh.
Ví Dụ: Cài Đặt Prometheus và Grafana với Helm
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install prometheus prometheus-community/prometheus -n monitoring --create-namespace
helm install grafana grafana/grafana -n monitoring
6.2. Sử Dụng ELK Stack
- Elasticsearch: Lưu trữ và tìm kiếm logs.
- Logstash: Thu thập và xử lý logs từ các nguồn khác nhau.
- Kibana: Trực quan hóa logs thông qua giao diện web.
Ví Dụ: Triển Khai ELK Stack với Helm
helm repo add elastic https://helm.elastic.co
helm repo update
helm install elasticsearch elastic/elasticsearch -n logging --create-namespace
helm install kibana elastic/kibana -n logging
helm install logstash elastic/logstash -n logging
7. Kết Luận
Services trong Kubernetes đóng vai trò quan trọng trong việc kết nối và quản lý giao tiếp giữa các ứng dụng. Bằng cách hiểu rõ các loại Service, cách sử dụng Source IP, và termination behavior của Pods và Endpoints, bạn có thể thiết kế và triển khai các ứng dụng mạnh mẽ, an toàn và hiệu quả trên Kubernetes.
Những Điểm Chính:
- Types of Services: Hiểu và lựa chọn loại Service phù hợp với nhu cầu.
- Source IP Preservation: Duy trì thông tin khách hàng thông qua cấu hình
externalTrafficPolicy
. - Termination Behavior: Đảm bảo Pods được dừng một cách nhẹ nhàng và Endpoints được cập nhật chính xác.
- Best Practices: Thiết kế mạng chính xác, bảo mật Services, và giám sát hiệu quả.
8. Tiếp Theo
- Deploy an App trên Kubernetes với Minikube: Hướng dẫn chi tiết cách triển khai và quản lý ứng dụng sử dụng Minikube.
- Expose Your App Publicly trên Kubernetes: Hướng dẫn cách sử dụng Service để expose ứng dụng ra ngoài cluster.
- Scale Your App trên Kubernetes: Hướng dẫn chi tiết cách scale ứng dụng sử dụng kubectl và Horizontal Pod Autoscaler.
- Update Your App trên Kubernetes: Hướng dẫn cách thực hiện Rolling Update cho ứng dụng sử dụng kubectl.
- Security trên Kubernetes: Hướng dẫn cách áp dụng các tiêu chuẩn bảo mật và giới hạn quyền truy cập trong cluster.
- Sử Dụng Helm để Quản Lý Các Ứng Dụng Kubernetes: Tìm hiểu cách sử dụng Helm charts để dễ dàng triển khai và quản lý các ứng dụng phức tạp.
9. Tài Nguyên Tham Khảo
- Kubernetes Documentation – Services
- Kubernetes Documentation – Pod Security Standards
- Kubernetes Documentation – Network Policies
- Prometheus Documentation
- Grafana Documentation
- Helm Documentation
- ELK Stack Documentation
- The Kubernetes Book
- Kubernetes Up & Running
- AppArmor Documentation
- seccomp Documentation