Docker实用技巧:这些功能你可能不知道但很好用
Docker已经成为了现代开发和运维的标配工具。大部分人都知道基本的docker run、docker build命令,但Docker里还有一些不太为人知却非常实用的功能。掌握这些技巧,能让你的容器使用更加高效。
一、优化镜像大小:多阶段构建
很多Docker镜像最终很大,是因为包含了构建工具、源代码等不必要的文件。用多阶段构建可以解决这个问题。
传统做法的问题
FROM golang:1.20
WORKDIR /app
COPY . .
RUN go build -o myapp
CMD ["./myapp"]这样做出来的镜像包含Go编译环境和源代码,可能超过1GB。
多阶段构建的改进
# 第一阶段:构建
FROM golang:1.20 as builder
WORKDIR /app
COPY . .
RUN go build -o myapp
# 第二阶段:运行
FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/myapp .
ENTRYPOINT ["./myapp"]这样最终镜像只包含运行所需的最小环境,大小可能只有几十MB。
实际效果:一个Go应用的镜像从1.2GB减小到15MB。
二、控制资源使用:限制内存和CPU
在服务器上运行多个容器时,如果不加限制,某个容器可能占满所有资源,影响其他服务。
设置内存限制
docker run -d --memory=512m --memory-swap=1g nginx--memory=512m:限制最多使用512MB内存
--memory-swap=1g:内存+交换分区总共1GB
设置CPU限制
# 限制使用1个CPU核心
docker run -d --cpus=1 nginx
# 限制使用0.5个CPU核心
docker run -d --cpus=0.5 nginx
# 设置CPU优先级(0-1024,默认1024)
docker run -d --cpu-shares=512 nginx实际应用场景
开发环境:限制资源,避免影响其他工作
生产环境:确保关键服务有足够资源
测试环境:模拟低配服务器
三、更灵活的卷挂载:使用--mount
大多数人都用-v参数挂载卷,但--mount其实更好用。
基本用法对比
# 传统方式
docker run -v $(pwd)/data:/app/data nginx
# 新方式
docker run --mount type=bind,source=$(pwd)/data,target=/app/data nginx--mount的优势
更清晰的语法:参数意义明确
更多选项:比如设置只读
一致性:和docker service create语法一致
实用例子
# 只读挂载(防止容器修改宿主机文件)
docker run --mount type=bind,source=$(pwd)/config,target=/app/config,readonly nginx
# 挂载时设置权限
docker run --mount type=bind,source=$(pwd)/data,target=/app/data,readonly=false nginx四、高效查看日志:定位问题更快
容器出问题时,查看日志是最常用的排查方法。
实时查看日志
# 实时查看(类似tail -f)
docker logs -f <容器ID或名称>
# 查看最近100行
docker logs --tail 100 <容器ID>按时间筛选
# 查看最近10分钟的日志
docker logs --since 10m <容器ID>
# 查看从某个时间点开始的日志
docker logs --since 2024-01-01T00:00:00 <容器ID>
# 查看最近10分钟的最后50行
docker logs --since 10m --tail 50 <容器ID>格式化输出
# 显示时间戳
docker logs -t <容器ID>
# 只显示错误日志
docker logs --since 1h <容器ID> 2>&1 | grep -i error五、定期清理:释放磁盘空间
Docker用久了会占用大量磁盘空间,需要定期清理。
清理无用资源
# 清理所有未使用的资源(镜像、容器、网络、构建缓存)
docker system prune -a
# 只清理超过24小时的未使用资源
docker system prune -a --filter "until=24h"针对性地清理
# 删除所有停止的容器
docker container prune
# 删除所有未被使用的镜像
docker image prune -a
# 删除所有未被使用的卷
docker volume prune
# 删除所有未被使用的网络
docker network prune查看磁盘使用情况
# 查看详细使用情况
docker system df
# 查看具体是哪些镜像占空间
docker system df -v六、网络隔离:更安全的服务通信
默认情况下,所有容器都在同一个网络,不够安全。
创建自定义网络
# 创建网络
docker network create my_app_network
# 运行服务时指定网络
docker run -d --network=my_app_network --name web nginx
docker run -d --network=my_app_network --name db mysql网络间的服务发现
# 在web容器中可以直接ping db(通过服务名)
docker exec web ping db
# 也可以通过IP访问
docker network inspect my_app_network网络类型选择
# 桥接网络(默认,适合单机)
docker network create --driver bridge app_net
# 覆盖网络(适合集群)
docker network create --driver overlay cluster_net七、多平台构建:支持不同CPU架构
如果你的应用要在不同架构的机器上运行(比如x86和ARM),可以用多平台构建。
启用buildx
# 创建并切换到buildx构建器
docker buildx create --use --name multiarch-builder
# 检查构建器状态
docker buildx ls多平台构建
# 同时构建amd64和arm64版本
docker buildx build --platform linux/amd64,linux/arm64 -t myapp:latest .
# 推送到镜像仓库
docker buildx build --platform linux/amd64,linux/arm64 -t username/myapp:latest --push .实际应用
开发机是Mac M系列(ARM),服务器是x86
物联网设备使用ARM架构
需要同时支持多种环境
八、安全存储:保护敏感信息
不要在环境变量或Dockerfile中写死密码,用Docker Secret更安全。
创建secret
# 从文件创建
echo "my_secret_password" > password.txt
docker secret create db_password password.txt
# 从标准输入创建
echo "my_secret_password" | docker secret create db_password -在服务中使用
# docker-compose.yml示例
version: '3.8'
services:
db:
image: mysql
secrets:
- db_password
environment:
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_password
secrets:
db_password:
file: ./password.txt九、其他实用命令
1. 查看镜像构建历史
docker history nginx:latest可以看到镜像每一层是怎么构建的,用了什么命令。
2. 查看容器退出状态
# 运行一个临时容器
docker run --rm alpine sh -c "exit 1"
# 获取退出状态码
echo $?
# 或者用docker wait
docker run -d --name test alpine sleep 5
docker wait test退出状态0表示成功,非0表示失败。
3. 查看容器文件变化
# 运行容器并修改文件
docker run --name test alpine touch /test.txt
# 查看修改了哪些文件
docker diff testA:新增文件
C:修改文件
D:删除文件
4. 监控容器资源使用
# 实时监控所有容器
docker stats
# 监控特定容器
docker stats nginx mysql
# 不显示标题行,适合脚本处理
docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"十、实用组合技巧
快速进入容器
# 如果容器里没有bash,用sh
alias docker-exec='docker exec -it $(docker ps -q -f name=你想进入的容器名) sh'
# 或者用函数
dsh() {
docker exec -it $1 sh
}批量操作
# 停止所有运行的容器
docker stop $(docker ps -q)
# 删除所有已停止的容器
docker rm $(docker ps -aq)
# 更新所有运行中的容器
docker ps -q | xargs -I {} docker update --restart=always {}端口快速检查
# 查看哪些端口被映射
docker port <容器名>
# 查看所有容器的端口映射
docker ps --format "table {{.Names}}\t{{.Ports}}"总结建议
日常使用:
用多阶段构建减小镜像
设置资源限制避免影响其他服务
定期清理无用资源
生产环境:
使用自定义网络隔离服务
用Secret保护敏感信息
做好日志管理
跨平台场景:
用buildx支持多架构
测试不同平台的表现
故障排查:
熟练使用docker logs的各种参数
用docker diff和docker history辅助分析
这些技巧虽然不算基础知识,但掌握后能显著提升使用Docker的效率和体验。建议先挑选几个最需要的功能试试,熟练后再学习其他。好的工具要用得好,才能发挥最大价值。
本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!