mirror of
https://github.com/yeasy/docker_practice.git
synced 2026-03-24 18:55:31 +00:00
Remove blank lines after code block markers
This commit is contained in:
@@ -24,7 +24,6 @@ flowchart TD
|
||||
|
||||
UserSpace --- KernelSpace
|
||||
```
|
||||
|
||||
对于 Linux 而言,内核启动后会挂载 `root` 文件系统来提供用户空间支持。**Docker 镜像** 本质上就是一个 `root` 文件系统。
|
||||
|
||||
例如,官方镜像 `ubuntu:24.04` 包含了一套完整的 Ubuntu 24.04 最小系统的 root 文件系统——但 **不包含 Linux 内核** (因为容器共享宿主机的内核)。
|
||||
@@ -80,7 +79,6 @@ flowchart TD
|
||||
AppC --> Ubuntu
|
||||
end
|
||||
```
|
||||
|
||||
#### 分层是如何工作的?
|
||||
|
||||
笔者用一个实际的 Dockerfile 来解释分层:
|
||||
@@ -91,7 +89,6 @@ RUN apt-get update # 第 2 层:更新包索引
|
||||
RUN apt-get install nginx # 第 3 层:安装 nginx
|
||||
COPY app.conf /etc/nginx/ # 第 4 层:复制配置文件
|
||||
```
|
||||
|
||||
构建后的镜像结构:
|
||||
|
||||
```mermaid
|
||||
@@ -103,7 +100,6 @@ flowchart TD
|
||||
|
||||
Layer4 --> Layer3 --> Layer2 --> Layer1
|
||||
```
|
||||
|
||||
每一层的特点:
|
||||
|
||||
- **只读**:构建完成后不可修改
|
||||
@@ -115,7 +111,6 @@ flowchart TD
|
||||
> ⚠️ **笔者特别提醒**:理解这一点可以帮你避免构建出臃肿的镜像。**关键原理**:每一层的文件变化会被记录,但 **删除操作只是标记,不会真正减小镜像体积**。
|
||||
|
||||
```docker
|
||||
|
||||
## 错误示范 ❌
|
||||
|
||||
FROM ubuntu:24.04
|
||||
@@ -126,9 +121,7 @@ RUN apt-get remove build-essential # 试图删除编译工具
|
||||
|
||||
## 结果:镜像仍然包含 200MB 的编译工具!
|
||||
```
|
||||
|
||||
```docker
|
||||
|
||||
## 正确做法 ✅
|
||||
|
||||
FROM ubuntu:24.04
|
||||
@@ -142,11 +135,9 @@ RUN apt-get update && \
|
||||
## 在同一层完成安装、使用、清理
|
||||
|
||||
```
|
||||
|
||||
#### 查看镜像的分层
|
||||
|
||||
```bash
|
||||
|
||||
## 查看镜像的历史(每层的构建记录)
|
||||
|
||||
$ docker history nginx:latest
|
||||
@@ -159,7 +150,6 @@ a6bd71f48f68 2 weeks ago CMD ["nginx" "-g" "daemon off;"] 0B
|
||||
<missing> 2 weeks ago COPY 30-tune-worker-processes.sh /docker-ent… 4.62kB
|
||||
...
|
||||
```
|
||||
|
||||
### 2.1.5 镜像的标识
|
||||
|
||||
Docker 镜像有多种标识方式:
|
||||
@@ -169,7 +159,6 @@ Docker 镜像有多种标识方式:
|
||||
格式:`[仓库地址/]仓库名[:标签]`
|
||||
|
||||
```bash
|
||||
|
||||
## 完整格式
|
||||
|
||||
registry.example.com/myproject/myapp:v1.2.3
|
||||
@@ -183,7 +172,6 @@ ubuntu:24.04
|
||||
|
||||
nginx # 等同于 nginx:latest
|
||||
```
|
||||
|
||||
#### 2. 镜像 ID:Content-Addressable 标识
|
||||
|
||||
每个镜像有一个基于内容计算的唯一 ID:
|
||||
@@ -194,7 +182,6 @@ REPOSITORY TAG IMAGE ID CREATED SIZE
|
||||
nginx latest a6bd71f48f68 2 weeks ago 187MB
|
||||
ubuntu 24.04 ca2b0f26964c 3 weeks ago 78.1MB
|
||||
```
|
||||
|
||||
#### 3. 镜像摘要
|
||||
|
||||
更精确的标识,基于镜像内容的 SHA256 哈希:
|
||||
@@ -204,7 +191,6 @@ $ docker images --digests
|
||||
REPOSITORY TAG DIGEST IMAGE ID
|
||||
nginx latest sha256:6db391d1c0cfb30588ba0bf72ea999404f2764184d8b8d10d89e8a9c6... a6bd71f48f68
|
||||
```
|
||||
|
||||
> 💡 笔者建议:在生产环境使用镜像摘要而非标签,因为标签可以被覆盖,但摘要是不可变的。
|
||||
|
||||
### 2.1.6 镜像的来源
|
||||
|
||||
@@ -26,7 +26,6 @@ flowchart TD
|
||||
C1["• 独立进程空间<br/>• 独立网络环境<br/>• 独立文件系统<br/>• 独立用户空间"]
|
||||
end
|
||||
```
|
||||
|
||||
这种隔离是通过 Linux 内核的 **Namespace** 技术实现的。具体表现为:
|
||||
- **进程空间**:容器看不到宿主机上的其他进程。
|
||||
- **网络**:容器拥有独立的 IP、端口等网络资源。
|
||||
@@ -67,7 +66,6 @@ flowchart TD
|
||||
CApp --> CContainer --> CE --> CH --> CHW
|
||||
end
|
||||
```
|
||||
|
||||
| 特性 | 容器 | 虚拟机 |
|
||||
|------|------|--------|
|
||||
| **隔离级别** | 进程级 (Namespace)| 硬件级 (Hypervisor)|
|
||||
@@ -94,7 +92,6 @@ flowchart TD
|
||||
|
||||
ContainerLayer --> ImageLayerN --> ImageLayerN1 --> Dots --> ImageLayer1
|
||||
```
|
||||
|
||||
#### Copy-on-Write:写时复制
|
||||
|
||||
当容器需要修改镜像层中的文件时:
|
||||
@@ -107,13 +104,11 @@ flowchart TD
|
||||
读取文件:直接从镜像层读取(共享,高效)
|
||||
修改文件:复制到容器层,然后修改(只有这个容器能看到修改)
|
||||
```
|
||||
|
||||
#### ⚠️ 容器存储层的生命周期
|
||||
|
||||
> **笔者特别强调**:这是新手最容易踩的坑!**容器存储层与容器生命周期绑定。容器删除,数据就没了!**
|
||||
|
||||
```bash
|
||||
|
||||
## 创建容器,写入数据
|
||||
|
||||
$ docker run -it ubuntu bash
|
||||
@@ -127,7 +122,6 @@ $ docker rm abc123
|
||||
## 数据丢了!没有任何办法恢复!
|
||||
|
||||
```
|
||||
|
||||
#### 正确的数据持久化方式
|
||||
|
||||
按照 Docker 最佳实践,容器存储层应该保持 **无状态**。需要持久化的数据应该使用:
|
||||
@@ -138,7 +132,6 @@ $ docker rm abc123
|
||||
| **[绑定挂载 (Bind Mount) ](../08_data/8.2_bind-mounts.md)** | 挂载宿主机目录 | 开发时共享代码 |
|
||||
|
||||
```bash
|
||||
|
||||
## 使用数据卷(推荐)
|
||||
|
||||
$ docker run -v mydata:/var/lib/mysql mysql
|
||||
@@ -147,7 +140,6 @@ $ docker run -v mydata:/var/lib/mysql mysql
|
||||
|
||||
$ docker run -v /host/path:/container/path nginx
|
||||
```
|
||||
|
||||
这些位置的读写 **会跳过容器存储层**,直接写入宿主机,性能更好,也不会随容器删除而丢失。
|
||||
|
||||
### 2.2.5 容器的生命周期
|
||||
@@ -169,13 +161,11 @@ stateDiagram-v2
|
||||
|
||||
Deleted --> [*]
|
||||
```
|
||||
|
||||
图 2-1:容器生命周期状态流转图
|
||||
|
||||
#### 常用生命周期命令
|
||||
|
||||
```bash
|
||||
|
||||
## 创建并启动容器(最常用)
|
||||
|
||||
$ docker run nginx
|
||||
@@ -200,23 +190,19 @@ $ docker unpause abc123 # 恢复
|
||||
$ docker rm abc123 # 删除已停止的容器
|
||||
$ docker rm -f abc123 # 强制删除运行中的容器
|
||||
```
|
||||
|
||||
### 2.2.6 容器与进程的关系
|
||||
|
||||
> **核心概念**:容器的生命周期 = 主进程 (PID 1) 的生命周期
|
||||
|
||||
```bash
|
||||
|
||||
## 主进程运行,容器运行
|
||||
|
||||
## 主进程退出,容器停止
|
||||
|
||||
```
|
||||
|
||||
这就是为什么:
|
||||
|
||||
```bash
|
||||
|
||||
## 这个容器会立即退出(bash 没有输入就退出了)
|
||||
|
||||
$ docker run ubuntu
|
||||
@@ -225,7 +211,6 @@ $ docker run ubuntu
|
||||
|
||||
$ docker run nginx
|
||||
```
|
||||
|
||||
详细解释请参考[后台运行](../05_container/5.2_daemon.md)章节。
|
||||
|
||||
### 2.2.7 容器的隔离性
|
||||
|
||||
@@ -40,7 +40,6 @@ flowchart TB
|
||||
RepoNginx ~~~ RepoMysql
|
||||
end
|
||||
```
|
||||
|
||||
图 2-2:Registry、Repository 与 Tag 的层级关系
|
||||
|
||||
相关基本概念具体如下:
|
||||
@@ -58,11 +57,9 @@ flowchart TB
|
||||
```bash
|
||||
[registry 地址/][用户名/]仓库名[:标签]
|
||||
```
|
||||
|
||||
示例:
|
||||
|
||||
```bash
|
||||
|
||||
## 完整格式
|
||||
|
||||
registry.example.com/mycompany/myapp:v1.2.3
|
||||
@@ -86,7 +83,6 @@ jwilder/nginx-proxy:latest
|
||||
ghcr.io/username/myapp:v1.0
|
||||
gcr.io/google-containers/pause:3.6
|
||||
```
|
||||
|
||||
> 💡 **笔者提示**:如果不指定 Registry 地址,默认使用 Docker Hub。如果不指定标签,默认使用 `latest`。
|
||||
|
||||
### 2.3.3 公共 Registry 服务
|
||||
@@ -104,7 +100,6 @@ gcr.io/google-containers/pause:3.6
|
||||
- 付费账户支持私有仓库
|
||||
|
||||
```bash
|
||||
|
||||
## 从 Docker Hub 拉取镜像
|
||||
|
||||
$ docker pull nginx # 官方镜像
|
||||
@@ -115,7 +110,6 @@ $ docker pull bitnami/redis # 第三方镜像
|
||||
$ docker login
|
||||
$ docker push username/myapp:v1.0
|
||||
```
|
||||
|
||||
#### 其他公共 Registry
|
||||
|
||||
除了 Docker Hub,还有以下几个常见的公共 Registry:
|
||||
@@ -140,7 +134,6 @@ $ docker push username/myapp:v1.0
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
详细配置方法请参考[镜像加速器](../03_install/3.9_mirror.md)章节。
|
||||
|
||||
> ⚠️ **笔者提醒**:镜像加速器的可用性经常变化,使用前建议先测试是否可用。
|
||||
@@ -154,7 +147,6 @@ $ docker push username/myapp:v1.0
|
||||
Docker 官方提供了 [registry](https://hub.docker.com/_/registry/) 镜像,可以快速搭建私有 Registry:
|
||||
|
||||
```bash
|
||||
|
||||
## 启动一个本地 Registry
|
||||
|
||||
$ docker run -d -p 5000:5000 --name registry registry:2
|
||||
@@ -168,7 +160,6 @@ $ docker push localhost:5000/myapp:v1.0
|
||||
|
||||
$ docker pull localhost:5000/myapp:v1.0
|
||||
```
|
||||
|
||||
#### 企业级解决方案
|
||||
|
||||
官方 Registry 功能较为基础,企业环境常用以下方案:
|
||||
@@ -208,13 +199,11 @@ $ docker pull localhost:5000/myapp:v1.0
|
||||
│ │ docker run │
|
||||
│ │ 运行容器 │
|
||||
```
|
||||
|
||||
图 2-3:镜像构建、推送与拉取流程
|
||||
|
||||
#### 常用命令
|
||||
|
||||
```bash
|
||||
|
||||
## 登录 Registry
|
||||
|
||||
$ docker login # 登录 Docker Hub
|
||||
@@ -236,7 +225,6 @@ $ docker push registry.example.com/myteam/myapp:v1.0
|
||||
|
||||
$ docker logout
|
||||
```
|
||||
|
||||
### 2.3.7 镜像的安全性
|
||||
|
||||
在使用公共镜像或维护私有镜像时,安全性是不容忽视的重要环节。
|
||||
@@ -246,7 +234,6 @@ $ docker logout
|
||||
Docker Hub 的[官方镜像](https://hub.docker.com/search?q=&type=image&image_filter=official) (标有 “Official Image” 标识) 经过 Docker 团队审核,相对更安全。示例如下:
|
||||
|
||||
```bash
|
||||
|
||||
## 官方镜像示例
|
||||
|
||||
nginx # ✅ 官方
|
||||
@@ -258,7 +245,6 @@ redis # ✅ 官方
|
||||
bitnami/redis # ⚠️ 需要评估
|
||||
someuser/myapp # ⚠️ 需要评估
|
||||
```
|
||||
|
||||
#### 镜像签名
|
||||
|
||||
当前更推荐使用 Sigstore / Notation 体系进行镜像签名与验证。`Docker Content Trust (DCT)` 已进入退场阶段,不建议作为新项目主方案。
|
||||
@@ -266,7 +252,6 @@ someuser/myapp # ⚠️ 需要评估
|
||||
> 注意:Cosign 默认会把签名写回镜像所在仓库,请使用你有推送权限的镜像地址。
|
||||
|
||||
```bash
|
||||
|
||||
## 准备一个你有写权限的镜像地址
|
||||
$ export IMAGE=<你的仓库名>/nginx:1.27
|
||||
$ docker pull nginx:1.27
|
||||
@@ -280,11 +265,9 @@ $ cosign generate-key-pair
|
||||
$ cosign sign --key cosign.key $IMAGE
|
||||
$ cosign verify --key cosign.pub $IMAGE
|
||||
```
|
||||
|
||||
#### 漏洞扫描
|
||||
|
||||
```bash
|
||||
|
||||
## 使用 Docker Scout 扫描镜像漏洞
|
||||
|
||||
$ docker scout cves nginx:latest
|
||||
|
||||
Reference in New Issue
Block a user