news 2026/10/2 9:22:34

Docker命令知识点:打通镜像、容器与网络的逻辑链

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Docker命令知识点:打通镜像、容器与网络的逻辑链

Docker命令知识点1:把镜像、容器和网络这条逻辑链打通

我一直跟团队里的新人说,Docker命令背下来没用,你得把它的逻辑链打通。镜像怎么来的、容器怎么跑的、网络怎么通的、数据怎么存的,这几件事在脑子里串成一条线之后,你会发现那些看起来眼花缭乱的docker命令,其实就那么几类,每一类都有自己清晰的套路。这篇文章就是围绕这个目标来写的,适合刚装好Docker Desktop、正准备跑第一个容器的初学者,也适合用了几个月但全靠复制粘贴、遇到问题就懵的开发者。我把日常最高频的docker命令按场景拆开,讲清楚每条命令背后的原理和踩过的坑,保证你读完能自己排查问题,而不是继续到处搜答案。

1. 先把核心概念和命令逻辑理顺

1.1 镜像和容器的关系,以及命令参数的基本规律

理解Docker命令之前,必须先搞清楚镜像和容器到底是什么关系。我的类比一直是:镜像就是"安装包"或者"模板",容器就是"安装包运行起来之后的那个进程实例"。你用同一个镜像可以启动十个容器,它们彼此隔离互不影响,就像你用同一个Word模板创建了十份不同的文档一样。这个关系一旦建立起来,很多命令的命名逻辑就自然记住了——凡是操作镜像的命令,动词后面跟的是镜像名;凡是操作容器的命令,动词后面跟的是容器ID或名字。

Docker命令的通用格式是docker [全局参数] 对象类型动词 [对象名] [参数]。比如docker run nginx里面,run是动词,nginx是镜像名,实际操作的是镜像和容器的交界处——它先检查本地有没有nginx镜像,没有就去仓库拉取,然后基于这个镜像创建并启动一个容器。理解了这套结构,你看到docker pull、docker push、docker rm、docker rmi的时候,就不会搞混rm和rmi了——rm是remove容器,rmi是remove镜像,多一个字母i指代image。

还有一个容易忽略的点:docker命令的帮助系统。docker --help告诉你有哪些子命令,docker run --help告诉你这个子命令支持哪些参数,docker help run跟它等价。我见过太多人卡在某个参数上直接搜百度,其实先跑一下帮助命令往往几秒钟就解决了。Docker的命令行帮助写得非常完整,每个参数都有说明和默认值,这应该成为你的第一求助对象,而不是搜索引擎。

1.2 命令体系的分类记忆法

Docker命令虽然多,但按操作对象分就三类:镜像操作、容器操作、系统与网络操作。再把动词按动作分:增删改查、启停、交互。这样交叉下来,其实每类命令不会超过十几个。

我建议初学者不要一上来就背docker run的一大堆参数,而是先掌握一个最小闭环:docker pull拉镜像,docker run跑容器,docker ps看容器,docker exec进容器,docker stop停容器,docker rm删容器。这七个命令撑起了日常80%的工作。等你对这几个命令已经很熟悉了,再往run命令里逐步添加端口映射、数据卷、环境变量这些参数,会轻松很多,因为这些参数本质上是在回答"容器跑起来之后,它跟外面怎么通信、数据存哪里、用什么样的配置"这些问题。

2. 镜像管理命令:从拉取到清理的完整操作手册

2.1 镜像仓库地址三段式和拉取细节

docker pull是从镜像仓库拉取镜像的命令。这里有一个非常关键但很多人没搞懂的概念:镜像的完整名称其实是[仓库地址]/[命名空间]/[镜像名]:[标签]三段式。我们平时敲的docker pull nginx,其实是简写,默认的仓库地址是Docker Hub官方仓库,默认的标签是latest,默认的命名空间是官方库的library。

这个三段式意味着什么?意味着你可以从任意一个registry仓库拉取镜像,只要地址正确。很多企业内部的镜像仓库,拉取命令是docker pull registry.internal.example.com:5000/teamname/appname:v1.2.3,这种长名字在docker images列表里也会完整显示。新手最容易犯的错是把镜像名里的冒号当成端口号,其实冒号后面是版本标签。如果漏写了冒号和标签,默认拉取latest,而生产环境强烈不建议依赖latest,因为它指向的版本可能是会漂移的。

拉取镜像的时候还经常遇到网络问题。Docker Hub在国内的访问速度时好时坏,常规的做法是给Docker配置镜像加速器。Docker Desktop的设置里找到Docker Engine,修改registry-mirrors配置即可。但要注意,某些公共加速器后来关停了,配置完记得用docker pull拉一个实际镜像验证效果,不要配了就以为万事大吉。验证方法很简单:docker info的输出里会显示Registry Mirrors列表,确认你配置的地址在里面,然后实测拉取速度。

2.2 镜像的查看、标记、删除与导入导出

docker images列出本地已有的镜像列表,带-a参数可以看到所有层级的镜像,带--digests可以看摘要信息。这个命令的重点不是列出来,而是读懂输出:REPOSITORY列是镜像名,TAG列是版本,IMAGE ID列是镜像ID的前12位,SIZE列是镜像解压后的大小。镜像ID是SHA256的短哈希,同一个镜像即使被打了不同标签,镜像ID是一样的,这说明它们底层共享同一份数据。

docker tag是给镜像打标签的命令。它的本质不是复制镜像,而是给同一个镜像ID添加一个别名引用。理解了这点,你就明白为什么docker tag nginx nginx:backup之后用docker images会看到两行记录但IMAGE ID相同,磁盘占用没有翻倍。tag命令的全格式是docker tag 源镜像名:源标签 目标镜像名:目标标签,常用于把本地镜像打上私有仓库的完整地址,为docker push做准备。

删除镜像用docker rmi,注意这个命令只能删除没有被容器使用的镜像。如果你启动过某个镜像的容器但没删容器,docker rmi会报错image is being used by stopped container,这时候你得先docker rm删掉那个容器,或者用docker rmi -f强制删除——但我不推荐强制删,因为容易留下悬空镜像。镜像导入导出用docker save和docker load,这组命令用于离线环境迁移镜像,docker save -o nginx.tar nginx:latest把镜像保存成tar文件,docker load -i nginx.tar再导入。"save/load"和"export/import"是两套容易混淆的命令,前者操作镜像、保留历史层和元数据,后者操作容器文件系统、丢弃历史、体积更小,打包的是容器快照而不是镜像,这俩用错场景会出问题——比如export出来的包无法用docker tag重新打标签,也无法push到仓库。

清理本地不用的镜像和时间悬空的数据卷,我一般用docker image prune -a加docker volume prune配合。但这两个命令都要谨慎,-a会把没有被容器使用的镜像全部删掉,包括那些你事先想保留的。所以执行prune之前,先docker images确认一遍要保留的镜像是否在跑。我在生产服务器上踩过一次坑,本来想清理临时构建的中间层镜像,结果docker system prune -af把所有没在运行的容器和没被使用的镜像全清了,连回滚用的旧版本镜像都没了,从那以后我清理命令都会看清楚参数再执行。

2.3 镜像背后的分层存储原理

镜像的一个核心特性是分层存储。每一条构建指令对应一个只读层,docker pull的时候,如果本地已经有某些层,只会下载缺失的层,这就是为什么同一个基础镜像拉多个应用镜像时速度较快。docker history 镜像名可以查看镜像的历史构建记录,能看到每一层执行了什么指令、大小多少。排查镜像体积过大问题时,这个命令特别有用——你能直观地看到是哪一层塞进了不该有的文件。另一个相关的因素是,容器内删除文件不会缩减镜像大小,因为新增的层记录了删除操作,但下面那一层的数据还在,这叫写时复制机制下的"层不可变",理解了这一点就不会对镜像越用越大感到奇怪了。

3. 容器生命周期:run、ps、exec这些命令的真实用法

3.1 docker run的核心参数拆解

docker run是整个Docker命令行里最复杂、最常见的命令,因为它后面可以挂几十个参数。但我不建议死记硬背,只需要明白:run的参数是在回答"这个容器应该怎么跑起来"这个问题。我把常用参数按职责分成了五组。

第一组是运行模式:-d后台运行,-it交互式前台运行(OpenStdin + TTY)。为什么老是看到docker run -it这个组合?因为你要在容器里操作终端,就必须加-i(保持标准输入打开)和-t(分配一个伪终端),只用其中一个会导致操作异常。第二组是端口映射:-p 宿主机端口:容器端口,这里要注意映射的方向是"外面到里面",比如-p 8080:80表示宿主机的8080端口转发到容器的80端口。第三组是数据持久化:-v 宿主机目录:容器目录,或者用更规范的--mount type=bind,source=...,target=...语法。第四组是资源限制:-m限制内存,--cpus限制CPU核数,不设限制的话容器可以吃掉宿主机全部资源,等于是个隐患。第五组是环境变量:-e 键=值,很多镜像靠环境变量来配置,比如MySQL的MYSQL_ROOT_PASSWORD。

以一个最常见的MySQL容器为例,完整的启动命令是:

docker run -d \ --name mysql8 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD=yourpassword \ -e TZ=Asia/Shanghai \ -v /data/mysql:/var/lib/mysql \ mysql:8.0

这条命令的意思是用后台模式启动一个叫mysql8的容器,宿主机3306端口映射到容器3306,设置了root密码为yourpassword、时区为上海,容器里的数据目录挂载到宿主机的/data/mysql,使用mysql 8.0版本镜像。这里面最容易出问题的是挂载目录和权限:宿主机的/data/mysql目录如果不存在,Docker会帮你创建,但创建出来的目录属主可能不是容器内MySQL进程的uid,启动时可能报权限错误。这种情况下,一个常见的解决思路是手动chown调整目录权限,或者指定一个已准备好的属主一致的目录。

关于docker run和docker start的区别,也值得强调一下:docker run是"创建新容器并启动",docker start是"启动一个已经存在的容器"。如果你以为docker run nginx能重新启动之前那个容器,就错了,它会再创建一个全新的容器,这也是新手看到一堆同名容器堆积的原因之一。

3.2 ps、logs、exec、attach和容器的状态流转

docker ps查看当前正在运行的容器列表,-a参数查看所有状态的容器(包括已退出和已创建的),-q只显示容器ID,这个参数在批量操作时非常有用,比如docker stop $(docker ps -q)一键停掉所有运行中的容器。--filter参数可以按条件过滤,最常用的是--filter "name=mysql"按名字筛选,--filter "status=exited"查看已经停止的容器。

容器状态流转是一条清晰的路径:Created(已创建未启动)、Running(运行中)、Paused(已暂停)、Exited(已退出)、Dead(死亡)。docker stop是优雅停止,先给容器内主进程发SIGTERM信号,等待超时才发SIGKILL;docker kill是直接发SIGKILL强杀。在需要快速释放端口、但进程卡死不退的场景下,kill比stop更好用。docker restart等价于先stop再start。

docker logs查看容器日志,最常用的参数是-f(跟踪输出)、--tail 100(只看最后100行)、-t(带时间戳)。查看MySQL容器启动失败的原因、查看应用崩没崩,全靠它。注意docker logs显示的是容器内PID 1进程的标准输出,应用必须把日志写到stdout而不是文件里,否则logs什么都看不到。

进入运行中的容器有两条常用命令:docker exec -it 容器名 bash和docker attach 容器名。这两个的差别很关键:exec是在容器里新建一个进程,你在这个进程里做的操作不会影响容器主进程,退出exec也不会让容器停掉;attach是连接到容器的主进程,你输入的内容会直接发给它,退出attach往往会让容器跟着停掉。所以日常调试一律用exec,别用attach。还有一个高频错误是exec的参数顺序:docker exec -it 容器名 bash是先参数后容器名再命令,很多人写成docker exec 容器名 -it bash,会报错误。原因在于Docker命令行工具的解析方式——它把第一个非选项参数当作容器名,后面的参数原样传给容器内要执行的命令。

最后说下删除容器:docker rm只能删已停止的容器,运行中的容器会提示冲突,需要docker rm -f强制删除(等价于先kill再rm),或者先docker stop再docker rm。批量清理已退出的容器用docker container prune,这个命令会删除所有处于Exited状态的容器,不会动运行中的,相对安全。

4. 网络与数据卷:容器之间到底怎么通信

4.1 三种网络模式和自定义网络的实际应用

docker网络连接这块常见的问题,我从docker network命令讲起。安装Docker后默认有三个网络:bridge(桥接)、host(主机)、none(无网络)。默认创建的容器都挂在bridge网络下,容器通过NAT方式访问外网,宿主机通过端口映射访问容器。

网络模式在docker run中通过--network参数指定。host模式是容器直接使用宿主机网络栈,没有隔离,端口也不需要映射,性能最好,但安全性差、容易端口冲突;none模式是完全没有网络,用于某些安全要求高的场景;自定义bridge网络则是最推荐的生产环境方案,因为它自带了DNS解析功能——你在自定义网络里可以通过容器名直接访问其他容器,而不需要查IP。

自定义网络的创建和使用:

docker network create my-net docker run -d --name nginx-demo --network my-net nginx docker run -it --rm --network my-net curlimages/curl curl http://nginx-demo

第二个容器通过容器名nginx-demo访问到了第一个容器里的nginx服务。这在没自定义网络时是不可行的——默认bridge网络下,容器间只能通过IP访问,但容器重启后IP会变,写死IP等于埋雷。所以凡是需要容器间通信的场景,比如nginx反代后端应用、微服务调用,都应该把相关容器放进同一个自定义网络。

排查网络不通的高频步骤,我一般按这个顺序走:先docker network ls看容器挂在哪个网络;再docker inspect 容器名的NetworkSettings部分看IP和网络详情;然后进入容器执行ping或telnet测连通性,比如docker exec 容器名 telnet 目标IP 端口看端口通不通;最后检查是否跨了不同的自定义网络。跨自定义网络默认是不通的,解决方式是把容器加入另一个网络:docker network connect my-net 容器名,这个命令可以给已经在运行的容器额外加网卡,不需要重启。

4.2 数据卷的本质:不销毁、可共享、能备份

容器是临时性的,删除容器后里面的数据也一起没了,所以必须用数据卷。docker命令行处理数据持久化的方式有三种:bind mount(绑定挂载)、volume(数据卷)、tmpfs(内存挂载)。

bind mount就是把宿主机的某个目录直接映射到容器内目录,宿主机改文件容器立刻能看到,适合开发调试场景,但可移植性差,换个机器路径就变了。volume是由docker管理的目录,存放位置在/var/lib/docker/volumes/下,创建方式docker volume create mydata,挂载时-v mydata:/data,不占宿主机具体路径、迁移方便、支持docker volume backup这类工具备份数据,生产环境首选。tmpfs是直接写内存的,容器停了数据就没,速度极快,适合存临时缓存。

在docker run里挂载数据卷时,我强烈建议用--mount语法而不是-v:

docker run -d \ --name mysql8 \ --mount type=volume,source=mysql-data,target=/var/lib/mysql \ mysql:8.0

为什么推荐--mount?因为它的键值对清晰,source、target、type一目了然,特别是目录路径带空格或特殊字符时,-v的斜杠拆解很容易出错。--mount语法还有一个隐藏好处:如果你指定的volume不存在,它会自动创建,这一点对搭建环境来说省心不少。

查看数据卷用docker volume ls,清理无主数据卷用docker volume prune。特别注意:删除容器时docker rm containerName不会删除关联的数据卷,需要用docker rm -v或者在确认数据已备份后手动删volume,这也意味着你在测试时反复创建容器,数据卷会一直攒着,时间久了占不少磁盘。我见过一台开发机被几十个孤立的mysql数据卷撑爆磁盘的案例。

4.3 docker cp:容器和宿主机之间的文件传输

开发调试的时候经常需要在容器和宿主机之间拷贝文件,这就要用docker cp。用法很简单:宿主机文件拷进容器是docker cp ./app.jar 容器名:/app/app.jar,容器文件拷出来是docker cp 容器名:/etc/nginx/nginx.conf ./nginx.conf.bak。

注意docker cp的制作方向:它不管容器是运行中还是已停止,都能操作,因为它是直接操作容器的文件系统层,不需要容器进程参与。这个命令适合少量文件的临时拷贝,不适合大数据量的持久同步,后者应该用挂载解决。拷贝大文件时,如果碰到Permission Denied,多半是容器内目标路径的属主和权限问题,可以加--follow-link参数处理符号链接场景,或者进入容器查看目标目录的权限设置。

5. 一学就会的容器编排进阶:Dockerfile和Compose

5.1 Dockerfile核心指令的完整拆解

docker build从Dockerfile构建镜像,这条命令把构建上下文中的所有文件打包发送给Docker守护进程,然后逐条执行Dockerfile里的指令。这里有个"构建上下文"的概念:docker build .中的点,指的不是Dockerfile所在路径那么简单,而是整个目录会被当作构建上下文,目录越大,打包上传越慢。所以大型项目一定要写.dockerignore文件,把node_modules、target、.git这些大目录排除在外,否则构建时间长到怀疑人生。

Dockerfile的指令按执行顺序,我觉得最常用的是这几个。FROM指定基础镜像,必须是第一条非注释指令,选基础镜像的关键是体积和安全性——尽量选alpine或slim版本,一个ubuntu基础镜像200MB起步,alpine才几十MB。WORKDIR切换工作目录,这是一个容易被忽略但很重要的指令,它相当于cd,建议每条RUN、COPY、CMD之前都明确指定WORKDIR,避免路径混乱。COPY把构建上下文中的文件复制进镜像,ADD在COPY的基础上支持解压tar包和远程URL,但官方建议优先用COPY,因为ADD的行为隐式较多、可预期性差。RUN在构建阶段执行命令,是安装依赖、编译代码的地方。EXPOSE声明容器运行时监听的端口,注意它只是元数据声明,真正让端口可访问还是要靠运行时的-p参数。CMD和ENTRYPOINT定义容器启动时执行的命令,它们的关系可以这样理解:ENTRYPOINT是主程序入口,CMD是默认参数。如果Dockerfile里写了CMD ["nginx", "-g", "daemon off;"],docker run 镜像名 -t会用-t覆盖掉CMD的默认参数;而ENTRYPOINT就没那么容易覆盖。

多阶段构建是控制镜像体积的实战利器。比如Java项目构建,第一个阶段用maven镜像编译出jar包,第二个阶段用jre镜像只拷贝jar包运行,这样最终的镜像不包含任何编译工具链,体积能小一半以上。实现方式是Dockerfile里写多个FROM,每个FROM开启一个新构建阶段,最后一个阶段默认是最终镜像。

5.2 docker compose:用文件声明代替交互输入

docker compose是把多个容器的配置写进一个docker-compose.yml文件、一条命令完成创建和启动的工具。它解决的问题是:一个项目往往涉及多个服务(mysql、redis、nginx、应用),如果全用docker run命令去拼,命令又长又容易出错,而且多个服务之间的依赖、网络、数据卷关系无从管理。

compose文件的核心结构是 services、networks、volumes 三段。services下面定义每个服务,字段基本对应docker run的参数——image对应镜像、ports对应端口映射、environment对应环境变量、volumes对应挂载、depends_on对应依赖顺序。写一个最简单的应用加数据库配置:

version: '3.8' services: app: build: . ports: - "8080:8080" environment: SPRING_PROFILES_ACTIVE: prod DB_HOST: mysql depends_on: - mysql networks: - app-net mysql: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: rootpass MYSQL_DATABASE: appdb volumes: - mysql-data:/var/lib/mysql networks: - app-net networks: app-net: volumes: mysql-data:

这个文件里最关键的一点是DB_HOST直接写成了mysql——因为compose会自动为服务创建共享网络,服务名即主机名,应用容器里不需要写IP就能访问到mysql服务。这跟我前面说的自定义网络DNS解析是同一套原理,只不过compose替你把网络建好了。

常用的compose命令不多:docker compose up -d后台启动所有服务,docker compose down停止并删除所有服务容器,docker compose logs -f跟踪日志,docker compose ps查看服务状态,docker compose exec 服务名 命令进入某个服务容器。注意新版compose命令已经不需要中间的连字符,是docker compose而不是docker-compose,老版本插件方式已经逐步淘汰了。修改配置后重新加载用docker compose up -d就够了,它会自动比对配置变化并重建有改动的容器,不需要每次down再up——down再up会丢掉容器的运行状态数据(但数据卷里的数据不会丢)。

6. 高频问题诊断:那些年我踩过的Docker命令坑

6.1 启动失败与网络不通的排查步骤

"docker run之后容器秒退"大概是让最多人崩溃的问题了。这个现象的本质是容器的主进程执行完就退出了,容器没有前台进程可跑。而我看到很多新手用的镜像,启动命令都是前台阻塞式的,比如nginx的daemon off;,MySQL的mysqld。如果你镜像本身没有问题,但容器还是秒退,正确排查方法是先别加-d,直接前台运行看清楚报错信息:docker run --rm 镜像名,这时终端会直接显示启动日志。加上--rm是为了退出时自动清理容器,避免调试过程中堆积垃圾容器。日志里常见的错误包括权限拒绝、端口占用、配置文件语法错误等,看到具体报错再去搜解决方案,比盲猜有效率得多。

网络不通是另一个高频问题。有一回我用docker run -p 8080:80 nginx启动了一个nginx容器,宿主机curl localhost:8080却一直超时。排查顺序是:先docker ps确认容器状态是Up;再docker logs 容器名确认nginx确实在监听;然后docker port 容器名查看实际端口映射,结果发现端口映射被正确映射到8080了;最后查宿主机防火墙,原来是防火墙拦住了8080端口。这个案例说明一个道理:Docker端口映射只是做了NAT转发规则,最终能不能访问还取决于宿主机防火墙是否放行,这两个环节都要兼顾。

6.2 磁盘占满、时区错误和其他疑难杂症

Docker用久了,最典型的症状是磁盘缓慢占满。罪魁祸首通常是三类:无主镜像(dangling images,即<none>:<none>的中间层)、停止的容器和孤立数据卷。这时候执行docker system df像"磁盘体检报告"一样列出各项占用,然后再对症清理:docker image prune清悬空镜像,docker container prune清停止容器,docker volume prune清孤立数据卷,docker system df确认回收效果。注意prune系列默认只清理Docker闲置的资源,不会动挂载的宿主机目录。

时区问题也很常见,容器默认用的UTC时间,和北京时间差8小时。日志时间怎么看都对不上,特别干扰排查。解决的通用方案是在docker run时加-e TZ=Asia/Shanghai。多数主流镜像支持这个环境变量,部分镜像如果用的不是glibc而是精简的发行版,可能需要额外安装tzdata。如果配置了TZ依然无效,检查镜像本身的/etc/localtime和/etc/timezone是否真的是Asia/Shanghai,有时候在Dockerfile里加一条RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime更直接。

还有一类问题是docker exec进入容器后发现没有vim、没有ping、没有telnet。精简镜像里本来就不带这些工具,因为容器哲学是"一个容器只跑一个进程"。这时候可以在容器里执行apt update && apt install -y vim(基于Debian的镜像)或apk add vim(基于Alpine的镜像)临时装工具调试,也可以直接用宿主机的命令配合docker exec参数达到目的。从外面测试容器服务时,其实不一定非要进容器:docker exec 容器名 curl http://127.0.0.1:8080或者宿主机上telnet 127.0.0.1 映射出来的端口。

下面我把高频命令整理成速查表,方便贴在手边:

操作命令
拉取镜像docker pull nginx:1.24
查看本地镜像docker images
删除镜像docker rmi nginx:1.24
运行容器(前台交互)docker run -it --rm ubuntu bash
运行容器(后台+端口+数据卷)docker run -d -p 8080:80 -v /data:/usr/share/nginx/html nginx
查看运行中的容器docker ps
查看所有容器docker ps -a
查看容器日志(跟踪)docker logs -f 容器名
进入容器docker exec -it 容器名 bash
停止/强制停止容器docker stop 容器名 / docker kill 容器名
删除容器docker rm 容器名
容器与宿主机互拷文件docker cp 源路径 目标路径
构建镜像docker build -t 镜像名:标签 .
查看容器/镜像详细信息docker inspect 容器名/镜像名
查看网络列表/清理悬空资源docker network ls / docker system prune

7. 批量操作与运行内存限制经验

7.1 用组合命令处理多个容器

单容器操作学会之后,多容器管理是压测和本地调试最常见的场景。用命令行的组合技巧可以大幅提高效率。比如docker stop $(docker ps -q)能停掉所有运行中的容器,docker rm $(docker ps -aq)能删掉所有容器(包括已停止的),docker rmi $(docker images -q)清掉本地全部镜像。这套组合逻辑的本质是:先用查询命令拿到ID列表,再交给操作命令执行。但执行之前一定三思,特别是docker rmi $(docker images -q)这种指令,一条下去本地所有镜像都没了,重建环境要花大半天。真要批量清理,我建议先docker ps -aq输出列表确认一下,再执行删除;或者用prune系列命令替代,它们带安全过滤,比组合命令稳妥得多。

批量查看多个容器的状态和数据,docker inspect配合--format参数能按模板输出指定字段。比如你想批量查看所有运行中容器的IP,可以执行docker inspect --format '{{.Name}} {{.NetworkSettings.IPAddress}}' $(docker ps -q)。这个格式化输出的语法初看有点复杂,但它是从docker命令里提取精确信息的最强工具,比人眼在超长JSON里翻效率高太多。

7.2 资源限制参数一定要写

我遇到不止一次生产环境的崩溃,最后查下来都是容器没写资源限制,进程把宿主机内存吃光导致的。Docker默认不限制容器资源,一个容器确实能占满整台机器。运维规范里,跑任何正式容器都要加上内存和CPU限制:docker run -d --memory=512m --cpus=1.0 nginx,意思是最多用512MB内存和1个CPU核心。这个限制不仅保护宿主机,也保护容器自身——单个容器内存暴涨时,OOM机制会先杀那个容器而不是整个宿主机。

查看资源使用量用docker stats,它实时显示各容器的CPU、内存、网络IO,类似宿主机上的top。在压测场景里,我习惯开两个终端,一个跑docker stats --no-stream定时采样,另一个跑压测脚本,这样能直观看到容器到底吃到多少资源,给调优提供依据。--no-stream参数很实用,它只输出当前时刻的状态而不是持续滚动刷新,便于记录数据。

8. 写在最后的一点经验

这些Docker命令单独看都不难,难的是把它们组合起来解决实际问题。我个人的习惯是:每接触一个新镜像或新项目,先自己写一遍完整的docker run命令,确认每个参数的作用,再把它改写成docker compose文件保存下来。这个过程重复上十几次,命令就不再是需要查的"知识点"了,而是像呼吸一样自然的东西。遇到报错别慌,先docker logs看应用日志,再docker inspect查配置状态,这两板斧解决不了再搜具体的错误关键字。下一篇我会继续写Docker命令知识点2,把镜像构建、Dockerfile优化和compose编排的经验展开细讲,到时候可以结合这期的基础一起看。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/2 9:21:58

端侧视觉AI浏览器推理实战:WebGL与WebGPU加速的工程化落地

1. 端侧视觉 AI 的工程真相&#xff1a;从一个浏览器标签页说起 把神经网络塞进一个浏览器标签页&#xff0c;这件事听起来像是某个周末黑客松的炫技项目&#xff0c;但我第一次在真实业务里动这个念头&#xff0c;是因为一个很现实的问题&#xff1a;用户上传的图片里有人脸、…

作者头像 李华
网站建设 2026/10/2 9:20:23

螺旋矩阵 II 边界控制详解:循环不变量与按层填充

我第一次做 LeetCode 59. 螺旋矩阵 II 的时候&#xff0c;第一反应是去写一个"方向数组"&#xff0c;上下左右四个方向&#xff0c;碰到边界就转向。结果 n3 跑得挺好&#xff0c;n4 一落地就越界&#xff0c;调了十分钟才意识到&#xff1a;这道题如果只跟着感觉走&…

作者头像 李华
网站建设 2026/10/2 9:20:17

ADB 自动化测试实战:命令、Python 封装、元素定位与排错

1. 先搞懂 adb 是什么&#xff1a;它凭什么成为自动化测试的地基刚接触 adb 自动化测试的人&#xff0c;几乎都会经历同一个阶段&#xff1a;把adb devices敲进命令行&#xff0c;看到一串设备号&#xff0c;然后陷入沉默——这玩意儿到底能帮我干什么&#xff1f;我自己的经历…

作者头像 李华
网站建设 2026/10/2 9:20:00

Linux安装Chrome与依赖解决、离线部署及沙箱权限指南

最小化安装的Linux服务器上装Chrome&#xff0c;最典型的场面是这样的&#xff1a;wget下来一个几十兆的deb包&#xff0c;dpkg -i一把梭&#xff0c;屏幕上立刻刷出一屏"依赖关系问题使得 google-chrome-stable 的配置工作不能继续"&#xff0c;然后卡在那里&#x…

作者头像 李华
网站建设 2026/10/2 9:19:56

ReaxFF反应力场参数拟合完全指南:从量子化学数据到LAMMPS模拟

我第一次接触ReaxFF反应力场时&#xff0c;最崩溃的不是分子动力学跑不动&#xff0c;而是被“参数拟合”这四个字堵在原地。网上讲ReaxFF的资料不算少&#xff0c;但绝大多数默认你手里已经有了一套可用的力场参数&#xff0c;只管扔进LAMMPS去跑。等到自己真的需要拟合一套Re…

作者头像 李华
网站建设 2026/10/2 9:19:52

COLA框架实战:Java工程化落地DDD的架构工具箱

1. 这不是又一本讲DDD的书&#xff0c;而是一套能立刻上手改代码的架构工具箱你打开一个Spring Boot项目&#xff0c;看到Controller里塞了200行逻辑&#xff0c;Service层调用七八个Mapper&#xff0c;DTO和VO在包里像俄罗斯套娃一样层层嵌套&#xff0c;领域模型&#xff1f;…

作者头像 李华