目录
External Secrets Operator:外挂式密钥管理
7、总结与展望
开篇:GitOps到底是什么鬼?
你是否遇到过这些让人抓狂的场景:
- 生产环境配置莫名其妙地"漂移"了,跟测试环境长得不一样
- 回滚时手忙脚乱,kubectl apply了一堆不知道哪来的yaml
- 多集群管理像在玩"打地鼠",这边刚修好那边又崩了
- 凌晨3点被报警叫醒,发现是某人"手滑"改了配置
如果你频频点头,那么恭喜你,GitOps就是为你量身打造的解药!
GitOps的核心理念简单粗暴:Git仓库就是唯一的真相来源(Single Source of Truth)。所有基础设施和应用配置都以声明式的方式存储在Git中,自动化工具(如ArgoCD)负责将Git中的期望状态同步到实际集群。
💡 效率技巧:把GitOps想象成"基础设施的版本控制"。就像你用Git管理代码一样,现在你用Git管理整个基础设施。版本回滚?
git revert就行!
GitOps四大核心原则
1. 声明式(Declarative)
就像你告诉服务员"我要一份宫保鸡丁",而不是一步步教他怎么炒。声明式配置只描述"我想要什么状态",而不是"怎么达到这个状态"。
# 声明式:我要一个3副本的Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3 # 我要3个副本
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: my-app:v1.2.3
2. 版本化(Versioned)
所有配置变更都通过Git版本控制,这意味着:
- 每次变更都有审计日志(谁、什么时候、改了什么)
- 回滚就是一次
git revert或git checkout - 代码审查(Code Review)可以应用到基础设施变更
3. 自动化(Automated)
人工执行kubectl apply?那是上个时代的事情了。GitOps工具会自动:
- 监听Git仓库变更
- 检测期望状态与实际状态的差异
- 自动同步或发出告警
4. 可审计(Auditable)
由于所有变更都在Git中,审计变得异常简单:
# 查看过去30天所有配置变更
git log --since="30 days ago" --oneline --all -- "*.yaml" "*.yml"
# 查看某个文件的所有修改历史
git log -p --follow -- config/production.yaml
⚠️ 避坑警告:不要把敏感信息(密码、API Key)直接提交到Git!后面我们会讲如何安全地管理密钥。
ArgoCD进阶实战
ApplicationSet:集群管理的瑞士军刀
当你管理几十个甚至上百个集群时,手动创建Application会疯掉。ApplicationSet就像Excel的"填充柄",一键生成多个Application。
场景:你有3个环境(dev/staging/prod),每个环境有5个应用,共15个Application需要管理。
# applicationset.yaml
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: my-apps
namespace: argocd
spec:
generators:
# 列表生成器:枚举所有环境和应用组合
- list:
elements:
- env: dev
cluster: dev-cluster
namespace: dev
- env: staging
cluster: staging-cluster
namespace: staging
- env: prod
cluster: prod-cluster
namespace: prod
template:
metadata:
name: '{{env}}-my-app'
spec:
project: default
source:
repoURL: https://github.com/myorg/gitops-repo.git
targetRevision: HEAD
path: apps/my-app/overlays/{{env}}
destination:
server: '{{cluster}}'
namespace: '{{namespace}}'
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
💡 效率技巧:ApplicationSet支持多种生成器(List、Git、Cluster、SCM Provider等)。对于大规模集群,推荐使用Git生成器,将配置数据放在单独的JSON/YAML文件中,方便自动化维护。
App of Apps:俄罗斯套娃的艺术
App of Apps是一种"递归"的管理模式:一个父Application管理多个子Application。这就像俄罗斯套娃,打开一个发现里面还有一堆。
典型架构:
┌─────────────────────────────────────┐
│ Root Application │
│ (管理所有基础设施组件) │
└──────────────────┬──────────────────┘
│
┌──────────────┼──────────────┬──────────────┐
▼ ▼ ▼ ▼
┌────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ArgoCD │ │Ingress │ │Monitoring│ │ Apps │
│(自身) │ │Controller│ │ Stack │ │ (业务应用)│
└────────┘ └──────────┘ └──────────┘ └──────────┘
│
┌─────────────────────────┼─────────────────────────┐
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│AppSet-1 │ │AppSet-2 │ │AppSet-3 │
│(微服务A)│ │(微服务B)│ │(微服务C)│
└─────────┘ └─────────┘ └─────────┘
# root-app.yaml - 根应用,部署所有基础设施
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: root-app
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: https://github.com/myorg/gitops-repo.git
targetRevision: HEAD
path: bootstrap/
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: true
# bootstrap/monitoring-app.yaml - 监控栈
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: monitoring
namespace: argocd
spec:
project: infrastructure
source:
repoURL: https://github.com/myorg/gitops-repo.git
targetRevision: HEAD
path: infrastructure/monitoring
helm:
valueFiles:
- values-{{ .Values.environment }}.yaml
destination:
server: https://kubernetes.default.svc
namespace: monitoring
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
⚠️ 避坑警告:App of Apps虽然强大,但不要嵌套太深!建议最多2-3层,否则排查问题时会像解毛线团一样痛苦。
多源支持:一个App吃遍天
ArgoCD 2.6+支持多源(Multiple Sources),允许一个Application从多个Git仓库或Helm chart组合配置。
场景:你想用开源Helm chart部署应用,但values.yaml放在自己的私有仓库。
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: complex-app
namespace: argocd
spec:
project: default
sources:
# 源1:开源Helm chart
- repoURL: https://charts.bitnami.com/bitnami
chart: wordpress
targetRevision: 15.x.x
helm:
valueFiles:
- $values/wordpress/values-common.yaml
# 源2:私有仓库的自定义配置
- repoURL: https://github.com/myorg/gitops-values.git
targetRevision: HEAD
ref: values
destination:
server: https://kubernetes.default.svc
namespace: wordpress
syncPolicy:
automated:
prune: true
selfHeal: true
💡 效率技巧:多源支持让你可以"站在巨人的肩膀上"——用社区成熟的Helm chart,同时保持自定义配置的独立性。
通知配置:让运维不再做"望夫石"
ArgoCD支持多种通知渠道(Slack、钉钉、企业微信、Webhook等)。配置好通知,再也不用盯着ArgoCD UI刷新了!
# argocd-notifications-cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-notifications-cm
namespace: argocd
data:
service.slack: |
token: $slack-token
template.app-sync-succeeded: |
message: |
✅ *应用同步成功*
应用: {{.app.metadata.name}}
环境: {{.app.metadata.labels.environment}}
版本: {{.app.status.sync.revision}}
操作人: {{.app.status.operationState.operation.initiatedBy.username}}
slack:
attachments: |
[{
"title": "{{.app.metadata.name}}",
"title_link": "{{.context.argocdUrl}}/applications/{{.app.metadata.name}}",
"color": "#18be18",
"fields": [
{"title": "环境", "value": "{{.app.metadata.labels.environment}}", "short": true},
{"title": "状态", "value": "{{.app.status.sync.status}}", "short": true}
]
}]
template.app-sync-failed: |
message: |
❌ *应用同步失败*
应用: {{.app.metadata.name}}
错误: {{.app.status.operationState.message}}
slack:
attachments: |
[{
"title": "{{.app.metadata.name}}",
"title_link": "{{.context.argocdUrl}}/applications/{{.app.metadata.name}}",
"color": "#f4c030",
"fields": [
{"title": "错误信息", "value": "{{.app.status.operationState.message}}", "short": false}
]
}]
trigger.on-sync-succeeded: |
- description: 应用同步成功时触发
oncePer: app.status.operationState?.syncResult?.revision
send:
- app-sync-succeeded
when: app.status.operationState.phase in ['Succeeded']
trigger.on-sync-failed: |
- description: 应用同步失败时触发
send:
- app-sync-failed
when: app.status.operationState.phase in ['Error', 'Failed']
💡 效率技巧:为不同环境配置不同的通知策略。生产环境失败立即通知,开发环境可以延迟或批量通知,避免"通知疲劳"。
多环境管理:从混乱到秩序
Kustomize Overlay:环境配置的千层饼
Kustomize是Kubernetes原生的配置管理工具,通过"基础+覆盖层"的方式管理多环境配置。
目录结构:
my-app/
├── base/ # 基础配置(环境无关)
│ ├── deployment.yaml
│ ├── service.yaml
│ └── kustomization.yaml
└── overlays/ # 环境特定覆盖
├── dev/ # 开发环境
│ ├── replica-patch.yaml
│ ├── resource-patch.yaml
│ └── kustomization.yaml
├── staging/ # 预发布环境
│ ├── replica-patch.yaml
│ └── kustomization.yaml
└── prod/ # 生产环境
├── replica-patch.yaml
├── hpa-patch.yaml
├── pdb-patch.yaml
└── kustomization.yaml
基础配置:
# base/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: my-app:latest
ports:
- containerPort: 8080
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
# base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
commonLabels:
app.kubernetes.io/name: my-app
app.kubernetes.io/managed-by: argocd
开发环境覆盖:
# overlays/dev/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: dev
namePrefix: dev-
resources:
- ../../base
patchesStrategicMerge:
- replica-patch.yaml
- resource-patch.yaml
configMapGenerator:
- name: app-config
literals:
- ENV=development
- LOG_LEVEL=debug
- DEBUG=true
# overlays/dev/replica-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 1 # 开发环境只需要1个副本
# overlays/dev/resource-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
template:
spec:
containers:
- name: app
resources:
requests:
memory: "64Mi" # 开发环境资源减半
cpu: "50m"
limits:
memory: "128Mi"
cpu: "100m"
生产环境覆盖:
# overlays/prod/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: prod
namePrefix: prod-
resources:
- ../../base
- hpa.yaml # 生产环境特有的HPA
- pdb.yaml # 生产环境特有的PDB
patchesStrategicMerge:
- replica-patch.yaml
- resource-patch.yaml
- probe-patch.yaml
configMapGenerator:
- name: app-config
literals:
- ENV=production
- LOG_LEVEL=warn
- DEBUG=false
# overlays/prod/replica-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 5 # 生产环境5个副本
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0 # 零停机部署
# overlays/prod/hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 5
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
⚠️ 避坑警告:不要在base里放环境特定的配置!曾经有人把生产环境的CPU限制放在base里,结果开发环境的小破机器直接OOM,那场面相当尴尬。
Helm Values分层:Values文件的俄罗斯方块
Helm通过values.yaml实现配置覆盖,支持全局values、环境values、本地values多层叠加。
目录结构:
helm-charts/
├── my-app/
│ ├── Chart.yaml
│ ├── values.yaml # 默认值(开发环境级别)
│ ├── values-staging.yaml # 预发布环境覆盖
│ ├── values-prod.yaml # 生产环境覆盖
│ └── templates/
└── global-values.yaml # 全局共享配置
全局配置:
# global-values.yaml
# 所有环境共享的基础配置
global:
imageRegistry: "registry.mycompany.com"
imagePullSecrets:
- name: regcred
labels:
app.kubernetes.io/managed-by: helm
company.io/team: platform
company.io/cost-center: engineering
Chart默认值(开发环境):
# my-app/values.yaml
replicaCount: 1
image:
repository: my-app
tag: latest
pullPolicy: IfNotPresent
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
env:
LOG_LEVEL: debug
DEBUG: "true"
ingress:
enabled: false # 开发环境不需要ingress
monitoring:
enabled: false # 开发环境不开监控
生产环境覆盖:
# my-app/values-prod.yaml
replicaCount: 5
image:
tag: stable # 生产环境用稳定标签
pullPolicy: Always
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "1Gi"
cpu: "1000m"
env:
LOG_LEVEL: warn
DEBUG: "false"
ingress:
enabled: true
hosts:
- host: my-app.mycompany.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: my-app-tls
hosts:
- my-app.mycompany.com
monitoring:
enabled: true
serviceMonitor:
enabled: true
namespace: monitoring
autoscaling:
enabled: true
minReplicas: 5
maxReplicas: 20
targetCPUUtilizationPercentage: 70
targetMemoryUtilizationPercentage: 80
podDisruptionBudget:
enabled: true
minAvailable: 3
ArgoCD Application引用:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app-prod
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/myorg/gitops-repo.git
targetRevision: HEAD
path: helm-charts/my-app
helm:
valueFiles:
- ../../global-values.yaml # 全局配置
- values-prod.yaml # 生产环境配置
parameters:
- name: image.tag
value: "v1.2.3" # CI/CD注入的版本号
destination:
server: https://prod-cluster
namespace: prod
💡 效率技巧:使用Helm的--set-file参数可以从文件加载大段配置(如证书、长JSON),避免values.yaml过于臃肿。
环境晋升:代码的升职之路
环境晋升(Promotion)是指代码从开发→测试→预发布→生产的流程。GitOps让这个过程变得可追溯、可审计。
Git分支策略:
main (生产环境)
↑
release/v1.2 (预发布环境)
↑
develop (开发/测试环境)
↑
feature/* (功能分支)
晋升流程:
# 1. 功能开发完成,合并到develop分支
git checkout develop
git merge feature/new-feature
git push origin develop
# → 自动部署到开发环境
# 2. 测试通过,创建release分支
git checkout -b release/v1.2.0
git push origin release/v1.2.0
# → 自动部署到预发布环境
# 3. 预发布验证通过,合并到main分支
git checkout main
git merge release/v1.2.0
git tag -a v1.2.0 -m "Release v1.2.0"
git push origin main --tags
# → 自动部署到生产环境
ArgoCD ApplicationSet实现自动晋升:
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: environment-promotion
namespace: argocd
spec:
generators:
- matrix:
generators:
- git:
repoURL: https://github.com/myorg/gitops-repo.git
revision: HEAD
directories:
- path: apps/*
- list:
elements:
- env: dev
branch: develop
cluster: dev-cluster
autoSync: true
- env: staging
branch: release/*
cluster: staging-cluster
autoSync: true
- env: prod
branch: main
cluster: prod-cluster
autoSync: false # 生产环境需要手动同步
template:
metadata:
name: '{{env}}-{{path.basename}}'
spec:
project: default
source:
repoURL: https://github.com/myorg/gitops-repo.git
targetRevision: '{{branch}}'
path: '{{path}}'
destination:
server: '{{cluster}}'
namespace: '{{env}}'
syncPolicy:
automated:
prune: true
selfHeal: '{{autoSync}}'
syncOptions:
- CreateNamespace=true
⚠️ 避坑警告:生产环境强烈建议关闭autoSync!给运维人员一个"确认"的机会,避免半夜被误操作搞醒。可以配合通知系统,收到同步请求后人工审批。
密钥管理:不能说的秘密
Sealed Secrets:把秘密装进保险箱
Sealed Secrets允许你将加密的Secret安全地存储在Git中,只有集群内的controller能解密。
安装Sealed Secrets:
# 安装controller
kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.0/controller.yaml
# 安装客户端工具kubeseal
# macOS
brew install kubeseal
# Linux
wget https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.0/kubeseal-0.24.0-linux-amd64.tar.gz
tar -xvzf kubeseal-0.24.0-linux-amd64.tar.gz kubeseal
sudo install -m 755 kubeseal /usr/local/bin/kubeseal
加密Secret:
# 方式1:从标准输入加密
cat <<EOF | kubeseal --controller-namespace=kube-system --controller-name=sealed-secrets --format yaml > mysecret.yaml
apiVersion: v1
kind: Secret
metadata:
name: my-secret
namespace: default
type: Opaque
stringData:
DB_PASSWORD: SuperSecretPassword123!
API_KEY: sk-1234567890abcdef
EOF
# 方式2:从已有Secret加密
kubectl create secret generic my-secret \
--from-literal=DB_PASSWORD=SuperSecretPassword123! \
--from-literal=API_KEY=sk-1234567890abcdef \
--dry-run=client -o yaml | \
kubeseal --controller-namespace=kube-system --format yaml > mysecret.yaml
生成的SealedSecret可以安全地提交到Git:
# mysecret.yaml
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: my-secret
namespace: default
spec:
encryptedData:
DB_PASSWORD: AgBy...(加密内容)
API_KEY: AgAt...(加密内容)
template:
metadata:
name: my-secret
namespace: default
type: Opaque
💡 效率技巧:Sealed Secret是集群绑定的(cluster-scoped),加密时使用的证书来自目标集群。如果要部署到多个集群,需要为每个集群单独加密,或使用全局恢复密钥。
External Secrets Operator:外挂式密钥管理
ESO从外部密钥管理系统(AWS Secrets Manager、Azure Key Vault、GCP Secret Manager、HashiCorp Vault等)同步密钥到Kubernetes。
架构图:
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ AWS Secrets │◄────│ External Secrets │────►│ Kubernetes │
│ Manager │ │ Operator │ │ Secret │
└─────────────────┘ └──────────────────┘ └─────────────────┘
▲ │
│ ▼
┌─────────────────┐ ┌─────────────────┐
│ HashiCorp Vault │ │ Pod │
└─────────────────┘ └─────────────────┘
安装ESO:
helm repo add external-secrets https://charts.external-secrets.io
helm install external-secrets external-secrets/external-secrets \
--namespace external-secrets \
--create-namespace
配置AWS Secrets Manager:
# secretstore.yaml - 配置密钥存储后端
apiVersion: external-secrets.io/v1beta1
kind: ClusterSecretStore
metadata:
name: aws-secrets-manager
spec:
provider:
aws:
service: SecretsManager
region: us-east-1
auth:
jwt:
serviceAccountRef:
name: external-secrets-sa
namespace: external-secrets
# externalsecret.yaml - 定义要同步的密钥
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: my-app-secrets
namespace: default
spec:
refreshInterval: 1h # 每小时同步一次
secretStoreRef:
kind: ClusterSecretStore
name: aws-secrets-manager
target:
name: my-app-secret # 创建的Secret名称
creationPolicy: Owner
template:
type: Opaque
metadata:
annotations:
managed-by: external-secrets
data:
# 可以转换密钥格式
DATABASE_URL: "postgresql://{{ .db_user }}:{{ .db_password }}@{{ .db_host }}:5432/{{ .db_name }}"
data:
- secretKey: db_user
remoteRef:
key: prod/my-app/database
property: username
- secretKey: db_password
remoteRef:
key: prod/my-app/database
property: password
- secretKey: db_host
remoteRef:
key: prod/my-app/database
property: host
- secretKey: db_name
remoteRef:
key: prod/my-app/database
property: database
⚠️ 避坑警告:不要把SecretStore的凭证也放在Git里!使用IRSA(AWS)、Workload Identity(GCP)或Azure AD Pod Identity,让Pod通过Service Account自动获取权限。
SOPS:加密界的瑞士军刀
SOPS(Secrets OPerationS)是Mozilla开源的加密工具,支持多种密钥管理系统,可以加密YAML、JSON、ENV等文件的部分或全部内容。
安装SOPS:
# macOS
brew install sops
# Linux
curl -LO https://github.com/getsops/sops/releases/download/v3.8.1/sops-v3.8.1.linux.amd64
mv sops-v3.8.1.linux.amd64 sops
chmod +x sops
sudo mv sops /usr/local/bin/
配置SOPS(使用AWS KMS):
# .sops.yaml - SOPS配置文件
creation_rules:
# 生产环境密钥使用特定的KMS key
- path_regex: prod/.*\.yaml$
kms: arn:aws:kms:us-east-1:123456789:key/prod-key
encrypted_regex: '^(data|stringData)$'
# 其他环境使用另一个key
- path_regex: .*/.*\.yaml$
kms: arn:aws:kms:us-east-1:123456789:key/dev-key
encrypted_regex: '^(data|stringData)$'
加密Secret:
# 加密文件
sops -e -i secret.yaml
# 解密文件
sops -d -i secret.yaml
# 直接编辑加密文件(自动解密/加密)
sops secret.yaml
加密后的文件:
apiVersion: v1
kind: Secret
metadata:
name: my-secret
stringData:
password: ENC[AES256_GCM,data:...,iv:...,type:str]
username: ENC[AES256_GCM,data:...,iv:...,type:str]
sops:
kms:
- arn: arn:aws:kms:us-east-1:123456789:key/prod-key
created_at: '2024-01-15T10:30:00Z'
enc: ...
lastmodified: '2024-01-15T10:30:00Z'
version: 3.8.1
与ArgoCD集成: 使用argocd-vault-plugin或ksops(Kustomize SOPS插件)在ArgoCD中自动解密SOPS加密的文件。
# kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
generators:
- ksops-generator.yaml
# ksops-generator.yaml
apiVersion: viaduct.ai/v1
kind: ksops
metadata:
name: secret-generator
files:
- secret.enc.yaml
💡 效率技巧:SOPS支持加密文件中的特定字段(通过encrypted_regex),这样你可以把非敏感配置和敏感配置放在同一个文件里,只有敏感字段会被加密。
灾难恢复:未雨绸缪的艺术
备份策略
备份什么?
- Git仓库:代码和配置的唯一真相来源
- ArgoCD状态:Application定义、Projects、Settings
- 集群etcd数据:Kubernetes所有资源的状态
ArgoCD备份脚本:
#!/bin/bash
# backup-argocd.sh
BACKUP_DIR="/backup/argocd/$(date +%Y%m%d)"
mkdir -p "$BACKUP_DIR"
# 导出所有Applications
kubectl get applications -n argocd -o yaml > "$BACKUP_DIR/applications.yaml"
# 导出所有AppProjects
kubectl get appprojects -n argocd -o yaml > "$BACKUP_DIR/appprojects.yaml"
# 导出ArgoCD配置
kubectl get configmap argocd-cm -n argocd -o yaml > "$BACKUP_DIR/argocd-cm.yaml"
kubectl get configmap argocd-cmd-params-cm -n argocd -o yaml > "$BACKUP_DIR/argocd-cmd-params-cm.yaml"
kubectl get configmap argocd-ssh-known-hosts-cm -n argocd -o yaml > "$BACKUP_DIR/argocd-ssh-known-hosts-cm.yaml"
# 导出Secrets(注意:这些是base64编码的,需要额外加密存储)
kubectl get secrets -n argocd -o yaml > "$BACKUP_DIR/secrets.yaml"
# 压缩并上传到S3
tar -czf "$BACKUP_DIR.tar.gz" -C /backup/argocd "$(date +%Y%m%d)"
aws s3 cp "$BACKUP_DIR.tar.gz" s3://my-backup-bucket/argocd/
# 清理本地备份
rm -rf "$BACKUP_DIR" "$BACKUP_DIR.tar.gz"
echo "Backup completed: s3://my-backup-bucket/argocd/$BACKUP_DIR.tar.gz"
etcd备份(使用Velero):
# 安装Velero
velero install \
--provider aws \
--bucket my-backup-bucket \
--backup-location-config region=us-east-1 \
--snapshot-location-config region=us-east-1 \
--secret-file ./credentials-velero
# 创建备份(包含所有命名空间)
velero backup create full-cluster-backup \
--include-namespaces '*' \
--snapshot-volumes \
--ttl 720h0m0s
# 只备份关键命名空间
velero backup create critical-apps-backup \
--include-namespaces argocd,monitoring,ingress-nginx \
--snapshot-volumes
跨集群恢复
场景:生产集群完全不可用,需要在新集群恢复。
恢复步骤:
# 1. 创建新集群(使用terraform或eksctl等工具)
eksctl create cluster --name prod-recovery --region us-east-1
# 2. 安装ArgoCD
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# 3. 恢复ArgoCD配置
kubectl apply -f /backup/argocd/latest/appprojects.yaml
kubectl apply -f /backup/argocd/latest/applications.yaml
# 4. 如果使用Velero,恢复应用数据
velero restore create --from-backup full-cluster-backup
# 5. 等待ArgoCD自动同步所有应用
# 由于GitOps的声明式特性,所有应用会自动恢复到Git定义的状态!
RTO/RPO设计
| 指标 | 定义 | GitOps场景下的目标 |
|---|---|---|
| RTO (Recovery Time Objective) | 恢复时间目标 | < 5分钟 - ArgoCD从Git重新同步 |
| RPO (Recovery Point Objective) | 恢复点目标 | ≈ 0 - Git就是最新状态,无数据丢失 |
为什么GitOps的RPO可以接近0?
- 所有配置都在Git中,Git就是"备份"
- 应用数据使用Velero等工具定期备份
- 有状态数据(数据库)使用原生备份方案(如RDS快照)
架构图:
┌─────────────────────────────────────────────────────────────────┐
│ 灾难恢复架构 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ Git仓库 │◄───────►│ Git仓库 │ (异地多副本) │
│ │ (主-Region) │ │ (备-Region) │ │
│ └──────────────┘ └──────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ 生产集群 │ X │ 灾备集群 │ (故障时切换) │
│ │ (Primary) │ ──────► │ (Standby) │ │
│ └──────────────┘ 故障 └──────────────┘ │
│ │
│ 恢复流程: │
│ 1. 检测到主集群故障 (监控告警) │
│ 2. 切换DNS/流量到灾备集群 │
│ 3. ArgoCD自动从Git同步所有配置 (< 5分钟) │
│ 4. 恢复应用数据 (Velero/RDS快照) │
│ │
└─────────────────────────────────────────────────────────────────┘
💡 效率技巧:定期进行灾难恢复演练(Chaos Engineering)。用Litmus、Chaos Mesh等工具模拟集群故障,验证恢复流程是否顺畅。别等到真出事了才发现备份不能用!
总结与展望
关键数据回顾
| 指标 | 提升效果 |
|---|---|
| 部署频率 | 提升10倍(自动化触发,无需人工干预) |
| 恢复时间 | < 5分钟(Git回滚,一键恢复) |
| 配置漂移 | 降至0(Git为唯一来源,自动纠正漂移) |
实施路线图
阶段1:基础搭建(1-2周)
├── 部署ArgoCD
├── 配置Git仓库结构
└── 迁移2-3个非关键应用
阶段2:规模推广(1个月)
├── 引入ApplicationSet管理多应用
├── 建立多环境管理规范
└── 迁移核心业务应用
阶段3:生产就绪(1-2个月)
├── 实施密钥管理方案
├── 建立灾难恢复流程
├── 配置监控告警体系
└── 团队培训与文档完善
最后的话
GitOps不是银弹,但它确实解决了传统运维中的很多痛点。记住这几个关键点:
- Git是唯一真相来源 - 所有配置进Git,所有变更走Git
- 声明式优于命令式 - 描述期望状态,让系统自动收敛
- 自动化但不要盲目 - 生产环境保留人工确认环节
- 密钥管理要慎重 - 选择合适的方案,不要硬编码
- 灾难恢复要演练 - 备份不等于能恢复,定期验证
文末三件套
1. 【源码获取】
关注此系列获取后续更新,后台回复’gitops’获取完整示例代码仓库链接,包含:
- 完整的ArgoCD配置示例
- Kustomize和Helm最佳实践
- Sealed Secrets/ESO/SOPS配置模板
- 灾难恢复脚本
2. 【思考题】
你的GitOps实践到什么阶段了?
- ⬜ 还在用kubectl apply的手动时代?
- ⬜ 刚入门ArgoCD,部署了几个测试应用?
- ⬜ 已经在生产环境使用,但遇到各种坑?
- ⬜ 管理着1000+集群的GitOps老司机?
欢迎在评论区分享你的经验和踩过的坑!
3. 【系列预告】
云原生进阶系列后续内容:
- 成本优化 → 如何用GitOps管理资源配额,降低云成本
- 安全最佳实践 → RBAC、网络策略、镜像扫描
- 性能调优 → ArgoCD大规模集群性能优化
- 监控告警 → 构建完整的GitOps可观测性体系
CSDN标签:GitOps, ArgoCD进阶, 多环境管理, 声明式部署, 密钥管理, 灾难恢复
本文约5500字,创作不易,如果觉得有帮助,请点赞、收藏、转发三连支持!有问题欢迎在评论区留言讨论。
338

被折叠的 条评论
为什么被折叠?



