7.1. 发行版、CRI 与本地集群

同样是 Kubernetes,kubeadm、k3s、EKS 的运维方式完全不同;同样是容器,containerd、gVisor、Kata 的隔离边界也完全不同。这一章把「集群从哪来、容器怎么跑、本地怎么练」放在一张图里,帮你在选型时不混淆层次。

层级:

L3 · 平台

难度:

基础到进阶

预计:

45 分钟

前置:

Linux、容器基础、kubeadm 集群

7.1.1. 发行版与托管服务

类型

代表

适合

标准自建

kubeadm

学习、可控的自建集群

轻量发行版

k3s、MicroK8s

边缘、开发、资源受限环境

安全加固

RKE2、Talos

生产自建、不可变基础设施

企业平台

OpenShift、Rancher

多集群治理、开箱即用的平台能力

托管服务

EKS、GKE、AKS、ACK、TKE

不想运维控制面的生产集群

托管服务不是「不用懂 Kubernetes」,而是把控制面、etcd、升级窗口交给云厂商;节点池、网络、身份、存储和成本仍然由你负责。自建集群则要多承担 etcd 备份、证书轮换、控制面高可用和版本升级。

7.1.2. CRI:kubelet 与运行时的契约

从 v1.24 起 dockershim 被移除,kubelet 通过 CRI(Container Runtime Interface) 调用运行时。常见实现:

  • containerd:最通用的默认选择,生态完整,crictl 可直接调试。

  • CRI-O:更贴近 Kubernetes 的最小运行时,OpenShift 常用。

  • Docker Engine:仍可用于本地构建镜像,但不再作为集群运行时。

crictl info
crictl pods
crictl images
kubectl get nodes -o wide

crictl 连接的是节点上的 CRI socket;如果它报连接失败,先检查 /var/run/containerd/containerd.sock 或 /var/run/crio/crio.sock。

7.1.3. 强隔离运行时

运行时

隔离方式

代价

runc

内核 namespace/cgroup

最轻,隔离最弱

gVisor

用户态内核(Sentry)

系统调用兼容性与性能损失

Kata Containers

轻量虚拟机

启动慢、资源开销高

Firecracker

微虚拟机

需要专门集成,适合 Serverless

用 RuntimeClass 把运行时暴露给 Pod:

runtimeclass-gvisor.yaml
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  name: gvisor
handler: runsc
---
apiVersion: v1
kind: Pod
metadata:
  name: untrusted-demo
spec:
  runtimeClassName: gvisor
  containers:
    - name: app
      image: nginx:1.27

前提是节点已安装对应 handler(如 runsc),否则 Pod 会停在 FailedCreatePodSandBox。不要给所有 Pod 默认套 gVisor;先评估系统调用、GPU、网络性能。

7.1.4. 本地开发集群

工具

特点

kind

用 Docker 容器当节点,CI 友好,最接近上游

k3d

k3s in Docker,启动快,资源占用低

minikube

功能全,驱动多,适合完整实验

colima / OrbStack

macOS 上的容器与 Linux 虚拟机运行时,可配合 kind/k3d

kind create cluster --name demo --image kindest/node:v1.31.0
kubectl cluster-info --context kind-demo
kind delete cluster --name demo

本地集群适合验证 YAML、CRD、Operator、Ingress;不适合压测真实网络与云盘性能。需要多节点、LoadBalancer、CSI 时,再切换到云上或虚拟机集群。

7.1.5. 实验:用 kind 观察 CRI

kind create cluster --name cri-demo
docker exec -it cri-demo-control-plane crictl info
docker exec -it cri-demo-control-plane crictl pods
kubectl run web --image=nginx:1.27
kubectl get pod web -o wide

观察 crictl pods 中的 sandbox 与业务容器,再对照 kubectl describe pod web 的容器 ID。理解「Pod 先有 sandbox,再有业务容器」是排查 CNI/运行时问题的关键。

7.1.6. 验证清单

  • 能说出当前集群是托管还是自建,升级由谁负责。

  • crictl info 能连上运行时,crictl pods 能看到 Pod sandbox。

  • 至少验证一种强隔离运行时,并知道它的性能代价。

  • 能用 kind/k3d 在 2 分钟内创建并删除一个本地集群。

  • 能解释 Docker 构建镜像与 CRI 运行容器的区别。

7.1.7. 排错表

现象

原因

处理

crictl 连接失败

socket 路径不对 / 运行时未启动

检查 kubelet --container-runtime-endpoint

Pod FailedCreatePodSandBox

RuntimeClass handler 不存在

节点安装 runsc/kata,检查 runtimeClass

本地集群镜像拉取慢

Docker 网络 / 代理

配置 kind/k3d 的镜像代理或预拉取

节点 NotReady

CNI 未安装

安装 CNI 后看 NetworkPluginNotReady

托管集群无法 SSH 节点

云厂商限制

用节点池镜像/启动脚本,不要依赖手工登录

7.1.8. 进阶挑战

  1. 用 kind 创建一个三节点集群,验证 Pod 跨节点通信。

  2. 在节点安装 gVisor,比较普通 runc 与 gVisor Pod 的启动时间与系统调用错误。

  3. 用 k3d 创建一个带 Ingress 的本地集群,部署一个 HTTPRoute 或 Ingress。

  4. 对比 EKS/GKE/AKS 的节点升级策略,写一份升级窗口检查表。

7.1.9. 小结

  • 发行版决定运维边界,运行时决定隔离边界,本地工具决定反馈速度。

  • CRI 是 kubelet 与运行时的契约;Docker 不再是集群运行时。

  • 强隔离运行时要用 RuntimeClass 显式声明,并接受性能与兼容性代价。

  • 本地集群优先 kind/k3d,生产集群优先托管或经过验证的发行版。

7.1.10. 延伸阅读