Lab 7 — GitOps với Helm + ArgoCD
🎯 Mục tiêu
Sau lab này, bạn sẽ:
- Hiểu Helm đóng vai trò gì trong GitOps.
- Biết cách tổ chức một Helm Chart trong Git repository.
- Biết cách để ArgoCD render và deploy Helm Chart.
- Biết cách quản lý
values.yamlcho Kubernetes Application. - Thực hành thay đổi configuration trong Git và để ArgoCD tự động cập nhật Kubernetes.
- Hiểu một số cách tổ chức Helm + GitOps thường gặp trong production.
🤔 1. Vấn đề thực tế
Ở các lab trước, chúng ta đã biết ArgoCD có thể lấy Kubernetes manifests từ Git:
Git Repository
│
│ YAML
▼
ArgoCD
│
▼
Kubernetes
Ví dụ:
kubernetes/
├── deployment.yaml
├── service.yaml
├── configmap.yaml
└── ingress.yaml
Cách này hoạt động tốt.
Nhưng hãy tưởng tượng application của bạn có:
Deployment
Service
ConfigMap
Ingress
HPA
ServiceAccount
Secret
...
Và bạn có:
dev
staging
production
Lúc này số lượng YAML sẽ tăng rất nhanh.
Ví dụ:
dev/
├── deployment.yaml
├── service.yaml
├── ingress.yaml
staging/
├── deployment.yaml
├── service.yaml
├── ingress.yaml
production/
├── deployment.yaml
├── service.yaml
├── ingress.yaml
Bạn sẽ bắt đầu gặp vấn đề:
"Tôi chỉ muốn thay đổi image version, tại sao phải sửa rất nhiều YAML?"
Đây là lúc Helm trở nên hữu ích.
🧠 2. Hiểu nhanh: Helm + GitOps
2.1 Helm giải quyết vấn đề gì?
Helm cho phép chúng ta tạo template cho Kubernetes manifests.
Thay vì viết:
image: my-app:1.0.0
replicas: 2
ta có thể viết:
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
replicas: {{ .Values.replicaCount }}
Sau đó configuration được đưa vào:
replicaCount: 3
image:
repository: my-app
tag: "2.0.0"
Helm sẽ render thành Kubernetes YAML hoàn chỉnh.
2.2 Helm Chart là gì?
Có thể hiểu đơn giản:
Helm Chart = một package chứa template Kubernetes + configuration.
Ví dụ:
my-app/
├── Chart.yaml
├── values.yaml
└── templates/
├── deployment.yaml
├── service.yaml
└── ingress.yaml
Trong đó:
Chart.yaml
│
│ Metadata
▼
Helm Chart
values.yaml
│
│ Configuration
▼
templates/
│
│ Render
▼
Kubernetes YAML
2.3 Vậy ArgoCD làm gì?
ArgoCD không thay thế Helm.
Hai công cụ có nhiệm vụ khác nhau:
Git
│
▼
Helm Chart
│
│ Render
▼
Kubernetes YAML
│
▼
ArgoCD
│
│ Sync
▼
Kubernetes
Helm = package/template application
ArgoCD = GitOps deployment engine
Đây là điểm rất quan trọng.
Helm giúp chúng ta tạo Kubernetes manifests linh hoạt. ArgoCD đảm bảo Kubernetes luôn khớp với trạng thái được định nghĩa trong Git.
ArgoCD hỗ trợ Helm Charts như một trong những cách chính để tạo desired state cho application. (Argo CD)
🏗️ 3. Architecture
Trong lab này chúng ta xây dựng:
Developer
│
│ git push
▼
┌─────────────────┐
│ Git Repository │
│ │
│ Helm Chart │
│ ├── Chart.yaml │
│ ├── values.yaml │
│ └── templates/ │
└────────┬────────┘
│
│ Watch
▼
┌──────────────┐
│ ArgoCD │
│ │
│ Helm Render │
│ Sync │
└──────┬───────┘
│
│ Apply
▼
┌─────────────────┐
│ Kubernetes │
│ │
│ Deployment │
│ Service │
│ Pod │
└─────────────────┘
Flow quan trọng nhất:
Git
↓
Helm Chart
↓
ArgoCD
↓
Helm Render
↓
Kubernetes
🧪 4. Chuẩn bị môi trường
4.1 Kiểm tra Kubernetes
kubectl get nodes
Kết quả mong muốn:
NAME STATUS ROLES AGE
minikube Ready control-plane ...
4.2 Kiểm tra Helm
helm version
Ví dụ:
version.BuildInfo{
Version:"v3.x.x",
...
}
4.3 Kiểm tra ArgoCD
kubectl get pods -n argocd
Bạn cần thấy các component của ArgoCD đang Running.
Ví dụ:
NAME READY STATUS
argocd-server 1/1 Running
argocd-repo-server 1/1 Running
argocd-application-controller 1/1 Running
Nếu chưa cài ArgoCD, hãy hoàn thành Lab 3 — Install ArgoCD trước. Cách cài đặt chính thức hiện tại của ArgoCD sử dụng namespace argocd và manifest cài đặt chính thức. (Argo CD)
🧱 5. Tạo Helm Chart
🧠 Explain
Thay vì tự tạo hàng loạt file Kubernetes YAML, chúng ta sẽ để Helm quản lý chúng.
Tạo chart:
helm create todo-app
Kiểm tra:
cd todo-app
tree
Bạn sẽ thấy cấu trúc tương tự:
todo-app/
├── Chart.yaml
├── values.yaml
├── charts/
└── templates/
├── deployment.yaml
├── service.yaml
├── ingress.yaml
├── serviceaccount.yaml
├── hpa.yaml
└── ...
Helm đã tạo sẵn rất nhiều template.
Trong lab này, chúng ta không cần tất cả.
🧹 6. Tối giản Helm Chart
🧠 Explain
Khi học Helm, đừng cố học thuộc toàn bộ cấu trúc mà Helm generate.
Chúng ta chỉ cần hiểu:
Chart.yaml
↓
Thông tin Chart
values.yaml
↓
Configuration
templates/
↓
Kubernetes resources
Xóa các template không cần thiết:
rm -f templates/ingress.yaml
rm -f templates/hpa.yaml
rm -f templates/serviceaccount.yaml
rm -f templates/tests/*
Giữ lại:
todo-app/
├── Chart.yaml
├── values.yaml
└── templates/
├── deployment.yaml
└── service.yaml
⚙️ 7. Tạo values.yaml
🧠 Explain
values.yaml là nơi chúng ta đưa configuration ra khỏi Kubernetes template.
Ví dụ:
replicaCount: 2
image:
repository: nginx
tag: "1.27"
service:
type: ClusterIP
port: 80
Điều này giúp chúng ta thay đổi configuration mà không phải sửa template.
Ví dụ:
dev
replicaCount: 1
image.tag: "1.27"
Trong production:
production
replicaCount: 3
image.tag: "1.28"
Template vẫn giữ nguyên.
✍️ 8. Tạo values.yaml
Thay nội dung values.yaml bằng:
replicaCount: 2
image:
repository: nginx
tag: "1.27"
service:
type: ClusterIP
port: 80
📦 9. Tạo Deployment Template
Mở:
templates/deployment.yaml
Thay bằng:
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Release.Name }}
template:
metadata:
labels:
app: {{ .Release.Name }}
spec:
containers:
- name: nginx
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
ports:
- containerPort: 80
📡 10. Tạo Service Template
Mở:
templates/service.yaml
Thay bằng:
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}
spec:
type: {{ .Values.service.type }}
selector:
app: {{ .Release.Name }}
ports:
- port: {{ .Values.service.port }}
targetPort: 80
🔍 11. Kiểm tra Helm Render
🧠 Explain
Đây là bước cực kỳ quan trọng.
Trước khi để ArgoCD deploy, hãy hiểu Helm thực sự tạo ra cái gì.
Chạy:
helm template todo-app .
Bạn sẽ thấy Helm biến:
replicas: {{ .Values.replicaCount }}
thành:
replicas: 2
Và:
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
thành:
image: "nginx:1.27"
Mental Model
values.yaml
│
▼
Helm Template
│
▼
Kubernetes YAML
Helm không trực tiếp chạy Pod.
Nó chủ yếu giúp tạo ra Kubernetes manifests.
🧪 12. Kiểm tra bằng helm lint
Chạy:
helm lint .
Nếu thành công:
1 chart(s) linted, 0 chart(s) failed
Nếu có lỗi YAML hoặc cấu trúc Chart, Helm sẽ báo ở đây.
Tip:
helm lintnên được chạy trong CI trước khi merge Pull Request.
📦 13. Đưa Helm Chart vào Git
🧠 Explain
GitOps yêu cầu:
Git phải chứa desired state của hệ thống.
Vì vậy Helm Chart cũng phải nằm trong Git.
Ví dụ repository:
gitops-repo/
│
└── apps/
└── todo-app/
├── Chart.yaml
├── values.yaml
└── templates/
├── deployment.yaml
└── service.yaml
Commit:
git add .
git commit -m "feat: add todo app helm chart"
git push
🚀 14. Tạo ArgoCD Application
🧠 Explain
Bây giờ Git đã chứa Helm Chart.
Chúng ta cần nói cho ArgoCD biết:
"Hãy lấy Chart này từ repository và deploy nó vào Kubernetes."
Tạo:
argocd/todo-app.yaml
Nội dung:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: todo-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/YOUR_USERNAME/YOUR_GITOPS_REPO.git
targetRevision: main
path: apps/todo-app
destination:
server: https://kubernetes.default.svc
namespace: todo-app
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
Thay:
YOUR_USERNAME
YOUR_GITOPS_REPO
bằng repository thật của bạn.
ArgoCD Application dùng source để xác định Git repository/path và destination để xác định Kubernetes cluster/namespace cần deploy. (Argo CD)
🧠 15. Điều gì đang xảy ra?
Đây là phần quan trọng nhất của lab.
Khi bạn:
kubectl apply -f argocd/todo-app.yaml
ArgoCD sẽ:
GitHub
│
│ Pull
▼
┌─────────────────┐
│ Helm Chart │
│ │
│ Chart.yaml │
│ values.yaml │
│ templates/ │
└────────┬────────┘
│
│ Helm render
▼
Kubernetes manifests
│
▼
ArgoCD
│
│ Sync
▼
Kubernetes
ArgoCD hỗ trợ nhiều kiểu source như plain manifests, Kustomize và Helm. (Argo CD)
▶️ 16. Deploy Application
Apply Application:
kubectl apply -f argocd/todo-app.yaml
Kiểm tra:
kubectl get applications -n argocd
Bạn có thể thấy:
NAME SYNC STATUS HEALTH STATUS
todo-app Synced Healthy
Kiểm tra Kubernetes:
kubectl get all -n todo-app
Kết quả tương tự:
NAME READY
pod/todo-app-xxxxxxxxxx-xxxxx 1/1
pod/todo-app-xxxxxxxxxx-yyyyy 1/1
NAME TYPE CLUSTER-IP
service/todo-app ClusterIP 10.x.x.x
👀 17. Xem Application trên ArgoCD
Port-forward ArgoCD:
kubectl port-forward svc/argocd-server \
-n argocd 8080:443
Mở:
https://localhost:8080
Bạn sẽ thấy:
┌─────────────────────────────┐
│ todo-app │
│ │
│ Synced Healthy │
│ │
│ ┌──────────────┐ │
│ │ Deployment │ │
│ └──────┬───────┘ │
│ │ │
│ Pods │
│ │ │
│ Service │
│ │
└─────────────────────────────┘
Đây là lúc GitOps bắt đầu trở nên rất trực quan:
Git nói application phải như thế nào → ArgoCD đảm bảo Kubernetes đúng như vậy.
🔄 18. Thay đổi Application bằng Git
Bây giờ chúng ta thử điều tuyệt vời nhất.
Mở:
values.yaml
Thay:
replicaCount: 2
thành:
replicaCount: 4
Commit:
git add values.yaml
git commit -m "scale todo app to 4 replicas"
git push
👀 19. See Result
Kiểm tra:
kubectl get pods -n todo-app
Bạn sẽ thấy số lượng Pod tăng lên:
NAME READY
todo-app-xxxxx-xxxxx 1/1
todo-app-xxxxx-yyyyy 1/1
todo-app-xxxxx-zzzzz 1/1
todo-app-xxxxx-aaaaa 1/1
Hoặc:
kubectl get deployment -n todo-app
NAME READY UP-TO-DATE AVAILABLE
todo-app 4/4 4 4
Bạn không cần chạy:
kubectl scale deployment ...
Bạn chỉ thay đổi Git.
🧠 20. Tại sao điều này quan trọng?
So sánh hai cách.
❌ Cách thủ công
Developer
│
│ kubectl scale
▼
Kubernetes
Vấn đề:
Git ──────────── Kubernetes
❌ lệch nhau
Git nói:
replicas: 2
Kubernetes thực tế:
replicas: 4
✅ GitOps
Developer
│
│ git push
▼
Git
│
▼
ArgoCD
│
▼
Kubernetes
Bây giờ:
Git
│
│ Desired State
▼
ArgoCD
│
│ Reconcile
▼
Kubernetes
Git trở thành Source of Truth.
🩹 21. Thử Self-Healing
Đây là một bài test rất đáng làm.
Chạy:
kubectl scale deployment todo-app \
-n todo-app \
--replicas=1
Kiểm tra:
kubectl get deployment -n todo-app
Ban đầu:
READY
1/1
Nhưng hãy chờ một chút.
ArgoCD phát hiện:
Git desired state:
replicas = 4
Kubernetes:
replicas = 1
Sau đó ArgoCD sẽ đưa cluster trở lại:
replicas = 4
Kiểm tra:
kubectl get deployment todo-app -n todo-app
READY
4/4
Đây chính là Self-Healing.
🔥 22. Một thay đổi khác: Image Version
Tiếp tục sửa:
image:
repository: nginx
tag: "1.28"
Commit:
git add values.yaml
git commit -m "chore: upgrade nginx image"
git push
Flow:
values.yaml
│
│ git push
▼
GitHub
│
▼
ArgoCD
│
│ Helm render
▼
image: nginx:1.28
│
▼
Kubernetes
Bạn có thể kiểm tra:
kubectl describe deployment todo-app -n todo-app
🎛️ 23. Quản lý nhiều Environment
Đây mới là nơi Helm thực sự hữu ích trong GitOps.
Giả sử có:
dev
staging
production
Ta không muốn copy toàn bộ Chart ba lần.
Thay vào đó:
apps/
└── todo-app/
├── Chart.yaml
├── templates/
│ ├── deployment.yaml
│ └── service.yaml
│
└── values/
├── dev.yaml
├── staging.yaml
└── production.yaml
Ví dụ:
dev.yaml
replicaCount: 1
image:
repository: nginx
tag: "1.27"
staging.yaml
replicaCount: 2
image:
repository: nginx
tag: "1.27"
production.yaml
replicaCount: 4
image:
repository: nginx
tag: "1.28"
Concept:
Helm Chart
│
┌──────────┼──────────┐
▼ ▼ ▼
dev staging production
│ │ │
1 Pod 2 Pods 4 Pods
⚙️ 24. Override Helm Values trong ArgoCD
ArgoCD có thể truyền Helm values khi render application.
Ví dụ:
spec:
source:
repoURL: https://github.com/YOUR_USERNAME/YOUR_GITOPS_REPO.git
targetRevision: main
path: apps/todo-app
helm:
valueFiles:
- values/production.yaml
Điều này cho phép:
Same Chart
│
├── values/dev.yaml
│
├── values/staging.yaml
│
└── values/production.yaml
Mỗi environment sử dụng configuration riêng.
Helm hỗ trợ nhiều file values và file được chỉ định sau sẽ có độ ưu tiên cao hơn file trước. (Helm Blog)
🧩 25. Một Pattern tốt hơn cho Production
Một GitOps repository có thể được tổ chức như:
gitops/
│
├── apps/
│ └── todo-app/
│ ├── Chart.yaml
│ ├── templates/
│ │ ├── deployment.yaml
│ │ └── service.yaml
│ │
│ └── values/
│ ├── dev.yaml
│ ├── staging.yaml
│ └── production.yaml
│
└── argocd/
├── todo-app-dev.yaml
├── todo-app-staging.yaml
└── todo-app-production.yaml
Architecture:
Git
│
┌─────────┼─────────┐
│ │ │
Dev Staging Prod
│ │ │
▼ ▼ ▼
ArgoCD ArgoCD ArgoCD
│ │ │
▼ ▼ ▼
Kubernetes Kubernetes Kubernetes
⚠️ 26. Một số lỗi thường gặp
❌ ArgoCD báo OutOfSync
Đừng lập tức chạy:
kubectl apply
Hãy hỏi:
Git đang muốn gì và Kubernetes đang có gì?
Kiểm tra:
argocd app get todo-app
Sau đó xem:
Desired State
vs
Live State
❌ Helm chạy được nhưng ArgoCD fail
Trước tiên test:
helm lint .
Sau đó:
helm template todo-app .
Nếu Helm render đã lỗi thì vấn đề nằm ở Chart.
Nếu Helm render thành công nhưng ArgoCD lỗi, hãy kiểm tra:
Repository
Path
Revision
Values
Destination
Permissions
❌ Sửa trực tiếp Kubernetes
Ví dụ:
kubectl edit deployment todo-app -n todo-app
Đây là điều nên tránh trong GitOps.
Vì:
Git:
replicas = 2
Kubernetes:
replicas = 5
Bạn đã tạo ra configuration drift.
Nếu thay đổi là thay đổi chính thức:
Edit Git
↓
Commit
↓
Pull Request
↓
Review
↓
ArgoCD
↓
Kubernetes
💡 27. Production Tips
① Không copy Helm Chart cho từng environment
❌ Không nên:
todo-dev-chart/
todo-staging-chart/
todo-prod-chart/
Thường tốt hơn:
One Chart
+
Different Values
② Không nhét mọi thứ vào values.yaml
values.yaml nên chứa configuration.
Không nên biến nó thành một file chứa toàn bộ application logic.
③ Pin version
Thay vì:
image:
tag: latest
nên dùng:
image:
tag: "1.28.3"
Production cần biết chính xác version nào đang chạy.
④ Production nên đi qua Pull Request
Flow tốt:
Developer
│
▼
Git Push
│
▼
Pull Request
│
▼
Review
│
▼
Merge
│
▼
ArgoCD
│
▼
Production
Điều này tạo ra:
- Audit history
- Code review
- Rollback dễ dàng
- Không cần SSH vào production để deploy
Đó cũng chính là một trong những giá trị cốt lõi của GitOps: application configuration và environment được version-control, deployment có thể audit và tự động hóa. (Argo CD)
🧪 28. Exercise
Exercise 1 — Thay đổi Replica
Thay:
replicaCount: 2
thành:
replicaCount: 3
Commit → Push.
Kiểm tra:
kubectl get pods -n todo-app
Mục tiêu:
3 Pods
Exercise 2 — Thay đổi Image
Đổi:
tag: "1.27"
sang một version khác.
Kiểm tra:
kubectl describe deployment todo-app -n todo-app
Tìm:
Image:
Exercise 3 — Test Self-Healing
Scale thủ công:
kubectl scale deployment todo-app \
-n todo-app \
--replicas=1
Chờ ArgoCD reconcile.
Kiểm tra:
kubectl get deployment -n todo-app
Mục tiêu:
3/3
nếu Git đang khai báo:
replicaCount: 3
Exercise 4 — Tạo Staging Environment
Tạo:
values/staging.yaml
với:
replicaCount: 2
image:
repository: nginx
tag: "1.28"
Tạo một ArgoCD Application riêng:
todo-app-staging
Deploy vào:
todo-staging
Kết quả:
Git
│
┌───────┴────────┐
│ │
production staging
│ │
▼ ▼
ArgoCD ArgoCD
│ │
▼ ▼
todo-app-prod todo-app-staging
🧠 29. Tổng kết bản chất
Sau lab này, bạn không cần học thuộc hàng chục câu lệnh Helm.
Chỉ cần nhớ 4 thành phần:
Chart
↓
Templates
Values
↓
Configuration
Helm
↓
Render Kubernetes manifests
ArgoCD
↓
Sync Git → Kubernetes
Hay nhớ bằng một câu:
Helm quyết định Kubernetes manifest được tạo như thế nào; ArgoCD quyết định manifest đó được đồng bộ xuống Kubernetes như thế nào.
Flow cuối cùng:
Developer
│
│ git push
▼
┌─────────────────┐
│ Git Repository │
│ │
│ Helm Chart │
│ values.yaml │
│ templates/ │
└────────┬────────┘
│
▼
ArgoCD
│
│ Helm Render
▼
Kubernetes Manifest
│
│ Sync
▼
┌─────────────────┐
│ Kubernetes │
│ │
│ Deployment │
│ Service │
│ Pods │
└─────────────────┘
🎓 Sau Lab 7
Bạn đã đi từ:
Lab 1–5
Kubernetes + GitOps fundamentals
↓
Lab 6
Kustomize
↓
Lab 7
Helm + ArgoCD
Ở Lab 8 — Environment Management, chúng ta sẽ giải quyết bài toán lớn hơn:
Làm thế nào quản lý Dev / Staging / Production mà không copy-paste Kubernetes configuration?
Đây là bước rất quan trọng để chuyển từ một GitOps lab đơn giản sang GitOps architecture thực tế.
All rights reserved