
如果手邊只有一個 K8s 叢集,更新頻率不高,使用 kubectl apply 手動部署其實就足夠了。但當架構規模擴大,遇到以下場景時,手動操作就會開始顯得捉襟見肘:
kubectl context 容易導致操作失誤這時候,引入 GitOps + Argo CD 就能有效解決這些痛點。
其核心邏輯非常直觀:「將部署的操作自動化,減少人為介入」。
這篇筆記主要紀錄建置這套流程的關鍵步驟,包含:使用 Helm 安裝 Argo CD、設定 GitLab SSO,以及如何妥善規劃權限管理。
這邊不談太多理論,但有一個觀念至關重要。
傳統的部署方式往往缺乏標準化,每個人手動 apply 的內容可能不盡相同,久而久之環境會產生「漂移」 (Drift),難以追溯。 GitOps 將 Git 視為「標準 SOP」,而 Argo CD 則是執行者。它會確保叢集的實際狀態 (Live State) 永遠與 Git 倉庫中的定義 (Desired State) 保持一致。如果有人手動修改了叢集資源,Argo CD 會偵測到差異並標示為 OutOfSync,甚至可以設定自動修復 (Self-healing) 將其還原。
理解這點後,接下來的設定步驟會更有脈絡。
(前置作業如 Helm Repo 添加這裡就跳過了,直接進入 SSO 和權限設定的重頭戲)
這步很簡單,先把 Helm 的 repo 加進來,然後把 Argo CD 的預設 values.yaml 匯出來,等等直接改。
# 新增 Helm repository helm repo add argo https://argoproj.github.io/argo-helm helm repo update # 匯出預設 values 供修改使用 helm show values argo/argo-cd --version 8.3.2 > values.yaml
這一步是為了建立 Argo CD 與 GitLab 之間的信任關係。透過在 GitLab 設定 Application,讓使用者能直接使用 GitLab 帳號登入 Argo CD,便於帳號統一管理。
Settings → ApplicationsArgoCD SSOhttp://<your-node-ip>:32009/api/dex/callbackopenid, read_user, email⚠️ 記得 Client ID 和 Secret 不要丟進 Git 倉庫。
設定方式有兩種:
A. 直接寫進 values.yaml(推薦,方便自動化) B. 安裝完後進 Argo CD UI 補設定(適合臨時調整)
Argo CD 需要存取 Git 倉庫的權限來拉取程式碼。 強烈建議不要使用個人帳號的 Token,以免人員異動或密碼變更導致正式環境的部署中斷。最佳實踐是申請一個專用的 Group Access Token。
Settings → Access Tokens。argocd-group-readonlyread_repository 和 read_api 就好,權限越小越安全。Reporter(能讀就好)。這是關鍵的一步。我們會建立一份自定義的 values.yaml,將前面取得的 SSO 和 Repo 資訊填入,覆蓋 Helm 的預設設定。
configs:
cm:
# 這裡填 Argo CD 的入口網址,SSO callback 會用到
url: http://<your-node-ip>:32009
# 這是最容易卡關的地方:Dex (SSO) 設定
dex.config: |
connectors:
- type: gitlab
id: gitlab
name: GitLab
config:
baseURL: https://gitlab.example.com
clientID: <your-gitlab-oauth-client-id>
clientSecret: <your-gitlab-oauth-client-secret>
# 記得要去 GitLab Application 設定裡把這個 Callback URL 填對
redirectURI: http://<your-node-ip>:32009/api/dex/callback
# 這裡把剛剛申請的 Token 填進去,讓 Argo CD 認得你的 GitLab
credentialTemplates:
gitlab-group-token:
url: https://gitlab.example.com
username: oauth2 # 固定寫 oauth2 即可
password: <your-gitlab-group-access-token>
# 預先註冊 Repo,省得之後在 UI 一個一個加
repositories:
kong-api-gateway:
url: https://gitlab.example.com/your-group/kong-api-gateway.git
type: git
argocd-deployment:
url: https://gitlab.example.com/your-group/argocd-deployment.git
type: git
# Server 網路設定 (Lab 環境偷懶用 NodePort,正式環境請上 Ingress)
server:
service:
type: NodePort
nodePortHttp: 32009
nodePortHttps: 32010
# 開發環境允許 HTTP,不然會一直跳憑證錯誤
extraArgs:
- --insecure
💡 生產環境建議:Ingress + TLS 取代 NodePort,並移除
--insecure。
設定檔都準備好後,直接開工:
# 安裝 Argo CD
helm upgrade --install homelab-argo argo/argo-cd \
--version 8.3.2 \
-f values.yaml \
-n argocd --create-namespace
# 等 Pod 跑起來
kubectl wait --for=condition=ready pod \
-l app.kubernetes.io/name=argocd-server \
-n argocd --timeout=300s
# 拿初始 admin 密碼
kubectl -n argocd get secret argocd-initial-admin-secret \
-o jsonpath="{.data.password}" | base64 -d
第一次登入記得馬上改 admin 密碼。
Argo CD 安裝完成後,還需要定義「誰可以管理哪些資源」以及「可以部署到哪些叢集」。AppProject 機制類似於權限白名單,若未正確設定,Argo CD 將無法進行任何部署操作。
建立 argocd-projects.yaml:
apiVersion: v1
kind: List
items:
# Default Project - 基本權限
- apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: default
namespace: argocd
spec:
# 允許所有來源 repo
sourceRepos:
- '*'
# 允許部署到所有叢集與 namespace
destinations:
- namespace: '*'
server: '*'
# 允許操作集群級資源
clusterResourceWhitelist:
- group: '*'
kind: '*'
# 允許操作命名空間級資源
namespaceResourceWhitelist:
- group: '*'
kind: '*'
# 自訂 Project - 依需求調整
- apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: your-project
namespace: argocd
spec:
description: 你的專案描述
sourceRepos:
- 'https://gitlab.example.com/your-group/*'
destinations:
- namespace: '*'
server: https://kubernetes.default.svc
# 集群級資源白名單
clusterResourceWhitelist:
- group: ''
kind: Namespace
- group: 'rbac.authorization.k8s.io'
kind: ClusterRole
- group: 'rbac.authorization.k8s.io'
kind: ClusterRoleBinding
- group: 'apiextensions.k8s.io'
kind: CustomResourceDefinition
# 命名空間級資源白名單
namespaceResourceWhitelist:
- group: ''
kind: ConfigMap
- group: ''
kind: Secret
- group: ''
kind: Service
- group: ''
kind: ServiceAccount
- group: 'apps'
kind: Deployment
- group: 'apps'
kind: StatefulSet
- group: 'batch'
kind: Job
- group: 'batch'
kind: CronJob
- group: 'networking.k8s.io'
kind: Ingress
# Argo CD Controller 額外的 RBAC 權限(支援 metrics-server 等)
- apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: argocd-application-controller-auth-delegator
labels:
app.kubernetes.io/component: application-controller
app.kubernetes.io/name: argocd-application-controller
app.kubernetes.io/part-of: argocd
rules:
# Auth delegation for metrics-server
- apiGroups: ["authentication.k8s.io"]
resources: ["tokenreviews"]
verbs: ["create"]
- apiGroups: ["authorization.k8s.io"]
resources: ["subjectaccessreviews"]
verbs: ["create"]
# API Services management
- apiGroups: ["apiregistration.k8s.io"]
resources: ["apiservices"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: argocd-application-controller-auth-delegator
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: argocd-application-controller-auth-delegator
subjects:
- kind: ServiceAccount
name: argocd-application-controller
namespace: argocd
# 套用 AppProject 跟 RBAC 設定 kubectl apply -f argocd-projects.yaml -n argocd # 看 Project 有沒有建起來 kubectl get appprojects -n argocd # RBAC 權限也查一下 kubectl get clusterrole | grep argocd kubectl get clusterrolebinding | grep argocd
Argo CD 與 GitLab 整合時,權限主要分為三個層次:
💡 SSO 管「人」、Group Token 管「程式碼」、Registry Token 管「映像檔」。
這張圖是 Argo CD 的 Application 狀態頁,主要觀察以下重點指標:
testapp用 GitOps 部署的 K8s 資源樹大致長這樣:
📌 只要右上角顯示為 ✅ 綠色狀態,即代表部署成功。
這裡整理了日常維運可能用到的指令,方便快速查閱。
# 安裝 Helm(Windows) choco install kubernetes-helm # 安裝/升級 Argo CD helm upgrade --install argocd argo/argo-cd \ --namespace argocd --create-namespace \ -f values.yaml # 匯出目前設定 helm get values argocd -n argocd -o yaml > current-values.yaml
# 查詢 Argo CD Service
kubectl get svc argocd-server -n argocd
# Service 改成 NodePort
kubectl patch svc argocd-server -n argocd -p '{
"spec": {
"type": "NodePort",
"ports": [
{
"port": 80,
"targetPort": 8080,
"nodePort": 32009
}
]
}
}'
# 拿初始 admin 密碼
kubectl -n argocd get secret argocd-initial-admin-secret \
-o jsonpath="{.data.password}" | base64 -d
# 匯出 AppProject 設定
kubectl get appprojects -n argocd -o yaml > argocd-projects.yaml
⚠️ admin 密碼拿到後,記得馬上改掉。