Argo CDargocd cert add-ssh命令详解:为仓库服务器安全注册 SSH known hosts
【免费下载链接】argo-cdDeclarative Continuous Deployment for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/ar/argo-cd
argocd cert add-ssh是 Argo CD 命令行工具中用于将 SSH 服务器公钥(known hosts)注册进 Argo CD 证书库的核心命令。在 Argo CD 通过 SSH 协议访问 Git 仓库的场景下,仓库服务器的公钥必须预先登记,否则连接会直接失败。阅读本文后,你将掌握该命令的完整语法、全部参数含义、与ssh-keyscan组合的批处理用法,并能从源码层面理解数据解析与存储的底层原理。
命令概览与适用场景
argocd cert add-ssh的功能定位是"为仓库服务器添加 SSH known host 条目"(Add SSH known host entries for repository servers)。它隶属于argocd cert命令族——该命令族在 cmd/argocd/commands/cert.go 中由NewCertCommand注册,负责"管理仓库证书与 SSH known hosts 条目"(Manage repository certificates and SSH known hosts entries),包含四个子命令:
| 子命令 | 用途 |
|---|---|
add-ssh | 添加 SSH known host 条目 |
add-tls | 为仓库服务器SERVERNAME添加 TLS 证书数据 |
list | 列出已配置的证书 |
rm | 按类型移除指定仓库服务器的证书 |
在 Argo CD 的架构中,argocd-repo-server(仓库服务器)负责拉取 Git 仓库内容用于应用渲染与对比。当仓库使用 SSH 协议(如git@github.com:org/repo.git)时,repo-server 需要像 OpenSSH 客户端一样校验目标主机的主机密钥。与 TLS 配置不同,SSH 公钥必须预先配置在 Argo CD 中(详见 docs/operator-manual/declarative-setup.md),否则所有 SSH 仓库连接都会失败。argocd cert add-ssh正是完成这一预登记的推荐手段。
命令语法与核心选项
基本语法如下:
argocd cert add-ssh --batch [flags]专属选项
| 选项 | 类型 | 说明 |
|---|---|---|
--batch | bool | 以批处理方式读取 SSH known hosts 数据(强制标志,当前版本必须指定) |
--from string | string | 从文件读取 SSH known hosts 数据(默认为从 stdin 读取) |
-h, --help | - | 显示add-ssh的帮助信息 |
--upsert | bool | 如果输入中的密钥与已存在条目不同,替换现有 SSH 服务器公钥 |
这里有一个值得注意的细节:--batch虽然被定义为一个布尔标志,但从源码看它目前是强制项。在 NewCertAddSSHCommand 的实现中,如果未指定--batch,命令会直接报错you need to specify --batch or specify --help for usage instructions,源码注释也明确写道:"--batchis a flag, but it is mandatory for now."(--batch是一个标志,但目前是强制的)。因此实际使用时请始终带上--batch。
继承自父命令的常用选项
add-ssh还会继承argocd根命令及连接相关的大量全局选项,日常最常用到的包括:
| 选项 | 说明 |
|---|---|
--auth-token string | 认证令牌;也可通过ARGOCD_AUTH_TOKEN环境变量设置 |
--config string | Argo CD 配置文件路径(默认/home/user/.config/argocd/config) |
--server string | Argo CD 服务器地址 |
--core | 若为 true,CLI 直接与 Kubernetes API 交互而非通过 Argo CD API 服务器 |
--grpc-web | 启用 gRPC-web 协议,适用于 Argo CD 服务器位于不支持 HTTP2 的代理之后 |
--plaintext | 禁用 TLS |
--insecure | 跳过服务器证书与域名校验 |
--port-forward | 通过端口转发连接到随机的 argocd-server 端口 |
--loglevel string | 日志级别:debug、info、warn、error(默认info) |
--logformat string | 日志格式:json或text(默认json) |
完整继承选项可运行argocd cert add-ssh --help查看,或参考 docs/user-guide/commands/argocd_cert_add-ssh.md。
实战:从ssh-keyscan批量导入
官方推荐的标准用法是利用 OpenSSH 客户端自带的ssh-keyscan工具扫描目标主机公钥,再通过管道喂给argocd cert add-ssh --batch。argocd cert命令的帮助示例(cmd/argocd/commands/cert.go)给出了这一组合的典型写法:
ssh-keyscan cd.example.com | argocd cert add-ssh --batchdocs/user-guide/private-repositories.md中更详细的示例是循环扫描多个主流 Git 托管平台(docs/user-guide/private-repositories.md):
$ for host in bitbucket.org github.com gitlab.com ssh.dev.azure.com vs-ssh.visualstudio.com ; do ssh-keyscan $host 2> /dev/null ; done bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDQeJzhupRu0u0cdeg... github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk= ...将ssh-keyscan的输出直接重定向或管道化即可完成批量登记,无需逐条手动录入。
实战:从 known_hosts 文件导入
如果你已有现成的known_hosts文件(例如/etc/ssh/ssh_known_hosts或~/.ssh/known_hosts),可使用--from参数直接从文件读取(docs/user-guide/private-repositories.md):
argocd cert add-ssh --batch --from /etc/ssh/ssh_known_hosts不带--from时,命令默认从标准输入读取,执行后会提示 "Enter SSH known hosts entries, one per line. Press CTRL-D when finished.",粘贴数据后按 Ctrl-D 结束输入即可。
输入格式要求与注意事项
- 每条记录格式为
<server_name> <keytype> <base64-encoded_key>,一行一条(docs/operator-manual/declarative-setup.md)。 - 输入中的空行与
#开头的注释行会被自动忽略——源码IsValidSSHKnownHostsEntry明确跳过注释与空行,因为从known_hosts文件或ssh-keyscan输出复制粘贴时经常会带入注释(util/cert/cert.go)。 - 主机名不能是哈希形式:当从
known_hosts文件导入时,主机名或 IP 地址不得被哈希(ssh-keygen生成的|1|...形式条目无法用于 CLI 或 UI 添加;如果必须使用哈希数据,只能走声明式 ConfigMap 配置,但这样做会破坏 CLI 与 UI 的证书管理能力,一般不建议)。此约束在 docs/user-guide/private-repositories.md 中有明确说明。 - 单个数据流最多接受 256 条 known hosts 条目(
CertificateMaxEntriesPerStream = 256),超出会报limit exceeded错误(util/cert/cert.go)。
源码级原理:数据如何被解析与存储
理解argocd cert add-ssh的底层实现有助于排查问题。命令入口为 NewCertAddSSHCommand,其处理流程如下:
- 建立 gRPC 连接:通过
headless.NewClientOrDie创建客户端,并获取证书管理客户端certIf(NewCertClientOrDieWithContext),随后所有操作通过该 gRPC 客户端与 Argo CD API 服务器交互。 - 读取原始数据:根据是否指定
--from,调用certutil.ParseSSHKnownHostsFromPath或certutil.ParseSSHKnownHostsFromStream读取并筛选合法行;若解析结果为空,则报错No valid SSH known hosts data found.。 - 逐条分词与拆分:对每条记录调用
TokenizeSSHKnownHostsEntry拆出主机名、密钥子类型(如ssh-rsa、ssh-ed25519、ecdsa-sha2-nistp256)和密钥数据(util/cert/cert.go);再调用KnownHostsLineToPublicKey借助golang.org/x/crypto/ssh的ssh.ParseKnownHosts完成严格解析(util/cert/cert.go)。 - 展开多主机名:一条 known hosts 记录可能同时声明多个主机名(如
host1,host2 ssh-rsa ...),源码会为其中的每个主机名分别生成一个RepositoryCertificate条目,ServerName为对应主机名,CertType固定为"ssh",CertSubType为密钥类型,CertData为密钥数据(cmd/argocd/commands/cert.go)。 - 调用 API 写入:将全部条目封装为
RepositoryCertificateCreateRequest(携带Upsert标志)调用CreateCertificate落库,最后打印Successfully created N SSH known host entries。
命令输出的成功条数取自 API 响应len(response.Items),而非输入行数——这意味着 API 侧可能因去重或 upsert 逻辑返回不同数量的结果,若你发现导入条数与预期不符,可从响应条数入手排查。
密钥指纹与校验
工具库 util/cert/cert.go 提供了SSHFingerprintSHA256与SSHFingerprintSHA256FromString函数,可计算 SSH 公钥的 SHA256 指纹(base64 编码、去掉末尾等号)。对应的单元测试 util/cert/cert_test.go 用 Bitbucket、GitHub、GitLab、Azure 等真实公钥数据验证了指纹计算结果,你可以用同样的方式校验待导入的密钥来源是否可信,作为导入前的安全自查手段。
与其他管理方式的对比
argocd cert add-ssh是 CLI 侧管理 SSH known hosts 的推荐方式,但同一数据还有另外两种管理入口:
1. Web UI 管理
在 Argo CD Web UI 中可进入 Settings → Certificates,点击 "Add SSH known hosts" 粘贴数据(粘贴时注意密钥数据中不能有换行)。界面操作示意图见 docs/assets/cert-management-add-ssh.png,完整步骤见 docs/user-guide/private-repositories.md。
2. 声明式 ConfigMap 配置
所有 SSH 公钥最终都存储在名为argocd-ssh-known-hosts-cm的 ConfigMap 中,其唯一数据键为ssh_known_hosts(docs/operator-manual/argocd-ssh-known-hosts-cm.yaml)。在 GitOps 自管理(self-managed)部署中,可以直接编辑该 ConfigMap 来声明式地维护 known hosts:
apiVersion: v1 kind: ConfigMap metadata: labels: app.kubernetes.io/name: argocd-ssh-known-hosts-cm app.kubernetes.io/part-of: argocd name: argocd-ssh-known-hosts-cm data: ssh_known_hosts: | # This file was automatically generated by hack/update-ssh-known-hosts.sh. DO NOT EDIT [ssh.github.com]:443 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg= github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=ConfigMap 中的示例数据由 hack/update-ssh-known-hosts.sh 自动生成。需要注意,该 ConfigMap 会被挂载到argocd-server与argocd-repo-serverPod 的/app/config/ssh路径下生成ssh_known_hosts文件;修改 ConfigMap 后 Pod 中生效可能存在延迟,取决于 Kubernetes 配置(docs/operator-manual/declarative-setup.md)。更多细节可参考 docs/operator-manual/declarative-setup.md 与 docs/user-guide/private-repositories.md。
常用配套命令
argocd cert add-ssh通常与argocd cert命令族的其他子命令配合使用(完整参考见 docs/user-guide/commands/argocd_cert.md):
# 列出所有已注册的 SSH known hosts 条目 argocd cert list --cert-type ssh # 列出所有 HTTPS 类型的 TLS 证书 argocd cert list --cert-type https # 移除指定仓库服务器的全部 SSH known hosts 条目(会先弹出 y/n 确认) argocd cert rm --cert-type ssh cd.example.com # 移除某仓库服务器的全部证书与 known hosts(不限定类型) argocd cert rm cd.example.com其中cert rm实现上禁止使用单个*作为主机名通配符以防误删全部条目,但理论上仍可通过其他 glob 模式(如?*)匹配到全部证书,删除时请谨慎(cmd/argocd/commands/cert.go)。
常见问题排查
- 报错 "you need to specify --batch":当前版本
--batch为强制标志,请在命令中显式添加。 - 报错 "No valid SSH known hosts data found.":输入数据中没有任何合法行。检查是否每条记录均为
<host> <keytype> <base64-key>三段式格式,以及是否误用了哈希主机名(|1|...形式)。 - 命令成功但仓库连接仍失败:确认已导入的条目针对的是仓库实际连接的主机名——例如 GitHub 走 SSH 时连接的可能是
ssh.github.com(端口 443)而非github.com,官方 ConfigMap 示例中同时维护了这两种主机名。 - 条目导入数量与输入不一致:一条 known hosts 记录可能对应多个主机名,CLI 会按主机名展开成多条存储;同时 API 端存在去重逻辑,最终以命令输出的成功条数为准。
小结
argocd cert add-ssh --batch是 Argo CD 管理员为 SSH 协议仓库建立信任链的关键命令:通过ssh-keyscan管道或--from文件导入两种方式批量登记公钥,配合--upsert处理密钥轮换,即可让argocd-repo-server安全地拉取 SSH 仓库。理解其背后的解析流程(过滤注释行、展开多主机名、gRPC 落库)以及argocd-ssh-known-hosts-cmConfigMap 这一最终存储形态,将帮助你在排障和设计 GitOps 自管理方案时更加得心应手。
【免费下载链接】argo-cdDeclarative Continuous Deployment for Kubernetes项目地址: https://gitcode.com/GitHub_Trending/ar/argo-cd
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考