4.3 打标与推送词条:tag、push 与摘要引用


4.3 打标与推送词条:tag、push 与摘要引用

本节摘要:docker tag 给镜像挂仓库引用名,docker push 把镜像发运到仓库,内容摘要(digest)则是签收时的核对凭据。本节讲清 tag 是改名不是复制的本质、引用名的构成规则、推送输出里层挂载的含义,以及为什么 CI 与生产都改用摘要而不用标签引用镜像。

某天凌晨发布后,有同事问:为什么同一个镜像在仓库里有好几个名字?它们各自占空间吗?删一个名字会删掉镜像吗?这些问题全指向同一条命令——tag。它是仓库部使用频率最高、误解也最深的词条,本节把它与 push 串成完整链路讲透。

命令链条:tag 到 push

docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG] docker push [OPTIONS] NAME[:TAG]

现场一:tag 的本质是再加一个名字

$ docker images myweb REPOSITORY TAG IMAGE ID CREATED SIZE myweb 0.1 8c4e21ab77d2 2 days ago 112MB $ docker tag myweb:0.1 registry.local:5000/myweb:0.1 $ docker tag myweb:0.1 registry.local:5000/myweb:1 $ docker images | grep 8c4e21ab77d2 myweb 0.1 8c4e21ab77d2 2 days ago 112MB registry.local:5000/myweb 0.1 8c4e21ab77d2 2 days ago 112MB registry.local:5000/myweb 1 8c4e21ab77d2 2 days ago 112MB

三个引用名,同一个 IMAGE ID——tag 没有复制任何数据,只是在镜像的内容之上又挂了一块门牌。所以删掉其中一个名字(rmi 输出 Untagged)不占空间也不伤内容,只有最后一个名字被摘掉时层才真正可回收。理解了这一点,"给镜像换个仓库名就能推"这句话才真正落地:push 认的是引用名里的仓库地址部分,tag 就是把地址写进名字的工序。

引用名的完整构成值得背下来:[仓库地址/]命名空间/名字[:标签]。带地址(如 registry.local:5000/...)就推往自建仓库,不带则默认公共仓库;命名空间在公共仓库是账号或组织名。4.2 推送前的 tag 工序,写的正是这个规则。

现场二:push 输出与层挂载

$ docker push registry.local:5000/myweb:0.1 The push refers to repository [registry.local:5000/myweb] c4d1a9e2b3f0: Pushed 9c1b6e4a2f0d: Mounted from library/mybase 8a3e1c9d4b2a: Mounted from library/mybase 0.1: digest: sha256:8b42de6f... size: 1159

逐行读。Pushed 表示该层从本机上传;Mounted from 是仓库侧的妙处——这层内容仓库里已经有了(比如来自之前推过的基础镜像),直接引用现成数据,不用再传。所以第二次推同系镜像通常快得惊人:变的只有应用层,基础层全挂载。这正是贰部分层思想在仓库侧的回响。

⚠️ 常见坑:push 被拒报 denied: requested access to the resource is denied,多数时候不是权限故障,而是引用名里的仓库地址或命名空间写错——它想推去你没有权限的地方。先 docker images 核对引用名,再 docker login 对应仓库,最后重推。

词条卡:digest 摘要引用

$ docker images --digests registry.local:5000/myweb REPOSITORY TAG DIGEST IMAGE ID registry.local:5000/myweb 0.1 sha256:8b42de6f... 8c4e21ab77d2 $ docker pull registry.local:5000/myweb@sha256:8b42de6f...

标签是可变的——同名标签今天与昨天可以指向不同内容;摘要是内容的哈希,内容变则摘要变,不可伪造。两者的差别在发布场景里是事故级的:生产机写 myweb:1,仓库侧有人重新推了同标签,下次拉取拿到的就是另一个镜像;写摘要引用,拉到的永远是你验过的那份。CI 归档产物、生产部署清单,推荐一律用摘要引用。

链路全景:一次发布的完整手续

链路全景:一次发布的完整手续

链路上每一步对应的命令此前都已就位:build 在贰部、tag 与 push 在本节、pull 在贰部、摘要核对在本节。把这条链跑熟,镜像的发布事务就没有黑箱了。

延伸现场:一镜像多牌时的删除语义

把开篇同事的问题收尾:同一镜像挂了多个名字后执行 rmi,删的是名字还是镜像?现场演示:

$ docker rmi registry.local:5000/myweb:1 Untagged: registry.local:5000/myweb:1 $ docker rmi myweb:0.1 Error response from daemon: conflict: unable to delete 8c4e21ab77d2 (must be forced) - image is referenced in multiple repositories

第一条输出只有 Untagged——摘牌,层数据原地不动。第二条报 conflict:这个 IMAGE ID 还挂在 registry.local:5000/myweb:0.1 名下,守护进程拒绝误删,除非 --force。规则一句话:rmi 默认只删名字,轮到镜像的最后一个名字被摘时才动层数据。--force 留给明确知道自己在做什么的时刻,一般它都不该出现。

再补一条 CI 实践:push 之后立即用 docker inspect --format '{{index .RepoDigests 0}}' 取回执摘要写进部署清单。日后生产对账,清单上的摘要与仓库现值逐字比对,就能确认线上跑的正是验收过的那份——比按标签部署再翻日志求证省心得多。

本节要点回顾

  • tag 是挂名不是复制:同 IMAGE ID 多引用名,摘牌不删层数据。
  • 引用名决定去向:地址部分写清仓库,denied 报错先查名字再查登录。
  • Mounted from 是仓库侧的层复用:同系镜像二次推送近乎瞬完。
  • 摘要引用防标签漂移:CI 归档与生产部署按 digest 取货,回滚就是换摘要。
  • 推送回执必须留档:digest 是这次发布内容在宇宙里的唯一指纹。

镜像的进出港手续到此齐备。叁部的容器删了数据就没了?伍部数据部专治这个不服:卷、绑定挂载与临时盘。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U