Bài 15: Cấu Hình Service (ClusterIP, NodePort)

Sau khi đã học cách tối ưu Pod với HPA (Horizontal Pod Autoscaler) ở Bài 14, chúng ta chính thức bước sang domain Services & Networking (20%) một trong những phần nặng nhất và hay ra đề nhất trong kỳ thi CKAD.

Bài viết này thuộc đúng domain đó, tập trung vào Service, thành phần cơ bản để kết nối các Pod ổn định và expose ứng dụng ra ngoài. Trong kỳ thi, bạn thường gặp những task như tạo Service kiểu ClusterIP để map cổng 8080 của container ra 80 trong cluster, chuyển một Service từ ClusterIP sang NodePort với cổng cố định 30080, hoặc tạo một Service không có selector rồi tự định nghĩa Endpoints. Những câu này tưởng đơn giản nhưng rất dễ mất điểm nếu bạn nhầm giữa port/targetPort/nodePort hoặc đặt selector lệch nhãn Pod.

Service Là Gì? Tại Sao Cần Nó?

Service là một abstraction layer giúp bạn kết nối đến các Pod một cách ổn định, dù Pod có chết đi sống lại, IP thay đổi liên tục.

Vấn đề Giải pháp bằng Service
Pod có IP động => Không thể hardcode Service có IP tĩnh (ClusterIP)
Nhiều Pod cùng Service => cần load balance Service tự động round-robin
Cần expose ra ngoài cluster Dùng NodePort hoặc LoadBalancer

CKAD Tip: Không bao giờ kết nối trực tiếp bằng Pod IP luôn dùng Service Name (DNS).

Các Loại Service Trong Kubernetes

Loại Mục đích Port mở Dùng khi
ClusterIP (default) Giao tiếp trong cluster Chỉ nội bộ API backend, DB, microservices
NodePort Expose ra ngoài qua node 30000–32767 Dev/test, truy cập tạm thời
LoadBalancer Expose qua cloud LB Tùy cloud Production (AWS ELB, GCP, etc.)
ExternalName Map đến DNS bên ngoài Không mở port Gọi API bên ngoài

Trong môi trường thi CKAD, bạn chỉ cần nhớ ClusterIPNodePort. LoadBalancer thường không khả dụng trong môi trường thi.

Dưới đây là minh họa về các loại Service trong Kubernetes để bạn dễ hình dung:

https://k21academy.com/wp-content/uploads/2020/11/KubernetesPods_Diagram-47.png

Cấu Trúc YAML Service Cơ Bản

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: my-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
  type: ClusterIP

Giải thích nhanh:

  • port: cổng mà Service expose trong cluster.
  • targetPort: cổng container trong Pod.
  • nodePort: chỉ dùng khi type: NodePort.

CKAD Golden Rule: port là của Service, targetPort là của Pod, nodePort là của Node.

Thực Hành 1: Tạo Deployment + Service ClusterIP

  1. Tạo Deployment

    apiVersion: apps/v1
    kind: Deployment
    metadata:
     name: nginx-app
    spec:
     replicas: 3
     selector:
       matchLabels:
         app: nginx
     template:
       metadata:
         labels:
           app: nginx
       spec:
         containers:
         - name: nginx
           image: nginx:alpine
           ports:
           - containerPort: 80
    kubectl apply -f nginx-deployment.yaml
  2. Expose Deployment bằng lệnh Imperative

    kubectl expose deployment nginx-app \
     --name=nginx-service \
     --port=80 \
     --target-port=80
  3. Tạo Service YAML (Cách thi yêu cầu)

    apiVersion: v1
    kind: Service
    metadata:
     name: nginx-service-yaml
    spec:
     selector:
       app: nginx
     ports:
       - protocol: TCP
         port: 8080
         targetPort: 80
     type: ClusterIP
  4. Test kết nối nội bộ

    kubectl run test-pod --image=busybox --rm -it --restart=Never -- sh
    wget -qO- http://nginx-service-yaml:8080

Mẹo: Kubernetes tự resolve DNS theo ServiceName.Namespace.svc.cluster.local.

Thực Hành 2: Chuyển Sang NodePort Expose Ra Ngoài

Service NodePort YAML:

apiVersion: v1
kind: Service
metadata:
  name: nginx-nodeport
spec:
  selector:
    app: nginx
  type: NodePort
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
      nodePort: 30080

Áp dụng:

kubectl apply -f nginx-nodeport.yaml

Truy cập từ máy host:

minikube service nginx-nodeport --url
curl http://$(minikube ip):30080

Trong CKAD: NodePort thường dùng để xác thực ứng dụng chạy đúng (ví dụ 30080, 30081).

So Sánh ClusterIP vs NodePort

Tiêu chí ClusterIP NodePort
type Mặc định NodePort
IP Nội bộ IP của Node
Port range Tùy ý 30000–32767
Sử dụng Microservices Test, demo
nodePort? Không
Lệnh nhanh kubectl expose kubectl expose --type=NodePort

Service Không Có Selector (Rất Hay Ra Đề)

Đề thi mẫu: “Tạo Service backend-external trỏ đến IP 203.0.113.10:8080 mà không dùng selector.”

Giải pháp:

apiVersion: v1
kind: Service
metadata:
  name: backend-external
spec:
  ports:
    - port: 80
      targetPort: 8080
---
apiVersion: v1
kind: Endpoints
metadata:
  name: backend-external
subsets:
  - addresses:
      - ip: 203.0.113.10
    ports:
      - port: 8080

Tip: Service không selector + Endpoints = kết nối tới service ngoài cluster.

Debug Service Không Kết Nối

Lỗi Nguyên nhân Cách fix
Connection refused Sai targetPort Kiểm tra containerPort
Service not found Sai tên kubectl get svc
No endpoints Sai selector kubectl get pod -l app=xxx
Pending Pod chưa ready kubectl get pod

Debug nhanh:

kubectl describe svc nginx-service
kubectl get endpoints nginx-service

Bài Tập CKAD

Đề: Trong namespace exam, tạo:

  • Deployment web (image: httpd, replicas: 2)
  • Service web-svc (ClusterIP, port 8080→80)
  • Service web-ext (NodePort, port 80→80, nodePort: 30081)

Đáp án:

web-deployment.yaml

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

web-services.yaml

apiVersion: v1
kind: Service
metadata:
  name: web-svc
  namespace: exam
spec:
  selector:
    app: web
  ports:
    - port: 8080
      targetPort: 80
  type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
  name: web-ext
  namespace: exam
spec:
  selector:
    app: web
  type: NodePort
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30081

Chạy:

kubectl create ns exam
kubectl apply -f web-deployment.yaml
kubectl apply -f web-services.yaml
kubectl -n exam get svc,pod,ep

Liên Hệ Với Chứng Chỉ CKAD

Domain Services & Networking (20%) luôn có 2–3 câu hỏi liên quan đến Service, chiếm số điểm khá lớn vì kiểm tra khả năng hiểu đúng cách expose và định tuyến nội bộ trong Kubernetes. Trong kỳ thi, bạn thường gặp yêu cầu tạo Service ClusterIP để route cổng 8080 của container sang 80 trong cluster, chuyển một Service sang NodePort với cổng cụ thể như 30080, hoặc tạo Service không có selector rồi định nghĩa thủ công Endpoints để trỏ đến IP cố định.

Các lỗi phổ biến khiến thí sinh mất điểm là nhầm lẫn giữa port, targetPort, nodePort; selector không khớp với nhãn Pod nên Service không có endpoints; hoặc quên thêm type: NodePort khi đề bài yêu cầu expose ra ngoài.

Mẹo thi:

  • Luôn ghi rõ type: NodePort khi đề yêu cầu expose ra ngoài, tránh bị mặc định là ClusterIP.
  • port là cổng của Service, targetPort là cổng container trong Pod, và nodePort chỉ có khi Service là NodePort.
  • Kiểm tra `kubectl get endpoints ` ngay sau khi apply để xác minh selector hoạt động đúng.
  • Trong bài thi, có thể dùng kubectl expose để tạo nhanh Service, nhưng khi nộp bài nên dùng YAML chuẩn để dễ chỉnh sửa.

Tóm Tắt Kiến Thức Cho CKAD

Khái niệm Giá trị cần nhớ
Default type ClusterIP
NodePort range 30000–32767
port Cổng Service
targetPort Cổng container
nodePort Chỉ khi type: NodePort
Lệnh nhanh kubectl expose deploy X --port=A --target-port=B --type=NodePort

Kết Luận

Bài này mình đã hướng dẫn chi tiết cách tạo và quản lý Service trong Kubernetes, từ ClusterIP, NodePort đến Service không có selector và cách debug khi Service không hoạt động. Bạn giờ đã có thể kết nối các Pod ổn định, expose ứng dụng ra ngoài, và kiểm tra routing một cách thành thạo trong môi trường thực tế. Tiếp theo, ở Bài 16: Sử Dụng Ingress Và Network Policy, chúng ta sẽ mở rộng sang phần routing nâng cao và bảo mật mạng nội bộ hai kỹ năng quan trọng để hoàn thiện domain Services & Networking (20%).

Điều hướng chuỗi bài viết<< Bài 14: Tối Ưu Hóa Pod Với HPA (Horizontal Pod Autoscaler)>> Bài 16: Sử Dụng Ingress Và Network Policy

Thông tin nổi bật

Báo cáo quan trọng

Sự kiện đang hiện hành

Chia sẻ bài viết:
Theo dõi
Thông báo của
0 Góp ý
Được bỏ phiếu nhiều nhất
Mới nhất Cũ nhất
Phản hồi nội tuyến
Xem tất cả bình luận