0

Lab 20 — GitOps Production Architecture

Scenario: Chúng ta đã biết GitOps, ArgoCD, Helm, Kustomize, Secrets, CI/CD và Monitoring. Bây giờ hãy ghép chúng lại thành một Production GitOps Architecture hoàn chỉnh.


🎯 1. Mục tiêu

Sau Lab này, bạn sẽ hiểu và xây dựng được:

  • Kiến trúc GitOps thực tế cho một Kubernetes application.
  • Vai trò của Application Repository, GitOps Repository, CI/CDArgoCD.
  • Luồng deploy từ lúc Developer git push đến khi Application chạy trên Kubernetes.
  • Cách tách CICD để hệ thống an toàn và dễ quản lý hơn.
  • Những nguyên tắc quan trọng khi đưa GitOps vào Production.

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

Ở các Lab trước, chúng ta có thể deploy Application bằng:

kubectl apply -f deployment.yaml

Hoặc:

helm upgrade --install todo-app ./chart

Ban đầu cách này rất tiện.

Nhưng hãy tưởng tượng một team có:

10 Developers
5 Applications
3 Environments
2 Kubernetes Clusters

Một ngày Developer hỏi:

"Production đang chạy version nào?"

Bạn phải kiểm tra Kubernetes.

Người khác hỏi:

"Ai đã thay đổi replica từ 3 thành 5?"

Bạn phải tìm trong history hoặc kiểm tra cluster.

Một Engineer chạy:

kubectl edit deployment

để sửa nhanh Production.

Git lúc này không còn phản ánh chính xác trạng thái Production.

Đây chính là vấn đề GitOps giải quyết.

GitOps đưa chúng ta về một nguyên tắc đơn giản:

Git là nơi mô tả trạng thái mong muốn của hệ thống.

Kubernetes chỉ cần đảm bảo:

Git desired state
       ↓
     ArgoCD
       ↓
Kubernetes actual state

Nếu hai trạng thái khác nhau:

Git              Kubernetes
 │                    │
 │ replicas: 3        │ replicas: 5
 │                    │
 └─────── Diff ───────┘
            ↓
         ArgoCD
            ↓
          Sync
            ↓
       replicas: 3

🧠 3. Hiểu nhanh

3.1. GitOps Architecture là gì?

Thay vì Developer hoặc DevOps Engineer trực tiếp thay đổi Kubernetes:

Developer
    │
    │ kubectl apply
    ▼
Kubernetes

chúng ta chuyển sang:

Developer
    │
    │ Git Push
    ▼
Git
    │
    │
    ▼
  ArgoCD
    │
    │ Sync
    ▼
Kubernetes

Điểm quan trọng nhất:

Không deploy bằng cách sửa trực tiếp Kubernetes.

Thay đổi nên đi qua Git.


3.2. Application Repository

Đây là repository chứa source code của Application.

Ví dụ:

todo-backend/
├── src/
├── package.json
├── Dockerfile
└── ...

Developer thay đổi code:

git push

CI sẽ:

Test
  ↓
Build
  ↓
Docker Image
  ↓
Push Registry

Ví dụ:

todo-backend:1.2.0

3.3. GitOps Repository

GitOps Repository không chứa source code Application.

Nó chứa:

Application nên được chạy như thế nào trên Kubernetes.

Ví dụ:

todo-gitops/
├── environments/
│   ├── dev/
│   ├── staging/
│   └── production/
│
└── applications/
    └── todo-app/

Trong đó có thể mô tả:

replicas: 3
image:
  repository: todo-backend
  tag: "1.2.0"

GitOps Repository chính là:

Source of Truth cho Kubernetes.


3.4. CI và CD khác nhau như thế nào?

Đây là điểm rất quan trọng.

CI — Continuous Integration

CI chịu trách nhiệm:

Source Code
     ↓
Test
     ↓
Build
     ↓
Docker Image
     ↓
Registry

Ví dụ:

todo-backend:1.2.0

CD — Continuous Delivery / Deployment

CD chịu trách nhiệm:

GitOps Repository
        ↓
      ArgoCD
        ↓
    Kubernetes

Vì vậy:

             CI                         CD
              │                          │
              ▼                          ▼
        Build Image                  ArgoCD
              │                          │
              ▼                          ▼
          Registry                Kubernetes

Một nguyên tắc production rất quan trọng

CI tạo Artifact. CD triển khai Artifact.

Không nên để GitHub Actions vừa build image vừa trực tiếp chạy:

kubectl apply

vào Production nếu bạn đã sử dụng GitOps.


🏗️ 4. Architecture

Một Production GitOps Architecture cơ bản:

                         ┌─────────────────┐
                         │    Developer    │
                         └────────┬────────┘
                                  │
                                  │ git push
                                  ▼
                         ┌─────────────────┐
                         │ Application Repo│
                         │                 │
                         │ Source Code     │
                         └────────┬────────┘
                                  │
                                  │ Trigger CI
                                  ▼
                         ┌─────────────────┐
                         │  GitHub Actions │
                         │                 │
                         │ Test            │
                         │ Build           │
                         │ Docker Image    │
                         └────────┬────────┘
                                  │
                                  │ Push
                                  ▼
                         ┌─────────────────┐
                         │ Container       │
                         │ Registry        │
                         └─────────────────┘


              Update image version
                       │
                       ▼

                  ┌─────────────────┐
                  │  GitOps Repo     │
                  │                  │
                  │ dev/             │
                  │ staging/         │
                  │ production/      │
                  └────────┬─────────┘
                           │
                           │ Watch
                           ▼
                  ┌─────────────────┐
                  │     ArgoCD      │
                  │                 │
                  │ Detect Diff     │
                  │ Sync             │
                  │ Self-Healing    │
                  └────────┬────────┘
                           │
                           │ Deploy
                           ▼
                  ┌─────────────────┐
                  │   Kubernetes    │
                  │                 │
                  │ Frontend        │
                  │ Backend         │
                  │ PostgreSQL      │
                  └────────┬────────┘
                           │
                           ▼
                  ┌─────────────────┐
                  │ Prometheus      │
                  │ Grafana         │
                  │ Alertmanager    │
                  └─────────────────┘

Bạn có thể nhìn Architecture này thành 4 lớp:

1. Source Code
       ↓
2. CI / Container Registry
       ↓
3. GitOps / ArgoCD
       ↓
4. Kubernetes / Monitoring

🧪 5. Chuẩn bị môi trường

Trong Lab này, chúng ta sử dụng:

GitHub
GitHub Actions
Container Registry
ArgoCD
Kubernetes
Helm / Kustomize
Prometheus
Grafana

Bạn có thể sử dụng cluster Kubernetes local từ các Lab trước.

Kiểm tra:

kubectl get nodes

Kết quả mong đợi:

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

Kiểm tra ArgoCD:

kubectl get pods -n argocd

Các Pod của ArgoCD nên ở trạng thái:

Running

📁 6. Thiết kế Repository

6.1. Tại sao cần tách Repository?

Đây là một quyết định architecture quan trọng.

Thay vì:

todo-app/
├── src/
├── Dockerfile
└── kubernetes/

chúng ta tách thành:

todo-backend/

và:

todo-gitops/

Application Repository

todo-backend/
├── src/
├── tests/
├── Dockerfile
├── package.json
└── ...

GitOps Repository

todo-gitops/
├── applications/
│   └── todo-app/
│
└── environments/
    ├── dev/
    ├── staging/
    └── production/

Lợi ích:

  • Developer không cần quyền trực tiếp vào Production.
  • GitOps change có history riêng.
  • Dễ review deployment configuration.
  • Dễ audit.
  • ArgoCD chỉ cần theo dõi GitOps Repository.

🏗️ 7. Thiết kế Environment

Một hệ thống thực tế thường có:

dev
 │
 ▼
staging
 │
 ▼
production

Mỗi environment có configuration riêng.

Ví dụ:

environments/
├── dev/
│   ├── kustomization.yaml
│   └── values.yaml
│
├── staging/
│   ├── kustomization.yaml
│   └── values.yaml
│
└── production/
    ├── kustomization.yaml
    └── values.yaml

Ví dụ:

DEV
replicas: 1

STAGING
replicas: 2

PRODUCTION
replicas: 3

Application vẫn giống nhau.

Chỉ có configuration khác nhau.


🧩 8. Base và Environment Overlay

Nếu sử dụng Kustomize, chúng ta có thể tổ chức:

applications/
└── todo-app/
    └── base/
        ├── deployment.yaml
        ├── service.yaml
        └── kustomization.yaml

environments/
├── dev/
│   └── kustomization.yaml
│
├── staging/
│   └── kustomization.yaml
│
└── production/
    └── kustomization.yaml

Base

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

Deployment
Service
ConfigMap
Ingress

Overlay

Overlay thay đổi những thứ phụ thuộc environment:

replicas
image
resources
hostname
configuration

Ví dụ:

              Base
               │
       ┌───────┼────────┐
       ▼       ▼        ▼
      Dev    Staging  Production
       │       │        │
      1 Pod   2 Pods   3 Pods

Tại sao cách này tốt?

Bạn không cần copy toàn bộ YAML cho từng environment.

Nếu sửa:

Service

thì chỉ sửa Base.


🚀 9. Deploy Application bằng ArgoCD

Bây giờ chúng ta kết nối GitOps Repository với ArgoCD.

Ví dụ Application:

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

  source:
    repoURL: https://github.com/example/todo-gitops.git
    targetRevision: main
    path: environments/production

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

  syncPolicy:
    automated:
      prune: true
      selfHeal: true

Apply:

kubectl apply -f argocd/application.yaml

Kiểm tra:

kubectl get applications -n argocd

Bạn có thể xem:

NAME               SYNC STATUS   HEALTH STATUS
todo-production    Synced        Healthy

👀 10. See Result — ArgoCD quản lý Application

Mở ArgoCD UI.

Bạn sẽ thấy:

todo-production

SYNC:   Synced
HEALTH: Healthy

Architecture lúc này:

GitOps Repository
       │
       │
       ▼
     ArgoCD
       │
       │
       ▼
 Kubernetes
       │
       ├── Deployment
       ├── Service
       └── Pods

Điểm quan trọng:

Bạn không cần chạy kubectl apply cho mỗi lần thay đổi configuration nữa.


🔄 11. Thực hành GitOps Workflow

Bây giờ hãy thử một thay đổi đơn giản.

Giả sử Production đang chạy:

replicas: 3

Thay đổi GitOps Repository:

replicas: 5

Commit:

git add .
git commit -m "scale production to 5 replicas"
git push

ArgoCD phát hiện:

Git:
replicas = 5

Kubernetes:
replicas = 3

ArgoCD hiển thị:

OutOfSync

Sau khi Sync:

Git:
replicas = 5

Kubernetes:
replicas = 5

Trạng thái trở lại:

Synced
Healthy

🧠 12. Hiểu bản chất của Self-Healing

Đây là một trong những tính năng mạnh nhất của GitOps.

Giả sử Git nói:

replicas = 3

Nhưng một Engineer chạy:

kubectl scale deployment todo-backend --replicas=10

Kubernetes trở thành:

replicas = 10

Trong khi Git vẫn:

replicas = 3

ArgoCD phát hiện:

Desired State ≠ Actual State

Nếu bật:

selfHeal: true

ArgoCD sẽ đưa Kubernetes trở về:

replicas = 3

Đây chính là GitOps:

             Git
              │
              │ Desired State
              ▼
           ArgoCD
              │
              │ Reconcile
              ▼
         Kubernetes
              │
              │ Actual State
              └──────────┐
                         │
                    Difference?
                         │
                         ▼
                      Fix it

🔐 13. Secrets trong Production

Một lỗi phổ biến của người mới là commit:

stringData:
  password: my-production-password

vào Git.

Không nên làm vậy.

GitOps không có nghĩa là:

"Cho tất cả mọi thứ vào Git."

GitOps nên quản lý:

Application Configuration
Deployment Configuration
Infrastructure Configuration

Nhưng Secret cần cơ chế bảo vệ phù hợp.

Một architecture tốt hơn:

GitOps Repository
       │
       │ Reference
       ▼
External Secrets
       │
       ▼
Secret Manager
       │
       ▼
Kubernetes Secret

Ví dụ Secret Manager có thể là:

AWS Secrets Manager
HashiCorp Vault
GCP Secret Manager
Azure Key Vault

Nguyên tắc:

Git lưu reference, Secret Manager lưu secret thật.


🔒 14. Production Security

Trong Production, không nên để:

Developer
   │
   │ kubectl
   ▼
Production Cluster

Mô hình tốt hơn:

Developer
    │
    │ Pull Request
    ▼
GitHub
    │
    │ Review
    ▼
GitOps Repository
    │
    ▼
ArgoCD
    │
    ▼
Production

Developer chỉ cần quyền cần thiết trên Git.

ArgoCD mới là thành phần có quyền deploy.

Điều này giúp giảm nguy cơ:

kubectl delete namespace production

do thao tác nhầm hoặc quyền quá rộng.


🔁 15. Production Deployment Flow

Hãy tưởng tượng Developer sửa Backend.

Bước 1 — Developer

git push

Bước 2 — CI

GitHub Actions chạy:

Test
 ↓
Build
 ↓
Docker Image
 ↓
Push Registry

Ví dụ:

todo-backend:1.3.0

Bước 3 — Update GitOps

CI tạo Pull Request:

image:
  tag: 1.3.0

Bước 4 — Review

Team review:

1.2.0 → 1.3.0

Bước 5 — Merge

Sau khi approve:

GitOps main

được cập nhật.

Bước 6 — ArgoCD

ArgoCD phát hiện:

OutOfSync

và Sync:

1.2.0
   ↓
1.3.0

Bước 7 — Kubernetes

Kubernetes thực hiện:

Rolling Update

Bước 8 — Monitoring

Prometheus/Grafana theo dõi:

CPU
Memory
Request Rate
Latency
HTTP 5xx
Pod Restart

Toàn bộ flow:

Developer
    │
    ▼
Application Repo
    │
    ▼
GitHub Actions
    │
    ▼
Docker Registry
    │
    ▼
GitOps Repo
    │
    ▼
Pull Request
    │
    ▼
Review
    │
    ▼
Merge
    │
    ▼
ArgoCD
    │
    ▼
Kubernetes
    │
    ▼
Monitoring

🚨 16. Khi Deployment bị lỗi thì sao?

Đây là tình huống rất thực tế.

Developer deploy:

v1.3.0

Nhưng Application bị:

HTTP 500

Monitoring phát hiện:

5xx ↑

ArgoCD có thể cho biết:

Deployment Synced
Health: Degraded

Lúc này DevOps Engineer có thể rollback bằng Git.

Ví dụ:

v1.3.0
   ↓
v1.2.0

Thay đổi GitOps:

image:
  tag: 1.2.0

Commit:

git commit -m "rollback todo-backend to 1.2.0"
git push

ArgoCD Sync:

1.3.0
   ↓
1.2.0

Tại sao rollback bằng Git tốt?

Bạn có history:

commit A → v1.2.0
commit B → v1.3.0
commit C → v1.2.0

Bạn biết:

  • Ai thay đổi?
  • Thay đổi lúc nào?
  • Thay đổi cái gì?
  • Vì sao rollback?

Đây chính là auditability — khả năng truy vết thay đổi.


📊 17. Monitoring Architecture

GitOps không thay thế Monitoring.

Hai hệ thống giải quyết hai vấn đề khác nhau:

GitOps
   │
   └── "System SHOULD look like this"

Monitoring
   │
   └── "System IS behaving like this"

Kết hợp:

                 Git
                  │
                  ▼
               ArgoCD
                  │
                  ▼
             Kubernetes
                  │
        ┌─────────┴─────────┐
        ▼                   ▼
   Application          Infrastructure
        │                   │
        └─────────┬─────────┘
                  ▼
             Prometheus
                  │
                  ▼
               Grafana
                  │
                  ▼
             Alertmanager

Ví dụ:

ArgoCD:
Healthy

Nhưng:

HTTP 500:
↑↑↑↑↑

Điều này cho thấy:

Deployment thành công không có nghĩa Application hoạt động tốt.

Đây là một insight rất quan trọng khi làm Production.


🧯 18. Những lỗi thường gặp trong Production

❌ 18.1. Sửa trực tiếp Kubernetes

kubectl edit deployment

Sau đó quên cập nhật Git.

Kết quả:

Git ≠ Kubernetes

Tốt hơn

Thay đổi GitOps Repository:

Git
 ↓
ArgoCD
 ↓
Kubernetes

❌ 18.2. CI deploy trực tiếp Production

Ví dụ:

run: kubectl apply -f production/

Điều này làm CI trở thành một deployment engine khác ngoài ArgoCD.

Architecture trở nên:

GitHub Actions ──┐
                 ├──► Kubernetes
ArgoCD ──────────┘

Hai hệ thống cùng có thể thay đổi Production.

Rất khó kiểm soát.

Tốt hơn

GitHub Actions
      │
      ▼
GitOps Repo
      │
      ▼
    ArgoCD
      │
      ▼
 Kubernetes

❌ 18.3. Commit Secret vào Git

Không nên:

password: production-password

Ngay cả private repository cũng không nên coi là nơi lưu Secret an toàn mặc định.


❌ 18.4. Không có Pull Request

Một người có thể sửa:

production/values.yaml

và deploy ngay.

Production nên có:

Pull Request
     ↓
Code Review
     ↓
Merge
     ↓
ArgoCD

❌ 18.5. Dùng latest

Không nên:

image: todo-backend:latest

Tốt hơn:

image: todo-backend:1.3.0

Hoặc tốt hơn nữa:

image digest

Ví dụ:

todo-backend@sha256:...

Lý do:

latest

có thể trỏ tới Image khác nhau theo thời gian.

Production cần immutable artifact — artifact không thay đổi sau khi build.


🏆 19. Production GitOps Checklist

Trước khi nói rằng hệ thống GitOps đã "Production Ready", hãy kiểm tra:

Git
├── [ ] Git là Source of Truth
├── [ ] Có Pull Request
├── [ ] Có Code Review
└── [ ] Có Audit History

CI
├── [ ] Automated Test
├── [ ] Build Docker Image
├── [ ] Push Registry
└── [ ] Image có version rõ ràng

GitOps
├── [ ] Tách Application Repo và GitOps Repo
├── [ ] Có dev / staging / production
├── [ ] ArgoCD quản lý deployment
├── [ ] Self-Healing
└── [ ] Prune

Security
├── [ ] Không commit Secret
├── [ ] RBAC
├── [ ] Least Privilege
└── [ ] Production access được kiểm soát

Operations
├── [ ] Monitoring
├── [ ] Alerting
├── [ ] Rollback
└── [ ] Troubleshooting process

🧠 20. Understand — Bức tranh lớn

Sau Lab này, bạn không cần nhớ hàng trăm câu lệnh.

Chỉ cần nhớ một flow:

                 ┌──────────────┐
                 │  Developer   │
                 └──────┬───────┘
                        │
                     git push
                        │
                        ▼
               ┌─────────────────┐
               │ Application Repo│
               └────────┬────────┘
                        │
                        ▼
               ┌─────────────────┐
               │ GitHub Actions  │
               │                 │
               │ Test            │
               │ Build           │
               │ Push Image      │
               └────────┬────────┘
                        │
                        ▼
               ┌─────────────────┐
               │ Container       │
               │ Registry        │
               └─────────────────┘
                        │
                        │ Image Version
                        ▼
               ┌─────────────────┐
               │   GitOps Repo   │
               │                 │
               │ Dev             │
               │ Staging         │
               │ Production      │
               └────────┬────────┘
                        │
                        ▼
               ┌─────────────────┐
               │     ArgoCD      │
               │                 │
               │ Sync            │
               │ Self-Healing    │
               └────────┬────────┘
                        │
                        ▼
               ┌─────────────────┐
               │   Kubernetes    │
               └────────┬────────┘
                        │
                        ▼
               ┌─────────────────┐
               │ Monitoring      │
               │ Prometheus      │
               │ Grafana         │
               └─────────────────┘

Có thể hiểu đơn giản:

Developer thay đổi Code → CI tạo Image → GitOps Repo thay đổi → ArgoCD triển khai → Kubernetes chạy → Monitoring quan sát.

Đây là tư duy cốt lõi của một Production GitOps Platform.


🚀 21. Production Tips

💡 Tip 1 — Git nên là nơi duy nhất quyết định Deployment

Nếu có thể, tránh:

kubectl apply
kubectl edit
kubectl scale

trực tiếp trên Production.

Hãy thay đổi Git và để ArgoCD reconcile.


💡 Tip 2 — Tách CI và CD

Một cách dễ nhớ:

CI = Build it
CD = Deploy it

GitHub Actions có thể build image.

ArgoCD deploy image đó.


💡 Tip 3 — Production nên có Approval

Không nên:

git push
   ↓
Production

Nên:

git push
   ↓
Pull Request
   ↓
Review
   ↓
Merge
   ↓
Production

💡 Tip 4 — Monitoring không phải GitOps

ArgoCD trả lời:

"Kubernetes có đúng với Git không?"

Prometheus trả lời:

"Application có đang hoạt động tốt không?"

Hai thứ bổ sung cho nhau.


💡 Tip 5 — Rollback bằng Git

Đừng coi rollback là:

kubectl rollout undo

là chiến lược chính của GitOps.

Trong GitOps, rollback tốt nhất thường là:

Git
 ↓
Revert commit
 ↓
ArgoCD
 ↓
Kubernetes

Bạn vừa rollback Application, vừa giữ được lịch sử thay đổi.


🎯 22. Tổng kết

Trong Lab này, chúng ta đã ghép toàn bộ kiến thức của Phase GitOps thành một Architecture hoàn chỉnh.

Từ:

Application Code

đến:

Production Kubernetes

với flow:

Developer
    ↓
Application Repo
    ↓
CI
    ↓
Container Registry
    ↓
GitOps Repo
    ↓
ArgoCD
    ↓
Kubernetes
    ↓
Monitoring

Quan trọng nhất không phải là nhớ cách viết Application, Kustomization hay Helm.

Điều cần nhớ là tư duy kiến trúc:

Code được build bởi CI.

Deployment được mô tả bằng Git.

ArgoCD biến Git thành trạng thái thực tế trên Kubernetes.

Monitoring cho chúng ta biết hệ thống thực tế có đang khỏe hay không.

Đây chính là nền tảng để bước sang Final Project — Production GitOps Platform, nơi chúng ta sẽ tự xây dựng toàn bộ flow này từ đầu đến cuối.


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í