3、Docker容器管理:容器的创建、启动、停止与删除、进入容器与执行命令、容器日志查看、容器资源限制(CPU/内存)
好,咱们进入第三讲。这一章全是实操,说白了就是怎么把容器玩得转。你想想看,镜像拉下来只是个“模板”,真正干活的是容器。我刚开始接触Docker时,觉得容器就是个轻量级虚拟机,后来踩了不少坑才明白——它比虚拟机灵活得多,但也更“脆弱”。
3.1 容器的创建与启动
创建容器最常用的命令就是 docker run。这个命令其实做了两件事:先创建,再启动。我个人习惯把它拆开理解,方便排查问题。
核心命令:
# 创建并启动一个nginx容器
docker run -d --name my-nginx -p 8080:80 nginx:latest
# 只创建不启动
docker create --name my-redis -p 6379:6379 redis:7.0
# 启动已创建的容器
docker start my-redis
这里有个细节:-d 参数表示后台运行,不加的话容器会直接挂在前台,你一关终端它就停了。我在项目中遇到过有人忘了加 -d,结果部署脚本跑完,容器也跟着退出了,排查了半天才发现是这个问题。
我的小技巧:创建容器时尽量指定 --name,不然Docker会随机生成一个名字,比如“focused_curie”这种,后期管理起来很头疼。
3.2 容器的停止与删除
停止和删除是日常操作,但顺序很重要。先停再删,这是规矩。
# 停止容器
docker stop my-nginx
# 强制停止(相当于拔电源)
docker kill my-nginx
# 删除容器
docker rm my-nginx
# 强制删除运行中的容器
docker rm -f my-nginx
嗯,这里要注意:docker stop 会给容器发送 SIGTERM 信号,让它优雅退出。而 docker kill 直接发 SIGKILL,相当于“暴力关机”。我曾经在生产环境误用了 kill,导致数据库没来得及刷盘,重启后数据丢了。从那以后,我养成了习惯——能 stop 就别 kill。
避坑指南:删除容器前,确认数据是否已持久化。如果容器里存了重要数据又没有挂载卷,删了就真没了。我曾经手滑删过一个没挂载卷的MySQL容器,结果...嗯,你懂的。
3.3 进入容器与执行命令
有时候需要进容器里看看,比如检查日志、调试配置。常用的有两种方式:
| 命令 | 说明 | 适用场景 |
|---|---|---|
docker exec -it 容器名 bash |
进入容器并启动交互式shell | 需要长时间在容器内操作 |
docker exec 容器名 命令 |
在容器内执行单条命令 | 快速查看状态或执行脚本 |
# 进入容器
docker exec -it my-nginx bash
# 在容器内执行单条命令
docker exec my-nginx cat /etc/nginx/nginx.conf
# 查看容器内进程
docker exec my-nginx ps aux
我个人习惯用 docker exec 而不是 docker attach。为什么?因为 attach 会连接到容器的主进程,退出时容易把容器也停了。而 exec 是新建一个进程,退出不影响容器运行。
3.4 容器日志查看
日志是排查问题的第一手资料。Docker的日志查看命令很强大,但很多人只用 docker logs 不加参数,信息太多反而找不到重点。
# 查看全部日志
docker logs my-nginx
# 实时跟踪日志(类似 tail -f)
docker logs -f my-nginx
# 只看最后50行
docker logs --tail 50 my-nginx
# 带时间戳查看
docker logs -t my-nginx
# 按时间过滤(最近10分钟)
docker logs --since 10m my-nginx
实战经验:我在排查线上问题时,通常先用 --tail 100 看最后100行,再用 --since 5m 看最近5分钟的日志。这样既能快速定位问题,又不会信息过载。
另外,如果容器日志太多,建议配置日志轮转。不然一个容器跑几个月,日志文件能撑爆磁盘。我见过一个案例,某团队没配日志轮转,结果日志文件占了100多G,导致服务器磁盘告警。
3.5 容器资源限制(CPU/内存)
这是生产环境必须掌握的技能。不加限制的话,一个容器可能把宿主机所有资源吃光,影响其他服务。说白了,就是给容器“上枷锁”。
3.5.1 内存限制
# 限制内存最大使用512MB,交换分区512MB
docker run -d --name my-app --memory="512m" --memory-swap="512m" nginx
# 只限制内存,不限制交换分区(不推荐)
docker run -d --name my-app --memory="512m" nginx
这里有个坑:--memory-swap 如果不设置,默认是内存的两倍。也就是说,你设了 --memory="512m",实际可用内存可能是512MB物理内存 + 512MB交换分区。我曾经因为这个配置,导致容器内存超限后开始用交换分区,性能急剧下降。
建议:生产环境一定要把 --memory 和 --memory-swap 设为相同值,彻底禁用交换分区。容器用交换分区,性能会变得不可控。
3.5.2 CPU限制
# 限制使用1.5个CPU核心
docker run -d --name my-app --cpus="1.5" nginx
# 按权重分配CPU(默认1024)
docker run -d --name my-app --cpu-shares=512 nginx
# 绑定到特定CPU核心
docker run -d --name my-app --cpuset-cpus="0,2" nginx
| 参数 | 作用 | 适用场景 |
|---|---|---|
--cpus |
限制CPU使用上限(精确控制) | 需要严格限制资源 |
--cpu-shares |
设置CPU权重(相对值) | 多个容器共享CPU |
--cpuset-cpus |
绑定到指定CPU核心 | 对延迟敏感的服务 |
我个人推荐用 --cpus,因为它最直观。比如你有个4核的服务器,给每个容器分1核,最多跑4个。而 --cpu-shares 是相对权重,如果只有一个容器在跑,它可能吃掉所有CPU,起不到限制作用。
3.6 综合实战:部署一个带资源限制的Nginx
最后,咱们来个综合练习。假设你要部署一个Nginx服务,要求:
- 容器名:web-prod
- 映射端口:宿主机80 -> 容器80
- 内存限制:256MB,禁用交换分区
- CPU限制:最多使用0.5核
- 后台运行
docker run -d \
--name web-prod \
-p 80:80 \
--memory="256m" \
--memory-swap="256m" \
--cpus="0.5" \
nginx:alpine
启动后,验证一下:
# 查看容器状态
docker ps
# 查看资源使用情况
docker stats web-prod
# 查看日志
docker logs --tail 20 web-prod
我的习惯:每次部署完,我都会用 docker stats 观察几分钟,确认资源使用在预期范围内。如果发现内存持续接近上限,说明限制设得太紧了,需要调整。
好了,这一章的内容就这些。说白了,容器管理就是“创建-启动-停止-删除”的循环,加上日志和资源限制这两个护身符。你把这些练熟了,生产环境基本就能应付了。下一章咱们聊聊数据持久化,那才是真正让容器“活起来”的关键。