GitOps trên Kubernetes với Flux v2: Tự động hóa đồng bộ hạ tầng và ứng dụng từ Git

DevOps tutorial - IT technology blog
DevOps tutorial - IT technology blog

Nỗi ám ảnh khi triển khai thủ công: Vì sao chúng tôi cần GitOps

Sáu tháng trước, những đợt triển khai vào thứ Năm hàng tuần của chúng tôi thực sự là một mớ hỗn độn. Bốn cụm Kubernetes—gồm hai môi trường staging và hai môi trường production phân bổ trên us-east-1 và eu-central-1—hoàn toàn phụ thuộc vào các GitLab CI runner đẩy manifest thô qua kubectl apply. Mỗi khi một job deploy bị timeout giữa chừng hoặc có kỹ sư vá hotfix trực tiếp lên pod đang chạy lúc 2 giờ sáng, trạng thái của cluster sẽ âm thầm lệch khỏi Git (configuration drift). Không một ai có thể xác minh những gì thực sự đang chạy mà không trực tiếp kiểm tra cluster thực tế.

Vấn đề bảo mật cũng rối rắm không kém. Mười bốn lập trình viên nắm giữ context kubeconfig với quyền cluster-admin trên laptop cá nhân, còn các CI runner thì lưu trữ token quản trị có thời hạn dài. Mỗi khi có bản release lỗi, việc rollback thường ngốn tới 45 phút chỉ để mò mẫm các manifest thủ công. Chúng tôi cần dứt điểm hoàn toàn khỏi mô hình phân phối dạng push (push-based delivery), và quyết định chuyển sang GitOps: để các cluster tự động kéo (pull) và đối soát (reconcile) trạng thái của chính mình trực tiếp từ Git repository.

Khái niệm cốt lõi: Tìm hiểu kiến trúc của Flux v2

Flux v2 hoạt động như một tập hợp các Kubernetes controller chuyên dụng được xây dựng trên nền tảng Custom Resource Definitions (CRDs). Thay vì nhồi nhét tất cả vào một tiến trình daemon nặng nề, Flux phân chia các tác vụ đồng bộ cho những micro-controller chuyên biệt:

  • Source Controller: Kéo dữ liệu từ Git repository, Helm registry, OCI artifact hoặc S3 bucket. Controller này đóng gói nội dung thành các file tarball bất biến (immutable) và cung cấp chúng nội bộ bên trong cluster.
  • Kustomize Controller: Tiếp nhận các Kubernetes manifest thô hoặc Kustomize overlay đã được Source Controller giải nén, sau đó đối soát chúng với trạng thái thực tế của cluster.
  • Helm Controller: Quản lý các bản release, nâng cấp và chu kỳ kiểm thử của Helm chart theo mô hình khai báo (declarative) thông qua custom resource, loại bỏ hoàn toàn nhu cầu cài đặt Helm CLI trên các CI build node.
  • Notification Controller: Gửi thông báo rollout theo thời gian thực tới Slack hoặc PagerDuty, đồng thời lắng nghe webhook gửi đến để các commit có thể kích hoạt quá trình đối soát ngay lập tức thay vì phải chờ hết chu kỳ polling.

Nhờ các controller này chạy trực tiếp bên trong cluster, cơ chế đồng bộ sẽ chủ động kéo các thay đổi từ ngoài vào trong. CI pipeline bên ngoài của bạn chỉ cần quyền đẩy commit lên Git hoặc xuất bản image tag, hoàn toàn không bao giờ phải chạm trực tiếp tới Kubernetes API.

Thực hành: Triển khai Flux v2 từ con số 0

Cài đặt Flux trên một cluster mới tinh chỉ mất chưa đầy mười phút. Dưới đây là quy trình thực chiến mà chúng tôi đã áp dụng để bootstrap toàn bộ hạ tầng và triển khai workload tự động đầu tiên.

Bước 1: Cài đặt Flux CLI và kiểm tra điều kiện tiên quyết

Cài đặt CLI độc lập trên máy trạm của bạn. Bạn sẽ chủ yếu sử dụng công cụ này để bootstrap và debug nhanh khi cần.

# Trên Linux/macOS thông qua curl
curl -s https://fluxcd.io/install.sh | sudo bash

# Kiểm tra tính tương thích của Kubernetes cluster (yêu cầu v1.28 trở lên)
flux check --pre

Lệnh kiểm tra trước (pre-check) sẽ xác minh xem context kubeconfig hiện tại của bạn có quyền quản trị viên cluster hay không, đồng thời đảm bảo phiên bản Kubernetes API đáp ứng đủ các yêu cầu của CRD.

Bước 2: Bootstrap Flux vào Git Repository

Quá trình bootstrapping sẽ cài đặt các Flux controller vào namespace flux-system. Nó cũng thiết lập một Git repository chuyên dụng để lưu trữ các manifest cấu hình của Flux cùng với mã nguồn ứng dụng của bạn.

export GITHUB_TOKEN="ghp_PersonalAccessTokenCuaBanVaoDay"
export GITHUB_USER="username-github-cua-ban"

flux bootstrap github \
  --owner=$GITHUB_USER \
  --repository=fleet-infra \
  --branch=main \
  --path=./clusters/production \
  --personal

Flux sẽ ghi định nghĩa controller vào ./clusters/production/flux-system, đẩy chúng lên GitHub và tạo sẵn một deploy key. Chỉ trong khoảng 90 giây, tất cả các pod controller cốt lõi sẽ được khởi động và sẵn sàng hoạt động.

Bước 3: Định nghĩa GitSource và Kustomization cho Workload

Tiếp theo, hãy chỉ định cho Flux biết workload của bạn nằm ở đâu và triển khai như thế nào. Clone repository fleet-infra về máy local và tạo thư mục chứa manifest của ứng dụng:

git clone https://github.com/$GITHUB_USER/fleet-infra.git
cd fleet-infra
mkdir -p ./clusters/production/apps

Định nghĩa repository chứa ứng dụng của bạn trong file ./clusters/production/apps/webapp-source.yaml:

apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
  name: webapp-source
  namespace: flux-system
spec:
  interval: 1m
  url: https://github.com/username-github-cua-ban/sample-webapp
  ref:
    branch: main

Bây giờ hãy hướng dẫn Flux cách triển khai mã nguồn đó trong file ./clusters/production/apps/webapp-kustomization.yaml:

apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: webapp-deploy
  namespace: flux-system
spec:
  interval: 5m
  targetNamespace: default
  sourceRef:
    kind: GitRepository
    name: webapp-source
  path: "./k8s/overlays/production"
  prune: true
  wait: true
  timeout: 2m

Hãy đặc biệt lưu ý cấu hình prune: true. Thiết lập này đảm bảo khi bạn xóa một manifest trong Git, Flux sẽ gỡ bỏ tài nguyên tương ứng khỏi cluster, tránh tình trạng sót lại các service hoặc secret mồ côi (orphan resources).

Bước 4: Commit và kiểm tra quá trình đối soát (Reconciliation)

Đẩy các khai báo này lên repository:

git add clusters/production/apps/
git commit -m "feat: dang ky webapp kustomization"
git push origin main

Mặc định, Flux sẽ thăm dò (poll) repository mỗi phút một lần, nhận diện thay đổi và áp dụng các manifest. Bạn không cần phải chờ hết chu kỳ này mà có thể kiểm tra trạng thái đồng bộ ngay lập tức:

# Ép buộc đồng bộ ngay lập tức
flux reconcile source git flux-system

# Kiểm tra các Git source
flux get sources git

# Kiểm tra quá trình đối soát Kustomization và health check
flux get kustomizations

Bạn có thể tự mình kiểm tra cơ chế tự phục hồi (self-healing). Hãy chạy lệnh kubectl scale deployment webapp --replicas=0 để giả lập một sự cố ngoài ý muốn. Chỉ trong vài phút, Kustomize controller sẽ phát hiện điểm sai lệch và tự động khôi phục số lượng replica về đúng trạng thái mong muốn.

Nhìn lại sau sáu tháng vận hành trên môi trường Production

Việc chuyển đổi pipeline phân phối sang Flux v2 đã thay đổi hoàn toàn cách chúng tôi vận hành hàng ngày. Tần suất triển khai tăng vọt từ hai đợt cố định mỗi tuần lên mức trung bình 18 bản cập nhật mỗi ngày. Thời gian phục hồi trung bình (MTTR) giảm mạnh từ 45 phút xuống dưới 3 phút; việc khắc phục một bản release lỗi giờ đây chỉ đơn giản là thực hiện lệnh git revert.

Quan trọng hơn cả, chúng tôi đã thu hồi quyền truy cập cluster trực tiếp từ 14 máy trạm và loại bỏ toàn bộ token admin khỏi các CI worker. Git hiện là nguồn chân lý duy nhất (single source of truth), lịch sử commit chính là nhật ký kiểm toán (audit log), và các cluster của chúng tôi có thể tự chữa lành mỗi khi phát sinh sai lệch cấu hình.

Share: