一、Docker 诞生逻辑:解决的核心问题
Docker 核心目标是解决软件开发与部署中的环境不一致痛点,具体解决以下三大问题:
- 环境配置繁琐:开发、测试、生产环境的操作系统、依赖版本、配置参数差异大,导致应用 "本地能跑,上线报错";
- 跨平台兼容困难:跨 Windows/Linux 等系统部署时,需重新配置环境,耗时费力;
- 部署一致性差:应用迭代后,不同版本的环境兼容对运维成本高。
Docker 核心思路:"带环境安装",提出 "镜像即应用" 理念 ------ 将应用运行所需的系统环境、依赖包、配置文件、代码完整打包为镜像,实现 "一次打包,到处运行"。
二、Docker 与传统虚拟机的核心区别
表格
| 特性 | 传统虚拟机(VMware/VirtualBox) | Docker 容器 |
|---|---|---|
| 虚拟化级别 | 硬件级虚拟化(模拟完整硬件) | 内核级虚拟化(共享宿主机内核) |
| 操作系统 | 每个虚拟机独立安装 Guest OS | 共享宿主机内核,无独立 OS |
| 体积 | 数 G 级别 | 数 M 级别 |
| 启动速度 | 数分钟 | 秒级 |
| 资源利用率 | 低(资源隔离导致浪费) | 极高(共享内核,按需分配资源) |
| 移植性 | 差(与 Hypervisor 强绑定) | 极强(跨 Docker 环境无缝运行) |
核心差异总结:虚拟机是 "模拟一台完整电脑",Docker 容器是 "模拟应用的最小运行环境"。
三、Docker 核心架构与三要素
1. 核心架构(C/S 架构)
表格
| 组件 | 核心职责 |
|---|---|
| Docker 客户端(Client) | 用户交互入口,通过 docker 命令向守护进程发送请求(支持本地 / 远程通信) |
| Docker 守护进程(Daemon) | 运行在宿主机的后台进程,管理镜像、容器、网络、数据卷等所有资源,处理客户端请求 |
| Docker 仓库(Registry) | 存储 / 分发镜像的远程服务,分公有(Docker Hub / 阿里云)和私有仓库 |
2. 三大核心要素(镜像 / 容器 / 仓库)
(1)镜像(Image):容器的 "模板"
- 本质 :静态、只读的文件包,包含应用运行所需的系统文件、依赖、配置、代码等(如
ubuntu:16.04、mysql:5.7); - 核心特性:分层存储(联合文件系统,拉取时仅下载缺失层)、不可修改(修改需基于原镜像创建新镜像);
- 作用:一个镜像可创建任意多个容器实例(类 → 实例)。
(2)容器(Container):镜像的 "运行实例"
- 本质:镜像运行时的动态实例,轻量版 Linux 系统(仅含应用运行最小环境);
- 核心特性:可写层(在镜像只读层上添加可写层,修改仅作用于该层)、完全隔离(沙箱机制,资源独立);
- 生命周期:可创建、启动、停止、删除、暂停。
(3)仓库(Repository):镜像的 "存储分发中心"
- 核心操作 :
docker pull(拉取镜像到本地)、docker push(推送本地镜像到仓库); - 镜像加速:国内配置阿里云 / 科大 / 网易镜像加速器,解决 Docker Hub 下载慢问题;
- 核心链路:仓库拉取镜像 → 基于镜像创建容器 → 运行容器提供服务。
四、Docker 核心常用操作
1. 镜像核心操作(查看 / 搜索 / 拉取 / 删除)
bash
运行
# 1. 查看本地镜像
docker images # 基础查看
docker images -aq # 仅显示所有镜像ID
# 2. 搜索远程镜像(Docker Hub)
docker search 镜像名 # 如 docker search mysql
# 3. 拉取远程镜像
docker pull mysql:5.7 # 指定版本
docker pull mysql # 默认拉取latest版本
# 4. 删除本地镜像
docker rmi -f 镜像ID # 删除单个镜像
docker rmi -f 镜像ID1 镜像ID2 # 删除多个镜像
docker rmi -f $(docker images -aq) # 删除所有镜像
2. 容器核心操作(创建 / 启动 / 进入 / 停止 / 删除)
bash
运行
# 1. 查看容器
docker ps # 查看运行中的容器
docker ps -a # 查看所有容器(运行+停止)
docker ps -q # 仅显示容器ID
# 2. 创建并启动容器(核心)
docker run -itd --name 容器名 -p 主机端口:容器端口 镜像名 /bin/bash
# 关键参数:
# --name:指定容器名(唯一)
# -d:后台运行
# -it:交互模式(配合/bin/bash进入容器)
# -p:端口映射(如 3306:3306)
# -P:随机端口映射
# 3. 进入运行中的容器
docker exec -it 容器ID/容器名 /bin/bash # 推荐(新终端,退出不停止容器)
docker attach 容器ID/容器名 # 老版本(原有终端,退出容器停止)
# 4. 容器启停/重启
docker start 容器ID/容器名 # 启动已停止容器
docker stop 容器ID/容器名 # 停止运行中容器
docker kill 容器ID/容器名 # 强制停止
docker restart 容器ID/容器名 # 重启容器
# 5. 删除容器
docker rm 容器ID/容器名 # 删除已停止容器
docker rm -f 容器ID/容器名 # 强制删除运行中容器
docker rm -f $(docker ps -aq) # 删除所有容器
3. 容器高级操作(日志 / 进程 / 元数据 / 数据拷贝)
bash
运行
# 1. 查看容器日志
docker logs -tf 容器ID # 实时查看+显示时间戳
docker logs --tail 100 容器ID # 查看最后100行日志
# 2. 查看容器内进程
docker top 容器ID/容器名
# 3. 查看容器元数据(网络/挂载/环境变量等)
docker inspect 容器ID/容器名
# 4. 宿主机与容器数据拷贝
docker cp 容器ID:容器内路径 宿主机路径 # 容器 → 宿主机
docker cp 宿主机路径 容器ID:容器内路径 # 宿主机 → 容器
五、Docker 网络:容器互联互通
1. 宿主机访问容器:端口映射
通过 -p 参数绑定宿主机端口与容器端口,实现外网访问:
bash
运行
# 宿主机3344端口映射到容器8080端口(tomcat)
docker run -itd -p 3344:8080 --name tomcat01 tomcat
# 访问:宿主机IP:3344 → 容器内tomcat
2. 容器间通信:虚拟网络
Docker 默认创建 docker0 桥接网络(网段 172.17.0.X),同一网络容器可通过内网 IP 通信。
bash
运行
# 1. 查看Docker网络
docker network ls
# 2. 创建自定义桥接网络(隔离通信)
docker network create -d bridge mynet01
# 3. 容器加入/退出自定义网络
docker run -itd --name tomcat03 --network mynet01 tomcat # 创建时加入
docker network connect mynet01 容器ID # 已存在容器加入
docker network disconnect mynet01 容器ID # 容器退出网络
六、Docker 数据持久化:数据卷(Volume)
1. 核心原理
数据卷是宿主机目录 / 文件与容器目录 / 文件的绑定,实现双向实时同步,数据独立于容器生命周期(容器删除数据不丢失)。
2. 核心操作:目录映射(-v 参数)
bash
运行
# 基础语法:-v 宿主机目录:容器目录
docker run -itd -v /tmp/webapps:/usr/local/tomcat/webapps --name tomcat02 tomcat
# 实战:MySQL 数据持久化
docker run -d -p 3306:3306 \
-v /home/mysql/conf:/etc/mysql/conf.d \ # 配置文件持久化
-v /home/mysql/data:/var/lib/mysql \ # 数据持久化
-e MYSQL_ROOT_PASSWORD=123456 \ # 设置root密码
--name mysql01 \
mysql
3. 数据卷核心特性
- 双向同步:宿主机 / 容器修改实时同步;
- 持久化存储:独立于容器,容器删除数据仍在;
- 可共享:多个容器挂载同一数据卷,实现数据共享;
- 易备份:直接备份宿主机数据卷目录。
七、Docker 定制镜像:commit vs Dockerfile
1. 简易定制:docker commit(不推荐)
基于运行中的容器制作镜像,无追溯性,适合简单场景:
bash
运行
# 1. 启动默认tomcat,进入容器修改
docker run -d -p 8080:8080 tomcat
docker exec -it 容器ID /bin/bash
cp -r webapps.dist/* webapps # 修复tomcat默认无webapps问题
exit
# 2. 制作新镜像
docker commit -a="作者" -m="add webapps" 容器ID mytomcat:1.0
2. 标准定制:Dockerfile(企业级推荐)
Dockerfile 是构建镜像的脚本文件,包含镜像构建的所有步骤,支持自动化、可重复构建。
(1)Dockerfile 核心指令
表格
| 指令 | 作用 |
|---|---|
| FROM | 指定基础镜像(所有镜像必须包含),如 FROM centos:7 |
| RUN | 镜像构建时执行命令(如安装软件),如 RUN yum -y install vim |
| ADD/COPY | 宿主机文件复制到容器(ADD 自动解压压缩包,COPY 仅复制) |
| WORKDIR | 指定容器工作目录(后续命令基于该目录) |
| VOLUME | 定义匿名数据卷(持久化) |
| EXPOSE | 声明容器暴露端口(仅声明,不映射) |
| ENV | 设置环境变量(如 ENV JAVA_HOME /usr/local/jdk8) |
| CMD/ENTRYPOINT | 容器启动命令(CMD 可被覆盖,ENTRYPOINT 不可覆盖) |
(2)实战:定制 JDK8+Tomcat8.5 镜像
步骤 1 :准备文件(jdk-8u161-linux-x64.tar.gz、apache-tomcat-8.5.20.tar.gz、Dockerfile 同目录);步骤 2:编写 Dockerfile:
dockerfile
# 基础镜像
FROM centos:7
# 作者信息
MAINTAINER libowen<379872721@qq.com>
# 添加并解压JDK/Tomcat
ADD jdk-8u161-linux-x64.tar.gz /usr/local
ADD apache-tomcat-8.5.20.tar.gz /usr/local
# 安装vim
RUN yum -y install vim
# 设置环境变量
ENV MYPATH /usr/local
WORKDIR $MYPATH
ENV JAVA_HOME $MYPATH/jdk1.8.0_161
ENV CLASS_PATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME $MYPATH/apache-tomcat-8.5.20
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
# 暴露端口
EXPOSE 8080
# 启动Tomcat并跟踪日志
CMD $MYPATH/apache-tomcat-8.5.20/bin/startup.sh && tail -F $MYPATH/apache-tomcat-8.5.20/logs/catalina.out
步骤 3:构建镜像并启动容器:
bash
运行
# 构建镜像
docker build -t mytomcat8:1.0 .
# 启动容器
docker run -itd -p 8081:8080 --name tomcat8 mytomcat8:1.0
八、镜像 / 容器的导入导出(离线迁移)
1. 镜像导入导出(保留分层,推荐)
bash
运行
# 导出镜像为压缩包
docker save -o nginx.tar nginx:latest
# 导入镜像
docker load -i nginx.tar
2. 容器导入导出(仅保留当前状态,体积小)
bash
运行
# 导出容器为压缩包
docker export 容器ID -o mysql.tar
# 导入为新镜像
docker import mysql.tar mysql:v001
九、实战:SpringBoot 微服务容器化
1. 核心步骤
- SpringBoot 项目打包为 JAR 包(如
blog-0.0.1-SNAPSHOT.jar); - 编写 Dockerfile(同 JAR 包目录);
- 构建镜像;
- 启动容器。
2. 实战代码
Dockerfile:
dockerfile
# 基础镜像:JDK8
FROM java:8
# 添加JAR包并命名
ADD blog-0.0.1-SNAPSHOT.jar /blog.jar
# 声明暴露端口
EXPOSE 8080
# 启动命令
ENTRYPOINT ["java", "-jar", "/blog.jar"]
构建 + 启动:
bash
运行
# 构建镜像
docker build -t blog:1.0 .
# 启动容器
docker run -itd -p 8080:8080 --name blog-service blog:1.0
十、Docker 核心价值与 DevOps 落地
- 快速交付部署:一次打包,多环境运行,交付周期从天级缩至分钟级;
- 便捷扩缩容:基于镜像快速创建 / 停止容器,配合 K8s 实现自动化扩缩容;
- 简化运维:开发 / 测试 / 生产环境一致,降低排障成本;
- 高效资源利用:内核级虚拟化,服务器资源利用率提升数倍。
总结
- 核心逻辑:Docker 以 "镜像标准化打包、容器隔离化运行" 解决环境不一致问题,核心是镜像和容器两大组件;
- 核心操作:围绕镜像(拉取 / 构建 / 删除)、容器(创建 / 启停 / 数据卷 / 网络)展开,Dockerfile 是企业级镜像定制的标准方式;
- 核心价值:实现应用 "一次打包,到处运行",是 DevOps 和云原生技术的基础,为后续 K8s 学习打下核心基础。