目录
一、Docker 概述
1.1 Docker 的定义与核心价值
1.2 容器技术与传统虚拟化的对比
1.3 Docker 的三大核心概念
(1)镜像(Image)
(2)容器(Container)
(3)仓库(Repository)
1.4 Docker 的应用场景
二、Docker 环境部署(CentOS 系统)
2.1 安装前的准备工作
(1)关闭系统防火墙与 SELinux
(2)配置 Docker 软件源
2.2 安装 Docker CE
2.3 配置国内镜像加速
2.4 启动 Docker 服务
2.5 优化内核参数
三、Docker 镜像操作详解
3.1 获取镜像(docker pull)
3.2 查看镜像列表(docker images)
3.3 查看镜像详细信息(docker inspect)
3.4 修改镜像标签(docker tag)
3.5 删除镜像(docker rmi)
3.6 镜像导入导出(docker save/load)
(1)导出镜像为 tar 文件
(2)删除本地镜像
(3)从 tar 文件导入镜像
(4)命令说明
四、Docker 容器操作实战
4.1 容器的创建与启动
(1)创建容器(docker create)
(2)查看容器列表(docker ps)
(3)启动容器(docker start)
4.2 容器的快速运行(docker run)
4.3 容器的终止与删除
(1)优雅停止容器(docker stop)
(2)强制终止容器(docker kill)
(3)删除容器(docker rm)
4.4 进入容器与命令执行
(1)进入运行中的容器(docker exec)
(2)容器内命令执行(一次性)
4.5 容器的导入导出(docker export/import)
(1)导出容器文件系统
(2)从导出文件创建镜像
(3)与 docker save/load 的区别
五、Docker 数据卷管理
5.1 数据卷的基本概念
5.2 创建与使用数据卷
(1)创建命名数据卷
(2)查看数据卷列表
(3)查看数据卷详细信息
(4)在容器中挂载数据卷
5.3 数据卷容器(共享数据)
(1)创建数据卷容器
(2)其他容器挂载数据卷容器
5.4 数据卷的备份与恢复
(1)备份数据卷
(2)恢复数据卷
六、Docker 网络基础
6.1 Docker 默认网络模式
6.2 创建自定义网络
6.3 容器连接网络
七、Dockerfile 基础
7.1 Dockerfile 的作用
7.2 常用 Dockerfile 指令
(1)基础镜像指定
(2)作者信息
(3)工作目录设置
(4)复制文件
(5)安装依赖
(6)暴露端口
(7)设置环境变量
(8)定义启动命令
7.3 构建镜像
八、Docker Compose 入门
8.1 Compose 的作用
8.2 Compose 文件示例
8.3 常用 Compose 命令
九、总结
十、Docker 应用场景深度解析
10.1 开发环境一致性管理
10.2 持续集成 / 持续部署(CI/CD)
10.3 微服务架构实践
10.4 云计算与资源优化
十一、Docker 镜像高级操作
11.1 镜像层原理与 AUFS
11.2 镜像构建最佳实践
11.3 镜像安全管理
十二、Docker 容器高级操作
12.1 容器资源限制
12.2 容器检查点与恢复
12.3 容器日志管理
十三、Docker 数据管理进阶
13.1 数据卷驱动扩展
13.2 数据卷备份自动化
13.3 容器数据迁移方案
十四、Docker 网络高级配置
14.1 自定义网络驱动
14.2 容器网络通信
14.3 网络故障排查
十五、Docker 安全最佳实践
15.1 容器权限控制
15.2 镜像安全加固
15.3 运行时安全防护
Docker 是一种轻量级容器技术,旨在解决开发、测试和生产环境中的环境一致性问题。它通过将应用程序及其依赖项打包成一个独立的容器,实现了应用的隔离、可移植性和资源的高效利用。
与传统虚拟化技术相比,Docker 具有以下核心优势:
特性 | Docker 容器 | 传统虚拟机 |
---|---|---|
启动速度 | 秒级 | 分钟级 |
资源占用 | 几乎无额外消耗 | 损耗约 50% |
性能表现 | 接近原生应用 | 存在虚拟化层开销 |
单机支持量 | 上千个容器 | 几十个虚拟机 |
隔离级别 | 资源隔离 | 完全隔离 |
# 停止防火墙服务
systemctl stop firewalld
# 禁用防火墙开机自启
systemctl disable firewalld
# 临时关闭SELinux
setenforce 0
# 永久关闭SELinux(修改配置文件)
sed -i 's/=enforcing/=disabled/' /etc/selinux/config
# 下载Docker官方YUM源配置文件
curl -o /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 修改仓库配置(适配CentOS 8)
sed -i 's/$releasever/8/g' /etc/yum.repos.d/docker-ce.repo
sed -i 's/$basearch/x86_64/g' /etc/yum.repos.d/docker-ce.repo
# 清理旧索引
dnf clean all
# 生成新的缓存索引
dnf makecache
# 安装Docker CE
dnf -y install docker-ce
# 创建Docker配置目录
mkdir -p /etc/docker/
# 写入镜像加速配置
cat >/etc/docker/daemon.json <
# 重载系统服务配置
systemctl daemon-reload
# 重启Docker服务
systemctl restart docker
# 设置Docker开机自启
systemctl enable docker
# 验证安装结果
docker version
# 添加内核参数配置
cat >>/etc/sysctl.conf <
# 拉取指定版本的Nginx镜像
docker pull nginx:1.24.0
# 命令语法
docker pull [OPTIONS] NAME[:TAG|@DIGEST]
# 常用参数
--all-tags # 拉取所有标签的镜像
--disable-content-trust # 禁用镜像签名验证
# 示例说明
docker pull nginx # 拉取最新版Nginx镜像
docker pull alpine@sha256:abcdef123... # 通过摘要拉取精确版本
# 列出本地所有镜像
docker images
# 命令语法
docker images [OPTIONS] [REPOSITORY[:TAG]]
# 常用参数
-a, --all # 显示所有镜像(包括中间层)
--digests # 显示镜像摘要
-f, --filter # 按条件过滤(如dangling=true显示虚悬镜像)
--format # 自定义输出格式
--no-trunc # 完整显示镜像ID
-q, --quiet # 仅显示镜像ID
# 输出字段说明
REPOSITORY # 镜像仓库名称
TAG # 镜像标签
IMAGE ID # 镜像唯一标识
CREATED # 镜像创建时间
VIRTUAL SIZE # 镜像虚拟大小
# 查看Nginx镜像的详细信息
docker inspect nginx:1.24.0
# 命令语法
docker inspect [OPTIONS] NAME|ID
# 常用参数
--format, -f # 使用Go模板指定输出格式
--size, -s # 显示文件系统大小(仅容器)
# 示例:获取镜像创建时间
docker inspect -f "{{.Created}}" nginx:1.24.0
# 为Nginx镜像添加新标签
docker tag nginx:1.24.0 nginx:v1
# 命令语法
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
# 操作说明
# 1. 源镜像可以是名称:标签或镜像ID
# 2. 目标镜像格式相同,若不指定标签则使用latest
# 3. 标签本质是镜像的别名,不创建新镜像
# 示例场景
# 将私有仓库镜像重命名
docker tag private-registry/nginx:1.24.0 nginx:prod
# 按标签删除镜像
docker rmi nginx:v1
# 按ID删除镜像
docker rmi c15a2b3c4d5e
# 命令语法
docker rmi [OPTIONS] IMAGE [IMAGE...]
# 常用参数
-f, --force # 强制删除(即使有容器依赖)
--no-prune # 不删除未使用的父镜像层
# 注意事项
1. 删除前确保没有容器依赖(使用docker ps -a检查)
2. 多个标签指向同一镜像时,删除一个标签不影响镜像本身
3. 仅当所有标签都删除后,镜像才会从磁盘移除
docker save -o nginx.tar nginx:1.24.0
docker rmi nginx:1.24.0
docker load < nginx.tar
docker save
:将镜像打包为 tar 文件(包含所有层和元数据)docker load
:从 tar 文件加载镜像到本地# 创建交互式CentOS容器
docker create -it centos:7
# 命令语法
docker create [OPTIONS] IMAGE [COMMAND] [ARG...]
# 常用参数
-i, --interactive # 保持标准输入打开
-t, --tty # 分配伪终端
-p, --publish # 端口映射(宿主机:容器)
-v, --volume # 挂载数据卷
--name # 指定容器名称
-e, --env # 设置环境变量
--network # 指定网络
# 示例:创建带端口映射的Nginx容器
docker create -p 8080:80 --name my-nginx nginx:1.24.0
# 查看所有容器(包括停止的)
docker ps -a
# 命令语法
docker ps [OPTIONS]
# 常用参数
-a, --all # 显示所有容器
-q, --quiet # 仅显示容器ID
-s, --size # 显示文件系统大小
-f, --filter # 按条件过滤(如status=running)
--last int # 显示最近创建的n个容器
# 启动名为my-nginx的容器
docker start my-nginx
# 命令语法
docker start [OPTIONS] CONTAINER
# 常用参数
-a, --attach # 附加到容器的标准输入输出
-i, --interactive # 保持标准输入打开
--checkpoint # 从检查点恢复容器
# 示例:启动容器并进入交互模式
docker start -ai my-nginx
# 运行一个交互式CentOS容器
docker run -it centos:7 /bin/bash
# 命令语法
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
# 常用参数(扩展)
-d, --detach # 后台运行容器
-m, --memory # 限制内存使用
--cpus # 限制CPU使用
-P, --publish-all # 发布所有暴露端口
# 示例场景
# 1. 后台运行Nginx服务
docker run -d -p 80:80 --name web-server nginx:1.24.0
# 2. 运行带内存限制的MySQL容器
docker run -d -m 512m --name mysql-server mysql:8.0
# 停止容器(默认等待10秒)
docker stop my-nginx
# 自定义等待时间(20秒)
docker stop -t 20 my-nginx
docker kill my-nginx
# 删除已停止的容器
docker rm my-nginx
# 强制删除运行中的容器
docker rm -f my-nginx
# 删除容器并移除关联数据卷
docker rm -v my-nginx
# 批量删除容器(删除所有停止的容器)
docker rm $(docker ps -a -q)
# 进入容器并打开bash终端
docker exec -it my-nginx /bin/bash
# 命令语法
docker exec [OPTIONS] CONTAINER COMMAND
# 常用参数
-d, --detach # 后台执行命令
-u, --user # 指定执行用户
-w, --workdir # 指定工作目录
# 示例:在容器中执行ls命令
docker exec my-nginx ls /etc
# 在CentOS容器中执行ls命令
docker run centos:7 ls /root
docker export my-nginx > nginx-container.tar
docker import nginx-container.tar nginx:exported
操作 | 作用对象 | 包含内容 | 导入方式 |
---|---|---|---|
save/load | 镜像 | 所有层 + 历史记录 | docker load |
export/import | 容器 | 当前文件系统 | docker import |
docker volume create my-data-volume
docker volume ls
docker volume inspect my-data-volume
# 方式1:使用-v选项挂载命名卷
docker run -d -v my-data-volume:/app/data --name app-container nginx:1.24.0
# 方式2:挂载宿主机目录
docker run -d -v /host/path:/container/path --name app-container nginx:1.24.0
# 方式3:挂载宿主机文件
docker run -d -v /host/file:/container/file:ro --name app-container nginx:1.24.0
docker create -v /data --name data-container alpine:latest
docker run -d --volumes-from data-container --name app1 nginx:1.24.0
docker run -d --volumes-from data-container --name app2 nginx:1.24.0
# 1. 创建临时容器挂载数据卷
docker run --rm -v my-data-volume:/data -v $(pwd):/backup alpine tar cvf /backup/backup.tar /data
# 2. 压缩备份文件
tar -czf backup.tar.gz backup.tar
# 1. 删除旧数据卷(可选)
docker volume rm my-data-volume
# 2. 创建新数据卷
docker volume create my-data-volume
# 3. 解压备份到新数据卷
docker run --rm -v my-data-volume:/data -v $(pwd):/backup alpine tar xvf /backup/backup.tar -C /data
# 创建桥接网络
docker network create my-bridge-network
# 创建覆盖网络(用于Docker Swarm)
docker network create --driver overlay my-overlay-network
# 查看网络列表
docker network ls
# 查看网络详情
docker network inspect my-bridge-network
# 创建容器时指定网络
docker run -d --network my-bridge-network --name web-server nginx:1.24.0
# 将已运行容器连接到网络
docker network connect my-bridge-network web-server
# 断开容器网络连接
docker network disconnect my-bridge-network web-server
FROM centos:7
MAINTAINER your-name
WORKDIR /app
COPY src/ /app/
RUN yum install -y nginx
EXPOSE 80
ENV APP_ENV production
CMD ["nginx", "-g", "daemon off;"]
# 构建镜像(-t指定镜像名称:标签)
docker build -t my-nginx:1.0 .
# 命令语法
docker build [OPTIONS] PATH
# 常用参数
-f, --file # 指定Dockerfile路径
--no-cache # 不使用缓存构建
--tag, -t # 指定镜像名称和标签
version: '3'
services:
web:
build: .
ports:
- "80:80"
depends_on:
- db
volumes:
- ./html:/usr/share/nginx/html
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: password
volumes:
- db-data:/var/lib/mysql
volumes:
db-data:
# 启动所有服务
docker compose up
# 后台启动服务
docker compose up -d
# 停止服务
docker compose down
# 查看服务状态
docker compose ps
# 构建服务镜像
docker compose build
# 进入服务容器
docker compose exec web bash
通过本笔记,我们系统学习了 Docker 容器技术的核心概念与实践操作:
Docker 通过轻量级虚拟化技术,极大提升了应用部署效率和资源利用率,是云计算和微服务架构的重要基础设施。建议读者通过实践操作巩固所学知识,逐步掌握 Docker 的高级特性与最佳实践。
在软件开发过程中,"在我机器上能运行" 而 "在测试环境不能运行" 的问题屡见不鲜。Docker 通过容器技术为开发团队提供了标准化的开发环境解决方案:
统一开发环境
开发人员可基于同一个基础镜像(如node:18
或python:3.9
)构建开发环境,确保团队成员使用相同的运行时环境、依赖库和工具版本。
# 基于Node.js镜像创建开发环境容器
docker run -it -v $(pwd):/app -p 3000:3000 node:18 bash
多服务协同开发
对于前后端分离项目,可使用 Docker Compose 定义前端、后端、数据库等服务的协同运行环境,避免因环境差异导致的联调问题。
Docker 与 CI/CD 流程的结合大幅提升了软件交付效率:
自动化测试环境
在代码提交后,CI 系统可自动拉取最新代码,基于 Dockerfile 构建测试容器,执行单元测试和集成测试,确保代码质量。
# GitLab CI中的Docker测试配置
test:
image: maven:3.8-openjdk-17
script:
- mvn test
artifacts:
paths:
- target/surefire-reports
一键部署生产环境
CD 系统可通过 Docker Compose 或 Kubernetes 将测试通过的容器镜像部署到生产环境,实现 "构建一次,运行处处" 的目标。
Docker 为微服务架构提供了天然的部署载体:
服务拆分与独立部署
每个微服务(如用户服务、订单服务)可打包为独立容器,单独迭代和部署,降低服务间耦合度。
# 部署用户服务容器
docker run -d -p 8081:8081 -e DB_URL=mysql://user-svc:3306/users user-service:v1.0
服务弹性伸缩
通过 Docker Swarm 或 Kubernetes 可根据流量自动调整容器实例数量,例如电商大促期间动态扩容订单服务容器。
云服务提供商借助 Docker 技术实现资源的高效利用:
多租户资源隔离
同一物理服务器上可运行数千个 Docker 容器,每个容器通过命名空间和资源限制实现租户间隔离,相比传统虚拟机大幅提升硬件利用率。
按需分配计算资源
用户可根据业务需求动态申请容器化应用,如临时启动大数据分析容器处理批量任务,完成后释放资源,降低成本。
Docker 镜像采用分层存储(Layer)机制,基于 AUFS(联合文件系统)实现增量更新:
镜像层结构
每个镜像由多个只读层叠加而成,最新层为可写层(容器运行时修改的内容存储在此)。例如nginx:1.24.0
镜像可能包含以下层:
层复用与缓存
不同镜像可共享相同的基础层,如多个基于python:3.9
的镜像只需下载一次基础层。构建镜像时,若某层未修改,Docker 会直接使用缓存。
分层原则
# 优化后的Dockerfile分层
FROM python:3.9-slim AS base
RUN apt-get update && apt-get install -y gcc
FROM base AS dependencies
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
FROM dependencies AS app
COPY . .
CMD ["python", "app.py"]
减少镜像大小
--no-cache-dir
参数避免缓存残留# 多阶段构建示例
FROM golang:1.19 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp
FROM alpine:3.16
COPY --from=builder /app/myapp /usr/bin/
CMD ["myapp"]
使用官方镜像
优先从 Docker Hub 官方仓库拉取镜像(如nginx
、mysql
),避免使用未知来源的镜像。
漏洞扫描
使用trivy
或clair
等工具扫描镜像漏洞,确保生产环境镜像安全:
trivy image nginx:1.24.0
镜像签名与验证
通过 Docker Content Trust 为镜像添加签名,确保镜像在传输过程中未被篡改。
内存限制
使用-m
或--memory
参数限制容器可用内存,防止单个容器占用过多系统资源:
# 限制容器最多使用512MB内存
docker run -d -m 512m --name mysql-server mysql:8.0
CPU 限制
通过--cpus
参数指定容器可使用的 CPU 核心数,适用于多任务并发场景:
# 限制容器使用2个CPU核心
docker run -d --cpus 2 --name redis-server redis:7.0
I/O 限制
使用--device-read-bps
和--device-write-bps
限制容器的磁盘读写速度:
docker run -d --device-read-bps /dev/sda:10MB --device-write-bps /dev/sda:5MB nginx:1.24.0
Docker 支持保存容器状态并在需要时恢复,适用于需要临时暂停的长任务:
创建检查点
docker checkpoint create my-container checkpoint1
查看检查点
docker checkpoint ls my-container
从检查点恢复容器
docker start --checkpoint checkpoint1 my-container
查看容器日志
使用docker logs
命令获取容器运行日志,支持实时跟踪和过滤:
# 实时跟踪Nginx容器日志
docker logs -f my-nginx
# 查看最近100行日志
docker logs --tail 100 my-nginx
日志驱动配置
在daemon.json
中配置日志驱动(如将日志发送到 ELK Stack):
{
"log-driver": "gelf",
"log-opts": {
"gelf-address": "udp://192.168.1.100:12201",
"tag": "docker"
}
}
除默认的本地数据卷外,Docker 支持多种数据卷驱动以适应不同场景:
NFS 驱动
用于容器与远程 NFS 服务器的数据同步,适用于多节点共享数据:
docker volume create -d nfs \
--opt server=192.168.1.100 \
--opt share=/nfs/data \
nfs-volume
GlusterFS 驱动
提供分布式存储能力,适合需要高可用性的数据卷:
docker volume create -d glusterfs \
--opt volume-name=docker-vol \
--opt servers=gluster1:gluster2:gluster3 \
gluster-volume
通过 Cron 任务实现数据卷定期备份:
创建备份脚本
# backup_volumes.sh
#!/bin/bash
DATE=$(date +%Y%m%d)
VOLUMES=$(docker volume ls -q)
for VOL in $VOLUMES; do
docker run --rm -v $VOL:/data -v /backup:/backup alpine tar cvf /backup/$VOL-$DATE.tar /data
gzip /backup/$VOL-$DATE.tar
done
设置 Cron 计划
# 每周日凌晨2点执行备份
0 2 * * 0 /path/to/backup_volumes.sh
跨主机数据卷迁移
docker run --rm -v source-vol:/data -v $(pwd):/backup alpine tar cvf /backup/vol.tar /data
vol.tar
复制到目标主机并导入: docker volume create target-vol
docker run --rm -v target-vol:/data -v $(pwd):/backup alpine tar xvf /backup/vol.tar -C /data
容器数据批量导出
# 导出所有容器的文件系统
for CONTAINER in $(docker ps -a -q); do
docker export $CONTAINER > $CONTAINER.tar
done
Macvlan 驱动
为容器分配物理网络地址,使其直接接入宿主机网络:
docker network create -d macvlan \
--subnet=192.168.1.0/24 \
--gateway=192.168.1.1 \
--opt parent=eth0 \
macvlan-network
IPv6 网络支持
在daemon.json
中启用 IPv6 并配置子网:
{
"ipv6": true,
"fixed-cidr-v6": "2001:db8::/64"
}
服务发现与负载均衡
使用 Docker Swarm 的内置负载均衡功能,通过服务名称实现容器间通信:
# docker-compose.yml
version: '3'
services:
web:
image: nginx:1.24.0
ports:
- "80:80"
deploy:
replicas: 3
update_config:
parallelism: 1
delay: 10s
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: password
volumes:
- db-data:/var/lib/mysql
volumes:
db-data:
网络策略配置
通过--network-alias
为容器设置别名,简化服务间调用:
docker run -d --network my-network --network-alias api-server my-api:v1
容器网络连接测试
使用docker exec
进入容器后,通过ping
和telnet
测试网络连通性:
docker exec -it my-container bash
ping -c 3 google.com
telnet db-server 3306
查看网络配置
使用docker inspect
获取容器网络详细信息:
docker inspect -f "{{json .NetworkSettings}}" my-container
非 root 用户运行容器
在 Dockerfile 中使用USER
指令切换到非 root 用户:
FROM ubuntu:22.04
RUN useradd -m appuser
WORKDIR /app
COPY . .
USER appuser
CMD ["python", "app.py"]
限制容器能力
使用--cap-drop
参数移除不必要的系统能力:
docker run -d --cap-drop=ALL --cap-add=NET_BIND_SERVICE nginx:1.24.0
最小化镜像原则
-slim
后缀的基础镜像(如python:3.9-slim
)FROM alpine:3.16
RUN apk add --no-cache nginx && \
rm -rf /var/cache/apk/*
镜像漏洞扫描
在 CI 流程中集成镜像扫描工具,如:
# Jenkins Pipeline
stage('Security Scan') {
steps {
sh 'trivy image --severity HIGH,CRITICAL my-app:latest'
}
}
启用 Seccomp 配置
使用预定义的 Seccomp 配置文件限制容器系统调用:
docker run -d --security-opt seccomp=default nginx:1.24.0
配置 AppArmor 策略
在宿主机上为容器应用 AppArmor 配置文件:
docker run -d --security-opt apparmor=nginx-profile nginx:1.24.0