Argo CD 接手新的 RKE 叢集前,要先完成 Git 存取、Vault 驗證與節點前置設定。少了這些條件,第一次同步就可能出現 ExternalSecret 讀不到 Vault、workload 缺少 Secret,或 PVC 等不到儲存空間的情況。
範例使用 Git repository ssh://[email protected]/platform/k8s-infra.git、API server https://rke-api.example.internal:6443 與 Vault https://vault.example.internal:8200。example-api 和 example-worker 有公開入口,example-admin 維持內部使用。
Argo CD 接手後的同步順序
手動套用 clusters/root-app.yaml 後,Argo CD 從 clusters/apps 建立 child Applications,再管理 apps/ 與基礎設施設定。
這份 bootstrap 範例的 waves 如下:
-40:Gateway API CRDs。-30:Istio base。-20:Istio control plane。-10:Istio CNI 與 ESO。-5:ztunnel。0:Redis 與 Longhorn。5:application ExternalSecrets。10:application workloads 與 monitoring。15:Istio observability 與 Kiali。18、20、30:admin、worker、API services。40:shared infrastructure 與 ingresses。
Wave 控制套用順序,不能單憑編號判定其他 controller 產生的物件已就緒。
第一次同步前的人工檢查
kubectl能連線 RKE cluster。- Argo CD 已安裝在
argocdnamespace,並可讀取私有 Git repository。 - Pods 可以連線 Vault。
- Vault Kubernetes auth、ESO policies 與 roles 已建立。
- 必要資料已存在 Vault KV v2。
- Longhorn 的 node 與 storage 前置條件已完成。
- Istio ambient 所需的 node 設定已完成。
- 公開服務有可用的 ingress 路徑。
安裝 Argo CD
這裡的 lab 範例使用 stable manifest;需要可重現的重建流程時,應固定到審查過的 release:
kubectl create namespace argocd
kubectl apply -n argocd --server-side --force-conflicts \
-f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
提供 Git credential 與 host trust
先取得 Git host key,從可信任管道核對 fingerprint,再將它加入 Argo CD 的 known hosts。ssh-keyscan 只能取回網路上的 key,不能證明 server 身分。
Repository credential 直接建立在 cluster:
ssh-keyscan git.example.com > /tmp/argocd_known_hosts
ssh-keygen -lf /tmp/argocd_known_hosts
kubectl -n argocd create configmap argocd-ssh-known-hosts-cm \
--from-file=ssh_known_hosts=/tmp/argocd_known_hosts \
--dry-run=client -o yaml | kubectl apply -f -
kubectl -n argocd create secret generic k8s-infra-repo \
--from-literal=type=git \
--from-literal=url=ssh://[email protected]/platform/k8s-infra.git \
--from-file=sshPrivateKey=/home/user/.ssh/k8s_infra \
--dry-run=client -o yaml | kubectl apply -f -
kubectl -n argocd label secret k8s-infra-repo \
argocd.argoproj.io/secret-type=repository --overwrite
建立 Vault 的 reviewer 身分
ESO 使用 Kubernetes ServiceAccount 向 Vault 驗證;Vault 需要有權呼叫 TokenReview 的 reviewer:
kubectl create namespace vault-auth --dry-run=client -o yaml | kubectl apply -f -
kubectl -n vault-auth create serviceaccount vault-auth
kubectl create clusterrolebinding vault-auth-tokenreview \
--clusterrole=system:auth-delegator \
--serviceaccount=vault-auth:vault-auth
將以下內容存成 vault-auth-token.yaml:
apiVersion: v1
kind: Secret
metadata:
name: vault-auth-token
namespace: vault-auth
annotations:
kubernetes.io/service-account.name: vault-auth
type: kubernetes.io/service-account-token
先等待 token controller 填入 Secret;若等待失敗,先停止後續步驟。再從目標 cluster 的 kubeconfig context 取得 JWT 與 CA;--flatten 會納入以檔案路徑引用的 CA:
kubectl apply -f vault-auth-token.yaml
kubectl -n vault-auth wait --for=jsonpath='{.data.token}' secret/vault-auth-token --timeout=60s
TOKEN_REVIEWER_JWT=$(kubectl -n vault-auth get secret vault-auth-token -o jsonpath='{.data.token}' | base64 -d)
kubectl config view --raw --minify --flatten -o jsonpath='{.clusters[0].cluster.certificate-authority-data}' | base64 -d > ca.crt
在 Vault 設定 Kubernetes auth:
export VAULT_ADDR=https://vault.example.internal:8200
vault login
vault auth enable kubernetes
vault write auth/kubernetes/config \
kubernetes_host="https://rke-api.example.internal:6443" \
kubernetes_ca_cert=@ca.crt \
token_reviewer_jwt="$TOKEN_REVIEWER_JWT"
Auth mount 若已存在,只更新 config。Vault 1.9 起,新建 Kubernetes auth mount 預設使用 disable_iss_validation=true,由 Kubernetes 在 TokenReview 時驗證 issuer;舊 mount 可能保留先前設定。遇到 issuer mismatch 時,先查現有 mount 的設定,參考 Vault Kubernetes auth 文件。
保存應用程式資料與 policy
真正的值先放進 Vault,Git 只保留對應關係:
vault kv put secret/example-api/env-file dotenv=@.env
vault kv put secret/example-worker/config-file config.json=@config.json
vault kv put secret/example-admin/config-file config=@config.yml
Policy 要使用 KV v2 API path,例如:
path "secret/data/example-api/*" {
capabilities = ["read"]
}
還須將 policy 綁到 ESO 使用的 role,並建立信任 Vault CA 的 ClusterSecretStore。完整的 policy、role、Store 與 ExternalSecret 範例見 Vault 與 External Secrets。
啟動 root Application 並檢查首輪同步
kubectl apply -f clusters/root-app.yaml
kubectl -n argocd get applications
先查 controller 與它產生的 Secrets,再查平台元件:
kubectl -n external-secrets get pods
kubectl get clustersecretstore
kubectl -n example-api get secret example-api-env-file
kubectl -n example-worker get secret example-worker-config-file
kubectl -n example-admin get secret example-admin-config-file
kubectl -n longhorn-system get pods
kubectl -n istio-system get pods
kubectl -n istio-system get daemonset istio-cni-node ztunnel
kubectl -n monitoring get podmonitor
最後看 workloads:
kubectl -n redis get pods
kubectl -n example-admin get pods
kubectl -n example-worker get pods
kubectl -n example-api get pods
從最早失敗的依賴排查
ClusterSecretStore 不健康時,先查 Vault auth 與 ESO logs:
kubectl describe clustersecretstore vault-example-api
kubectl -n external-secrets logs deploy/external-secrets --tail=120
ExternalSecret 讀不到資料時,核對 role、ServiceAccount 綁定、KV v2 policy path,以及 remote key/property。Redis 或其他 PVC 使用者無法啟動時,先查 Longhorn。
Pods 沒有加入 ambient 時,確認 namespace label、CNI 與 ztunnel 健康。Enrollment 本身不需要 restart;由 sidecar 遷移時才需要移除 injection 設定並重建受影響的 Pods。參考 Istio enrollment。
