1. Docker 简介
1.1 出现原因
解决开发和运维之间因运行环境不一致而产生的问题——开发完将代码和环境打包给运维,实现”一次镜像,处处运行”。
1.2 核心目标
Build, Ship and Run Any App Anywhere — 通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的 APP 运行环境能够做到”一次镜像,处处运行”。
容器技术演进路线:光盘 > Appliance > Virtual Machine > Docker
Docker 可以存放:静态 Web 网站、用户数据库、前端、消息队列、中间件等。
1.3 容器与虚拟机比较
传统虚拟机技术(Virtual Machine):
- 带环境安装的一种解决方案
- 虚拟机就是一个普通文件,不用就删
- 基于安装在操作系统上的虚拟机管理系统,虚拟出各种硬件
- 缺点:资源占用多、冗余步骤多、启动慢
容器虚拟化技术:
- 弥补传统虚拟机的缺点
- 与系统其他部分隔离开的一系列进程,从另一个镜像运行
- 不是模拟一个完整的操作系统,而是对进程进行隔离
- 不需要捆绑一整套操作系统
1.4 DevOps 价值
- 更快速的应用交付和部署
- 更便捷的升级和扩缩容
- 更简单的运维
- 更高效的计算资源利用
1.5 使用企业
新浪、美团、蘑菇街等。
1.6 相关网站
2. Docker 安装
2.1 基本组成
| 组件 | 说明 |
|---|---|
| 镜像(Image) | 只读的模板,可用来创建 Docker 容器 |
| 容器(Container) | 容器是用镜像创建的运行实例,可看作简易版的 Linux 环境 |
| 仓库(Repository) | 集中存放镜像,分为公开仓库和私有仓库 |
2.2 平台架构
Docker 采用 C/S 模式架构,后端是松耦合架构。

2.3 CentOS 7 安装步骤
# 1. 确定 CentOS 版本cat /etc/redhat-release
# 2. 卸载旧版本yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine
# 3. 安装 gcc 相关依赖yum install -y gcc gcc-c++
# 4. 安装 yum-utilsyum install -y yum-utils
# 5. 设置阿里云镜像仓库yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 6. 安装 Docker CEyum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# 7. 启动 Dockersystemctl start docker
# 8. 验证安装docker run hello-world卸载 Docker:
yum remove docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extrasrm -rf /var/lib/dockerrm -rf /var/lib/containerd2.4 阿里云镜像加速
- 注册阿里云账号
- 获取镜像加速地址
- 粘贴脚本执行
- 重启 Docker 服务
2.5 底层原理
Docker 利用的是宿主机的内核,不需要加载操作系统 OS 内核,因此比虚拟机有更少的抽象层,启动更快、资源占用更少。

2.6 docker run hello-world 执行流程
本地没有 hello-world 镜像时,Docker 从远程仓库下载镜像,在容器内运行,输出 “Hello from Docker!” 后容器自动终止。
3. Docker 常用命令
3.1 帮助启动类命令
# 启动 / 停止 / 重启 Dockersystemctl start dockersystemctl stop dockersystemctl restart docker
# 查看 Docker 状态systemctl status docker
# 设置开机自启systemctl enable docker
# 查看概要信息docker info
# 查看帮助文档docker --helpdocker 具体命令 --help3.2 镜像命令
# 列出本地所有镜像docker images
# 搜索镜像是否存在远程仓库docker search 镜像名
# 下载镜像docker pull 镜像名
# 查看镜像/容器/数据卷所占空间docker system df
# 删除镜像(-f 强制删除)docker rmi 镜像名/镜像IDdocker rmi -f 镜像名/镜像ID
# 删除所有镜像docker rmi -f $(docker images -q)3.3 容器命令
# 新建并启动容器(交互模式)docker run -it --name=容器名 镜像名 /bin/bash
# 新建并启动容器(后台模式/守护式容器)docker run -d 镜像名
# 端口映射启动docker run -d -p 外部端口:内部端口 镜像名docker run 常用参数:
| 参数 | 说明 |
|---|---|
-i | 以交互模式运行 |
-t | 为容器重新分配一个伪输入终端 |
--name | 为容器指定名称 |
-d | 后台运行并返回容器 ID |
-p | 端口映射(主机端口:容器端口) |
-P | 随机端口映射 |
--privileged=true | 授予容器扩展权限 |
# 列出当前正在运行的容器docker ps
# 列出所有容器(包含历史)docker ps -a
# 退出容器# 方式一:exit(容器停止)# 方式二:Ctrl + P + Q(容器不停止)
# 启动 / 重启 / 停止 / 强制停止 容器docker start 容器ID或容器名docker restart 容器ID或容器名docker stop 容器ID或容器名docker kill 容器ID或容器名
# 删除已停止的容器docker rm 容器ID或容器名
# 一次性删除多个容器docker rm -f $(docker ps -a -q)docker ps -a -q | xargs docker rm3.4 容器管理命令
# 查看容器日志docker logs 容器ID或容器名
# 查看容器内运行的进程docker top 容器ID或容器名
# 查看容器内部细节docker inspect 容器ID或容器名
# 进入正在运行的容器(推荐)docker exec -it 容器ID bash
# 重新进入容器docker attach 容器ID
exec和attach的区别:exec进入容器后开启新的终端,attach直接进入容器启动命令的终端。
3.5 文件拷贝与导入导出
# 从容器内拷贝文件到主机docker cp 容器ID:容器内路径 目的主机路径docker cp c056eed39a11:/tmp/1 /root
# 导出容器为 tar 归档文件docker export 容器ID > 文件名.tar
# 从 tar 包导入为镜像cat redis.tar | docker import - test/redis:latest
# 保存镜像为 tar 文件docker save -o 文件名.tar 镜像名:版本
# 从 tar 文件加载镜像docker load -i 文件名.tar3.6 提交容器为新镜像
# 将容器提交为新的镜像docker commit -m="提交的描述信息" -a="作者" 容器ID 目标镜像名:[标签名]docker commit -m="add vim wget" -a="zzvv" ac988ab03635 test/centos:83.7 镜像打标签与推送
# 镜像打标签docker tag 镜像ID 指定仓库地址/仓库名:镜像版本
# 推送镜像到仓库docker push 指定仓库地址/仓库名:镜像版本4. Docker 镜像
4.1 镜像概念
- 轻量、可执行的独立软件包
- 只能通过镜像文件才能生成 Docker 容器实例
4.2 分层镜像
pull 镜像的过程就是一层一层在下载。
4.3 UnionFS(联合文件系统)
- 分层、轻量且高性能的文件系统
- 支持对文件系统的修改作为一次提交来一层层叠加
- 可将不同目录挂载到同一虚拟文件系统下
- 镜像可以通过分层来进行继承
- 是 Docker 镜像的基础
- 特性:一次同时加载多个文件系统,各层文件系统叠加起来,外部看是一个文件系统
4.4 镜像加载原理
- Docker 镜像由一层一层的文件系统组成
- 最底层是引导文件系统
bootfs(boot file system),包含 bootloader 和 kernel - boot 加载完整内核后存在于内存中,内存使用权从 bootfs 转交给内核,然后卸载 bootfs
4.5 分层结构的好处
最大好处是共享资源,方便复制迁移。
Docker 镜像层都是只读的,容器层是可写的。
5. 本地镜像发布到阿里云
5.1 操作流程
- 登录阿里云开发者平台:https://cr.console.aliyun.com/
- 进入控制台 > 容器镜像服务
- 创建命名空间和仓库名称
- 进入管理界面获取脚本
- 将本地镜像推送到阿里云
# 登录阿里云容器镜像服务docker login --username=用户名 registry.cn-hangzhou.aliyuncs.com
# 为镜像打标签docker tag 镜像ID registry.cn-hangzhou.aliyuncs.com/命名空间/仓库名:版本
# 推送镜像docker push registry.cn-hangzhou.aliyuncs.com/命名空间/仓库名:版本6. 本地镜像发布到私有仓库
6.1 搭建 Docker Registry 私有仓库
# 1. 拉取 registry 镜像docker pull registry
# 2. 运行私有库(使用容器卷映射)docker run -d -p 5000:5000 -v /root/registry:/tmp/registry --privileged=true registry
# 3. 为镜像打标签(指向私有仓库地址)docker tag redis:latest 8.130.164.248:5000/redis:latest
# 4. 修改 Docker 配置,增加加速节点和仓库节点vi /etc/docker/daemon.json{ "registry-mirrors": ["https://c5fd77pt.mirror.aliyuncs.com"], "insecure-registries": ["172.24.252.156:5000"]}# 5. 重启 Dockersystemctl restart docker
# 6. 推送镜像到私有仓库docker push 8.130.164.248:5000/redis:latest
# 7. 验证仓库中的镜像curl -XGET http://8.130.164.248:5000/v2/_catalog
# 8. 从私有仓库拉取镜像docker pull 8.130.164.248:5000/redis:latest7. Docker 容器数据卷
7.1 概念
卷(Volume)是目录或文件,设计目的是数据的持久化,完全独立于容器的生存周期。Docker 容器删除时不会删除其挂载的数据卷。
7.2 特点
- 数据卷可在容器之间共享或重用数据
- 卷中的更改可以直接实时生效
- 数据卷中的更改不会包含在镜像的更新中
- 数据卷的生命周期一直持续到没有容器使用它
7.3 创建数据卷
# 创建映射(-v 物理机路径:容器内路径)docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录 镜像名添加
--privileged=true参数,否则挂载会遇到cannot open directory: Permission denied错误。
7.4 读写规则
# 默认读写模式docker run -it --privileged=true -v /宿主机目录:/容器内目录 镜像名
# 只读模式(容器内只读不写)docker run -it --privileged=true -v /宿主机目录:/容器内目录:ro 镜像名7.5 卷的继承和共享
# 容器2 继承容器1 的卷规则docker run -it --privileged=true --volumes-from 父容器 镜像名8. Docker 常规安装简介
8.1 通用步骤
- 搜索镜像:
docker search 镜像名 - 拉取镜像:
docker pull 镜像名 - 查看镜像:
docker images - 启动镜像:
docker run - 停止容器:
docker stop - 移除容器:
docker rm
8.2 常见应用安装
Tomcat:
docker search tomcatdocker pull tomcatdocker run -d -p 8080:8080 --name mytomcat tomcatMySQL:
docker search mysqldocker pull mysql:5.7docker run -d -p 3306:3306 \ --name mymysql \ -e MYSQL_ROOT_PASSWORD=root \ -v /root/mysql/data:/var/lib/mysql \ mysql:5.7Redis:
docker search redisdocker pull redisdocker run -d -p 6379:6379 \ --name myredis \ redisNginx:
docker search nginxdocker pull nginxdocker run -d -p 80:80 \ --name mynginx \ -v /root/nginx/html:/usr/share/nginx/html \ nginx9. Dockerfile 解析
9.1 概念
Dockerfile 是构建 Docker 镜像的文本文件,由构建镜像所需的指令和参数构成的脚本。
9.2 构建三部曲
- 编写 Dockerfile 文件
- 构建 镜像:
docker build - 运行 容器:
docker run
9.3 基础知识
- 每条保留字指令都必须为大写字母,且后面要跟随至少一个参数
- 指令按照从上到下顺序执行
#表示注释- 每条指令都会创建一个新的镜像层并对镜像进行提交
9.4 构建流程
- 从基础镜像运行一个容器
- 执行一条指令并对容器做出修改
- 执行类似
docker commit的操作提交一个新的镜像层 - Docker 再基于刚提交的镜像运行一个新容器
- 执行 Dockerfile 中的下一条指令,直到所有指令执行完成
9.5 常用保留字指令
| 指令 | 说明 |
|---|---|
FROM | 基础镜像,指定存在的镜像作为模板 |
MAINTAINER | 镜像维护者的姓名和邮箱地址 |
RUN | 容器构建时需要运行的命令(docker build 时执行) |
EXPOSE | 当前容器对外暴露的端口 |
WORKDIR | 指定创建容器后终端默认登录的工作目录 |
USER | 指定镜像以什么用户执行,默认 root |
ENV | 在构建镜像过程中设置环境变量 |
ADD | 将宿主机目录下的文件拷贝进镜像,且会自动处理 URL 和解压 tar 压缩包 |
COPY | 将构建上下文目录中的文件/目录复制到镜像内的目标路径 |
VOLUME | 容器数据卷,用于数据保存和持久化 |
CMD | 指定容器启动后要执行的命令(docker run 时执行),可被覆盖 |
ENTRYPOINT | 指定容器启动时要运行的命令,不会被覆盖 |
9.6 CMD 与 RUN 的区别
- RUN:在
docker build构建镜像时执行 - CMD:在
docker run启动容器时执行
Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效。CMD 会被
docker run之后的参数替换。
9.7 ENTRYPOINT 与 CMD 的配合
ENTRYPOINT 不会被 docker run 后面的命令覆盖。当 ENTRYPOINT 和 CMD 一起使用时,CMD 不再是直接运行命令,而是作为参数传递给 ENTRYPOINT:
ENTRYPOINT ["executable"]CMD ["param1", "param2"]# 最终执行:executable param1 param2优点:执行 docker run 时可以指定 ENTRYPOINT 运行所需的参数。
9.8 Dockerfile 实战案例
自定义镜像 MyCentosJava-8,使 CentOS 7 具备 vim + ifconfig + JDK8:
FROM centos:7
ENV MYPATH /usr/localWORKDIR $MYPATH
RUN yum -y install vim net-tools glibc.i686RUN mkdir -p /usr/local/java
ADD jdk-8u144-linux-x64.tar.gz /usr/local/java/
ENV JAVA_HOME /usr/local/java/jdk1.8.0_144ENV JRE_HOME $JAVA_HOME/jreENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATHENV PATH $JAVA_HOME/bin:$PATH
EXPOSE 80
CMD echo $MYPATHCMD echo "success--------ok"CMD /bin/bash构建镜像:
docker build -t centos-new:7 .10. Docker 微服务实战
10.1 构建微服务项目
通过 IDEA 新建普通微服务模块:
- 建 Module:
docker_boot - 改 POM
- 写 YML
- 主启动类
- 业务类
10.2 Dockerfile 发布微服务
- IDEA 打包微服务 jar 包
- 编写 Dockerfile
- 构建镜像:
docker build -t 镜像名 . - 运行容器:
docker run -d -p 端口:端口 镜像名 - 访问测试
11. Docker 网络
11.1 网络情况
- 未启动 Docker 时:
ens33、lo、virbr0 - 启动 Docker 后:会产生名为
docker0的虚拟网桥
11.2 常用命令
# 查看网络docker network ls
# 查看网络源数据docker network inspect 网络名字
# 删除网络docker network rm 网络名字
# 创建网络docker network create 网络名字11.3 网络模式
| 模式 | 参数 | 说明 |
|---|---|---|
| bridge | --network bridge | 默认模式,为每个容器分配 IP 并连接至 docker0 虚拟网桥 |
| host | --network host | 容器不虚拟自己的网卡,使用宿主机的 IP 和端口 |
| none | --network none | 容器有独立的 Network namespace,但没有进行任何网络设置 |
| container | --network container:容器名 | 新容器和指定容器共享 IP、端口范围等 |
11.4 自定义网络
容器 IP 变动时可以通过服务名直接网络通信,不受 IP 变化影响。
12. Docker Compose 容器编排
12.1 概念
Docker Compose 负责实现对 Docker 容器集群的快速编排,可以管理多个 Docker 容器组成的一个应用。需要定义一个 YAML 配置文件,配置好容器之间的调度问题就能直接管理多个容器。
12.2 核心概念
| 概念 | 说明 |
|---|---|
| 服务(Service) | 一个个应用的容器实例 |
| 工程(Project) | 由一组关联的应用容器组成的一个完整业务单元 |
| 配置文件 | docker-compose.yaml |
12.3 三步骤
- 编写 Dockerfile — 定义各个微服务应用并构建出对应的镜像文件
- 编写 docker-compose.yaml — 定义完整业务单元,安排好整体应用中各个容器服务
- 执行 docker-compose up — 启动并运行整个应用程序,完成一键部署上线
12.4 常用命令
| 命令 | 说明 |
|---|---|
docker-compose up | 创建并启动所有容器 |
docker-compose up -d | 后台创建并启动所有容器 |
docker-compose down | 停止并删除容器、网络、卷、镜像 |
docker-compose ps | 列出项目中所有容器 |
docker-compose logs | 查看容器日志 |
docker-compose build | 构建或重新构建服务 |
docker-compose start | 启动已存在的容器 |
docker-compose stop | 停止运行中的容器 |
docker-compose restart | 重启容器 |
12.5 Compose 编排微服务
改造微服务工程 docker_boot:
- SQL 建表建库
- 改 POM
- 写 YML
- 主启动类
- 业务类
mvn package打成 jar 包上传到 Linux
不使用 Compose 的方式:
- 单独启动 MySQL 容器实例
- 单独启动 Redis 容器实例
- 单独启动微服务工程
- 需要手动管理启动顺序
使用 Compose 的方式:
- 通过
docker-compose.yaml一键定义和管理所有容器 - 自动处理依赖和启动顺序
13. 可视化工具与容器监控
13.1 Portainer — 轻量级可视化工具
Portainer 是 Docker 的轻量级可视化管理工具,提供 Web 界面管理 Docker 容器、镜像、网络、数据卷等。
13.2 CAdvisor + InfluxDB + Grafana — 容器监控方案
- CAdvisor:容器资源监控工具,收集容器的 CPU、内存、网络等数据
- InfluxDB:时序数据库,存储 CAdvisor 收集的监控数据
- Grafana:数据可视化平台,展示 InfluxDB 中的监控数据