mirror of
https://github.com/yeasy/docker_practice.git
synced 2026-03-11 12:21:17 +00:00
Fix format issue
This commit is contained in:
@@ -1,129 +0,0 @@
|
||||
---
|
||||
trigger: always_on
|
||||
---
|
||||
|
||||
# Project Rules
|
||||
|
||||
This document serves as the single source of truth for all formatting, structure, and writing rules for the project.
|
||||
|
||||
> [!NOTE]
|
||||
> **Root special files**: `README.md` and `SUMMARY.md` in the project root are special files with relaxed rules. Only basic formatting rules apply (bold-spacing, trailing-newline).
|
||||
|
||||
## 1. Markdown Formatting Rules
|
||||
|
||||
### 1.1 Bold Text
|
||||
|
||||
- **Rule**: Do not put spaces inside the bold markers.
|
||||
- Correct: `**Bold Text**`
|
||||
- Incorrect: `**Bold Text**`
|
||||
- **Context**: Ensure there is a space outside the bold markers if adjacent to other text (except punctuation).
|
||||
- Correct: `这是 **加粗** 文字`
|
||||
- Incorrect: `这是 **加粗** 文字`
|
||||
|
||||
### 1.2 Header Spacing
|
||||
|
||||
- **Rule**: Headers must be followed by exactly one blank line.
|
||||
- No blank line after header: ❌
|
||||
- Multiple blank lines after header: ❌
|
||||
- Exactly one blank line: ✅
|
||||
|
||||
### 1.3 Header Hierarchy
|
||||
|
||||
- **Rule**: Header levels must not skip. H2 cannot be followed directly by H4.
|
||||
- Correct: `## → ### → ####`
|
||||
- Incorrect: `## → ####`
|
||||
|
||||
### 1.4 Trailing Newline
|
||||
|
||||
- **Rule**: Files must end with exactly one newline character.
|
||||
- No trailing newline: ❌
|
||||
- Multiple trailing newlines: ❌
|
||||
|
||||
## 2. Header Structure Rules
|
||||
|
||||
### 2.1 Chapter Hierarchy
|
||||
|
||||
- **Level 1 (#)**: Chapter titles, e.g., `# 第一章:章标题`
|
||||
- **Level 2 (##)**: Section titles with numbering, e.g., `## 1.1 小节标题`
|
||||
- **Level 3 (###)**: Subsection titles with numbering, e.g., `### 1.1.1 子节标题`
|
||||
- **Level 4+ (####)**: No numbering allowed (can use ordinal: 1, 2, 3...)
|
||||
- **Exception**: `本章小结` does not require numbering.
|
||||
- **Exception**: Appendix files (13_appendix) have relaxed numbering rules:
|
||||
- `13.1_glossary`: Organized by alphabet, no X.X.X numbering required
|
||||
- `13.2_reading_list`: Organized by category
|
||||
- `13.3_code_examples`, `13.4_api_reference`, `13.5_agents_md`: Reference materials
|
||||
- `13.6_versions`, `13.7_case_templates`: Special format files
|
||||
|
||||
### 2.2 File Header Levels
|
||||
|
||||
- **Section files** (`X.X_*.md`): First header must be level 2 (##)
|
||||
- **README.md**: First header must be level 1 (#)
|
||||
- **summary.md**: First header must be level 2 (##)
|
||||
|
||||
### 2.2 No English Parentheses in Headers
|
||||
|
||||
- **Rule**: Headers should not contain English explanations in parentheses.
|
||||
- Incorrect: `### 工具使用 (Tool Use)`
|
||||
- Correct: `### 工具使用`
|
||||
|
||||
### 2.3 Single Child Headers
|
||||
|
||||
- **Rule**: A header level should have 0 or at least 2 children, avoid exactly 1 child.
|
||||
- Incorrect: H2 with only one H3 child
|
||||
- Correct: H2 with 0, 2, or more H3 children
|
||||
|
||||
### 2.5 Bridge Text
|
||||
|
||||
- **Rule**: When a header has sub-headers, it MUST be followed by introductory text before the first sub-header.
|
||||
- **Purpose**: To guide the reader and explain what the section covers.
|
||||
- **Quality**: The introductory text must mention the sub-section topics, not just generic phrases.
|
||||
|
||||
```markdown
|
||||
# ❌ 错误
|
||||
|
||||
### 2.1.1 子章节
|
||||
|
||||
# ❌ 错误
|
||||
|
||||
本节包括以下几个方面。
|
||||
|
||||
### 2.1.1 子章节A
|
||||
|
||||
# ✅ 正确
|
||||
|
||||
本节介绍 XXX 的相关内容,包括子章节A和子章节B两个方面。
|
||||
|
||||
### 2.1.1 子章节A
|
||||
```
|
||||
|
||||
## 3. Content Rules
|
||||
|
||||
### 3.1 Figure Captions
|
||||
|
||||
- **Format**: `图 X-Y:Title`
|
||||
- **Position**: Below the image.
|
||||
- **Numbering**: Chapter-Sequence (e.g., `图 7-1` for the first figure in Chapter 7).
|
||||
- **Example**: `图 7-1:成对比较法评估流程`
|
||||
|
||||
### 3.2 Content Introduction
|
||||
|
||||
- **Rule**: All figures and code blocks must have introductory text before them.
|
||||
- **Incorrect**: Header followed directly by image or code block.
|
||||
- **Correct**: Header → Introductory text → Image/Code block.
|
||||
|
||||
```markdown
|
||||
### Example Section
|
||||
|
||||
Below is a code example demonstrating the concept:
|
||||
|
||||
\`\`\`python
|
||||
print("Hello")
|
||||
\`\`\`
|
||||
```
|
||||
|
||||
## 4. Validation
|
||||
|
||||
Run `python check_rules.py` to validate all markdown files against these rules.
|
||||
|
||||
Available options:
|
||||
- `--verbose` or `-v`: Show all scanned files
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -16,5 +16,4 @@ docker-compose.override.yml
|
||||
.obsidian/
|
||||
.vscode/
|
||||
|
||||
.agent/combine.py
|
||||
combine.py
|
||||
.agent/
|
||||
|
||||
@@ -14,27 +14,32 @@ Docker 做的事情类似:无论你的应用是用 Python、Java、Node.js 还
|
||||
|
||||
笔者认为,Docker 解决的是软件开发中最古老的问题之一:**"在我机器上明明能跑啊!"**
|
||||
|
||||
```
|
||||
开发环境 生产环境
|
||||
┌─────────────────┐ ┌─────────────────┐
|
||||
│ Python 3.14 │ ≠ │ Python 3.11 │
|
||||
│ Ubuntu 24.04 │ │ Ubuntu 22.04 │
|
||||
│ 特定版本的库 │ │ 不同版本的库 │
|
||||
└─────────────────┘ └─────────────────┘
|
||||
↓ ↓
|
||||
运行正常 运行失败!
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph Dev ["开发环境"]
|
||||
direction TB
|
||||
A["Python 3.14<br/>Ubuntu 24.04<br/>特定版本的库"] --> B["运行正常"]
|
||||
end
|
||||
subgraph Prod ["生产环境"]
|
||||
direction TB
|
||||
C["Python 3.11<br/>Ubuntu 22.04<br/>不同版本的库"] --> D["运行失败!"]
|
||||
end
|
||||
A -. "≠" .-> C
|
||||
```
|
||||
|
||||
有了 Docker:
|
||||
|
||||
```
|
||||
开发环境 生产环境
|
||||
┌─────────────────┐ ┌─────────────────┐
|
||||
│ Docker 镜像 │ = │ 同一个镜像 │
|
||||
│ (包含所有依赖) │ │ (完全一致) │
|
||||
└─────────────────┘ └─────────────────┘
|
||||
↓ ↓
|
||||
运行正常 运行正常!
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph Dev ["开发环境"]
|
||||
direction TB
|
||||
A["Docker 镜像<br/>(包含所有依赖)"] --> B["运行正常"]
|
||||
end
|
||||
subgraph Prod ["生产环境"]
|
||||
direction TB
|
||||
C["同一个镜像<br/>(完全一致)"] --> D["运行正常!"]
|
||||
end
|
||||
A === "=" === C
|
||||
```
|
||||
|
||||
### Docker vs 虚拟机
|
||||
@@ -79,13 +84,15 @@ Docker 使用 [Go 语言](https://golang.google.cn/) 开发,基于 Linux 内
|
||||
|
||||
Docker 的底层实现经历了多次演进:
|
||||
|
||||
```
|
||||
2013 2014 2015 现在
|
||||
│ │ │ │
|
||||
▼ ▼ ▼ ▼
|
||||
LXC ──→ libcontainer ──→ runC ──→ containerd + runC
|
||||
│
|
||||
└── OCI 标准化
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph Timeline
|
||||
direction LR
|
||||
LXC["LXC<br/>(2013)"] --> libcontainer["libcontainer<br/>(2014)"]
|
||||
libcontainer --> runC["runC<br/>(2015)"]
|
||||
runC --> containerd["containerd + runC<br/>(现在)"]
|
||||
runC --> OCI["OCI<br/>标准化"]
|
||||
end
|
||||
```
|
||||
|
||||
- **LXC**(2013):Docker 最初基于 Linux Containers
|
||||
|
||||
@@ -57,16 +57,17 @@ Docker 的出现为上述问题提供了完美的解决方案。它通过"一次
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```
|
||||
开发环境 测试环境 生产环境
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
┌─────────┐ ┌─────────┐ ┌─────────┐
|
||||
│ Docker │ = │ Docker │ = │ Docker │
|
||||
│ 镜像 │ │ 镜像 │ │ 镜像 │
|
||||
└─────────┘ └─────────┘ └─────────┘
|
||||
↓ ↓ ↓
|
||||
完全一致 完全一致 完全一致
|
||||
```mermaid
|
||||
flowchart TD
|
||||
dev["开发环境"] --> img1["Docker 镜像"]
|
||||
test["测试环境"] --> img2["Docker 镜像"]
|
||||
prod["生产环境"] --> img3["Docker 镜像"]
|
||||
|
||||
img1 === img2 === img3
|
||||
|
||||
img1 --> res1["完全一致"]
|
||||
img2 --> res2["完全一致"]
|
||||
img3 --> res3["完全一致"]
|
||||
```
|
||||
|
||||
### Docker 的核心优势
|
||||
@@ -112,40 +113,42 @@ $ docker compose up
|
||||
|
||||
Docker 容器共享宿主机内核,无需为每个应用运行完整的操作系统。
|
||||
|
||||
```
|
||||
传统虚拟机方案:
|
||||
┌────────────────────────────────────────────────┐
|
||||
│ 物理服务器 (64GB 内存) │
|
||||
├──────────────┬───────────────┬─────────────────┤
|
||||
│ VM1 │ VM2 │ VM3 │
|
||||
│ 8GB 内存 │ 8GB 内存 │ 8GB 内存 │
|
||||
│ (含 OS 2GB) │ (含 OS 2GB) │ (含 OS 2GB) │
|
||||
│ 应用 1 │ 应用 2 │ 应用 3 │
|
||||
└──────────────┴───────────────┴─────────────────┘
|
||||
实际可用于应用:3 × 6GB = 18GB ❌
|
||||
```mermaid
|
||||
flowchart TD
|
||||
subgraph VM ["传统虚拟机方案 (实际可用于应用: 18GB) ❌"]
|
||||
direction TB
|
||||
Server1["物理服务器 (64GB 内存)"]
|
||||
subgraph VMs [" "]
|
||||
direction LR
|
||||
VM1["VM1<br/>8GB 内存 (含 OS 2GB)<br/>应用 1"]
|
||||
VM2["VM2<br/>8GB 内存 (含 OS 2GB)<br/>应用 2"]
|
||||
VM3["VM3<br/>8GB 内存 (含 OS 2GB)<br/>应用 3"]
|
||||
end
|
||||
Server1 --- VMs
|
||||
end
|
||||
|
||||
Docker 方案:
|
||||
┌────────────────────────────────────────────────┐
|
||||
│ 物理服务器 (64GB 内存) │
|
||||
│ 宿主机 OS + Docker (约 4GB) │
|
||||
├──────────────┬───────────────┬─────────────────┤
|
||||
│ 容器 1 │ 容器 2 │ 容器 3 │
|
||||
│ 应用 1 │ 应用 2 │ 应用 3 │
|
||||
│ (按需分配) │ (按需分配) │ (按需分配) │
|
||||
└──────────────┴───────────────┴─────────────────┘
|
||||
实际可用于应用:约 60GB ✅
|
||||
subgraph Docker ["Docker 方案 (实际可用于应用: 约 60GB) ✅"]
|
||||
direction TB
|
||||
Server2["物理服务器 (64GB 内存)<br/>宿主机 OS + Docker (约 4GB)"]
|
||||
subgraph Containers [" "]
|
||||
direction LR
|
||||
C1["容器 1<br/>应用 1<br/>(按需分配)"]
|
||||
C2["容器 2<br/>应用 2<br/>(按需分配)"]
|
||||
C3["容器 3<br/>应用 3<br/>(按需分配)"]
|
||||
end
|
||||
Server2 --- Containers
|
||||
end
|
||||
```
|
||||
|
||||
#### 4. 持续交付和部署
|
||||
|
||||
Docker 完美契合 DevOps 的工作流程:
|
||||
|
||||
```
|
||||
代码提交 ──→ 自动构建镜像 ──→ 自动测试 ──→ 自动部署
|
||||
│ │ │ │
|
||||
▼ ▼ ▼ ▼
|
||||
Git docker 容器内 容器滚动
|
||||
push build 运行测试 更新
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["代码提交<br/>(Git push)"] --> B["自动构建镜像<br/>(docker build)"]
|
||||
B --> C["自动测试<br/>(容器内运行测试)"]
|
||||
C --> D["自动部署<br/>(容器滚动更新)"]
|
||||
```
|
||||
|
||||
使用 [Dockerfile](../04_image/4.5_build.md) 定义镜像构建过程,使得:
|
||||
@@ -172,17 +175,25 @@ Docker 可以在几乎任何平台上运行:
|
||||
- **独立部署**:更新一个服务不影响其他服务
|
||||
- **技术多样**:不同服务可以用不同语言和框架
|
||||
|
||||
```
|
||||
┌───────────────────────────────────────────────────┐
|
||||
│ 微服务架构示例 │
|
||||
├─────────────┬─────────────┬───────────────────────┤
|
||||
│ 前端容器 │ API 容器 │ Worker 容器 │
|
||||
│ (Node.js) │ (Python) │ (Go) │
|
||||
├─────────────┴─────────────┴───────────────────────┤
|
||||
│ Redis 容器 │
|
||||
├───────────────────────────────────────────────────┤
|
||||
│ PostgreSQL 容器 │
|
||||
└───────────────────────────────────────────────────┘
|
||||
```mermaid
|
||||
flowchart TD
|
||||
subgraph Microservices ["微服务架构示例"]
|
||||
direction TB
|
||||
subgraph AppLayer ["应用层"]
|
||||
direction LR
|
||||
Frontend["前端容器<br/>(Node.js)"]
|
||||
API["API 容器<br/>(Python)"]
|
||||
Worker["Worker 容器<br/>(Go)"]
|
||||
end
|
||||
Redis["Redis 容器"]
|
||||
DB["PostgreSQL 容器"]
|
||||
|
||||
Frontend --> API
|
||||
API --> Redis
|
||||
API --> DB
|
||||
Worker --> Redis
|
||||
Worker --> DB
|
||||
end
|
||||
```
|
||||
|
||||
### Docker 不适合的场景
|
||||
|
||||
@@ -10,17 +10,19 @@ Docker 镜像作为容器运行的基石,其设计理念和实现机制至关
|
||||
|
||||
我们都知道,操作系统分为**内核**和**用户空间**:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 用户空间 │
|
||||
│ ┌─────────────────────────────────────────────────────┐ │
|
||||
│ │ 应用程序、工具、库、配置文件... │ │
|
||||
│ │ (这部分被打包成 Docker 镜像) │ │
|
||||
│ └─────────────────────────────────────────────────────┘ │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ Linux 内核 │
|
||||
│ (容器共享宿主机的内核) │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```mermaid
|
||||
flowchart TD
|
||||
subgraph UserSpace ["用户空间"]
|
||||
direction TB
|
||||
App["应用程序、工具、库、配置文件...<br/>(这部分被打包成 Docker 镜像)"]
|
||||
end
|
||||
|
||||
subgraph KernelSpace ["Linux 内核"]
|
||||
direction TB
|
||||
Kernel["容器共享宿主机的内核"]
|
||||
end
|
||||
|
||||
UserSpace --- KernelSpace
|
||||
```
|
||||
|
||||
对于 Linux 而言,内核启动后会挂载 `root` 文件系统来提供用户空间支持。**Docker 镜像**本质上就是一个 `root` 文件系统。
|
||||
@@ -52,28 +54,29 @@ Docker 镜像是一个特殊的文件系统,包含:
|
||||
|
||||
假设你有三个应用,都基于 Ubuntu 运行:
|
||||
|
||||
```
|
||||
传统方式(不分层):
|
||||
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
||||
│ App A │ │ App B │ │ App C │
|
||||
│ Ubuntu │ │ Ubuntu │ │ Ubuntu │
|
||||
│ 500MB │ │ 500MB │ │ 500MB │
|
||||
└─────────────┘ └─────────────┘ └─────────────┘
|
||||
总计:1.5GB ❌
|
||||
```mermaid
|
||||
flowchart TD
|
||||
subgraph Traditional ["传统方式(不分层)总计: 1.5GB ❌"]
|
||||
direction LR
|
||||
AppA_Trad["App A<br/>Ubuntu 500MB"]
|
||||
AppB_Trad["App B<br/>Ubuntu 500MB"]
|
||||
AppC_Trad["App C<br/>Ubuntu 500MB"]
|
||||
end
|
||||
|
||||
Docker 分层方式:
|
||||
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
||||
│ App A │ │ App B │ │ App C │
|
||||
│ 50MB │ │ 30MB │ │ 40MB │
|
||||
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
|
||||
│ │ │
|
||||
└────────────────┼────────────────┘
|
||||
▼
|
||||
┌─────────────────┐
|
||||
│ Ubuntu │
|
||||
│ (共享)500MB │
|
||||
└─────────────────┘
|
||||
总计:620MB ✅
|
||||
subgraph DockerLayered ["Docker 分层方式 总计: 620MB ✅"]
|
||||
direction TB
|
||||
subgraph Apps ["应用层"]
|
||||
direction LR
|
||||
AppA["App A 50MB"]
|
||||
AppB["App B 30MB"]
|
||||
AppC["App C 40MB"]
|
||||
end
|
||||
Ubuntu["Ubuntu<br/>(共享)500MB"]
|
||||
|
||||
AppA --> Ubuntu
|
||||
AppB --> Ubuntu
|
||||
AppC --> Ubuntu
|
||||
end
|
||||
```
|
||||
|
||||
#### 分层是如何工作的?
|
||||
@@ -89,16 +92,14 @@ COPY app.conf /etc/nginx/ # 第 4 层:复制配置文件
|
||||
|
||||
构建后的镜像结构:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ 第 4 层: COPY app.conf (只读) │ ← 最新添加的层
|
||||
├─────────────────────────────────────┤
|
||||
│ 第 3 层: nginx 安装文件 (只读) │
|
||||
├─────────────────────────────────────┤
|
||||
│ 第 2 层: apt 缓存更新 (只读) │
|
||||
├─────────────────────────────────────┤
|
||||
│ 第 1 层: Ubuntu 基础系统 (只读) │ ← 基础镜像层
|
||||
└─────────────────────────────────────┘
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Layer4["第 4 层: COPY app.conf (只读)<br/>← 最新添加的层"]
|
||||
Layer3["第 3 层: nginx 安装文件 (只读)"]
|
||||
Layer2["第 2 层: apt 缓存更新 (只读)"]
|
||||
Layer1["第 1 层: Ubuntu 基础系统 (只读)<br/>← 基础镜像层"]
|
||||
|
||||
Layer4 --> Layer3 --> Layer2 --> Layer1
|
||||
```
|
||||
|
||||
每一层的特点:
|
||||
|
||||
@@ -14,24 +14,17 @@
|
||||
|
||||
> 💡 **笔者认为,理解这一点是理解 Docker 的关键****容器的本质是一个特殊的进程。**
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 普通进程 │
|
||||
│ • 与其他进程共享系统资源 │
|
||||
│ • 可以看到其他进程 │
|
||||
│ • 共享网络和文件系统 │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```mermaid
|
||||
flowchart TD
|
||||
subgraph NormalProcess ["普通进程"]
|
||||
direction TB
|
||||
N1["• 与其他进程共享系统资源<br/>• 可以看到其他进程<br/>• 共享网络和文件系统"]
|
||||
end
|
||||
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 容器进程 │
|
||||
│ ┌───────────────────────────────────────────────────────┐ │
|
||||
│ │ • 有自己的进程空间(看不到宿主机上的其他进程) │ │
|
||||
│ │ • 有自己的网络(独立 IP、端口) │ │
|
||||
│ │ • 有自己的文件系统(独立的 root 目录) │ │
|
||||
│ │ • 有自己的用户(容器内的 root ≠ 宿主机的 root) │ │
|
||||
│ └───────────────────────────────────────────────────────┘ │
|
||||
│ 但仍然运行在宿主机的内核上 │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
subgraph ContainerProcess ["容器进程 (运行在宿主机内核上)"]
|
||||
direction TB
|
||||
C1["• 有自己的进程空间(看不到宿主机上的其他进程)<br/>• 有自己的网络(独立 IP、端口)<br/>• 有自己的文件系统(独立的 root 目录)<br/>• 有自己的用户(容器内的 root ≠ 宿主机的 root)"]
|
||||
end
|
||||
```
|
||||
|
||||
这种隔离是通过 Linux 内核的 **Namespace** 技术实现的。
|
||||
@@ -40,21 +33,35 @@
|
||||
|
||||
很多初学者会混淆容器和虚拟机。笔者用一张图来说明:
|
||||
|
||||
```
|
||||
虚拟机 容器
|
||||
┌───────────────────────┐ ┌───────────────────────┐
|
||||
│ App A │ App B │ │ App A │ App B │
|
||||
├────────────┼──────────┤ ├────────────┼──────────┤
|
||||
│ Guest OS │ Guest OS │ │ Container │ Container│
|
||||
│ (完整系统) │ (完整系统)│ │ (仅应用) │ (仅应用) │
|
||||
├────────────┴──────────┤ └────────────┴──────────┤
|
||||
│ Hypervisor │ │ Docker Engine │
|
||||
├───────────────────────┤ ├───────────────────────┤
|
||||
│ Host OS │ │ Host OS │
|
||||
├───────────────────────┤ ├───────────────────────┤
|
||||
│ Hardware │ │ Hardware │
|
||||
└───────────────────────┘ └───────────────────────┘
|
||||
每个 VM 运行完整 OS 所有容器共享宿主机内核
|
||||
```mermaid
|
||||
flowchart TD
|
||||
subgraph VM ["虚拟机 (每个 VM 运行完整 OS)"]
|
||||
direction TB
|
||||
subgraph VMApp ["应用层"]
|
||||
VA[App A] & VB[App B]
|
||||
end
|
||||
subgraph VMGuest ["Guest OS (完整系统)"]
|
||||
G1[Guest OS] & G2[Guest OS]
|
||||
end
|
||||
V[Hypervisor]
|
||||
VMH[Host OS]
|
||||
VMHW[Hardware]
|
||||
VMApp --> VMGuest --> V --> VMH --> VMHW
|
||||
end
|
||||
|
||||
subgraph Container ["容器 (所有容器共享宿主机内核)"]
|
||||
direction TB
|
||||
subgraph CApp ["应用层"]
|
||||
CA[App A] & CB[App B]
|
||||
end
|
||||
subgraph CContainer ["隔离层"]
|
||||
CC1[Container 仅应用] & CC2[Container 仅应用]
|
||||
end
|
||||
CE[Docker Engine]
|
||||
CH[Host OS]
|
||||
CHW[Hardware]
|
||||
CApp --> CContainer --> CE --> CH --> CHW
|
||||
end
|
||||
```
|
||||
|
||||
| 特性 | 容器 | 虚拟机 |
|
||||
@@ -73,19 +80,15 @@
|
||||
|
||||
当容器运行时,Docker 会在镜像的只读层之上创建一个**可写层**(容器存储层):
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ 容器存储层(可读写) │ ← 容器运行时创建
|
||||
│ 运行时产生的文件变化记录在这里 │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ 镜像第 N 层(只读) │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ 镜像第 N-1 层(只读) │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ ... │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ 镜像第 1 层(只读) │ ← 基础镜像层
|
||||
└─────────────────────────────────────────────┘
|
||||
```mermaid
|
||||
flowchart TD
|
||||
ContainerLayer["容器存储层(可读写)<br/>容器运行时创建,记录文件变化"]
|
||||
ImageLayerN["镜像第 N 层(只读)"]
|
||||
ImageLayerN1["镜像第 N-1 层(只读)"]
|
||||
Dots["..."]
|
||||
ImageLayer1["镜像第 1 层(只读)<br/>基础镜像层"]
|
||||
|
||||
ContainerLayer --> ImageLayerN --> ImageLayerN1 --> Dots --> ImageLayer1
|
||||
```
|
||||
|
||||
#### Copy-on-Write(写时复制)
|
||||
@@ -143,35 +146,26 @@ $ docker run -v /host/path:/container/path nginx
|
||||
|
||||
### 容器的生命周期
|
||||
|
||||
掌握容器的生命周期对于管理和调试 Docker 应用非常重要。下图展示了容器从创建到删除的完整状态流转。
|
||||
掌握容器的生命周期对于管理和调试 Docker 应用非常重要。如图 2-1 所示,容器会经历从创建到删除的完整状态流转。
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────┐
|
||||
│ 容器生命周期 │
|
||||
└──────────────────────────────────────────────────┘
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
direction TB
|
||||
[*] --> Created : docker create
|
||||
Created --> Running : docker start
|
||||
Running --> Stopped : docker stop
|
||||
Running --> Paused : docker pause
|
||||
Paused --> Running : docker unpause
|
||||
|
||||
docker create docker start docker stop
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
┌─────────┐ ┌─────────┐ ┌─────────┐
|
||||
│ Created │───────────▶│ Running │───────────▶│ Stopped │
|
||||
└─────────┘ └─────────┘ └─────────┘
|
||||
│ │ │
|
||||
│ │ docker pause │
|
||||
│ ▼ │
|
||||
│ ┌─────────┐ │
|
||||
│ │ Paused │ │
|
||||
│ └─────────┘ │
|
||||
│ │ │
|
||||
│ docker rm │ docker rm │
|
||||
└───────────────────────┴──────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌──────────┐
|
||||
│ Deleted │
|
||||
└──────────┘
|
||||
Created --> Deleted : docker rm
|
||||
Stopped --> Deleted : docker rm
|
||||
Paused --> Deleted : docker rm
|
||||
|
||||
Deleted --> [*]
|
||||
```
|
||||
|
||||
图 2-1 容器生命周期状态流转图
|
||||
|
||||
#### 常用生命周期命令
|
||||
|
||||
运行以下命令:
|
||||
|
||||
@@ -14,7 +14,7 @@ Docker Registry 是镜像分发和管理的核心组件。本节将介绍 Regist
|
||||
|
||||
#### Registry、仓库、标签的关系
|
||||
|
||||
Docker Registry 中可以包含多个 Repository,每个 Repository 可以包含多个 Tag。下图清晰地展示了它们之间的层级关系。
|
||||
Docker Registry 中可以包含多个 Repository,每个 Repository 可以包含多个 Tag。如图 2-2 所示,它们之间具有清晰的层级关系。
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
@@ -37,6 +37,8 @@ Docker Registry 中可以包含多个 Repository,每个 Repository 可以包
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
图 2-2 Registry、Repository 与 Tag 的层级关系
|
||||
|
||||
| 概念 | 说明 | 示例 |
|
||||
|------|------|------|
|
||||
| **Registry** | 存储镜像的服务 | Docker Hub、ghcr.io |
|
||||
@@ -176,7 +178,7 @@ $ docker pull localhost:5000/myapp:v1.0
|
||||
|
||||
#### 完整工作流程
|
||||
|
||||
下图展示了从开发环境构建镜像,推送到 Registry,再到生产环境拉取运行的完整流程。
|
||||
如图 2-3 所示,镜像从开发环境构建后推送到 Registry,再由生产环境拉取并运行。
|
||||
|
||||
```
|
||||
开发者机器 Registry 生产服务器
|
||||
@@ -194,6 +196,8 @@ $ docker pull localhost:5000/myapp:v1.0
|
||||
│ │ 运行容器 │
|
||||
```
|
||||
|
||||
图 2-3 镜像构建、推送与拉取流程
|
||||
|
||||
#### 常用命令
|
||||
|
||||
运行以下命令:
|
||||
@@ -244,16 +248,23 @@ someuser/myapp # ⚠️ 需要评估
|
||||
|
||||
#### 镜像签名
|
||||
|
||||
使用 Docker Content Trust (DCT) 验证镜像来源:
|
||||
当前更推荐使用 Sigstore / Notation 体系进行镜像签名与验证。`Docker Content Trust (DCT)` 已进入退场阶段,不建议作为新项目主方案。
|
||||
|
||||
> 注意:Cosign 默认会把签名写回镜像所在仓库,请使用你有推送权限的镜像地址。
|
||||
|
||||
```bash
|
||||
## 启用镜像签名验证
|
||||
## 准备一个你有写权限的镜像地址
|
||||
$ export IMAGE=<你的仓库名>/nginx:1.27
|
||||
$ docker pull nginx:1.27
|
||||
$ docker tag nginx:1.27 $IMAGE
|
||||
$ docker push $IMAGE
|
||||
|
||||
$ export DOCKER_CONTENT_TRUST=1
|
||||
## 生成签名密钥(会生成 cosign.key / cosign.pub)
|
||||
$ cosign generate-key-pair
|
||||
|
||||
## 此后的 pull/push 会验证签名
|
||||
|
||||
$ docker pull nginx:latest
|
||||
## 使用 Cosign 签名与验证
|
||||
$ cosign sign --key cosign.key $IMAGE
|
||||
$ cosign verify --key cosign.pub $IMAGE
|
||||
```
|
||||
|
||||
#### 漏洞扫描
|
||||
|
||||
@@ -13,8 +13,8 @@ Ubuntu 是 Docker 最常用的运行环境之一。本节将介绍如何在 Ubun
|
||||
Docker 支持诸多版本的 [Ubuntu](https://ubuntu.com/server) 操作系统。但是较旧的版本上将不会有 Docker 新版本的持续更新,以截至 2026 年初的几个 Ubuntu LTS(Long Term Support,长期支持)版本为例:
|
||||
|
||||
|
||||
* Ubuntu Noble 24.04 (LTS),Docker v30.x
|
||||
* Ubuntu Jammy 22.04 (LTS), Docker v30.x
|
||||
* Ubuntu Noble 24.04 (LTS),Docker v29.x
|
||||
* Ubuntu Jammy 22.04 (LTS), Docker v29.x
|
||||
|
||||
> **注意**:Ubuntu 20.04 LTS 已于 2025 年结束标准支持,不再推荐用于新部署。
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ $ sudo dnf install docker-ce docker-ce-cli containerd.io
|
||||
|
||||
### CentOS8 额外设置
|
||||
|
||||
由于 CentOS8 防火墙使用了 `nftables`,但 Docker 尚未支持 `nftables`, 我们可以使用如下设置使用 `iptables`:
|
||||
CentOS 8/Stream 默认使用 `nftables`。Docker 在新版本中已提供 `nftables` 实验支持,但在一些环境下仍可能遇到兼容性问题。若你遇到容器网络异常,可以先切换回 `iptables` 后端:
|
||||
|
||||
更改 `/etc/firewalld/firewalld.conf`
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
> `hub.atomgit.com` 仅包含部分官方镜像,可以满足初学者的使用。
|
||||
|
||||
### Ubuntu 16.04+、Debian 8+、CentOS 7+
|
||||
### Ubuntu 22.04+、Debian 12+、Rocky/Alma/CentOS Stream 9+
|
||||
|
||||
目前主流 Linux 发行版均已使用 [systemd](https://systemd.io/) 进行服务管理,这里介绍如何在使用 systemd 的 Linux 发行版中配置镜像加速器。
|
||||
|
||||
@@ -49,9 +49,9 @@ $ sudo systemctl daemon-reload
|
||||
$ sudo systemctl restart docker
|
||||
```
|
||||
|
||||
### Windows 10
|
||||
### Windows 10/11
|
||||
|
||||
对于使用 `Windows 10` 的用户,在任务栏托盘 Docker 图标内右键菜单选择 `Change settings`,打开配置窗口后在左侧导航菜单选择 `Docker Engine`,在右侧像下边一样编辑 json 文件,之后点击 `Apply & Restart` 保存后 Docker 就会重启并应用配置的镜像地址了。
|
||||
对于使用 `Windows 10/11` 的用户,在任务栏托盘 Docker 图标内右键菜单选择 `Change settings`,打开配置窗口后在左侧导航菜单选择 `Docker Engine`,在右侧像下边一样编辑 json 文件,之后点击 `Apply & Restart` 保存后 Docker 就会重启并应用配置的镜像地址了。
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -82,18 +82,20 @@ Registry Mirrors:
|
||||
https://hub.atomgit.com/
|
||||
```
|
||||
|
||||
### `k8s.gcr.io` 镜像
|
||||
### Kubernetes 官方镜像地址迁移
|
||||
|
||||
可以登录 [阿里云 容器镜像服务](https://www.aliyun.com/product/acr?source=5176.11533457&userCode=8lx5zmtu&type=copy) **镜像中心**->**镜像搜索** 查找。
|
||||
|
||||
例如 `k8s.gcr.io/coredns:1.6.7` 镜像可以用 `registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:1.6.7` 代替。
|
||||
Kubernetes 社区已将官方镜像地址从 `k8s.gcr.io` 迁移到 `registry.k8s.io`。建议优先使用新地址。
|
||||
|
||||
一般情况下有如下对应关系:
|
||||
|
||||
```bash
|
||||
## 旧地址(已迁移)
|
||||
## $ docker pull k8s.gcr.io/xxx
|
||||
|
||||
$ docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/xxx
|
||||
## 新地址(推荐)
|
||||
$ docker pull registry.k8s.io/xxx
|
||||
```
|
||||
|
||||
### 不再提供服务的镜像
|
||||
@@ -112,6 +114,4 @@ $ docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/xxx
|
||||
|
||||
某些云服务商提供了 **仅供内部** 访问的镜像服务,当您的 Docker 运行在云平台时可以选择它们。
|
||||
|
||||
* [Azure 中国镜像 `https://dockerhub.azk8s.cn`](https://github.com/Azure/container-service-for-azure-china/blob/master/aks/README.md#22-container-registry-proxy)
|
||||
|
||||
* [腾讯云 `https://mirror.ccs.tencentyun.com`](https://cloud.tencent.com/act/cps/redirect?redirect=10058&cps_key=3a5255852d5db99dcd5da4c72f05df61)
|
||||
|
||||
@@ -28,17 +28,11 @@ $ docker stop 容器名或ID
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```
|
||||
docker stop mycontainer
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ 1. 发送 SIGTERM 信号给容器主进程(PID 1) │
|
||||
│ ↓ │
|
||||
│ 2. 等待容器优雅退出(默认 10 秒) │
|
||||
│ ↓ │
|
||||
│ 3. 如果超时仍未退出,发送 SIGKILL 强制终止 │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```mermaid
|
||||
flowchart TD
|
||||
cmd["docker stop mycontainer"] --> A["1. 发送 SIGTERM 信号给容器主进程 (PID 1)"]
|
||||
A --> B["2. 等待容器优雅退出 (默认 10 秒)"]
|
||||
B --> C["3. 如果超时仍未退出,发送 SIGKILL 强制终止"]
|
||||
```
|
||||
|
||||
#### 自定义超时时间
|
||||
@@ -178,39 +172,20 @@ $ docker restart -t 30 容器名
|
||||
|
||||
具体内容如下:
|
||||
|
||||
```
|
||||
docker create
|
||||
│
|
||||
▼
|
||||
┌──────────┐
|
||||
┌────────│ Created │────────┐
|
||||
│ └──────────┘ │
|
||||
│ │ │
|
||||
│ │ docker start│
|
||||
│ ▼ │
|
||||
│ ┌──────────┐ │
|
||||
│ ┌────│ Running │────┐ │
|
||||
│ │ └──────────┘ │ │
|
||||
│ │ │ │ │
|
||||
│ │ docker │ docker │ │
|
||||
│ │ pause │ stop │ │
|
||||
│ ▼ │ │ │
|
||||
│ ┌──────┐ │ │ │
|
||||
│ │Paused│ │ │ │
|
||||
│ └──────┘ │ │ │
|
||||
│ │ │ │ │
|
||||
│ │ docker │ │ │
|
||||
│ │ unpause │ │ │
|
||||
│ ▼ ▼ │ │
|
||||
│ └──────►┌──────────┐◄┘ │
|
||||
│ │ Stopped │ │
|
||||
│ └──────────┘ │
|
||||
│ │ │
|
||||
│ │ docker rm │
|
||||
│ ▼ │
|
||||
│ ┌──────────┐ │
|
||||
└──────────►│ Deleted │◄────┘
|
||||
└──────────┘
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
direction TB
|
||||
[*] --> Created : docker create
|
||||
Created --> Running : docker start
|
||||
Running --> Stopped : docker stop
|
||||
Running --> Paused : docker pause
|
||||
Paused --> Running : docker unpause
|
||||
|
||||
Created --> Deleted : docker rm
|
||||
Stopped --> Deleted : docker rm
|
||||
Paused --> Deleted : docker rm
|
||||
|
||||
Deleted --> [*]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
# 数据管理
|
||||
|
||||
数据管理 示意图如下:
|
||||
如图 8-1 所示,Docker 数据管理主要围绕三类挂载方式展开。
|
||||
|
||||

|
||||

|
||||
|
||||
图 8-1 Docker 数据挂载类型示意图
|
||||
|
||||
这一章介绍如何在 Docker 内部以及容器之间管理数据,在容器中管理数据主要有两种方式:
|
||||
|
||||
|
||||
@@ -159,7 +159,7 @@ $ ssh-add ~/.ssh/id_rsa
|
||||
$ docker build -t test --ssh default=$SSH_AUTH_SOCK .
|
||||
```
|
||||
|
||||
### docker compose build 使用 BuildKit
|
||||
### 使用 `docker compose build` 与 BuildKit
|
||||
|
||||
Docker Compose 同样支持 BuildKit,这使得多服务应用的构建更加高效。
|
||||
|
||||
|
||||
@@ -18,12 +18,12 @@ Linux 系统请使用以下介绍的方法安装。
|
||||
|
||||
> **提示**:版本更新较快,请访问上述链接获取最新版本号,替换下方命令中的版本号。
|
||||
|
||||
例如,在 Linux 64 位系统上直接下载对应的二进制包(以 v2.40.3 为例)。
|
||||
例如,在 Linux 64 位系统上直接下载对应的二进制包(以 v5.0.2 为例)。
|
||||
|
||||
```bash
|
||||
$ DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}
|
||||
$ mkdir -p $DOCKER_CONFIG/cli-plugins
|
||||
$ curl -SL https://github.com/docker/compose/releases/download/v2.40.3/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose
|
||||
$ curl -SL https://github.com/docker/compose/releases/download/v5.0.2/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose
|
||||
```
|
||||
|
||||
之后,执行
|
||||
@@ -38,7 +38,7 @@ $ chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose
|
||||
|
||||
```bash
|
||||
$ docker compose version
|
||||
Docker Compose version v2.40.3
|
||||
Docker Compose version v5.0.2
|
||||
```
|
||||
|
||||
### bash 补全命令
|
||||
@@ -46,7 +46,7 @@ Docker Compose version v2.40.3
|
||||
运行以下命令:
|
||||
|
||||
```bash
|
||||
$ curl -L https://raw.githubusercontent.com/docker/compose/v2.40.3/contrib/completion/bash/docker-compose | sudo tee /etc/bash_completion.d/docker-compose > /dev/null
|
||||
$ curl -L https://raw.githubusercontent.com/docker/compose/v5.0.2/contrib/completion/bash/docker-compose | sudo tee /etc/bash_completion.d/docker-compose > /dev/null
|
||||
```
|
||||
|
||||
### 卸载
|
||||
|
||||
@@ -84,7 +84,7 @@ command: echo "hello world"
|
||||
|
||||
### `configs`
|
||||
|
||||
仅用于 `Swarm mode`(已弃用,推荐使用 Kubernetes)。
|
||||
`configs` 来自 Compose Specification。它在 Swarm 中是原生对象;在本地 `docker compose` 模式下通常以文件挂载的形式实现,具体能力取决于 Compose 版本与运行平台。
|
||||
|
||||
### `cgroup_parent`
|
||||
|
||||
@@ -108,7 +108,7 @@ container_name: docker-web-container
|
||||
|
||||
### `deploy`
|
||||
|
||||
仅用于 `Swarm mode`(已弃用,推荐使用 Kubernetes)。
|
||||
`deploy` 用于描述副本数、更新策略、资源限制等部署参数。该字段在 Swarm 中支持最完整;在本地 `docker compose up` 场景下通常只有部分字段生效。
|
||||
|
||||
### `devices`
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
### 架构概览
|
||||
|
||||
在开始之前,让我们先理解我们要构建的架构:
|
||||
在开始之前,先看整体架构(如图 10-1 所示):
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
@@ -28,6 +28,8 @@
|
||||
(浏览器访问)
|
||||
```
|
||||
|
||||
图 10-1 Django + PostgreSQL 的 Compose 架构
|
||||
|
||||
**关键点**:
|
||||
- `web` 服务运行 Django 应用,对外暴露 8000 端口
|
||||
- `db` 服务运行 PostgreSQL 数据库,只在内部网络可访问
|
||||
@@ -44,7 +46,7 @@ $ mkdir django-docker && cd django-docker
|
||||
|
||||
我们需要创建三个文件:`Dockerfile`、`requirements.txt` 和 `compose.yaml`。
|
||||
|
||||
### Step 1: 创建 Dockerfile
|
||||
### 步骤 1:创建 Dockerfile
|
||||
|
||||
```docker
|
||||
FROM python:3.12-slim
|
||||
@@ -82,7 +84,7 @@ COPY . /code/
|
||||
|
||||
> 💡 **笔者建议**:总是将变化频率低的文件先复制,变化频率高的后复制。这样可以最大化利用 Docker 的构建缓存。
|
||||
|
||||
### Step 2: 创建 requirements.txt
|
||||
### 步骤 2:创建 requirements.txt
|
||||
|
||||
```txt
|
||||
Django>=5.0,<6.0
|
||||
@@ -98,9 +100,9 @@ gunicorn>=21.0,<22.0
|
||||
| `psycopg[binary]` | PostgreSQL 数据库驱动(推荐使用 psycopg 3) |
|
||||
| `gunicorn` | 生产环境 WSGI 服务器(可选,开发时可不用) |
|
||||
|
||||
### Step 3: 创建 compose.yaml
|
||||
### 步骤 3:创建 compose.yaml
|
||||
|
||||
Step 3: 创建 `compose.yaml` 配置如下:
|
||||
配置如下:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
@@ -182,7 +184,7 @@ web:
|
||||
| `depends_on` + `healthcheck` | 启动顺序 | 确保数据库就绪后 Django 才启动,避免连接错误 |
|
||||
| `environment` | 环境变量 | 推荐用环境变量管理配置,避免硬编码 |
|
||||
|
||||
### Step 4: 创建 Django 项目
|
||||
### 步骤 4:创建 Django 项目
|
||||
|
||||
运行以下命令创建新的 Django 项目:
|
||||
|
||||
@@ -214,7 +216,7 @@ django-docker/
|
||||
|
||||
> 💡 **Linux 用户注意**:如果遇到权限问题,执行 `sudo chown -R $USER:$USER .`
|
||||
|
||||
### Step 5: 配置数据库连接
|
||||
### 步骤 5:配置数据库连接
|
||||
|
||||
修改 `mysite/settings.py`,配置数据库连接:
|
||||
|
||||
@@ -241,7 +243,7 @@ ALLOWED_HOSTS = ['*']
|
||||
|
||||
在 Docker Compose 中,各服务通过服务名相互访问。Docker 内置的 DNS 会将 `db` 解析为 db 服务容器的 IP 地址。这是 Docker Compose 的核心功能之一。
|
||||
|
||||
### Step 6: 启动应用
|
||||
### 步骤 6:启动应用
|
||||
|
||||
运行以下命令:
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
### 架构概览
|
||||
|
||||
如图 10-2 所示,Rails 与 PostgreSQL 在同一 Compose 网络中协同工作。
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Docker Compose 网络 │
|
||||
@@ -25,6 +27,8 @@
|
||||
localhost:3000
|
||||
```
|
||||
|
||||
图 10-2 Rails + PostgreSQL 的 Compose 架构
|
||||
|
||||
### 准备工作
|
||||
|
||||
创建项目目录:
|
||||
@@ -35,7 +39,7 @@ $ mkdir rails-docker && cd rails-docker
|
||||
|
||||
需要创建三个文件:`Dockerfile`、`Gemfile` 和 `compose.yaml`。
|
||||
|
||||
### Step 1: 创建 Dockerfile
|
||||
### 步骤 1:创建 Dockerfile
|
||||
|
||||
```docker
|
||||
FROM ruby:3.2
|
||||
@@ -70,7 +74,7 @@ COPY . /myapp
|
||||
| `nodejs` | Rails Asset Pipeline 需要 |
|
||||
| 先复制 Gemfile | 只有依赖变化时才重新 `bundle install` |
|
||||
|
||||
### Step 2: 创建 Gemfile
|
||||
### 步骤 2:创建 Gemfile
|
||||
|
||||
创建一个初始的 `Gemfile`,稍后会被 `rails new` 覆盖:
|
||||
|
||||
@@ -85,9 +89,9 @@ gem 'rails', '~> 7.1'
|
||||
$ touch Gemfile.lock
|
||||
```
|
||||
|
||||
### Step 3: 创建 compose.yaml
|
||||
### 步骤 3:创建 compose.yaml
|
||||
|
||||
Step 3: 创建 `compose.yaml` 配置如下:
|
||||
配置如下:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
@@ -123,7 +127,7 @@ volumes:
|
||||
| `depends_on: db` | 确保数据库先启动 |
|
||||
| `DATABASE_URL` | Rails 12-factor 风格的数据库配置 |
|
||||
|
||||
### Step 4: 生成 Rails 项目
|
||||
### 步骤 4:生成 Rails 项目
|
||||
|
||||
使用 `docker compose run` 生成项目骨架:
|
||||
|
||||
@@ -149,7 +153,7 @@ compose.yaml bin db public
|
||||
|
||||
> ⚠️ **Linux 用户**:如遇权限问题,执行 `sudo chown -R $USER:$USER .`
|
||||
|
||||
### Step 5: 重新构建镜像
|
||||
### 步骤 5:重新构建镜像
|
||||
|
||||
由于生成了新的 Gemfile,需要重新构建镜像以安装完整依赖:
|
||||
|
||||
@@ -157,7 +161,7 @@ compose.yaml bin db public
|
||||
$ docker compose build
|
||||
```
|
||||
|
||||
### Step 6: 配置数据库连接
|
||||
### 步骤 6:配置数据库连接
|
||||
|
||||
修改 `config/database.yml`:
|
||||
|
||||
@@ -181,7 +185,7 @@ production:
|
||||
|
||||
> 💡 使用 `DATABASE_URL` 环境变量配置数据库,符合 12-factor 应用原则,便于在不同环境间切换。
|
||||
|
||||
### Step 7: 启动应用
|
||||
### 步骤 7:启动应用
|
||||
|
||||
运行以下命令:
|
||||
|
||||
@@ -201,7 +205,7 @@ web-1 | Puma starting in single mode...
|
||||
web-1 | * Listening on http://0.0.0.0:3000
|
||||
```
|
||||
|
||||
### Step 8: 创建数据库
|
||||
### 步骤 8:创建数据库
|
||||
|
||||
在另一个终端执行:
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
## 10.9 使用 compose 搭建 LNMP 环境
|
||||
## 10.9 使用 Compose 搭建 LNMP 环境
|
||||
|
||||
本项目的维护者 [khs1994](https://github.com/khs1994) 的开源项目 [khs1994-docker/lnmp](https://github.com/khs1994-docker/lnmp) 使用 Docker Compose 搭建了一套 LNMP 环境,各位开发者可以参考该项目在 Docker 或 Kubernetes 中运行 LNMP。
|
||||
|
||||
@@ -123,16 +123,23 @@ $ snyk container test nginx:latest
|
||||
|
||||
### 镜像签名验证
|
||||
|
||||
使用 Docker Content Trust (DCT) 验证镜像来源:
|
||||
当前更推荐使用 Sigstore / Notation 体系进行镜像签名。`Docker Content Trust (DCT)` 已进入退场阶段,不建议作为新项目主方案。
|
||||
|
||||
> 注意:Cosign 默认会把签名写回镜像所在仓库,请使用你有推送权限的镜像地址。
|
||||
|
||||
```bash
|
||||
## 启用镜像签名验证
|
||||
## 准备示例镜像
|
||||
$ export IMAGE=<你的仓库地址>/myimage:latest
|
||||
$ docker pull nginx:1.27
|
||||
$ docker tag nginx:1.27 $IMAGE
|
||||
$ docker push $IMAGE
|
||||
|
||||
$ export DOCKER_CONTENT_TRUST=1
|
||||
## 生成签名密钥(会生成 cosign.key / cosign.pub)
|
||||
$ cosign generate-key-pair
|
||||
|
||||
## 此后的 pull/push 会验证签名
|
||||
|
||||
$ docker pull myregistry/myimage:latest
|
||||
## Cosign: 签名与验证
|
||||
$ cosign sign --key cosign.key $IMAGE
|
||||
$ cosign verify --key cosign.pub $IMAGE
|
||||
```
|
||||
|
||||
---
|
||||
@@ -364,13 +371,18 @@ SBOM 类似于食品的配料表,列出了容器镜像中包含的所有软件
|
||||
|
||||
- **Cosign**: Sigstore 项目的一部分,用于签署和验证容器镜像。
|
||||
```bash
|
||||
## 签署镜像
|
||||
## 使用有写权限的仓库地址
|
||||
$ export IMAGE=<你的仓库地址>/myimage:tag
|
||||
$ docker pull nginx:1.27
|
||||
$ docker tag nginx:1.27 $IMAGE
|
||||
$ docker push $IMAGE
|
||||
|
||||
$ cosign sign --key cosign.key myimage:tag
|
||||
## 生成签名密钥(会生成 cosign.key / cosign.pub)
|
||||
$ cosign generate-key-pair
|
||||
|
||||
## 验证镜像
|
||||
|
||||
$ cosign verify --key cosign.pub myimage:tag
|
||||
## 签署与验证镜像
|
||||
$ cosign sign --key cosign.key $IMAGE
|
||||
$ cosign verify --key cosign.pub $IMAGE
|
||||
```
|
||||
|
||||
### 3. SLSA(Supply-chain Levels for Software Artifacts)
|
||||
@@ -388,7 +400,7 @@ $ cosign verify --key cosign.pub myimage:tag
|
||||
| 资源限制 | ⭐⭐⭐ | `-m`, `--cpus` |
|
||||
| 只读文件系统 | ⭐⭐ | `--read-only` |
|
||||
| 最小能力 | ⭐⭐ | `--cap-drop=all` |
|
||||
| 镜像签名 | ⭐⭐ | Docker Content Trust |
|
||||
| 镜像签名 | ⭐⭐ | `cosign` / Notation |
|
||||
|
||||
## 延伸阅读
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
## 简介
|
||||
|
||||
简介 示意图如下:
|
||||
如图 12-5 所示,etcd 项目使用该标识。
|
||||
|
||||

|
||||

|
||||
|
||||
图 12-5 etcd 项目标识
|
||||
|
||||
`etcd` 是 `CoreOS` 团队于 2013 年 6 月发起的开源项目,它的目标是构建一个高可用的分布式键值(`key-value`)数据库,基于 `Go` 语言实现。我们知道,在分布式系统中,各种服务的配置信息的管理分享,服务的发现是一个很基本同时也是很重要的问题。`CoreOS` 项目就希望基于 `etcd` 来解决这一问题。
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ kubectl [command]
|
||||
|
||||
## expose
|
||||
|
||||
将 replication controller service 或 pod 暴露为新的 kubernetes service
|
||||
将 replication controller service 或 pod 暴露为新的 Kubernetes service
|
||||
|
||||
## label
|
||||
|
||||
@@ -62,7 +62,7 @@ kubectl [command]
|
||||
|
||||
## config
|
||||
|
||||
修改 kubernetes 配置文件
|
||||
修改 Kubernetes 配置文件
|
||||
|
||||
## cluster-info
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
## 基本概念
|
||||
|
||||
基本概念 示意图如下:
|
||||
如图 12-2 所示,Kubernetes 由控制平面与工作节点构成。
|
||||
|
||||

|
||||

|
||||
|
||||
图 12-2 Kubernetes 基本概念示意图
|
||||
|
||||
* 节点(`Node`):一个节点是一个运行 Kubernetes 中的主机。
|
||||
* 容器组(`Pod`):一个 Pod 对应于由若干容器组成的一个容器组,同个组内的容器共享一个存储卷(volume)。
|
||||
|
||||
@@ -13,10 +13,12 @@
|
||||
|
||||
### 运行原理
|
||||
|
||||
下面这张图完整展示了 Kubernetes 的运行原理。
|
||||
如图 12-3 所示,该图完整展示了 Kubernetes 的运行原理。
|
||||
|
||||

|
||||
|
||||
图 12-3 Kubernetes 运行原理图
|
||||
|
||||
可见,Kubernetes 首先是一套分布式系统,由多个节点组成,节点分为两类:一类是属于管理平面的主节点/控制节点(Master Node);一类是属于运行平面的工作节点(Worker Node)。
|
||||
|
||||
显然,复杂的工作肯定都交给控制节点去做了,工作节点负责提供稳定的操作接口和能力抽象即可。
|
||||
@@ -49,3 +51,5 @@
|
||||
* kube-proxy 是一个简单的网络访问代理,同时也是一个 Load Balancer。它负责将访问到某个服务的请求具体分配给工作节点上的 Pod(同一类标签)。
|
||||
|
||||

|
||||
|
||||
图 12-4 kube-proxy 请求转发示意图
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
## Kubernetes 简介
|
||||
|
||||
Kubernetes 简介 示意图如下:
|
||||
如图 12-1 所示,Kubernetes 使用舵手图标作为项目标识。
|
||||
|
||||

|
||||

|
||||
|
||||
图 12-1 Kubernetes 项目标识
|
||||
|
||||
### 什么是 Kubernetes
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ spec:
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:1.24
|
||||
image: nginx:1.27
|
||||
ports:
|
||||
- containerPort: 80
|
||||
```
|
||||
@@ -77,7 +77,7 @@ kubectl get svc nginx-service
|
||||
|
||||
### 步骤 3:模拟滚动更新(Rolling Update)
|
||||
|
||||
修改 `nginx-deployment.yaml`,将镜像版本改为 `nginx:latest`。
|
||||
修改 `nginx-deployment.yaml`,将镜像版本改为 `nginx:1.27-alpine`。
|
||||
|
||||
```bash
|
||||
kubectl apply -f nginx-deployment.yaml
|
||||
|
||||
@@ -34,7 +34,7 @@ sudo k3s kubectl get nodes
|
||||
输出类似:
|
||||
```
|
||||
NAME STATUS ROLES AGE VERSION
|
||||
k3s-master Ready control-plane,master 1m v1.28.2+k3s1
|
||||
k3s-master Ready control-plane,master 1m v1.35.1+k3s1
|
||||
```
|
||||
|
||||
### 快速使用
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
## 使用 kubeadm 部署 kubernetes(使用 Docker)
|
||||
## 使用 kubeadm 部署 Kubernetes(使用 Docker)
|
||||
|
||||
`kubeadm` 提供了 `kubeadm init` 以及 `kubeadm join` 这两个命令作为快速创建 `kubernetes` 集群的最佳实践。
|
||||
`kubeadm` 提供了 `kubeadm init` 以及 `kubeadm join` 这两个命令,作为快速创建 `Kubernetes` 集群的最佳实践。
|
||||
|
||||
> ⚠️ **重要说明**:自 Kubernetes 1.24 起,内置 `dockershim` 已被移除,Kubernetes 默认不再直接使用 Docker Engine 作为容器运行时(CRI)。因此,**更推荐参考**同目录下的《[使用 kubeadm 部署 kubernetes(CRI 使用 containerd)](kubeadm.md)》。
|
||||
> ⚠️ **重要说明**:自 Kubernetes 1.24 起,内置 `dockershim` 已被移除,Kubernetes 默认不再直接使用 Docker Engine 作为容器运行时(CRI)。因此,**更推荐参考**同目录下的《[使用 kubeadm 部署 Kubernetes(CRI 使用 containerd)](kubeadm.md)》。
|
||||
>
|
||||
> 本文档主要用于历史环境/学习目的:如果你确实需要在较新版本中继续使用 Docker Engine,通常需要额外部署 `cri-dockerd` 并在 `kubeadm init/join` 中指定 `--cri-socket`。
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## 使用 kubeadm 部署 kubernetes(CRI 使用 containerd)
|
||||
## 使用 kubeadm 部署 Kubernetes(CRI 使用 containerd)
|
||||
|
||||
`kubeadm` 提供了 `kubeadm init` 以及 `kubeadm join` 这两个命令作为快速创建 `kubernetes` 集群的最佳实践。
|
||||
`kubeadm` 提供了 `kubeadm init` 以及 `kubeadm join` 这两个命令,作为快速创建 `Kubernetes` 集群的最佳实践。
|
||||
|
||||
> **版本说明**:Kubernetes 版本更新较快(约每 4 个月一个新版本),本文档基于 Kubernetes 1.35 编写。请访问 [Kubernetes 官方发布页](https://kubernetes.io/releases/) 获取最新版本信息。
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
## 一步步部署 kubernetes 集群
|
||||
## 一步步部署 Kubernetes 集群
|
||||
|
||||
可以参考 [opsnull/follow-me-install-kubernetes-cluster](https://github.com/opsnull/follow-me-install-kubernetes-cluster) 项目一步步部署 kubernetes 集群。
|
||||
可以参考 [opsnull/follow-me-install-kubernetes-cluster](https://github.com/opsnull/follow-me-install-kubernetes-cluster) 项目一步步部署 Kubernetes 集群。
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
## 阿里云
|
||||
|
||||
阿里云 示意图如下:
|
||||
如图 13-3 所示,阿里云是国内主流云服务平台之一。
|
||||
|
||||

|
||||
|
||||
图 13-3 阿里云标识
|
||||
|
||||
[阿里云](https://www.aliyun.com/?source=5176.11533457\&userCode=8lx5zmtu\&type=copy) 创立于 2009 年,是中国较早的云计算平台。阿里云致力于提供安全、可靠的计算和数据处理能力。
|
||||
|
||||
[阿里云](https://www.aliyun.com/?source=5176.11533457\&userCode=8lx5zmtu\&type=copy) 的客户群体中,活跃着微博、虎牙、魅族、优酷等一大批明星互联网公司。在天猫双 11 全球狂欢节等极富挑战的应用场景中,阿里云保持着良好的运行纪录。
|
||||
|
||||
[阿里云容器服务 Kubernetes 版 ACK](https://www.aliyun.com/product/kubernetes?source=5176.11533457\&userCode=8lx5zmtu\&type=copy) 提供了高性能、可伸缩的容器应用管理服务,支持在一组云服务器上通过 Docker 容器来进行应用生命周期管理。容器服务极大简化了用户对容器管理集群的搭建工作,无缝整合了阿里云虚拟化、存储、网络和安全能力。容器服务提供了多种应用发布方式和流水线般的持续交付能力,原生支持微服务架构,助力用户无缝上云和跨云管理。
|
||||
|
||||

|
||||

|
||||
|
||||
图 13-4 阿里云容器服务示意图
|
||||
|
||||
@@ -1,13 +1,26 @@
|
||||
## 亚马逊云
|
||||
|
||||
亚马逊云 示意图如下:
|
||||
如图 13-1 所示,AWS 是全球主流云服务平台之一。
|
||||
|
||||

|
||||
|
||||
图 13-1 AWS 标识
|
||||
|
||||
[AWS](https://www.amazonaws.cn),即 Amazon Web Services,是亚马逊(Amazon)公司的 IaaS 和 PaaS 平台服务。AWS 提供了一整套基础设施和应用程序服务,使用户几乎能够在云中运行一切应用程序:从企业应用程序和大数据项目,到社交游戏和移动应用程序。AWS 面向用户提供包括弹性计算、存储、数据库、应用程序在内的一整套云计算服务,能够帮助企业降低 IT 投入成本和维护成本。
|
||||
|
||||
自 2006 年初起,亚马逊 AWS 开始在云中为各种规模的公司提供技术服务平台。利用亚马逊 AWS,软件开发人员可以轻松购买计算、存储、数据库和其他基于 Internet 的服务来支持其应用程序。开发人员能够灵活选择任何开发平台或编程环境,以便于其尝试解决问题。由于开发人员只需按使用量付费,无需前期资本支出,亚马逊 AWS 是向最终用户交付计算资源、保存的数据和其他应用程序的一种经济划算的方式。
|
||||
在容器领域,AWS 目前主流能力可以按场景分为四类:
|
||||
|
||||
2015 年 AWS 正式发布了 EC2 容器服务(ECS)。ECS 的目的是让 Docker 容器变的更加简单,它提供了一个集群和编排的层,用来控制主机上的容器部署,以及部署之后的集群内的容器的生命周期管理。ECS 是诸如 Docker Swarm、Kubernetes、Mesos 等工具的替代,它们工作在同一个层,除了作为一个服务来提供。这些工具和 ECS 不同的地方在于,前者需要用户自己来部署和管理,而 ECS 是“作为服务”来提供的。
|
||||
1. `Amazon EKS`:托管 Kubernetes 控制平面,适合标准云原生工作负载。
|
||||
2. `Amazon ECS`:AWS 原生容器编排服务,适合深度集成 AWS 生态(IAM、ALB、CloudWatch)场景。
|
||||
3. `AWS Fargate`:无服务器容器运行时,可与 EKS/ECS 结合使用,减少节点运维。
|
||||
4. `Amazon ECR`:镜像仓库服务,提供私有镜像管理、扫描与访问控制。
|
||||
|
||||
实践建议:
|
||||
|
||||
* 团队已具备 Kubernetes 经验,优先选择 EKS;
|
||||
* 追求更低运维复杂度且业务主要运行在 AWS,可优先 ECS + Fargate;
|
||||
* 无论编排方案如何,都建议使用 ECR 统一管理镜像生命周期。
|
||||
|
||||

|
||||
|
||||
图 13-2 AWS 容器服务示意图
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
## 腾讯云
|
||||
|
||||
腾讯云 示意图如下:
|
||||
如图 13-5 所示,腾讯云提供完整的云基础设施与容器能力。
|
||||
|
||||

|
||||
|
||||
图 13-5 腾讯云标识
|
||||
|
||||
[腾讯云](https://cloud.tencent.com/act/cps/redirect?redirect=1040\&cps_key=3a5255852d5db99dcd5da4c72f05df61\&from=console) 在架构方面经过多年积累,并且有着多年对海量互联网服务的经验。不管是社交、游戏还是其他领域,都有多年的成熟产品来提供产品服务。腾讯在云端完成重要部署,为开发者及企业提供云服务、云数据、云运营等整体一站式服务方案。
|
||||
|
||||
具体包括 [云服务器](https://cloud.tencent.com/act/cps/redirect?redirect=1001\&cps_key=3a5255852d5db99dcd5da4c72f05df61\&from=console)、[云存储](https://cloud.tencent.com/act/cps/redirect?redirect=1020\&cps_key=3a5255852d5db99dcd5da4c72f05df61\&from=console)、[云数据库](https://cloud.tencent.com/act/cps/redirect?redirect=1003\&cps_key=3a5255852d5db99dcd5da4c72f05df61\&from=console)、[视频与CDN](https://cloud.tencent.com/act/cps/redirect?redirect=1019\&cps_key=3a5255852d5db99dcd5da4c72f05df61\&from=console) 和 [域名注册](https://dnspod.cloud.tencent.com) 等基础云服务;腾讯云分析(MTA)、腾讯云推送(信鸽)等腾讯整体大数据能力;以及 QQ互联、QQ 空间、微云、微社区等云端链接社交体系。这些正是腾讯云可以提供给这个行业的差异化优势,造就了可支持各种互联网使用场景的高品质的腾讯云技术平台。
|
||||
|
||||
[腾讯云容器服务 TKE](https://cloud.tencent.com/act/cps/redirect?redirect=10058\&cps_key=3a5255852d5db99dcd5da4c72f05df61) 是高度可扩展的高性能容器管理服务,用户可以在托管的云服务器实例集群上轻松运行应用程序。使用该服务,将无需安装、运维、扩展用户的集群管理基础设施,只需进行简单的 API 调用,便可启动和停止 Docker 应用程序,查询集群的完整状态,以及使用各种云服务。用户可以根据用户的资源需求和可用性要求在用户的集群中安排容器的置放,满足业务或应用程序的特定要求。
|
||||
|
||||

|
||||

|
||||
|
||||
图 13-6 腾讯云容器服务示意图
|
||||
|
||||
@@ -116,18 +116,15 @@ flowchart TD
|
||||
|
||||
在 macOS 和 Windows 上,因为内核差异,架构稍微复杂:
|
||||
|
||||
```
|
||||
┌────────────── MacOS / Windows ──────────────┐
|
||||
│ Docker CLI │
|
||||
│ │ │
|
||||
├──────┼──────────────────────────────────────┤
|
||||
│ ▼ (Socket 映射) │
|
||||
│ ┌────────── Linux VM (虚拟机) ───────────┐ │
|
||||
│ │ │ │
|
||||
│ │ Dockerd <--> Containerd <--> Runc │ │
|
||||
│ │ │ │
|
||||
│ └────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────┘
|
||||
```mermaid
|
||||
flowchart TD
|
||||
subgraph HostOS ["MacOS / Windows"]
|
||||
CLI["Docker CLI"]
|
||||
subgraph LinuxVM ["Linux VM (虚拟机)"]
|
||||
Engine["Dockerd <--> Containerd <--> Runc"]
|
||||
end
|
||||
CLI -- "(Socket 映射)" --> Engine
|
||||
end
|
||||
```
|
||||
|
||||
- 使用轻量级虚拟机(Apple Virtualization / WSL 2)运行 Linux 内核
|
||||
|
||||
@@ -4,15 +4,24 @@
|
||||
|
||||
> **Namespace 是 Linux 内核提供的资源隔离机制,它让容器内的进程仿佛运行在独立的操作系统中。**Namespace 是容器技术的核心基础之一。它回答了一个关键问题:**如何让一个进程"以为"自己独占整个系统?**
|
||||
|
||||
```
|
||||
宿主机视角: 容器内视角:
|
||||
┌─────────────────────────┐ ┌─────────────────────────┐
|
||||
│ PID 1: systemd │ │ PID 1: nginx │ ← 容器认为自己是 PID 1
|
||||
│ PID 2: sshd │ │ PID 2: nginx worker │
|
||||
│ PID 3: dockerd │ │ │
|
||||
│ PID 1234: nginx ←──────│─────│ (实际是宿主机的 1234) │
|
||||
│ PID 1235: nginx worker │ │ │
|
||||
└─────────────────────────┘ └─────────────────────────┘
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph Host ["宿主机视角"]
|
||||
direction TB
|
||||
H1["PID 1: systemd"]
|
||||
H2["PID 2: sshd"]
|
||||
H3["PID 3: dockerd"]
|
||||
H4["PID 1234: nginx"]
|
||||
H5["PID 1235: nginx worker"]
|
||||
end
|
||||
|
||||
subgraph Container ["容器内视角"]
|
||||
direction TB
|
||||
C1["PID 1: nginx<br/>← 容器认为自己是 PID 1"]
|
||||
C2["PID 2: nginx worker"]
|
||||
end
|
||||
|
||||
H4 -. "(实际是宿主机的 1234)" .- C1
|
||||
```
|
||||
|
||||
### Namespace 的类型
|
||||
@@ -76,13 +85,21 @@ NET Namespace 负责网络栈的隔离,包括网卡、路由表和 iptables
|
||||
|
||||
#### NET 隔离效果
|
||||
|
||||
```
|
||||
宿主机 容器
|
||||
┌─────────────────────┐ ┌─────────────────────┐
|
||||
│ eth0: 192.168.1.10 │ │ eth0: 172.17.0.2 │ ← 不同的 IP
|
||||
│ docker0: 172.17.0.1│◄───────►│ (veth pair 连接) │
|
||||
│ 端口 80 可用 │ │ 端口 80 可用 │ ← 可以使用相同端口
|
||||
└─────────────────────┘ └─────────────────────┘
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph Host ["宿主机"]
|
||||
direction TB
|
||||
H1["eth0: 192.168.1.10<br/>端口 80 可用"]
|
||||
H2["docker0: 172.17.0.1"]
|
||||
end
|
||||
|
||||
subgraph Container ["容器"]
|
||||
direction TB
|
||||
C1["eth0: 172.17.0.2<br/>端口 80 可用"]
|
||||
C2["(veth pair 连接)"]
|
||||
end
|
||||
|
||||
H2 <--> C2
|
||||
```
|
||||
|
||||
#### NET 关键点
|
||||
@@ -185,12 +202,22 @@ USER Namespace 允许将容器内的用户 ID 映射到宿主机的不同用户
|
||||
|
||||
#### USER 隔离效果
|
||||
|
||||
```
|
||||
容器内 宿主机
|
||||
┌─────────────────┐ ┌─────────────────┐
|
||||
│ UID 0 (root) │───映射────►│ UID 100000 │ ← 非特权用户
|
||||
│ UID 1 (daemon) │───映射────►│ UID 100001 │
|
||||
└─────────────────┘ └─────────────────┘
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph Container ["容器内"]
|
||||
direction TB
|
||||
C1["UID 0 (root)"]
|
||||
C2["UID 1 (daemon)"]
|
||||
end
|
||||
|
||||
subgraph Host ["宿主机"]
|
||||
direction TB
|
||||
H1["UID 100000<br/>← 非特权用户"]
|
||||
H2["UID 100001"]
|
||||
end
|
||||
|
||||
C1 -- 映射 --> H1
|
||||
C2 -- 映射 --> H2
|
||||
```
|
||||
|
||||
#### 安全意义
|
||||
|
||||
@@ -8,17 +8,25 @@
|
||||
|
||||
> **核心作用**:让多个容器公平共享宿主机资源,防止单个容器耗尽系统资源。
|
||||
|
||||
```
|
||||
无 cgroups 限制: 有 cgroups 限制:
|
||||
┌──────────────────────┐ ┌──────────────────────┐
|
||||
│ 宿主机资源 │ │ 宿主机资源 │
|
||||
│ ┌─────────────┐ │ │ ┌───┬───┬───┐ │
|
||||
│ │ 容器 A │ │ │ │ A │ B │ C │ │
|
||||
│ │ 占用所有 │ │ │ │1GB│1GB│1GB│ ← 限制│
|
||||
│ │ 内存和 CPU │ │ │ ├───┼───┼───┤ │
|
||||
│ └─────────────┘ │ │ │2核│1核│1核│ │
|
||||
│ 容器 B、C 饥饿 │ │ └───┴───┴───┘ │
|
||||
└──────────────────────┘ └──────────────────────┘
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph NoLimit ["无 cgroups 限制"]
|
||||
direction TB
|
||||
subgraph HostRes1 ["宿主机资源"]
|
||||
A["容器 A<br/>占用所有<br/>内存和 CPU"]
|
||||
B["容器 B、C 饥饿"]
|
||||
end
|
||||
end
|
||||
|
||||
subgraph Limit ["有 cgroups 限制"]
|
||||
direction TB
|
||||
subgraph HostRes2 ["宿主机资源"]
|
||||
direction LR
|
||||
C_A["A<br/>1GB<br/>2核"]
|
||||
C_B["B<br/>1GB<br/>1核"]
|
||||
C_C["C<br/>1GB<br/>1核"]
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -8,25 +8,18 @@
|
||||
|
||||
> **核心思想**:将多个只读层叠加,最上层可写,形成完整的文件系统。
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ 容器看到的文件系统 │
|
||||
│ /bin /etc /lib /usr /var /app /data │
|
||||
└────────────────────────┬────────────────────────────────┘
|
||||
│
|
||||
┌───────────────┴───────────────┐
|
||||
│ UnionFS 联合挂载 │
|
||||
└───────────────┬───────────────┘
|
||||
│
|
||||
┌────────────────────────┴────────────────────────────────┐
|
||||
│ 容器层 (读写) │ /app/data/log.txt (新写入) │
|
||||
├────────────────────┼────────────────────────────────────│
|
||||
│ 镜像层3 (只读) │ /app/app.py │
|
||||
├────────────────────┼────────────────────────────────────│
|
||||
│ 镜像层2 (只读) │ /usr/local/bin/python │
|
||||
├────────────────────┼────────────────────────────────────│
|
||||
│ 镜像层1 (只读) │ /bin /etc /lib (基础系统) │
|
||||
└────────────────────┴────────────────────────────────────┘
|
||||
```mermaid
|
||||
flowchart TD
|
||||
ContainerFS["容器看到的文件系统<br/>/bin /etc /lib /usr /var /app /data"]
|
||||
UnionFS["UnionFS 联合挂载"]
|
||||
|
||||
ContainerLayer["容器层 (读写) : /app/data/log.txt (新写入)"]
|
||||
ImageLayer3["镜像层3 (只读) : /app/app.py"]
|
||||
ImageLayer2["镜像层2 (只读) : /usr/local/bin/python"]
|
||||
ImageLayer1["镜像层1 (只读) : /bin /etc /lib (基础系统)"]
|
||||
|
||||
ContainerFS --> UnionFS
|
||||
UnionFS --> ContainerLayer --> ImageLayer3 --> ImageLayer2 --> ImageLayer1
|
||||
```
|
||||
|
||||
---
|
||||
@@ -37,13 +30,10 @@ Docker 选择联合文件系统作为其存储驱动,主要基于以下几个
|
||||
|
||||
#### 1. 镜像分层复用
|
||||
|
||||
```
|
||||
nginx:alpine myapp:latest
|
||||
│ │
|
||||
└────────┬────────────┘
|
||||
│
|
||||
▼
|
||||
alpine:3.19 (共享基础层)
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Nginx["nginx:alpine"] --> Alpine["alpine:3.19 (共享基础层)"]
|
||||
MyApp["myapp:latest"] --> Alpine
|
||||
```
|
||||
|
||||
多个镜像共享相同的底层,节省磁盘空间。
|
||||
@@ -73,15 +63,21 @@ COPY . . # 层4:应用代码
|
||||
|
||||
当容器修改只读层中的文件时:
|
||||
|
||||
```
|
||||
修改前: 修改后:
|
||||
┌─────────────────────┐ ┌─────────────────────┐
|
||||
│ 容器层 (空) │ │ 容器层 │
|
||||
├─────────────────────┤ │ /etc/nginx.conf ←──┼── 复制到容器层后修改
|
||||
│ 镜像层 │ ├─────────────────────┤
|
||||
│ /etc/nginx.conf │ │ 镜像层 │
|
||||
└─────────────────────┘ │ /etc/nginx.conf │ (原文件仍在,但被遮蔽)
|
||||
└─────────────────────┘
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph Before ["修改前"]
|
||||
direction TB
|
||||
B_C["容器层 (空)"]
|
||||
B_I["镜像层<br/>/etc/nginx.conf"]
|
||||
end
|
||||
|
||||
subgraph After ["修改后"]
|
||||
direction TB
|
||||
A_C["容器层<br/>/etc/nginx.conf ← 复制到容器层后修改"]
|
||||
A_I["镜像层<br/>/etc/nginx.conf (原文件仍在,但被遮蔽)"]
|
||||
end
|
||||
B_C --- B_I
|
||||
A_C --- A_I
|
||||
```
|
||||
|
||||
**流程**:
|
||||
@@ -130,23 +126,19 @@ Storage Driver: overlay2
|
||||
|
||||
overlay2 是目前最推荐的存储驱动:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ merged(合并视图) │
|
||||
│ 容器看到的完整文件系统 │
|
||||
└─────────────────────────┬───────────────────────────────────┘
|
||||
│
|
||||
┌───────────────┴───────────────┐
|
||||
│ OverlayFS │
|
||||
└───────────────┬───────────────┘
|
||||
│
|
||||
┌────────────────┼────────────────┐
|
||||
▼ ▼ ▼
|
||||
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
||||
│ upper │ │ lower2 │ │ lower1 │
|
||||
│ (容器层) │ │ (镜像层) │ │ (基础层) │
|
||||
│ 读写 │ │ 只读 │ │ 只读 │
|
||||
└─────────────┘ └─────────────┘ └─────────────┘
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Merged["merged (合并视图)<br/>容器看到的完整文件系统"]
|
||||
OverlayFS["OverlayFS"]
|
||||
|
||||
Upper["upper<br/>(容器层)<br/>读写"]
|
||||
Lower2["lower2<br/>(镜像层)<br/>只读"]
|
||||
Lower1["lower1<br/>(基础层)<br/>只读"]
|
||||
|
||||
Merged --> OverlayFS
|
||||
OverlayFS --> Upper
|
||||
OverlayFS --> Lower2
|
||||
OverlayFS --> Lower1
|
||||
```
|
||||
|
||||
- **lowerdir**:只读的镜像层(可以有多个)
|
||||
|
||||
33
16_appendix/16.4_terminology.md
Normal file
33
16_appendix/16.4_terminology.md
Normal file
@@ -0,0 +1,33 @@
|
||||
## 16.4 术语词表(出版统一版)
|
||||
|
||||
本词表用于统一全书术语、缩写和命令表达,适用于最终出版前清稿。
|
||||
|
||||
### 核心术语统一表
|
||||
|
||||
| 统一写法(推荐) | 可接受写法 | 避免写法 | 说明 |
|
||||
|---|---|---|---|
|
||||
| Docker Engine | Docker 引擎 | docker engine | 产品名首字母大写。 |
|
||||
| Docker Desktop | - | docker desktop | 产品名首字母大写。 |
|
||||
| Dockerfile | - | Docker File、dockerfile | 固定拼写。 |
|
||||
| Docker 镜像(Image) | 镜像 | image(纯英文散落) | 首次出现建议中英文并列。 |
|
||||
| Docker 容器(Container) | 容器 | container(纯英文散落) | 与镜像区分清楚。 |
|
||||
| 仓库(Repository) | Repo(非正式) | 镜像仓库/Repository 混用不解释 | 首次出现需给出英文。 |
|
||||
| 注册服务器(Registry) | 镜像注册服务 | 私有仓库/Registry 混指 | Registry 与 Repository 需区分。 |
|
||||
| 标签(Tag) | 版本标签 | tag(正文中小写裸写) | 命令中保留原样。 |
|
||||
| Docker Compose | Compose | docker compose(当作产品名) | 产品名用 `Docker Compose`。 |
|
||||
| `docker compose` | - | `docker-compose`(新示例中) | 命令统一使用 V2 子命令写法。 |
|
||||
| `compose.yaml` | `compose.yml` | 新示例继续使用 `docker-compose.yml` | 教学默认文件名统一为 `compose.yaml`。 |
|
||||
| Kubernetes | K8s(缩写) | kubernetes(正文) | 正文统一首字母大写。 |
|
||||
| `kubectl` | - | kubeclt(拼写错误) | 命令与二进制名用反引号包裹。 |
|
||||
| etcd | - | Etcd(混用) | 项目官方写法为小写 `etcd`。 |
|
||||
| Docker Buildx | Buildx | buildx(正文裸写) | 产品名用 `Docker Buildx`。 |
|
||||
| BuildKit | - | buildkit | 固定大小写。 |
|
||||
| 控制平面(Control Plane) | - | 主控平面(未定义) | 章节内保持单一译名。 |
|
||||
| 工作节点(Worker Node) | 节点(在上下文明确时) | 工作机器(未定义) | 与控制平面对照使用。 |
|
||||
|
||||
### 清稿执行规则
|
||||
|
||||
1. 术语首次出现采用“中文(英文)”格式,例如“注册服务器(Registry)”。
|
||||
2. 命令、文件名、配置键统一使用反引号包裹。
|
||||
3. 同一章节中,术语只保留一种主写法,不混用同义词。
|
||||
4. 若引用历史名词(如 `docker-compose.yml`),需显式标注“历史文件名”。
|
||||
27
16_appendix/16.5_editorial_style.md
Normal file
27
16_appendix/16.5_editorial_style.md
Normal file
@@ -0,0 +1,27 @@
|
||||
## 16.5 出版清稿规范(图号与章节风格)
|
||||
|
||||
本规范用于最终出版前清稿,确保全书图号、图题、章节结构与行文风格一致。
|
||||
|
||||
### 图号与图题规范
|
||||
|
||||
1. 图号格式统一为:`图 <章号>-<序号> <图题>`,例如 `图 10-2 Rails + PostgreSQL 的 Compose 架构`。
|
||||
2. 图号在同一章内按出现顺序连续编号,不重复、不跳号。
|
||||
3. 正文引用图片统一写法:`如图 <章号>-<序号> 所示`,不使用“下图/上图/示意图如下”。
|
||||
4. 所有图片必须提供有意义的 alt 文本,不使用空 alt(``)。
|
||||
5. 图题单独成行,放在图片下方。
|
||||
|
||||
### 章节风格规范
|
||||
|
||||
1. 小节标题统一使用编号体例:`## 10.6 ...`、`### 步骤 1:...`。
|
||||
2. 步骤型内容统一使用“步骤 N:”中文格式,不使用 `Step N:`。
|
||||
3. 命令行示例统一以 `bash` 代码块展示,提示符统一为 `$`。
|
||||
4. 关键提醒统一使用引用块(`> 注意/提示/警告`),避免正文中混杂多种强调样式。
|
||||
5. 章节内术语使用需遵循《[术语词表(出版统一版)](16.4_terminology.md)》。
|
||||
|
||||
### 出版前自检清单
|
||||
|
||||
1. 是否仍存在“下图/上图/示意图如下”等相对指代。
|
||||
2. 是否存在未编号或编号冲突的图题。
|
||||
3. 是否存在 `kubernetes`、`compose` 等正文大小写不统一写法。
|
||||
4. 是否存在 `Step N:` 与“步骤 N:”混用。
|
||||
5. 是否存在未加反引号的命令、文件名和配置键名。
|
||||
@@ -10,3 +10,5 @@
|
||||
* [**Dockerfile 最佳实践**](16.1_best_practices.md):提供编写高效、安全 Dockerfile 的指导原则。
|
||||
* [**如何调试 Docker**](16.2_debug.md):介绍 Docker 调试技巧和工具。
|
||||
* [**资源链接**](16.3_resources.md):推荐更多 Docker 相关的学习资源。
|
||||
* [**术语词表(出版统一版)**](16.4_terminology.md):统一全书中英文术语、缩写与命令写法。
|
||||
* [**出版清稿规范(图号与章节风格)**](16.5_editorial_style.md):统一图号命名、图题写法与章节风格。
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* `--tls=true|false`:是否对 Docker 守护进程启用 TLS 安全机制,默认为否;
|
||||
* `--tlscacert=/.docker/ca.pem`:TLS CA 签名的可信证书文件路径;
|
||||
* `--tlscert=/.docker/cert.pem`:TLS 可信证书文件路径;
|
||||
* `--tlscert=/.docker/key.pem`:TLS 密钥文件路径;
|
||||
* `--tlskey=/.docker/key.pem`:TLS 密钥文件路径;
|
||||
* `--tlsverify=true|false`:启用 TLS 校验,默认为否。
|
||||
|
||||
### 客户端命令
|
||||
@@ -64,10 +64,12 @@
|
||||
|
||||
### 一张图总结 Docker 的命令
|
||||
|
||||
一张图总结 Docker 的命令 示意图如下:
|
||||
如图 16-1 所示,Docker 常用客户端命令可按功能分组理解。
|
||||
|
||||

|
||||
|
||||
图 16-1 Docker 客户端命令分类示意图
|
||||
|
||||
### 参考
|
||||
|
||||
* [官方文档](https://docs.docker.com/engine/reference/commandline/cli/)
|
||||
* [官方文档](https://docs.docker.com/reference/cli/docker/)
|
||||
|
||||
@@ -1,58 +1,40 @@
|
||||
## 服务端命令(dockerd)
|
||||
|
||||
### dockerd 命令选项
|
||||
### 使用说明
|
||||
|
||||
* `--api-cors-header=""`:CORS 头部域,默认不允许 CORS,要允许任意的跨域访问,可以指定为 "*";
|
||||
* `--authorization-plugin=""`:载入认证的插件;
|
||||
* `-b=""`:将容器挂载到一个已存在的网桥上。指定为 `none` 时则禁用容器的网络,与 `--bip` 选项互斥;
|
||||
* `--bip=""`:让动态创建的 `docker0` 网桥采用给定的 CIDR 地址; 与 `-b` 选项互斥;
|
||||
* `--cgroup-parent=""`:指定 cgroup 的父组,默认 fs cgroup 驱动为 `/docker`,systemd cgroup 驱动为 `system.slice`;
|
||||
* `--cluster-store=""`:构成集群(如 `Swarm`)时,集群键值数据库服务地址;
|
||||
* `--cluster-advertise=""`:构成集群时,自身的被访问地址,可以为 `host:port` 或 `interface:port`;
|
||||
* `--cluster-store-opt=""`:构成集群时,键值数据库的配置选项;
|
||||
* `--config-file="/etc/docker/daemon.json"`:daemon 配置文件路径;
|
||||
* `--containerd=""`:containerd 文件的路径;
|
||||
* `-D, --debug=true|false`:是否使用 Debug 模式。缺省为 false;
|
||||
* `--default-gateway=""`:容器的 IPv4 网关地址,必须在网桥的子网段内;
|
||||
* `--default-gateway-v6=""`:容器的 IPv6 网关地址;
|
||||
* `--default-ulimit=[]`:默认的 ulimit 值;
|
||||
* `--disable-legacy-registry=true|false`:是否允许访问旧版本的镜像仓库服务器;
|
||||
* `--dns=""`:指定容器使用的 DNS 服务器地址;
|
||||
* `--dns-opt=""`:DNS 选项;
|
||||
* `--dns-search=[]`:DNS 搜索域;
|
||||
* `--exec-opt=[]`:运行时的执行选项;
|
||||
* `--exec-root=""`:容器执行状态文件的根路径,默认为 `/var/run/docker`;
|
||||
* `--fixed-cidr=""`:限定分配 IPv4 地址范围;
|
||||
* `--fixed-cidr-v6=""`:限定分配 IPv6 地址范围;
|
||||
* `-G, --group=""`:分配给 unix 套接字的组,默认为 `docker`;
|
||||
* `-g, --graph=""`:Docker 运行时的根路径,默认为 `/var/lib/docker`;
|
||||
* `-H, --host=[]`:指定命令对应 Docker daemon 的监听接口,可以为 unix 套接字 `unix:///path/to/socket`,文件句柄 `fd://socketfd` 或 tcp 套接字 `tcp://[host[:port]]`,默认为 `unix:///var/run/docker.sock`;
|
||||
* `--icc=true|false`:是否启用容器间以及跟 daemon 所在主机的通信。默认为 true。
|
||||
* `--insecure-registry=[]`:允许访问给定的非安全仓库服务;
|
||||
* `--ip=""`:绑定容器端口时候的默认 IP 地址。缺省为 `0.0.0.0`;
|
||||
* `--ip-forward=true|false`:是否检查启动在 Docker 主机上的启用 IP 转发服务,默认开启。注意关闭该选项将不对系统转发能力进行任何检查修改;
|
||||
* `--ip-masq=true|false`:是否进行地址伪装,用于容器访问外部网络,默认开启;
|
||||
* `--iptables=true|false`:是否允许 Docker 添加 iptables 规则。缺省为 true;
|
||||
* `--ipv6=true|false`:是否启用 IPv6 支持,默认关闭;
|
||||
* `-l, --log-level="debug|info|warn|error|fatal"`:指定日志输出级别;
|
||||
* `--label="[]"`:添加指定的键值对标注;
|
||||
* `--log-driver="json-file|syslog|journald|gelf|fluentd|awslogs|splunk|etwlogs|gcplogs|none"`:指定日志后端驱动,默认为 `json-file`;
|
||||
* `--log-opt=[]`:日志后端的选项;
|
||||
* `--mtu=VALUE`:指定容器网络的 `mtu`;
|
||||
* `-p=""`:指定 daemon 的 PID 文件路径。缺省为 `/var/run/docker.pid`;
|
||||
* `--raw-logs`:输出原始,未加色彩的日志信息;
|
||||
* `--registry-mirror=<scheme>://<host>`:指定 `docker pull` 时使用的注册服务器镜像地址;
|
||||
* `-s, --storage-driver=""`:指定使用给定的存储后端;
|
||||
* `--selinux-enabled=true|false`:是否启用 SELinux 支持。缺省值为 false。SELinux 目前尚不支持 overlay 存储驱动;
|
||||
* `--storage-opt=[]`:驱动后端选项;
|
||||
* `--tls=true|false`:是否对 Docker daemon 启用 TLS 安全机制,默认为否;
|
||||
* `--tlscacert=/.docker/ca.pem`:TLS CA 签名的可信证书文件路径;
|
||||
* `--tlscert=/.docker/cert.pem`:TLS 可信证书文件路径;
|
||||
* `--tlscert=/.docker/key.pem`:TLS 密钥文件路径;
|
||||
* `--tlsverify=true|false`:启用 TLS 校验,默认为否;
|
||||
* `--userland-proxy=true|false`:是否使用用户态代理来实现容器间和出容器的回环通信,默认为 true;
|
||||
* `--userns-remap=default|uid:gid|user:group|user|uid`:指定容器的用户命名空间,默认是创建新的 UID 和 GID 映射到容器内进程。
|
||||
`dockerd` 参数会随版本变化。建议优先在目标机器上执行 `dockerd --help`,并以 `daemon.json` 为主进行持久化配置。
|
||||
|
||||
### 常用选项(Docker Engine 29.x)
|
||||
|
||||
* `--config-file="/etc/docker/daemon.json"`:指定 daemon 配置文件路径;
|
||||
* `--data-root=""`:Docker 数据目录(默认 `/var/lib/docker`);
|
||||
* `-H, --host=[]`:指定 daemon 监听地址(Unix socket / TCP);
|
||||
* `-D, --debug`:开启调试日志;
|
||||
* `-l, --log-level="debug|info|warn|error|fatal"`:日志级别;
|
||||
* `--group=""`:Unix socket 所属用户组(默认 `docker`);
|
||||
* `--containerd=""`:指定 containerd socket;
|
||||
* `--exec-opt=[]`:运行时执行选项(如 cgroup 驱动);
|
||||
* `--default-ulimit=[]`:设置容器默认 ulimit;
|
||||
* `--dns=[]` / `--dns-search=[]` / `--dns-opt=[]`:DNS 配置;
|
||||
* `--registry-mirror=[]`:镜像加速地址;
|
||||
* `--insecure-registry=[]`:允许访问不安全仓库;
|
||||
* `--iptables=true|false` / `--ip-forward=true|false` / `--ip-masq=true|false`:网络转发与 NAT 规则控制;
|
||||
* `--ipv6=true|false`:启用 IPv6;
|
||||
* `--storage-driver=""` / `--storage-opt=[]`:存储驱动及参数;
|
||||
* `--log-driver=""` / `--log-opt=[]`:容器日志驱动与参数;
|
||||
* `--authorization-plugin=[]`:鉴权插件;
|
||||
* `--selinux-enabled=true|false`:启用 SELinux 集成(依赖发行版策略);
|
||||
* `--userns-remap=...`:用户命名空间映射;
|
||||
* `--tls` / `--tlscacert` / `--tlscert` / `--tlskey` / `--tlsverify`:TLS 安全配置。
|
||||
|
||||
### 历史参数提示
|
||||
|
||||
以下参数已移除或不建议继续使用:
|
||||
|
||||
* `--graph`:请改用 `--data-root`;
|
||||
* `--cluster-store` / `--cluster-advertise` / `--cluster-store-opt`:已移除;
|
||||
* `--disable-legacy-registry`:已移除。
|
||||
|
||||
### 参考
|
||||
|
||||
* [官方文档](https://docs.docker.com/engine/reference/commandline/dockerd/)
|
||||
* [官方文档](https://docs.docker.com/reference/cli/dockerd/)
|
||||
|
||||
@@ -102,11 +102,11 @@ $ docker run --network=my-net --ip=172.25.3.3 -itd --name=my-container busybox
|
||||
|
||||
### Docker 的配置文件放在哪里,如何修改配置?
|
||||
|
||||
答:使用 `systemd` 的系统(如 Ubuntu 16.04、Centos 等)的配置文件在 `/etc/docker/daemon.json`。
|
||||
答:使用 `systemd` 的系统(如 Ubuntu 22.04+、Debian 12+、Rocky/Alma/CentOS Stream 9+)的配置文件在 `/etc/docker/daemon.json`。
|
||||
|
||||
### 如何更改 Docker 的默认存储位置?
|
||||
|
||||
答:Docker 的默认存储位置是 `/var/lib/docker`,如果希望将 Docker 的本地文件存储到其他分区,可以使用 Linux 软连接的方式来完成,或者在启动 daemon 时通过 `-g` 参数指定,或者修改配置文件 `/etc/docker/daemon.json` 的 "data-root" 项 。可以使用 `docker system info | grep "Root Dir"` 查看当前使用的存储位置。
|
||||
答:Docker 的默认存储位置是 `/var/lib/docker`,如果希望将 Docker 的本地文件存储到其他分区,可以使用 Linux 软连接的方式来完成,或者修改配置文件 `/etc/docker/daemon.json` 的 `data-root` 项。可以使用 `docker info | grep "Docker Root Dir"` 查看当前使用的存储位置。
|
||||
|
||||
例如,如下操作将默认存储位置迁移到 /storage/docker。
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
* 1.5.0 2026-02-05
|
||||
* 全面重构章节目录结构 (01-15)
|
||||
* 支持 Docker Engine v30.x
|
||||
* 支持 Docker Engine v29.x
|
||||
* 优化文档图片引用路径
|
||||
|
||||
* 1.4.0 2026-01-11
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Docker — 从入门到实践
|
||||
|
||||
[](https://github.com/yeasy/docker_practice) [](https://github.com/yeasy/docker_practice/releases) [](https://github.com/docker/docker-ce) [][1]
|
||||
[](https://github.com/yeasy/docker_practice) [](https://github.com/yeasy/docker_practice/releases) [](https://docs.docker.com/engine/release-notes/) [][1]
|
||||
|
||||
**v1.5.4**
|
||||
|
||||
|
||||
@@ -117,12 +117,12 @@
|
||||
* [高级特性](12_orchestration/kubernetes/advanced.md)
|
||||
* [实战练习](12_orchestration/kubernetes/practice.md)
|
||||
* [部署 Kubernetes](12_orchestration/setup/README.md)
|
||||
* [使用 kubeadm 部署 kubernetes(CRI 使用 containerd)](12_orchestration/setup/kubeadm.md)
|
||||
* [使用 kubeadm 部署 kubernetes(CRI 使用 Docker)](12_orchestration/setup/kubeadm-docker.md)
|
||||
* [使用 kubeadm 部署 Kubernetes(CRI 使用 containerd)](12_orchestration/setup/kubeadm.md)
|
||||
* [使用 kubeadm 部署 Kubernetes(使用 Docker)](12_orchestration/setup/kubeadm-docker.md)
|
||||
* [在 Docker Desktop 使用](12_orchestration/setup/docker-desktop.md)
|
||||
* [Kind - Kubernetes IN Docker](12_orchestration/setup/kind.md)
|
||||
* [K3s - 轻量级 Kubernetes](12_orchestration/setup/k3s.md)
|
||||
* [一步步部署 kubernetes 集群](12_orchestration/setup/systemd.md)
|
||||
* [一步步部署 Kubernetes 集群](12_orchestration/setup/systemd.md)
|
||||
* [部署 Dashboard](12_orchestration/setup/dashboard.md)
|
||||
* [Kubernetes 命令行 kubectl](12_orchestration/kubectl/README.md)
|
||||
* [第十三章 容器生态](13_ecosystem/README.md)
|
||||
@@ -182,3 +182,5 @@
|
||||
* [附录四:Dockerfile 最佳实践](16_appendix/16.1_best_practices.md)
|
||||
* [附录五:如何调试 Docker](16_appendix/16.2_debug.md)
|
||||
* [附录六:资源链接](16_appendix/16.3_resources.md)
|
||||
* [附录七:术语词表(出版统一版)](16_appendix/16.4_terminology.md)
|
||||
* [附录八:出版清稿规范(图号与章节风格)](16_appendix/16.5_editorial_style.md)
|
||||
|
||||
Reference in New Issue
Block a user