第一章:Docker基础概念与核心原理
Docker 是一种开源的容器化平台,允许开发者将应用程序及其依赖打包到一个轻量、可移植的容器中,从而实现“一次构建,随处运行”。其核心基于 Linux 内核的命名空间(Namespaces)和控制组(Cgroups)技术,为应用提供隔离的运行环境。
镜像与容器的关系
Docker 镜像是一个只读模板,包含运行应用程序所需的所有文件、库和配置。容器则是镜像的运行实例。每次启动容器时,Docker 会在镜像之上添加一个可写层,供运行时使用。
- 镜像通过 Dockerfile 定义构建过程
- 容器由镜像启动,具备独立的文件系统和网络栈
- 多个容器可共享同一镜像,节省存储资源
核心组件架构
Docker 系统主要由以下几个组件构成:
| 组件 | 功能描述 |
|---|
| Docker Daemon | 后台服务,负责管理镜像、容器、网络和存储 |
| Docker Client | 用户与 Docker Daemon 交互的命令行工具(如 docker run) |
| Registry | 集中存放镜像的仓库,如 Docker Hub |
运行一个简单容器
以下命令将从 Docker Hub 拉取 Nginx 镜像并启动一个容器:
# 拉取官方 Nginx 镜像
docker pull nginx
# 启动容器,映射主机 8080 端口到容器 80 端口
docker run -d -p 8080:80 --name my-nginx nginx
上述指令中,
-d 表示后台运行,
-p 实现端口映射,
--name 为容器指定名称。执行后可通过浏览器访问
http://localhost:8080 查看 Nginx 欢迎页。
graph TD
A[Dockerfile] --> B[Build]
B --> C[Docker Image]
C --> D[Run]
D --> E[Docker Container]
E --> F[Isolated Process]
第二章:Docker环境搭建与基础操作
2.1 理解镜像与容器:从概念到实践
镜像与容器的基本关系
Docker 镜像是一个只读模板,包含运行容器所需的文件系统和配置。容器则是镜像的可运行实例,具备独立进程空间和网络栈。
- 镜像通过分层结构实现高效复用
- 容器在镜像之上添加可写层
- 同一镜像可启动多个隔离容器
快速启动一个Nginx容器
docker run -d --name my-nginx -p 8080:80 nginx:alpine
该命令拉取
nginx:alpine 镜像并后台运行容器,将主机 8080 端口映射至容器 80 端口。
-d 表示守护模式,
--name 指定容器名称。
镜像与容器的状态管理
| 操作 | 镜像命令 | 容器命令 |
|---|
| 列出 | docker images | docker ps -a |
| 删除 | docker rmi | docker rm |
2.2 安装Docker并验证运行环境
在主流Linux发行版中,安装Docker推荐使用官方仓库方式,以确保版本的稳定性和及时更新。
安装步骤
- 更新系统包索引:
sudo apt update - 安装依赖包以支持HTTPS源:
sudo apt install ca-certificates curl gnupg - 添加Docker官方GPG密钥:
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
上述命令创建密钥环目录并将Docker GPG公钥写入,确保软件包来源可信。参数
-m 0755设置目录权限为仅所有者可写,增强安全性。
验证安装
安装完成后执行:
sudo docker run hello-world
该命令会拉取测试镜像并在容器中运行,输出成功信息表示Docker引擎正常工作。若出现权限错误,需将用户加入docker组:
sudo usermod -aG docker $USER。
2.3 运行第一个Nginx容器并访问服务
启动一个Nginx容器是验证Docker环境是否正常工作的最直观方式。使用以下命令即可快速部署:
docker run -d -p 8080:80 --name my-nginx nginx
该命令中,
-d 表示后台运行容器,
-p 8080:80 将主机的8080端口映射到容器的80端口,
--name my-nginx 指定容器名称便于管理,最后的
nginx 是官方镜像名。
参数详解与作用
- -d(detach):使容器在后台独立运行,不占用当前终端
- -p(publish):建立主机与容器之间的端口映射关系
- --name:为容器指定易读名称,替代随机生成的ID
验证服务可访问性
执行完成后,可通过浏览器或curl访问
http://localhost:8080,若返回Nginx欢迎页,说明容器已成功运行且网络配置正确。
2.4 容器生命周期管理:启动、停止与删除
容器的生命周期由创建、运行、暂停、停止到最终删除构成,Docker 提供了标准化命令进行全流程控制。
常用生命周期命令
docker run:创建并启动容器docker start:启动已停止的容器docker stop:优雅停止运行中的容器(发送 SIGTERM)docker rm:删除容器
典型操作示例
# 启动一个 Nginx 容器
docker run -d --name webserver nginx
# 停止正在运行的容器
docker stop webserver
# 删除已停止的容器
docker rm webserver
上述命令中,
-d 表示后台运行,
--name 指定容器名称便于管理。stop 命令会先发送终止信号,等待容器进程退出,若超时未响应则强制 kill。
批量清理策略
可结合过滤参数高效管理:
docker rm $(docker ps -aq --filter status=exited)
该命令删除所有非运行状态的容器,
ps -aq 列出所有容器 ID,
--filter 精准匹配退出状态。
2.5 镜像操作实战:拉取、查看与清理
拉取远程镜像
使用
docker pull 命令可从镜像仓库下载指定镜像。例如:
docker pull nginx:latest
该命令从 Docker Hub 拉取最新版 Nginx 镜像。
nginx 是镜像名称,
latest 是标签,代表最新版本。
查看本地镜像
拉取后可通过以下命令列出所有本地镜像:
docker images
输出包含镜像名、标签、镜像ID、创建时间及占用空间,便于资源管理。
清理无用镜像
为释放磁盘空间,可删除未被使用的镜像:
docker rmi <IMAGE_ID>:删除指定镜像docker image prune -a:清除所有悬空镜像
定期清理可避免存储资源浪费,保持环境整洁。
第三章:Dockerfile构建自定义镜像
3.1 Dockerfile语法详解与最佳实践
Dockerfile基础指令解析
Dockerfile是构建Docker镜像的核心脚本,每条指令代表一个镜像层。常用指令包括
FROM、
COPY、
RUN、
CMD等。
# 基于官方Ubuntu镜像
FROM ubuntu:22.04
# 维护者信息
LABEL maintainer="dev@example.com"
# 安装依赖
RUN apt-get update && apt-get install -y nginx
# 复制本地文件到容器
COPY index.html /var/www/html/
# 暴露端口
EXPOSE 80
# 启动命令
CMD ["nginx", "-g", "daemon off;"]
上述代码中,
FROM指定基础镜像;
RUN在构建时执行命令;
COPY复制上下文文件;
EXPOSE声明服务端口;
CMD定义容器启动时的默认行为。
最佳实践建议
- 使用精简的基础镜像(如Alpine Linux)以减小体积
- 合并频繁变更的
RUN指令以减少镜像层数 - 利用缓存机制,将不变指令置于Dockerfile上游
- 避免在镜像中存储敏感信息,应通过环境变量注入
3.2 编写第一个Dockerfile部署静态网站
在本节中,我们将通过编写一个简单的 Dockerfile 来部署一个静态网站。使用 Nginx 作为 Web 服务器是部署静态资源的常见选择。
构建基础镜像
首先创建项目目录,并准备一个简单的 HTML 文件
index.html,然后编写 Dockerfile:
FROM nginx:alpine
COPY index.html /usr/share/nginx/html/index.html
EXPOSE 80
上述代码中,
FROM 指令指定基础镜像是轻量级的
nginx:alpine;
COPY 将本地的 HTML 文件复制到容器中的 Nginx 默认路径;
EXPOSE 80 声明服务运行端口。
构建与运行容器
执行以下命令构建镜像并运行容器:
docker build -t my-static-site .docker run -d -p 8080:80 my-static-site
访问
http://localhost:8080 即可查看部署成功的静态页面。
3.3 构建并测试自定义镜像
编写Dockerfile构建镜像
FROM ubuntu:20.04
LABEL maintainer="admin@example.com"
RUN apt-get update && apt-get install -y nginx
COPY index.html /var/www/html/
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
该Dockerfile基于Ubuntu 20.04安装Nginx,将自定义页面复制到Web根目录。其中
EXPOSE 80声明服务端口,
CMD指定容器启动命令。
构建与验证流程
使用以下命令构建镜像:
docker build -t my-nginx:v1 .:构建并标记镜像docker run -d -p 8080:80 my-nginx:v1:启动容器映射端口curl http://localhost:8080:验证服务响应
通过本地访问测试,确认自定义内容正确加载,表明镜像构建成功且运行正常。
第四章:容器网络与数据持久化
4.1 理解Docker默认网络模式与端口映射
Docker 默认采用 `bridge` 网络模式,容器启动时会自动连接到默认的桥接网络 `docker0`,实现容器间通信和外部访问。
默认网络模式特性
- 每个容器分配独立的 IP 地址
- 容器之间可通过内部 IP 通信
- 对外暴露服务需依赖端口映射
端口映射配置
使用
-p 参数将宿主机端口映射到容器:
docker run -d -p 8080:80 nginx
该命令将宿主机的 8080 端口映射到容器的 80 端口。参数解析:
8080 是宿主机端口,
80 是容器内服务监听端口,实现外部通过
http://localhost:8080 访问 Nginx 服务。
常用端口映射方式对比
| 模式 | 语法 | 说明 |
|---|
| 绑定特定端口 | -p 8080:80 | 宿主 8080 → 容器 80 |
| 随机分配端口 | -P | Docker 自动分配高位端口 |
4.2 自定义网络连接多个容器
在 Docker 中,自定义网络能够实现多个容器间的高效通信与服务发现。通过创建独立的用户定义网络,容器可以在隔离环境中安全交互。
创建自定义网络
使用以下命令创建一个桥接网络:
docker network create --driver bridge mynet
其中
--driver bridge 指定使用桥接模式,
mynet 为网络名称,可供后续容器加入。
容器连接与通信
启动两个容器并接入同一网络:
docker run -d --name web --network mynet nginx
docker run -it --name client --network mynet alpine ping web
Docker 内置 DNS 服务器允许容器通过名称(如
web)直接解析 IP,无需手动绑定。
| 参数 | 说明 |
|---|
| --network | 指定容器加入的网络 |
| --name | 为容器分配可解析的主机名 |
4.3 使用卷(Volume)实现数据持久化
在容器化应用中,数据的持久化是关键需求。Docker 卷(Volume)是 Docker 原生支持的数据持久化机制,独立于容器生命周期,确保数据不随容器删除而丢失。
创建与使用卷
通过以下命令可创建并挂载卷:
docker volume create app-data
docker run -d --name webapp -v app-data:/app/data nginx
其中,
app-data 是命名卷名称,挂载至容器内的
/app/data 路径,实现数据持久存储。
卷的优势
- 数据独立于容器,支持跨容器共享;
- 可由 Docker 管理,支持备份、迁移和快照;
- 性能优于绑定挂载(Bind Mount),尤其在 macOS 和 Windows 上。
典型应用场景
| 场景 | 说明 |
|---|
| 数据库存储 | 如 MySQL 数据目录挂载至卷,防止数据丢失 |
| 日志持久化 | 将应用日志写入卷,便于集中分析 |
4.4 实战:部署带持久化存储的MySQL容器
在生产环境中,数据库的数据持久化至关重要。使用Docker部署MySQL时,必须通过卷(Volume)机制实现数据持久化,避免容器重启导致数据丢失。
创建持久化存储卷
使用Docker命名卷可方便管理数据:
docker volume create mysql_data
该命令创建名为
mysql_data 的卷,用于存放MySQL的数据文件,确保数据独立于容器生命周期。
启动带持久化的MySQL容器
docker run -d \
--name mysql-db \
-e MYSQL_ROOT_PASSWORD=securepass123 \
-v mysql_data:/var/lib/mysql \
-p 3306:3306 \
mysql:8.0
关键参数说明:
-v mysql_data:/var/lib/mysql 将命名卷挂载到MySQL数据目录;
-e MYSQL_ROOT_PASSWORD 设置初始密码;
-p 3306:3306 映射默认端口,便于外部访问。
第五章:总结与进阶学习建议
构建持续学习的技术路径
技术演进迅速,掌握基础后应主动拓展知识边界。建议从实际项目出发,逐步引入高阶概念,如微服务架构中的服务网格(Service Mesh)或事件驱动设计。
- 深入理解分布式系统的一致性模型,如 Raft 或 Paxos
- 实践容器编排技术,Kubernetes 集群管理是必备技能
- 关注可观测性三大支柱:日志、指标与追踪
代码质量与工程化实践
高质量代码不仅运行稳定,更易于维护。以下是一个 Go 语言中实现重试机制的实用示例:
// WithRetry 执行带指数退避的重试逻辑
func WithRetry(attempts int, sleep time.Duration, fn func() error) error {
var err error
for i := 0; i < attempts; i++ {
err = fn()
if err == nil {
return nil
}
time.Sleep(sleep)
sleep *= 2 // 指数退避
}
return fmt.Errorf("重试失败: %v", err)
}
技术选型参考矩阵
面对多样化的工具链,合理评估至关重要。下表列出常见场景的技术组合建议:
| 场景 | 推荐技术栈 | 适用规模 |
|---|
| 小型 Web 服务 | Go + Gin + SQLite | 千级 QPS |
| 高并发 API 网关 | Envoy + Kubernetes + Prometheus | 万级 QPS |
| 实时数据处理 | Kafka + Flink + Redis | 流式大规模 |
参与开源与实战积累
贡献开源项目是提升工程能力的有效途径。可从修复文档错别字开始,逐步参与功能开发。例如,向 CNCF 项目提交 PR,不仅能提升代码审查能力,还能建立技术影响力。