mirror of
https://github.com/yeasy/docker_practice.git
synced 2026-08-10 16:37:34 +00:00
Fix and improve
This commit is contained in:
+2
-1
@@ -152,7 +152,8 @@ module.exports = config({
|
||||
// }]
|
||||
// }
|
||||
],
|
||||
sidebar: {
|
||||
sidebar: "auto",
|
||||
legacySidebar: {
|
||||
'/cloud/': [
|
||||
'intro',
|
||||
'tencentCloud',
|
||||
|
||||
@@ -88,8 +88,7 @@ $ git clone https://github.com/company/project.git
|
||||
$ docker compose up
|
||||
## 完整的开发环境就准备好了
|
||||
|
||||
具体内容如下:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
#### 2. 秒级启动
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
## 2.1 Docker 镜像
|
||||
|
||||
## Docker 镜像
|
||||
|
||||
Docker 镜像作为容器运行的基石,其设计理念和实现机制至关重要。本节将深入探讨镜像的本质、与操作系统的关系、内容构成以及核心的分层存储机制。
|
||||
|
||||
### 一句话理解镜像
|
||||
@@ -50,7 +48,6 @@ Docker 镜像是一个特殊的文件系统,包含:
|
||||
|
||||
### 分层存储:镜像的核心设计
|
||||
|
||||
### 分层存储:镜像的核心设计
|
||||
|
||||
镜像的分层存储机制是 Docker 最具创新性的特性之一。通过 Union FS 技术,Docker 能够高效地构建和管理镜像。
|
||||
|
||||
@@ -128,8 +125,6 @@ RUN apt-get update
|
||||
RUN apt-get install -y build-essential # 安装编译工具(约 200MB)
|
||||
RUN make && make install # 编译应用
|
||||
RUN apt-get remove build-essential # 试图删除编译工具
|
||||
## 结果:镜像仍然包含 200MB 的编译工具!
|
||||
|
||||
## 结果:镜像仍然包含 200MB 的编译工具!
|
||||
```
|
||||
|
||||
@@ -144,8 +139,6 @@ RUN apt-get update && \
|
||||
apt-get autoremove -y && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
## 在同一层完成安装、使用、清理
|
||||
|
||||
## 在同一层完成安装、使用、清理
|
||||
```
|
||||
|
||||
#### 查看镜像的分层
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
## 2.2 Docker 容器
|
||||
|
||||
## Docker 容器
|
||||
|
||||
容器是 Docker 技术的核心,是应用实际运行的载体。本节将从容器的本质、与虚拟机的区别、存储层机制以及生命周期管理等方面,全面解析 Docker 容器。
|
||||
|
||||
### 一句话理解容器
|
||||
@@ -73,7 +71,6 @@
|
||||
|
||||
### 容器的存储层
|
||||
|
||||
### 容器的存储层
|
||||
|
||||
理解容器的存储层机制对于数据的持久化和镜像的优化至关重要。本节将介绍容器的可写层以及 Copy-on-Write 机制。
|
||||
|
||||
@@ -126,8 +123,6 @@ root@abc123:/# exit
|
||||
|
||||
$ docker rm abc123
|
||||
|
||||
## 数据丢了!没有任何办法恢复!
|
||||
|
||||
## 数据丢了!没有任何办法恢复!
|
||||
```
|
||||
|
||||
@@ -154,7 +149,6 @@ $ docker run -v /host/path:/container/path nginx
|
||||
|
||||
### 容器的生命周期
|
||||
|
||||
### 容器的生命周期
|
||||
|
||||
掌握容器的生命周期对于管理和调试 Docker 应用非常重要。下图展示了容器从创建到删除的完整状态流转。
|
||||
|
||||
@@ -222,8 +216,6 @@ $ docker rm -f abc123 # 强制删除运行中的容器
|
||||
```bash
|
||||
## 主进程运行,容器运行
|
||||
|
||||
## 主进程退出,容器停止
|
||||
|
||||
## 主进程退出,容器停止
|
||||
```
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
## 2.3 Docker Registry
|
||||
|
||||
## Docker Registry
|
||||
|
||||
Docker Registry 是镜像分发和管理的核心组件。本节将介绍 Registry 的基本概念、公共和私有服务的选择,以及镜像的安全管理。
|
||||
|
||||
### 一句话理解 Registry
|
||||
@@ -12,10 +10,6 @@ Docker Registry 是镜像分发和管理的核心组件。本节将介绍 Regist
|
||||
|
||||
### 核心概念
|
||||
|
||||
#### Registry、仓库、标签的关系
|
||||
|
||||
### 核心概念
|
||||
|
||||
要熟练使用 Docker Registry,首先需要理清它与仓库(Repository)、标签(Tag)之间的关系。
|
||||
|
||||
#### Registry、仓库、标签的关系
|
||||
@@ -50,9 +44,6 @@ Docker Registry 中可以包含多个 Repository,每个 Repository 可以包
|
||||
| **Tag(标签)** | 仓库内的版本标识 | `latest`、`1.25`、`alpine` |
|
||||
|
||||
#### 镜像的完整名称
|
||||
|
||||
#### 镜像的完整名称
|
||||
|
||||
一个完整的 Docker 镜像名称由 Registry 地址、用户名/组织名、仓库名和标签组成。了解其结构有助于我们更准确地定位镜像。
|
||||
|
||||
```
|
||||
@@ -90,7 +81,6 @@ gcr.io/google-containers/pause:3.6
|
||||
|
||||
### 公共 Registry 服务
|
||||
|
||||
### 公共 Registry 服务
|
||||
|
||||
公共 Registry 服务为开发者提供了便捷的镜像获取途径。其中最著名的是 Docker Hub。
|
||||
|
||||
@@ -138,7 +128,7 @@ $ docker push username/myapp:v1.0
|
||||
}
|
||||
```
|
||||
|
||||
详细配置方法请参考[镜像加速器](../install/3.9_mirror.md)章节。
|
||||
详细配置方法请参考[镜像加速器](../03_install/3.9_mirror.md)章节。
|
||||
|
||||
> ⚠️ **笔者提醒**:镜像加速器的可用性经常变化,使用前建议先测试是否可用。
|
||||
|
||||
@@ -148,7 +138,6 @@ $ docker push username/myapp:v1.0
|
||||
|
||||
#### 官方 Registry 镜像
|
||||
|
||||
#### 官方 Registry 镜像
|
||||
|
||||
Docker 官方提供了 [registry](https://hub.docker.com/_/registry/) 镜像,可以快速搭建私有 Registry:
|
||||
|
||||
@@ -174,7 +163,7 @@ $ docker pull localhost:5000/myapp:v1.0
|
||||
| 方案 | 特点 |
|
||||
|------|------|
|
||||
| **[Harbor](https://goharbor.io/)** | CNCF 项目,功能全面(用户管理、漏洞扫描、镜像签名) |
|
||||
| **[Nexus Repository](../repository/6.4_nexus3_registry.md)** | 支持多种制品类型(Docker、Maven、npm 等) |
|
||||
| **[Nexus Repository](../06_repository/6.4_nexus3_registry.md)** | 支持多种制品类型(Docker、Maven、npm 等) |
|
||||
| **云厂商服务** | 阿里云 ACR、腾讯云 TCR、AWS ECR 等 |
|
||||
|
||||
笔者建议:
|
||||
@@ -184,10 +173,6 @@ $ docker pull localhost:5000/myapp:v1.0
|
||||
|
||||
### 镜像的推送和拉取
|
||||
|
||||
#### 完整工作流程
|
||||
|
||||
### 镜像的推送和拉取
|
||||
|
||||
掌握镜像的推送(Push)和拉取(Pull)是使用 Docker Registry 的基本功。
|
||||
|
||||
#### 完整工作流程
|
||||
@@ -239,7 +224,6 @@ $ docker logout
|
||||
|
||||
### 镜像的安全性
|
||||
|
||||
### 镜像的安全性
|
||||
|
||||
在使用公共镜像或维护私有镜像时,安全性是不容忽视的重要环节。
|
||||
|
||||
@@ -298,11 +282,11 @@ $ trivy image nginx:latest
|
||||
| **Docker Hub** | 默认的公共 Registry |
|
||||
| **私有 Registry** | 企业内部使用,推荐 Harbor |
|
||||
|
||||
现在你已经了解了 Docker 的三个核心概念:[镜像](2.1_image.md)、[容器](2.2_container.md)和仓库。接下来,让我们开始[安装 Docker](../install/README.md),动手实践!
|
||||
现在你已经了解了 Docker 的三个核心概念:[镜像](2.1_image.md)、[容器](2.2_container.md)和仓库。接下来,让我们开始[安装 Docker](../03_install/README.md),动手实践!
|
||||
|
||||
### 延伸阅读
|
||||
|
||||
- [Docker Hub](../repository/6.1_dockerhub.md):Docker Hub 的详细使用
|
||||
- [私有仓库](../repository/6.2_registry.md):搭建私有 Registry
|
||||
- [私有仓库高级配置](../repository/6.3_registry_auth.md):认证、TLS 配置
|
||||
- [镜像加速器](../install/3.9_mirror.md):配置镜像加速
|
||||
- [Docker Hub](../06_repository/6.1_dockerhub.md):Docker Hub 的详细使用
|
||||
- [私有仓库](../06_repository/6.2_registry.md):搭建私有 Registry
|
||||
- [私有仓库高级配置](../06_repository/6.3_registry_auth.md):认证、TLS 配置
|
||||
- [镜像加速器](../03_install/3.9_mirror.md):配置镜像加速
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
## 3.1 Ubuntu 安装 Docker
|
||||
|
||||
## Ubuntu 安装 Docker
|
||||
|
||||
Ubuntu 是 Docker 最常用的运行环境之一。本节将介绍如何在 Ubuntu 系统上安装 Docker,并配置国内镜像加速。
|
||||
|
||||
>警告:切勿在没有配置 Docker APT 源的情况下直接使用 apt 命令安装 Docker.
|
||||
|
||||
### 准备工作
|
||||
|
||||
### 准备工作
|
||||
|
||||
在开始安装之前,我们需要确认系统版本是否满足要求,并清理可能存在的旧版本。
|
||||
|
||||
@@ -188,4 +185,4 @@ For more examples and ideas, visit:
|
||||
|
||||
### 参考文档
|
||||
|
||||
* [Docker 官方 Ubuntu 安装文档](https://docs.docker.com/install/linux/docker-ce/ubuntu/)
|
||||
* [Docker 官方 Ubuntu 安装文档](https://docs.docker.com/engine/install/ubuntu/)
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
## 3.2 Debian 安装 Docker
|
||||
|
||||
## Debian 安装 Docker
|
||||
|
||||
Debian 以其稳定性著称,是 Docker 的理想宿主系统。本节将指导你在 Debian 上完成 Docker 的安装。
|
||||
|
||||
>警告:切勿在没有配置 Docker APT 源的情况下直接使用 apt 命令安装 Docker.
|
||||
|
||||
### 准备工作
|
||||
|
||||
### 准备工作
|
||||
|
||||
安装前请仔细检查 Debian 版本支持情况,并卸载旧版本以避免冲突。
|
||||
|
||||
@@ -181,4 +178,4 @@ For more examples and ideas, visit:
|
||||
|
||||
### 参考文档
|
||||
|
||||
* [Docker 官方 Debian 安装文档](https://docs.docker.com/install/linux/docker-ce/debian/)
|
||||
* [Docker 官方 Debian 安装文档](https://docs.docker.com/engine/install/debian/)
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
## 3.3 Fedora 安装 Docker
|
||||
|
||||
## Fedora 安装 Docker
|
||||
|
||||
Fedora 作为技术前沿的 Linux 发行版,对 Docker 有着良好的支持。本节介绍在 Fedora 上的安装步骤。
|
||||
|
||||
>警告:切勿在没有配置 Docker dnf 源的情况下直接使用 dnf 命令安装 Docker.
|
||||
|
||||
### 准备工作
|
||||
|
||||
### 准备工作
|
||||
|
||||
确保你的 Fedora 版本在支持列表中,并清理旧版本。
|
||||
|
||||
@@ -39,7 +36,6 @@ $ sudo dnf remove docker \
|
||||
|
||||
### 使用 dnf 安装
|
||||
|
||||
### 使用 dnf 安装
|
||||
|
||||
使用 dnf 包管理器安装是推荐的方式,便于后续的更行和管理。
|
||||
|
||||
@@ -190,4 +186,4 @@ For more examples and ideas, visit:
|
||||
|
||||
### 参考文档
|
||||
|
||||
* [Docker 官方 Fedora 安装文档](https://docs.docker.com/install/linux/docker-ce/fedora)。
|
||||
* [Docker 官方 Fedora 安装文档](https://docs.docker.com/engine/install/fedora/)。
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
## 3.4 CentOS 安装 Docker
|
||||
|
||||
## CentOS 安装 Docker
|
||||
|
||||
CentOS(及其替代品 Rocky Linux、AlmaLinux)是企业级服务器常用的操作系统。本节介绍在这些系统上安装 Docker 的步骤。
|
||||
|
||||
>警告:切勿在没有配置 Docker YUM 源的情况下直接使用 yum 命令安装 Docker.
|
||||
|
||||
### 准备工作
|
||||
|
||||
### 准备工作
|
||||
|
||||
安装前请确认系统版本和内核版本满足 Docker 的运行要求。
|
||||
|
||||
@@ -41,7 +38,6 @@ $ sudo yum remove docker \
|
||||
|
||||
### 使用 yum 安装
|
||||
|
||||
### 使用 yum 安装
|
||||
|
||||
使用 yum/dnf 安装是管理 Docker 生命周期的标准方式。
|
||||
|
||||
@@ -219,6 +215,6 @@ $ sudo sysctl -p
|
||||
|
||||
### 参考文档
|
||||
|
||||
* [Docker 官方 CentOS 安装文档](https://docs.docker.com/install/linux/docker-ce/centos/)。
|
||||
* [Docker 官方 CentOS 安装文档](https://docs.docker.com/engine/install/centos/)。
|
||||
* https://firewalld.org/2018/07/nftables-backend
|
||||
* https://github.com/moby/libnetwork/issues/2496
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
## 3.5 树莓派卡片电脑安装 Docker
|
||||
|
||||
## 树莓派卡片电脑安装 Docker
|
||||
|
||||
树莓派等 ARM 架构设备在物联网和边缘计算领域应用广泛。本节介绍如何在树莓派上安装 Docker。
|
||||
|
||||
>警告:切勿在没有配置 Docker APT 源的情况下直接使用 apt 命令安装 Docker.
|
||||
|
||||
@@ -70,4 +70,4 @@ $ docker rm webserver
|
||||
|
||||
### 参考链接
|
||||
|
||||
* [官方文档](https://docs.docker.com/docker-for-mac/install/)
|
||||
* [官方文档](https://docs.docker.com/desktop/setup/install/mac-install/)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
### 系统要求
|
||||
|
||||
[Docker Desktop for Windows](https://docs.docker.com/docker-for-windows/install/) 支持 64 位版本的 Windows 11 或 Windows 10(需开启 Hyper-V),推荐使用 Windows 11。
|
||||
[Docker Desktop for Windows](https://docs.docker.com/desktop/setup/install/windows-install/) 支持 64 位版本的 Windows 11 或 Windows 10(需开启 Hyper-V),推荐使用 Windows 11。
|
||||
|
||||
### 安装
|
||||
|
||||
@@ -44,5 +44,5 @@ Docker 启动之后会在 Windows 任务栏出现鲸鱼图标。
|
||||
|
||||
### 参考链接
|
||||
|
||||
* [官方文档](https://docs.docker.com/docker-for-windows/install/)
|
||||
* [官方文档](https://docs.docker.com/desktop/setup/install/windows-install/)
|
||||
* [WSL 2 Support is coming to Windows 10 Versions 1903 and 1909](https://devblogs.microsoft.com/commandline/wsl-2-support-is-coming-to-windows-10-versions-1903-and-1909/)
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
## 4.1 获取镜像
|
||||
|
||||
## 获取镜像
|
||||
|
||||
从 Docker 镜像仓库获取镜像可谓是 Docker 运作的第一步。本节将介绍如何使用 `docker pull` 命令下载镜像,以及如何理解下载过程。
|
||||
|
||||
### docker pull 命令
|
||||
@@ -14,7 +12,6 @@ docker pull [选项] [Registry地址/]仓库名[:标签]
|
||||
|
||||
#### 镜像名称格式
|
||||
|
||||
#### 镜像名称格式
|
||||
|
||||
Docker 镜像名称由 Registry 地址、用户名、仓库名和标签组成。其标准格式如下:
|
||||
|
||||
@@ -184,7 +181,7 @@ $ sudo systemctl restart docker # Linux
|
||||
## 或在 Docker Desktop 中重启
|
||||
```
|
||||
|
||||
详见 [镜像加速器](../install/3.9_mirror.md) 章节。
|
||||
详见 [镜像加速器](../03_install/3.9_mirror.md) 章节。
|
||||
|
||||
---
|
||||
|
||||
@@ -266,5 +263,5 @@ $ docker system prune
|
||||
|
||||
- [列出镜像](4.2_list.md):查看本地镜像
|
||||
- [删除镜像](4.3_rm.md):清理本地镜像
|
||||
- [镜像加速器](../install/3.9_mirror.md):加速镜像下载
|
||||
- [Docker Hub](../repository/6.1_dockerhub.md):官方镜像仓库
|
||||
- [镜像加速器](../03_install/3.9_mirror.md):加速镜像下载
|
||||
- [Docker Hub](../06_repository/6.1_dockerhub.md):官方镜像仓库
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
## 4.2 列出镜像
|
||||
|
||||
## 列出镜像
|
||||
|
||||
在下载了镜像后,我们可以使用 `docker image ls` 命令列出本地主机上的镜像。
|
||||
|
||||
### 基本用法
|
||||
|
||||
+1
-4
@@ -94,7 +94,6 @@ Deleted: sha256:32770d1dcf835f192cafd6b9263b7b597a1778a403a109e2cc2ee866f74adf23
|
||||
|
||||
#### 删除流程
|
||||
|
||||
#### 删除流程
|
||||
|
||||
Docker 会检测镜像是否有容器依赖或其他标签指向,只有在确认为无用资源时才会真正删除存储层。
|
||||
|
||||
@@ -218,8 +217,6 @@ $ docker rmi ubuntu:24.04
|
||||
Untagged: ubuntu:24.04
|
||||
## 只是移除标签,镜像仍存在(因为还有 ubuntu:latest 指向它)
|
||||
|
||||
#### 原因二:多个标签指向同一镜像
|
||||
|
||||
当同一个镜像有多个标签时,`docker rmi` 只是删除指定的标签,不会删除镜像本身。
|
||||
|
||||
```
|
||||
@@ -306,5 +303,5 @@ Build Cache 0 0 0B 0B
|
||||
### 延伸阅读
|
||||
|
||||
- [列出镜像](4.2_list.md):查看和过滤镜像
|
||||
- [删除容器](../05_container/4.3_rm.md):清理容器
|
||||
- [删除容器](../05_container/5.6_rm.md):清理容器
|
||||
- [数据卷](../08_data_network/data/volume.md):清理数据卷
|
||||
|
||||
@@ -255,5 +255,5 @@ $ docker run -v mydata:/app/data myapp
|
||||
|
||||
- [后台运行](5.2_daemon.md):理解 `-d` 参数和容器生命周期
|
||||
- [进入容器](5.4_attach_exec.md):操作运行中的容器
|
||||
- [网络配置](../network/README.md):理解端口映射的原理
|
||||
- [网络配置](../08_data_network/network/README.md):理解端口映射的原理
|
||||
- [数据管理](../08_data_network/README.md):数据持久化方案
|
||||
|
||||
@@ -59,8 +59,6 @@ $ docker run -d ubuntu:24.04
|
||||
|
||||
#### 核心原理:容器的生命周期与主进程绑定
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ Docker 容器的生命周期 = 容器内 PID 1 进程的生命周期 │
|
||||
@@ -168,8 +166,7 @@ $ docker run --rm ubuntu:24.04 echo "Hello, World!"
|
||||
Hello, World!
|
||||
## 容器执行完后自动删除
|
||||
|
||||
具体内容如下:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
#### 4. 配合日志查看
|
||||
@@ -242,4 +239,4 @@ $ docker attach mycontainer
|
||||
- [进入容器](5.4_attach_exec.md):如何进入正在运行的容器执行命令
|
||||
- [容器日志](../16_appendix/16.1_best_practices.md):生产环境的日志管理最佳实践
|
||||
- [HEALTHCHECK 健康检查](../07_dockerfile/7.12_healthcheck.md):自动检测容器内服务是否正常
|
||||
- [Docker Compose](../compose/README.md):管理多个后台容器的更好方式
|
||||
- [Docker Compose](../10_compose/README.md):管理多个后台容器的更好方式
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
### docker stop(推荐)
|
||||
|
||||
#### 基本用法
|
||||
#### docker stop 基本用法
|
||||
|
||||
运行以下命令:
|
||||
|
||||
@@ -296,6 +296,6 @@ $ docker inspect 容器名
|
||||
|
||||
### 延伸阅读
|
||||
|
||||
- [启动容器](5.1_run.md):容器启动详解
|
||||
- [删除容器](4.3_rm.md):清理容器
|
||||
- [容器日志](logs.md):排查停止原因
|
||||
- [启动容器](../05_container/5.1_run.md):容器启动详解
|
||||
- [删除容器](5.6_rm.md):清理容器
|
||||
- [容器日志](5.2_daemon.md):排查停止原因
|
||||
|
||||
@@ -24,7 +24,7 @@ Docker 提供两种进入容器的命令:
|
||||
|
||||
### docker exec(推荐)
|
||||
|
||||
#### 基本用法
|
||||
#### docker exec 基本用法
|
||||
|
||||
运行以下命令:
|
||||
|
||||
@@ -49,7 +49,7 @@ $ docker exec -it 容器名 /bin/sh
|
||||
| `-w` | 指定工作目录 |
|
||||
| `-e` | 设置环境变量 |
|
||||
|
||||
#### 示例
|
||||
#### docker exec 示例
|
||||
|
||||
运行以下命令:
|
||||
|
||||
@@ -117,7 +117,7 @@ root@69d137adef7a:/# # 有提示符
|
||||
|
||||
### docker attach(谨慎使用)
|
||||
|
||||
#### 基本用法
|
||||
#### docker attach 基本用法
|
||||
|
||||
运行以下命令:
|
||||
|
||||
@@ -139,7 +139,7 @@ $ docker attach 容器名
|
||||
└─────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### 示例
|
||||
#### docker attach 示例
|
||||
|
||||
运行以下命令:
|
||||
|
||||
@@ -292,5 +292,5 @@ $ docker exec -u root -it myapp bash
|
||||
### 延伸阅读
|
||||
|
||||
- [后台运行](5.2_daemon.md):理解容器主进程
|
||||
- [查看容器](ls.md):列出和过滤容器
|
||||
- [容器日志](logs.md):查看容器输出
|
||||
- [查看容器](5.1_run.md):列出和过滤容器
|
||||
- [容器日志](5.2_daemon.md):查看容器输出
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
本章将具体介绍如何来管理一个容器,包括创建、启动和停止等。
|
||||
|
||||
* [启动容器](5.1_run.md)
|
||||
* [启动容器](../05_container/5.1_run.md)
|
||||
* [守护态运行](5.2_daemon.md)
|
||||
* [终止容器](5.3_stop.md)
|
||||
* [进入容器](5.4_attach_exec.md)
|
||||
|
||||
@@ -48,8 +48,7 @@ $ docker pull nginx:alpine
|
||||
$ docker login
|
||||
## 输入用户名和密码
|
||||
|
||||
具体内容如下:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
打标签并推送:
|
||||
@@ -139,4 +138,4 @@ Docker Hub 会对官方镜像和付费用户的镜像进行安全扫描。在镜
|
||||
### 延伸阅读
|
||||
|
||||
- [私有仓库](6.2_registry.md):搭建自己的 Registry
|
||||
- [镜像加速器](../install/3.9_mirror.md):加速下载
|
||||
- [镜像加速器](../03_install/3.9_mirror.md):加速下载
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
|
||||
如果您需要搭建私有仓库,可以通过官方提供的 `registry` 镜像快速部署。
|
||||
|
||||
|
||||
你可以使用官方 `registry` 镜像来运行。
|
||||
|
||||
```bash
|
||||
|
||||
@@ -140,11 +140,9 @@ $ docker run --rm \
|
||||
|
||||
### 编辑 Docker Compose 配置
|
||||
|
||||
编辑 `docker-compose.yml` 配置如下:
|
||||
编辑 `compose.yaml`(或 `docker-compose.yml`)配置如下:
|
||||
|
||||
```yaml
|
||||
|
||||
|
||||
services:
|
||||
registry:
|
||||
image: registry
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
### 基本语法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
WORKDIR <工作目录路径>
|
||||
```
|
||||
@@ -14,8 +12,6 @@ WORKDIR <工作目录路径>
|
||||
|
||||
### 基本用法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
WORKDIR /app
|
||||
|
||||
@@ -30,8 +26,6 @@ COPY . . # 复制到 /app/
|
||||
|
||||
#### 常见错误
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ❌ 错误:cd 在下一个 RUN 中无效
|
||||
|
||||
@@ -41,8 +35,6 @@ RUN echo "hello" > world.txt # 文件在根目录!
|
||||
|
||||
#### 原因分析
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```
|
||||
RUN cd /app
|
||||
↓
|
||||
@@ -58,8 +50,6 @@ RUN echo "hello" > world.txt
|
||||
|
||||
#### 正确做法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ✅ 正确:使用 WORKDIR
|
||||
|
||||
@@ -85,8 +75,6 @@ RUN pwd # 输出 /a/b/c
|
||||
|
||||
### 使用环境变量
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ENV APP_HOME=/app
|
||||
WORKDIR $APP_HOME
|
||||
@@ -98,8 +86,6 @@ RUN pwd # 输出 /app
|
||||
|
||||
### 多阶段构建中的 WORKDIR
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 构建阶段
|
||||
|
||||
@@ -123,8 +109,6 @@ COPY --from=builder /build/dist .
|
||||
|
||||
#### 1. 尽早设置 WORKDIR
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
FROM node:20
|
||||
WORKDIR /app # 尽早设置
|
||||
@@ -137,8 +121,6 @@ CMD ["node", "server.js"]
|
||||
|
||||
#### 2. 使用绝对路径
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ✅ 推荐:绝对路径,意图明确
|
||||
|
||||
@@ -151,8 +133,6 @@ WORKDIR app
|
||||
|
||||
#### 3. 不要用 RUN cd
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ❌ 避免
|
||||
|
||||
@@ -166,8 +146,6 @@ RUN echo "hello" > world.txt
|
||||
|
||||
#### 4. 适时重置 WORKDIR
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
WORKDIR /app
|
||||
## ... 应用相关操作 ...
|
||||
@@ -175,8 +153,7 @@ WORKDIR /app
|
||||
WORKDIR /data
|
||||
## ... 数据相关操作 ...
|
||||
|
||||
具体内容如下:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
---
|
||||
@@ -224,6 +201,6 @@ $ docker run -w /tmp myimage pwd
|
||||
|
||||
### 延伸阅读
|
||||
|
||||
- [COPY 复制文件](copy.md):文件复制
|
||||
- [RUN 执行命令](../../04_image/4.5_build.md):执行构建命令
|
||||
- [最佳实践](../../16_appendix/16.1_best_practices.md):Dockerfile 编写指南
|
||||
- [COPY 复制文件](7.2_copy.md):文件复制
|
||||
- [RUN 执行命令](../04_image/4.5_build.md):执行构建命令
|
||||
- [最佳实践](../16_appendix/16.1_best_practices.md):Dockerfile 编写指南
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
### 基本语法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
USER <用户名>[:<用户组>]
|
||||
USER <UID>[:<GID>]
|
||||
@@ -39,8 +37,6 @@ root 用户运行的风险:
|
||||
|
||||
#### 创建并切换用户
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
FROM node:20-alpine
|
||||
|
||||
@@ -65,8 +61,6 @@ CMD ["node", "server.js"]
|
||||
|
||||
#### 使用 UID/GID
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 也可以使用数字
|
||||
|
||||
@@ -214,8 +208,6 @@ CMD ["node", "server.js"]
|
||||
|
||||
#### 1. 始终使用非 root 用户
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ✅ 推荐
|
||||
|
||||
@@ -242,8 +234,6 @@ USER 1000:1000
|
||||
|
||||
#### 3. 多阶段构建中的 USER
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 构建阶段可以用 root
|
||||
|
||||
@@ -302,6 +292,6 @@ RUN mkdir -p /app/data && chown appuser:appuser /app/data
|
||||
|
||||
### 延伸阅读
|
||||
|
||||
- [安全](../../security/README.md):容器安全实践
|
||||
- [ENTRYPOINT](entrypoint.md):入口脚本中的用户切换
|
||||
- [最佳实践](../../16_appendix/16.1_best_practices.md):Dockerfile 安全
|
||||
- [安全](../11_ops/security/README.md):容器安全实践
|
||||
- [ENTRYPOINT](7.5_entrypoint.md):入口脚本中的用户切换
|
||||
- [最佳实践](../16_appendix/16.1_best_practices.md):Dockerfile 安全
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
### 基本语法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
HEALTHCHECK [选项] CMD <命令>
|
||||
HEALTHCHECK NONE
|
||||
@@ -38,8 +36,6 @@ Starting ──成功──> Healthy ──失败N次──> Unhealthy
|
||||
|
||||
#### Web 服务检查
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
FROM nginx
|
||||
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
|
||||
@@ -94,8 +90,6 @@ HEALTHCHECK CMD wget -q --spider http://localhost/ || exit 1
|
||||
|
||||
#### 数据库
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## MySQL
|
||||
|
||||
@@ -108,8 +102,6 @@ HEALTHCHECK CMD redis-cli ping || exit 1
|
||||
|
||||
#### 自定义脚本
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
COPY healthcheck.sh /usr/local/bin/
|
||||
HEALTHCHECK CMD ["healthcheck.sh"]
|
||||
@@ -119,7 +111,7 @@ HEALTHCHECK CMD ["healthcheck.sh"]
|
||||
|
||||
### 在 Compose 中使用
|
||||
|
||||
可以在 `docker-compose.yml` 中覆盖或定义健康检查:
|
||||
可以在 `compose.yaml`(或 `docker-compose.yml`)中覆盖或定义健康检查:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
@@ -218,6 +210,6 @@ HEALTHCHECK --start-period=60s CMD curl -f http://localhost/ || exit 1
|
||||
|
||||
### 延伸阅读
|
||||
|
||||
- [CMD 容器启动命令](cmd.md):启动主进程
|
||||
- [Compose 模板文件](../../compose/10.5_compose_file.md):Compose 中的健康检查
|
||||
- [Docker 调试](../../16_appendix/16.2_debug.md):容器排障
|
||||
- [CMD 容器启动命令](7.4_cmd.md):启动主进程
|
||||
- [Compose 模板文件](../10_compose/10.5_compose_file.md):Compose 中的健康检查
|
||||
- [Docker 调试](../16_appendix/16.2_debug.md):容器排障
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
### 基本语法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ONBUILD <其它指令>
|
||||
```
|
||||
@@ -52,16 +50,13 @@ FROM my-node-base
|
||||
|
||||
## 构建时会自动执行 COPY 和 RUN
|
||||
|
||||
具体内容如下:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 执行机制
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```
|
||||
基础镜像构建:
|
||||
Dockerfile (含 ONBUILD) ──build──> 基础镜像 (记录了 ONBUILD 触发器)
|
||||
@@ -77,8 +72,6 @@ FROM 基础镜像 ──build──> 读取基础镜像触发器 ──> 执行
|
||||
|
||||
#### 1. 自动处理依赖安装
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## Python 基础镜像
|
||||
|
||||
@@ -88,8 +81,6 @@ ONBUILD RUN pip install -r requirements.txt
|
||||
|
||||
#### 2. 自动编译代码
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## Go 基础镜像
|
||||
|
||||
@@ -99,8 +90,6 @@ ONBUILD RUN go build -o app main.go
|
||||
|
||||
#### 3. 处理静态资源
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## Nginx 静态网站基础镜像
|
||||
|
||||
@@ -165,5 +154,5 @@ python:3.12-onbuild
|
||||
|
||||
### 延伸阅读
|
||||
|
||||
- [COPY 指令](copy.md):文件复制
|
||||
- [Dockerfile 最佳实践](../../16_appendix/16.1_best_practices.md):基础镜像设计
|
||||
- [COPY 指令](7.2_copy.md):文件复制
|
||||
- [Dockerfile 最佳实践](../16_appendix/16.1_best_practices.md):基础镜像设计
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
### 基本语法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
LABEL <key>=<value> <key>=<value> ...
|
||||
```
|
||||
@@ -25,8 +23,6 @@ LABEL <key>=<value> <key>=<value> ...
|
||||
|
||||
#### 定义单个标签
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
LABEL version="1.0"
|
||||
LABEL description="这是一个 Web 应用服务器"
|
||||
@@ -34,8 +30,6 @@ LABEL description="这是一个 Web 应用服务器"
|
||||
|
||||
#### 定义多个标签(推荐)
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
LABEL maintainer="user@example.com" \
|
||||
version="1.2.0" \
|
||||
@@ -65,8 +59,6 @@ LABEL maintainer="user@example.com" \
|
||||
|
||||
#### 示例
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
LABEL org.opencontainers.image.authors="yeasy" \
|
||||
org.opencontainers.image.documentation="https://yeasy.gitbooks.io" \
|
||||
@@ -164,4 +156,4 @@ $ docker rmi $(docker images -q --filter "label=stage=builder")
|
||||
### 延伸阅读
|
||||
|
||||
- [OCI 标签规范](https://github.com/opencontainers/image-spec/blob/main/annotations.md)
|
||||
- [Dockerfile 最佳实践](../../16_appendix/16.1_best_practices.md)
|
||||
- [Dockerfile 最佳实践](../16_appendix/16.1_best_practices.md)
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
### 基本语法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
SHELL ["executable", "parameters"]
|
||||
```
|
||||
@@ -150,5 +148,5 @@ SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
|
||||
### 延伸阅读
|
||||
|
||||
- [RUN 指令](../../04_image/4.5_build.md):执行命令
|
||||
- [Dockerfile 最佳实践](../../16_appendix/16.1_best_practices.md):错误处理与调试
|
||||
- [RUN 指令](../04_image/4.5_build.md):执行命令
|
||||
- [Dockerfile 最佳实践](../16_appendix/16.1_best_practices.md):错误处理与调试
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
## 7.17 多阶段构建
|
||||
|
||||
## 之前的做法
|
||||
|
||||
在 Docker 17.05 版本之前,我们构建 Docker 镜像时,通常会采用两种方式:
|
||||
|
||||
### 全部放入一个 Dockerfile
|
||||
|
||||
一种方式是将所有的构建过程编包含在一个 `Dockerfile` 中,包括项目及其依赖库的编译、测试、打包等流程,这里可能会带来的一些问题:
|
||||
一种方式是将所有的构建过程包含在一个 `Dockerfile` 中,包括项目及其依赖库的编译、测试、打包等流程,这里可能会带来的一些问题:
|
||||
|
||||
* 镜像层次多,镜像体积较大,部署时间变长
|
||||
|
||||
|
||||
@@ -27,8 +27,7 @@ storage/
|
||||
|
||||
## 自行添加其他需要排除的文件,例如 .env.* 文件
|
||||
|
||||
具体内容如下:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
在 `laravel.conf` 文件中写入 nginx 配置。
|
||||
@@ -123,8 +122,6 @@ RUN set -x ; cd ${LARAVEL_PATH} \
|
||||
|
||||
### 最后一个阶段构建 NGINX 镜像
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
FROM nginx:alpine as nginx
|
||||
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
### 基本语法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
RUN <command>
|
||||
RUN ["executable", "param1", "param2"]
|
||||
@@ -17,8 +15,6 @@ RUN ["executable", "param1", "param2"]
|
||||
|
||||
#### 1. Shell 格式
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
RUN apt-get update
|
||||
```
|
||||
@@ -32,8 +28,6 @@ RUN apt-get update
|
||||
|
||||
#### 2. Exec 格式
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
RUN ["apt-get", "update"]
|
||||
```
|
||||
@@ -105,8 +99,6 @@ RUN wget http://url | gzip -d > file
|
||||
|
||||
#### Q: 为什么 `RUN cd /app` 不生效?
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
RUN cd /app
|
||||
RUN touch hello.txt
|
||||
@@ -125,8 +117,6 @@ RUN touch hello.txt
|
||||
|
||||
#### Q: 环境变量不生效?
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
RUN export MY_VAR=hello
|
||||
RUN echo $MY_VAR
|
||||
@@ -189,6 +179,6 @@ RUN --mount=type=secret,id=mysecret \
|
||||
|
||||
### 延伸阅读
|
||||
|
||||
- [CMD 容器启动命令](cmd.md):容器启动时的命令
|
||||
- [WORKDIR 指定工作目录](workdir.md):改变目录
|
||||
- [Dockerfile 最佳实践](../../16_appendix/16.1_best_practices.md)
|
||||
- [CMD 容器启动命令](7.4_cmd.md):容器启动时的命令
|
||||
- [WORKDIR 指定工作目录](7.10_workdir.md):改变目录
|
||||
- [Dockerfile 最佳实践](../16_appendix/16.1_best_practices.md)
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
### 基本语法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
COPY [选项] <源路径>... <目标路径>
|
||||
COPY [选项] ["<源路径1>", "<源路径2>", ... "<目标路径>"]
|
||||
@@ -17,8 +15,6 @@ COPY [选项] ["<源路径1>", "<源路径2>", ... "<目标路径>"]
|
||||
|
||||
#### 复制单个文件
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 复制文件到指定目录
|
||||
|
||||
@@ -31,8 +27,6 @@ COPY config.json /app/settings.json
|
||||
|
||||
#### 复制多个文件
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 复制多个指定文件
|
||||
|
||||
@@ -46,8 +40,6 @@ COPY src/*.js /app/src/
|
||||
|
||||
#### 复制目录
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 复制整个目录的内容(不是目录本身)
|
||||
|
||||
@@ -86,9 +78,8 @@ COPY app[0-9].js /app/ # app0.js ~ app9.js
|
||||
|
||||
### 目标路径
|
||||
|
||||
#### 绝对路径
|
||||
|
||||
具体内容如下:
|
||||
#### 绝对路径
|
||||
|
||||
```docker
|
||||
COPY app.js /usr/src/app/
|
||||
@@ -96,8 +87,6 @@ COPY app.js /usr/src/app/
|
||||
|
||||
#### 相对路径(基于 WORKDIR)
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
WORKDIR /app
|
||||
COPY package.json ./ # 复制到 /app/package.json
|
||||
@@ -182,8 +171,6 @@ ADD app.tar.gz /app/
|
||||
|
||||
#### 从其他构建阶段复制
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 构建阶段
|
||||
|
||||
@@ -202,8 +189,6 @@ COPY --from=builder /app/dist /usr/share/nginx/html
|
||||
|
||||
#### 使用 --link 优化缓存(BuildKit)
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 使用 --link 后,文件以独立层添加,不依赖前序指令
|
||||
|
||||
@@ -243,8 +228,6 @@ Dockerfile
|
||||
|
||||
#### 1. 利用缓存,先复制依赖文件
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ✅ 好:先复制依赖定义,再安装,最后复制代码
|
||||
|
||||
@@ -260,22 +243,17 @@ RUN npm install
|
||||
|
||||
#### 2. 使用 .dockerignore
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 确保 node_modules 不被复制
|
||||
|
||||
COPY . .
|
||||
## .dockerignore 中应包含 node_modules
|
||||
|
||||
具体内容如下:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
#### 3. 明确复制路径
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ✅ 好:明确的路径
|
||||
|
||||
@@ -301,7 +279,7 @@ COPY . .
|
||||
|
||||
### 延伸阅读
|
||||
|
||||
- [ADD 指令](add.md):复制和解压
|
||||
- [WORKDIR 指令](workdir.md):设置工作目录
|
||||
- [多阶段构建](../multistage-builds.md):优化镜像大小
|
||||
- [最佳实践](../../16_appendix/16.1_best_practices.md):Dockerfile 编写指南
|
||||
- [ADD 指令](7.3_add.md):复制和解压
|
||||
- [WORKDIR 指令](7.10_workdir.md):设置工作目录
|
||||
- [多阶段构建](7.17_multistage_builds.md):优化镜像大小
|
||||
- [最佳实践](../16_appendix/16.1_best_practices.md):Dockerfile 编写指南
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
### 基本语法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ADD [选项] <源路径>... <目标路径>
|
||||
ADD [选项] ["<源路径>", ... "<目标路径>"]
|
||||
@@ -31,9 +29,7 @@ ADD [选项] ["<源路径>", ... "<目标路径>"]
|
||||
|
||||
### 自动解压功能
|
||||
|
||||
#### 基本用法
|
||||
|
||||
具体内容如下:
|
||||
#### 基本用法(自动解压本地 tar)
|
||||
|
||||
```docker
|
||||
## 自动解压 tar.gz 到目标目录
|
||||
@@ -58,8 +54,6 @@ ADD ubuntu-noble-core-cloudimg-amd64-root.tar.gz /
|
||||
|
||||
#### 解压过程
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```
|
||||
ADD app.tar.gz /app/
|
||||
│
|
||||
@@ -79,8 +73,6 @@ app.tar.gz 包含: /app/ 目录结果:
|
||||
|
||||
#### 基本用法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 从 URL 下载文件
|
||||
|
||||
@@ -98,8 +90,6 @@ ADD https://example.com/app.zip /app/app.zip
|
||||
|
||||
#### 推荐替代方案
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ❌ 不推荐:使用 ADD 下载
|
||||
|
||||
@@ -120,8 +110,6 @@ RUN curl -fsSL https://example.com/app.tar.gz | tar -xz -C /app
|
||||
|
||||
### 修改文件所有者
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ADD --chown=node:node app.tar.gz /app/
|
||||
ADD --chown=1000:1000 files/ /app/
|
||||
@@ -133,8 +121,6 @@ ADD --chown=1000:1000 files/ /app/
|
||||
|
||||
#### ✅ 适合使用 ADD
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 解压本地 tar 文件
|
||||
|
||||
@@ -148,8 +134,6 @@ ADD dist.tar.gz /app/
|
||||
|
||||
#### ❌ 不适合使用 ADD
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 复制普通文件(用 COPY)
|
||||
|
||||
@@ -199,8 +183,6 @@ ADD app.tar.gz /app/
|
||||
|
||||
#### 1. 默认使用 COPY
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ✅ 大多数场景使用 COPY
|
||||
|
||||
@@ -209,8 +191,6 @@ COPY . /app/
|
||||
|
||||
#### 2. 仅在需要解压时使用 ADD
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ✅ 自动解压场景
|
||||
|
||||
@@ -219,8 +199,6 @@ ADD app.tar.gz /app/
|
||||
|
||||
#### 3. 不要用 ADD 下载文件
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ❌ 避免
|
||||
|
||||
@@ -233,8 +211,6 @@ RUN curl -fsSL https://example.com/file.tar.gz | tar -xz -C /app
|
||||
|
||||
#### 4. 解压后清理
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 如果需要控制解压过程
|
||||
|
||||
@@ -257,6 +233,6 @@ RUN tar -xzf /tmp/app.tar.gz -C /app && \
|
||||
|
||||
### 延伸阅读
|
||||
|
||||
- [COPY 复制文件](copy.md):基本复制操作
|
||||
- [多阶段构建](../multistage-builds.md):减少镜像体积
|
||||
- [最佳实践](../../16_appendix/16.1_best_practices.md):Dockerfile 编写指南
|
||||
- [COPY 复制文件](7.2_copy.md):基本复制操作
|
||||
- [多阶段构建](7.17_multistage_builds.md):减少镜像体积
|
||||
- [最佳实践](../16_appendix/16.1_best_practices.md):Dockerfile 编写指南
|
||||
|
||||
@@ -20,8 +20,6 @@ CMD 有三种格式:
|
||||
|
||||
#### exec 格式(推荐)
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
CMD ["python", "app.py"]
|
||||
@@ -35,8 +33,6 @@ CMD ["node", "server.js"]
|
||||
|
||||
#### shell 格式
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
CMD echo "Hello World"
|
||||
CMD nginx -g "daemon off;"
|
||||
@@ -70,8 +66,6 @@ CMD ["sh", "-c", "echo $HOME"]
|
||||
|
||||
#### 信号传递问题示例
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ❌ shell 格式:docker stop 会超时
|
||||
|
||||
@@ -85,8 +79,7 @@ CMD node server.js
|
||||
CMD ["node", "server.js"]
|
||||
## SIGTERM 直接发给 node
|
||||
|
||||
具体内容如下:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
---
|
||||
@@ -117,8 +110,6 @@ CMD ["/bin/bash"] + cat /etc/os-release
|
||||
|
||||
#### 错误示例
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ❌ 容器启动后立即退出
|
||||
|
||||
@@ -127,8 +118,6 @@ CMD service nginx start
|
||||
|
||||
#### 原因分析
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```
|
||||
1. CMD service nginx start
|
||||
↓ 被转换为
|
||||
@@ -145,8 +134,6 @@ CMD service nginx start
|
||||
|
||||
#### 正确做法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ✅ 让 nginx 在前台运行
|
||||
|
||||
@@ -164,8 +151,6 @@ CMD ["nginx", "-g", "daemon off;"]
|
||||
|
||||
#### 单独使用 CMD
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## Dockerfile
|
||||
|
||||
@@ -179,8 +164,6 @@ $ docker run myimage curl -v ... # 完全覆盖
|
||||
|
||||
#### 搭配 ENTRYPOINT
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## Dockerfile
|
||||
|
||||
@@ -193,7 +176,7 @@ $ docker run myimage # curl -s http://example.com
|
||||
$ docker run myimage http://other.com # curl -s http://other.com(参数覆盖)
|
||||
```
|
||||
|
||||
详见 [ENTRYPOINT 入口点](entrypoint.md) 章节。
|
||||
详见 [ENTRYPOINT 入口点](7.5_entrypoint.md) 章节。
|
||||
|
||||
---
|
||||
|
||||
@@ -201,8 +184,6 @@ $ docker run myimage http://other.com # curl -s http://other.com(参数覆盖
|
||||
|
||||
#### 1. 优先使用 exec 格式
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ✅ 推荐
|
||||
|
||||
@@ -215,8 +196,6 @@ CMD ["sh", "-c", "echo $PATH && python app.py"]
|
||||
|
||||
#### 2. 确保应用在前台运行
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ✅ 前台运行
|
||||
|
||||
@@ -232,8 +211,6 @@ CMD systemctl start nginx
|
||||
|
||||
#### 3. 使用双引号
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ✅ 正确:双引号
|
||||
|
||||
@@ -246,8 +223,6 @@ CMD ['node', 'server.js']
|
||||
|
||||
#### 4. 配合 ENTRYPOINT 使用
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 用于可配置参数的场景
|
||||
|
||||
@@ -257,6 +232,8 @@ CMD ["--port", "8080"]
|
||||
## 运行时可以覆盖端口
|
||||
|
||||
$ docker run myapp --port 9000
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
---
|
||||
@@ -274,8 +251,6 @@ CMD ["echo", "second"] # 只有这个生效
|
||||
|
||||
#### Q: 如何在 CMD 中使用环境变量?
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 方法1:使用 shell 格式
|
||||
|
||||
@@ -314,6 +289,6 @@ CMD ["python", "app.py"]
|
||||
|
||||
### 延伸阅读
|
||||
|
||||
- [ENTRYPOINT 入口点](entrypoint.md):固定的启动命令
|
||||
- [后台运行](../../05_container/5.2_daemon.md):容器前台/后台概念
|
||||
- [最佳实践](../../16_appendix/16.1_best_practices.md):Dockerfile 编写指南
|
||||
- [ENTRYPOINT 入口点](7.5_entrypoint.md):固定的启动命令
|
||||
- [后台运行](../05_container/5.2_daemon.md):容器前台/后台概念
|
||||
- [最佳实践](../16_appendix/16.1_best_practices.md):Dockerfile 编写指南
|
||||
|
||||
@@ -40,8 +40,6 @@ ENTRYPOINT nginx -g "daemon off;"
|
||||
|
||||
#### 行为对比
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 只用 CMD
|
||||
|
||||
@@ -82,14 +80,12 @@ $ docker run myimage -v http://other.com # curl -s -v http://other.com ✓
|
||||
|
||||
### 场景一:让镜像像命令一样使用
|
||||
|
||||
#### 需求
|
||||
#### 需求(启动前准备)
|
||||
|
||||
创建一个查询公网 IP 的"命令"镜像。
|
||||
|
||||
#### 使用 CMD 的问题
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
FROM ubuntu:24.04
|
||||
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
|
||||
@@ -104,14 +100,11 @@ $ docker run myip -i # ✗ 错误!
|
||||
exec: "-i": executable file not found
|
||||
## -i 替换了整个 CMD,被当作可执行文件
|
||||
|
||||
具体内容如下:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
#### 使用 ENTRYPOINT 解决
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
FROM ubuntu:24.04
|
||||
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
|
||||
@@ -130,8 +123,6 @@ HTTP/1.1 200 OK
|
||||
|
||||
#### 交互图示
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```
|
||||
ENTRYPOINT ["curl", "-s", "http://myip.ipip.net"]
|
||||
│
|
||||
@@ -153,8 +144,6 @@ curl -s http://myip.ipip.net -i
|
||||
|
||||
#### 实现方式
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
FROM redis:7-alpine
|
||||
COPY docker-entrypoint.sh /usr/local/bin/
|
||||
@@ -186,8 +175,6 @@ exec "$@"
|
||||
|
||||
#### 工作流程
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```
|
||||
docker run redis docker run redis bash
|
||||
│ │
|
||||
@@ -210,8 +197,6 @@ docker-entrypoint.sh redis-server docker-entrypoint.sh bash
|
||||
|
||||
### 场景三:带参数的应用
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
FROM python:3.12-slim
|
||||
WORKDIR /app
|
||||
@@ -238,8 +223,7 @@ $ docker run myapp --host 0.0.0.0 --port 9000
|
||||
$ docker run myapp --help
|
||||
## 执行: python app.py --help
|
||||
|
||||
具体内容如下:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
---
|
||||
@@ -282,8 +266,6 @@ $ docker run --entrypoint /bin/cat myimage /etc/os-release
|
||||
|
||||
#### 1. 使用 exec 格式
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ✅ 推荐
|
||||
|
||||
@@ -296,8 +278,6 @@ ENTRYPOINT python app.py
|
||||
|
||||
#### 2. 提供有意义的默认参数
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ENTRYPOINT ["nginx"]
|
||||
CMD ["-g", "daemon off;"]
|
||||
@@ -346,6 +326,6 @@ wait $PID
|
||||
|
||||
### 延伸阅读
|
||||
|
||||
- [CMD 容器启动命令](cmd.md):默认命令
|
||||
- [最佳实践](../../16_appendix/16.1_best_practices.md):启动命令设计
|
||||
- [后台运行](../../05_container/5.2_daemon.md):前台/后台概念
|
||||
- [CMD 容器启动命令](7.4_cmd.md):默认命令
|
||||
- [最佳实践](../16_appendix/16.1_best_practices.md):启动命令设计
|
||||
- [后台运行](../05_container/5.2_daemon.md):前台/后台概念
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
### 基本语法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 格式一:单个变量
|
||||
|
||||
@@ -20,8 +18,6 @@ ENV <key1>=<value1> <key2>=<value2> ...
|
||||
|
||||
#### 设置单个变量
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ENV NODE_VERSION 20.10.0
|
||||
ENV APP_ENV production
|
||||
@@ -29,8 +25,6 @@ ENV APP_ENV production
|
||||
|
||||
#### 设置多个变量
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ENV NODE_VERSION=20.10.0 \
|
||||
APP_ENV=production \
|
||||
@@ -45,8 +39,6 @@ ENV NODE_VERSION=20.10.0 \
|
||||
|
||||
#### 1. 后续指令中使用
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ENV NODE_VERSION=20.10.0
|
||||
|
||||
@@ -67,8 +59,6 @@ COPY . $APP_HOME
|
||||
|
||||
#### 2. 容器运行时使用
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ENV DATABASE_URL=postgres://localhost/mydb
|
||||
```
|
||||
@@ -149,8 +139,6 @@ DATABASE_URL=postgres://localhost/mydb
|
||||
|
||||
#### 组合使用
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ARG 接收构建时参数
|
||||
|
||||
@@ -177,8 +165,6 @@ $ docker build --build-arg NODE_VERSION=18 -t myapp .
|
||||
|
||||
#### 1. 统一管理版本号
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ✅ 好:版本集中管理
|
||||
|
||||
@@ -195,8 +181,6 @@ RUN apt-get install nginx=1.25.0
|
||||
|
||||
#### 2. 不要存储敏感信息
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ❌ 错误:密码写入镜像
|
||||
|
||||
@@ -206,14 +190,11 @@ ENV DB_PASSWORD=secret123
|
||||
|
||||
## docker run -e DB_PASSWORD=xxx myimage
|
||||
|
||||
具体内容如下:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
#### 3. 为应用提供合理默认值
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ENV APP_ENV=production \
|
||||
APP_PORT=8080 \
|
||||
@@ -222,8 +203,6 @@ ENV APP_ENV=production \
|
||||
|
||||
#### 4. 使用有意义的变量名
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ✅ 好:清晰的命名
|
||||
|
||||
@@ -265,8 +244,6 @@ $ docker exec mycontainer env
|
||||
|
||||
#### Q: 多行 ENV 还是多个 ENV
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ✅ 推荐:减少层数
|
||||
|
||||
@@ -295,6 +272,6 @@ ENV VAR3=value3
|
||||
|
||||
### 延伸阅读
|
||||
|
||||
- [ARG 构建参数](arg.md):构建时变量
|
||||
- [Compose 环境变量](../../compose/10.5_compose_file.md):Compose 中的环境变量
|
||||
- [最佳实践](../../16_appendix/16.1_best_practices.md):Dockerfile 编写指南
|
||||
- [ARG 构建参数](7.7_arg.md):构建时变量
|
||||
- [Compose 环境变量](../10_compose/10.5_compose_file.md):Compose 中的环境变量
|
||||
- [最佳实践](../16_appendix/16.1_best_practices.md):Dockerfile 编写指南
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
### 基本语法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ARG <参数名>[=<默认值>]
|
||||
```
|
||||
@@ -37,8 +35,6 @@ ARG <参数名>[=<默认值>]
|
||||
|
||||
#### 定义和使用
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 定义有默认值的 ARG
|
||||
|
||||
@@ -70,8 +66,6 @@ $ docker build --build-arg NODE_VERSION=18 -t myapp .
|
||||
|
||||
#### FROM 之前的 ARG
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## FROM 之前的 ARG 只能用于 FROM 指令
|
||||
|
||||
@@ -87,8 +81,6 @@ RUN echo $REGISTRY # 输出空
|
||||
|
||||
#### FROM 之后重新声明
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ARG NODE_VERSION=20
|
||||
|
||||
@@ -102,8 +94,6 @@ RUN echo "Node version: $NODE_VERSION"
|
||||
|
||||
#### 多阶段构建中的 ARG
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ARG BASE_VERSION=alpine
|
||||
|
||||
@@ -126,8 +116,6 @@ RUN echo "Running with Node $NODE_VERSION"
|
||||
|
||||
#### 1. 控制基础镜像版本
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ARG ALPINE_VERSION=3.19
|
||||
FROM alpine:${ALPINE_VERSION}
|
||||
@@ -139,8 +127,6 @@ $ docker build --build-arg ALPINE_VERSION=3.18 .
|
||||
|
||||
#### 2. 设置软件版本
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ARG NGINX_VERSION=1.25.0
|
||||
|
||||
@@ -149,8 +135,6 @@ RUN curl -fsSL https://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz | tar -x
|
||||
|
||||
#### 3. 配置构建环境
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ARG BUILD_ENV=production
|
||||
ARG ENABLE_DEBUG=false
|
||||
@@ -164,8 +148,6 @@ RUN if [ "$ENABLE_DEBUG" = "true" ]; then \
|
||||
|
||||
#### 4. 配置私有仓库
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ARG NPM_TOKEN
|
||||
|
||||
@@ -223,8 +205,6 @@ $ docker build --build-arg HTTP_PROXY=http://proxy:8080 .
|
||||
|
||||
#### 1. 为 ARG 提供合理默认值
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ✅ 好:有默认值
|
||||
|
||||
@@ -237,8 +217,6 @@ ARG NODE_VERSION
|
||||
|
||||
#### 2. 不要用 ARG 存储敏感信息
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ❌ 错误:密码会被记录在镜像历史中
|
||||
|
||||
@@ -247,14 +225,11 @@ RUN echo "password=$DB_PASSWORD" > /app/.env
|
||||
|
||||
## ✅ 正确:使用 secrets 或运行时环境变量
|
||||
|
||||
具体内容如下:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
#### 3. 使用 ARG 提高构建灵活性
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ARG BASE_IMAGE=python:3.12-slim
|
||||
FROM ${BASE_IMAGE}
|
||||
@@ -263,8 +238,7 @@ FROM ${BASE_IMAGE}
|
||||
|
||||
## docker build --build-arg BASE_IMAGE=python:3.11-alpine .
|
||||
|
||||
具体内容如下:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
---
|
||||
@@ -282,6 +256,6 @@ FROM ${BASE_IMAGE}
|
||||
|
||||
### 延伸阅读
|
||||
|
||||
- [ENV 设置环境变量](env.md):运行时环境变量
|
||||
- [FROM 指令](../../04_image/4.5_build.md):基础镜像指定
|
||||
- [多阶段构建](../multistage-builds.md):复杂构建场景
|
||||
- [ENV 设置环境变量](7.6_env.md):运行时环境变量
|
||||
- [FROM 指令](../04_image/4.5_build.md):基础镜像指定
|
||||
- [多阶段构建](7.17_multistage_builds.md):复杂构建场景
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
### 基本语法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
VOLUME ["/路径1", "/路径2"]
|
||||
VOLUME /路径
|
||||
@@ -40,8 +38,6 @@ VOLUME /路径
|
||||
|
||||
#### 定义单个卷
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
FROM mysql:8.0
|
||||
VOLUME /var/lib/mysql
|
||||
@@ -49,8 +45,6 @@ VOLUME /var/lib/mysql
|
||||
|
||||
#### 定义多个卷
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
FROM myapp
|
||||
VOLUME ["/data", "/logs", "/config"]
|
||||
@@ -110,8 +104,6 @@ RUN echo "hello" > /data/test.txt
|
||||
|
||||
#### 正确做法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
FROM ubuntu
|
||||
|
||||
@@ -130,8 +122,6 @@ VOLUME /data
|
||||
|
||||
#### 数据库持久化
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
FROM postgres:15
|
||||
VOLUME /var/lib/postgresql/data
|
||||
@@ -139,8 +129,6 @@ VOLUME /var/lib/postgresql/data
|
||||
|
||||
#### 日志目录
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
FROM nginx
|
||||
VOLUME /var/log/nginx
|
||||
@@ -148,8 +136,6 @@ VOLUME /var/log/nginx
|
||||
|
||||
#### 上传文件目录
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
FROM myapp
|
||||
VOLUME /app/uploads
|
||||
@@ -219,8 +205,7 @@ volumes:
|
||||
$ docker run --rm mysql:8.0
|
||||
## 容器停止后,数据丢失!
|
||||
|
||||
具体内容如下:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
**解决**:始终使用命名卷
|
||||
@@ -235,8 +220,6 @@ $ docker run -v mysql_data:/var/lib/mysql mysql:8.0
|
||||
|
||||
#### 1. 定义必须持久化的路径
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 数据库必须使用卷
|
||||
|
||||
@@ -246,8 +229,6 @@ VOLUME /var/lib/postgresql/data
|
||||
|
||||
#### 2. 不要在 VOLUME 后修改目录
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ❌ 避免
|
||||
|
||||
@@ -262,8 +243,6 @@ VOLUME /app/data
|
||||
|
||||
#### 3. 文档中说明 VOLUME 用途
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 持久化用户上传的文件
|
||||
|
||||
@@ -288,6 +267,6 @@ VOLUME /var/lib/mysql
|
||||
|
||||
### 延伸阅读
|
||||
|
||||
- [数据卷](../../08_data_network/data/volume.md):卷的管理和使用
|
||||
- [挂载主机目录](../../08_data_network/data/bind-mounts.md):Bind Mount
|
||||
- [Compose 数据管理](../../compose/10.5_compose_file.md):Compose 中的卷配置
|
||||
- [数据卷](../08_data_network/data/volume.md):卷的管理和使用
|
||||
- [挂载主机目录](../08_data_network/data/bind-mounts.md):Bind Mount
|
||||
- [Compose 数据管理](../10_compose/10.5_compose_file.md):Compose 中的卷配置
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
### 基本语法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
EXPOSE <端口> [<端口>/<协议>...]
|
||||
```
|
||||
@@ -14,8 +12,6 @@ EXPOSE <端口> [<端口>/<协议>...]
|
||||
|
||||
### 基本用法
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 声明单个端口
|
||||
|
||||
@@ -97,16 +93,13 @@ $ docker port $(docker ps -q)
|
||||
|
||||
#### 没有 EXPOSE 也能 -p
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 即使没有 EXPOSE,也可以使用 -p
|
||||
|
||||
FROM nginx
|
||||
## 没有 EXPOSE
|
||||
|
||||
具体内容如下:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
```bash
|
||||
@@ -121,8 +114,6 @@ $ docker run -p 8080:80 mynginx
|
||||
|
||||
#### 误解:EXPOSE 会打开端口
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ❌ 错误理解:这不会让容器可从外部访问
|
||||
|
||||
@@ -138,8 +129,6 @@ EXPOSE 只是元数据声明。容器是否实际监听该端口,取决于容
|
||||
|
||||
#### 正确理解
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## Dockerfile
|
||||
|
||||
@@ -159,8 +148,6 @@ $ docker run -p 8080:80 nginx # 2. 映射:宿主机 8080 → 容器 80
|
||||
|
||||
#### 1. 总是声明应用使用的端口
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## Web 服务
|
||||
|
||||
@@ -180,8 +167,6 @@ EXPOSE 6379
|
||||
|
||||
#### 2. 使用明确的协议
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## 默认是 TCP
|
||||
|
||||
@@ -198,8 +183,6 @@ EXPOSE 53/tcp 53/udp
|
||||
|
||||
#### 3. 与应用实际端口保持一致
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ✅ 好:EXPOSE 与应用端口一致
|
||||
|
||||
@@ -217,8 +200,6 @@ CMD ["node", "server.js"] # 实际监听 3000
|
||||
|
||||
### 使用环境变量
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
ARG PORT=80
|
||||
EXPOSE $PORT
|
||||
@@ -256,6 +237,6 @@ services:
|
||||
|
||||
### 延伸阅读
|
||||
|
||||
- [网络配置](../../network/README.md):Docker 网络详解
|
||||
- [端口映射](../../network/port_bindingbindingbinding.md):-p 参数详解
|
||||
- [Compose 端口](../../compose/10.5_compose_file.md):Compose 中的端口配置
|
||||
- [网络配置](../08_data_network/network/README.md):Docker 网络详解
|
||||
- [端口映射](../08_data_network/network/port_mapping.md):-p 参数详解
|
||||
- [Compose 端口](../10_compose/10.5_compose_file.md):Compose 中的端口配置
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
Dockerfile 是一个文本文件,其內包含了一条条的 **指令(Instruction)**,每一条指令构建一层,therefore 每一条指令的内容,就是描述该层应当如何构建。
|
||||
|
||||
在 [第四章](04_image/README.md) 中,我们通过 `docker commit` 学习了镜像的构成。但是,手动 `commit` 只能作为临时修补,并不适合作为生产环境镜像的构建方式。
|
||||
在 [第四章](../04_image/README.md) 中,我们通过 `docker commit` 学习了镜像的构成。但是,手动 `commit` 只能作为临时修补,并不适合作为生产环境镜像的构建方式。
|
||||
|
||||
使用 Dockerfile 构建镜像有以下优势:
|
||||
|
||||
@@ -35,7 +35,7 @@ Dockerfile 一般分为四部分:基础镜像信息、维护者信息、镜像
|
||||
* [ONBUILD 为他人作嫁衣裳](7.13_onbuild.md)
|
||||
* [LABEL 为镜像添加元数据](7.14_label.md)
|
||||
* [SHELL 指令](7.15_shell.md)
|
||||
* [RUN 执行命令](5.1_run.md)
|
||||
* [RUN 执行命令](7.1_run.md)
|
||||
|
||||
此外,我们还将介绍 Dockerfile 的最佳实践和常见问题。
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
数据管理 示意图如下:
|
||||
|
||||

|
||||

|
||||
|
||||
这一章介绍如何在 Docker 内部以及容器之间管理数据,在容器中管理数据主要有两种方式:
|
||||
|
||||
|
||||
@@ -29,8 +29,6 @@ Bind Mount(绑定挂载)将**宿主机的目录或文件**直接挂载到容
|
||||
|
||||
#### 选择建议
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```
|
||||
需求 推荐方案
|
||||
─────────────────────────────────────────
|
||||
@@ -95,8 +93,7 @@ $ docker run -d \
|
||||
$ echo "Hello" > src/index.html
|
||||
## 浏览器刷新即可看到变化
|
||||
|
||||
具体内容如下:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
#### 场景二:配置文件挂载
|
||||
@@ -329,4 +326,4 @@ $ docker run -v /app/data:/data ...
|
||||
|
||||
- [数据卷](volume.md):Docker 管理的持久化存储
|
||||
- [tmpfs 挂载](tmpfs.md):内存临时存储
|
||||
- [Compose 数据管理](../compose/10.5_compose_file.md):Compose 中的挂载配置
|
||||
- [Compose 数据管理](../../10_compose/10.5_compose_file.md):Compose 中的挂载配置
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
## tmpfs 挂载
|
||||
|
||||
`tmpfs` 挂载会把数据放在宿主机内存中,而不是写入容器可写层或数据卷。
|
||||
|
||||
### 适用场景
|
||||
|
||||
- 临时缓存
|
||||
- 会话数据
|
||||
- 不希望落盘的敏感中间文件
|
||||
|
||||
### 基本用法
|
||||
|
||||
```bash
|
||||
$ docker run --tmpfs /run:rw,noexec,nosuid,size=64m nginx
|
||||
```
|
||||
|
||||
也可以使用 `--mount` 语法:
|
||||
|
||||
```bash
|
||||
$ docker run --mount type=tmpfs,destination=/run,tmpfs-size=67108864 nginx
|
||||
```
|
||||
|
||||
### 注意事项
|
||||
|
||||
- 容器停止后,`tmpfs` 数据会丢失。
|
||||
- `tmpfs` 占用宿主机内存,建议显式限制大小。
|
||||
- 不适合需要持久化的数据。
|
||||
|
||||
### 与 Volume / Bind Mount 对比
|
||||
|
||||
| 类型 | 数据位置 | 持久化 | 典型用途 |
|
||||
|------|---------|-------|---------|
|
||||
| Volume | Docker 管理目录 | 是 | 数据库、长期业务数据 |
|
||||
| Bind Mount | 宿主机指定目录 | 是 | 开发联调、配置文件共享 |
|
||||
| tmpfs | 内存 | 否 | 高速临时数据、敏感临时文件 |
|
||||
@@ -31,8 +31,6 @@ flowchart LR
|
||||
|
||||
#### 容器存储层(不推荐存储重要数据)
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
subgraph Container [容器]
|
||||
@@ -47,8 +45,6 @@ graph TD
|
||||
|
||||
#### 数据卷(推荐)
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
subgraph Container [容器]
|
||||
@@ -417,4 +413,4 @@ $ docker volume inspect my-vol
|
||||
|
||||
- [绑定挂载](bind-mounts.md):挂载宿主机目录
|
||||
- [tmpfs 挂载](tmpfs.md):内存中的临时存储
|
||||
- [存储驱动](../14_implementation/14.4_ufs.md):Docker 存储的底层原理
|
||||
- [存储驱动](../../14_implementation/14.4_ufs.md):Docker 存储的底层原理
|
||||
|
||||
@@ -47,8 +47,6 @@ graph TD
|
||||
|
||||
### 数据流向
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```
|
||||
容器 A (172.17.0.2) → docker0 → 容器 B (172.17.0.3) (容器间通信)
|
||||
容器 A (172.17.0.2) → docker0 → eth0 → 互联网 (访问外网)
|
||||
@@ -159,8 +157,7 @@ $ docker run -d --name app --network app-net myapp
|
||||
|
||||
## app 容器中可以用 redis:6379 连接 Redis
|
||||
|
||||
具体内容如下:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
### 连接到多个网络
|
||||
@@ -234,8 +231,6 @@ $ docker port mycontainer
|
||||
|
||||
### 端口映射示意图
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```
|
||||
外部请求 http://宿主机IP:8080
|
||||
│
|
||||
@@ -329,4 +324,4 @@ $ docker network prune
|
||||
|
||||
- [配置 DNS](dns.md):自定义 DNS 设置
|
||||
- [端口映射](port_mapping.md):高级端口配置
|
||||
- [Compose 网络](../compose/10.5_compose_file.md):Compose 中的网络配置
|
||||
- [Compose 网络](../../10_compose/10.5_compose_file.md):Compose 中的网络配置
|
||||
|
||||
@@ -164,5 +164,5 @@ iptables -t nat -A DOCKER -p tcp --dport 8080 -j DNAT --to-destination 172.17.0.
|
||||
|
||||
### 延伸阅读
|
||||
|
||||
- [EXPOSE 指令](../07_dockerfile/7.9_expose.md):在 Dockerfile 中声明端口
|
||||
- [EXPOSE 指令](../../07_dockerfile/7.9_expose.md):在 Dockerfile 中声明端口
|
||||
- [网络模式](README.md):Host 模式不需要端口映射
|
||||
|
||||
@@ -19,7 +19,7 @@ Buildx 使用 [BuildKit 引擎](9.1_buildkit.md) 进行构建,支持许多新
|
||||
`docker buildx bake` 是一个高级构建命令,支持从 HCL、JSON 或 Compose 文件中定义构建目标,实现复杂的流水线构建。
|
||||
|
||||
```bash
|
||||
## 从 docker-compose.yml 构建所有服务
|
||||
## 从 Compose 文件构建所有服务
|
||||
|
||||
$ docker buildx bake
|
||||
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
Docker Buildx 是一个 docker CLI 插件,其扩展了 docker 命令,支持 [Moby BuildKit](9.1_buildkit.md) 提供的功能。提供了与 docker build 相同的用户体验,并增加了许多新功能。
|
||||
|
||||
> 该功能仅适用于 Docker v19.03+ 版本
|
||||
> Buildx 需要 Docker v19.03+。在较新版本中已更常用且功能更完整。
|
||||
|
||||
## 本章内容
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
通过第一部分中的介绍,我们知道使用一个 `Dockerfile` 模板文件,可以让用户很方便的定义一个单独的应用容器。然而,在日常工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。例如要实现一个 Web 项目,除了 Web 服务容器本身,往往还需要再加上后端的数据库服务容器,甚至还包括负载均衡容器等。
|
||||
|
||||
`Compose` 恰好满足了这样的需求。它允许用户通过一个单独的 `docker-compose.yml` 模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。
|
||||
`Compose` 恰好满足了这样的需求。它允许用户通过一个单独的 `compose.yaml`(历史默认名也常见为 `docker-compose.yml`)模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。
|
||||
|
||||
### 模板文件规范
|
||||
|
||||
@@ -16,13 +16,13 @@ Compose 模板文件采用 YAML 格式,扩展名为 `.yml` 或 `.yaml`。
|
||||
|
||||
> **注意**:自 Compose V2 起,`version` 字段已不再强制要求。在 Docker Compose v5 中,规范已完全不需要顶层 `version` 字段。为了保持最佳兼容性,建议不在新文件中使用该字段。
|
||||
|
||||
Docker Compose 默认使用 `docker-compose.yml` 作为模板文件。
|
||||
Docker Compose 默认使用 `compose.yaml`,也兼容 `compose.yml`、`docker-compose.yaml`、`docker-compose.yml` 等文件名。
|
||||
|
||||
`Compose` 中有两个重要的概念:
|
||||
|
||||
* 服务 (`service`):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。
|
||||
|
||||
* 项目 (`project`):由一组关联的应用容器组成的一个完整业务单元,在 `docker-compose.yml` 文件中定义。
|
||||
* 项目 (`project`):由一组关联的应用容器组成的一个完整业务单元,在 Compose 文件中定义。
|
||||
|
||||
`Compose` 的默认管理对象是项目,通过子命令对项目中的一组容器进行便捷地生命周期管理。
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ Linux 系统请使用以下介绍的方法安装。
|
||||
|
||||
### Linux
|
||||
|
||||
在 Linux 上,你可以通过下载 `docker-compose` 二进制包来安装。
|
||||
在 Linux 上,你可以通过下载 Docker Compose CLI 插件(二进制文件名为 `docker-compose`)来安装。
|
||||
|
||||
从 [官方 GitHub Release](https://github.com/docker/compose/releases) 处直接下载编译好的二进制文件即可。
|
||||
|
||||
|
||||
@@ -50,14 +50,12 @@ RUN pip install redis flask
|
||||
CMD ["python", "app.py"]
|
||||
```
|
||||
|
||||
#### docker-compose.yml
|
||||
#### compose.yaml
|
||||
|
||||
编写 `docker-compose.yml` 文件,这个是 Compose 使用的主模板文件。
|
||||
编写 `compose.yaml` 文件,这是 Compose 推荐使用的主模板文件(也兼容 `docker-compose.yml` 等历史文件名)。
|
||||
|
||||
```yaml
|
||||
|
||||
services:
|
||||
|
||||
web:
|
||||
build: .
|
||||
ports:
|
||||
@@ -139,7 +137,7 @@ $ docker compose start
|
||||
$ docker compose run web python app.py
|
||||
```
|
||||
|
||||
#### 验证 `docker-compose.yml`
|
||||
#### 验证 Compose 文件
|
||||
|
||||
运行以下命令:
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ docker compose [-f=<arg>...] [options] [COMMAND] [ARGS...]
|
||||
|
||||
### 命令选项
|
||||
|
||||
* `-f, --file FILE` 指定使用的 Compose 模板文件,默认为 `docker-compose.yml`,可以多次指定。
|
||||
* `-f, --file FILE` 指定使用的 Compose 模板文件。默认会自动识别 `compose.yaml`(也兼容 `docker-compose.yml` 等),并且可以多次指定。
|
||||
|
||||
* `-p, --project-name NAME` 指定项目名称,默认将使用所在目录名称作为项目名。
|
||||
|
||||
@@ -264,7 +264,7 @@ $ docker compose scale web=3 db=2
|
||||
|
||||
如果使用 `docker compose up -d`,将会在后台启动并运行所有的容器。一般推荐生产环境下使用该选项。
|
||||
|
||||
默认情况,如果服务容器已经存在,`docker compose up` 将会尝试停止容器,然后重新创建(保持使用 `volumes-from` 挂载的卷),以保证新启动的服务匹配 `docker-compose.yml` 文件的最新内容。如果用户不希望容器被停止并重新创建,可以使用 `docker compose up --no-recreate`。这样将只会启动处于停止状态的容器,而忽略已经运行的服务。如果用户只想重新部署某个服务,可以使用 `docker compose up --no-deps -d <SERVICE_NAME>` 来重新创建服务并后台停止旧服务,启动新服务,并不会影响到其所依赖的服务。
|
||||
默认情况,如果服务容器已经存在,`docker compose up` 将会尝试停止容器,然后重新创建(保持使用 `volumes-from` 挂载的卷),以保证新启动的服务匹配 Compose 文件的最新内容。如果用户不希望容器被停止并重新创建,可以使用 `docker compose up --no-recreate`。这样将只会启动处于停止状态的容器,而忽略已经运行的服务。如果用户只想重新部署某个服务,可以使用 `docker compose up --no-deps -d <SERVICE_NAME>` 来重新创建服务并后台停止旧服务,启动新服务,并不会影响到其所依赖的服务。
|
||||
|
||||
选项:
|
||||
|
||||
|
||||
@@ -2,11 +2,9 @@
|
||||
|
||||
模板文件是使用 `Compose` 的核心,涉及到的指令关键字也比较多。但大家不用担心,这里面大部分指令跟 `docker run` 相关参数的含义都是类似的。
|
||||
|
||||
默认的模板文件名称为 `docker-compose.yml`,格式为 YAML 格式。
|
||||
默认的模板文件名称为 `compose.yaml`(也兼容 `docker-compose.yml` 等历史文件名),格式为 YAML。
|
||||
|
||||
```yaml
|
||||
|
||||
|
||||
services:
|
||||
webapp:
|
||||
image: examples/web
|
||||
@@ -18,18 +16,16 @@ services:
|
||||
|
||||
注意每个服务都必须通过 `image` 指令指定镜像或 `build` 指令(需要 Dockerfile)等来自动构建生成镜像。
|
||||
|
||||
如果使用 `build` 指令,在 `Dockerfile` 中设置的选项(例如:`CMD`, `EXPOSE`, `VOLUME`, `ENV` 等) 将会自动被获取,无需在 `docker-compose.yml` 中重复设置。
|
||||
如果使用 `build` 指令,在 `Dockerfile` 中设置的选项(例如:`CMD`、`EXPOSE`、`VOLUME`、`ENV` 等)将会自动被获取,无需在 Compose 文件中重复设置。
|
||||
|
||||
下面分别介绍各个指令的用法。
|
||||
|
||||
### `build`
|
||||
|
||||
指定 `Dockerfile` 所在文件夹的路径(可以是绝对路径,或者相对 docker-compose.yml 文件的路径)。 `Compose` 将会利用它自动构建这个镜像,然后使用这个镜像。
|
||||
指定 `Dockerfile` 所在文件夹的路径(可以是绝对路径,或者相对 Compose 文件的路径)。`Compose` 将会利用它自动构建这个镜像,然后使用这个镜像。
|
||||
|
||||
```yaml
|
||||
|
||||
services:
|
||||
|
||||
webapp:
|
||||
build: ./dir
|
||||
```
|
||||
@@ -41,9 +37,7 @@ services:
|
||||
使用 `arg` 指令指定构建镜像时的变量。
|
||||
|
||||
```yaml
|
||||
|
||||
services:
|
||||
|
||||
webapp:
|
||||
build:
|
||||
context: ./dir
|
||||
@@ -130,8 +124,6 @@ devices:
|
||||
解决容器的依赖、启动先后的问题。以下例子中会先启动 `redis` `db` 再启动 `web`
|
||||
|
||||
```yaml
|
||||
|
||||
|
||||
services:
|
||||
web:
|
||||
build: .
|
||||
@@ -187,7 +179,7 @@ tmpfs:
|
||||
|
||||
从文件中获取环境变量,可以为单独的文件路径或列表。
|
||||
|
||||
如果通过 `docker-compose -f FILE` 方式来指定 Compose 模板文件,则 `env_file` 中变量的路径会基于模板文件路径。
|
||||
如果通过 `docker compose -f FILE` 方式来指定 Compose 模板文件,则 `env_file` 中变量的路径会基于模板文件路径。
|
||||
|
||||
如果有变量名称与 `environment` 指令冲突,则按照惯例,以后者为准。
|
||||
|
||||
@@ -246,7 +238,7 @@ expose:
|
||||
|
||||
>注意:不建议使用该指令。
|
||||
|
||||
链接到 `docker-compose.yml` 外部的容器,甚至并非 `Compose` 管理的外部容器。
|
||||
链接到 Compose 文件外部的容器,甚至并非 `Compose` 管理的外部容器。
|
||||
|
||||
```yaml
|
||||
external_links:
|
||||
@@ -475,8 +467,6 @@ volumes:
|
||||
如果路径为数据卷名称,必须在文件中配置数据卷。
|
||||
|
||||
```yaml
|
||||
|
||||
|
||||
services:
|
||||
my_src:
|
||||
image: mysql:8.0
|
||||
@@ -561,9 +551,9 @@ db:
|
||||
image: "mongo:${MONGO_VERSION}"
|
||||
```
|
||||
|
||||
如果执行 `MONGO_VERSION=3.2 docker-compose up` 则会启动一个 `mongo:3.2` 镜像的容器;如果执行 `MONGO_VERSION=2.8 docker-compose up` 则会启动一个 `mongo:2.8` 镜像的容器。
|
||||
如果执行 `MONGO_VERSION=3.2 docker compose up` 则会启动一个 `mongo:3.2` 镜像的容器;如果执行 `MONGO_VERSION=2.8 docker compose up` 则会启动一个 `mongo:2.8` 镜像的容器。
|
||||
|
||||
若当前目录存在 `.env` 文件,执行 `docker-compose` 命令时将从该文件中读取变量。
|
||||
若当前目录存在 `.env` 文件,执行 `docker compose` 命令时将从该文件中读取变量。
|
||||
|
||||
在当前目录新建 `.env` 文件并写入以下内容。
|
||||
|
||||
@@ -573,7 +563,7 @@ db:
|
||||
MONGO_VERSION=3.6
|
||||
```
|
||||
|
||||
执行 `docker-compose up` 则会启动一个 `mongo:3.6` 镜像的容器。
|
||||
执行 `docker compose up` 则会启动一个 `mongo:3.6` 镜像的容器。
|
||||
|
||||
### 参考资料
|
||||
|
||||
|
||||
@@ -42,12 +42,10 @@
|
||||
$ mkdir django-docker && cd django-docker
|
||||
```
|
||||
|
||||
我们需要创建三个文件:`Dockerfile`、`requirements.txt` 和 `docker-compose.yml`。
|
||||
我们需要创建三个文件:`Dockerfile`、`requirements.txt` 和 `compose.yaml`。
|
||||
|
||||
### Step 1: 创建 Dockerfile
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
FROM python:3.12-slim
|
||||
|
||||
@@ -86,8 +84,6 @@ COPY . /code/
|
||||
|
||||
### Step 2: 创建 requirements.txt
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```txt
|
||||
Django>=5.0,<6.0
|
||||
psycopg[binary]>=3.1,<4.0
|
||||
@@ -102,9 +98,9 @@ gunicorn>=21.0,<22.0
|
||||
| `psycopg[binary]` | PostgreSQL 数据库驱动(推荐使用 psycopg 3) |
|
||||
| `gunicorn` | 生产环境 WSGI 服务器(可选,开发时可不用) |
|
||||
|
||||
### Step 3: 创建 docker-compose.yml
|
||||
### Step 3: 创建 compose.yaml
|
||||
|
||||
Step 3: 创建 docker-compose.yml 配置如下:
|
||||
Step 3: 创建 `compose.yaml` 配置如下:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
@@ -204,7 +200,7 @@ $ docker compose run --rm web django-admin startproject mysite .
|
||||
|
||||
```
|
||||
django-docker/
|
||||
├── docker-compose.yml
|
||||
├── compose.yaml
|
||||
├── Dockerfile
|
||||
├── requirements.txt
|
||||
├── manage.py
|
||||
@@ -317,7 +313,7 @@ $ docker compose logs db
|
||||
**可能原因**:
|
||||
|
||||
1. **开发服务器没有自动重载**:确保使用 `runserver` 而不是 `gunicorn`
|
||||
2. **Volume 挂载问题**:检查 `docker-compose.yml` 中的 volumes 配置
|
||||
2. **Volume 挂载问题**:检查 `compose.yaml` 中的 volumes 配置
|
||||
3. **缓存问题**:尝试 `docker compose restart web`
|
||||
|
||||
#### Q3: 权限问题(Linux)
|
||||
@@ -342,10 +338,10 @@ $ sudo chown -R $USER:$USER .
|
||||
| **Volume** | 挂载代码目录 | 代码直接 COPY 进镜像 |
|
||||
| **ALLOWED_HOSTS** | `['*']` | 具体域名 |
|
||||
|
||||
**生产环境 docker-compose.yml 示例**:
|
||||
**生产环境 Compose 文件示例**:
|
||||
|
||||
```yaml
|
||||
## docker-compose.prod.yml
|
||||
## compose.prod.yaml
|
||||
|
||||
services:
|
||||
web:
|
||||
@@ -360,7 +356,7 @@ services:
|
||||
|
||||
### 延伸阅读
|
||||
|
||||
- [Compose 模板文件详解](10.5_compose_file.md):深入理解 docker-compose.yml 的所有配置项
|
||||
- [Compose 模板文件详解](10.5_compose_file.md):深入理解 Compose 文件的所有配置项
|
||||
- [使用 WordPress](10.8_wordpress.md):另一个 Compose 实战案例
|
||||
- [Dockerfile 最佳实践](../16_appendix/16.1_best_practices.md):构建更小、更安全的镜像
|
||||
- [数据管理](../08_data_network/README.md):Volume 和数据持久化详解
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
|
||||
### 架构概览
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Docker Compose 网络 │
|
||||
@@ -35,12 +33,10 @@
|
||||
$ mkdir rails-docker && cd rails-docker
|
||||
```
|
||||
|
||||
需要创建三个文件:`Dockerfile`、`Gemfile` 和 `docker-compose.yml`。
|
||||
需要创建三个文件:`Dockerfile`、`Gemfile` 和 `compose.yaml`。
|
||||
|
||||
### Step 1: 创建 Dockerfile
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
FROM ruby:3.2
|
||||
|
||||
@@ -89,9 +85,9 @@ gem 'rails', '~> 7.1'
|
||||
$ touch Gemfile.lock
|
||||
```
|
||||
|
||||
### Step 3: 创建 docker-compose.yml
|
||||
### Step 3: 创建 compose.yaml
|
||||
|
||||
Step 3: 创建 docker-compose.yml 配置如下:
|
||||
Step 3: 创建 `compose.yaml` 配置如下:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
@@ -147,7 +143,8 @@ $ docker compose run --rm web rails new . --force --database=postgresql --skip-b
|
||||
$ ls
|
||||
Dockerfile Gemfile Rakefile config lib tmp
|
||||
Gemfile.lock README.md app config.ru log vendor
|
||||
docker-compose.yml bin db public
|
||||
compose.yaml bin db public
|
||||
|
||||
```
|
||||
|
||||
> ⚠️ **Linux 用户**:如遇权限问题,执行 `sudo chown -R $USER:$USER .`
|
||||
|
||||
@@ -6,11 +6,9 @@ WordPress 是全球最流行的内容管理系统(CMS)。使用 Docker Compo
|
||||
|
||||
### 项目结构
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```
|
||||
wordpress/
|
||||
├── docker-compose.yml
|
||||
├── compose.yaml
|
||||
├── .env # 环境变量(敏感信息)
|
||||
└── nginx/ # 可选:反向代理配置
|
||||
└── nginx.conf
|
||||
@@ -18,7 +16,7 @@ wordpress/
|
||||
|
||||
---
|
||||
|
||||
### 编写 `docker-compose.yml`
|
||||
### 编写 `compose.yaml`
|
||||
|
||||
这是一个生产可用的最小化配置:
|
||||
|
||||
@@ -79,7 +77,7 @@ networks:
|
||||
|
||||
#### 1. 环境变量(.env)
|
||||
|
||||
为了安全,不要在 `docker-compose.yml` 中直接写密码。创建 `.env` 文件:
|
||||
为了安全,不要在 `compose.yaml` 中直接写密码。创建 `.env` 文件:
|
||||
|
||||
```ini
|
||||
DB_ROOT_PASSWORD=somestrongrootpassword
|
||||
|
||||
+3
-6
@@ -1,6 +1,5 @@
|
||||
## ELK/EFK 堆栈
|
||||
|
||||
## ELK/EFK 堆栈
|
||||
|
||||
ELK (Elasticsearch, Logstash, Kibana) 是目前业界最流行的开源日志解决方案。而在容器领域,由于 Fluentd 更加轻量级且对容器支持更好,EFK (Elasticsearch, Fluentd, Kibana) 组合也变得非常流行。
|
||||
|
||||
@@ -15,16 +14,14 @@ ELK (Elasticsearch, Logstash, Kibana) 是目前业界最流行的开源日志解
|
||||
|
||||
### 部署流程
|
||||
|
||||
### 部署流程
|
||||
|
||||
我们将使用 Docker Compose 来一键部署整个日志堆栈。
|
||||
|
||||
#### 1. 编写 docker-compose.yml
|
||||
#### 1. 编写 Compose 文件
|
||||
|
||||
1. 编写 docker-compose.yml 配置如下:
|
||||
1. 编写 `compose.yaml`(或 `docker-compose.yml`)配置如下:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
services:
|
||||
elasticsearch:
|
||||
image: docker.elastic.co/elasticsearch/elasticsearch:7.17.0
|
||||
@@ -80,7 +77,7 @@ networks:
|
||||
|
||||
创建 `fluentd/conf/fluent.conf`:
|
||||
|
||||
```conf
|
||||
```ini
|
||||
<source>
|
||||
@type forward
|
||||
port 24224
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
## Prometheus + Grafana
|
||||
|
||||
## Prometheus + Grafana
|
||||
|
||||
Prometheus 和 Grafana 是目前最流行的开源监控组合,前者负责数据采集与存储,后者负责数据可视化。
|
||||
|
||||
@@ -17,7 +16,6 @@ Prometheus 的主要组件包括:
|
||||
|
||||
### 快速部署
|
||||
|
||||
### 快速部署
|
||||
|
||||
我们可以使用 Docker Compose 快速部署一套 Prometheus + Grafana 监控环境。
|
||||
|
||||
@@ -45,11 +43,9 @@ scrape_configs:
|
||||
|
||||
#### 2. 编写 Docker Compose 文件
|
||||
|
||||
创建 `docker-compose.yml`:
|
||||
创建 `compose.yaml`(或 `docker-compose.yml`):
|
||||
|
||||
```yaml
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
prometheus:
|
||||
image: prom/prometheus:latest
|
||||
@@ -99,7 +95,7 @@ networks:
|
||||
运行以下命令:
|
||||
|
||||
```bash
|
||||
$ docker-compose up -d
|
||||
$ docker compose up -d
|
||||
```
|
||||
|
||||
启动后,访问以下地址:
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
| IPC | 进程通信 | 隔离共享内存 |
|
||||
| UTS | 主机名 | 独立主机名 |
|
||||
|
||||
详见 [命名空间](../14_implementation/14.2_namespace.md) 章节。
|
||||
详见 [命名空间](../../14_implementation/14.2_namespace.md) 章节。
|
||||
|
||||
### 2. 控制组(Cgroups)
|
||||
|
||||
@@ -279,8 +279,7 @@ COPY .env /app/
|
||||
|
||||
## docker run -e DB_PASSWORD=xxx 或使用 Docker Secrets
|
||||
|
||||
具体内容如下:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
### 4. 固定依赖版本
|
||||
@@ -393,6 +392,6 @@ $ cosign verify --key cosign.pub myimage:tag
|
||||
|
||||
## 延伸阅读
|
||||
|
||||
- [命名空间](../14_implementation/14.2_namespace.md):隔离机制详解
|
||||
- [控制组](../14_implementation/14.3_cgroups.md):资源限制详解
|
||||
- [最佳实践](../16_appendix/16.1_best_practices.md):Dockerfile 安全配置
|
||||
- [命名空间](../../14_implementation/14.2_namespace.md):隔离机制详解
|
||||
- [控制组](../../14_implementation/14.3_cgroups.md):资源限制详解
|
||||
- [最佳实践](../../16_appendix/16.1_best_practices.md):Dockerfile 安全配置
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
## 内核能力机制
|
||||
|
||||
## 内核能力机制
|
||||
|
||||
Docker 利用 Linux 的能力机制(Capabilities)来限制容器的权限,从而提高系统的安全性。
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
## 内核命名空间
|
||||
|
||||
## 内核命名空间
|
||||
|
||||
命名空间(Namespace)是 Linux 容器隔离的基础,它确保了容器内的进程无法干扰主机或其他容器。
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
## 其它安全特性
|
||||
|
||||
## 其它安全特性
|
||||
|
||||
除了上述机制,Linux 内核还提供了一系列安全增强功能,可以进一步保护容器环境。
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
## 总结
|
||||
|
||||
## 总结
|
||||
|
||||
Docker 的安全性依赖于多层隔离机制的协同工作,同时需要用户遵循最佳实践。
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
## etcd 集群
|
||||
|
||||
下面我们使用 [Docker Compose](../compose/) 模拟启动一个 3 节点的 `etcd` 集群。
|
||||
下面我们使用 [Docker Compose](../../10_compose/README.md) 模拟启动一个 3 节点的 `etcd` 集群。
|
||||
|
||||
编辑 `docker-compose.yml` 文件
|
||||
编辑 `compose.yaml`(或 `docker-compose.yml`)文件
|
||||
|
||||
```yaml
|
||||
version: "3.6"
|
||||
services:
|
||||
|
||||
node1:
|
||||
|
||||
@@ -15,9 +15,7 @@
|
||||
```bash
|
||||
$ curl -L https://github.com/etcd-io/etcd/releases/download/v3.4.0/etcd-v3.4.0-linux-amd64.tar.gz -o etcd-v3.4.0-linux-amd64.tar.gz
|
||||
|
||||
## 国内用户可以使用以下方式加快下载
|
||||
|
||||
$ curl -L https://download.fastgit.org/etcd-io/etcd/releases/download/v3.4.0/etcd-v3.4.0-linux-amd64.tar.gz -o etcd-v3.4.0-linux-amd64.tar.gz
|
||||
## 国内用户可选择就近的网络加速方式(以可用镜像站为准)
|
||||
|
||||
$ tar xzvf etcd-v3.4.0-linux-amd64.tar.gz
|
||||
$ cd etcd-v3.4.0-linux-amd64
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
简介 示意图如下:
|
||||
|
||||

|
||||

|
||||
|
||||
`etcd` 是 `CoreOS` 团队于 2013 年 6 月发起的开源项目,它的目标是构建一个高可用的分布式键值(`key-value`)数据库,基于 `Go` 语言实现。我们知道,在分布式系统中,各种服务的配置信息的管理分享,服务的发现是一个很基本同时也是很重要的问题。`CoreOS` 项目就希望基于 `etcd` 来解决这一问题。
|
||||
|
||||
|
||||
@@ -28,13 +28,13 @@ kubectl [command]
|
||||
|
||||
通过文件名、标准输入、资源名或者 label selector 删除资源
|
||||
|
||||
## log
|
||||
## logs
|
||||
|
||||
输出 pod 中一个容器的日志
|
||||
|
||||
## rolling-update
|
||||
## rollout
|
||||
|
||||
对指定的 replication controller 执行滚动升级
|
||||
对 Deployment 等资源执行滚动更新/回滚
|
||||
|
||||
## exec
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# Kubernetes
|
||||
|
||||
`Kubernetes` 是 Google 团队发起并维护的基于 Docker 的开源容器集群管理系统,它不仅支持常见的云平台,而且支持内部数据中心。
|
||||
`Kubernetes` 是 Google 发起的开源容器编排系统,它支持多种云平台与私有数据中心。
|
||||
|
||||
建于 Docker 之上的 `Kubernetes` 可以构建一个容器的调度服务,其目的是让用户透过 `Kubernetes` 集群来进行云端容器集群的管理,而无需用户进行复杂的设置工作。系统会自动选取合适的工作节点来执行具体的容器集群调度处理工作。其核心概念是 `Container Pod`。一个 `Pod` 由一组工作于同一物理工作节点的容器构成。这些组容器拥有相同的网络命名空间、IP以及存储配额,也可以根据实际情况对每一个 `Pod` 进行端口映射。此外,`Kubernetes` 工作节点会由主系统进行管理,节点包含了能够运行 Docker 容器所用到的服务。
|
||||
`Kubernetes` 负责对容器工作负载进行调度与编排,其目的是让用户通过集群声明式地管理应用,而无需手动干预每个容器的生命周期细节。
|
||||
|
||||
Kubernetes 的最小调度单位是 `Pod`。一个 `Pod` 由一组紧密协作的容器构成,它们共享网络命名空间、IP 以及部分存储资源,也可以根据需要对 Pod 进行端口映射。
|
||||
|
||||
本章将分为 5 节介绍 `Kubernetes`,包括
|
||||
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
基本概念 示意图如下:
|
||||
|
||||

|
||||

|
||||
|
||||
* 节点(`Node`):一个节点是一个运行 Kubernetes 中的主机。
|
||||
* 容器组(`Pod`):一个 Pod 对应于由若干容器组成的一个容器组,同个组内的容器共享一个存储卷(volume)。
|
||||
* 容器组生命周期(`pos-states`):包含所有容器状态集合,包括容器组状态类型,容器组生命周期,事件,重启策略,以及 replication controllers。
|
||||
* 容器组生命周期(`pod-states`):包含所有容器状态集合,包括容器组状态类型,容器组生命周期,事件,重启策略,以及 replication controllers。
|
||||
* Replication Controllers:主要负责指定数量的 pod 在同一时间一起运行。
|
||||
* 服务(`services`):一个 Kubernetes 服务是容器组逻辑的高级抽象,同时也对外提供访问容器组的策略。
|
||||
* 卷(`volumes`):一个卷就是一个目录,容器对其有访问权限。
|
||||
@@ -179,35 +179,28 @@ Kubernetes 校验节点可用依赖于 ID。在当前的版本中,有两个接
|
||||
|
||||
### Replication Controllers
|
||||
|
||||
> [!NOTE]
|
||||
> Replication Controller 保证指定数量的 Pod 副本在任何时候都处于运行状态。
|
||||
> 注:Replication Controller(RC)是早期的控制器类型,现代 Kubernetes 更推荐使用 ReplicaSet/Deployment。
|
||||
|
||||
### 服务
|
||||
|
||||
> [!NOTE]
|
||||
> 服务(Service)定义一组 Pod 的逻辑集合和访问它们的策略。
|
||||
> 注:服务(Service)定义一组 Pod 的逻辑集合和访问它们的策略。
|
||||
|
||||
### 卷
|
||||
|
||||
> [!NOTE]
|
||||
> 卷(Volume)包含可被 Pod 中容器访问的数据的目录。
|
||||
> 注:卷(Volume)包含可被 Pod 中容器访问的数据的目录。
|
||||
|
||||
### 标签
|
||||
|
||||
> [!NOTE]
|
||||
> 标签(Label)是附加到对象(如 Pods)上的键值对,用于组织和选择对象子集。
|
||||
> 注:标签(Label)是附加到对象(如 Pods)上的键值对,用于组织和选择对象子集。
|
||||
|
||||
### 接口权限
|
||||
|
||||
> [!NOTE]
|
||||
> 接口权限通过认证、授权和准入控制来保护 Kubernetes API 的访问。
|
||||
> 注:接口权限通过认证、授权和准入控制来保护 Kubernetes API 的访问。
|
||||
|
||||
### web界面
|
||||
|
||||
> [!NOTE]
|
||||
> Kubernetes Dashboard 是一个基于 Web 的用户界面,用于管理集群。
|
||||
> 注:Kubernetes Dashboard 是一个基于 Web 的用户界面,用于管理集群。
|
||||
|
||||
### 命令行操作
|
||||
|
||||
> [!NOTE]
|
||||
> kubectl 是 Kubernetes 的命令行工具,用于与集群进行交互。
|
||||
> 注:kubectl 是 Kubernetes 的命令行工具,用于与集群进行交互。
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
下面这张图完整展示了 Kubernetes 的运行原理。
|
||||
|
||||

|
||||

|
||||
|
||||
可见,Kubernetes 首先是一套分布式系统,由多个节点组成,节点分为两类:一类是属于管理平面的主节点/控制节点(Master Node);一类是属于运行平面的工作节点(Worker Node)。
|
||||
|
||||
@@ -48,4 +48,4 @@
|
||||
* kubelet 是工作节点执行操作的 agent,负责具体的容器生命周期管理,根据从数据库中获取的信息来管理容器,并上报 pod 运行状态等;
|
||||
* kube-proxy 是一个简单的网络访问代理,同时也是一个 Load Balancer。它负责将访问到某个服务的请求具体分配给工作节点上的 Pod(同一类标签)。
|
||||
|
||||

|
||||

|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Kubernetes 简介 示意图如下:
|
||||
|
||||

|
||||

|
||||
|
||||
### 什么是 Kubernetes
|
||||
|
||||
@@ -67,7 +67,7 @@ Kubernetes 的最小调度单位。一个 Pod 可以包含一个或多个紧密
|
||||
|
||||
### 架构
|
||||
|
||||
Kubernetes 也是 C/S 架构,由 **Master (控制平面)**和**Worker (工作节点)** 组成:
|
||||
Kubernetes 也是 C/S 架构,由 **Control Plane(控制平面)** 和 **Worker Node(工作节点)** 组成:
|
||||
|
||||
- **Control Plane**:负责决策(API Server, Scheduler, Controller Manager, etcd)
|
||||
- **Worker Node**:负责干活(Kubelet, Kube-proxy, Container Runtime)
|
||||
@@ -86,5 +86,5 @@ Kubernetes 的学习曲线较陡峭。建议的学习路径:
|
||||
|
||||
### 延伸阅读
|
||||
|
||||
- [Minikube 安装](../kubernetes/setup/README.md):本地体验 K8s
|
||||
- [Minikube 安装](../setup/README.md):本地体验 K8s
|
||||
- [Kubernetes 官网](https://kubernetes.io/):官方文档
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
### 安装 Docker
|
||||
|
||||
参考 [安装 Docker](../../install) 一节安装 Docker。
|
||||
参考 [安装 Docker](../../03_install/README.md) 一节安装 Docker。
|
||||
|
||||
### 安装 **kubelet** **kubeadm** **kubectl**
|
||||
|
||||
@@ -199,8 +199,7 @@ $ kubectl taint nodes --all node-role.kubernetes.io/master-
|
||||
|
||||
## $ kubectl taint nodes NODE_NAME node-role.kubernetes.io/master=true:NoSchedule
|
||||
|
||||
具体内容如下:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
### 参考文档
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
### 安装 containerd
|
||||
|
||||
参考 [安装 Docker](../../install) 一节添加 apt/yum 源,之后执行如下命令。
|
||||
参考 [安装 Docker](../../03_install/README.md) 一节添加 apt/yum 源,之后执行如下命令。
|
||||
|
||||
```bash
|
||||
## debian 系
|
||||
@@ -419,8 +419,7 @@ $ kubectl taint nodes --all node-role.kubernetes.io/master-
|
||||
|
||||
## $ kubectl taint nodes NODE_NAME node-role.kubernetes.io/master=true:NoSchedule
|
||||
|
||||
具体内容如下:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
### 参考文档
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
阿里云 示意图如下:
|
||||
|
||||

|
||||

|
||||
|
||||
[阿里云](https://www.aliyun.com/?source=5176.11533457\&userCode=8lx5zmtu\&type=copy) 创立于 2009 年,是中国较早的云计算平台。阿里云致力于提供安全、可靠的计算和数据处理能力。
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
亚马逊云 示意图如下:
|
||||
|
||||

|
||||

|
||||
|
||||
[AWS](https://www.amazonaws.cn),即 Amazon Web Services,是亚马逊(Amazon)公司的 IaaS 和 PaaS 平台服务。AWS 提供了一整套基础设施和应用程序服务,使用户几乎能够在云中运行一切应用程序:从企业应用程序和大数据项目,到社交游戏和移动应用程序。AWS 面向用户提供包括弹性计算、存储、数据库、应用程序在内的一整套云计算服务,能够帮助企业降低 IT 投入成本和维护成本。
|
||||
|
||||
@@ -10,4 +10,4 @@
|
||||
|
||||
2015 年 AWS 正式发布了 EC2 容器服务(ECS)。ECS 的目的是让 Docker 容器变的更加简单,它提供了一个集群和编排的层,用来控制主机上的容器部署,以及部署之后的集群内的容器的生命周期管理。ECS 是诸如 Docker Swarm、Kubernetes、Mesos 等工具的替代,它们工作在同一个层,除了作为一个服务来提供。这些工具和 ECS 不同的地方在于,前者需要用户自己来部署和管理,而 ECS 是“作为服务”来提供的。
|
||||
|
||||

|
||||

|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
腾讯云 示意图如下:
|
||||
|
||||

|
||||

|
||||
|
||||
[腾讯云](https://cloud.tencent.com/act/cps/redirect?redirect=1040\&cps_key=3a5255852d5db99dcd5da4c72f05df61\&from=console) 在架构方面经过多年积累,并且有着多年对海量互联网服务的经验。不管是社交、游戏还是其他领域,都有多年的成熟产品来提供产品服务。腾讯在云端完成重要部署,为开发者及企业提供云服务、云数据、云运营等整体一站式服务方案。
|
||||
|
||||
|
||||
@@ -83,6 +83,7 @@ $ podman run -d --pod mypod --name webbing nginx
|
||||
|
||||
如果你习惯使用 `docker` 命令,可以简单地设置别名:
|
||||
|
||||
```bash
|
||||
$ alias docker=podman
|
||||
```
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
## 14.2 命名空间
|
||||
|
||||
命名空间(Namespace)是 Linux 内核的一个强大特性,为容器提供了隔离的运行环境。
|
||||
|
||||
### 什么是 Namespace
|
||||
@@ -39,11 +37,11 @@ Linux 内核提供了以下几种 Namespace,Docker 容器使用了全部:
|
||||
|
||||
PID Namespace 负责进程 ID 的隔离,使得容器内的进程彼此不可见。
|
||||
|
||||
#### 作用
|
||||
#### PID 的作用
|
||||
|
||||
隔离进程 ID,让每个容器有自己的进程编号空间。
|
||||
|
||||
#### 效果
|
||||
#### PID 隔离效果
|
||||
|
||||
运行以下命令:
|
||||
|
||||
@@ -62,7 +60,7 @@ PID USER COMMAND
|
||||
2 root nginx: worker process
|
||||
```
|
||||
|
||||
#### 关键点
|
||||
#### PID 关键点
|
||||
|
||||
- 容器内的 PID 1 进程特殊重要——它是容器的主进程,退出则容器停止
|
||||
- 容器内无法看到宿主机或其他容器的进程
|
||||
@@ -74,13 +72,11 @@ PID USER COMMAND
|
||||
|
||||
NET Namespace 负责网络栈的隔离,包括网卡、路由表和 iptables 规则等。
|
||||
|
||||
#### 作用
|
||||
#### NET 的作用
|
||||
|
||||
隔离网络栈,每个容器拥有独立的网络环境。
|
||||
|
||||
#### 效果
|
||||
|
||||
具体内容如下:
|
||||
#### NET 隔离效果
|
||||
|
||||
```
|
||||
宿主机 容器
|
||||
@@ -91,7 +87,7 @@ NET Namespace 负责网络栈的隔离,包括网卡、路由表和 iptables
|
||||
└─────────────────────┘ └─────────────────────┘
|
||||
```
|
||||
|
||||
#### 关键点
|
||||
#### NET 关键点
|
||||
|
||||
- 每个容器有独立的网卡、IP、路由表、iptables 规则
|
||||
- 多个容器可以监听相同端口(如都监听 80)
|
||||
@@ -103,13 +99,11 @@ NET Namespace 负责网络栈的隔离,包括网卡、路由表和 iptables
|
||||
|
||||
MNT Namespace 负责文件系统挂载点的隔离,确保容器看到独立的文件系统视图。
|
||||
|
||||
#### 作用
|
||||
#### MNT 的作用
|
||||
|
||||
隔离文件系统挂载点,每个容器有自己的根目录。
|
||||
|
||||
#### 效果
|
||||
|
||||
具体内容如下:
|
||||
#### MNT 隔离效果
|
||||
|
||||
```
|
||||
宿主机文件系统: 容器内看到的:
|
||||
@@ -138,11 +132,11 @@ MNT Namespace 负责文件系统挂载点的隔离,确保容器看到独立的
|
||||
|
||||
UTS Namespace 主要用于隔离主机名和域名。
|
||||
|
||||
#### 作用
|
||||
#### UTS 的作用
|
||||
|
||||
隔离主机名和域名,让每个容器可以有自己的主机名。
|
||||
|
||||
#### 效果
|
||||
#### UTS 隔离效果
|
||||
|
||||
运行以下命令:
|
||||
|
||||
@@ -166,7 +160,7 @@ UTS = "UNIX Time-sharing System",是历史遗留的名称。
|
||||
|
||||
IPC Namespace 用于隔离进程间通信资源,如 System V IPC 和 POSIX 消息队列。
|
||||
|
||||
#### 作用
|
||||
#### IPC 的作用
|
||||
|
||||
隔离 System V IPC 和 POSIX 消息队列。
|
||||
|
||||
@@ -176,7 +170,7 @@ IPC Namespace 用于隔离进程间通信资源,如 System V IPC 和 POSIX 消
|
||||
- 消息队列(message queues)
|
||||
- 共享内存(shared memory)
|
||||
|
||||
#### 关键点
|
||||
#### IPC 关键点
|
||||
|
||||
- 同一容器内的进程可以通过 IPC 通信
|
||||
- 不同容器的进程无法通过 IPC 通信(除非显式共享)
|
||||
@@ -187,13 +181,11 @@ IPC Namespace 用于隔离进程间通信资源,如 System V IPC 和 POSIX 消
|
||||
|
||||
USER Namespace 允许将容器内的用户 ID 映射到宿主机的不同用户 ID。
|
||||
|
||||
#### 作用
|
||||
#### USER 的作用
|
||||
|
||||
隔离用户和组 ID,实现权限隔离。
|
||||
|
||||
#### 效果
|
||||
|
||||
具体内容如下:
|
||||
#### USER 隔离效果
|
||||
|
||||
```
|
||||
容器内 宿主机
|
||||
@@ -305,5 +297,5 @@ Namespace 提供了隔离但不是安全边界:
|
||||
|
||||
- [控制组(Cgroups)](14.3_cgroups.md):资源限制机制
|
||||
- [联合文件系统](14.4_ufs.md):分层存储的实现
|
||||
- [安全](../security/README.md):容器安全实践
|
||||
- [安全](../11_ops/security/README.md):容器安全实践
|
||||
- [Linux Namespace 官方文档](https://man7.org/linux/man-pages/man7/namespaces.7.html)
|
||||
|
||||
@@ -172,8 +172,7 @@ abc123 Exited (137) 5 seconds ago hopeful_darwin
|
||||
|
||||
## 137 = 128 + 9,表示被 SIGKILL(9) 杀死
|
||||
|
||||
具体内容如下:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
#### CPU 限制验证
|
||||
@@ -191,8 +190,7 @@ $ docker run --rm stress --cpu 4
|
||||
$ docker run --rm --cpus=1 stress --cpu 4
|
||||
## 只能使用约 100% CPU(1 个核心)
|
||||
|
||||
具体内容如下:
|
||||
|
||||
...
|
||||
```
|
||||
|
||||
---
|
||||
@@ -299,5 +297,5 @@ $ docker run -d --name cadvisor \
|
||||
### 延伸阅读
|
||||
|
||||
- [命名空间](14.2_namespace.md):资源隔离
|
||||
- [安全](../security/README.md):容器安全概述
|
||||
- [安全](../11_ops/security/README.md):容器安全概述
|
||||
- [Docker Stats](../05_container/README.md):监控容器资源
|
||||
|
||||
@@ -37,8 +37,6 @@ Docker 选择联合文件系统作为其存储驱动,主要基于以下几个
|
||||
|
||||
#### 1. 镜像分层复用
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```
|
||||
nginx:alpine myapp:latest
|
||||
│ │
|
||||
@@ -202,8 +200,6 @@ $ docker inspect nginx:alpine --format '{{json .GraphDriver.Data}}' | jq
|
||||
|
||||
#### 1. 减少镜像层数
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```docker
|
||||
## ❌ 每条命令创建一层
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
在 Github 新建一个名为 `drone-demo` 的仓库。
|
||||
|
||||
打开我们已经 [部署好的 Drone 网站](10.2_install.md) 或者 [Drone Cloud](https://cloud.drone.io),使用 GitHub 账号登录,在界面中关联刚刚新建的 `drone-demo` 仓库。
|
||||
打开我们已经 [部署好的 Drone 网站](install.md) 或者 [Drone Cloud](https://cloud.drone.io),使用 GitHub 账号登录,在界面中关联刚刚新建的 `drone-demo` 仓库。
|
||||
|
||||
## 编写项目源代码
|
||||
|
||||
@@ -92,7 +92,7 @@ $ git push origin master
|
||||
|
||||
当然我们也可以把构建结果上传到 GitHub,Docker Registry,云服务商提供的对象存储,或者生产环境中。
|
||||
|
||||
本书 GitBook 也使用 Drone 进行 CI/CD,具体配置信息请查看本书根目录 [`.drone.yml`](../../../.drone.yml) 文件。
|
||||
本书 GitBook 也使用 Drone 进行 CI/CD,具体配置信息请查看本书根目录 [`.drone.yml`](https://github.com/yeasy/docker_practice/blob/master/.drone.yml) 文件。
|
||||
|
||||
## 参考链接
|
||||
|
||||
|
||||
@@ -22,11 +22,9 @@
|
||||
|
||||
### 配置 Drone
|
||||
|
||||
我们通过使用 `Docker Compose` 来启动 `Drone`,编写 `docker-compose.yml` 文件。
|
||||
我们通过使用 `Docker Compose` 来启动 `Drone`,编写 `compose.yaml`(或 `docker-compose.yml`)文件。
|
||||
|
||||
```yaml
|
||||
|
||||
|
||||
services:
|
||||
|
||||
drone-server:
|
||||
@@ -87,5 +85,5 @@ DRONE_GITHUB_CLIENT_SECRET=
|
||||
运行以下命令:
|
||||
|
||||
```bash
|
||||
$ docker-compose up -d
|
||||
$ docker compose up -d
|
||||
```
|
||||
|
||||
@@ -21,11 +21,11 @@ CentOS 官方镜像的使用非常简单。
|
||||
|
||||
```bash
|
||||
$ docker run -it centos:7 bash
|
||||
Unable to find image 'centos:latest' locally
|
||||
latest: Pulling from library/centos
|
||||
Unable to find image 'centos:7' locally
|
||||
7: Pulling from library/centos
|
||||
3d8673bd162a: Pull complete
|
||||
Digest: sha256:a66ffcb73930584413de83311ca11a4cb4938c9b2521d331026dad970c19adf4
|
||||
Status: Downloaded newer image for centos:latest
|
||||
Status: Downloaded newer image for centos:7
|
||||
[root@43eb3b194d48 /]# cat /etc/redhat-release
|
||||
CentOS Linux release 7.9.2009 (Core)
|
||||
```
|
||||
@@ -41,6 +41,7 @@ CentOS Linux release 7.9.2009 (Core)
|
||||
|
||||
使用 `docker run` 命令直接运行 `Fedora` 官方镜像,并登录 `bash`。
|
||||
|
||||
```bash
|
||||
$ docker run -it fedora bash
|
||||
Unable to find image 'fedora:latest' locally
|
||||
latest: Pulling from library/fedora
|
||||
@@ -49,6 +50,7 @@ Digest: sha256:64a02df6aac27d1200c2572fe4b9949f1970d05f74d367ce4af994ba5dc3669e
|
||||
Status: Downloaded newer image for fedora:latest
|
||||
[root@196ca341419b /]# cat /etc/redhat-release
|
||||
Fedora release 39 (Thirty Nine)
|
||||
```
|
||||
|
||||
|
||||
### 相关资源
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
应该保证在一个容器中只运行一个进程。将多个应用解耦到不同容器中,保证了容器的横向扩展和复用。例如 web 应用应该包含三个容器:web应用、数据库、缓存。
|
||||
|
||||
如果容器互相依赖,你可以使用 [Docker 自定义网络](../network/README.md) 来把这些容器连接起来。
|
||||
如果容器互相依赖,你可以使用 [Docker 自定义网络](../08_data_network/network/README.md) 来把这些容器连接起来。
|
||||
|
||||
#### 镜像层数尽可能少
|
||||
|
||||
|
||||
@@ -39,6 +39,15 @@ $ sudo kill -SIGUSR1 $(pidof dockerd)
|
||||
|
||||
*注意,本操作会移除所有的 Docker 本地数据,包括镜像和容器等。*
|
||||
|
||||
更安全的替代方式是优先使用以下命令进行清理:
|
||||
|
||||
```bash
|
||||
$ docker system prune
|
||||
```
|
||||
|
||||
如果你只是想“恢复出厂设置”,在 Docker Desktop 里也提供了相应入口。
|
||||
|
||||
```bash
|
||||
$ sudo rm -rf /var/lib/docker
|
||||
```
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* Docker 官方文档:https://docs.docker.com/
|
||||
* Docker Hub:https://hub.docker.com
|
||||
* Docker 的源代码仓库:https://github.com/moby/moby
|
||||
* Docker 路线图 https://github.com/docker/roadmap/projects
|
||||
* Docker 路线图:https://github.com/docker/roadmap/projects
|
||||
* Docker 发布版本历史:https://docs.docker.com/release-notes/
|
||||
* Docker 常见问题:https://docs.docker.com/engine/faq/
|
||||
* Docker 远端应用 API:https://docs.docker.com/develop/sdk/
|
||||
@@ -22,7 +22,7 @@
|
||||
* Docker 邮件列表: https://groups.google.com/forum/#!forum/docker-user
|
||||
* Docker 社区 Slack:https://dockercommunity.slack.com/
|
||||
* Docker Community Discord: https://discord.gg/docker
|
||||
* Docker 的 Twitter 主页:https://twitter.com/docker
|
||||
* Docker 的 X (Twitter) 主页:https://twitter.com/docker
|
||||
|
||||
### 其它
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ $ docker run --network=my-net --ip=172.25.3.3 -itd --name=my-container busybox
|
||||
|
||||
### 可以在一个容器中同时运行多个应用进程么?
|
||||
|
||||
答:一般并不推荐在同一个容器内运行多个应用进程。如果有类似需求,可以通过一些额外的进程管理机制,比如 `supervisord` 来管理所运行的进程。可以参考 https://docs.docker.com/config/containers/multi-service\_container/ 。
|
||||
答:一般并不推荐在同一个容器内运行多个应用进程。如果有类似需求,可以通过一些额外的进程管理机制,比如 `supervisord` 来管理所运行的进程。可以参考 https://docs.docker.com/engine/containers/multi-service_container/ 。
|
||||
|
||||
### 如何控制容器占用系统资源(CPU、内存)的份额?
|
||||
|
||||
@@ -168,7 +168,7 @@ lrwxrwxrwx. 1 root root 15 11月 17 13:43 docker -> /storage/docker
|
||||
|
||||
### Docker 能在非 Linux 平台(比如 Windows 或 macOS )上运行么?
|
||||
|
||||
答:完全可以。安装方法请查看 [安装 Docker](../../install/) 一节
|
||||
答:完全可以。安装方法请查看 [安装 Docker](../../03_install/README.md) 一节
|
||||
|
||||
### 如何将一台宿主主机的 Docker 环境迁移到另外一台宿主主机?
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
| `Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?` | Docker 服务未启动 | Linux: `sudo systemctl start docker`<br>Mac/Win: 启动 Docker Desktop |
|
||||
| `permission denied while trying to connect to the Docker daemon socket` | 当前用户不在 `docker` 用户组 | `sudo usermod -aG docker $USER` (需重新登录) |
|
||||
| `manifest for ... not found: manifest unknown` | 镜像 tag 不存在 | 检查 Docker Hub 该镜像是否存在该 tag,或拼写是否正确 |
|
||||
| `connection refused` (pull image) | 网络不通或镜像源无法访问 | 检查网络,配置[镜像加速器](../../install/3.9_mirror.md) |
|
||||
| `connection refused` (pull image) | 网络不通或镜像源无法访问 | 检查网络,配置[镜像加速器](../../03_install/3.9_mirror.md) |
|
||||
| `Bind for 0.0.0.0:8080 failed: port is already allocated` | 端口被占用 | 检查占用端口的进程 (`lsof -i:8080`) 并杀掉,或换个端口映射 (`-p 8081:80`) |
|
||||
| `exec user process caused "exec format error"` | 架构不匹配 (如在 x86 上跑 ARM 镜像) | 使用 `docker buildx` 构建多架构镜像,或拉取对应架构的镜像 |
|
||||
| `standard_init_linux.go:211: exec user process caused "no such file or directory"` | 找不到解释器或依赖库 | 检查 `ENTRYPOINT`/`CMD` 脚本开头的 shebang (`#!/bin/sh` vs `#!/bin/bash`),或确认二进制文件是否依赖缺失 (Alpine 常见缺少 glibc) |
|
||||
|
||||
@@ -33,7 +33,7 @@ $ docker save -o minio.tar minio/minio:latest
|
||||
把压缩文件复制到内网服务器上,使用下面的命令导入镜像
|
||||
|
||||
```bash
|
||||
$ docker load minio.tar
|
||||
$ docker load -i minio.tar
|
||||
```
|
||||
|
||||
#### 运行 minio
|
||||
@@ -55,4 +55,4 @@ $ sudo docker run -d -p 9000:9000 -p 9090:9090 --name minio1 \
|
||||
|
||||
#### 访问 web 管理页面
|
||||
|
||||
http://x.x.x.x:9090
|
||||
打开 `http://<server-ip>:9090` 访问 Web 控制台。
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
[MongoDB](https://en.wikipedia.org/wiki/MongoDB) 是开源的 NoSQL 数据库实现。
|
||||
|
||||
该仓库位于 `https://hub.docker.com/_/mongo/` ,提供了 MongoDB 2.x ~ 4.x 各个版本的镜像。
|
||||
该仓库位于 `https://hub.docker.com/_/mongo/`。具体可用版本以 Docker Hub 上的 tags 列表为准。
|
||||
|
||||
### 使用方法
|
||||
|
||||
@@ -37,7 +37,6 @@ $ docker run -it --rm \
|
||||
mongo \
|
||||
sh -c 'exec mongo "some-mongo:27017/test"'
|
||||
```
|
||||
```
|
||||
|
||||
### Dockerfile
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
[MySQL](https://en.wikipedia.org/wiki/MySQL) 是开源的关系数据库实现。
|
||||
|
||||
该仓库位于 `https://hub.docker.com/_/mysql/` ,提供了 MySQL 5.5 ~ 8.x 各个版本的镜像。
|
||||
该仓库位于 `https://hub.docker.com/_/mysql/`。具体可用版本以 Docker Hub 上的 tags 列表为准。
|
||||
|
||||
### 使用方法
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
[Nginx](https://en.wikipedia.org/wiki/Nginx) 是开源的高效的 Web 服务器实现,支持 HTTP、HTTPS、SMTP、POP3、IMAP 等协议。
|
||||
|
||||
该仓库位于 `https://hub.docker.com/_/nginx/` ,提供了 Nginx 1.0 ~ 1.19.x 各个版本的镜像。
|
||||
该仓库位于 `https://hub.docker.com/_/nginx/`。具体可用版本以 Docker Hub 上的 tags 列表为准。
|
||||
|
||||
### 使用方法
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
[Node.js](https://en.wikipedia.org/wiki/Node.js) 是基于 JavaScript 的可扩展服务端和网络软件开发平台。
|
||||
|
||||
该仓库位于 `https://hub.docker.com/_/node/` ,提供了 Node.js 0.10 ~ 14.x 各个版本的镜像。
|
||||
该仓库位于 `https://hub.docker.com/_/node/`。具体可用版本以 Docker Hub 上的 tags 列表为准。
|
||||
|
||||
### 使用方法
|
||||
|
||||
@@ -30,7 +30,7 @@ $ docker run -it --rm --name my-running-app my-nodejs-app
|
||||
$ docker run -it --rm \
|
||||
--name my-running-script \
|
||||
# -v "$(pwd)":/usr/src/myapp \
|
||||
--mount type=bind,src=`$(pwd)`,target=/usr/src/myapp \
|
||||
--mount type=bind,src="$(pwd)",target=/usr/src/myapp \
|
||||
-w /usr/src/myapp \
|
||||
node:12-alpine \
|
||||
node your-daemon-or-script.js
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
[PHP](https://en.wikipedia.org/wiki/Php)(Hypertext Preprocessor 超文本预处理器的字母缩写)是一种被广泛应用的开放源代码的多用途脚本语言,它可嵌入到 HTML 中,尤其适合 web 开发。
|
||||
|
||||
该仓库位于 `https://hub.docker.com/_/php/` ,提供了 PHP 5.x ~ 8.x 各个版本的镜像。
|
||||
该仓库位于 `https://hub.docker.com/_/php/`。具体可用版本以 Docker Hub 上的 tags 列表为准。
|
||||
|
||||
### 使用方法
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
[Redis](https://en.wikipedia.org/wiki/Redis) 是开源的内存 Key-Value 数据库实现。
|
||||
|
||||
该仓库位于 `https://hub.docker.com/_/redis/` ,提供了 Redis 3.x ~ 6.x 各个版本的镜像。
|
||||
该仓库位于 `https://hub.docker.com/_/redis/`。具体可用版本以 Docker Hub 上的 tags 列表为准。
|
||||
|
||||
### 使用方法
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
[Ubuntu](https://en.wikipedia.org/wiki/Ubuntu) 是流行的 Linux 发行版,其自带软件版本往往较新一些。
|
||||
|
||||
该仓库位于 `https://hub.docker.com/_/ubuntu/` ,提供了 Ubuntu 从 12.04 ~ 20.04 各个版本的镜像。
|
||||
该仓库位于 `https://hub.docker.com/_/ubuntu/`。具体可用版本以 Docker Hub 上的 tags 列表为准。
|
||||
|
||||
### 使用方法
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
[WordPress](https://en.wikipedia.org/wiki/WordPress) 是开源的 Blog 和内容管理系统框架,它基于 PHP 和 MySQL。
|
||||
|
||||
该仓库位于 `https://hub.docker.com/_/wordpress/` ,提供了 WordPress 4.x ~ 5.x 版本的镜像。
|
||||
该仓库位于 `https://hub.docker.com/_/wordpress/`。具体可用版本以 Docker Hub 上的 tags 列表为准。
|
||||
|
||||
### 使用方法
|
||||
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
* [数据管理](08_data_network/data/README.md)
|
||||
* [数据卷](08_data_network/data/volume.md)
|
||||
* [挂载主机目录](08_data_network/data/bind-mounts.md)
|
||||
* [tmpfs 挂载](08_data_network/data/tmpfs.md)
|
||||
* [网络配置](08_data_network/network/README.md)
|
||||
* [配置 DNS](08_data_network/network/dns.md)
|
||||
* [外部访问容器](08_data_network/network/port_mapping.md)
|
||||
@@ -158,6 +159,7 @@
|
||||
* [GitHub Actions](15_cases/ci/actions/README.md)
|
||||
* [Drone](15_cases/ci/drone/README.md)
|
||||
* [部署 Drone](15_cases/ci/drone/install.md)
|
||||
* [Drone Demo](15_cases/ci/drone/demo/README.md)
|
||||
* [在 IDE 中使用 Docker](15_cases/ide/README.md)
|
||||
* [VS Code](15_cases/ide/vsCode.md)
|
||||
* [第十六章 附录](16_appendix/README.md)
|
||||
|
||||
Reference in New Issue
Block a user