Docker命令实战指南:从基础到高级应用
1. Docker基础命令实战
第一次接触Docker时,我被那些晦涩的命令搞得晕头转向。直到后来才发现,掌握几个核心命令就能应付80%的日常场景。先来看最基础的"hello world"级操作:
# 检查Docker是否安装成功
docker --version
docker info
这两个命令就像汽车的仪表盘,--version告诉你安装的Docker引擎版本,而info会显示更详细的系统信息,包括容器数量、存储驱动等。我经常用info检查Docker的运行状态,特别是在服务异常时。
镜像操作是Docker的起点。还记得我第一次拉取镜像时,盯着下载进度条看了半天:
# 搜索并拉取官方MySQL镜像
docker search mysql
docker pull mysql:5.7
这里有个实用技巧:search命令的--filter=STARS=3000可以筛选星标超过3000的优质镜像。拉取特定版本时一定要指定tag(如5.7),否则默认拉取latest可能带来兼容性问题。
镜像管理常用命令:
# 查看本地镜像列表
docker images
# 删除指定镜像
docker rmi -f mysql:5.7
# 清理所有悬空镜像
docker image prune
注意-f参数是强制删除运行中的镜像,但生产环境慎用。我曾在测试环境误删基础镜像,导致所有依赖它的容器崩溃。
2. 容器生命周期管理
容器操作是Docker的核心。最常用的run命令就像魔术师的帽子,能变出各种服务实例:
# 启动一个Nginx容器
docker run -d --name my_nginx -p 8080:80 nginx
这个命令包含了几个关键参数:
-d:后台运行(detach模式)--name:给容器起个易记的名字-p:端口映射(主机端口:容器端口)
有一次我忘记映射端口,在主机上死活访问不到Nginx,排查了半天才发现问题。现在养成了习惯,启动容器后立即执行docker ps检查端口映射。
容器状态管理三板斧:
# 查看运行中的容器
docker ps
# 停止/启动容器
docker stop my_nginx
docker start my_nginx
# 删除容器
docker rm my_nginx
进阶技巧:docker run -it ubuntu /bin/bash会进入交互模式,就像SSH到一台临时虚拟机。我常用这种方式测试新环境,退出后容器自动销毁,不留痕迹。
3. 数据持久化与卷管理
初学Docker时,我最困惑的就是容器重启后数据丢失的问题。直到学会使用数据卷(Volume),才真正理解"牲畜 vs 宠物"的比喻。
挂载主机目录最简单实用:
docker run -v /宿主机路径:/容器路径 mysql
但更规范的做法是使用命名卷:
# 创建管理卷
docker volume create db_vol
# 挂载到容器
docker run -v db_vol:/var/lib/mysql mysql
我曾遇到过容器权限问题,解决方案是添加--privileged=true参数。但要注意这会降低安全性,生产环境应该通过chown提前设置好目录权限。
数据备份也很重要:
# 备份卷数据到tar包
docker run --rm -v db_vol:/volume -v /backup:/backup alpine \
tar cvf /backup/db_backup.tar /volume
4. 网络配置实战
Docker网络刚开始像黑盒子,直到我动手实践才理清几种模式:
# 查看现有网络
docker network ls
# 创建自定义桥接网络
docker network create --driver bridge my_net
把容器接入自定义网络:
docker run --network=my_net --name web nginx
docker run --network=my_net --name db mysql
这样web容器可以直接用db主机名访问数据库,不需要知道IP。我在微服务项目中常用这种方式实现服务发现。
端口映射的进阶用法:
# 随机映射主机端口
docker run -P nginx
# 查看实际映射端口
docker port 容器ID
遇到网络问题时,docker network inspect是救命稻草,它能显示所有连接的容器和IP分配情况。
5. 镜像构建与Dockerfile
从消费者变成生产者,Dockerfile是必经之路。这是我常用的模板:
FROM python:3.8-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["gunicorn", "app:app", "-b", "0.0.0.0:5000"]
构建命令:
docker build -t my_app:v1 .
几个优化技巧:
- 合理使用
.dockerignore文件加速构建 - 多阶段构建减小镜像体积
- 固定基础镜像版本避免意外更新
我曾因为没固定基础镜像版本,导致生产环境构建突然失败。现在所有FROM都带具体版本号,比如python:3.8.12-slim。
6. 日志与故障排查
掌握排查技巧能节省大量时间。查看日志最直接:
docker logs -f --tail 100 容器ID
-f是实时跟踪,--tail只看最后N行。对于卡死的容器,docker stats能看资源占用:
CONTAINER ID NAME CPU % MEM USAGE / LIMIT
c3f279d17e0a redis 0.5% 156MiB / 3GiB
进入容器排查也很方便:
docker exec -it 容器ID /bin/bash
但要注意,修改运行中容器的文件只是临时生效,重建容器会丢失。持久化变更应该更新Dockerfile重新构建。
7. 安全最佳实践
安全常被忽视,直到出问题才后悔。几个关键点:
- 不要使用root用户运行进程:
RUN groupadd -r appuser && useradd -r -g appuser appuser
USER appuser
- 定期扫描镜像漏洞:
docker scan 镜像名
- 限制容器资源:
docker run -m 512m --cpus=1 nginx
- 使用只读文件系统:
docker run --read-only -v /tmp:/tmp alpine
8. 常用工具链
除了命令行,这些工具能提升效率:
- Docker Compose:一键启动多容器应用
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis:alpine"
- Portainer:图形化管理界面
docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer
- Watchtower:自动更新容器
docker run -d --name watchtower -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower
9. 生产环境经验
在真实项目中踩过的坑:
-
存储驱动选择:对于写入密集的应用,
overlay2比aufs性能更好 -
时区问题:基础镜像通常是UTC时间,需要显式设置:
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime
-
信号处理:确保应用能正确处理SIGTERM,否则
docker stop会超时强制kill -
健康检查:关键服务应该配置HEALTHCHECK
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost/ || exit 1
10. 性能调优技巧
当容器规模变大后,这些优化很关键:
-
镜像分层:将变化频率低的层放在Dockerfile前面
-
构建缓存:合理排序COPY和RUN指令,最大化利用缓存
-
资源限制:为每个容器设置合理的CPU和内存限制
-
日志轮转:防止日志撑爆磁盘
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
11. 跨主机网络方案
当单机Docker不够用时,需要考虑:
- Overlay网络:适合Swarm集群
docker network create -d overlay my_overlay
- Macvlan:让容器直接使用物理网络
docker network create -d macvlan \
--subnet=192.168.1.0/24 \
--gateway=192.168.1.1 \
-o parent=eth0 my_macvlan
- Ingress负载均衡:Swarm模式下自动配置
12. 备份与迁移
可靠的备份策略包括:
- 镜像导出:
docker save -o my_app.tar my_app:v1
docker load -i my_app.tar
- 容器快照:
docker export 容器ID > container.tar
docker import container.tar my_image
- 卷备份:
docker run --rm -v 数据卷:/volume -v /backup:/backup alpine \
tar cvf /backup/backup.tar /volume
13. CI/CD集成
在自动化流程中使用Docker的典型场景:
- 构建阶段:
# .gitlab-ci.yml示例
build_image:
stage: build
script:
- docker build -t $CI_REGISTRY_IMAGE .
- docker push $CI_REGISTRY_IMAGE
- 测试阶段:
docker-compose -f docker-compose.test.yml up --abort-on-container-exit
- 部署阶段:
docker stack deploy -c docker-compose.prod.yml my_stack
14. 监控与告警
完善的监控体系应该包括:
- 基础指标:
docker stats
- Prometheus监控:
# docker-compose.yml片段
monitor:
image: prom/prometheus
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
- 日志聚合:
docker run --name logspout \
-v /var/run/docker.sock:/var/run/docker.sock \
gliderlabs/logspout \
syslog+tls://logs.example.com:514
15. 资源清理
随着时间推移,系统会积累各种资源:
# 删除所有停止的容器
docker container prune
# 删除所有未被使用的网络
docker network prune
# 删除所有悬空镜像
docker image prune
# 一键清理所有资源
docker system prune
建议在crontab中设置定期清理:
0 3 * * * /usr/bin/docker system prune -f
16. 多阶段构建实战
这是减小镜像大小的神器:
# 构建阶段
FROM golang:1.16 AS builder
WORKDIR /src
COPY . .
RUN go build -o app .
# 运行阶段
FROM alpine:latest
WORKDIR /app
COPY --from=builder /src/app .
CMD ["./app"]
最终镜像只有十几MB,而包含完整Go环境的构建镜像超过1GB。我在Java项目中也常用这种方式,先用Maven镜像构建,然后只拷贝jar包到JRE镜像。
17. 容器编排基础
虽然Kubernetes是主流,但Docker Swarm更简单易用:
# 初始化Swarm集群
docker swarm init
# 部署服务
docker service create --replicas 3 -p 80:80 --name web nginx
# 滚动更新
docker service update --image nginx:1.19 web
适合中小型项目的快速部署,我曾在客户现场用Swarm 30分钟搭建起高可用集群。
18. 自定义网络插件
当默认网络不满足需求时:
# 创建Macvlan网络
docker network create -d macvlan \
--subnet=192.168.1.0/24 \
--gateway=192.168.1.1 \
-o parent=eth0 my_macvlan
这样容器会获得和物理机同网段的IP,可以直接被外部访问。我在IoT项目中用这种方式让设备直接与容器通信。
更多推荐



所有评论(0)