0

Lab 12 — Image Automation với ArgoCD

🎯 Mục tiêu

Sau Lab này, bạn sẽ:

  • Hiểu tại sao GitOps vẫn cần Image Automation.
  • Hiểu cách tự động phát hiện Docker Image mới.
  • Biết Argo CD Image Updater hoạt động như thế nào.
  • Tự động cập nhật image tag trong GitOps repository.
  • Hiểu cách kiểm soát version image an toàn trong production.

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

Ở các Lab trước, chúng ta đã có flow:

Developer
    │
    │ git push
    ▼
GitHub
    │
    ▼
CI/CD
    │
    │ docker build
    ▼
Container Registry
    │
    │ image: todo-api:v2
    ▼
GitOps Repository
    │
    ▼
ArgoCD
    │
    ▼
Kubernetes

Ví dụ hôm nay bạn sửa code:

todo-api
v1
 │
 │ Developer sửa code
 ▼
v2

CI build image:

todo-api:v2

Nhưng Kubernetes vẫn đang sử dụng:

image: ghcr.io/example/todo-api:v1

Vấn đề là:

Ai sẽ nói cho ArgoCD biết rằng v2 đã tồn tại?

Nếu làm thủ công, Developer/DevOps phải sửa GitOps repository:

image: ghcr.io/example/todo-api:v2

Sau đó:

git commit
git push

ArgoCD mới phát hiện thay đổi.

Với một team lớn, việc này nhanh chóng trở thành công việc lặp đi lặp lại.

Image Automation giải quyết vấn đề này

Thay vì:

Build Image
    ↓
DevOps sửa YAML
    ↓
git commit
    ↓
ArgoCD deploy

Ta muốn:

Build Image
    ↓
Registry
    ↓
Image Updater phát hiện version mới
    ↓
GitOps Repository được cập nhật
    ↓
ArgoCD
    ↓
Kubernetes

Đó chính là Image Automation.


🧠 2. Hiểu nhanh

2.1. Image Automation là gì?

Image Automation là quá trình tự động:

phát hiện Docker Image mới → cập nhật version image trong GitOps → để ArgoCD deploy version mới.

Ví dụ:

GitOps Repository

image: todo-api:v1

Registry xuất hiện:

todo-api:v2

Image Updater phát hiện:

v1 → v2

Sau đó cập nhật Git:

image: todo-api:v2

ArgoCD nhìn thấy Git thay đổi và deploy:

Kubernetes
    ↓
todo-api:v2

2.2. ArgoCD có tự làm việc này không?

Không.

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

ArgoCD chủ yếu làm nhiệm vụ:

Git
 ↓
Compare
 ↓
Sync
 ↓
Kubernetes

Nó không mặc định đi tìm Docker Image mới.

Chúng ta cần thêm một thành phần:

Argo CD Image Updater

Nó chịu trách nhiệm theo dõi image trong Container Registry.


🏗️ 3. Architecture

Architecture của Lab này:

                   ┌──────────────────┐
                   │    Developer     │
                   └────────┬─────────┘
                            │
                         git push
                            │
                            ▼
                   ┌──────────────────┐
                   │    GitHub CI     │
                   └────────┬─────────┘
                            │
                       docker build
                            │
                            ▼
                   ┌──────────────────┐
                   │ Container        │
                   │ Registry         │
                   │                  │
                   │ todo-api:v1      │
                   │ todo-api:v2      │
                   └────────┬─────────┘
                            │
                     detect new image
                            │
                            ▼
                   ┌──────────────────┐
                   │ Argo CD Image    │
                   │ Updater          │
                   └────────┬─────────┘
                            │
                      update Git
                            │
                            ▼
                   ┌──────────────────┐
                   │ GitOps Repository│
                   │                  │
                   │ image: v2        │
                   └────────┬─────────┘
                            │
                       Git change
                            │
                            ▼
                   ┌──────────────────┐
                   │      ArgoCD      │
                   └────────┬─────────┘
                            │
                          Sync
                            │
                            ▼
                   ┌──────────────────┐
                   │   Kubernetes     │
                   │                  │
                   │ todo-api:v2      │
                   └──────────────────┘

Hãy nhớ 3 vai trò:

Thành phần Nhiệm vụ
CI/CD Build & push Image
Image Updater Phát hiện Image mới và cập nhật Git
ArgoCD Đồng bộ Git → Kubernetes

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

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

Kubernetes
ArgoCD
Argo CD Image Updater
GitHub
GitHub Container Registry (GHCR)

Giả sử GitOps repository có cấu trúc:

gitops-repo/
└── apps/
    └── todo-api/
        ├── deployment.yaml
        └── service.yaml

🚀 5. Cài đặt Argo CD Image Updater

5.1. Tại sao cần cài thêm Image Updater?

ArgoCD không tự theo dõi Container Registry.

Image Updater sẽ đứng giữa:

Container Registry
        │
        ▼
Image Updater
        │
        ▼
Git
        │
        ▼
ArgoCD

Cài đặt:

kubectl create namespace argocd-image-updater

Sau đó cài Image Updater bằng manifest chính thức phù hợp với phiên bản bạn đang sử dụng.

Kiểm tra:

kubectl get pods -n argocd-image-updater

Kết quả mong đợi:

NAME                                  READY   STATUS
argocd-image-updater-xxxxx            1/1     Running

👀 See Result

Nếu Pod ở trạng thái:

Running

thì Image Updater đã chạy.


🧩 6. Chuẩn bị Application

Trước tiên, ArgoCD cần quản lý application của chúng ta.

Ví dụ:

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

  source:
    repoURL: https://github.com/example/gitops-repo.git
    targetRevision: main
    path: apps/todo-api

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

  syncPolicy:
    automated:
      prune: true
      selfHeal: true

Application này nói với ArgoCD:

"Hãy lấy configuration từ Git repository và deploy vào Kubernetes."


🔖 7. Khai báo Image cần theo dõi

Đây là phần quan trọng nhất của Lab.

Argo CD Image Updater cần biết:

Application nào và Image nào cần được tự động cập nhật?

Chúng ta khai báo image cần theo dõi bằng annotation trên ArgoCD Application.

Ví dụ:

metadata:
  name: todo-api
  namespace: argocd

  annotations:
    argocd-image-updater.argoproj.io/image-list: todo=ghcr.io/example/todo-api

Bây giờ Image Updater biết:

ArgoCD Application: todo-api

        ↓

Theo dõi:

ghcr.io/example/todo-api

🔄 8. Chọn Strategy cập nhật Image

Không phải cứ thấy image mới là update.

Ví dụ Registry có:

v1.0.0
v1.1.0
v1.2.0
v2.0.0

Chúng ta cần quy định:

"Version nào được phép tự động deploy?"

Đây chính là Update Strategy.

Ví dụ:

latest
    ↓
digest
    ↓
semver
    ↓
name

Trong production, SemVer thường dễ kiểm soát hơn.

Ví dụ:

v1.0.0
v1.1.0
v1.2.0

Cho phép:

v1.x.x

nhưng không tự động nhảy sang:

v2.x.x

Đây là một nguyên tắc rất quan trọng:

Automation tốt không có nghĩa là update tất cả mọi thứ. Automation tốt là automation có giới hạn.


🛠️ 9. Cấu hình Image Updater

Ví dụ:

metadata:
  annotations:

    argocd-image-updater.argoproj.io/image-list: |
      todo=ghcr.io/example/todo-api

    argocd-image-updater.argoproj.io/todo.update-strategy: semver

Bây giờ:

Registry

v1.0.0
v1.1.0
v1.2.0
v2.0.0

Image Updater có thể chọn:

v1.2.0

thay vì tự động nhảy lên:

v2.0.0

📦 10. Deploy Version đầu tiên

Giả sử GitOps repository đang chứa:

containers:
  - name: todo-api
    image: ghcr.io/example/todo-api:v1.0.0

ArgoCD deploy:

todo-api:v1.0.0

Kiểm tra:

kubectl get pods -n todo-app

Bạn sẽ thấy:

todo-api-xxxxx    1/1    Running

Kiểm tra image:

kubectl get pod -n todo-app -o jsonpath="{.items[0].spec.containers[0].image}"

Kết quả:

ghcr.io/example/todo-api:v1.0.0

🧪 11. Tạo Image Version mới

Bây giờ giả lập Developer release version mới.

Build:

docker build -t ghcr.io/example/todo-api:v1.1.0 .

Push:

docker push ghcr.io/example/todo-api:v1.1.0

Registry lúc này:

ghcr.io/example/todo-api

v1.0.0
v1.1.0   ← NEW

👀 12. Image Updater phát hiện Version mới

Image Updater sẽ định kỳ kiểm tra Registry.

Flow:

Image Updater
      │
      │ Check Registry
      ▼
   Registry
      │
      ├── v1.0.0
      └── v1.1.0  ← New
              │
              ▼
       Select v1.1.0

Kiểm tra log:

kubectl logs -n argocd-image-updater \
  deployment/argocd-image-updater

Bạn sẽ thấy các log liên quan tới việc kiểm tra và cập nhật image.


📝 13. Image Updater cập nhật Git

Đây là điểm quan trọng nhất cần hiểu.

Image Updater không đơn giản chỉ chạy:

kubectl set image ...

Thay vào đó, trong GitOps workflow, chúng ta muốn:

Git
 ↓
Change
 ↓
ArgoCD
 ↓
Kubernetes

Ví dụ ban đầu:

image: ghcr.io/example/todo-api:v1.0.0

Sau automation:

image: ghcr.io/example/todo-api:v1.1.0

GitOps repository trở thành:

main
 │
 ├── Deployment
 │      image: v1.1.0
 │
 └── Service

💡 Tại sao phải cập nhật Git?

Vì Git vẫn phải là:

Source of Truth

Nếu Image Updater chỉ sửa trực tiếp Kubernetes:

Registry
   ↓
Image Updater
   ↓
Kubernetes

thì Git không biết Kubernetes đang chạy version nào.

Đó là điều chúng ta không muốn trong GitOps.


🔄 14. ArgoCD tự động Deploy

Git thay đổi:

v1.0.0
   ↓
v1.1.0

ArgoCD phát hiện:

Git
 │
 │ Diff
 ▼
ArgoCD
 │
 │ Sync
 ▼
Kubernetes

Kiểm tra:

kubectl get pods -n todo-app

Sau đó:

kubectl get pod -n todo-app \
  -o jsonpath="{.items[0].spec.containers[0].image}"

Kết quả:

ghcr.io/example/todo-api:v1.1.0

🎉 Image đã được cập nhật tự động.


🔍 15. Nhìn lại toàn bộ Flow

Bây giờ hãy nhìn lại toàn bộ quá trình:

① Developer
      │
      │ git push
      ▼
② GitHub Actions
      │
      │ docker build
      │ docker push
      ▼
③ Container Registry
      │
      │ v1.1.0
      ▼
④ Image Updater
      │
      │ update Git
      ▼
⑤ GitOps Repository
      │
      │ Git change
      ▼
⑥ ArgoCD
      │
      │ Sync
      ▼
⑦ Kubernetes
      │
      ▼
    v1.1.0

Đây chính là:

Automated GitOps Deployment


🧠 16. Điều quan trọng cần hiểu

16.1. CI và Image Updater có vai trò khác nhau

Rất dễ nhầm hai thành phần này.

CI/CD

Source Code
    ↓
Build
    ↓
Test
    ↓
Docker Image
    ↓
Registry

CI trả lời:

"Image mới đã được tạo chưa?"


Image Updater

Registry
    ↓
Detect new version
    ↓
Update Git

Image Updater trả lời:

"Có version mới, GitOps repository có cần cập nhật không?"


ArgoCD

Git
 ↓
Sync
 ↓
Kubernetes

ArgoCD trả lời:

"Git đang muốn Kubernetes chạy version nào?"


🔐 17. Production: Đừng Auto Update mọi Image

Đây là kinh nghiệm rất quan trọng.

Không nên:

latest
  ↓
Auto Deploy

Vì:

latest
 ↓
Có thể thay đổi bất kỳ lúc nào
 ↓
Production thay đổi ngoài dự kiến

Thay vào đó nên dùng version cụ thể:

v1.2.3
v1.2.4
v1.2.5

hoặc digest:

sha256:xxxxxxxx

⚠️ 18. Một số lỗi thường gặp

❌ Image mới nhưng không được update

Kiểm tra:

kubectl logs -n argocd-image-updater \
  deployment/argocd-image-updater

Các nguyên nhân phổ biến:

  • Image Updater không truy cập được Registry.
  • Image private nhưng chưa cấu hình credentials.
  • Annotation sai.
  • Strategy không phù hợp.
  • Tag mới không thỏa điều kiện SemVer.

❌ Image đã update nhưng Kubernetes chưa thay đổi

Kiểm tra ArgoCD:

Application
   ↓
Sync Status
   ↓
Health Status

Có thể Git đã thay đổi nhưng ArgoCD chưa Sync.

Nếu sử dụng:

syncPolicy:
  automated:

ArgoCD có thể tự Sync.


❌ Production tự nhiên chạy version mới

Nguyên nhân thường là policy quá rộng.

Ví dụ:

semver

nhưng không giới hạn version phù hợp.

Production nên có policy rõ ràng:

v1.x.x
   ↓
Auto Update

v2.x.x
   ↓
Manual Approval

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

Exercise 1 — Auto Update

  • [ ] Deploy todo-api:v1.0.0.
  • [ ] Cấu hình Image Updater.
  • [ ] Push v1.1.0.
  • [ ] Kiểm tra Image Updater.
  • [ ] Kiểm tra Git.
  • [ ] Kiểm tra ArgoCD.
  • [ ] Kiểm tra Kubernetes.

Flow cần đạt:

v1.0.0
  ↓
Push v1.1.0
  ↓
Image Updater
  ↓
Git
  ↓
ArgoCD
  ↓
Kubernetes v1.1.0

Exercise 2 — Test SemVer

Tạo:

v1.2.0
v2.0.0

Cấu hình policy chỉ cho phép:

v1.x.x

Kiểm tra Kubernetes.

Bạn cần chứng minh rằng:

v1.1.0
   ↓
v1.2.0       ✅ Auto Update

v2.0.0       ❌ Không Auto Update

Exercise 3 — Debug

Cố tình tạo một lỗi:

Image tag không tồn tại

Ví dụ:

image: ghcr.io/example/todo-api:v99.99.99

Sau đó tìm hiểu:

Git
 ↓
ArgoCD
 ↓
Kubernetes

đang báo lỗi ở đâu.

Mục tiêu không phải chỉ sửa lỗi, mà phải trả lời được:

"Lỗi xảy ra ở layer nào?"


🏆 20. Production Pattern

Một workflow thực tế có thể giống:

Developer
    │
    │ Pull Request
    ▼
GitHub
    │
    ▼
CI
 ┌──┴─────────────┐
 │ Test           │
 │ Build          │
 │ Security Scan  │
 └──────┬─────────┘
        │
        ▼
Container Registry
        │
        │ New Image
        ▼
Image Updater
        │
        │ Git Commit / PR
        ▼
GitOps Repository
        │
        ▼
ArgoCD
        │
        ▼
Kubernetes

Với production, mình khuyên không nhất thiết cho Image Updater tự commit thẳng vào main.

Một mô hình an toàn hơn:

New Image
    ↓
Image Updater
    ↓
Pull Request
    ↓
Review
    ↓
Merge
    ↓
ArgoCD
    ↓
Production

Như vậy vẫn tự động hóa phần lớn công việc nhưng giữ lại human approval trước Production.


🎯 21. Tổng kết

Sau Lab này, bạn cần nhớ 3 thành phần có 3 nhiệm vụ khác nhau:

┌────────────────────┐
│ CI/CD              │
│ Build Image        │
└─────────┬──────────┘
          │
          ▼
┌────────────────────┐
│ Container Registry │
│ Store Image        │
└─────────┬──────────┘
          │
          ▼
┌────────────────────┐
│ Image Updater      │
│ Detect + Update Git│
└─────────┬──────────┘
          │
          ▼
┌────────────────────┐
│ GitOps Repository  │
│ Source of Truth    │
└─────────┬──────────┘
          │
          ▼
┌────────────────────┐
│ ArgoCD             │
│ Sync Git → K8s     │
└─────────┬──────────┘
          │
          ▼
┌────────────────────┐
│ Kubernetes         │
│ Run Application    │
└────────────────────┘

Một câu cần nhớ:

🚀 CI tạo Image → Image Updater cập nhật Git → ArgoCD đưa Git vào Kubernetes.

Đó chính là mảnh ghép giúp GitOps chuyển từ "deploy tự động" sang "quản lý version application một cách tự động và có kiểm soát".


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í