Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
commit-message:
prefix: "chore(deps)"
labels:
- "dependencies"
groups:
dependencies:
patterns:
- "*"

- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
commit-message:
prefix: "chore(deps)"
labels:
- "dependencies"
groups:
dependencies:
patterns:
- "*"
2 changes: 1 addition & 1 deletion .github/workflows/check-link.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
name: check-link
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4.1.1
- uses: actions/checkout@v6.0.2
# search Issues :-(
- run: |
docker run -i --rm \
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
name: Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4.1.1
- uses: actions/checkout@v6.0.2
- name: Build Gitbook
uses: docker://yeasy/docker_practice
with:
Expand Down
27 changes: 27 additions & 0 deletions .github/workflows/dependabot-automerge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Dependabot auto-merge
on: pull_request

permissions:
contents: write
pull-requests: write

jobs:
dependabot:
runs-on: ubuntu-latest
if: github.actor == 'dependabot[bot]'
steps:
- name: Dependabot metadata
id: metadata
uses: dependabot/fetch-metadata@v2
with:
github-token: "${{ secrets.GITHUB_TOKEN }}"
- name: Approve a PR
run: gh pr review --approve "$PR_URL"
env:
PR_URL: ${{github.event.pull_request.html_url}}
GH_TOKEN: ${{secrets.GITHUB_TOKEN}}
- name: Enable auto-merge for Dependabot PRs
run: gh pr merge --auto --merge "$PR_URL"
env:
PR_URL: ${{github.event.pull_request.html_url}}
GH_TOKEN: ${{secrets.GITHUB_TOKEN}}
12 changes: 8 additions & 4 deletions 02_basic_concept/2.2_container.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,26 @@

### 2.2.2 容器的本质

> 💡 **笔者认为,理解这一点是理解 Docker 的关键:** **容器的本质是一个特殊的进程。**
> 💡 笔者认为,理解这一点是理解 Docker 的关键:**容器的本质是一个特殊的进程**。

```mermaid
flowchart TD
subgraph NormalProcess ["普通进程"]
direction TB
N1["• 与其他进程共享系统资源<br/>• 可以看到其他进程<br/>• 共享网络和文件系统"]
N1["• 共享系统资源<br/>• 共享网络<br/>• 共享文件系统"]
end

subgraph ContainerProcess ["容器进程 (运行在宿主机内核上)"]
direction TB
C1["• 有自己的进程空间(看不到宿主机上的其他进程)<br/>• 有自己的网络(独立 IP、端口)<br/>• 有自己的文件系统(独立的 root 目录)<br/>• 有自己的用户(容器内的 root ≠ 宿主机的 root)"]
C1["• 独立进程空间<br/>• 独立网络环境<br/>• 独立文件系统<br/>• 独立用户空间"]
end
```

这种隔离是通过 Linux 内核的 **Namespace** 技术实现的。
这种隔离是通过 Linux 内核的 **Namespace** 技术实现的。具体表现为:
- **进程空间**:容器看不到宿主机上的其他进程。
- **网络**:容器拥有独立的 IP、端口等网络资源。
- **文件系统**:容器拥有独立的 root 目录。
- **用户**:容器内的 root 用户不等于宿主机的 root 用户。

### 2.2.3 容器 vs 虚拟机:核心区别

Expand Down
4 changes: 2 additions & 2 deletions 03_install/3.7_mac.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ $ brew install --cask docker

如同 macOS 其它软件一样,安装也非常简单,双击下载的 `.dmg` 文件,然后将那只叫 [Moby](https://www.docker.com/blog/call-me-moby-dock/) 的鲸鱼图标拖拽到 `Application` 文件夹即可 (其间需要输入用户密码)。

![图](../_images/install-mac-dmg.png)
![图](../_images/install-mac-dmg.jpg)

### 3.7.3 运行

从应用中找到 Docker 图标并点击运行。

![图](../_images/install-mac-apps.png)
![图](../_images/install-mac-apps.jpg)

运行之后,会在右上角菜单栏看到多了一个鲸鱼图标,这个图标表明了 Docker 的运行状态。

Expand Down
2 changes: 1 addition & 1 deletion 04_image/4.5_build.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ FROM scratch
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
```

* *exec* 格式:`RUN ["可执行文件", "参数1", "参数2"]`,这更像是函数调用中的格式。
* *exec* 格式:`RUN [可执行文件”, “参数1”, “参数2]`,这更像是函数调用中的格式。

Dockerfile 中每一个指令都会建立一层,`RUN` 也不例外。每一个 `RUN` 的行为,就和刚才我们手工建立镜像的过程一样:新建立一层,在其上执行这些命令,执行结束后,`commit` 这一层的修改,构成新的镜像。

Expand Down
4 changes: 2 additions & 2 deletions 07_dockerfile/7.4_cmd.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ CMD 有三种格式:

| 格式 | 语法 | 推荐程度 |
|------|------|---------|
| **exec 格式**| `CMD ["可执行文件", "参数1", "参数2"]` | ✅**推荐** |
| **exec 格式**| `CMD [可执行文件”, “参数1”, “参数2]` | ✅**推荐** |
| **shell 格式** | `CMD 命令 参数1 参数2` | ⚠️ 简单场景 |
| **参数格式** | `CMD ["参数1", "参数2"]` | 配合 ENTRYPOINT |
| **参数格式** | `CMD [参数1”, “参数2]` | 配合 ENTRYPOINT |

#### exec 格式 (推荐)

Expand Down
2 changes: 1 addition & 1 deletion 07_dockerfile/7.5_entrypoint.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

| 格式 | 语法 | 推荐程度 |
|------|------|---------|
| **exec 格式**| `ENTRYPOINT ["可执行文件", "参数1"]` | ✅**推荐** |
| **exec 格式**| `ENTRYPOINT [可执行文件”, “参数1]` | ✅**推荐** |
| **shell 格式** | `ENTRYPOINT 命令 参数` | ⚠️ 不推荐 |

```docker
Expand Down
2 changes: 1 addition & 1 deletion 07_dockerfile/summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@
| 要点 | 说明 |
|------|------|
| **作用** | 指定容器启动时的默认命令 |
| **推荐格式** | exec 格式 `CMD ["程序", "参数"]` |
| **推荐格式** | exec 格式 `CMD [“程序”, “参数”]` |
| **覆盖方式** | `docker run image 新命令` |
| **与 ENTRYPOINT** | CMD 作为 ENTRYPOINT 的默认参数 |
| **核心原则** | 应用必须在前台运行 |
Expand Down
14 changes: 10 additions & 4 deletions 08_data/8.2_bind-mounts.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,24 @@ Bind Mount (绑定挂载) 将 **宿主机的目录或文件** 直接挂载到容
```mermaid
flowchart LR
subgraph Host ["宿主机"]
direction TB
Dir1["/home/user/code/<br/>├── index.html<br/>├── style.css<br/>└── app.js"]
Dir1["/home/user/code/"]
end

subgraph Container ["容器"]
direction TB
Dir2["/usr/share/nginx/html/<br/>(同一份文件)"]
Dir2["/usr/share/nginx/html/"]
end

Dir1 <-->|Bind Mount| Dir2
```

目录结构(同一份文件):
```text
/home/user/code/ (或 /usr/share/nginx/html/)
├── index.html
├── style.css
└── app.js
```

---

### 8.2.2 Bind Mount vs Volume
Expand Down
2 changes: 1 addition & 1 deletion 14_kubernetes_setup/14.1_kubeadm.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ oom_score = 0
async_remove = false
```

### 14.1.3 安装 **kubelet****kubeadm****kubectl****cri-tools****kubernetes-cni**
### 14.1.3 安装 **kubelet****kubeadm****kubectl****cri-tools****kubernetes-cni**

需要在每台机器上安装以下的软件包:

Expand Down
2 changes: 1 addition & 1 deletion 14_kubernetes_setup/14.2_kubeadm-docker.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

参考[安装 Docker](../03_install/README.md) 一节安装 Docker。

### 14.2.2 安装 **kubelet****kubeadm****kubectl**
### 14.2.2 安装 **kubelet****kubeadm****kubectl**

需要在每台机器上安装以下的软件包:

Expand Down
88 changes: 88 additions & 0 deletions 17_ecosystem/17.4_buildah.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
## 17.4 Buildah - 容器镜像构建工具

本节介绍 Buildah,包括其基础概念、应用场景以及基本指令。

### Buildah 简介

Buildah 是一个用于构建 OCI(Open Container Initiative)兼容格式容器镜像的开源命令行工具。与 Docker 需要一直运行的守护进程(daemon)不同,Buildah 的设计初衷是无需守护进程(daemonless)即可工作,并且也不强制要求 root 权限(rootless)。这使得在持续集成/持续部署(CI/CD)环境中构建镜像时能够更加轻量且安全。

Buildah 由 Red Hat 主导开发,通常和 Podman、Skopeo 一起使用,被认为是构建、运行和管理容器的一套现代化工具链。在很多需要增强安全性和无需依赖守护进程的场景中,Buildah 是 `docker build` 命令的最佳替代方案。

### 核心特性

- **无守护进程(Daemonless)**:Buildah 直接通过系统调用拉取、构建和推送镜像,减少了单点故障的风险和资源开销。
- **构建效率高**:可以挂载镜像的根文件系统到本地,并直接利用宿主机的工具对其进行操作,非常灵活。
- **兼容性**:不仅支持处理传统的 Dockerfile,还能完全兼容 OCI(Open Container Initiative)标准和 Docker 格式。
- **与 Podman 集成**:Podman 自身构建镜像的命令 `podman build` 底层实际上也是依赖 Buildah 库来实现的。

### 安装 Buildah

在许多主流的 Linux 发行版中都可以通过包管理器直接安装 Buildah。

以 Fedora/CentOS/RHEL 为例:

```bash
$ sudo dnf install -y buildah
```

以 Ubuntu/Debian 为例(需引入官方源后):

```bash
$ sudo apt-get update
$ sudo apt-get -y install buildah
```

### 基础用法示例

#### 1. 从现有的 Dockerfile 构建镜像

Buildah 最常见的用法就是像 Docker 一样根据 `Dockerfile` 来构建镜像,可以直接使用 `buildah bud`(或者 `buildah build-using-dockerfile`)命令:

```bash
$ buildah bud -t my-app:latest .
```

可以看到在这点上,它与 `docker build` 的体验完全一致。

#### 2. 交互式从空镜像开始构建

除了使用 Dockerfile,Buildah 最强大的功能来自于它的交互式和脚本化构建机制。我们可以从一个极简的镜像(或基础镜像)开始构建:

```bash
# 获取一个基础镜像
$ container=$(buildah from alpine:latest)

# 获取挂载点,并查看其路径
$ mnt=$(buildah mount $container)
$ echo $mnt
/var/lib/containers/storage/overlay/xxx/merged

# 利用宿主机直接创建文件,而不需要在容器内部运行命令
$ echo "Hello Buildah" > $mnt/hello.txt

# 添加一些配置和命令
$ buildah config --cmd "cat /hello.txt" $container

# 将容器提交为镜像
$ buildah commit $container my-hello-image:latest

# 构建完成后可以卸载并清理容器上下文
$ buildah unmount $container
$ buildah rm $container
```

这种模式在自动化流水线中极为有用,因为我们可以将上述过程编写成标准的 bash 脚本,无需为了构建镜像而撰写只在其独立语法中运行的 Dockerfile 指令。

#### 3. 查看和推送镜像

通过 `buildah images` 可以查看当前环境中的镜像。推送镜像到外部 Registry 也十分安全方便:

```bash
# 查看本地构建的镜像
$ buildah images

# 推送镜像到 Docker Hub(注意需要先登录)
$ buildah push my-hello-image:latest docker://docker.io/username/my-hello-image:latest
```

结合其无需特权和灵活脚本的优点,Buildah 正变得越来越受到构建和分发 OCI 镜像的用户喜爱。
79 changes: 79 additions & 0 deletions 17_ecosystem/17.5_skopeo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
## 17.5 Skopeo - 容器镜像管理工具

本节介绍 Skopeo,包括其基础概念、应用场景以及基本指令。

### Skopeo 简介

Skopeo 是一个由 Red Hat 赞助开源的命令行工具,它可以在不需要运行容器守护进程(如 Docker Daemon)的前提下,对容器镜像进行极其高效的操作和管理,包括:检查、复制、删除和签名等操作。

Skopeo 最大的特点是其可以在“不将镜像拉取到本地”的情况下,直接在远端 Registry(镜像仓库)之间完成检查和搬运,从而大幅度节省带宽和磁盘空间。这也是它在容器运维和分发领域非常受欢迎的原因。

### 核心特性

- **远程巡检**:通过 `skopeo inspect` 可以查看远端仓库中镜像的元数据(例如包含哪些层、环境变量信息、入口命令等),而完全无需拉取该镜像。
- **镜像复制与同步**:支持各种格式之间的相互传输,如在不同的容器仓库之间、或者从仓库拉取到本地的目录、或者存储为 OCI 布局结构等。
- **镜像删除**:可以远程删除仓库中的镜像(需要拥有权限)。
- **签名验证**:支持在分发镜像前进行数字签名以保障安全性。

### 安装 Skopeo

类似于 Buildah,Skopeo 也直接包含在大部分主流的 Linux 源中。

在 Fedora/CentOS/RHEL 等发行版中:

```bash
$ sudo dnf install -y skopeo
```

在 Ubuntu/Debian 中:

```bash
$ sudo apt-get update
$ sudo apt-get -y install skopeo
```

如果是 macOS 环境,可以通过 Homebrew 安装:

```bash
$ brew install skopeo
```

### 基础用法示例

#### 1. 远程检查镜像

有时候我们只想知道远端镜像的详细信息,并不想拉取它。下面是检查 Docker Hub 上的 Alpine 镜像的例子:

```bash
$ skopeo inspect docker://docker.io/library/alpine:latest
```

这个命令会返回一段 JSON 格式的数据,其中包含了诸如镜像摘要(Digest)、创建时间、架构(Architecture)、标签(Tags)等丰富信息。在自动化的工具和系统审查环境中,这是一个不可或缺的利器。

#### 2. 同步与复制镜像

`skopeo copy` 是使用最为广泛的命令。它可以在不同的仓库、不同的格式之间无缝搬运镜像。

例如,从一个公共仓库直接搬运镜像到一个私有企业仓库(无需将其先 `docker pull` 到本地,再 `docker push`):

```bash
$ skopeo copy docker://docker.io/library/alpine:latest docker://registry.example.com/library/alpine:latest
```

又或者,你可以将远程镜像拉取到本地,只为了检查其拆解后的格式,比如将镜像解压到本地某个目录下以 OCI 规范存放:

```bash
$ skopeo copy docker://docker.io/library/alpine:latest oci:alpine-oci
```

如果我们要将本地的某个目录下的打包好的镜像再次推向 Registry 或转换为其它存储类型也是完全支持的,诸如:
- `docker://` 远端 Registry
- `docker-archive:` / `docker-daemon:` Docker 对应的归档文件或本地守护进程
- `oci:` / `oci-archive:` OCI 相关文件格式
- `dir:` 本地纯目录

#### 3. 校验机制与安全

如果你不信任公开仓库上的镜像,或是需要通过特定的 TLS 证书和鉴权,Skopeo 的功能也是能很好的支持的,比如它可以直接传递诸如 `--src-creds` 或 `--dest-tls-verify=false` 等参数,这在进行网络隔离的复杂镜像搬运操作中常常会用到。

对于复杂的容器环境或那些纯粹用于镜像资产管理的节点来说,Skopeo 提供了一个直接而强大的数据“搬运工”。
Loading