microsoft/hcsshim
GitHub: microsoft/hcsshim
hcsshim 是微软提供的 Go 语言库和工具集,封装了 Windows Host Compute Service API,用于在 Windows 平台上启动和管理各类容器。
Stars: 684 | Forks: 297
# hcsshim
[](https://github.com/microsoft/hcsshim/actions?query=branch%3Amaster)
本包包含用于使用 Windows [Host Compute Service](https://techcommunity.microsoft.com/t5/containers/introducing-the-host-compute-service-hcs/ba-p/382332) (HCS) 来启动和管理 [Windows Containers](https://docs.microsoft.com/en-us/virtualization/windowscontainers/about/) 的 Golang 接口。它还包含其他用于管理 Windows Containers 的辅助工具和函数,例如用于 Host Network Service (HNS) 的 Golang 接口,以及用于支持运行 Linux Hyper-V 容器的[客户代理](./internal/guest/README.md)(在代码库中通常被称为 GCS 或 Guest Compute Service)的代码。
它主要用于 [Moby](https://github.com/moby/moby) 和 [Containerd](https://github.com/containerd/containerd) 项目,但也可以被其他项目自由使用。
## 构建
虽然这个仓库可以作为某种类型的库来调用 HCS API,但该仓库中也构建了几个二进制文件。主要的包括 Linux 客户代理,以及 [runtime v2 containerd shim api](https://github.com/containerd/containerd/blob/master/runtime/v2/README.md) 的一个实现。
### Linux Hyper-V Container Guest Agent
要构建 Linux 客户代理本身,只需将你的 GOOS 设置为 "Linux" 并从 ./cmd/gcs 进行构建。
```
C:\> $env:GOOS="linux"
C:\> go build .\cmd\gcs\
```
或者在 Linux 机器上
```
> go build ./cmd/gcs
```
如果你想将它打包在 rootfs 中,以便与其他所有工具一起启动,那么你需要提供一个可以将其打包进去的 rootfs。一种简单的方法是导出容器的 rootfs。
```
docker pull busybox
docker run --name base_image_container busybox
docker export base_image_container | gzip > base.tar.gz
BASE=./base.tar.gz
make all
```
如果构建成功,在 `./out` 文件夹中你应该会看到:
```
> ls ./out/
delta.tar.gz initrd.img rootfs.tar.gz
```
### Containerd Shim
有关 [Runtime V2 API](https://github.com/containerd/containerd/blob/main/docs/runtime-v2.md) 的信息。
与典型的 Linux 架构(shim -> runc)相反,runhcs shim 既用于启动容器,也用于管理容器的生命周期。
```
C:\> $env:GOOS="windows"
C:\> go build .\cmd\containerd-shim-runhcs-v1
```
然后将该二进制文件放置在你的环境中 Containerd 所在的同一目录下。
可以通过运行以下命令来生成默认的 Containerd 配置文件:
```
.\containerd.exe config default | Out-File "C:\Program Files\containerd\config.toml" -Encoding ascii
```
这个配置文件已经将该 shim 设置为 cri 交互的默认 runtime。
要尝试使用 ctr.exe 测试该 shim:
```
C:\> ctr.exe run --runtime io.containerd.runhcs.v1 --rm mcr.microsoft.com/windows/nanoserver:2004 windows-test cmd /c "echo Hello World!"
```
### Containerd Shim V2
V2 shim 是对 Windows containerd shim 的重写。V1 shim
([`containerd-shim-runhcs-v1`](./cmd/containerd-shim-runhcs-v1)) 是一个单一的单体
二进制文件,用于处理 LCOW (Linux Containers on Windows)、Hyper-V WCOW (Windows Containers on Windows)、进程隔离的
WCOW 以及 host-process 容器。在 V2 模型中,这个单体被拆分为专注的、
按平台划分的 shim,每个 shim 都由一个 sandbox 以 1:1 的比例支撑。
V2 shim 的使用方式与 V1 shim 相同,但它们暴露的
API 接口是不同的。V1 shim 仅实现了 containerd 的
[Task API](https://github.com/containerd/containerd/blob/main/docs/runtime-v2.md),
并通过单个服务使用它来同时管理 sandbox 生命周期和容器/进程(task)
生命周期。相反,每个 V2 shim 将这些职责分配给
containerd 现在为此提供的两个 API:使用
[Sandbox API](https://github.com/containerd/containerd/blob/main/docs/sandbox-api.md)
来管理 sandbox,而使用
[Task API](https://github.com/containerd/containerd/blob/main/docs/runtime-v2.md)
来管理在其中运行的容器和进程。在内部,每个 V2 shim
都将它们实现为独立的 sandbox 和 task 服务,外加一个用于诊断的辅助
`shimdiag` 服务。
所有三个 shim 都遵循相同的 CRI pod 模型。一个带有
`"io.kubernetes.cri.container-type": "sandbox"` 注解的 task 会被视为创建该 pod 的 pause/infra 容器;同级的负载 task 设置 `"io.kubernetes.cri.container-type":
"container"` 并通过 `"io.kubernetes.cri.sandbox-id"` 来引用其 pause 容器。“sandbox”在*物理上*对应什么
取决于具体的 shim,并在下面各小节中进行了说明。
#### containerd-shim-lcow-v2
- **目的:** 运行 Linux Containers on Windows (LCOW) —— 一个托管 Linux
容器的 Linux utility VM。
- **Sandbox:** Linux UVM。每个 shim 实例都由单个 UVM 以 1:1 的比例支撑。此 shim 支持*在同一个 UVM 中运行*
*多个 pod*,因此单个 shim 实例可以托管多个
CRI pod。
- **Tasks:** 在 UVM 内运行的 Linux 容器和进程,通过
上述相同的 CRI 注解进行标识。
- **实现:** [`./cmd/containerd-shim-lcow-v2`](./cmd/containerd-shim-lcow-v2)。
- **Build Tag:** lcow
- **平台要求:** Windows Server 2025 (build 26100) 或更高版本。
#### containerd-shim-wcow-v2
- **目的:** 运行 Hyper-V 隔离的 Windows 容器 (WCOW) —— 一个在其中托管
进程和/或 Host Process 容器的 Windows utility VM。
- **Sandbox:** Windows utility VM (UVM)。每个 shim 实例都由单个 UVM 以 1:1 的比例支撑。
- **Tasks:** 在 UVM 内运行的 Windows 容器和进程,通过
上述标准的 CRI 注解进行标识。
- **实现:** 即将推出。
- **Build Tag:** wcow
#### containerd-shim-process-v2
- **目的:** 运行进程隔离的 Windows Server 容器和 Host
Process 容器 —— 直接在宿主机上执行且没有 utility VM 的负载。
- **Sandbox:** 一个 *pause 容器*。pause 容器是一个最小化的、长期运行的
容器,它拥有 pod 的共享资源(例如网络 namespace),并
在同级负载容器启动、停止或替换时保持它们的活动状态。
这是标准的 Kubernetes pod 模型:pause 容器是
pod 其余部分所依附的 sandbox。
- **Tasks:** 属于该 pod 的实际负载容器,通过
`io.kubernetes.cri.sandbox-id` 注解链接回 pause 容器。
- **实现:** 即将推出。
- **Build Tag:** process
##### 构建
V2 shim 源码受上述 build tag 保护,因此必须将 tag 传递
给 `go build`。例如,`LCOW` shim 具有 `lcow` tag-
```
C:\> $env:GOOS="windows"
C:\> go build -tags lcow .\cmd\containerd-shim-lcow-v2
```
将生成的 `containerd-shim-lcow-v2.exe` 放在与 `containerd.exe` 相同的目录中,
与 V1 shim 相同。
##### 运行单元测试
shim 的单元测试(以及其余带 tag 的包)是通过
shim 特定的 build tag 来运行的:
```
C:\> go test -tags lcow ./...
```
##### 运行 parity 测试
仓库在 [`./test/parity`](./test/parity) 下提供了 parity 测试,该测试将
相同的输入提供给旧的 V1 和新的 V2 流水线,并断言
生成的 HCS ComputeSystem 文档是等效的。它们位于 `test` Go
模块中,并且也是使用 build tag 构建的:
```
C:\> cd test
C:\> go test -tags lcow ./parity/...
```
### Linting
代码必须通过 linting 阶段,该阶段使用 [`golangci-lint`][lint]。
由于 `./test` 是一个独立的 Go 模块,linter 会从根目录和
`test` 目录中分别运行。此外,linter 运行时会将 `GOOS` 同时设置为 `windows` 和
`linux`。
Linting 设置存储在 [`.golangci.yaml`](./.golangci.yaml) 中,可以通过
将以下内容添加到你的工作区或文件夹设置中,在 VSCode 中自动运行:
```
"go.lintTool": "golangci-lint",
"go.lintOnSave": "package",
```
此外,还提供了其他的编辑器[集成选项][lint-ide]。
或者,可以在本地[安装][lint-install]并运行 `golangci-lint`:
```
# 使用 . 或指定一个路径以仅 lint 一个 package
# 要显示所有 lint 错误,请使用 flags "--max-issues-per-linter=0 --max-same-issues=0"
> golangci-lint run
```
要在整个仓库中针对 `GOOS=windows` 和 `linux` 运行:
```
> foreach ( $goos in ('windows', 'linux') ) {
foreach ( $repo in ('.', 'test') ) {
pwsh -Command "cd $repo && go env -w GOOS=$goos && golangci-lint.exe run --verbose"
}
}
```
### Go Generate
流水线会检查通过 `go generate` 自动生成的代码是否为最新。
与 [linting 阶段](#linting)类似,`go generate` 会在根 Go 模块和 test Go 模块中分别运行。
这可以通过以下方式完成:
```
> go generate ./...
> cd test && go generate ./...
```
## 依赖
此项目需要 Golang 1.18 或更高版本才能构建。
有关运行此项目的系统要求,请参阅 Microsoft 关于 [Windows Container requirements](https://docs.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/system-requirements) 的文档。
## 报告安全问题
安全问题与 bug 应通过电子邮件私下报告给 Microsoft Security
Response Center (MSRC),邮箱地址为 [secure@microsoft.com](mailto:secure@microsoft.com)。你应该
在 24 小时内收到回复。如果由于某种原因你没有收到,请通过
电子邮件跟进,以确保我们收到了你的原始消息。更多信息,包括
[MSRC PGP](https://technet.microsoft.com/en-us/security/dn606155) 密钥,可以在
[Security TechCenter](https://technet.microsoft.com/en-us/security/default) 中找到。
有关更多详细信息,请参阅 Technet 上的 [Report a Computer Security Vulnerability](https://technet.microsoft.com/en-us/security/ff852094.aspx)
Copyright (c) 2018 Microsoft Corp. All rights reserved.
标签:EVTX分析, Golang, HCS, Windows容器, 安全编程, 容器运行时, 日志审计, 虚拟化, 运维工具