0

Lab 10 — ArgoCD Application & Project

🎯 Mục tiêu

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

  • Hiểu ApplicationAppProject khác nhau như thế nào.
  • Tạo một ArgoCD Application bằng YAML.
  • Tạo AppProject để giới hạn Git RepositoryKubernetes Namespace mà Application được phép sử dụng.
  • Hiểu cách dùng Project để tạo boundary/security cho môi trường DevOps thực tế.
  • Biết cách kiểm tra các lỗi thường gặp như InvalidSpec, PermissionDenied, OutOfSync.

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

Ở các lab trước, bạn đã dùng ArgoCD để deploy application.

Ví dụ:

Git Repository
      │
      ▼
    ArgoCD
      │
      ▼
 Kubernetes
      │
      └── todo-app

Ban đầu, bạn chỉ có một vài Application nên mọi thứ khá đơn giản.

Nhưng hãy tưởng tượng công ty có:

                    ArgoCD
                      │
        ┌─────────────┼─────────────┐
        ▼             ▼             ▼
      Team A        Team B        Team C
        │             │             │
       Dev          Staging        Prod

Nếu tất cả team đều có quyền:

Git Repository: *
Namespace: *
Cluster Resource: *

thì sẽ rất nguy hiểm.

Ví dụ Team A chỉ nên deploy:

GitHub:
    company/team-a/*

Kubernetes:
    team-a-dev

nhưng lại có quyền deploy:

production
kube-system
monitoring

thì một thay đổi sai có thể ảnh hưởng cả cluster.

Vì vậy chúng ta cần 2 khái niệm:

Application
    ↓
"Deploy cái gì và deploy ở đâu?"

AppProject
    ↓
"Application này được phép làm những gì?"

Đây chính là mục tiêu của lab này.


🧠 2. Hiểu nhanh

2.1. ArgoCD Application là gì?

Applicationmột đối tượng Kubernetes mà ArgoCD dùng để mô tả một ứng dụng cần được deploy.

Nó trả lời 3 câu hỏi:

1. Lấy manifest từ đâu?
2. Deploy vào đâu?
3. Dùng Project nào?

Ví dụ:

spec:
  project: todo-project

  source:
    repoURL: https://github.com/example/gitops.git
    path: apps/todo

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

Có thể hiểu:

Application
│
├── Project
│     └── todo-project
│
├── Source
│     └── GitHub → apps/todo
│
└── Destination
      └── Kubernetes → todo-app

ArgoCD sau đó liên tục so sánh trạng thái trong Git với trạng thái thực tế trong cluster. Nếu khác nhau, Application có thể ở trạng thái OutOfSync. ([Argo CD][1])


2.2. AppProject là gì?

Nếu Application nói:

"Tôi muốn deploy Todo App."

thì AppProject nói:

"Bạn được phép deploy Todo App ở đâu và từ đâu."

Ví dụ:

AppProject: todo-project

Allowed Git:
    github.com/company/todo-gitops

Allowed Namespace:
    todo-app

Allowed Cluster Resources:
    Không cho phép

Diagram:

                 AppProject
                     │
          ┌──────────┼──────────┐
          ▼          ▼          ▼
      Git Repo   Namespace   Resources
          │          │           │
          ▼          ▼           ▼
       Allowed    todo-app      Limited

Đây là lớp kiểm soát rất quan trọng khi ArgoCD được sử dụng bởi nhiều team. ArgoCD cho phép Project giới hạn repositories và destinations mà Application được phép sử dụng. ([Argo CD][2])


🏗️ 3. Architecture

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

                         GitHub
                           │
                           │
                    GitOps Repository
                           │
                           ▼
                    ┌─────────────┐
                    │   ArgoCD    │
                    │             │
                    │ Application │
                    └──────┬──────┘
                           │
                           │ uses
                           ▼
                    ┌─────────────┐
                    │ AppProject  │
                    │             │
                    │ Git: allowed│
                    │ Namespace:  │
                    │ todo-app    │
                    └──────┬──────┘
                           │
                           │ permission check
                           ▼
                    Kubernetes Cluster
                           │
                           ▼
                       todo-app

Flow quan trọng:

Application
     │
     ▼
"Deploy từ repo X vào namespace Y"
     │
     ▼
AppProject kiểm tra
     │
     ├── Repo X được phép? ──► YES
     │
     ├── Namespace Y được phép? ──► YES
     │
     └── Resource được phép? ──► YES
                                │
                                ▼
                              Sync

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

4.1. Kiểm tra ArgoCD

Nếu bạn đã hoàn thành các lab trước:

kubectl get pods -n argocd

Bạn cần thấy các component chính đang Running.

Ví dụ:

NAME                                               READY   STATUS
argocd-server-xxx                                  1/1     Running
argocd-repo-server-xxx                             1/1     Running
argocd-application-controller-xxx                  1/1     Running

Kiểm tra CLI:

argocd version --client

4.2. Kiểm tra Application hiện tại

argocd app list

Bạn có thể đã có Application từ các lab trước.

Ví dụ:

NAME       PROJECT    STATUS     HEALTH
todo-app   default     Synced     Healthy

Điểm đáng chú ý:

PROJECT
   ↓
default

Application hiện tại đang sử dụng Project mặc định.

Trong lab này chúng ta sẽ tạo Project riêng:

default
   ↓
todo-project

🧪 5. Tạo Namespace cho Todo App

Trước tiên tạo namespace:

kubectl create namespace todo-app

Kiểm tra:

kubectl get namespace todo-app

Kết quả:

NAME       STATUS
todo-app   Active

🧪 6. Tạo AppProject

🤔 Tại sao cần làm việc này?

Không nên để tất cả Application sử dụng default Project trong môi trường production.

Thay vào đó, chúng ta tạo:

todo-project

và giới hạn nó:

Git Repository
      ↓
chỉ GitOps repo của Todo App

Kubernetes
      ↓
chỉ namespace todo-app

6.1. Tạo file Project

Tạo:

argocd/
└── projects/
    └── todo-project.yaml

Nội dung:

apiVersion: argoproj.io/v1alpha1
kind: AppProject

metadata:
  name: todo-project
  namespace: argocd

spec:
  description: Project for Todo Application

  sourceRepos:
    - https://github.com/YOUR_USERNAME/YOUR_GITOPS_REPO.git

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

  clusterResourceWhitelist: []

Thay YOUR_USERNAME/YOUR_GITOPS_REPO bằng repository GitOps của bạn.


6.2. Apply Project

kubectl apply -f argocd/projects/todo-project.yaml

Kiểm tra:

kubectl get appproject -n argocd

Kết quả:

NAME           AGE
default        ...
todo-project   ...

🧠 7. Hiểu cấu hình AppProject

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

sourceRepos

sourceRepos:
  - https://github.com/YOUR_USERNAME/YOUR_GITOPS_REPO.git

Có nghĩa:

Application thuộc Project này chỉ được phép lấy manifest từ repository được khai báo.

Ví dụ Application cố tình sử dụng:

repoURL: https://github.com/random-user/malicious-repo.git

ArgoCD sẽ từ chối vì repository này không nằm trong sourceRepos.


destinations

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

Có nghĩa:

Application chỉ được deploy vào namespace todo-app trên cluster này.

Nếu Application muốn deploy vào:

kube-system

hoặc:

production

Project sẽ chặn.


clusterResourceWhitelist

clusterResourceWhitelist: []

Điều này rất đáng chú ý.

Application không được cấp quyền tạo các cluster-scoped resources thông qua whitelist này.

Ví dụ các resource như:

ClusterRole
ClusterRoleBinding
Namespace
CustomResourceDefinition

không nên mặc nhiên cho phép mọi team tạo.

Production tip: Đây là tư duy least privilege — chỉ cấp đúng quyền cần thiết, không cấp toàn cluster chỉ vì "cho dễ".


🧪 8. Tạo Application sử dụng Project

Bây giờ chúng ta tạo Application.

Tạo:

argocd/
└── applications/
    └── todo-app.yaml

Nội dung:

apiVersion: argoproj.io/v1alpha1
kind: Application

metadata:
  name: todo-app
  namespace: argocd

spec:
  project: todo-project

  source:
    repoURL: https://github.com/YOUR_USERNAME/YOUR_GITOPS_REPO.git
    targetRevision: main
    path: apps/todo

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

  syncPolicy:
    automated:
      prune: true
      selfHeal: true

Application directory thông thường có thể chứa plain Kubernetes YAML; ArgoCD cũng hỗ trợ Helm, Kustomize và các config-management tool khác. ([Argo CD][3])


🧪 9. Apply Application

kubectl apply -f argocd/applications/todo-app.yaml

Kiểm tra:

kubectl get application -n argocd

Bạn sẽ thấy:

NAME       SYNC STATUS   HEALTH STATUS
todo-app   Synced        Healthy

Hoặc kiểm tra bằng CLI:

argocd app get todo-app

👀 10. See Result trên ArgoCD

Mở ArgoCD UI:

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

Sau đó truy cập:

https://localhost:8080

Trong Application:

todo-app

Bạn sẽ thấy:

Project
   todo-project

Source
   GitHub
   apps/todo

Destination
   todo-app

Sync
   Synced

Health
   Healthy

Điều quan trọng là Application không còn thuộc default Project.


🧪 11. Thử phá Project để hiểu bản chất

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

Đừng chỉ tạo YAML rồi xem Synced.

Hãy thử tạo một Application vi phạm policy.

11.1. Sai Repository

Sửa:

repoURL: https://github.com/random-user/test.git

Apply:

kubectl apply -f argocd/applications/todo-app.yaml

Kiểm tra:

argocd app get todo-app

ArgoCD có thể báo lỗi liên quan đến repository không được Project cho phép.

Bản chất:

Application
     │
     │ repo = random-user/test
     ▼
todo-project
     │
     │ sourceRepos?
     ▼
    ❌ NO
     │
     ▼
  DENIED

🧪 12. Thử deploy vào Namespace khác

Đổi:

destination:
  server: https://kubernetes.default.svc
  namespace: default

Apply:

kubectl apply -f argocd/applications/todo-app.yaml

Kiểm tra:

argocd app get todo-app

Lúc này Project sẽ không cho phép Application deploy vào default.

Bởi vì:

destinations:
  - namespace: todo-app

chỉ cho phép:

todo-app

không phải:

default

🧠 13. Application vs AppProject

Đây là điểm bạn nên nhớ.

Application AppProject
Mục đích Mô tả application Kiểm soát quyền
Git Repository Chọn repo/path Giới hạn repo
Namespace Chọn namespace Giới hạn namespace
Cluster Chọn cluster Giới hạn cluster
Resource Deploy resources Có thể giới hạn resources
Scope Một application Một nhóm applications

Có thể nhớ bằng câu:

Application nói "deploy gì". Project nói "được phép deploy ở đâu".


🏗️ 14. Mô hình nhiều Team

Trong production, bạn có thể tổ chức:

                       ArgoCD
                          │
          ┌───────────────┼───────────────┐
          │               │               │
          ▼               ▼               ▼
    team-a-project  team-b-project  platform-project
          │               │               │
          ▼               ▼               ▼
       team-a           team-b         platform
       namespace        namespace      namespace

Ví dụ:

team-a-project
├── repo: github.com/company/team-a/*
└── namespace: team-a-*

team-b-project
├── repo: github.com/company/team-b/*
└── namespace: team-b-*

platform-project
├── repo: github.com/company/platform/*
└── namespace: monitoring

Như vậy:

Team A
   ├── deploy Team A
   └── ❌ không deploy Production

Team B
   ├── deploy Team B
   └── ❌ không deploy Team A

Platform Team
   ├── monitoring
   ├── ingress
   └── infrastructure

Đây mới là lý do AppProject thực sự hữu ích trong môi trường doanh nghiệp.


🔐 15. Production Tip — Đừng dùng default Project cho mọi thứ

default Project rất tiện khi học:

Lab
 ↓
default project
 ↓
Application

Nhưng khi hệ thống lớn hơn:

Production
     ↓
nhiều Team
     ↓
nhiều Application

nên tạo Project riêng:

team-a
team-b
team-c
platform
monitoring

và giới hạn:

Source Repository
        +
Destination
        +
Resource Permission

Điều này giúp giảm blast radius — tức là khi một team hoặc một cấu hình bị sai, phạm vi ảnh hưởng được giới hạn.


🧪 16. Exercise 1 — Tạo Project cho Backend

Tạo:

backend-project

Yêu cầu:

Git Repository:
    GitOps repository của bạn

Namespace:
    todo-app

Cluster:
    local Kubernetes cluster

Sau đó tạo:

backend-app

và cho Application sử dụng:

project: backend-project

Kiểm tra

argocd app list

Kỳ vọng:

NAME           PROJECT           STATUS
backend-app    backend-project   Synced

🧪 17. Exercise 2 — Test Permission

Thử thay đổi Application:

namespace: default

và kiểm tra:

argocd app get backend-app

Câu hỏi

Tại sao Application không thể deploy vào default?

Gợi ý:

Nhìn vào:

spec:
  destinations:

của AppProject.


🧪 18. Exercise 3 — Multi-Team

Tạo:

team-a-project
team-b-project

Mô hình:

team-a-project
└── namespace: team-a

team-b-project
└── namespace: team-b

Sau đó tạo:

team-a-app
team-b-app

Kỳ vọng:

team-a-app
    │
    └── team-a-project
            │
            └── team-a namespace


team-b-app
    │
    └── team-b-project
            │
            └── team-b namespace

Cuối cùng thử cho:

team-a-app

deploy vào:

team-b

và quan sát kết quả.


🧪 19. Troubleshooting

Application is invalid

Kiểm tra:

argocd app get todo-app

Sau đó kiểm tra Project:

kubectl get appproject todo-project -n argocd -o yaml

Đặc biệt kiểm tra:

sourceRepos:
destinations:

❌ Repository không được phép

Nếu thấy lỗi liên quan đến:

repository is not permitted

kiểm tra:

spec:
  sourceRepos:

Repository trong Application phải match repository được Project cho phép.


❌ Namespace không được phép

Nếu thấy lỗi tương tự:

destination is not permitted

kiểm tra:

spec:
  destinations:

Ví dụ Project chỉ cho:

destinations:
  - namespace: todo-app

thì Application không thể deploy vào:

default
production
monitoring

❌ Application OutOfSync

Đầu tiên:

argocd app get todo-app

Sau đó:

argocd app diff todo-app

Bạn cần phân biệt:

OutOfSync
    ≠
Deployment Failed

OutOfSync chỉ có nghĩa:

Git Desired State
       ≠
Cluster Live State

ArgoCD phát hiện sự khác biệt giữa desired state trong Git và live state trong Kubernetes. ([Argo CD][1])


💡 20. Production Tips

① Không cấp quyền quá rộng

Tránh:

sourceRepos:
  - '*'

destinations:
  - namespace: '*'
    server: '*'

nếu không thực sự cần.

Thay vào đó:

Allowed Repository
        +
Allowed Namespace
        +
Allowed Resources

② Tách Project theo boundary

Thay vì:

one-project
└── 100 applications

có thể tổ chức:

platform-project
team-a-project
team-b-project
monitoring-project

Từ đó dễ quản lý quyền và giảm blast radius.


③ Project cũng nên được quản lý bằng Git

Đừng tạo Project production thủ công mãi bằng:

kubectl apply ...

Mục tiêu cuối cùng của GitOps là:

Git
 │
 ├── Applications
 ├── AppProjects
 ├── Helm
 ├── Kustomize
 └── Policies
        │
        ▼
      ArgoCD
        │
        ▼
   Kubernetes

Như vậy cấu hình quyền cũng có history:

Who changed?
When?
Why?
What changed?

④ Cẩn thận với prune

Ở các lab trước bạn có thể đã sử dụng:

automated:
  prune: true

Prune có nghĩa ArgoCD có thể xóa resource không còn tồn tại trong desired state. ArgoCD mặc định không tự động prune trong automated sync nếu bạn chưa bật tùy chọn này. ([Argo CD][4])

Trong production, nên đặc biệt cẩn thận với:

prune: true

nhất là khi repository hoặc path có thể bị thay đổi ngoài ý muốn.


🧠 21. Tổng kết

Sau lab này, hãy nhớ mô hình:

                 ArgoCD
                    │
        ┌───────────┴───────────┐
        │                       │
   Application              AppProject
        │                       │
        │                       │
   "Deploy gì?"          "Được phép làm gì?"
        │                       │
        ▼                       ▼
    Git Source             Permissions
    Destination             Repository
    Sync Policy              Namespace
                             Resources

Hay đơn giản hơn:

Application = What + Where AppProject = Where you're allowed to go

Trong GitOps production:

Developer
    │
    ▼
Git
    │
    ▼
Application
    │
    ▼
AppProject
    │
    ├── Repository allowed?
    ├── Destination allowed?
    └── Resource allowed?
             │
             ▼
           ArgoCD
             │
             ▼
        Kubernetes

Đây là nền tảng để bước sang các bài tiếp theo như GitOps CI/CD Pipeline, Image Automation, ApplicationSet và App of Apps. ArgoCD cũng sử dụng Application làm nền tảng cho các cơ chế quản lý nhiều application như ApplicationSet.


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í