Kiến trúc và Quản lý Pod trong Kubernetes

Định nghĩa Pod và Vai trò trong Kubernetes

Trong hệ sinh thái Kubernetes, Pod được xem là đơn vị tính toán nhỏ nhất có thể được triển khai và quản lý. Thay vì làm việc trực tiếp với các container riêng lẻ, Kubernetes điều phối các Pod. Mỗi Pod đóng gói một hoặc nhiều container (như Docker, containerd) chia sẻ cùng một môi trường thực thi, bao gồm không gian mạng (network namespace) và không gian lưu trữ (storage).

Về mặt khái niệm, Pod có thể được so sánh với một nhóm các quy trình tiến trình (process group) chạy trên cùng một máy chủ ảo logic. Các container bên trong một Pod luôn được lịch trình (schedule) tới cùng một Node (worker node) và bắt buộc phải khởi động cùng nhau. Một ví dụ điển hình là kiến trúc "Sidecar", nơi một container chính chạy ứng dụng web, trong khi một container phụ trợ (sidecar) chịu trách nhiệm thu thập logs hoặc đẩy dữ liệu.

Mô hình Mạng và Lưu trữ của Pod

Một trong những đặc điểm quan trọng nhất của Pod là việc chia sẻ không gian mạng. Khi một Pod được tạo ra, Kubernetes khởi động một container nền tảng gọi là pause. Container này giữ giữ các không gian tên mạng (Network Namespace). Tất cả các container ứng dụng trong Pod đó sẽ tham gia vào không gian mạng này, cho phép chúng giao tiếp với nhau thông qua localhost. Do đó, các container trong cùng một Pod không thể sử dụng cùng một cổng (port) để tránh xung đột.

Về lưu trữ, người dùng có thể định nghĩa các Volume ở cấp độ Pod. Các Volume này được chia sẻ và có thể truy cập bởi mọi container nằm trong Pod đó. Điều này cho phép dữ liệu tồn tại ngay cả khi container bị khởi động lại, miễn là Pod chưa bị xóa hoặc tái tạo sang Node khác.

Tại sao cần sự trừu tượng Pod?

Việc sử dụng Pod thay vì container trực tiếp mang lại nhiều lợi ích kiến trúc, đặc biệt là trong việc quản lý các ứng dụng được chia thành các thành phần nhỏ (microservices) cần tương tác chặt chẽ.

  • Truyền thông hiệu quả: Các container trong cùng Pod chia sẻ IP và không gian mạng, giúp chúng giao tiếp qua localhost mà không cần qua lớp mạng phức tạp, giảm thiểu độ trễ.
  • Quản lý tập trung: Pod đóng vai trò là đơn vị khai thác chung cho các container. Ví dụ, bạn có thể triển khai một ứng dụng web và một agent đồng bộ hóa file từ Git trong cùng một Pod. Cả hai sẽ chia sẻ cùng một thư mục lưu trữ (Volume) để cập nhật mã nguồn mà không cần sửa đổi logic của ứng dụng chính.
  • Tách biệt mối quan tâm: Xét một kịch bản thu thập log. Thay vì tích hợp logic gửi log trực tiếp vào ứng dụng kinh doanh, ta có thể chạy một container chuyên biệt (như Fluentd) trong cùng một Pod. Container này sẽ đọc file log từ ổ đĩa chia sẻ và gửi đi. Điều này giữ cho mã nguồn ứng dụng sạch sẽ và giảm sự liên kết.

Vòng đời và Cách thức Quản lý Pod

Pod có thể được tạo ra theo hai cách chính: Pod tự trị (Bare Pod)Pod được quản lý bởi Controller.

1. Pod tự trị (Bare Pods)

Đây là các Pod được tạo trực tiếp thông qua file YAML hoặc câu lệnh mà không có bộ điều khiển nào giám sát. Nhược điểm lớn của loại này là tính "yếu đuối". Nếu Pod tự trị bị xóa hoặc Node gặp sự cố, nó sẽ biến mất vĩnh viễn và không được tự động tạo lại.

Dưới đây là ví dụ về định nghĩa một Pod tự trị chạy máy chủ Nginx:

apiVersion: v1
kind: Pod
metadata:
  name: static-web-example
  namespace: default
  labels:
    app: web-server
    tier: frontend
spec:
  containers:
  - name: main-nginx
    image: nginx:1.21-alpine
    ports:
    - containerPort: 80
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"
  restartPolicy: Always

Sau khi áp dụng file này bằng kubectl apply -f static-web-example.yaml, Pod sẽ chạy. Tuy nhiên, nếu bạn chạy lệnh kubectl delete pod static-web-example, nó sẽ mất vĩnh viễn.

2. Pod được quản lý bởi Controller

Trong môi trường sản xuất (production), hầu hết các Pod đều được quản lý bởi các bộ điều khiển workload như Deployment, StatefulSet, DaemonSet, hoặc Job. Các Controller này đảm bảo số lượng Pod (replicas) luôn được duy trì ở mức mong muốn. Nếu một Pod bị lỗi, Controller sẽ tự động tạo một Pod mới để thay thế.

Ví dụ dưới đây sử dụng Deployment để quản lý 2 bản sao (replicas) của ứng dụng web:

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

Khi bạn xóa một Pod do Deployment này quản lý, Kubernetes sẽ ngay lập tức nhận thấy sự chênh lệch giữa trạng thái thực tế và trạng thái mong muốn (desired state) và tạo ra một Pod mới để duy trì số lượng là 2.

Quy trình tạo Pod trong Kubernetes

Việc tạo một Pod đi qua một quy trình điều phối chặt chẽ giữa các thành phần của Control Plane và Worker Node:

  1. Gửi yêu cầu: Người dùng thực hiện lệnh kubectl apply. Yêu cầu này được gửi tới API Server.
  2. Lưu trữ và Lập lịch: API Server lưu thông tin Pod vào etcd (kho dữ liệu phân tán). Sau đó, Scheduler giám sát các tài nguyên chưa được gán Node, sử dụng thuật toán để chọn Node phù hợp nhất (dựa trên CPU, RAM, ràng buộc phần cứng...) và cập nhật thông tin này lại vào API Server.
  3. Thực thi: Kubelet (tác nhân chạy trên Node) theo dõi API Server. Khi thấy một Pod được gán cho Node mình quản lý, Kubelet sẽ giao tiếp với Container Runtime (như Docker, Containerd) để kéo image và khởi động container.
  4. Cập nhật trạng thái: Sau khi container chạy, Kubelet báo cáo trạng thái lại cho API Server, hoàn tất quy trình tạo.

Cấu trúc Manifest của Pod

Để định nghĩa một Pod, chúng ta sử dụng file YAML với 4 trường bắt buộc: apiVersion, kind, metadata, và spec.

  • apiVersion: Chỉ định phiên bản API của Kubernetes (ví dụ: v1 cho Pod).
  • kind: Loại tài nguyên muốn tạo (ở đây là Pod).
  • metadata: Dữ liệu mô tả tài nguyên như tên (name), không gian tên (namespace), và các nhãn (labels) giúp nhận diện.
  • spec: Định nghĩa trạng thái mong muốn của Pod, bao gồm danh sách các container, ảnh (image) sử dụng, cổng mạng, và Volume.

Ví dụ một cấu trúc Pod nâng cao hơn với biến môi trường và Volume:

apiVersion: v1
kind: Pod
metadata:
  name: advanced-app-pod
  labels:
    env: production
    version: v1
spec:
  containers:
  - name: app-core
    image: busybox
    command: ["/bin/sh", "-c", "while true; do echo hello; sleep 10;done"]
    env:
    - name: LOG_LEVEL
      value: "info"
    volumeMounts:
    - name: data-storage
      mountPath: /data
  volumes:
  - name: data-storage
    emptyDir: {}

Để tìm hiểu chi tiết các trường cấu hình, bạn có thể sử dụng công cụ kubectl explain. Ví dụ: kubectl explain pod.spec.containers sẽ hiển thị chi tiết các cấu hình có thể thiết lập cho container.

Thẻ: Kubernetes Pod Container-Orchestration Kubectl docker

Đăng vào ngày 16 tháng 05 lúc 13:19