Podman、containerd 与 CRI 生态

共 21 题
📑 题目列表 21 题
#
★★★

1. containerd 的 CRI plugin 如何实现 Kubernetes 的容器运行时接口?

请说明 containerd 的 CRI plugin 如何实现 Kubernetes 的容器运行时接口?

  • CRI 是 kubelet 与运行时之间的接口
  • containerd 的 CRI plugin 实现 RuntimeService/ImageService
  • 与 kubelet 的 gRPC 交互

Kubernetes 的 CRI(Container Runtime Interface)定义了 kubelet 与容器运行时之间的 gRPC 接口,包含 RuntimeService(容器生命周期:创建/启动/停止/删除)与 ImageService(镜像拉取/检查)。containerd 通过内置的 CRI plugin(cri 插件)实现该接口:containerd 作为运行时,暴露 CRI 的 gRPC 服务,kubelet 通过 gRPC 调用与 containerd 交互,管理 Pod 沙箱(sandbox)与容器。containerd 负责容器创建、镜像管理、运行时(runc/gVisor)调用,CRI plugin 把 kubelet 请求转换为 containerd 内部操作。这是 K8s 使用 containerd 作为运行时(或 CRI-O)的机制。

CRI 是 kubelet 与运行时的抽象接口,containerd 的 CRI plugin 实现 RuntimeService/ImageService,kubelet 经 gRPC 调用。

#
★★

2. BuildKit 如何导入/导出构建缓存(inline/registry/local)以加速 CI 构建?

请说明 BuildKit 如何导入/导出构建缓存(inline/registry/local)以加速 CI 构建?

  • 缓存导出类型(inline/registry/local)
  • 缓存导入复用
  • 加速 CI 构建的原理

BuildKit 支持把构建缓存导出(--cache-to)与导入(--cache-from)以跨构建复用。类型:1) inline:把缓存内嵌进镜像(随镜像推送到仓库),简单但镜像变大;2) registry:把缓存导出到专门的 registry 缓存(如 type=registry,ref=...),镜像不臃肿,CI 可用;3) local:把缓存导出到本地目录(type=local,dest=...),用同一目录复用。CI 构建时先用 --cache-from 加载缓存,命中层则不重建,加速 CI。原理层缓存按层复用,缓存命中可跳过重建步骤。配合认证与多平台,可显著缩短 CI 构建时间。

缓存导入/导出(inline/registry/local)复用层缓存,跳过重建步骤,加速 CI 构建。

docker build --cache-to=type=registry,ref=myapp:cache --cache-from=type=registry,ref=myapp:cache .
docker build --cache-from=type=local,src=/cache --cache-to=type=local,dest=/cache .
#
★★

3. BuildKit 的 buildkitd 守护进程如何组织构建会话与执行前端(frontend)?

请说明 BuildKit 的 buildkitd 守护进程如何组织构建会话与执行前端(frontend)?

  • buildkitd 守护进程与构建会话
  • frontend(前端)解析 Dockerfile
  • 执行器与快照

buildkitd 是 BuildKit 的守护进程,负责构建的执行与缓存管理。构建时客户端发起构建会话(Build Session),buildkitd 接收并处理。frontend(前端,如 dockerfile 前端)解析 Dockerfile 并生成构建计划(LLB),buildkitd 使用执行器(executor)在沙箱中执行构建步骤,用快照(snapshot)管理每步的文件系统状态。buildkitd 管理缓存、并行执行、多平台构建。frontend 与 buildkitd 的分离使构建逻辑可扩展(自定义 frontend)。构建会话可断点续传、支持多客户端。

buildkitd 是构建守护进程,frontend 解析 Dockerfile 生成计划,executor 执行、snapshot 管状态,是 BuildKit 架构核心。

#
★★

4. CRI 在 K8s 容器运行时的接口

请说明 CRI 在 K8s 容器运行时的接口?

  • CRI 的定位与协议
  • RuntimeService 与 ImageService
  • 支持运行时(containerd/CRI-O)

CRI(Container Runtime Interface)是 Kubernetes 定义的标准接口,用于 kubelet 与容器运行时通信。它通过 gRPC 定义两个服务:RuntimeService(管理 Pod 与容器生命周期:RunPodSandbox、CreateContainer、StartContainer、StopContainer 等)与 ImageService(管理镜像:PullImage、ListImages、RemoveImage)。kubelet 作为 CRI 客户端,调用这些接口管理容器与镜像。兼容 CRI 的运行时包括 containerd、CRI-O、kata-containers 等。CRI 让 K8s 与运行时解耦,支持多种运行时而无须改 kubelet。

CRI 是 kubelet 与运行时间的 gRPC 接口(RuntimeService+ImageService),使 K8s 与运行时解耦。

#
★★

5. Kata Containers 如何通过轻量级虚拟机(VMM)实现强隔离容器运行时?

请说明 Kata Containers 如何通过轻量级虚拟机(VMM)实现强隔离容器运行时?

  • Kata 把容器放进轻量级 VM
  • 用 VMM 提供内核隔离
  • 强隔离与性能权衡

Kata Containers 是强隔离容器运行时:每个容器(或 Pod 沙箱)运行在独立的轻量级虚拟机(VMM,如 QEMU/Cloud Hypervisor)中,拥有自己的内核,与宿主机及其他容器隔离。它结合了容器的镜像/OCI 接口与 VM 的内核隔离,即使容器被攻破,也难逃逸到宿主机(有独立内核边界)。实现:通过 containerd 的 CRI 集成,Kata 创建 VM 沙箱,容器在 VM 内运行。收益:强隔离(安全)、兼容 OCI;代价:性能与内存开销高于普通容器(有 VM 启动与资源开销)。适用安全要求高的多租户场景。

Kata 用轻量级 VM 提供独立内核,实现强隔离但增加 VM 开销,是安全容器与普通容器间的权衡。

#
★★

6. Podman rootless 模式如何通过 slirp4netns 实现端口映射与网络隔离?

请说明 Podman rootless 模式如何通过 slirp4netns 实现端口映射与网络隔离?

  • rootless 无 root 网络用 slirp4netns
  • 用户态网络栈与端口转发
  • 网络隔离

Podman rootless 模式下容器以非 root 运行,无法直接创建网络命名空间与 iptables,默认使用 slirp4netns 提供用户态网络栈:容器通过 slirp4netns 在用户态模拟网络(NAT),无需 root 权限。端口映射通过 slirp4netns 的端口转发实现(容器端口转发到宿主机),网络隔离指容器与其他容器/宿主机通过用户态 NAT 隔离。slirp4netns 适用于 rootless 的简单 NAT 网络,但性能比 rootful 的 veth/bridge 略低。需要更复杂网络时用 rootless 的 pasta 或配置。rootless 网络增强了无特权安全性。

rootless 用 slirp4netns 用户态 NAT 提供网络与端口映射,无需 root 但性能略低,是 rootless 安全性的基础。

#
★★

7. Podman 如何通过 play kube / generate kube 与 Kubernetes Pod 清单兼容?

请说明 Podman 如何通过 play kube / generate kube 与 Kubernetes Pod 清单兼容?

  • play kube 从 k8s 清单创建 Pod
  • generate kube 从容器生成清单
  • 与 K8s 的互操作

Podman 支持与 Kubernetes Pod 清单互操作:1) podman play kube <pod.yaml>:读取 Kubernetes Pod/Deployment 清单,在本地创建对应的 Pod 与容器,无需 K8s 集群;2) podman generate kube <pod>:把本地运行的 Pod/容器生成 Kubernetes 清单(.yaml),便于部署到 K8s。这使开发环境(Podman)与生产(K8s)共享同一清单,提升一致性。兼容性:Podman 支持大部分 K8s 清单字段(container、volume、restartPolicy 等),但部分 K8s 特定功能(如 service mesh)不支持。podman play kube 常用 --replace 更新。

play kube/generate kube 让 Podman 与 K8s 清单双向转换,实现开发与生产一致性。

podman play kube pod.yaml
podman generate kube mypod > pod.yaml
podman play kube --replace pod.yaml
#
★★

8. containerd 如何通过 CNI 插件为容器配置网络(沙箱创建与接口拆除)?

请说明 containerd 如何通过 CNI 插件为容器配置网络(沙箱创建与接口拆除)?

  • CNI 插件为容器配网
  • 沙箱创建时配置网络
  • 移除时拆除接口

containerd 通过 CNI(Container Network Interface)插件为容器配置网络。创建 Pod 沙箱(sandbox)时,containerd 调用 CNI 插件(如 bridge、calico、flannel)为沙箱创建网络命名空间并配置网络接口(veth、IP 分配、路由)。这是"ADD"操作。容器加入沙箱后使用该网络。移除沙箱/容器时,containerd 调用 CNI 的"DEL"操作拆除网络接口、释放 IP。CNI 把网络配置与运行时解耦,支持多种网络插件。containerd 通过 CRI 的 PodSandbox 管理网络生命周期。

containerd 在沙箱创建时调 CNI ADD 配置网络、移除时 DEL 拆除,与具体网络插件解耦。

#
★★

9. containerd 的垃圾回收如何清理不再使用的镜像与快照?

请说明 containerd 的垃圾回收(GC)如何清理不再使用的镜像与快照?

  • containerd 的 GC 机制
  • 清理未引用镜像与快照
  • 与 Docker prune 的区别

containerd 内置垃圾回收(GC)机制,定期清理不再被引用的对象:1) 镜像(image):没有容器引用的镜像;2) 快照(snapshot):没有容器/镜像引用的快照层;3) 内容(content):无引用的 blob。GC 通过引用计数跟踪对象,删除未被引用的内存与磁盘资源。containerd 的 GC 是自动/后台的,不同于 Docker 的显式 docker system prune。用 ctr images prunenerdctl system prune 可手动清理。GC 释放磁盘,但需注意正在使用的镜像/快照不会被误删。配置可通过 containerd 配置调整 GC 行为。

containerd GC 按引用清理未使用的镜像/快照/content,自动后台运行,释放磁盘。

#
★★

10. ctr 与 nerdctl 作为 containerd 客户端工具的定位差异与调试场景?

请说明 ctr 与 nerdctl 作为 containerd 客户端工具的定位差异与调试场景?

  • ctr 是 containerd 原生 CLI
  • nerdctl 是 Docker 兼容 CLI
  • 调试场景差异

ctr 是 containerd 的原生 CLI,直接操作 containerd 的 gRPC API,功能底层、适合调试 containerd 内部(namespace、image、container、task、snapshot、content),但接口偏底层、不友好、无 Docker 兼容。nerdctl 是 containerd 的"类 Docker"兼容 CLI,支持 nerdctl rundocker compose 等 Docker 风格命令,并支持 CNI、K8s 相关功能,适合日常管理 containerd 与迁移 Docker 工作流。调试场景:排查 containerd 底层(namespace/快照/镜像存储)用 ctr;日常容器管理、与 Docker 兼容操作用 nerdctl。两者定位互补。

ctr 是底层原生 CLI,用排查 containerd 内部;nerdctl 是 Docker 兼容 CLI,用于日常管理,定位互补。

#
★★

11. ctr 的 namespace、image、container、task 子命令分别执行哪些管理操作?

请说明 ctr 的 namespace、image、container、task 子命令分别执行哪些管理操作?

  • namespace 管理多租户
  • image 镜像管理
  • container/task 容器与任务管理

ctr 子命令:1) ctr namespace:管理命名空间(create/list/remove),用于多租户隔离(不同命名空间隔离容器与镜像);2) ctr images:管理镜像(pull/list/import/export/remove),负责镜像拉取与存储;3) ctr containers:管理容器(create/list/delete),定义容器对象(配置);4) ctr tasks:管理任务(start/stop/exec),任务是容器对象的运行实例(进程)。层次:namespace 隔离 → image 镜像 → container 配置 → task 运行时。ctr 从底层暴露这些对象,便于调试 containerd 各层。

ctr 子命令对应 containerd 各对象:namespace 隔离、images 镜像、containers 容器配置、tasks 运行实例。

#
★★

12. daemon.json 关键配置(log-driver/max-size、registry-mirrors、insecure-registries)

请说明 Docker daemon.json 关键配置:log-driver/max-size、registry-mirrors、insecure-registries?

  • log-driver 与日志大小
  • registry-mirrors 镜像加速
  • insecure-registries 不安全的私有仓库

daemon.json 是 Docker 守护进程配置,关键项:1) log-driverlog-opts:指定日志驱动(json-file/journald/syslog)与日志轮转(max-size/max-file),防止日志占满磁盘;2) registry-mirrors:配置镜像加速器(registry mirror),加快镜像拉取,常用于国内加速;3) insecure-registries:声明 HTTP 或自签名证书的私有仓库(跳过 TLS 校验),用于内网私有仓库,但有安全风险(明文传输)。其他如 data-root(存储目录)、exec-optsstorage-driver。修改后需重启 dockerd。配置需兼顾性能、安全与运维。

daemon.json 配置日志驱动与大小、镜像加速器、私有仓库安全,是 Docker 运维的重要配置。

{
  "log-driver": "json-file",
  "log-opts": { "max-size": "10m", "max-file": "3" },
  "registry-mirrors": ["https://mirror.example.com"],
  "insecure-registries": ["10.0.0.1:5000"]
}
#
★★

13. kubelet 作为 CRI gRPC 客户端如何与容器运行时(RuntimeService/ImageService)交互?

请说明 kubelet 作为 CRI gRPC 客户端如何与容器运行时(RuntimeService/ImageService)交互?

  • kubelet 是 CRI 客户端
  • 调用 RuntimeService/ImageService
  • 交互流程

kubelet 是 CRI 的 gRPC 客户端,通过 Unix socket 连接容器运行时(如 containerd/CRI-O)的 CRI gRPC 服务。kubelet 调用 RuntimeService 管理 Pod 沙箱与容器(RunPodSandbox、CreateContainer、StartContainer、StopContainer、RemoveContainer),调用 ImageService 管理镜像(PullImage、ListImages、RemoveImage)。kubelet 按 Pod 生命周期驱动这些调用:先建沙箱(网络),再拉镜像、建容器、启动,监控状态。运行时通过 CRI 返回状态,kubelet 与 apiserver 同步。kubelet 与运行时通过 gRPC 接口解耦,支持多种运行时。

kubelet 作为 CRI gRPC 客户端调用 RuntimeService/ImageService 管理容器与镜像,是 K8s 与运行时交互核心。

#
★★

14. kubelet 如何通过 streaming API 支撑 kubectl exec/attach/port-forward?

请说明 kubelet 如何通过 streaming API 支撑 kubectl exec/attach/port-forward?

  • streaming API 与 kubectl exec/attach/port-forward
  • kubelet 作为流式服务端
  • 与运行时/CRI 的配合

kubectl exec/attach/port-forward 需要交互式流(stdin/stdout、端口转发),kubelet 通过 streaming API(kubelet 的 streaming 服务器)支撑。流程:kubectl 请求 apiserver,apiserver 转发到 kubelet 的 streaming 端点,kubelet 用 CRI 的 ExecAttach/PortForward 调用运行时(containerd)建立流,再由 kubelet 的 streaming 服务器把流(WebSocket/SPDY)中转给客户端。kubectl exec 通过此流执行容器内命令、attach 附加容器、port-forward 建立端口转发。streaming API 把长连接流与 kubelet 解耦,支撑交互式操作。

kubelet 的 streaming API 中转 kubectl exec/attach/port-forward 的交互流,配合 CRI 的 exec/attach/portforward 实现。

#
★★

15. kubelet 如何采集容器日志并处理日志轮转与磁盘占用?

请说明 kubelet 如何采集容器日志并处理日志轮转与磁盘占用?

  • 容器日志采集路径
  • 日志轮转(log rotation)
  • 磁盘占用控制

kubelet 采集容器日志:容器日志由运行时写在节点目录(如 /var/log/containers/、/var/log/pods/),kubelet 通过容器运行时(CRI)与日志文件管理,日志最终由日志采集器(如 filebeat、fluentd)转发到集中日志系统。日志轮转与磁盘占用:kubelet 通过 kubelet 配置与容器运行时日志策略控制轮转,如 containerLogMaxSize(如 10Mi)与 containerLogMaxFiles(如 5)限制单容器日志大小与文件数,防止日志占满磁盘;containerd 的日志配置(max-size/max-file)也控制。kubelet 监控日志文件,超限自动轮转。磁盘占用控制是节点稳定性关键。

kubelet 采集容器日志并配合运行时日志轮转(maxSize/maxFiles)控制磁盘占用,防日志占满。

#
★★

16. kubelet 如何采集节点与容器指标并对外暴露?

请说明 kubelet 如何采集节点与容器指标并对外暴露?

  • kubelet 的 cAdvisor 集成
  • 节点与容器指标
  • 通过 metrics API 暴露

kubelet 内置集成 cAdvisor,采集节点与容器运行指标:CPU、内存、网络、磁盘、文件系统等。指标通过 kubelet 的 metrics 端点暴露(如 /metrics 供 Prometheus 抓取),以及通过 metrics-server(K8s 的 metrics API)提供容器/节点资源使用(供 HPA、kubectl top 使用)。kubelet 采集的指标包括节点级(CPU/内存总量)与容器级(cgroup 数据)。metrics-server 定期从 kubelet 拉取聚合,提供 ResourceMetrics API。指标采集与暴露是监控与自动扩缩的基础。

kubelet 集成 cAdvisor 采集节点/容器指标,经 metrics 端点与 metrics-server 暴露,支撑监控与 HPA。

#

17. BuildKit 如何生成镜像 provenance/SBOM 以支持供应链审计?

请说明 BuildKit 如何生成镜像 provenance/SBOM 以支持供应链审计?

  • provenance(来源/构建信息)
  • SBOM(软件物料清单)
  • 供应链审计

BuildKit 支持生成镜像的 provenance 与 SBOM 以支持供应链安全:1) provenance(来源):记录镜像构建的元数据(构建命令、依赖、基础镜像、构建参数、attestation),可追溯镜像来源;2) SBOM(Software Bill of Materials,软件物料清单):列出镜像内包含的软件包与版本,用于漏洞扫描与合规审计。通过 BuildKit 的 attestation(如 --attest type=sbom--attest type=provenance)生成,并推送到 registry(OCI 附件)。这使得镜像可验证来源、可审计软件组成,支持供应链安全(SLSA 等)。

BuildKit 的 attestation 生成 provenance/SBOM,记录来源与软件清单,支持供应链审计与合规。

#

18. BuildKit 如何通过 --cache-from=type=local 复用本地构建缓存?

请说明 BuildKit 如何通过 --cache-from=type=local 复用本地构建缓存?

  • type=local 缓存
  • 本地缓存导出/导入
  • 复用场景

--cache-from=type=local 让 BuildKit 从本地目录加载构建缓存,--cache-to=type=local,dest=... 导出缓存到本地目录。本地缓存适合在单机/CI 中跨构建复用:构建时用 --cache-from=type=local,src=/cache 加载上轮缓存的层,命中层则跳过重建,构建完成用 --cache-to=type=local,dest=/cache 导出新缓存,供下次使用。相比 registry 缓存,本地缓存无需网络/仓库,适合单机多次构建或 CI runner 本地加速。缓存目录需持久化(如 CI 缓存卷)。它是 BuildKit 本地加速构建的手段。

type=local 缓存从本地目录加载/导出层缓存,跨构建复用,跳过重建加速本地/CI 构建。

docker build --cache-from=type=local,src=/cache \
  --cache-to=type=local,dest=/cache .
#

19. BuildKit 的 executor 如何执行构建步骤(沙箱、快照与并行)?

请说明 BuildKit 的 executor 如何执行构建步骤(沙箱、快照与并行)?

  • executor 在沙箱执行构建步骤
  • 快照管理文件系统状态
  • 并行执行

BuildKit 的 executor 负责执行构建步骤:1) 沙箱:每个构建步骤在隔离的沙箱(命名空间)中执行,避免相互干扰与宿主机污染;2) 快照:每个步骤用快照(snapshot)管理文件系统(在步骤基础上叠加,COW),步骤完成生成新快照作为下一层;3) 并行:executor 可并行执行无依赖的构建步骤,提升构建速度;4) 缓存:步骤结果按输入哈希缓存,命中则跳过。executor 通过 runc 等运行时执行命令,配合快照实现层管理与构建加速。executor 是 BuildKit 构建执行的引擎。

executor 在沙箱并行执行步骤、用快照管理文件系统状态、按哈希缓存,是构建执行与层管理的核心。

#

20. Cloud Hypervisor 作为轻量级 VMM 的架构特点与在 Kata Containers 中的角色?

请说明 Cloud Hypervisor 作为轻量级 VMM 的架构特点与在 Kata Containers 中的角色?

  • Cloud Hypervisor 的轻量架构
  • 面向云/容器负载
  • 在 Kata 中作为 VMM

Cloud Hypervisor 是面向云工作负载与容器的轻量级 VMM(虚拟机监视器),基于 Rust 编写,精简(去掉传统 PC 的兼容设备,聚焦云负载),启动快、内存占用低、性能好。架构特点:精简设备模型、virtio 支持、低延迟启动、适合容器场景。在 Kata Containers 中,Cloud Hypervisor 可作为 Kata 的 VMM 之一(替代 QEMU),为 Kata 的轻量级 VM 沙箱提供更轻、更快、更安全的虚拟化,减少 VM 启动延迟与资源开销,提升 Kata 的性能与密度。Cloud Hypervisor 定位是"云原生的轻量 VMM"。

Cloud Hypervisor 是精简轻量 VMM,在 Kata 中作为 VMM 提供更轻快的 VM 沙箱,提升性能与密度。

#

21. gVisor 如何通过用户态内核(Sentry/Gofer)拦截系统调用实现隔离?

请说明 gVisor 如何通过用户态内核(Sentry/Gofer)拦截系统调用实现隔离?

  • gVisor 拦截系统调用
  • Sentry 用户态内核
  • Gofer 文件系统代理

gVisor 是用户态内核实现的容器沙箱:容器进程的系统调用被拦截,不直接到达宿主机内核,而是由用户态的内核(Sentry)处理。Sentry 用 Go 实现系统调用语义,模拟内核行为,提供进程管理、网络、文件系统等接口,从而把容器与宿主机内核隔离,即使容器有系统调用漏洞也难以逃逸到宿主机。Gofer 负责文件系统访问,代理容器与宿主机文件系统的交互,减少攻击面。架构:系统调用 → Sentry(用户态内核)→ 宿主机。代价:系统调用经用户态处理有性能开销。gVisor 提供强隔离但性能低于普通容器。

gVisor 用 Sentry 用户态内核拦截系统调用、Gofer 代理文件系统,隔离容器与宿主机内核,代价是性能开销。