update per windsonsea's comments
parent
c608681964
commit
5d9137280e
|
@ -4,14 +4,6 @@ title: "Kubernetes 的取证容器检查点"
|
|||
date: 2022-12-05
|
||||
slug: forensic-container-checkpointing-alpha
|
||||
---
|
||||
<!--
|
||||
---
|
||||
layout: blog
|
||||
title: "Forensic container checkpointing in Kubernetes"
|
||||
date: 2022-12-05
|
||||
slug: forensic-container-checkpointing-alpha
|
||||
---
|
||||
-->
|
||||
|
||||
**作者:** [Adrian Reber](https://github.com/adrianreber) (Red Hat)
|
||||
<!--
|
||||
|
@ -84,8 +76,8 @@ The feature is behind a [feature gate][container-checkpoint-feature-gate], so
|
|||
make sure to enable the `ContainerCheckpoint` gate before you can use the new
|
||||
feature.
|
||||
-->
|
||||
|
||||
该功能在[特性门][container-checkpoint-feature-gate]后面,因此在使用新功能之前,请确保启用了 ContainerCheckpoint 特性门。
|
||||
该功能在[特性门控][container-checkpoint-feature-gate]后面,因此在使用这个新功能之前,
|
||||
请确保启用了 ContainerCheckpoint 特性门控。
|
||||
|
||||
<!--
|
||||
The runtime must also support container checkpointing:
|
||||
|
@ -115,7 +107,8 @@ is also necessary to install CRIU. Usually runc or crun depend on CRIU and
|
|||
therefore it is installed automatically.
|
||||
-->
|
||||
要将取证容器检查点与 CRI-O 结合使用,需要使用命令行选项--enable-criu-support=true 启动运行时。
|
||||
Kubernetes 方面,你需要在启用 ContainerCheckpoint 特性门的情况下运行你的集群。由于检查点功能是由 CRIU 提供的,因此也有必要安装 CRIU。
|
||||
Kubernetes 方面,你需要在启用 ContainerCheckpoint 特性门控的情况下运行你的集群。
|
||||
由于检查点功能是由 CRIU 提供的,因此也有必要安装 CRIU。
|
||||
通常 runc 或 crun 依赖于 CRIU,因此它是自动安装的。
|
||||
|
||||
<!--
|
||||
|
@ -151,7 +144,7 @@ For a container named *counter* in a pod named *counters* in a namespace named
|
|||
curl -X POST "https://localhost:10250/checkpoint/default/counters/counter"
|
||||
```
|
||||
-->
|
||||
对于名为 **default** 的命名空间中名为 **counters** 的 pod 中的名为 **counter** 的容器, **kubelet** API 端点可在以下位置访问:
|
||||
对于 **default** 命名空间中 **counters** Pod 中名为 **counter** 的容器,可通过以下方式访问 **kubelet** API 端点:
|
||||
|
||||
```shell
|
||||
curl -X POST "https://localhost:10250/checkpoint/default/counters/counter"
|
||||
|
@ -166,7 +159,8 @@ use of the *kubelet* `checkpoint` API:
|
|||
--insecure --cert /var/run/kubernetes/client-admin.crt --key /var/run/kubernetes/client-admin.key
|
||||
```
|
||||
-->
|
||||
为了完整起见,以下 curl 命令行选项对于让 curl 接受 **kubelet** 的自签名证书并授权使用 **kubelet** 检查点 API 是必要的:
|
||||
为了完整起见,以下 `curl` 命令行选项对于让 `curl` 接受 **kubelet** 的自签名证书并授权使用
|
||||
**kubelet** 检查点 API 是必要的:
|
||||
|
||||
```shell
|
||||
--insecure --cert /var/run/kubernetes/client-admin.crt --key /var/run/kubernetes/client-admin.key
|
||||
|
@ -183,8 +177,8 @@ Once the checkpointing has finished the checkpoint should be available at
|
|||
|
||||
You could then use that tar archive to restore the container somewhere else.
|
||||
-->
|
||||
触发这个 **kubelet** API 将从 CRI-O 请求创建一个检查点,CRI-O 从你的低级运行时(例如,runc)请求一个检查点。
|
||||
看到这个请求,runc 调用 criu 工具来执行实际的检查点操作。
|
||||
触发这个 **kubelet** API 将从 CRI-O 请求创建一个检查点,CRI-O 从你的低级运行时(例如 `runc`)请求一个检查点。
|
||||
看到这个请求,`runc` 调用 `criu` 工具来执行实际的检查点操作。
|
||||
|
||||
检查点操作完成后,检查点应该位于
|
||||
`/var/lib/kubelet/checkpoints/checkpoint-<pod-name>_<namespace-name>-<container-name>-<timestamp>.tar`
|
||||
|
@ -204,9 +198,9 @@ during restore, I recommend that you use the latest version of CRI-O from the
|
|||
manually create certain directories Kubernetes would create before starting the
|
||||
container.
|
||||
-->
|
||||
使用检查点 tar 归档文件,可以在 Kubernetes 之外的 CRI-O 沙箱实例中恢复容器。为了在恢复过程中获得更好的用户体验,我建议你使用 CRI-O GitHub 的 **main** 分支中最新版本的 CRI-O。
|
||||
使用检查点 tar 归档文件,可以在 Kubernetes 之外的 CRI-O 沙箱实例中恢复容器。
|
||||
为了在恢复过程中获得更好的用户体验,建议你使用 CRI-O GitHub 的 **main** 分支中最新版本的 CRI-O。
|
||||
如果你使用的是 CRI-O v1.25,你需要在启动容器之前手动创建 Kubernetes 会创建的某些目录。
|
||||
|
||||
<!--
|
||||
The first step to restore a container outside of Kubernetes is to create a pod sandbox
|
||||
using *crictl*:
|
||||
|
@ -347,7 +341,8 @@ spec:
|
|||
nodeName: <destination-node>
|
||||
```
|
||||
-->
|
||||
要恢复此检查点镜像(container-image-registry.example/user/checkpoint-image:latest),该镜像需要在 Pod 的规范中列出。下面是一个清单示例:
|
||||
要恢复此检查点镜像(container-image-registry.example/user/checkpoint-image:latest),
|
||||
该镜像需要在 Pod 的规约中列出。下面是一个清单示例:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
|
@ -371,7 +366,8 @@ instead of the usual steps to create and start a container,
|
|||
CRI-O fetches the checkpoint data and restores the container from that
|
||||
specified checkpoint.
|
||||
-->
|
||||
Kubernetes 将新的 Pod 调度到一个节点上。该节点上的 kubelet 指示容器运行时(本例中为 CRI-O)基于指定为 `registry/user/checkpoint-image:latest` 的镜像创建并启动容器。
|
||||
Kubernetes 将新的 Pod 调度到一个节点上。该节点上的 kubelet 指示容器运行时(本例中为 CRI-O)
|
||||
基于指定为 `registry/user/checkpoint-image:latest` 的镜像创建并启动容器。
|
||||
CRI-O 检测到 `registry/user/checkpoint-image:latest` 是对检查点数据的引用,而不是容器镜像。
|
||||
然后,与创建和启动容器的通常步骤不同,CRI-O 获取检查点数据,并从指定的检查点恢复容器。
|
||||
|
||||
|
@ -380,7 +376,8 @@ The application in that Pod would continue running as if the checkpoint had not
|
|||
within the container, the application looks and behaves like any other container that had been
|
||||
started normally and not restored from a checkpoint.
|
||||
-->
|
||||
该 Pod 中的应用程序将继续运行,就像检查点未被获取一样;在该容器中,应用程序的外观和行为,与正常启动且未从检查点恢复的任何其他容器相似。
|
||||
该 Pod 中的应用程序将继续运行,就像检查点未被获取一样;在该容器中,
|
||||
应用程序的外观和行为,与正常启动且未从检查点恢复的任何其他容器相似。
|
||||
|
||||
<!--
|
||||
With these steps, it is possible to replace a Pod running on one node
|
||||
|
|
|
@ -110,12 +110,19 @@ For a container named *counter* in a pod named *counters* in a namespace named
|
|||
|
||||
在分析检查点之前的最后一步是告诉 Kubernetes 创建检查点。如上一篇文章所述,这需要访问 **kubelet** 唯一的“检查点” API 端点。
|
||||
|
||||
对于名为 **default** 的命名空间中名为 **counters** 的 pod 中的名为 **counter** 的容器, **kubelet** API 端点可在以下位置访问:
|
||||
对于 **default** 命名空间中 **counters** Pod 中名为 **counter** 的容器,
|
||||
可通过以下方式访问 **kubelet** API 端点:
|
||||
|
||||
<!--
|
||||
```shell
|
||||
# run this on the node where that Pod is executing
|
||||
curl -X POST "https://localhost:10250/checkpoint/default/counters/counter"
|
||||
```
|
||||
-->
|
||||
```shell
|
||||
# 在运行 Pod 的节点上运行这条命令
|
||||
curl -X POST "https://localhost:10250/checkpoint/default/counters/counter"
|
||||
```
|
||||
|
||||
<!--
|
||||
For completeness the following `curl` command-line options are necessary to
|
||||
|
@ -174,7 +181,8 @@ SIZE`). This is mainly the size of the memory pages included in the checkpoint,
|
|||
but there is also information about the size of all changed files in the
|
||||
container (`ROOT FS DIFF SIZE`).
|
||||
-->
|
||||
这展示了有关该检查点归档中的检查点的一些信息。我们可以看到容器的名称、有关容器运行时和容器引擎的信息。它还列出了检查点的大小(`CHKPT SIZE`)。
|
||||
这展示了有关该检查点归档中的检查点的一些信息。我们可以看到容器的名称、有关容器运行时和容器引擎的信息。
|
||||
它还列出了检查点的大小(`CHKPT SIZE`)。
|
||||
这主要是检查点中包含的内存页的大小,同时也有有关容器中所有更改文件的大小的信息(`ROOT FS DIFF SIZE`)。
|
||||
|
||||
<!--
|
||||
|
@ -265,7 +273,8 @@ was created just as expected.
|
|||
With the help of `rootfs-diff.tar` it is possible to inspect all files that
|
||||
were created or changed compared to the base image of the container.
|
||||
-->
|
||||
与该容器所基于的容器镜像(`quay.io/adrianreber/counter:blog`)相比,它包含容器提供的服务的所有访问信息以及预期创建的 `logfile` 可以检查 `test-file` 文件。
|
||||
与该容器所基于的容器镜像(`quay.io/adrianreber/counter:blog`)相比,
|
||||
它包含容器提供的服务的所有访问信息以及预期创建的 `logfile` 可以检查 `test-file` 文件。
|
||||
|
||||
在 `rootfs-diff.tar` 的帮助下,可以根据容器的基本镜像检查所有创建或修改的文件。
|
||||
|
||||
|
@ -326,7 +335,8 @@ is more data to be analyzed in `checkpoint/pstree.img`.
|
|||
|
||||
Let's compare the so far collected information to the still running container:
|
||||
-->
|
||||
这意味着容器内的三个进程是 `bash`、`counter.py`(Python 解释器)和 `tee`。 `checkpoint/pstree.img` 中有更多数据可供分析,以获取有关进程起源的详细信息。
|
||||
这意味着容器内的三个进程是 `bash`、`counter.py`(Python 解释器)和 `tee`。
|
||||
`checkpoint/pstree.img` 中有更多数据可供分析,以获取有关进程起源的详细信息。
|
||||
|
||||
让我们将目前为止收集到的信息与仍在运行的容器进行比较。
|
||||
|
||||
|
@ -360,7 +370,8 @@ processes.
|
|||
One last example of what `crit` can tell us about the container is the information
|
||||
about the UTS namespace:
|
||||
-->
|
||||
在此输出中,我们首先获取容器中第一个进程的 PID。在运行容器的系统上,它会查找其 PID 和子进程。你应该看到三个进程,第一个进程是 `bash`,容器 PID 命名空间中的 PID 为 1。
|
||||
在此输出中,我们首先获取容器中第一个进程的 PID。在运行容器的系统上,它会查找其 PID 和子进程。
|
||||
你应该看到三个进程,第一个进程是 `bash`,容器 PID 命名空间中的 PID 为 1。
|
||||
然后查看 `/proc/<PID>/comm`,可以找到与检查点镜像完全相同的值。
|
||||
|
||||
需要记住的重点是,检查点包含容器的 PID 命名空间内的视图。因为这些信息对于恢复进程非常重要。
|
||||
|
@ -426,7 +437,8 @@ important to remember that anyone that can access the checkpoint
|
|||
archive has access to all information that was stored in the memory of the
|
||||
container's processes.
|
||||
-->
|
||||
确实有我的数据。通过这种方式,我可以轻松查看容器中进程的所有内存页面的内容,但需要注意的是可以访问检查点存档的任何人都可以访问存储在容器进程内存中的所有信息。
|
||||
确实有我的数据。通过这种方式,我可以轻松查看容器中进程的所有内存页面的内容,
|
||||
但需要注意的是可以访问检查点存档的任何人都可以访问存储在容器进程内存中的所有信息。
|
||||
|
||||
<!--
|
||||
#### Using gdb for further analysis
|
||||
|
@ -514,10 +526,13 @@ are just the starting point. Depending on your requirements it is possible to
|
|||
look at certain things in much more detail, but this article should give you an
|
||||
introduction how to start the analysis of your checkpoint.
|
||||
-->
|
||||
借助容器检查点,可以在不停止容器且在容器不知情的情况下,为正在运行的容器创建检查点。 在 Kubernetes 中对容器创建一个检查点的结果是检查点存档文件;
|
||||
使用不同的工具,如 `checkpointctl`、`tar`、`crit` 和 `gdb`,可以分析检查点。即使使用像 `grep` 这样的简单工具,也可以在检查点存档中找到信息。
|
||||
借助容器检查点,可以在不停止容器且在容器不知情的情况下,为正在运行的容器创建检查点。
|
||||
在 Kubernetes 中对容器创建一个检查点的结果是检查点存档文件;
|
||||
使用不同的工具,如 `checkpointctl`、`tar`、`crit` 和 `gdb`,可以分析检查点。
|
||||
即使使用像 `grep` 这样的简单工具,也可以在检查点存档中找到信息。
|
||||
|
||||
我在本文中展示的如何分析检查点的不同示例,这只是一个起点。 根据你的需求,可以更详细地查看某些内容,本文向你介绍了如何开始进行检查点分析。
|
||||
我在本文中展示的如何分析检查点的不同示例,这只是一个起点。
|
||||
根据你的需求,可以更详细地查看某些内容,本文向你介绍了如何开始进行检查点分析。
|
||||
|
||||
<!--
|
||||
## How do I get involved?
|
||||
|
|
Loading…
Reference in New Issue