Course Content
1. DevOps overview
DevOps là gì
0/1
4. Kubernetes từ cơ bản đến nâng cao
0/20
8. Monitoring, Logging và Tracing
Khóa Học: DevOps Zero to Hero. (Đăng nhập để xem các video 1 cách miễn phí)

1. Network có sẵn mà chúng ta có thể sử dụng

Mọi ứng dụng microservices đều cần giao tiếp với nhau. Trong video này, mình sẽ chỉ cho các bạn cách kết nối hai deployment trên Kubernetes, và điều này sẽ giúp các dịch vụ của bạn có thể trò chuyện và làm việc cùng nhau như một nhóm

 

2. Tạo 2 Deployment đơn giản (ví dụ nginx và curl client)

Tạo namespace:

kubectl create ns nginx

Ví dụ file nginx-deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80

Ví dụ file curl-client-deployment.yaml:

tạo namespace:

kubectl create ns curl
apiVersion: apps/v1
kind: Deployment
metadata:
  name: curl-client
  namespace: curl
spec:
  replicas: 1
  selector:
    matchLabels:
      app: curl-client
  template:
    metadata:
      labels:
        app: curl-client
    spec:
      containers:
      - name: curl
        image: appropriate/curl
        command: ["sleep", "3600"]

3. Tạo Service cho Deployment nginx để curl-client có thể gọi tới

Ví dụ file nginx-service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
  namespace: nginx
spec:
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

4. Triển khai các resource lên cluster

kubectl apply -f nginx-deployment.yaml
kubectl apply -f curl-client-deployment.yaml
kubectl apply -f nginx-service.yaml

5. Kiểm tra kết nối giữa 2 Deployment

  • Lấy tên Pod của curl-client:

kubectl get pods -l app=curl-client -n curl
  • Vào Pod curl-client để thử gọi nginx-service:

kubectl exec -it <curl-client-pod-name> -- sh
curl http://nginx-service.nginx

Ở đây, nginx-service là tên Service và nginx là namespace, Kubernetes sẽ tự động resolve DNS nội bộ và chuyển tiếp request tới các Pod của nginx.

KubeDNS trong Kubernetes

KubeDNS là công cụ giúp các pod và service trong Kubernetes “nói chuyện” với nhau qua tên thay vì IP. Điều này cực kỳ quan trọng vì các pod trong Kubernetes thường có IP động, mà không phải lúc nào bạn cũng muốn nhớ hết chúng.

  • Khi bạn tạo một service trong Kubernetes, nó sẽ tự động có một tên DNS, ví dụ: nginx-service.default.svc.cluster.local.

  • Các pod trong cluster có thể dùng tên này để giao tiếp mà không cần phải lo về IP.

Ví dụ:
Giả sử có một service tên nginx-service, để gọi tới, bạn chỉ cần dùng:

curl nginx-service.default.svc.cluster.local

Cân Bằng Tải trong Kubernetes (Load Balancing)

Kubernetes cung cấp nhiều cách để phân phối lưu lượng giữa các pod thông qua Service.

ClusterIPCân bằng tải nội bộ:

  • Đây là kiểu service mặc định, dùng để phân phối yêu cầu từ pod này sang pod khác trong cluster.

  • Kubernetes tự động chia đều lưu lượng giữa các pod thông qua Kube Proxy (chạy bằng iptables hoặc ipvs).

apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  selector:
    app: web-service
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

NodePortCân bằng tải cho truy cập ngoài cluster:

  • Nếu bạn muốn truy cập dịch vụ từ bên ngoài Kubernetes, dùng kiểu NodePort.

  • Kubernetes sẽ mở một port trên mỗi node, và khi truy cập vào port đó, yêu cầu sẽ được chuyển tới các pod trong service.

  • Kubernetes sẽ tự động chọn một cổng trong phạm vi 30000 – 32767 khi bạn tạo service với kiểu NodePort
apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  selector:
    app: web-service
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30080 (optional)
  type: NodePort

LoadBalancerCân bằng tải qua External Load Balancer (cho Cloud):

  • Khi bạn triển khai trên cloud, kiểu LoadBalancer sẽ tự động tạo một external load balancer.

  • Lưu lượng truy cập sẽ được chuyển qua load balancer và Kubernetes sẽ phân phối đến các pod.

apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  selector:
    app: web-service
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: LoadBalancer
 

(Tham khảo thêm)

Quy trình giao tiếp từ Pod đến Pod qua Service và vai trò của kube-proxy

Khi một Pod (ví dụ: Pod A) cần giao tiếp với một Pod khác (ví dụ: Pod B) thông qua một Service, luồng xử lý sẽ có sự tham gia của CoreDNS và kube-proxy như sau:

1. Phân giải tên miền (DNS Resolution)

Đầu tiên, Pod A sẽ sử dụng tên DNS của Service (ví dụ: my-service.default.svc.cluster.local) để bắt đầu kết nối. Yêu cầu này được gửi đến CoreDNS, là máy chủ DNS mặc định trong cụm Kubernetes. CoreDNS sẽ phân giải tên miền này thành địa chỉ IP ảo ổn định của Service, được gọi là ClusterIP.
https://kubernetes.io/docs/tutorials/services/connect-applications-service/

2. Vai trò của kube-proxy

Trên mỗi node trong cụm Kubernetes, có một agent tên là kube-proxy chạy dưới dạng DaemonSet. Nhiệm vụ chính của kube-proxy là theo dõi các thay đổi về đối tượng Service và EndpointSlices (danh sách các Pod đang hoạt động phía sau một Service) từ API Server.
https://kodekloud.com/blog/kube-proxy/
https://kubernetes.io/docs/reference/networking/virtual-ips/

3. Thiết lập quy tắc mạng (iptables/IPVS)

Khi một Service được tạo hoặc cập nhật, kube-proxy trên mỗi node sẽ nhận thông tin này. Dựa trên thông tin đó, kube-proxy sẽ thiết lập các quy tắc chuyển tiếp mạng trên chính node đó. Có một số chế độ hoạt động cho kube-proxy, nhưng phổ biến nhất là iptables và IPVS.

  • Chế độ iptables (mặc định): kube-proxy sẽ tạo ra các quy tắc iptables trong kernel của Linux. Các quy tắc này có nhiệm vụ theo dõi và xử lý các gói tin mạng.

4. Chặn và chuyển hướng lưu lượng (Traffic Interception & NAT)

Khi Pod A gửi một gói tin đến địa chỉ ClusterIP của Service, các quy tắc iptables do kube-proxy tạo ra trên node sẽ khớp với gói tin này và chặn nó lại.

Lúc này, quy tắc iptables sẽ thực hiện Destination Network Address Translation (DNAT). Nó sẽ thay đổi địa chỉ IP đích của gói tin từ ClusterIP (là một IP ảo) thành địa chỉ IP thực của một trong các Pod đích (Pod B) đang hoạt động phía sau Service đó. kube-proxy sẽ chọn một Pod đích một cách ngẫu nhiên (hoặc theo thuật toán cân bằng tải khác) từ danh sách các endpoint hợp lệ.

5. Chuyển tiếp đến Pod đích

Sau khi địa chỉ IP đích đã được thay đổi thành IP của Pod B, gói tin sẽ được hệ điều hành của node chuyển tiếp trực tiếp đến Pod B.

Như vậy, kube-proxy không thực sự “proxy” lưu lượng theo nghĩa truyền thống (tức là không đứng giữa luồng dữ liệu). Thay vào đó, nó hoạt động như một bộ điều khiển, thiết lập các quy tắc mạng ở tầng kernel để đảm bảo lưu lượng được định tuyến một cách chính xác và hiệu quả từ một IP ảo của Service đến IP thật của Pod.

 
 
 
 
 
0% Complete