资讯详情

Docker镜像管理实战:拉取、查看、删除、打标签与离线导出全攻略

📅 2026/10/22 4:41:31 | 华诺云谱 👁 阅读
Docker镜像管理实战:拉取、查看、删除、打标签与离线导出全攻略
说个实在话Docker入门这件事很多人卡住的位置不是安装不是写Dockerfile而是搞不明白镜像到底怎么玩。前面那篇一我们聊了Docker的整体概念和第一支容器怎么跑起来这篇我重点把镜像这块的“日常操作全家桶”讲透拉取、查看、删除、打标签、导出导入、推送到仓库以及我在真实环境里踩过的那些坑。目标很直接看完这篇你能像用手机装App一样熟练地管理Docker镜像而且知道每一步背后为什么这么做。这篇文章适合正在学Docker、已经能跑通docker run hello-world但面对docker images里一堆镜像不知道下一步干什么的读者。也适合那些在生产环境里被镜像清理、版本回滚、离线交付折磨过的运维同事。看完你可以直接照着操作本地环境敲一遍基本就通了。1. 镜像和容器的关系再捋一遍很多人命令背得滚瓜烂熟但一遇到问题就懵根子在于没把“镜像-容器”这对关系吃透。镜像可以理解成一台计算机的“硬盘克隆模板”里面预装了操作系统的基础文件、你想要的软件、配置好的一些环境变量全部打包成一套只读数据。容器则是这个模板每次被你启动出来的“活体实例”——它多了可写层里面有运行时的日志、临时文件、程序产生的数据。1.1 镜像的分层存储是怎么回事Docker镜像不是一个大文件而是由很多只读层Layer堆叠起来的。每一层对应Dockerfile里的一条指令或者说对应制作镜像时的一次文件系统变更。拉取镜像时看到的Pulling fs layer就是在拉这些层。这种分层设计带来两个好处第一是共享多个镜像可以公用底层的基础层。比如你的nginx镜像和redis镜像可能都基于同一个操作系统基础层本地只存一份就够了这也是为什么多个镜像加起来的总磁盘占用比想象中小的原因。第二是增量更新版本时只需要拉取有变化的层不需要整个重下。理解了层次你就明白了为什么删除镜像时偶尔看到删除好几个层以及为什么镜像构建时要尽量把不常变动的指令写前面。1.2 镜像在磁盘上到底是什么形态镜像在Docker环境内有自己的存储目录Linux上通常在/var/lib/docker/下面采用的内容寻址存储方式镜像层的内容通过哈希值来标识和校验。这些你不用直接操作但要知道镜像是分层的、内容寻址的、只读的。记住这三个词后面遇到docker save出来的包比想象中大或者小、docker images显示的镜像大小和实际占用不一致时你就不会一头雾水。注意docker images列表里显示的SIZE是镜像所有层的总大小如果多个镜像共享了同一层磁盘上实际占用并不是简单累加。1.3 一个镜像能启动出多少容器没有限制。同一个镜像可以同时启动十个八个容器它们之间互不干扰因为每个容器在镜像只读层之上挂了自己的可写层。这也是“一个镜像模板多次实例化”的思想。换句话说镜像解决的是“我要什么环境”容器解决的是“我现在就要跑起来”。2. 拉取镜像别只盯着latest不放手拉取镜像是使用Docker的第一步命令一看就会但里面的细节值得掰开揉碎讲一下。2.1 基本命令和镜像命名规则拉一个镜像的完整写法是docker pull [选项] 仓库地址/命名空间/镜像名:标签比如docker pull nginx:1.25-alpine拆解一下nginx是镜像名也是Docker Hub官方镜像的简写1.25-alpine是版本标签alpine后缀表示这个镜像采用Alpine Linux作为底层系统体积小。如果你不写标签默认是latestdocker pull nginx等价于拉取nginx:latest。2.2 为什么不建议在关键环境用latest这个问题我在团队里反复强调过。latest是一个流动标签官方更新大版本或者调整配置后同一时间点不同机器上docker pull nginx拉到的内容可能不一样。今天你的测试环境跑的是1.25明天重新部署就变成了1.27行为可能完全不同。到时候排查半天发现是镜像版本悄悄变了特别被动。在生产环境、脚本、编排文件里务必指定具体的版本标签。这样每次拉取内容可预期回滚也方便想回到旧版本只需要把标签改回去重新pull。实践里我还会用-alpine、-slim这类精简版本来节省磁盘和内存。但要注意精简版往往砍掉了很多调试工具比如bash都没有只有sh网络排查工具如curl、ping可能也不存在。适合追求部署效率的场景如果你进容器要经常调试还是用标准镜像顺手。2.3 拉取慢的解决思路从官方仓库拉取镜像在国内网络环境经常慢到怀疑人生。最常见的解决方式不是换源下载而是给Docker配置一个registry mirror也就是镜像源。修改Docker的配置文件/etc/docker/daemon.json{ registry-mirrors: [https://换成你网络中可用的镜像源地址] }改完后执行systemctl restart docker。这里不展开推荐具体哪家因为可用的公共镜像源一直在变你只需要知道配置原理Docker在拉取仓库时会先问配置的镜像源要数据源那边往往有缓存速度会好不少。注意配置生效后拉取镜像的地址写法不变对使用者完全透明。重要配置完registry-mirrors后如果发现镜像拉取正常了别高兴太早。到另外一台机器上部署时记得这台机器也要配或者直接把Docker配置纳入统一的初始化脚本里否则就变成只有你本机快换台机器又回到慢吞吞的状态。2.4 拉取过程中的状态怎么看执行docker pull时输出里有一堆Pull complete、Digest: sha256:...很多人直接略过。简单解释一下Pulling fs layer准备拉取分层数据Downloading下载层内容Extracting下载完成解压到本地存储Pull complete这一层就绪层下载是并行的所以你会看到多个层同时跳动。最后出现Digest是镜像清单的哈希用来做内容校验。如果下次再拉同一个镜像且内容没变Docker会直接显示Up to date或者只有部分层需要下载。3. 查看和管理本地镜像这些命令要形成肌肉记忆镜像拉下来之后日常打交道最多的就是docker images系列了。别觉得它简单很多排查技巧都藏在这几个命令里。3.1 docker images到底在看什么先看一个典型输出REPOSITORY TAG IMAGE ID CREATED SIZE nginx 1.25.3 2b7d6d9f3c1a 2 weeks ago 192MB redis 7.2 e4d3b4f2c1d8 4 weeks ago 117MB none none a2c1d3e4f5b6 6 weeks ago 85MB五列含义分别是仓库名、标签、镜像ID、创建时间、体积。其中IMAGE ID是镜像的唯一标识前面12位是完整哈希的缩写你可以在任何需要指定镜像的地方用它来代替名字比如docker rmi 2b7d6d9f3c1a。上面那个仓库名和标签都是none的就是悬空镜像。它产生的原因通常是同名同标签的新镜像覆盖了旧镜像旧镜像失去了标签关联但数据层还在磁盘上。悬空镜像本身没用还占空间需要定期清理。3.2 过滤和格式化输出镜像多了以后直接用docker images看起来费劲两个实用技巧# 按仓库名过滤 docker images nginx # 按标签过滤 docker images nginx:1.25 # 按悬空过滤 docker images -f danglingtrue # 自定义格式只输出镜像ID和仓库名 docker images --format {{.ID}} {{.Repository}}--format用的是Go模板语法不需要背用到时查一下就行。关键是知道Docker支持结构化输出这在写自动化脚本、巡检磁盘占用时非常有用。3.3 docker inspect是排查问题的放大镜想看得更细用docker inspect 镜像ID。它会输出一大段JSON包含镜像的架构、操作系统、环境变量、默认命令、端口暴露、分层数据等。比如排查“这个镜像默认跑了什么命令”就用它查Config.Cmd想确认镜像暴露了哪些端口查Config.ExposedPorts。拿到这个信息你就能预判容器启动后的行为不用盲猜。3.4 删除镜像的正确姿势与常见翻车现场删除镜像是docker rmi一次可以删多个docker rmi nginx:1.25 redis:7.2翻车点在于容器还在运行时它依赖的镜像删不掉。Docker会返回冲突错误提醒你镜像正被容器使用。这时候先停容器、删容器再来删镜像。所以正确的清理顺序是容器 - 镜像。还有一个隐蔽的问题你删掉了某个镜像的标签以为释放了空间但查看磁盘还是占得满满当当。因为可能还有别的镜像依赖它的分层或者留下了悬空镜像。这时候用docker system df看空间分布再用清理命令# 清理所有悬空镜像 docker image prune # 清理所有未被容器使用的镜像慎用 docker image prune -aprune -a会把没有容器引用的镜像全部清掉包括你辛苦拉下来备用的旧版本。用了默认latest标签的团队尤其要小心建议执行前先docker ps -a确认哪些容器还在或者先导出备份再清理。4. 镜像的导出与导入离线交付和备份的救命稻草在没有外部网络的环境里部署Docker是最常见的需求之一。这时候docker pull用不了就得靠docker save和docker load这对组合。4.1 docker save与docker load的标准用法# 把镜像保存成tar包 docker save nginx:1.25-alpine -o nginx-1.25-alpine.tar # 在目标机器上导入 docker load -i nginx-1.25-alpine.tarload执行完镜像的仓库名和标签都会保留下来直接docker run就行不用重新tag。如果tar包太大可以配合gzip压缩docker save nginx:1.25-alpine | gzip nginx-1.25-alpine.tar.gz # 导入时直接支持压缩格式 docker load -i nginx-1.25-alpine.tar.gz实测下来docker load能自动识别gzip压缩包不需要先解压再导入省一步操作。4.2 别把save和export搞混了这是很多入门者踩过的坑。docker export导出的是容器的文件系统快照而docker save导出的是镜像本身。具体区别我列个表维度docker savedocker export操作对象镜像容器是否保留镜像历史层保留完整分层结构扁平化只保留当前文件系统是否保留标签/CMD等元数据保留不保留导入方式docker loaddocker import典型场景镜像迁移、离线部署检查容器内文件系统、容器级备份如果你误用了export导出一个镜像跑起来的容器再import回来会得到一个没有CMD、没有ENTRYPOINT、没有健康检查、标签也丢失的裸镜像。启动时要么手写完整docker run命令要么进容器手动起进程极其别扭。经验要交付运行环境永远用docker save/load要临时看看容器文件系统里到底有什么才考虑export。别偷懒混用踩一次坑就记住了。4.3 多架构镜像的保存与分发docker pull默认拉取的是当前平台对应的镜像比如在ARM服务器上就拉ARM版本的。docker save保存下来的也只是当前平台的镜像。如果你要跨架构分发比如把一份镜像同时部署到x86和ARM机器上选择之一是拉取多架构清单或者分别在对应架构的机器上pull再save。这个问题在混合架构机房很常见处理思路通常是根据目标机器的架构分流而不是试图用一个包解决所有架构。更复杂的多架构清单管理涉及构建和仓库侧能力入门阶段先记住save/load是跟着平台走的。5. 给镜像打标签与内网仓库推送镜像操作里最容易被忽略、但实际工作中最重要的部分是docker tag和docker push。没有这两招你永远只在公共仓库和本机之间打转无法建立自己的镜像流转体系。5.1 docker tag到底在干嘛docker tag不是重命名镜像而是给同一个镜像多贴一个标签。底层逻辑是镜像ID不变但多了个可读的名字指针。语法是docker tag 源镜像名:原标签 目标镜像名:新标签典型的用法是把本地镜像改造成符合仓库规范的完整名字# 给本地nginx镜像打一个新的完整仓库标签 docker tag nginx:1.25-alpine 127.0.0.1:5000/mynginx:1.25这条命令执行后本地相当于出现了两个标签都指向同一个镜像ID。docker push 127.0.0.1:5000/mynginx:1.25时推送的就是这个新标签指向的内容。理解了标签是可叠加的你就明白删除镜像时docker rmi后面跟的标签只是删掉一个引用只有该镜像的所有标签都删完且没有容器用它真正的内容才会被回收。5.2 搭建一个最简内网镜像仓库私有仓库用官方开源的registry方案就够了。启动起来非常简单docker run -d -p 5000:5000 --name my-registry --restartalways registry:2几分钟内你就有一个监听在5000端口的内网镜像仓库。之后把镜像tag成127.0.0.1:5000/镜像名:标签再推上去docker tag nginx:1.25-alpine 127.0.0.1:5000/mynginx:1.25 docker push 127.0.0.1:5000/mynginx:1.25其他机器要从这个仓库拉镜像同样把镜像地址写成127.0.0.1:5000/mynginx:1.25。如果是远程访问把127.0.0.1换成这台仓库机器的IP即可。5.3 仓库地址的HTTP凭证问题这个坑十个人有八个人会踩。默认情况下Docker要求仓库走HTTPS加密连接而你本地搭的这个registry只有HTTP。直接执行docker login 127.0.0.1:5000大概率报错提示http: server gave HTTP response to HTTPS client。解决办法是修改Docker配置文件把这个仓库地址加入insecure-registries白名单让Docker允许访问不加密的HTTP仓库{ insecure-registries: [127.0.0.1:5000] }重启Docker后重试。这个配置只建议用于内网可信环境。公网环境的仓库一定要配好证书走HTTPS否则镜像内容和登录凭证在网络传输中是明文这是底线问题。5.4 push和pull的命名对称性Docker里push和pull是严格对称的推送时写的完整镜像名拉取时必须写一样的包括仓库地址、命名空间、标签。很多人推上去简单写了push 127.0.0.1:5000/nginx:1.25但在目标机器上只写pull 127.0.0.1:5000/nginx结果不匹配不是拉下来的是latest的旧包就是直接manifest unknown。养成习惯推送时怎么写的拉取时就怎么抄。6. 常见问题与排查技巧实录最后这部分我把实际使用中频率最高的问题做个速查汇总。每一个我都亲自遇到过给出的是经过验证的处理方式。报错或现象常见原因处理方法manifest unknown仓库里没有这个标签先查仓库里的标签列表确认版本号写对了pull access denied没有权限访问该仓库或镜像docker login登录或确认镜像名是否属于你的账号image operating system cannot be used on this platform架构不匹配换对应架构的镜像或使用支持多架构的镜像重新拉取Got permission denied while trying to connect当前用户不在docker组执行sudo usermod -aG docker 当前用户名后重新登录或使用sudo dockerno space left on device磁盘写满包含悬空镜像、日志、构建缓存用docker system df看分布docker image prune清悬空必要时docker system prune -a还要看容器日志容器删了但镜像删不掉可能还有别的标签指向它docker images -a看看所有标签全部删除或直接用docker rmi 镜像ID -f慎用容器正常但镜像无法删除容器在运行中先docker rm -f 容器名再删镜像6.1 镜像占用空间的隐藏杀手docker image prune -a之后你会惊奇地发现磁盘空间并没有释放很多。因为真正占空间的往往是停止的容器自带的可写层、构建缓存、日志文件。这几个位置经常被忽略。排查手法依次是# 看各对象占用 docker system df # 删除所有停止的容器 docker container prune # 删除构建缓存 docker builder prune # 如果确实想清理趋于全部干净 docker system prune -a --volumes最后一条要谨慎。-a会清掉所有未被使用的镜像--volumes会删掉未被容器挂载的命名卷数据一旦删除不可恢复。执行前确认不是生产环境或已做备份。6.2 架构不匹配的处理细节ARM机器上运行镜像报平台错误通常出现在把x86架构的镜像直接搬到ARM服务器上或者反过来。现在很多常用镜像都发布了多架构版本直接拉取Docker会自动匹配平台。老镜像或者冷门镜像可能只有单一架构那就只能找对应架构的替代版本没有人能绕过。如果你在开发机上构建了一个x86的镜像想给家里的ARM小主机用不能直接把docker save的包拿过去load那样运行时照样报平台错。要么在目标机上重新build或pull要么用支持多架构构建的方案提前解决问题。入门阶段不深挖构建链但记住这句话能少走弯路。6.3 日志导致的空间暴涨镜像只占镜像的份额容器日志却可能悄悄吃掉整个磁盘。一个基础镜像才100多MB但一个运行了三个月的容器标准输出日志可能膨胀到几十GB。这种问题靠docker system prune清不干净正确做法是限制日志大小在Docker配置里加log-opts限制日志文件和大小或者用日志轮转机制。这个主题展开又是一篇文章这里只是提醒一点——排查磁盘异常时镜像背锅往往不冤但最狠的嫌疑人其实是日志。最后再说两句实在话镜像管理说到底就是一套增删查改再加传输的循环。把docker pull、docker images、docker rmi、docker tag、docker save这几个命令练成肌肉记忆Docker对你来说就不再是黑盒了。我个人在实际操作里最大的体会是每一条镜像操作命令背后都要想清楚它在动分层、标签还是仓库元数据想清楚了你就能在出问题时快速定位而不用把Docker数据目录翻个底朝天。把这篇文章打开开一个终端跟着把命令敲一遍。不需要多就五条拉一个指定版本的镜像查看它打个新标签导出再导入最后启动一个容器。跑通了你对Docker镜像的感觉就完全不一样了。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑