microsoft/hcsshim

GitHub: microsoft/hcsshim

hcsshim 是微软提供的 Go 语言库和工具集,封装了 Windows Host Compute Service API,用于在 Windows 平台上启动和管理各类容器。

Stars: 684 | Forks: 297

# hcsshim [![Build status](https://static.pigsec.cn/wp-content/uploads/repos/cas/1d/1d494e8e0d31b078d30d4187a990f06e7c891c9e4fc1b3499c6d8dedecded045.svg)](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容器, 安全编程, 容器运行时, 日志审计, 虚拟化, 运维工具