mirror of
https://github.com/yeasy/docker_practice.git
synced 2026-08-11 08:57:34 +00:00
Compare commits
92
Commits
11369ba10a
..
v1.9.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2cea196860 | ||
|
|
13fc8b34f0 | ||
|
|
29742c8f74 | ||
|
|
7cae0b6bb3 | ||
|
|
10381deee4 | ||
|
|
625d209fa8 | ||
|
|
b148d9efa9 | ||
|
|
4cb91a75f3 | ||
|
|
bf3107b775 | ||
|
|
7e3f90b522 | ||
|
|
e6527ae769 | ||
|
|
9c378b1ef9 | ||
|
|
340c8c9e61 | ||
|
|
89c2690a62 | ||
|
|
c554799b08 | ||
|
|
99c56217f5 | ||
|
|
9c98e35c62 | ||
|
|
0e0afbd4d3 | ||
|
|
30f0115cb9 | ||
|
|
62f48c1417 | ||
|
|
fab4e41587 | ||
|
|
229aec2f1e | ||
|
|
8ebf284f9e | ||
|
|
a89f7285c7 | ||
|
|
15c7fe1dc2 | ||
|
|
4d1e323faf | ||
|
|
16203c5018 | ||
|
|
3d3befa16a | ||
|
|
09fd556c18 | ||
|
|
37e376d578 | ||
|
|
04fd53ea3c | ||
|
|
b1cd2f0878 | ||
|
|
e416a1be7e | ||
|
|
e406ed9185 | ||
|
|
c36c420c7e | ||
|
|
72513eb673 | ||
|
|
8ea52620cc | ||
|
|
22dd236122 | ||
|
|
98f4f7b1e5 | ||
|
|
87bb4b2ceb | ||
|
|
dad26ccb28 | ||
|
|
84a801f3ac | ||
|
|
420a5776ce | ||
|
|
b2839f735c | ||
|
|
98e299a38e | ||
|
|
aa204fb454 | ||
|
|
1e9cdeea3f | ||
|
|
515ba9f64a | ||
|
|
9abc1cbb69 | ||
|
|
839a63f5af | ||
|
|
20a3479f8a | ||
|
|
52329fee5a | ||
|
|
8093b198ce | ||
|
|
77a537df54 | ||
|
|
e414d9475b | ||
|
|
037591e5af | ||
|
|
94f74fc86e | ||
|
|
4b44d64cd8 | ||
|
|
49a85c802e | ||
|
|
2a7f7d9a3d | ||
|
|
544ede8498 | ||
|
|
54a9a6e55b | ||
|
|
27617ea619 | ||
|
|
69fc2234d0 | ||
|
|
ac92e6c536 | ||
|
|
1fc64ab875 | ||
|
|
c9c72618c3 | ||
|
|
4b93651989 | ||
|
|
b3d1508310 | ||
|
|
1d780f70c5 | ||
|
|
ff48ac79ee | ||
|
|
077e55f494 | ||
|
|
1bed644e5e | ||
|
|
da5867c921 | ||
|
|
407d508590 | ||
|
|
6fcb74bccc | ||
|
|
d81405a807 | ||
|
|
983e7c18c3 | ||
|
|
9e194b9a74 | ||
|
|
6b2ebd12ac | ||
|
|
f86e3567e8 | ||
|
|
2dacddb999 | ||
|
|
422123dd70 | ||
|
|
adee45f7bc | ||
|
|
04b81a8c05 | ||
|
|
e85ca7a11e | ||
|
|
66905627b8 | ||
|
|
aec453b9bb | ||
|
|
565b40ab0b | ||
|
|
50fe8ebbbb | ||
|
|
c84927c196 | ||
|
|
2b0c00c5e5 |
@@ -16,9 +16,13 @@ jobs:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Install Chromium and CJK fonts
|
||||
uses: browser-actions/setup-chrome@v2
|
||||
with:
|
||||
chrome-version: stable
|
||||
- name: Install CJK fonts
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y chromium-browser fonts-noto-cjk fonts-noto-cjk-extra
|
||||
sudo apt-get install -y fonts-noto-cjk fonts-noto-cjk-extra
|
||||
|
||||
- name: Install mdpress (latest)
|
||||
run: |
|
||||
|
||||
@@ -17,9 +17,13 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Install Chromium and CJK fonts
|
||||
uses: browser-actions/setup-chrome@v2
|
||||
with:
|
||||
chrome-version: stable
|
||||
- name: Install CJK fonts
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y chromium-browser fonts-noto-cjk fonts-noto-cjk-extra
|
||||
sudo apt-get install -y fonts-noto-cjk fonts-noto-cjk-extra
|
||||
- name: Install mdpress (latest)
|
||||
run: |
|
||||
LATEST_TAG=$(curl -fsSL -H "Accept: application/vnd.github+json" -H "Authorization: Bearer ${{ github.token }}" https://api.github.com/repos/yeasy/mdpress/releases/latest | jq -r .tag_name)
|
||||
|
||||
@@ -23,9 +23,13 @@ jobs:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Install Chromium and CJK fonts
|
||||
uses: browser-actions/setup-chrome@v2
|
||||
with:
|
||||
chrome-version: stable
|
||||
- name: Install CJK fonts
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y chromium-browser fonts-noto-cjk fonts-noto-cjk-extra
|
||||
sudo apt-get install -y fonts-noto-cjk fonts-noto-cjk-extra
|
||||
|
||||
- name: Install mdpress (latest)
|
||||
run: |
|
||||
|
||||
@@ -172,7 +172,7 @@ registry.example.com/myproject/myapp:v1.2.3
|
||||
|
||||
## 简写(使用 Docker Hub)
|
||||
|
||||
nginx:1.25
|
||||
nginx:1.30
|
||||
ubuntu:24.04
|
||||
|
||||
## 省略标签(默认使用 latest)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## 2.3 仓库
|
||||
|
||||
> **版本说明**:本节示例基于 Docker v29.x 和常见镜像版本编写。示例中的版本号(如 `nginx:1.25`、`mysql:8.0`、`mysql:5.7` 等)为演示用途。实际使用时请访问 [Docker Hub 官方页面](https://hub.docker.com) 或相应镜像的发布页确认最新可用版本和标签。
|
||||
> **版本说明**:本节示例基于 Docker v29.x 和常见镜像版本编写。示例中的版本号(如 `nginx:1.30`、`mysql:8.4`、`mysql:5.7` 等)为演示用途。实际使用时请访问 [Docker Hub 官方页面](https://hub.docker.com) 或相应镜像的发布页确认最新可用版本和标签。
|
||||
|
||||
Docker Registry 是镜像分发和管理的核心组件。本节将介绍 Registry 的基本概念、公共和私有服务的选择,以及镜像的安全管理。
|
||||
|
||||
@@ -73,7 +73,7 @@ registry.example.com/mycompany/myapp:v1.2.3
|
||||
|
||||
## Docker Hub 官方镜像(省略 registry 和用户名)
|
||||
|
||||
nginx:1.25
|
||||
nginx:1.30
|
||||
ubuntu:24.04
|
||||
|
||||
## Docker Hub 用户镜像
|
||||
@@ -217,7 +217,7 @@ $ docker login registry.example.com # 登录其他 Registry
|
||||
|
||||
## 拉取镜像
|
||||
|
||||
$ docker pull nginx:1.25
|
||||
$ docker pull nginx:1.30
|
||||
|
||||
## 标记镜像(准备推送)
|
||||
|
||||
@@ -261,9 +261,9 @@ someuser/myapp # ⚠️ 需要评估
|
||||
|
||||
```bash
|
||||
## 准备一个你有写权限的镜像地址
|
||||
$ export IMAGE=<你的仓库名>/nginx:1.27
|
||||
$ docker pull nginx:1.27
|
||||
$ docker tag nginx:1.27 $IMAGE
|
||||
$ export IMAGE=<你的仓库名>/nginx:1.30
|
||||
$ docker pull nginx:1.30
|
||||
$ docker tag nginx:1.30 $IMAGE
|
||||
$ docker push $IMAGE
|
||||
|
||||
## 生成签名密钥(会生成 cosign.key / cosign.pub)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
> **版本号最佳实践**
|
||||
>
|
||||
> - **永远指定版本号**:避免使用 `latest` 标签,应指定具体的版本(如 `ubuntu:24.04`、`nginx:1.27`),以确保镜像内容稳定一致。
|
||||
> - **永远指定版本号**:避免使用 `latest` 标签,应指定具体的版本(如 `ubuntu:24.04`、`nginx:1.30`),以确保镜像内容稳定一致。
|
||||
> - **在生产环境使用摘要**:优先使用镜像摘要(SHA256)而非标签,如 `nginx@sha256:abc123...`,因为摘要不可变。
|
||||
> - **定期评估依赖**:即使指定了版本号,仍应定期检查依赖的基础镜像是否有安全更新。
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
现在让我们以定制一个 Web 服务器为例子,来讲解镜像是如何构建的。
|
||||
|
||||
> **版本提示**:以下示例中 `nginx` 镜像使用默认 `latest` 标签。生产环境建议指定具体版本号(如 `nginx:1.27`),以避免镜像更新带来的不兼容性。
|
||||
> **版本提示**:以下示例中 `nginx` 镜像使用默认 `latest` 标签。生产环境建议指定具体版本号(如 `nginx:1.30`),以避免镜像更新带来的不兼容性。
|
||||
|
||||
```bash
|
||||
$ docker run --name webserver -d -p 8080:80 nginx
|
||||
@@ -89,11 +89,11 @@ sha256:07e33465974800ce65751acc279adc6ed2dc5ed4e0838f8b86f0c87aa1795214
|
||||
$ docker image ls nginx
|
||||
REPOSITORY TAG IMAGE ID CREATED SIZE
|
||||
nginx v2 07e334659748 9 seconds ago 181.5 MB
|
||||
nginx 1.27 05a60462f8ba 12 days ago 181.5 MB
|
||||
nginx 1.30 05a60462f8ba 12 days ago 181.5 MB
|
||||
nginx latest e43d811ce2f4 4 weeks ago 181.5 MB
|
||||
```
|
||||
|
||||
> **版本说明**:上面示例中 `nginx:1.27` 代表 1.27 系列的最新 patch 版本。在实际应用中应根据需求选择确切的版本号,而不是盲目使用 `latest`。
|
||||
> **版本说明**:上面示例中 `nginx:1.30` 代表 1.30 系列的最新 patch 版本。在���际应用中应根据需求选择确切的版本号,而不是盲目使用 `latest`。
|
||||
|
||||
我们还可以用 `docker history` 具体查看镜像内的历史记录。例如先执行 `docker history nginx:v2`,再对比 `docker history nginx:latest`,就能看到我们刚刚提交出来的新层。
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ $ touch Dockerfile
|
||||
```
|
||||
其内容为:
|
||||
|
||||
> **版本提示**:下面示例中 `FROM nginx` 使用的是 `latest` 标签。在实际应用中应使用明确的版本号(如 `FROM nginx:1.27`),以确保 Dockerfile 的可重现性和稳定性。
|
||||
> **版本提示**:下面示例中 `FROM nginx` 使用的是 `latest` 标签。在实际应用中应使用明确的版本号(如 `FROM nginx:1.30`),以确保 Dockerfile 的可重现性和稳定性。
|
||||
|
||||
```docker
|
||||
FROM nginx
|
||||
|
||||
@@ -60,7 +60,7 @@ Docker 镜像的每一层都有一个唯一的 ID,这个 ID 是根据该层的
|
||||
|
||||
Docker 使用联合文件系统 (Union FS) 与写时复制思路来实现这种分层挂载。传统的实现方式常见于 `overlay2`、`aufs`、`btrfs`、`zfs` 等存储驱动;而在 Docker Engine 29.0 及之后的全新安装中,默认镜像后端已经变为 containerd image store,它使用 snapshotter 来管理这些层。
|
||||
|
||||
> **版本背景**:Docker Engine 29.0(发布于 2024 年 2 月)是一个重要版本分界点,引入了 containerd image store 作为默认镜像存储后端。这对镜像管理、OCI 合规性和供应链安全都有深远影响。如果你的 Docker 版本低于 29.0,镜像存储仍使用传统的 classic store 路径。
|
||||
> **版本背景**:Docker Engine 29.0(发布于 2025 年 11 月)是一个重要版本分界点,在全新安装场景下默认启用 containerd image store 作为镜像存储后端。这对镜像管理、OCI 合规性和供应链安全都有深远影响。如果你的 Docker 版本低于 29.0,镜像存储仍使用传统的 classic store 路径。
|
||||
|
||||
虽然底层实现细节不同,但它们都遵循上述的 **分层 + CoW** 模型;因此,无论你看到的是 `overlay2` 还是 containerd snapshotter,理解镜像层、容器层和写时复制的方式都是一样重要的。
|
||||
|
||||
|
||||
@@ -126,14 +126,14 @@ $ docker run -d -p 80:80 nginx:latest
|
||||
|
||||
## 数据库
|
||||
|
||||
$ docker run -d -p 3306:3306 mysql:8.0
|
||||
$ docker run -d -p 3306:3306 mysql:8.4
|
||||
|
||||
## 缓存服务
|
||||
|
||||
$ docker run -d -p 6379:6379 redis:latest
|
||||
```
|
||||
|
||||
> **版本说明**:示例使用常见的标签如 `latest` 或稳定大版本号如 `mysql:8.0`。具体版本可根据需求调整,生产环境建议明确指定版本号(如 `mysql:8.0.35`)而非使用 `latest`。
|
||||
> **版本说明**:示例使用常见的标签如 `latest` 或稳定大版本号如 `mysql:8.4`。具体版本可根据需求调整,生产环境建议明确指定版本号(如 `mysql:8.4.4`)而非使用 `latest`。
|
||||
|
||||
#### 2. 调试时先用前台模式
|
||||
|
||||
@@ -196,9 +196,9 @@ $ docker logs -t myapp
|
||||
|
||||
3. **以交互模式调试**:
|
||||
```bash
|
||||
# /bin/sh 覆盖镜像原本的启动命令,避免容器再次崩溃退出
|
||||
# 进入 shell 后可手动执行原启动命令,定位具体报错原因
|
||||
$ docker run -it myimage:v1.0.0 /bin/sh
|
||||
# 进入容器手动执行命令,查找问题
|
||||
|
||||
```
|
||||
|
||||
#### Q:容器在后台运行但无法访问服务
|
||||
|
||||
@@ -212,7 +212,7 @@ FROM node:22-alpine
|
||||
CMD ["node", "server.js"]
|
||||
```
|
||||
|
||||
> **版本说明**:示例使用 `node:22-alpine`,这是一个精简的 Node.js 22 版本镜像。可根据需求替换为其他版本(如 `node:20-alpine`、`node:latest`)。
|
||||
> **版本说明**:示例使用 `node:22-alpine`,这是一个精简的 Node.js 22 版本镜像。可根据需求替换为其他版本(如 `node:24-alpine`、`node:latest`)。
|
||||
|
||||
#### Q:容器无法停止
|
||||
|
||||
|
||||
@@ -10,11 +10,11 @@
|
||||
|
||||
本章示例涉及多个 Docker 镜像,遵循以下版本号最佳实践:
|
||||
|
||||
- **官方镜像**(如 `ubuntu`、`nginx`、`mysql`):使用具体大版本号(如 `ubuntu:24.04`、`mysql:8.0`)而非 `latest`,确保示例的可重复性
|
||||
- **官方镜像**(如 `ubuntu`、`nginx`、`mysql`):使用具体大版本号(如 `ubuntu:24.04`、`mysql:8.4`)而非 `latest`,确保示例的可重复性
|
||||
- **镜像标签约定**:
|
||||
- `latest` 或 `v1.0.0` 等:带标签的自定义镜像,示例中指定具体版本
|
||||
- `24.04`、`8.0`:官方镜像的稳定版本分支
|
||||
- 生产环境建议:指定精确版本号(如 `nginx:1.24.0`、`mysql:8.0.35`)而非仅大版本号
|
||||
- `24.04`、`8.4`:官方镜像的稳定版本分支
|
||||
- 生产环境建议:指定���确版本号(如 `nginx:1.30.0`、`mysql:8.4.4`)而非仅大版本号
|
||||
|
||||
* [启动容器](5.1_run.md)
|
||||
* [守护态运行](5.2_daemon.md)
|
||||
|
||||
@@ -80,7 +80,7 @@ server {
|
||||
ssl_certificate_key key/example.key;
|
||||
|
||||
ssl_session_timeout 5m;
|
||||
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||
ssl_prefer_server_ciphers on;
|
||||
large_client_header_buffers 4 32k;
|
||||
|
||||
@@ -82,9 +82,9 @@ RUN pwd # 输出 /app
|
||||
|
||||
```docker
|
||||
## 构建阶段
|
||||
## 建议使用 node:20 或 node: 等具体版本标签,避免使用 latest
|
||||
## 建议使用 node:22 或 node: 等具体版本标签,避免使用 latest
|
||||
|
||||
FROM node:20 AS builder
|
||||
FROM node:22 AS builder
|
||||
WORKDIR /build
|
||||
COPY package*.json ./
|
||||
RUN npm install
|
||||
@@ -105,8 +105,8 @@ COPY --from=builder /build/dist .
|
||||
#### 1. 尽早设置 WORKDIR
|
||||
|
||||
```docker
|
||||
# 建议使用 node:20 等主/次版本号标签
|
||||
FROM node:20
|
||||
# 建议使用 node:22 等主/次版本号标签
|
||||
FROM node:22
|
||||
WORKDIR /app # 尽早设置
|
||||
|
||||
COPY package*.json ./
|
||||
|
||||
@@ -35,7 +35,7 @@ flowchart LR
|
||||
#### 创建并切换用户
|
||||
|
||||
```docker
|
||||
FROM node:20-alpine
|
||||
FROM node:22-alpine
|
||||
|
||||
## 1. 创建用户和组
|
||||
|
||||
@@ -173,7 +173,7 @@ $ docker run -u root myimage
|
||||
切换用户后,确保应用有权访问文件:
|
||||
|
||||
```docker
|
||||
FROM node:20-alpine
|
||||
FROM node:22-alpine
|
||||
|
||||
## 创建用户
|
||||
|
||||
@@ -229,14 +229,14 @@ USER 1000:1000
|
||||
```docker
|
||||
## 构建阶段可以用 root
|
||||
|
||||
FROM node:20 AS builder
|
||||
FROM node:22 AS builder
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
RUN npm install && npm run build
|
||||
|
||||
## 生产阶段用非 root
|
||||
|
||||
FROM node:20-alpine
|
||||
FROM node:22-alpine
|
||||
RUN adduser -D appuser
|
||||
WORKDIR /app
|
||||
COPY --from=builder --chown=appuser:appuser /app/dist .
|
||||
|
||||
@@ -34,7 +34,7 @@ Starting ──成功──> Healthy ──失败N次──> Unhealthy
|
||||
#### Web 服务检查
|
||||
|
||||
```docker
|
||||
# 注:nginx 镜像推荐使用具体的版本标签(如 nginx:1.25-alpine)
|
||||
# 注:nginx 镜像推荐使用具体的版本标签(如 nginx:1.30-alpine)
|
||||
FROM nginx
|
||||
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ ONBUILD <其它指令>
|
||||
**基础镜像 (my-node-base)**:
|
||||
|
||||
```docker
|
||||
FROM node:20-alpine
|
||||
FROM node:22-alpine
|
||||
WORKDIR /app
|
||||
|
||||
## 这些指令将在子镜像构建时执行
|
||||
@@ -126,7 +126,7 @@ ONBUILD COPY dist/ /usr/share/nginx/html/
|
||||
建议在镜像标签中添加 `-onbuild` 后缀,明确告知使用者该镜像包含触发器。
|
||||
|
||||
```bash
|
||||
node:20-onbuild
|
||||
node:22-onbuild
|
||||
python:3.12-onbuild
|
||||
```
|
||||
|
||||
|
||||
@@ -14,12 +14,20 @@ Dockerfile 中的常用指令包括:
|
||||
|
||||
- **FROM**: 指定基础镜像,必须是第一条指令
|
||||
- **RUN**: 在镜像中执行命令,用于安装软件包等
|
||||
- **WORKDIR**: 设置工作目录
|
||||
- **COPY/ADD**: 复制文件到镜像中
|
||||
- **EXPOSE**: 声明容器监听的端口
|
||||
- **ENV**: 设置环境变量
|
||||
- **ENTRYPOINT**: 容器启动时的入口点
|
||||
- **COPY**: 复制文件到镜像中
|
||||
- **ADD**: 更高级的复制文件(支持 URL 和自动解压)
|
||||
- **CMD**: 容器默认执行的命令
|
||||
- **ENTRYPOINT**: 容器启动时的入口点
|
||||
- **ENV**: 设置环境变量
|
||||
- **ARG**: 构建时的参数变量
|
||||
- **VOLUME**: 定义匿名卷挂载点
|
||||
- **EXPOSE**: 声明容器监听的端口
|
||||
- **WORKDIR**: 设置工作目录
|
||||
- **USER**: 指定运行容器时的用户
|
||||
- **HEALTHCHECK**: 配置容器健康检查
|
||||
- **ONBUILD**: 设置触发器指令,在子镜像构建时执行
|
||||
- **LABEL**: 为镜像添加元数据标签
|
||||
- **SHELL**: 指定 RUN 等指令使用的 shell
|
||||
|
||||
### 最佳实践建议
|
||||
|
||||
|
||||
@@ -176,5 +176,5 @@ $ docker build --target builder -t username/imagename:tag .
|
||||
上面例子中我们使用 `COPY --from=0 /go/src/github.com/go/helloworld/app .` 从上一阶段的镜像中复制文件,我们也可以复制任意镜像中的文件。
|
||||
|
||||
```docker
|
||||
COPY --from=nginx:1.25-alpine /etc/nginx/nginx.conf /nginx.conf
|
||||
COPY --from=nginx:1.30-alpine /etc/nginx/nginx.conf /nginx.conf
|
||||
```
|
||||
|
||||
@@ -60,8 +60,8 @@ server {
|
||||
第一阶段进行前端构建。
|
||||
|
||||
```docker
|
||||
# 注:node 镜像推荐使用具体的版本标签(如 node:20-alpine)
|
||||
FROM node:20-alpine as frontend
|
||||
# 注:node 镜像推荐使用具体的版本标签(如 node:22-alpine)
|
||||
FROM node:22-alpine as frontend
|
||||
|
||||
COPY package.json /app/
|
||||
|
||||
@@ -128,8 +128,8 @@ RUN set -x ; cd ${LARAVEL_PATH} \
|
||||
### 7.18.5 最后一个阶段构建 NGINX 镜像
|
||||
|
||||
```docker
|
||||
# 注:nginx 镜像推荐使用具体的版本标签(如 nginx:1.25-alpine)
|
||||
FROM nginx:1.25-alpine as nginx
|
||||
# 注:nginx 镜像推荐使用具体的版本标签(如 nginx:1.30-alpine)
|
||||
FROM nginx:1.30-alpine as nginx
|
||||
|
||||
ARG LARAVEL_PATH=/app/laravel
|
||||
|
||||
@@ -179,8 +179,8 @@ $ docker run -dit --rm --network=laravel -p 8080:80 my/nginx
|
||||
完整的 `Dockerfile` 文件如下。
|
||||
|
||||
```docker
|
||||
# 注:生产环境推荐使用具体的版本标签,如 node:20-alpine、composer:2.x、php:8.3-fpm-alpine、nginx:1.25-alpine
|
||||
FROM node:20-alpine as frontend
|
||||
# 注:生产环境推荐使用具体的版本标签,如 node:22-alpine、composer:2.x、php:8.3-fpm-alpine、nginx:1.30-alpine
|
||||
FROM node:22-alpine as frontend
|
||||
|
||||
COPY package.json /app/
|
||||
|
||||
@@ -229,7 +229,7 @@ RUN set -x ; cd ${LARAVEL_PATH} \
|
||||
&& chmod -R 777 storage \
|
||||
&& php artisan package:discover
|
||||
|
||||
FROM nginx:1.25-alpine as nginx
|
||||
FROM nginx:1.30-alpine as nginx
|
||||
|
||||
ARG LARAVEL_PATH=/app/laravel
|
||||
|
||||
|
||||
@@ -178,7 +178,7 @@ ADD app.tar.gz /app/
|
||||
```docker
|
||||
## 构建阶段
|
||||
|
||||
FROM node:20 AS builder
|
||||
FROM node:22 AS builder
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm install
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
|
||||
这是 Dockerfile 使用中最常见的困惑之一。简单的答案是:
|
||||
|
||||
- **CMD**:定义容器的”默认命令”。如果用户在 `docker run` 时提供命令,CMD 会被覆盖
|
||||
- **ENTRYPOINT**:定义容器的”入口脚本”。通常用于启动应用的某个特定部分
|
||||
- **CMD**:定义容器的“默认命令”。如果用户在 `docker run` 时提供命令,CMD 会被覆盖
|
||||
- **ENTRYPOINT**:定义容器的“入口脚本”。通常用于启动应用的某个特定部分
|
||||
|
||||
**决策树**:
|
||||
|
||||
|
||||
@@ -158,15 +158,15 @@ $ docker build --build-arg NODE_VERSION=18 -t myapp .
|
||||
```docker
|
||||
## ✅ 好:版本集中管理
|
||||
|
||||
ENV NGINX_VERSION=1.25 \
|
||||
NODE_VERSION=20 \
|
||||
ENV NGINX_VERSION=1.30 \
|
||||
NODE_VERSION=22 \
|
||||
PYTHON_VERSION=3.12
|
||||
|
||||
RUN apt-get install nginx=${NGINX_VERSION}
|
||||
|
||||
## ❌ 差:版本分散在各处
|
||||
|
||||
RUN apt-get install nginx=1.25
|
||||
RUN apt-get install nginx=1.30
|
||||
```
|
||||
|
||||
#### 2. 不要存储敏感信息
|
||||
|
||||
@@ -93,14 +93,14 @@ RUN echo "Node version: $NODE_VERSION"
|
||||
```docker
|
||||
ARG BASE_VERSION=alpine
|
||||
|
||||
FROM node:20-${BASE_VERSION} AS builder
|
||||
FROM node:22-${BASE_VERSION} AS builder
|
||||
|
||||
## 需要重新声明
|
||||
|
||||
ARG NODE_VERSION=20
|
||||
RUN echo "Building with Node $NODE_VERSION"
|
||||
|
||||
FROM node:20-${BASE_VERSION}
|
||||
FROM node:22-${BASE_VERSION}
|
||||
|
||||
## 每个阶段都需要重新声明
|
||||
|
||||
@@ -125,8 +125,8 @@ $ docker build --build-arg ALPINE_VERSION=3.19 .
|
||||
#### 2. 设置软件版本
|
||||
|
||||
```docker
|
||||
# 使用次版本号 (1.25) 而非完整版本号 (1.25.0),以便自动更新到最新补丁版本
|
||||
ARG NGINX_VERSION=1.25
|
||||
# 使用次版本号 (1.30) 而非完整版本号 (1.30.0),以便自动更新到最新补丁版本
|
||||
ARG NGINX_VERSION=1.30
|
||||
|
||||
RUN curl -fsSL https://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz | tar -xz
|
||||
```
|
||||
|
||||
@@ -44,7 +44,7 @@ flowchart LR
|
||||
#### 定义单个卷
|
||||
|
||||
```docker
|
||||
FROM mysql:8.0
|
||||
FROM mysql:8.4
|
||||
VOLUME /var/lib/mysql
|
||||
```
|
||||
|
||||
@@ -63,7 +63,7 @@ VOLUME ["/data", "/logs", "/config"]
|
||||
如果运行时未指定挂载,Docker 会自动创建匿名卷:
|
||||
|
||||
```bash
|
||||
$ docker run mysql:8.0
|
||||
$ docker run mysql:8.4
|
||||
$ docker volume ls
|
||||
DRIVER VOLUME NAME
|
||||
local a1b2c3d4e5f6... # 自动创建的匿名卷
|
||||
@@ -74,7 +74,7 @@ local a1b2c3d4e5f6... # 自动创建的匿名卷
|
||||
```bash
|
||||
## 使用命名卷替代匿名卷
|
||||
|
||||
$ docker run -v mysql_data:/var/lib/mysql mysql:8.0
|
||||
$ docker run -v mysql_data:/var/lib/mysql mysql:8.4
|
||||
```
|
||||
|
||||
#### 3. 可被 Bind Mount 覆盖
|
||||
@@ -82,7 +82,7 @@ $ docker run -v mysql_data:/var/lib/mysql mysql:8.0
|
||||
```bash
|
||||
## 使用宿主机目录替代
|
||||
|
||||
$ docker run -v /my/data:/var/lib/mysql mysql:8.0
|
||||
$ docker run -v /my/data:/var/lib/mysql mysql:8.4
|
||||
```
|
||||
---
|
||||
|
||||
@@ -145,7 +145,7 @@ VOLUME /app/uploads
|
||||
```bash
|
||||
## 查看镜像定义的 VOLUME
|
||||
|
||||
$ docker inspect mysql:8.0 --format '{{json .Config.Volumes}}' | jq
|
||||
$ docker inspect mysql:8.4 --format '{{json .Config.Volumes}}' | jq
|
||||
{
|
||||
"/var/lib/mysql": {}
|
||||
}
|
||||
@@ -196,7 +196,7 @@ volumes:
|
||||
```bash
|
||||
## 使用 --rm 运行的容器,匿名卷会在容器删除时一起删除
|
||||
|
||||
$ docker run --rm mysql:8.0
|
||||
$ docker run --rm mysql:8.4
|
||||
|
||||
## 容器停止后,数据丢失!
|
||||
|
||||
@@ -205,7 +205,7 @@ $ docker run --rm mysql:8.0
|
||||
**解决**:始终使用命名卷
|
||||
|
||||
```bash
|
||||
$ docker run -v mysql_data:/var/lib/mysql mysql:8.0
|
||||
$ docker run -v mysql_data:/var/lib/mysql mysql:8.4
|
||||
```
|
||||
---
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ docker build -t my-image:1.0 .
|
||||
本章中的 Dockerfile 示例使用的基础镜像标签遵循以下原则:
|
||||
|
||||
- **通用标签**(如 `ubuntu:24.04`、`alpine`、`nginx`):保持原样,无需修改
|
||||
- **基础镜像版本号**(如 `node:20`、`python:3.12`):使用主或次版本号而非完整版本号(patch),这样可以自动获取最新的补丁版本,确保获得安全更新
|
||||
- **基础镜像版本号**(如 `node:22`、`python:3.12`):使用主或次版本号而非完整版本号(patch),这样可以自动获取最新的补丁版本,确保获得安全更新
|
||||
- **避免**:不建议使用 `latest` 标签和完整的 patch 版本号(如 `20.10.0`)作为基础镜像,因为这会导致构建的不可重现性或安全风险
|
||||
|
||||
读者在使用这些示例时,应根据实际生产环境需求选择合适的版本号。
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:20-alpine as frontend
|
||||
FROM node:22-alpine as frontend
|
||||
|
||||
COPY package.json /app/
|
||||
|
||||
@@ -47,7 +47,7 @@ RUN set -x ; cd ${LARAVEL_PATH} \
|
||||
&& chmod -R 777 storage \
|
||||
&& php artisan package:discover
|
||||
|
||||
FROM nginx:1.25-alpine as nginx
|
||||
FROM nginx:1.30-alpine as nginx
|
||||
|
||||
ARG LARAVEL_PATH=/app/laravel
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ ghi789... none null local
|
||||
| **none** | 禁用网络 | 完全隔离的容器 |
|
||||
| **overlay** | 跨主机网络 | Docker Swarm 集群 |
|
||||
| **macvlan** | 容器拥有独立 MAC 地址 | 需要直接接入物理网络 |
|
||||
| **ipvlan** | 容器共享父接口 MAC,独享 IP | 同网段大量容器、对 MAC 数量受限的网络 |
|
||||
|
||||
### 9.2.2 Bridge 网络:默认
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ $ docker buildx build --sbom=true -t myimage .
|
||||
> **⚠️ 注意与失败模式**:
|
||||
> 要使 SBOM (或其它 attestation 元数据) 成功附着并可见,对底层的存储格式有前置要求:默认的 classic image store 不支持 manifest list/index 这种存放 attestation 的结构。
|
||||
>
|
||||
> 如果只简单运行上述命令,你可能会面临 **”命令成功执行,但本地镜像中看不到 SBOM”** 的体会落差。
|
||||
> 如果只简单运行上述命令,你可能会面临 **“命令成功执行,但本地镜像中看不到 SBOM”** 的体会落差。
|
||||
>
|
||||
> **正确的解决路径有两条**:
|
||||
> 1. **推送到远端仓库**:使用 `docker buildx build --sbom=true --push -t myimage:tag` 时,SBOM 会正确保存到远端仓库。远端 OCI 兼容的镜像仓库能够完整存储这些元数据。
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
Docker Buildx 是一个 docker CLI 插件,其扩展了 docker 命令,支持 [Moby BuildKit](10.1_buildkit.md) 提供的功能。提供了与 docker build 相同的用户体验,并增加了许多新功能。
|
||||
|
||||
> Buildx 需要 Docker v19.03+ (Docker 19.03 及以上版本)。在较新版本中已更常用且功能更完整。
|
||||
> Buildx 需要 Docker v23.0+(该版本起 BuildKit 成为默认构建引擎)。推荐使用 Docker v28 及以上版本以获得最完整的 Buildx 功能支持。
|
||||
|
||||
## 本章内容
|
||||
|
||||
|
||||
@@ -490,7 +490,7 @@ volumes:
|
||||
```yaml
|
||||
services:
|
||||
my_src:
|
||||
image: mysql:8.0
|
||||
image: mysql:8.4
|
||||
volumes:
|
||||
- mysql_data:/var/lib/mysql
|
||||
|
||||
|
||||
@@ -106,6 +106,11 @@ services:
|
||||
POSTGRES_PASSWORD: password
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U postgres"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
web:
|
||||
build: .
|
||||
@@ -115,7 +120,8 @@ services:
|
||||
ports:
|
||||
- "3000:3000"
|
||||
depends_on:
|
||||
- db
|
||||
db:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
DATABASE_URL: postgres://postgres:password@db:5432/myapp_development
|
||||
|
||||
@@ -128,7 +134,7 @@ volumes:
|
||||
|--------|------|
|
||||
| `rm -f tmp/pids/server.pid` | 清理上次异常退出留下的 PID 文件 |
|
||||
| `volumes: .:/myapp` | 挂载代码目录,支持热更新 |
|
||||
| `depends_on: db` | 确保数据库先启动 |
|
||||
| `depends_on` + `condition` | 等待数据库健康检查通过后再启动 |
|
||||
| `DATABASE_URL` | Rails 12-factor 风格的数据库配置 |
|
||||
|
||||
### 11.7.6 步骤 4:生成 Rails 项目
|
||||
|
||||
@@ -28,13 +28,13 @@ services:
|
||||
# 数据库服务
|
||||
|
||||
db:
|
||||
image: mysql:8.0
|
||||
image: mysql:8.4
|
||||
container_name: wordpress_db
|
||||
restart: always
|
||||
command:
|
||||
# 使用原生密码认证(旧版 WP 兼容性)
|
||||
# 启用原生密码认证(MySQL 8.4 默认禁用,旧版 WP 兼容性需要)
|
||||
|
||||
- --default-authentication-plugin=mysql_native_password
|
||||
- --mysql-native-password=ON
|
||||
- --character-set-server=utf8mb4
|
||||
- --collation-server=utf8mb4_unicode_ci
|
||||
environment:
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
services:
|
||||
|
||||
db:
|
||||
image: mysql:8.0
|
||||
image: mysql:8.4
|
||||
command:
|
||||
- --default_authentication_plugin=mysql_native_password
|
||||
- --mysql-native-password=ON
|
||||
- --character-set-server=utf8mb4
|
||||
- --collation-server=utf8mb4_unicode_ci
|
||||
volumes:
|
||||
|
||||
@@ -41,7 +41,7 @@ flowchart TD
|
||||
每个 Dockerfile 指令创建一层,只有变化的层需要重建:
|
||||
|
||||
```docker
|
||||
FROM node:20 # 层1:基础镜像
|
||||
FROM node:22 # 层1:基础镜像
|
||||
COPY package.json ./ # 层2:依赖定义
|
||||
RUN npm install # 层3:安装依赖
|
||||
COPY . . # 层4:应用代码
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
##### 节点状态
|
||||
|
||||
节点的状态主要是用来描述处于 `Running` 的节点。当前可用的有 `NodeReachable` 和 `NodeReady`。以后可能会增加其他状态。`NodeReachable` 表示集群可达。`NodeReady` 表示 kubelet 返回 Status Ok 并且 HTTP 状态检查健康。
|
||||
节点的状态通过一组条件(Conditions)来描述。主要条件包括 `Ready`(kubelet 健康且可以接收 Pod)、`MemoryPressure`(内存不足)、`DiskPressure`(磁盘不足)和 `PIDPressure`(进程数过多)等。其中 `Ready` 条件最为关键:值为 `True` 表示节点健康可调度,`False` 表示节点异常,`Unknown` 表示节点控制器超过一定时间未收到心跳。
|
||||
|
||||
#### 节点管理
|
||||
|
||||
@@ -200,7 +200,7 @@ spec:
|
||||
spec:
|
||||
containers:
|
||||
- name: mysql
|
||||
image: mysql:8.0
|
||||
image: mysql:8.4
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /var/lib/mysql
|
||||
|
||||
@@ -138,12 +138,14 @@ $ sysctl --system
|
||||
|
||||
为了让 kubelet 正确运行,我们需要对其进行一些必要的配置。
|
||||
|
||||
#### 修改 `kubelet.service`
|
||||
#### 修改 `kubelet.service`(可选:IPVS 模式)
|
||||
|
||||
> **注意**:kube-proxy 的 IPVS 模式已在 Kubernetes 1.35 中被标记为弃用,并计划在后续版本中移除。新部署建议使用默认的 iptables 模式或 nftables 模式(Kubernetes 1.31+ 可用)。以下 IPVS 配置仅供需要兼容旧环境的场景参考。
|
||||
|
||||
`/etc/systemd/system/kubelet.service.d/10-proxy-ipvs.conf` 写入以下内容
|
||||
|
||||
```bash
|
||||
# 启用 ipvs 相关内核模块
|
||||
# 启用 ipvs 相关内核模块(已弃用,建议迁移至 nftables)
|
||||
|
||||
[Service]
|
||||
ExecStartPre=-/sbin/modprobe ip_vs
|
||||
|
||||
@@ -169,12 +169,14 @@ $ sysctl --system
|
||||
|
||||
为了让 kubelet 正确运行,我们需要对其进行一些必要的配置。
|
||||
|
||||
#### 修改 `kubelet.service`
|
||||
#### 修改 `kubelet.service`(可选:IPVS 模式)
|
||||
|
||||
> **注意**:kube-proxy 的 IPVS 模式已在 Kubernetes 1.35 中被标记为弃用,并计划在后续版本中移除。新部署建议使用默认的 iptables 模式或 nftables 模式(Kubernetes 1.31+ 可用)。以下 IPVS 配置仅供需要兼容旧环境的场景参考。
|
||||
|
||||
`/etc/systemd/system/kubelet.service.d/10-proxy-ipvs.conf` 写入以下内容
|
||||
|
||||
```bash
|
||||
# 启用 ipvs 相关内核模块
|
||||
# 启用 ipvs 相关内核模块(已弃用,建议迁移至 nftables)
|
||||
|
||||
[Service]
|
||||
ExecStartPre=-/sbin/modprobe ip_vs
|
||||
|
||||
@@ -193,10 +193,10 @@ $ kubectl label pods -l app=nginx version=v1
|
||||
|
||||
```bash
|
||||
# 添加注解
|
||||
$ kubectl annotate pod my-pod description=”Production pod”
|
||||
$ kubectl annotate pod my-pod description="Production pod"
|
||||
|
||||
# 修改注解
|
||||
$ kubectl annotate pod my-pod description=”Staging pod” --overwrite
|
||||
$ kubectl annotate pod my-pod description="Staging pod" --overwrite
|
||||
|
||||
# 删除注解
|
||||
$ kubectl annotate pod my-pod description-
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## 15.1 简介
|
||||
|
||||
> **版本说明:** 本章内容基于 etcd 3.5 系列版本编写(当前最新为 v3.5.x)。请访问 [etcd 官方发布页](https://github.com/etcd-io/etcd/releases) 获取最新版本信息。
|
||||
> **版本说明:** 本章内容基于 etcd 3.5 系列版本编写。官方维护最新两个次版本(当前为 3.5 和 3.6)。请访问 [etcd 官方发布页](https://github.com/etcd-io/etcd/releases) 获取最新版本信息。
|
||||
|
||||
如图 15-1 所示,etcd 项目使用该标识。
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
`etcd` 基于 `Go` 语言实现,因此,用户可以从[项目主页](https://github.com/etcd-io/etcd)下载源代码自行编译,也可以下载编译好的二进制文件,甚至直接使用制作好的 `Docker` 镜像文件来体验。
|
||||
|
||||
> 注意:etcd 官方仅维护最新两个次版本(当前为 3.5 和 3.6)。本章示例基于 etcd `3.5.x` 版本编写。etcd 3.6.x 可用于新部署。请访问 [etcd 官方发布页](https://github.com/etcd-io/etcd/releases) 获取最新版本。
|
||||
> 注意:etcd 官方仅维护最新两个次版本(当前为 3.5 和 3.6)。etcd 3.4 已于 2026 年 5 月结束支持(EOL),仍在使用 3.4 的用户应尽快升级。本章示例基于 etcd `3.5.x` 版本编写。etcd 3.6.x 可用于新部署。请访问 [etcd 官方发布页](https://github.com/etcd-io/etcd/releases) 获取最新版本。
|
||||
|
||||
### 15.2.1 二进制文件方式下载
|
||||
|
||||
|
||||
@@ -111,9 +111,11 @@ hello
|
||||
```
|
||||
支持的选项为
|
||||
|
||||
`--sort` 对结果进行排序
|
||||
`--sort-by` 指定排序字段(CREATE / KEY / MODIFY / VALUE / VERSION)
|
||||
|
||||
`--consistent` 将请求发给主节点,保证获取内容的一致性
|
||||
`--order` 指定排序顺序(ASCEND / DESCEND)
|
||||
|
||||
`--consistency` 指定一致性级别(`l` 线性一致,`s` 串行)
|
||||
|
||||
#### del
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ version: "3.6"
|
||||
services:
|
||||
|
||||
node1:
|
||||
image: quay.io/coreos/etcd:v3.5.17
|
||||
image: quay.io/coreos/etcd:v3.5.29
|
||||
volumes:
|
||||
- node1-data:/etcd-data
|
||||
expose:
|
||||
@@ -34,7 +34,7 @@ services:
|
||||
- docker-etcd
|
||||
|
||||
node2:
|
||||
image: quay.io/coreos/etcd:v3.5.17
|
||||
image: quay.io/coreos/etcd:v3.5.29
|
||||
volumes:
|
||||
- node2-data:/etcd-data
|
||||
networks:
|
||||
@@ -66,7 +66,7 @@ services:
|
||||
- docker-etcd
|
||||
|
||||
node3:
|
||||
image: quay.io/coreos/etcd:v3.5.17
|
||||
image: quay.io/coreos/etcd:v3.5.29
|
||||
volumes:
|
||||
- node3-data:/etcd-data
|
||||
networks:
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
Skopeo 是一个由 Red Hat 赞助开源的命令行工具,它可以在不需要运行容器守护进程(如 Docker Daemon)的前提下,对容器镜像进行极其高效的操作和管理,包括:检查、复制、删除和签名等操作。
|
||||
|
||||
Skopeo 最大的特点是其可以在”不将镜像拉取到本地”的情况下,直接在远端 Registry(镜像仓库)之间完成检查和搬运,从而大幅度节省带宽和磁盘空间。这也是它在容器运维和分发领域非常受欢迎的原因。
|
||||
Skopeo 最大的特点是其可以在“不将镜像拉取到本地”的情况下,直接在远端 Registry(镜像仓库)之间完成检查和搬运,从而大幅度节省带宽和磁盘空间。这也是它在容器运维和分发领域非常受欢迎的原因。
|
||||
|
||||
### 17.5.2 核心特性
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
Kubernetes 作为一个容器编排系统,为了屏蔽底层不同容器运行时的实现差异,引入了 CRI(Container Runtime Interface)标准。
|
||||
|
||||
- 早期版本中,Kubernetes 默认使用 docker 作为运行时,通过一个名为 `dockershim` 的桥接组件对接 Docker,Docker 再对接 containerd。
|
||||
- 随着 containerd 原生支持了 CRI 插件,Kubernetes 开始直接与 containerd 通信,去掉了 `dockershim` 和 `dockerd` 的中间层。这就是为什么从 Kubernetes 1.24+ 开始”弃用 Docker”引发了广泛关注,实际上 Kubernetes 只是弃用 `dockershim`,底层依然在使用从 Docker 基因中诞生的 containerd。参见 [Kubernetes 官方文档](https://kubernetes.io/docs/setup/production-environment/container-runtimes/#containerd)。
|
||||
- 随着 containerd 原生支持了 CRI 插件,Kubernetes 开始直接与 containerd 通信,去掉了 `dockershim` 和 `dockerd` 的中间层。这就是为什么从 Kubernetes 1.24+ 开始“弃用 Docker”引发了广泛关注,实际上 Kubernetes 只是弃用 `dockershim`,底层依然在使用从 Docker 基因中诞生的 containerd。参见 [Kubernetes 官方文档](https://kubernetes.io/docs/setup/production-environment/container-runtimes/#containerd)。
|
||||
- containerd 2.0+ 移除了已弃用的 CRI v1alpha2 接口,仅保留 CRI v1(Kubernetes 1.26+ 仅支持 CRI v1)。如果集群中仍有依赖 CRI v1alpha2 的组件,升级 containerd 2.x 前需先完成迁移。containerd 2.3+ 是 2.x 系列首个 LTS 版本,支持从 1.7 LTS 直接升级,生产环境推荐使用。详见 [containerd 发布说明](https://github.com/containerd/containerd/releases)。
|
||||
|
||||
### 17.6.3 为什么直接使用 containerd?
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
尽管这种方式在性能和启动速度上拥有巨大优势,但也带来了一个显著的缺点:**隔离性(Isolation)不足**。如果某个容器内的恶意进程利用了宿主机内核的漏洞完成了越狱(Privilege Escalation),它将对整个宿主机以及其上运行的所有其他容器造成毁灭性威胁。
|
||||
|
||||
如果在公有云环境(多租户场景)或运行不可信的第三方代码时,共享内核显然是不够安全的。为了解决这一问题,社区推出了”安全容器(Secure Containers/Sandboxed Containers)”的概念。安全容器的核心理念是:提供类似虚拟机的强隔离性,同时保持类似容器的轻量、快速启动和标准化管理。
|
||||
如果在公有云环境(多租户场景)或运行不可信的第三方代码时,共享内核显然是不够安全的。为了解决这一问题,社区推出了“安全容器(Secure Containers/Sandboxed Containers)”的概念。安全容器的核心理念是:提供类似虚拟机的强隔离性,同时保持类似容器的轻量、快速启动和标准化管理。
|
||||
|
||||
### 17.7.2 什么是 Kata Containers?
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ Docker 守护进程在启动容器时,会在后台为容器创建一套独立
|
||||
|
||||
尽管命名空间提供了很好的隔离性,但我们必须认识到:**所有的容器依然共享同一个宿主机的 Linux 内核**。
|
||||
|
||||
这意味着,一旦宿主机的内核存在提权漏洞(如著名的 Dirty COW 漏洞),攻击者有可能通过突破 Namespace 的限制,直接在内核层面执行恶意代码,从而实现”容器逃逸”。
|
||||
这意味着,一旦宿主机的内核存在提权漏洞(如著名的 Dirty COW 漏洞),攻击者有可能通过突破 Namespace 的限制,直接在内核层面执行恶意代码,从而实现“容器逃逸”。
|
||||
|
||||
> [!WARNING]
|
||||
> 为了缓解内核漏洞带来的威胁,生产环境务必保持宿主机 Linux 内核的及时修补与更新,或者借助诸如 gVisor、Kata Containers 等提供了独立内核的安全容器技术。同时,需要及时修补容器运行时(如 runC)的漏洞。2025 年 11 月披露的一系列 runC 容器逃逸漏洞(CVE-2025-31133、CVE-2025-52565、CVE-2025-52881)就表明,即使内核保持更新,运行时层的缺陷仍然可能导致容器隔离被突破。
|
||||
|
||||
@@ -50,7 +50,7 @@ dockerd \
|
||||
|
||||
### 18.3.3 Rootless 模式:非特权运行
|
||||
|
||||
为了从根本上解决“拥有 Docker socket 就是 root”的问题,Docker 在近年推出了 **Rootless 模式**。
|
||||
为了从根本上解决“拥有 Docker socket 就是 root”的问题,Docker 自 19.03 版本(2019 年)起提供了 **Rootless 模式**。
|
||||
|
||||
Rootless 模式允许在完全局限于非 `root` 用户的环境中运行 Docker 守护进程(`dockerd`)和容器。该模式利用了现代 Linux 内核的 User Namespace 技术和非特权网络命名空间实现。
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
一个普通的 Linux 内核提供了 300 多个系统调用,而一个正常运行的容器化应用(例如 Nginx 服务)通常只会用到几十个调用,这就给攻击者留下了大量的闲置入口点来进行内核层的缓冲区溢出攻击。
|
||||
|
||||
Docker 默认启用了 Seccomp 并利用预置的 [默认配置文件](https://github.com/moby/moby/blob/master/profiles/seccomp/default.json) 将可以利用的系统调用缩减到了不足一半(默认禁用了 44 个危险的统调用,比如修改时区或重启系统)。
|
||||
Docker 默认启用了 Seccomp 并利用预置的 [默认配置文件](https://github.com/moby/moby/blob/master/profiles/seccomp/default.json) 将可以利用的系统调用缩减到了不足一半(默认禁用了 44 个危险的系统调用,比如修改时区或重启系统)。
|
||||
|
||||
如果你对应用的系统调用特征了如指掌,你可以为容器定制专属规则。
|
||||
|
||||
|
||||
@@ -434,8 +434,8 @@ jobs:
|
||||
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
|
||||
|
||||
- name: Run Trivy vulnerability scan
|
||||
# 安全提醒:2026 年 3 月 Trivy GitHub Actions 遭受供应链攻击,
|
||||
# 75 个版本标签被劫持。务必使用不可变的 commit SHA 引用,而非可变标签。
|
||||
# 安全提醒:2026 年 3 月 19 日 Trivy GitHub Actions 遭受供应链攻击,
|
||||
# 76 个版本标签被劫持。务必使用不可变的 commit SHA 引用,而非可变标签。
|
||||
# 使用前请到 https://github.com/aquasecurity/trivy-action/releases 核实 SHA 对应正确版本。
|
||||
uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1 # v0.35.0
|
||||
with:
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
- **容器监控**:以 Prometheus 为主,讲解如何采集和展示容器性能指标。
|
||||
- **日志管理**:以 ELK (Elasticsearch, Logstash, Kibana) 套件为例,介绍集中式日志收集平台。
|
||||
|
||||
为了让读者能够在生产环境中真正用起来,本章会补齐以下”最小闭环”:
|
||||
为了让读者能够在生产环境中真正用起来,本章会补齐以下“最小闭环”:
|
||||
|
||||
* 关键指标与日志的验证方法
|
||||
* 常见故障排查路径
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* **指标监控**:以 Prometheus + Grafana 为主,完成指标采集、存储与可视化。
|
||||
* **日志管理**:以 EFK/ELK 为例,完成容器日志的集中采集、检索与分析。
|
||||
|
||||
生产环境中,建议将”可观测性”当成一个完整闭环:**采集 -> 存储 -> 展示 -> 告警 -> 排错 -> 容量治理**。
|
||||
生产环境中,建议将“可观测性”当成一个完整闭环:**采集 -> 存储 -> 展示 -> 告警 -> 排错 -> 容量治理**。
|
||||
|
||||
## 扩展阅读:Docker 日志驱动
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ Debian 是一个常用的基础镜像。
|
||||
```bash
|
||||
$ docker run -it debian bash
|
||||
root@668e178d8d69:/# cat /etc/issue
|
||||
Debian GNU/Linux 12
|
||||
Debian GNU/Linux 13
|
||||
```
|
||||
`Debian` 镜像很适合作为基础镜像,构建自定义镜像。
|
||||
|
||||
@@ -43,18 +43,18 @@ Debian GNU/Linux 12
|
||||
Ubuntu 是目前最流行的 Linux 发行版之一。
|
||||
|
||||
|
||||
下面以 `ubuntu:24.04` 为例,演示如何使用该镜像安装一些常用软件。
|
||||
下面以 `ubuntu:26.04` 为例,演示如何使用该镜像安装一些常用软件。
|
||||
|
||||
首先使用 `-ti` 参数启动容器,登录 `bash`,查看 `ubuntu` 的发行版本号。
|
||||
|
||||
```bash
|
||||
$ docker run -ti ubuntu:24.04 /bin/bash
|
||||
$ docker run -ti ubuntu:26.04 /bin/bash
|
||||
root@7d93de07bf76:/# cat /etc/os-release
|
||||
PRETTY_NAME="Ubuntu 24.04 LTS"
|
||||
PRETTY_NAME="Ubuntu 26.04 LTS"
|
||||
NAME="Ubuntu"
|
||||
VERSION_ID="24.04"
|
||||
VERSION="24.04 LTS (Noble Numbat)"
|
||||
VERSION_CODENAME=noble
|
||||
VERSION_ID="26.04"
|
||||
VERSION="26.04 LTS (Resolute Raccoon)"
|
||||
VERSION_CODENAME=resolute
|
||||
ID=ubuntu
|
||||
ID_LIKE=debian
|
||||
HOME_URL="https://www.ubuntu.com/"
|
||||
|
||||
@@ -50,7 +50,7 @@ latest: Pulling from library/fedora
|
||||
Digest: sha256:64a02df6aac27d1200c2572fe4b9949f1970d05f74d367ce4af994ba5dc3669e
|
||||
Status: Downloaded newer image for fedora:latest
|
||||
[root@196ca341419b /]# cat /etc/redhat-release
|
||||
Fedora release 39 (Thirty Nine)
|
||||
Fedora release 43 (Forty Three)
|
||||
```
|
||||
|
||||
### 20.4.3 相关资源
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
本章示例中使用的操作系统镜像版本遵循以下原则:
|
||||
|
||||
- **Alpine、Debian、Ubuntu、CentOS** 等操作系统镜像采用大版本或次版本标签(如 `alpine:3.21`、`ubuntu:24.04`),避免使用 `latest` 标签确保构建的可再现性
|
||||
- **Alpine、Debian、Ubuntu、CentOS** 等操作系统镜像采用大版本或次版本标签(如 `alpine:3.21`、`ubuntu:26.04`),避免使用 `latest` 标签确保构建的可再现性
|
||||
- **OS 大版本保留**,以便获得最新的安全补丁和修复
|
||||
- 在生产环境中,建议根据实际需求选择合适的版本,并定期更新以获得安全修复
|
||||
|
||||
|
||||
@@ -54,9 +54,9 @@ unit_test:
|
||||
|
||||
build_image:
|
||||
stage: build
|
||||
image: docker:27
|
||||
image: docker:29
|
||||
services:
|
||||
- docker:27-dind
|
||||
- docker:29-dind
|
||||
script:
|
||||
- echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin $CI_REGISTRY
|
||||
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
## DevOps 背景介绍
|
||||
|
||||
DevOps 是一种重要的开发和运维文化,强调开发团队和运维团队之间的协作和自动化。它致力于通过自动化和流程优化,加快软件交付速度,同时提高系统的稳定性和可靠性。Docker 作为容器化技术的领导者,已成为现代 DevOps 工作流中不可或缺的工具。通过容器化应用,开发团队可以确保”一次构建,处处运行”,消除开发、测试和生产环境的差异,大大简化了部署流程。
|
||||
DevOps 是一种重要的开发和运维文化,强调开发团队和运维团队之间的协作和自动化。它致力于通过自动化和流程优化,加快软件交付速度,同时提高系统的稳定性和可靠性。Docker 作为容器化技术的领导者,已成为现代 DevOps 工作流中不可或缺的工具。通过容器化应用,开发团队可以确保“一次构建,处处运行”,消除开发、测试和生产环境的差异,大大简化了部署流程。
|
||||
|
||||
## Docker 在 DevOps 中的角色
|
||||
|
||||
|
||||
@@ -190,7 +190,7 @@ ENV PG_MAJOR 9.3
|
||||
|
||||
ENV PG_VERSION 9.3.4
|
||||
|
||||
RUN curl -SL http://example.com/postgres-$PG_VERSION.tar.xz | tar -xJC /usr/src/postgress && …
|
||||
RUN curl -SL http://example.com/postgres-$PG_VERSION.tar.xz | tar -xJC /usr/src/postgres && …
|
||||
|
||||
ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH
|
||||
```
|
||||
|
||||
@@ -434,8 +434,8 @@ Kubernetes 进阶 (Week 24-36)
|
||||
- 题目数:55 道
|
||||
- 时间限制:90 分钟
|
||||
- 及格分数:73%(约 41 道题)
|
||||
- 费用:$165 USD
|
||||
- 有效期:3 年
|
||||
- 费用:$199 USD
|
||||
- 有效期:2 年
|
||||
|
||||
考试内容比例:
|
||||
```text
|
||||
@@ -587,7 +587,7 @@ A(要点):
|
||||
A(要点):
|
||||
```text
|
||||
1. 选择合适的基础镜像:
|
||||
scratch < alpine:3.17 < python:3.14-slim < python:3.14
|
||||
scratch < alpine:3.21 < python:3.14-slim < python:3.14
|
||||
|
||||
2. 多阶段构建:
|
||||
- 构建阶段只保留编译工具
|
||||
|
||||
@@ -25,13 +25,13 @@ $ docker run --name some-mongo -d --network my-mongo-net mongo
|
||||
```bash
|
||||
$ docker run --name some-app -d --network my-mongo-net application-that-uses-mongo
|
||||
```
|
||||
或者通过 `mongo`
|
||||
或者通过 `mongosh`(MongoDB 6.0+ 已移除旧版 `mongo` 命令行工具)
|
||||
|
||||
```bash
|
||||
$ docker run -it --rm \
|
||||
--network my-mongo-net \
|
||||
mongo \
|
||||
sh -c 'exec mongo "some-mongo:27017/test"'
|
||||
mongosh "some-mongo:27017/test"
|
||||
```
|
||||
|
||||
### Dockerfile
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
在项目中创建一个 Dockerfile。
|
||||
|
||||
```docker
|
||||
FROM node:20
|
||||
FROM node:22
|
||||
|
||||
## replace this with your application's default port
|
||||
|
||||
@@ -32,7 +32,7 @@ $ docker run -it --rm \
|
||||
|
||||
--mount type=bind,src="$(pwd)",target=/usr/src/myapp \
|
||||
-w /usr/src/myapp \
|
||||
node:20-alpine \
|
||||
node:22-alpine \
|
||||
node your-daemon-or-script.js
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user