
容器运行时云原生【免费下载链接】docker-ce:warning: This repository is deprecated and will be archived (Docker CE itself is NOT deprecated) see the https://github.com/docker/docker-ce/blob/master/README.md :warning:项目地址https://gitcode.com/gh_mirrors/do/docker-ce点击查看免费下载本文围绕 Docker CE 官方文档 trust_signer_add.md 展开系统讲解docker trust signer add命令的完整用法与底层实现从签名者signer与仓库密钥体系的关系、--key公钥文件的准备到单仓库、多仓库以及首次初始化仓库三种实战场景再到该命令在 docker-ce 仓库中的源码级工作原理、名称校验规则与错误处理策略。读者学完后能够独立完成为已签名仓库新增签名者初始化全新签名仓库和批量管理多个仓库签名者三套完整操作并理解其背后 TUFThe Update Framework委托角色机制。一、命令概览签名者管理在 docker trust 体系中的位置Docker Content TrustDCT借助 Notary 与 TUF 框架为镜像提供端到端的签名与校验能力。在这一体系中签名者signer是被允许对某个仓库的镜像 tag 进行签名的实体而docker trust signer add正是把某个实体的公钥登记进指定仓库的入口命令。从命令树来看trust命令组在 cmd.go 中注册了revoke、sign、key、signer与inspect五个子命令组其中signer组又在 signer.go 下挂载了add与remove两个子命令docker trust signer add # 添加签名者本文主题 docker trust signer remove # 移除签名者docker trust signer add的命令格式如下取自 trust_signer_add.mdUsage: docker trust signer add [OPTIONS] NAME REPOSITORY [REPOSITORY...] Add a signer Options: --help Print usage -k, --key list Path to the signers public key file参数说明参数/选项说明NAME签名者名称即签名者在该仓库中的唯一标识REPOSITORY [REPOSITORY...]一个或多个目标仓库形如example/trust-demo可一次性添加多个-k, --key list签名者公钥文件的路径必填可多次指定以一次性登记多个公钥--help打印命令帮助注意-k/--key传入的是签名者的公钥用于在 Notary/TUF 元数据中建立签名者角色。真正用来签名镜像的私钥则由docker trust key generate/docker trust key load负责加载到本地信任密钥库相关内容可参阅 trust_key_generate.md 与 trust_key_load.md。二、前置准备如何获取签名者的公钥文件--key参数要求提供签名者公钥的 PEM 文件路径。Docker 官方推荐的生成方式是docker trust key generate$ docker trust key generate alice Generating key for alice... Enter passphrase for new alice key with ID 17acf3c: Repeat passphrase for new alice key with ID 17acf3c: Successfully generated and loaded private key. Corresponding public key available: alice.pub $ ls alice.pub该命令会生成一对 ECDSA 密钥私钥加密后加载进本地 docker trust 密钥库公钥则以NAME.pub形式输出到当前目录或通过--dir指定目录此文件可直接作为docker trust signer add --key的输入。从源码看key_generate.go 中的generateKeyAndOutputPubPEM使用tufutils.GenerateKey(data.ECDSAKey)生成 ECDSA 密钥并将 PEM Block 的 Header 写入role: keyName最终输出PUBLIC KEY类型的 PEM 文件return pem.Block{ Type: PUBLIC KEY, Headers: map[string]string{ role: keyName, }, Bytes: pubKey.Public(), }, nil如果你已有现成的 PEM 格式公钥文件例如 OpenSSL 生成同样可以直接传给--key。ingestPublicKeys位于 signer_add.go会以只读方式打开文件用io.LimitReader将读取上限限制在 1 MiB再通过tufutils.ParsePEMPublicKey解析 PEM 内容若文件不存在或不是合法公钥会分别报错unable to read public key from file或could not parse public key from file。对应测试见 signer_add_test.go 的TestIngestPublicKeys。三、典型场景一向已有签名仓库添加签名者1. 查看仓库当前签名者状态在添加之前先用docker trust inspect --pretty确认目标仓库现状。假设仓库example/trust-demo已初始化且已有签名者bob$ docker trust inspect --pretty example/trust-demo No signatures for example/trust-demo List of signers and their keys: SIGNER KEYS bob 5600f5ab76a2 Administrative keys for example/trust-demo: Repository Key: 642692c14c9fc399da523a5f4e24fe306a0a6ee1cc79a10e4555b3c6ab02f71e Root Key: 3cb2228f6561e58f46dbc4cda4fcaff9d5ef22e865a94636f82450d1d2234949其中Repository Key是仓库级签名密钥对应 TUF 的targets角色Root Key是仓库的根信任锚对应 TUF 的root角色SIGNER / KEYS列表则是已登记的签名者及其公钥 ID。2. 执行添加命令持有仓库私钥的管理员执行以下命令alice.crt为 alice 的公钥 PEM 文件$ docker trust signer add alice example/trust-demo --key alice.crt Adding signer alice to example/trust-demo... Enter passphrase for repository key with ID 642692c: Successfully added signer: alice to example/trust-demo流程要点命令会提示输入仓库密钥Repository Key口令因为添加签名者需要修改仓库的 targets 委托元数据并签名发布提示中的642692c即上文docker trust inspect显示的 Repository Key 前 7 位 ID。3. 验证添加结果再次执行docker trust inspect --prettyalice已出现在签名者列表中$ docker trust inspect --pretty example/trust-demo No signatures for example/trust-demo List of signers and their keys: SIGNER KEYS alice 05e87edcaecb bob 5600f5ab76a2 Administrative keys for example/trust-demo: Repository Key: 642692c14c9fc399da523a5f4e24fe306a0a6ee1cc79a10e4555b3c6ab02f71e Root Key: 3cb2228f6561e58f46dbc4cda4fcaff9d5ef22e865a94636f82450d1d2234949此后alice即可用自己的私钥通过docker trust sign为example/trust-demo的 tag 签名签名流程详见 trust_sign.md。四、典型场景二在全新仓库上首次添加签名者当目标仓库尚未初始化时docker trust signer add会自动完成仓库初始化并同时建立 root key、repository key 与签名者角色。1. 确认仓库不可访问$ docker trust inspect --pretty example/trust-demo No signatures or cannot access example/trust-demo2. 执行首次添加$ docker trust signer add alice example/trust-demo --key alice.crt Initializing signed repository for example/trust-demo... Enter passphrase for root key with ID 748121c: Enter passphrase for new repository key with ID 95b9e55: Repeat passphrase for new repository key with ID 95b9e55: Successfully initialized example/trust-demo Adding signer alice to example/trust-demo... Successfully added signer: alice to example/trust-demo与场景一相比多出了三个阶段初始化提示要求设置 root key根密钥口令——这是整个信任链的锚点必须妥善保管仓库密钥创建要求为新建的 repository key 设置并重复确认口令签名者登记Successfully initialized之后才进入正常的添加签名者流程。3. 验证初始化结果$ docker trust inspect --pretty example/trust-demo No signatures for example/trust-demo SIGNED TAG DIGEST SIGNERS List of signers and their keys: SIGNER KEYS alice 6d52b29d940f Administrative keys for example/trust-demo: Repository Key: 95b9e5565eac3ef5ec01406801bdfb70feb40c17808d2222427c18046eb63beb Root Key: 748121c14bd1461f6c58cb3ef39087c8fdc7633bb11a98af844fd9a04e208103注意此时 Repository Key 与 Root Key 都是新建的对应交互提示中的95b9e55与748121c。底层原理未初始化仓库的自动初始化从源码看signer_add.go 的addSignerToRepo先通过notaryRepo.ListTargets()探测仓库是否已初始化若抛出client.ErrRepoNotInitialized或client.ErrRepositoryNotExist则进入初始化分支并打印Initializing signed repository for ...if _, err notaryRepo.ListTargets(); err ! nil { switch err.(type) { case client.ErrRepoNotInitialized, client.ErrRepositoryNotExist: fmt.Fprintf(cli.Out(), Initializing signed repository for %s...\n, repoName) if err : getOrGenerateRootKeyAndInitRepo(notaryRepo); err ! nil { return trust.NotaryError(repoName, err) } fmt.Fprintf(cli.Out(), Successfully initialized %q\n, repoName) ...其中getOrGenerateRootKeyAndInitRepo定义于 helpers.go优先复用本地已有的 root keygetOrGenerateNotaryKey否则生成新的 root key随后调用notaryRepo.Initialize([]string{rootKey.ID()}, data.CanonicalSnapshotRole)完成初始化——注意它显式使用远程托管的 snapshot keyCanonicalSnapshotRole这意味着快照角色密钥由 Notary 服务端管理简化了客户端密钥管理负担。五、典型场景三一次命令向多个仓库添加签名者REPOSITORY [REPOSITORY...]支持一次传入多个仓库适合批量登记同名签名者。1. 场景现状两个仓库example/trust-demo与example/trust-demo2均已初始化且存在已签名 tagv1由bob签名$ docker trust inspect --pretty example/trust-demo SIGNED TAG DIGEST SIGNERS v1 74d4bfa917d55d53c7df3d2ab20a8d926874d61c3da5ef6de15dd2654fc467c4 bob List of signers and their keys: SIGNER KEYS bob 5600f5ab76a2 Administrative keys for example/trust-demo: Repository Key: ecc457614c9fc399da523a5f4e24fe306a0a6ee1cc79a10e4555b3c6ab02f71e Root Key: 3cb2228f6561e58f46dbc4cda4fcaff9d5ef22e865a94636f82450d1d2234949$ docker trust inspect --pretty example/trust-demo2 SIGNED TAG DIGEST SIGNERS v1 74d4bfa917d55d53c7df3d2ab20a8d926874d61c3da5ef6de15dd2654fc467c4 bob List of signers and their keys: SIGNER KEYS bob 5600f5ab76a2 Administrative keys for example/trust-demo2: Repository Key: ece554f14c9fc399da523a5f4e24fe306a0a6ee1cc79a10e4553d2ab20a8d9268 Root Key: 3cb2228f6561e58f46dbc4cda4fcaff9d5ef22e865a94636f82450d1d22349492. 一次添加两个仓库$ docker trust signer add alice example/trust-demo example/trust-demo2 --key alice.crt Adding signer alice to example/trust-demo... Enter passphrase for repository key with ID 95b9e55: Successfully added signer: alice to example/trust-demo Adding signer alice to example/trust-demo2... Enter passphrase for repository key with ID ece554f: Successfully added signer: alice to example/trust-demo2命令会依次处理每个仓库且因为两个仓库的 Repository Key 不同会分别提示对应的口令。3. 验证批量结果$ docker trust inspect --pretty example/trust-demo SIGNED TAG DIGEST SIGNERS v1 74d4bfa917d55d53c7df3d2ab20a8d926874d61c3da5ef6de15dd2654fc467c4 bob List of signers and their keys: SIGNER KEYS alice 05e87edcaecb bob 5600f5ab76a2$ docker trust inspect --pretty example/trust-demo2 SIGNED TAG DIGEST SIGNERS v1 74d4bfa917d55d53c7df3d2ab20a8d926874d61c3da5ef6de15dd2654fc467c4 bob List of signers and their keys: SIGNER KEYS alice 05e87edcaecb bob 5600f5ab76a2两个仓库的签名者列表中都出现了alice说明批量添加成功。底层原理best effort 顺序处理源码中 addSigner 对每个仓库执行独立的addSignerToRepo逐仓库打印Adding signer ... to repo...与Successfully added signer: name to repo并采用**尽力而为best effort**策略某个仓库失败不中断后续仓库失败仓库被记录到errRepos切片全部处理完后统一返回Failed to add signer to: repo1, repo2错误。这正是文档中best effort basis的源码对应。六、best effort 行为与失败场景当多个仓库中存在无权限或不存在等失败情况时命令依然会继续处理其余仓库最后汇总错误$ docker trust signer add alice example/unauthorized example/authorized --key alice.crt Adding signer alice to example/unauthorized... you are not authorized to perform this operation: server returned 401. Adding signer alice to example/authorized... Enter passphrase for repository key with ID c6772a0: Successfully added signer: alice to example/authorized Failed to add signer to: example/unauthorized观察要点对example/unauthorized的添加因 401未授权失败但命令并未中断而是继续处理example/authorized授权仓库成功添加后命令返回值为非零错误并列出全部失败仓库失败时签名者不会被登记到example/unauthorized因为 Notary 元数据的发布notaryRepo.Publish()只有在服务端鉴权通过时才会成功。该行为与源码中addSigner的循环结构一一对应循环内errRepos append(errRepos, repoName)收集失败项循环结束后return fmt.Errorf(Failed to add signer to: %s, strings.Join(errRepos, , ))统一报错signer_add.go。七、签名者命名规则与常见错误docker trust signer add对NAME有严格校验规则定义于 signer_add.govar validSignerName regexp.MustCompile(^[a-z0-9][a-z0-9\_\-]*$).MatchString即以一个小写字母或数字开头后续可包含小写字母、数字、下划线_与连字符-。相关校验逻辑如下检查项触发条件报错信息最少参数未提供NAME REPOSITORYrequires at least 2 argument缺少公钥未提供--keypath to a public key must be provided using the --key flag保留关键字NAME为releasesreleases is a reserved keyword, please use a different signer name非法字符如ali/ce含斜杠signer name ali/ce must start with lowercase alphanumeric characters...大写字母如Alice同上必须以小写字母或数字开头首字符非法如_alice同上公钥文件不存在--key指向不存在的文件unable to read public key from file: ...公钥文件内容非法PEM 中无有效公钥could not parse public key from file: ...: no valid public key found这些规则的边界情形在 signer_add_test.go 的TestTrustSignerAddErrors中均有对应测试用例含not-enough-args、no-key、reserved-releases-signer-add、disallowed-chars、no-upper-case、start-with-letter。为何releases是保留字因为 TUF 委托角色targets/releases是已发布版本的汇聚角色——所有已发布的 tag 签名都会同步写入该角色见 sign.go 中addStagedSigner同时向targets/signer与targets/releases添加委托。docker trust inspect中 Repo Admin 对应的正是targets/targets/releases角色见 helpers.go。因此自定义签名者名不能与releases冲突。八、源码级原理一次 signer add 的完整执行链路将前文各场景串联起来docker trust signer add alice example/trust-demo --key alice.crt的完整链路如下命令解析signer_add.goCobra 解析参数options.signer args[0]、options.repos args[1:]--key通过opts.NewListOpts收集为可重复选项名称与公钥校验addSigner正则校验validSignerName、拒绝releases、要求--key非空随后ingestPublicKeys读取并解析 PEM 公钥为 TUFdata.PublicKey逐仓库处理addSignerToRepo通过trust.GetImageReferencesAndAuth解析镜像引用与认证信息以trust.ActionsPushAndPull权限创建 Notary 客户端cli.NotaryClientnotaryRepo.ListTargets()探测仓库状态若未初始化则走getOrGenerateRootKeyAndInitRepo自动初始化构造委托角色名targets/signerdata.RoleName(path.Join(data.CanonicalTargetsRole.String(), signerName))addStagedSigner将签名者公钥写入委托角色并暂存变更notaryRepo.Publish()将元数据签名并发布到 Notary 服务端结果汇总全部仓库处理完后若有失败项则返回Failed to add signer to: ...。其中addStagedSignersign.go完成两个关键动作func addStagedSigner(notaryRepo client.Repository, newSigner data.RoleName, signerKeys []data.PublicKey) error { // create targets/username if err : notaryRepo.AddDelegationRoleAndKeys(newSigner, signerKeys); err ! nil { return err } if err : notaryRepo.AddDelegationPaths(newSigner, []string{}); err ! nil { return err } // create targets/releases if err : notaryRepo.AddDelegationRoleAndKeys(trust.ReleasesRole, signerKeys); err ! nil { return err } return notaryRepo.AddDelegationPaths(trust.ReleasesRole, []string{}) }即新签名者的公钥会被同时登记到两个 TUF 委托角色——targets/signer签名者专属角色与targets/releases已发布版本汇聚角色后者保证了该签名者签出的 tag 能被全局识别为已发布。这就是为什么添加成功后docker trust inspect --pretty既能列出签名者又能在SIGNERS列中关联到已签名 tag 的原因。九、配合使用添加签名者之后的完整工作流docker trust signer add只是签名者生命周期管理的起点与之配套的常用命令如下命令作用参考文档docker trust key generate NAME生成密钥对并加载私钥trust_key_generate.mddocker trust key load KEYFILE加载已有私钥到信任密钥库trust_key_load.mddocker trust signer add NAME REPO [REPO...] --key pub.pem添加签名者本文trust_signer_add.mddocker trust sign IMAGE:TAG用签名者/管理员私钥签名 tagtrust_sign.mddocker trust inspect --pretty REPO查看签名者、已签名 tag 与管理密钥trust_inspect.mddocker trust signer remove NAME REPO [REPO...]移除签名者trust_signer_remove.mddocker trust revoke IMAGE:TAG撤销某个 tag 的签名trust_revoke.md典型完整流程先用docker trust key generate alice生成 alice 的密钥对 → 用docker trust signer add alice example/trust-demo --key alice.pub登记公钥 → alice 用docker trust sign example/trust-demo:v1签名镜像 → 团队用docker trust inspect --pretty example/trust-demo校验签名者与摘要 → 成员离职后用docker trust signer remove alice example/trust-demo回收权限。若某个签名者不再需要其移除会涉及 是否最后一个 release 签名者 的确认提示-f, --force可跳过确认实现细节见 signer_remove.go 的isLastSignerForReleases与 trust_signer_remove.md。十、使用建议与注意事项公钥文件来源优先使用docker trust key generate产出的NAME.pub其 PEM Header 中携带role标记与 Notary 客户端解析逻辑完全兼容外部生成的公钥同样可用但需确保为标准 PEMPUBLIC KEY格式且大小不超过 1 MiB 读取上限。口令安全root key 是整条信任链的根锚一旦丢失将无法管理仓库信任repository key 口令每次添加签名者都会用到建议由团队密钥管理流程统一保管。批量操作的预期多仓库添加是 best effort 的失败仓库会在命令末尾统一列出脚本化调用时应检查命令退出码与输出中的Failed to add signer to:汇总。命名规范签名者名一律小写字母/数字开头可含-与_且不可使用保留字releases。与 DCT 联动只有客户端开启 Content Trust环境变量DOCKER_CONTENT_TRUST1时镜像 pull/push 才会强制执行签名校验签名者登记的效果才会最终体现在供应链安全上。结语docker trust signer add是 Docker Content Trust 中授权签名实体的核心管理入口。本文从官方文档的三个实战场景出发结合 docker-ce 仓库中的 signer_add.go、signer.go、helpers.go、sign.go 等源码与 signer_add_test.go 测试用例完整还原了从公钥准备 → 名称校验 → 委托角色登记 → 元数据发布的全链路实现。掌握了它你就掌握了受信镜像仓库谁能签名这一关键权限维度的增删管理方法可以据此构建多人协作的镜像签名治理流程。赞分享容器运行时云原生【免费下载链接】docker-ce:warning: This repository is deprecated and will be archived (Docker CE itself is NOT deprecated) see the https://github.com/docker/docker-ce/blob/master/README.md :warning:项目地址https://gitcode.com/gh_mirrors/do/docker-ce点击查看免费下载相关推荐docker trust signer remove 完全指南从镜像仓库移除签名者signer的实战与原理docker trust signer remove 完全指南从镜像仓库移除签名者signer的实战与原理 docker trust signer remCLI开发工具Docker Trust Signer 完全指南管理镜像签名者docker trust signer的命令语法与实战Docker Trust Signer 完全指南管理镜像签名者 docker trust signer 的命令语法与实战 导读 本文围绕 Docker CCLI开发工具Docker CLI docker trust 内容信任完全指南镜像签名、密钥管理与签名者协作Docker CLI docker trust 内容信任完全指南镜像签名、密钥管理与签名者协作 docker trust 是 Docker CLI 中用于镜像CLI开发工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考