Argo CDargocd admin import深度指南:从备份文件恢复 Argo CD 控制面数据
【免费下载链接】argo-cdDeclarative Continuous Deployment for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/ar/argo-cd
argocd admin import是 Argo CD 管理员命令集中负责“恢复”的一侧:它把argocd admin export导出的多文档 YAML 备份重新写回集群,涵盖 Argo CD 核心 ConfigMap、Secret、AppProject、Application 与 ApplicationSet 等控制面资源。本文基于命令参考文档 argocd_admin_import.md 整理完整的命令语法与全部选项说明,并结合 NewImportCommand 的源码实现,逐段讲解导入、更新、冲突处理与 prune(清理)流程,帮助你构建可验证、可回滚的灾备恢复方案。
命令定位:admin 命令族中的恢复入口
argocd admin是一组面向 Argo CD 管理员、需要直接 Kubernetes 集群访问权限(而非通过 Argo CD API Server 认证)的命令集合,详见 argocd_admin.md。import子命令在 admin.go 中通过command.AddCommand(NewImportCommand())注册,其定义为:
Import Argo CD data from stdin (specify
-) or a file
从源码看(backup.go#L159-L177),该命令要求恰好一个位置参数SOURCE:传入-时从 stdin 读取备份内容,否则读取指定文件。它与同文件中的NewExportCommand(backup.go#L33-L157)互为镜像,共同构成 Argo CD 官方灾难恢复流程的基石。
典型用法:与 export 配对完成灾备恢复
在 disaster_recovery.md 中,官方推荐的“导出-导入”流程是通过 Argo CD 官方容器在本地执行,避免依赖本地安装的 CLI:
# 导出:将 Argo CD 数据写入 backup.yaml docker run -v ~/.kube:/home/argocd/.kube --rm quay.io/argoproj/argocd:$VERSION argocd admin export > backup.yaml # 导入:将 backup.yaml 恢复到集群 docker run -i -v ~/.kube:/home/argocd/.kube --rm quay.io/argocd/argocd:$VERSION argocd admin import - < backup.yaml两点必须牢记的使用前提:
- 命名空间要正确。官方文档特别提示:如果 Argo CD 安装在非默认命名空间,必须给 export/import 传
-n <namespace>;argocd admin export在错误的命名空间下执行不会报错,会静默产出空/不完整的备份(见 disaster_recovery.md#L28)。 - status 字段的处理。默认情况下
export会保留资源的status(例如 Application 的同步历史与健康状态),便于温备/灾备场景保留最后已知状态;若希望得到干净可重建的清单,可加--strip-status导出。对应地,import在更新时只有当备份清单中确实包含 status 字段时才会覆盖线上资源的 status(disaster_recovery.md#L32-L42),这一行为在源码updateLive中可直接印证(见下文)。
命令语法与完整选项参考
argocd admin import SOURCE [flags]以下是命令参考文档中列出的全部选项(argocd_admin_import.md),按“本命令专属选项”与“从父命令继承的选项”分组:
本命令选项
--application-namespaces strings Comma separated list of namespace globs to which import of applications is allowed. If not provided, value from 'application.namespaces' in argocd-cmd-params-cm will be used. If it's not defined, only applications without an explicit namespace will be imported to the Argo CD namespace --applicationset-namespaces strings Comma separated list of namespace globs which import of applicationsets is allowed. If not provided, value from 'applicationsetcontroller.namespaces' in argocd-cmd-params-cm will be used. If it's not defined, only applicationsets without an explicit namespace will be imported to the Argo CD namespace --as string Username to impersonate for the operation --as-group stringArray Group to impersonate for the operation, this flag can be repeated to specify multiple groups. --as-uid string UID to impersonate for the operation --certificate-authority string Path to a cert file for the certificate authority --client-certificate string Path to a client certificate file for TLS --client-key string Path to a client key file for TLS --cluster string The name of the kubeconfig cluster to use --context string The name of the kubeconfig context to use --disable-compression If true, opt-out of response compression for all requests to the server --dry-run Print what will be performed -h, --help help for import --ignore-tracking Do not update the tracking annotation if the resource is already tracked --insecure-skip-tls-verify If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure --kubeconfig string Path to a kube config. Only required if out-of-cluster -n, --namespace string If present, the namespace scope for this CLI request --override-on-conflict Override the resource on conflict when updating resources --password string Password for basic authentication to the API server --prompts-enabled Force optional interactive prompts to be enabled or disabled, overriding local configuration. If not specified, the local configuration value will be used, which is false by default. --proxy-url string If provided, this URL will be used to connect via proxy --prune Prune secrets, applications and projects which do not appear in the backup --request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") --server string The address and port of the Kubernetes API server --skip-resources-with-label string Skip importing resources based on the label e.g. '--skip-resources-with-label my-label/example.io=true' --stop-operation Stop any existing operations --tls-server-name string If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used. --token string Bearer token for authentication to the API server --user string The name of the kubeconfig user to use --username string Username for basic authentication to the API server --verbose Verbose output (versus only changed output)其中--as/--context/--kubeconfig/--server等 kubectl 风格选项由cli.AddKubectlFlagsToCmd(backup.go#L431)统一注入,决定了命令连接到哪个集群、哪个命名空间。真正控制导入行为的是--dry-run、--prune、--stop-operation、--ignore-tracking、--override-on-conflict、--skip-resources-with-label、--application-namespaces、--applicationset-namespaces、--prompts-enabled与--verbose这组选项,它们在源码中的注册位置见 backup.go#L432-L441。
从父命令继承的选项
--argocd-context string The name of the Argo-CD server context to use --auth-token string Authentication token; set this or the ARGOCD_AUTH_TOKEN environment variable --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/user/.config/argocd/config") --controller-name string Name of the Argo CD Application controller; set this or the ARGOCD_APPLICATION_CONTROLLER_NAME environment variable when the controller's name label differs from the default, for example when installing via the Helm chart (default "argocd-application-controller") --core If set to true then CLI talks directly to Kubernetes instead of talking to Argo CD API server --grpc-web Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. --grpc-web-root-path string Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. Set web root. -H, --header strings Sets additional header to all requests made by Argo CD CLI. (Can be repeated multiple times to add multiple headers, also supports comma separated headers) --http-retry-max int Maximum number of retries to establish http connection to Argo CD server --insecure Skip server certificate and domain verification --kube-context string Directs the command to the given kube-context --logformat string Set the logging format. One of: json|text (default "json") --loglevel string Set the logging level. One of: debug|info|warn|error (default "info") --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding --redis-compress string Enable this if the application controller is configured with redis compression enabled. (possible values: gzip, none) (default "gzip") --redis-haproxy-name string Name of the Redis HA Proxy; set this or the ARGOCD_REDIS_HAPROXY_NAME environment variable when the HA Proxy's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis-ha-haproxy") --redis-name string Name of the Redis deployment; set this or the ARGOCD_REDIS_NAME environment variable when the Redis's name label differs from the default, for example when installing via the Helm chart (default "argocd-redis") --repo-server-name string Name of the Argo CD Repo server; set this or the ARGOCD_REPO_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-repo-server") --server-crt string Server certificate file --server-name string Name of the Argo CD API server; set this or the ARGOCD_SERVER_NAME environment variable when the server's name label differs from the default, for example when installing via the Helm chart (default "argocd-server")源码深潜:import 的完整执行流程
下面按 backup.go#L177-L428 中Run函数的实际执行顺序拆解。
1. 建立客户端并读取输入
命令首先解析 kubeconfig 得到*rest.Config,并显式抬高限流阈值config.QPS = 100、config.Burst = 50(backup.go#L184-L187)——这说明官方预期导入大批量对象时不能受默认 QPS 限制拖慢,也解释了为什么恢复过程通常较快。随后按SOURCE参数决定输入来源(backup.go#L196-L200):
if in := args[0]; in == "-" { input, err = io.ReadAll(os.Stdin) } else { input, err = os.ReadFile(in) }命名空间则取自 kubeconfig 上下文(-n覆盖),并在控制台打印import process started <namespace>。
2. 先收集“线上存量”,构建 prune 候选集
在读取备份内容之前,命令先列出目标命名空间内的全部 Argo CD 资源,装入pruneObjects映射(backup.go#L224-L268):
- 所有 Argo CD ConfigMap(
isArgoCDConfigMap判定); - 所有 Argo CD Secret(
isArgoCDSecret判定); - 所有位于允许命名空间内的 Application;
- 所有 AppProject;
- 所有位于允许命名空间内的 ApplicationSet(对
IsForbidden/IsNotFound仅告警,容忍集群未启用 ApplicationSet)。
源码注释解释了这个设计的意图:“pruneObjects 追踪线上对象及其当前资源版本,遍历备份后仍留在映射中的项即表示该资源不再出现在备份里,应被 prune”。
3. 解析备份文件并逐对象处理
备份文件通过kube.SplitYAML切分为多组unstructured.Unstructured对象(backup.go#L270)。对每个备份对象:
- 命名空间归一化:若对象没有显式命名空间,则默认归入 Argo CD 控制面命名空间(backup.go#L276-L278);
- 匹配与摘除:按
Group/Kind/Name/Namespace计算kube.ResourceKey,命中pruneObjects即从候选集移除(backup.go#L279-L281),保证“出现在备份里”的资源绝不会被 prune; - 标签跳过:若对象携带
--skip-resources-with-label指定的标签(如my-label/example.io=true),打印跳过信息并continue(backup.go#L283-L287);判定逻辑见isSkipLabelMatches(backup.go#L544-L557),仅支持key=value单对格式; - 按 Kind 选择 dynamic client,并对 Application / ApplicationSet 再次做命名空间白名单校验:不在
--application-namespaces/--applicationset-namespaces(或argocd-cmd-params-cm中application.namespaces/applicationsetcontroller.namespaces配置的 glob)内的对象直接不导入(backup.go#L289-L309)。
4. 创建 / 保持不变 / 更新三分支
核心决策在 backup.go#L317-L366:
- 线上不存在:直接
Create; - spec 相等且无需停止操作:
specsEqual(*bakObj, liveObj) && checkAppHasNoNeedToStopOperation(...)成立时仅在--verbose下打印unchanged; - 其余情况:调用
updateLive生成新对象后Update。
其中updateLive(backup.go#L489-L512)的合并策略值得注意:它只用备份对象覆盖线上的spec(Secret/ConfigMap 覆盖data)、annotations、labels、finalizers,其余字段(如 status、resourceVersion)保持线上原值;对 Application 额外地——当且仅当备份中带有 status 字段时才覆盖 status,并在--stop-operation时把operation置空。这正是灾难恢复文档中“import 只覆盖备份里存在的 status”这一行为的源码依据。
5. 冲突处理:--override-on-conflict
Update若返回 Conflict(resourceVersion 冲突),默认只打印失败信息;加上--override-on-conflict后进入retry.RetryOnConflict重试循环:重新Get线上对象、把备份对象对齐到最新resourceVersion再提交(backup.go#L341-L354)。在恢复窗口内其他控制器可能仍在变更资源,这个选项能让导入“赢”下竞争,但代价是覆盖线上并发修改,需在有明确恢复意图时使用。
6. --stop-operation 与 --ignore-tracking
--stop-operation:若线上 Application 带有进行中的operation(同步/删除),默认会视为“spec 不一致”而触发更新;checkAppHasNoNeedToStopOperation(backup.go#L446-L454)负责该判定,更新时则把operation字段清空,等效于停止在途操作、让恢复后的 spec 从头重新收敛。--ignore-tracking:当 Argo CD 自身被另一个 Application 以 GitOps 方式管理时,线上对象带有 tracking 注解/标签。updateTracking(backup.go#L516-L541)会把线上对象的argocd.argoproj.io/instance注解与标签值回填到备份对象上,避免导入的 tracking 标记与现有管理关系冲突。
7. 清理阶段:--prune 与交互式确认
遍历备份后,pruneObjects中剩余的即“备份里没有、线上还存在”的资源(backup.go#L371-L425):
- 未加
--prune:仅逐条打印... needs pruning,不做任何变更; - 加
--prune:对 Secret/AppProject/Application/ApplicationSet 逐条通过promptUtil.Confirm("Are you sure you want to prune ... ? [y/n]")交互确认后删除;携带跳过标签的资源永不 prune; - 删除 Application 前会先清空其
finalizers(backup.go#L388-L397),避免删除被 finalizer 卡住; --prompts-enabled控制交互确认开关,默认取本地配置(默认 false),即非交互环境下 prune 确认会自动通过(backup.go#L441)。
流程结束后打印汇总:Import process completed successfully in namespace <ns> at <RFC3339 时间>, duration: <耗时>(backup.go#L426-L427),便于在恢复记录中留痕。
关键选项详解
| 选项 | 行为要点(源码依据) |
|---|---|
--dry-run | 所有 Create/Update/Delete 只打印动作、不真正执行,输出带(dry run)后缀(backup.go#L202-L205);建议每次恢复前先跑一遍 |
--prune | 删除备份中不存在的 Argo CD Secret、Application、AppProject、ApplicationSet,删除前逐条确认 |
--stop-operation | 恢复 Application 时清空线上在途operation,让恢复后的 spec 重新驱动同步 |
--ignore-tracking | 保留线上对象已有的 tracking 注解/标签,适用于 Argo CD 被 GitOps 管理的场景 |
--override-on-conflict | 更新遇 resourceVersion 冲突时自动重取并重试 |
--skip-resources-with-label k=v | 备份与清理两侧同时按标签跳过资源(导入侧 backup.go#L284-L287、清理侧 backup.go#L373-L377) |
--application-namespaces/--applicationset-namespaces | 命名空间 glob 白名单;缺省时回落到argocd-cmd-params-cm的application.namespaces/applicationsetcontroller.namespaces;再缺省时只有不带显式命名空间的对象会被导入到 Argo CD 命名空间 |
--verbose | 额外打印unchanged的不变对象,否则仅输出发生变更的行 |
--prompts-enabled | 覆盖本地配置,强制开/关 prune 的交互确认 |
实践建议与常见陷阱
- 先
--dry-run,再正式导入:dry-run 输出会精确列出将 created/updated/pruned 的对象,是恢复前的核对清单。 --prune是破坏性操作:它会删除当前集群中存在而备份中不存在的 Argo CD 资源。若目标集群是全新环境(无残留资源),prune 无实际影响;若向已有环境导入,务必确认备份是“全量”的,否则可能误删后建的对象。- 命名空间错误不会报错:与 export 相同,import 对错误命名空间只会在
needs pruning/created 列表上体现异常,-n与--kubeconfig/--context选择务必二次确认。 - RBAC 需要足够:命令直接走 Kubernetes API(dynamic client),执行账号需要对目标命名空间的 ConfigMap、Secret、applications.argoproj.io、appprojects.argoproj.io、applicationsets.argoproj.io 具有完整读写权限;权限不足时命令会打 warning 并跳过该 Kind 而非整体失败。
- 备份来源要匹配:
import只处理 Secret/ConfigMap/AppProject/Application/ApplicationSet 这五类对象,其余 Kind 会被 dynamic client 选择逻辑自然忽略;因此它恢复的是 Argo CD 控制面,而非应用集群中由 Argo CD 管理的业务资源——后者随 Application 恢复后由控制器重新收敛。
相关命令
argocd admin export:import 的对偶命令,定义于同一文件 backup.go#L33-L157,支持--out、--application-namespaces、--applicationset-namespaces与--strip-status,产出本文所描述的备份文件格式;argocd admin:包含 import/export 在内的管理员命令族,命令总览见 argocd_admin.md;- 灾难恢复全貌(导出、导入、Redis 状态与注意事项)见 disaster_recovery.md。
【免费下载链接】argo-cdDeclarative Continuous Deployment for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/ar/argo-cd
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考