0

Lab 8 — Environment Management với ArgoCD

🎯 1. Mục tiêu

Sau lab này, bạn sẽ hiểu và thực hành được:

  • Vì sao cần tách dev, staging, production.
  • Cách tổ chức GitOps Repository cho nhiều environment.
  • Cách dùng Kustomize Overlay để thay đổi cấu hình theo environment.
  • Cách để ArgoCD quản lý nhiều environment.
  • Cách promote ứng dụng từ devstagingproduction một cách an toàn.

🤔 2. Vấn đề thực tế

Giả sử bạn có một Todo App:

Frontend
Backend
PostgreSQL

Ban đầu bạn chỉ có một môi trường:

Developer
    │
    ▼
Kubernetes
    │
    └── Todo App

Mọi thứ khá đơn giản.

Nhưng khi đưa vào công ty, bạn thường sẽ có:

Development
    ↓
Staging
    ↓
Production

Ví dụ:

Environment Mục đích
dev Developer test tính năng
staging Test gần giống production
production Người dùng thật

Vấn đề xuất hiện khi mỗi environment cần cấu hình khác nhau.

Ví dụ:

DEV
replicas: 1
CPU: 100m
Memory: 128Mi

STAGING
replicas: 2
CPU: 250m
Memory: 256Mi

PRODUCTION
replicas: 3
CPU: 500m
Memory: 512Mi

Nếu copy toàn bộ Kubernetes YAML:

dev/
    deployment.yaml
    service.yaml
    configmap.yaml

staging/
    deployment.yaml
    service.yaml
    configmap.yaml

production/
    deployment.yaml
    service.yaml
    configmap.yaml

thì rất dễ xảy ra:

Sửa bug
   │
   ├── dev      ✓
   ├── staging  ✓
   └── production ✗

Hoặc tệ hơn:

Dev và Production vô tình chạy hai phiên bản cấu hình khác nhau mà không ai biết.

💡 Giải pháp

Thay vì copy toàn bộ YAML, chúng ta dùng:

Base
 │
 ├── dev
 ├── staging
 └── production

Base chứa cấu hình chung.

Overlay chứa những điểm khác biệt của từng environment.


🧠 3. Hiểu nhanh

3.1. Environment là gì?

Environment đơn giản là một môi trường chạy ứng dụng với mục đích khác nhau.

Ví dụ:

                    Git
                     │
          ┌──────────┼──────────┐
          ▼          ▼          ▼
         DEV      STAGING      PROD
          │          │          │
          ▼          ▼          ▼
       Cluster     Cluster     Cluster

Trong lab này chúng ta sẽ dùng một Kubernetes cluster để mô phỏng nhiều environment bằng namespace:

todo-dev
todo-staging
todo-prod

Trong production thực tế, mỗi environment có thể nằm trên:

DEV        → Kubernetes Cluster A
STAGING    → Kubernetes Cluster B
PRODUCTION → Kubernetes Cluster C

3.2. Base và Overlay

Đây là concept quan trọng nhất của lab.

Base

Base chứa những thứ giống nhau.

Ví dụ:

Deployment
Service
ConfigMap

Overlay

Overlay chứa những thứ khác nhau.

Ví dụ:

dev
 └── replicas = 1

staging
 └── replicas = 2

production
 └── replicas = 3

Diagram:

                    Base
                     │
          ┌──────────┼──────────┐
          ▼          ▼          ▼
        Overlay    Overlay    Overlay
          │          │          │
         dev       staging      prod
          │          │          │
        1 pod       2 pods      3 pods

Điểm quan trọng:

Không copy application configuration cho từng environment.

Chúng ta tái sử dụng Base và chỉ override những gì cần thay đổi.


3.3. ArgoCD quản lý Environment như thế nào?

ArgoCD sẽ theo dõi Git Repository.

Ví dụ:

Git Repository
│
├── base/
│
└── overlays/
    ├── dev/
    ├── staging/
    └── production/

ArgoCD có thể tạo 3 Application:

ArgoCD
│
├── todo-dev
│      └── overlays/dev
│
├── todo-staging
│      └── overlays/staging
│
└── todo-production
       └── overlays/production

Như vậy:

Git
 │
 │ Source of Truth
 ▼
ArgoCD
 │
 ├── DEV
 ├── STAGING
 └── PRODUCTION

🏗️ 4. Architecture

Trong lab này chúng ta xây dựng:

                    Git Repository
                         │
                         │
                ┌────────┴────────┐
                │                 │
              base/            overlays/
                │                 │
                │        ┌────────┼─────────┐
                │        │        │         │
                ▼        ▼        ▼         ▼
          Common YAML   dev   staging   production
                           │       │         │
                           └───────┼─────────┘
                                   │
                                   ▼
                                ArgoCD
                                   │
                  ┌────────────────┼────────────────┐
                  ▼                ▼                ▼
              todo-dev       todo-staging       todo-prod
                  │                │                │
                  ▼                ▼                ▼
               Namespace        Namespace        Namespace

🛠️ 5. Chuẩn bị

5.1. Kiểm tra Kubernetes

kubectl get nodes

Kết quả mong đợi:

NAME       STATUS   ROLES           AGE
minikube   Ready    control-plane   ...

5.2. Kiểm tra ArgoCD

kubectl get pods -n argocd

Các Pod chính cần ở trạng thái Running:

argocd-server
argocd-repo-server
argocd-application-controller

Nếu bạn chưa cài ArgoCD, hãy hoàn thành Lab 3 — Install ArgoCD trước.


📁 6. Tạo GitOps Repository

Chúng ta sử dụng cấu trúc:

gitops-repo/
│
├── base/
│   ├── deployment.yaml
│   ├── service.yaml
│   └── kustomization.yaml
│
└── overlays/
    ├── dev/
    │   ├── kustomization.yaml
    │   └── namespace.yaml
    │
    ├── staging/
    │   ├── kustomization.yaml
    │   └── namespace.yaml
    │
    └── production/
        ├── kustomization.yaml
        └── namespace.yaml

Tại sao cấu trúc này tốt?

Vì chúng ta có thể nhìn vào repository và ngay lập tức biết:

base        → cấu hình chung
dev         → cấu hình Development
staging     → cấu hình Staging
production  → cấu hình Production

🧪 7. Tạo Base

7.1. Tạo thư mục

mkdir -p gitops-repo/base
mkdir -p gitops-repo/overlays/{dev,staging,production}

cd gitops-repo

7.2. Tạo Deployment

Tạo:

base/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: todo-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: todo-app
  template:
    metadata:
      labels:
        app: todo-app
    spec:
      containers:
        - name: todo-app
          image: nginx:1.27
          ports:
            - containerPort: 80

Đây là cấu hình chung.

Nhưng chú ý:

replicas: 1

Trong production chúng ta không muốn chỉ có 1 Pod.

Vì vậy phần này sẽ được override ở Overlay.


7.3. Tạo Service

Tạo:

base/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: todo-app
spec:
  selector:
    app: todo-app
  ports:
    - port: 80
      targetPort: 80

7.4. Tạo Kustomization

Tạo:

base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
  - deployment.yaml
  - service.yaml

Bây giờ Base đã hoàn thành:

base/
├── deployment.yaml
├── service.yaml
└── kustomization.yaml

🧪 8. Tạo Development Environment

8.1. Tạo Kustomization

Tạo:

overlays/dev/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: todo-dev

resources:
  - ../../base

namePrefix: dev-

replicas:
  - name: todo-app
    count: 1

Ở đây chúng ta nói với Kustomize:

Lấy Base và biến nó thành cấu hình dành cho dev.


8.2. Tạo namespace

apiVersion: v1
kind: Namespace
metadata:
  name: todo-dev

Thêm vào:

resources:
  - ../../base
  - namespace.yaml

8.3. Test

Không cần deploy ngay.

Hãy render YAML:

kubectl kustomize overlays/dev

Bạn sẽ thấy:

namespace: todo-dev

và:

replicas: 1

Đây là một thói quen rất tốt:

Render trước, deploy sau.

Nó giúp phát hiện lỗi cấu hình trước khi đẩy vào cluster.


🧪 9. Tạo Staging Environment

Tạo:

overlays/staging/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: todo-staging

resources:
  - ../../base
  - namespace.yaml

namePrefix: staging-

replicas:
  - name: todo-app
    count: 2

Namespace:

apiVersion: v1
kind: Namespace
metadata:
  name: todo-staging

Render:

kubectl kustomize overlays/staging

Kết quả quan trọng:

replicas: 2
namespace: todo-staging

🧪 10. Tạo Production Environment

Tạo:

overlays/production/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: todo-prod

resources:
  - ../../base
  - namespace.yaml

namePrefix: prod-

replicas:
  - name: todo-app
    count: 3

Namespace:

apiVersion: v1
kind: Namespace
metadata:
  name: todo-prod

Render:

kubectl kustomize overlays/production

Kết quả:

replicas: 3
namespace: todo-prod

👀 11. So sánh 3 Environment

Bây giờ repository có:

gitops-repo/
│
├── base/
│
└── overlays/
    ├── dev/
    ├── staging/
    └── production/

Và:

             BASE
              │
      ┌───────┼────────┐
      ▼       ▼        ▼
     DEV    STAGING    PROD
      │       │        │
     1 Pod   2 Pods   3 Pods

Điều quan trọng là:

Chúng ta không tạo 3 Deployment khác nhau.

Chúng ta có một Deployment Base và thay đổi nó bằng Overlay.


🚀 12. Deploy thử bằng kubectl

Trước khi đưa ArgoCD vào, hãy đảm bảo Kustomize hoạt động.

12.1. Deploy Dev

kubectl apply -k overlays/dev

Kiểm tra:

kubectl get pods -n todo-dev

Bạn sẽ thấy:

NAME                    READY   STATUS
dev-todo-app-xxxxx      1/1     Running

12.2. Deploy Staging

kubectl apply -k overlays/staging

Kiểm tra:

kubectl get pods -n todo-staging

Kỳ vọng:

2 Pods

12.3. Deploy Production

kubectl apply -k overlays/production

Kiểm tra:

kubectl get pods -n todo-prod

Kỳ vọng:

3 Pods

🔄 13. Đưa Environment vào ArgoCD

Đây mới là phần quan trọng của GitOps.

Thay vì:

kubectl apply -k overlays/dev

chúng ta muốn:

Git Push
   ↓
ArgoCD
   ↓
Kubernetes

🧪 14. Tạo ArgoCD Application cho Dev

Tạo:

argocd/todo-dev.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: todo-dev
  namespace: argocd
spec:
  project: default

  source:
    repoURL: https://github.com/YOUR_USERNAME/gitops-repo.git
    targetRevision: main
    path: overlays/dev

  destination:
    server: https://kubernetes.default.svc
    namespace: todo-dev

  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true

Thay:

YOUR_USERNAME

bằng GitHub username của bạn.

Apply:

kubectl apply -f argocd/todo-dev.yaml

Kiểm tra:

kubectl get applications -n argocd

Bạn sẽ thấy:

NAME       SYNC STATUS   HEALTH STATUS
todo-dev   Synced        Healthy

🧪 15. Tạo Application cho Staging

Tạo:

argocd/todo-staging.yaml

Điểm khác biệt quan trọng:

metadata:
  name: todo-staging

và:

path: overlays/staging

Destination:

namespace: todo-staging

Apply:

kubectl apply -f argocd/todo-staging.yaml

Kiểm tra:

kubectl get applications -n argocd

Kết quả:

NAME            SYNC STATUS   HEALTH STATUS
todo-dev        Synced        Healthy
todo-staging    Synced        Healthy

🧪 16. Tạo Application cho Production

Tạo:

argocd/todo-production.yaml

Các giá trị quan trọng:

metadata:
  name: todo-production
path: overlays/production
namespace: todo-prod

Apply:

kubectl apply -f argocd/todo-production.yaml

Kiểm tra:

kubectl get applications -n argocd

Kỳ vọng:

NAME              SYNC STATUS   HEALTH STATUS
todo-dev          Synced        Healthy
todo-staging      Synced        Healthy
todo-production   Synced        Healthy

👀 17. Xem trên ArgoCD UI

Port-forward ArgoCD:

kubectl port-forward svc/argocd-server -n argocd 8080:443

Mở:

https://localhost:8080

Bạn sẽ thấy:

┌─────────────────────────────────────┐
│              ArgoCD                 │
│                                     │
│  todo-dev          Synced Healthy   │
│  todo-staging      Synced Healthy   │
│  todo-production   Synced Healthy   │
│                                     │
└─────────────────────────────────────┘

Đây chính là lúc GitOps bắt đầu trở nên rõ ràng.

ArgoCD không chỉ deploy application.

Nó đang quản lý trạng thái mong muốn của từng environment.


🔥 18. Thực hành quan trọng — Thay đổi Dev

Bây giờ hãy thay đổi:

overlays/dev/kustomization.yaml

Từ:

count: 1

thành:

count: 2

Commit:

git add .
git commit -m "scale dev to 2 replicas"
git push

ArgoCD phát hiện:

Git
 │
 │ replicas: 2
 ▼
ArgoCD
 │
 │ Sync
 ▼
Kubernetes

Kiểm tra:

kubectl get pods -n todo-dev

Bạn sẽ thấy:

2 Pods

💡 Đây chính là GitOps

Bạn không chạy:

kubectl scale deployment ...

Bạn thay đổi:

Git

Sau đó ArgoCD đưa Kubernetes về đúng trạng thái trong Git.


🧨 19. Thực hành Self-Healing

Đây là một tính năng cực kỳ quan trọng của ArgoCD.

Xem Deployment:

kubectl get deployment -n todo-dev

Sau đó cố tình thay đổi:

kubectl scale deployment dev-todo-app \
  --replicas=5 \
  -n todo-dev

Kiểm tra:

kubectl get deployment -n todo-dev

Có thể bạn sẽ thấy:

READY
5/5

Nhưng Git vẫn nói:

replicas: 2

ArgoCD phát hiện:

Git Desired State
replicas = 2

        ≠

Cluster Live State
replicas = 5

Và vì chúng ta đã bật:

selfHeal: true

ArgoCD sẽ đưa cluster trở lại:

replicas = 2

Kiểm tra:

kubectl get deployment -n todo-dev

🧠 Điều cần nhớ

Git
 │
 │ Desired State
 ▼
ArgoCD
 │
 │ Reconcile
 ▼
Kubernetes
 │
 │ Live State
 ▼
Match Git

Nếu:

Desired State ≠ Live State

ArgoCD sẽ cố gắng reconcile.


🔄 20. Promotion giữa các Environment

Đây là cách tư duy rất quan trọng trong production.

Giả sử developer có version:

v1.2.0

Quy trình:

Developer
    │
    ▼
   DEV
    │
    │ Test OK
    ▼
 STAGING
    │
    │ QA OK
    ▼
PRODUCTION

Không nên:

Developer
    │
    └──────────────► Production

Thay vào đó:

DEV
 │
 │ Validate
 ▼
STAGING
 │
 │ Validate
 ▼
PRODUCTION

Git trở thành nơi ghi nhận quá trình promotion.

Ví dụ:

overlays/dev
    image: todo:v1.2.0

overlays/staging
    image: todo:v1.2.0

overlays/production
    image: todo:v1.1.0

Sau khi staging test thành công:

production
    v1.1.0
       ↓
    v1.2.0

Commit thay đổi đó vào Git.

ArgoCD sẽ deploy production.


🧠 21. Production Tips

21.1. Không nên để mọi thứ khác nhau giữa các environment

Sai:

dev/
 ├── deployment.yaml
 ├── service.yaml
 ├── configmap.yaml
 └── ...

staging/
 ├── deployment.yaml
 ├── service.yaml
 ├── configmap.yaml
 └── ...

production/
 ├── deployment.yaml
 ├── service.yaml
 ├── configmap.yaml
 └── ...

Bạn sẽ phải maintain rất nhiều file.

Tốt hơn:

base/
    ├── deployment.yaml
    └── service.yaml

overlays/
    ├── dev/
    ├── staging/
    └── production/

21.2. Production không nên Auto Sync một cách tùy tiện

Dev có thể:

automated:
  prune: true
  selfHeal: true

Nhưng production cần cẩn thận hơn.

Một thay đổi sai trong Git có thể:

Git
 ↓
ArgoCD
 ↓
Production
 ↓
Incident

Trong nhiều hệ thống, production deployment được kiểm soát bằng:

Pull Request
    ↓
Code Review
    ↓
Approval
    ↓
Merge
    ↓
ArgoCD Sync

21.3. Git phải là Source of Truth

Không nên thường xuyên sửa trực tiếp:

kubectl edit deployment

hoặc:

kubectl scale deployment ...

rồi coi đó là thay đổi chính thức.

Thay vào đó:

Muốn thay đổi
      ↓
Sửa Git
      ↓
Pull Request
      ↓
Review
      ↓
Merge
      ↓
ArgoCD
      ↓
Kubernetes

21.4. Đừng tạo quá nhiều environment

Không phải cứ nhiều environment là tốt.

Một hệ thống nhỏ có thể chỉ cần:

dev
production

Một hệ thống lớn hơn:

dev
staging
production

Chỉ tạo thêm:

qa
uat
performance
sandbox

khi thực sự có nhu cầu.


🧪 22. Bài tập thực hành

Exercise 1 — Tạo Environment

Tạo:

dev
staging
production

với số replica:

dev        → 1
staging    → 2
production → 3

Exercise 2 — Deploy bằng ArgoCD

Tạo 3 ArgoCD Applications:

todo-dev
todo-staging
todo-production

Kiểm tra:

kubectl get applications -n argocd

Tất cả phải:

Synced
Healthy

Exercise 3 — Test Self-Healing

Scale Dev lên:

kubectl scale deployment dev-todo-app \
  --replicas=5 \
  -n todo-dev

Quan sát ArgoCD.

Sau đó kiểm tra:

kubectl get deployment -n todo-dev

Kỳ vọng:

5 replicas
   ↓
ArgoCD detects drift
   ↓
2 replicas

Exercise 4 — Promotion

Thay đổi image:

v1.0.0

thành:

v1.1.0

dev.

Sau khi test thành công:

dev
 ↓
staging
 ↓
production

Thực hiện promotion bằng Git commit.


🔍 23. Troubleshooting

ArgoCD báo OutOfSync

Kiểm tra:

kubectl get application todo-dev -n argocd

Sau đó xem chi tiết:

kubectl describe application todo-dev -n argocd

Thông thường nguyên nhân là:

Git State
    ≠
Cluster State

Pod không được tạo

Kiểm tra:

kubectl get pods -n todo-dev

Nếu Pod lỗi:

kubectl describe pod <pod-name> -n todo-dev

Xem log:

kubectl logs <pod-name> -n todo-dev

Kustomize render lỗi

Chạy trực tiếp:

kubectl kustomize overlays/dev

Nếu command này lỗi thì chưa cần kiểm tra ArgoCD.

Hãy sửa Kustomize trước.

Đây là cách debug hiệu quả:

Kustomize
   ↓
kubectl apply
   ↓
ArgoCD

Debug từ dưới lên trên thay vì đổ hết lỗi cho ArgoCD.


🧠 24. Tổng kết

Sau lab này, bạn cần hình dung được mô hình:

                 Git
                  │
          Source of Truth
                  │
                  ▼
               ArgoCD
                  │
       ┌──────────┼──────────┐
       ▼          ▼          ▼
      DEV       STAGING      PROD
       │          │          │
      1 Pod      2 Pods     3 Pods

Và quan trọng hơn:

Không phải:

Developer
   │
   └── kubectl apply
            ↓
       Kubernetes

Mà là:

Developer
   │
   │ git push
   ▼
Git Repository
   │
   │ Desired State
   ▼
ArgoCD
   │
   │ Reconcile
   ▼
Kubernetes

⭐ Mental Model cần nhớ

Environment Management không phải là tạo thật nhiều YAML.

Mục tiêu là:

Một Application
      +
Một Base
      +
Nhiều Overlay
      ↓
Nhiều Environment

và:

Git
 ↓
ArgoCD
 ↓
Kubernetes

đảm bảo mọi environment luôn tiến gần đến trạng thái được định nghĩa trong Git.


🚀 25. Bạn đã học được gì?

                    GitOps
                       │
             ┌─────────┴─────────┐
             │                   │
            Base              Overlay
             │                   │
             │          ┌────────┼────────┐
             │          ▼        ▼        ▼
             │         DEV    STAGING    PROD
             │
             └──────────────┬────────────
                            ▼
                          ArgoCD
                            │
                            ▼
                       Kubernetes

Bạn đã giải quyết được một vấn đề rất thực tế:

Làm thế nào để cùng một application chạy ở nhiều environment mà không phải copy và maintain hàng đống Kubernetes YAML?

Câu trả lời là:

Kustomize Base/Overlay + ArgoCD + Git làm Source of Truth.

Lab tiếp theo có thể đi sâu vào Lab 9 — GitOps Secrets, nơi chúng ta giải quyết một vấn đề production quan trọng hơn: Nếu Git là Source of Truth thì password, API key và database credentials sẽ được quản lý như thế nào mà không commit secret trực tiếp lên Git?


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí