Qingular

扩展接口(CNI/CSI/CRI)

·CKAk8s练习

Kubernetes 的三大扩展接口:容器网络接口(CNI)、容器存储接口(CSI)和容器运行时接口(CRI),是实现 Kubernetes 可扩展性的核心机制。

← 返回 CKA 练习目录

概述

Kubernetes 通过 CNI(Container Network Interface)、CSI(Container Storage Interface)和 CRI(Container Runtime Interface)三大标准接口实现了插件化的可扩展架构。这些接口将核心控制逻辑与具体实现解耦,使集群可以灵活选择网络、存储和运行时方案。CKA 考试要求理解各接口的作用和常见实现。


1. 三大接口概览

接口全称作用解决的问题
CNIContainer Network Interface容器网络Pod 网络连通与 IP 分配
CSIContainer Storage Interface容器存储持久化存储卷管理
CRIContainer Runtime Interface容器运行时容器创建与生命周期管理
┌─────────────────────────────────────────────────┐
│                   Kubernetes                      │
│  ┌───────────────────────────────────────────┐   │
│  │          API Server / Controller           │   │
│  │              ────────                      │   │
│  │        CRI       │      CNI      CSI       │   │
│  │         │        │        │        │       │   │
│  │    ┌────▼────┐ ┌─▼────┐ ┌─▼──────┐        │   │
│  │    │containerd│ │Calico│ │  CSI   │        │   │
│  │    │  CRI-O   │ │Flannel│ │ Driver │        │   │
│  │    │          │ │Cilium │ │(AWS,EBS│        │   │
│  │    └─────────┘ └──────┘ │  ...)  │        │   │
│  └─────────────────────────┴─────────┘        │   │
└─────────────────────────────────────────────────┘

2. CNI -- Container Network Interface

2.1 概述

CNI 定义了容器网络的配置规范。当 Pod 创建时,Kubelet 调用 CNI 插件负责分配 IP 地址,配置网络接口和路由规则,确保 Pod 间网络互通。

2.2 CNI 插件职责

功能说明
IP 地址管理(IPAM)为 Pod 分配唯一的 IP 地址
网络连通性确保同一节点和跨节点的 Pod 可以通信
网络策略实现 NetworkPolicy 访问控制(部分插件)
服务代理部分 CNI 插件集成 kube-proxy 替代方案

2.3 常见 CNI 插件对比

插件特点网络模式网络策略性能
Calico功能全面,支持 BGP纯 L3 路由(vxlan/ipip/bgp)支持优秀
Flannel简单易用,性能尚可Overlay(vxlan/host-gw)不支持中等
CiliumeBPF 驱动,高性能eBPF(vxlan/direct)支持(增强)极高
Weave简单部署,加密通信Overlay(weave mesh)支持中等
Multus多网络接口附加接口依赖元插件--

2.4 CNI 配置

# CNI 配置目录
/etc/cni/net.d/

# 查看当前使用的 CNI 插件
ls /etc/cni/net.d/
cat /etc/cni/net.d/10-calico.conflist
cat /etc/cni/net.d/10-flannel.conflist

# CNI 二进制目录
/opt/cni/bin/
ls /opt/cni/bin/
# 常见的 CNI 二进制:
# bridge, host-local, loopback, portmap, bandwidth, tuning
# 加上插件特有的二进制(calico, flannel, cilium 等)

# 查看 CNI 版本
/opt/cni/bin/bridge --version

2.5 CNI 配置示例

{
  "cniVersion": "0.3.1",
  "name": "k8s-pod-network",
  "plugins": [
    {
      "type": "calico",
      "datastore_type": "kubernetes",
      "ipam": {
        "type": "calico-ipam",
        "assign_ipv4": "true",
        "assign_ipv6": "false"
      },
      "policy": {
        "type": "k8s"
      }
    },
    {
      "type": "portmap",
      "capabilities": {"portMappings": true}
    },
    {
      "type": "bandwidth",
      "capabilities": {"bandwidth": true}
    }
  ]
}

2.6 CNI 调试命令

# 查看 Pod 网络接口
kubectl exec <pod-name> -- ip addr show
kubectl exec <pod-name> -- ip route

# 查看节点网络接口(通常是 CNI 创建的网桥或路由)
ip link show
ip route show

# 查看 CNI 插件日志
# Calico
kubectl logs -n calico-system -l k8s-app=calico-node
# Flannel
kubectl logs -n kube-flannel -l app=flannel
# Cilium
kubectl logs -n kube-system -l k8s-app=cilium

# 测试 Pod 间连通性
kubectl exec pod-a -- ping <pod-b-ip>

# 查看 IPAM 分配情况
# Calico
calicoctl ipam show
# Cilium
cilium ip list

3. CSI -- Container Storage Interface

3.1 概述

CSI 定义了存储系统的标准接口,允许 Kubernetes 无缝对接各种存储后端。使用 CSI 后,Kubernetes 核心代码无需包含各个云厂商的存储驱动。

3.2 CSI 架构组件

┌──────────────────────────────────────────────┐
│               Kubernetes Node                   │
│  ┌────────────────┐     ┌─────────────────┐   │
│  │   kubelet       │     │  CSI Driver     │   │
│  │  ────           │     │  ──────────     │   │
│  │  CSI Interface──┼─────┤  CSI Node       │   │
│  │                 │     │    Service      │   │
│  └────────────────┘     └────────┬────────┘   │
└──────────────────────────────────┼────────────┘
                                   │
┌──────────────────────────────────┼────────────┐
│         Control Plane            │            │
│  ┌────────────────┐     ┌───────▼────────┐   │
│  │  CSI Controller │     │  External      │   │
│  │  Sidecar        │     │  Provisioner   │   │
│  │  (Attacher,     │     │  (Storage      │   │
│  │   Resizer,      │     │   Backend)     │   │
│  │   Snapshotter)  │     │                │   │
│  └────────────────┘     └────────────────┘   │
└──────────────────────────────────────────────┘

3.3 CSI 核心组件

组件Sidecar功能
Provisionercsi-provisioner监听 PVC,自动创建存储卷
Attachercsi-attacher将存储卷挂载到节点
Resizercsi-resizer在线调整存储卷大小
Snapshottercsi-snapshotter创建和管理卷快照
Driver核心驱动实际与存储后端通信(二进制)
Node Driver Registrarnode-driver-registrar向 kubelet 注册 CSI 驱动

3.4 常见 CSI 驱动

存储类型CSI 驱动适用场景
AWS EBSebs.csi.aws.comAWS 块存储
AWS EFSefs.csi.aws.comAWS 文件存储
GCE PDpd.csi.storage.gke.ioGoogle Cloud 持久化磁盘
Azure Diskdisk.csi.azure.comAzure 托管磁盘
NFSnfs.csi.k8s.io通用 NFS 共享存储
Ceph/Rookrook-ceph.cephfs.csi.ceph.comCeph 分布式存储
Longhorndriver.longhorn.ioRancher 轻量分布式存储
HostPath内置(非 CSI)本地存储(仅测试用)

3.5 使用 CSI 的 StorageClass 示例

# StorageClass 使用 CSI 驱动
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: ebs-sc
provisioner: ebs.csi.aws.com
parameters:
  type: gp3
  fsType: ext4
  encrypted: "true"
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
reclaimPolicy: Delete
# 查看集群中的 CSI 驱动
kubectl get csidrivers

# 查看 CSI 驱动的详细信息
kubectl describe csidriver ebs.csi.aws.com

# 查看集群的 StorageClass
kubectl get storageclass
kubectl describe storageclass ebs-sc

# 查看 CSI 控制器 Pod
kubectl get pods -n kube-system | grep csi

# 查看 PV 的驱动信息
kubectl get pv -o yaml | grep -A5 "csi:"

4. CRI -- Container Runtime Interface

4.1 概述

CRI 是 kubelet 与容器运行时之间的接口协议。它使 kubelet 不直接依赖 Docker 或其他特定运行时,而是通过标准 gRPC API 与任何符合 CRI 规范的运行时通信。

4.2 CRI 架构

┌─────────────────────┐
│      kubelet        │
│    ──────────       │
│    gRPC Client      │
│    CRI API          │
└────────┬────────────┘
         │ gRPC (unix socket)
         ▼
┌─────────────────────┐
│   CRI Shim/Service  │
│  ────────────────   │
│   containerd        │
│   CRI-O             │
│   Docker via cri-dockerd │
└────────┬────────────┘
         │
         ▼
┌─────────────────────┐
│    Container         │
│    (runc / gVisor /  │
│     Kata Containers) │
└─────────────────────┘

4.3 CRI 运行时对比

运行时特点Socket 路径状态
containerd轻量、高性能、Kubernetes 默认unix:///var/run/containerd/containerd.sock推荐
CRI-O专为 Kubernetes 优化unix:///var/run/crio/crio.sock稳定
Docker (cri-dockerd)传统方案,需要适配器unix:///var/run/cri-dockerd.sock已弃用
gVisor沙箱隔离、增强安全unix:///var/run/gvisor/gvisor.sock特殊场景
Kata Containers轻量级 VM 级隔离unix:///var/run/kata-containers/kata.sock特殊场景

4.4 CRI 常用操作命令

# 使用 crictl 管理容器(推荐)
crictl version
crictl info

# 查看容器
crictl ps
crictl ps -a              # 包含已停止
crictl ps --name nginx    # 按名称过滤

# 查看镜像
crictl images
crictl images -v

# 拉取/删除镜像
crictl pull nginx:latest
crictl rmi nginx:latest

# 查看 Pod
crictl pods
crictl pods --name nginx

# 查看容器日志
crictl logs <container-id>
crictl logs -f <container-id>  # 实时日志

# 执行命令
crictl exec -it <container-id> /bin/sh

# 查看容器统计
crictl stats

# 查看容器详细信息
crictl inspect <container-id>
crictl inspectp <pod-id>

# 配置 crictl
cat /etc/crictl.yaml
# runtime-endpoint: unix:///var/run/containerd/containerd.sock
# image-endpoint: unix:///var/run/containerd/containerd.sock
# timeout: 10
# debug: false

4.5 查看 CRI 配置

# 查看 kubelet 使用的 CRI 配置
kubectl get nodes -o json | jq '.items[].status.nodeInfo.containerRuntimeVersion'

# 查看 containerd 配置
cat /etc/containerd/config.toml

# 查看 CRI-O 配置
cat /etc/crio/crio.conf

# 查看 kubelet CRI socket 配置
ps aux | grep kubelet | grep container-runtime-endpoint
# 或
cat /var/lib/kubelet/kubeadm-flags.env

5. 三大接口工作原理总结

Pod 创建流程(涉及三大接口):

1. API Server 创建 Pod
2. Scheduler 调度到节点
3. kubelet 收到 Pod 创建请求
   │
   ├── CRI(容器运行时)
   │    └── 通过 containerd/CRI-O 创建容器
   │
   ├── CNI(网络)
   │    └── 调用 CNI 插件分配 IP 地址、配置网络
   │
   └── CSI(存储,如有 PVC)
        └── 通过 CSI 驱动挂载存储卷

CKA 考试要点

  1. CRI:crictl 命令 -- 考试中常用 crictl 替代 docker 命令管理容器
  2. CRI Socket 配置 -- kubelet 通过 --container-runtime-endpoint 指定 socket
  3. CNI 配置目录 -- /etc/cni/net.d//opt/cni/bin/ 两个目录需要了解
  4. CSI 资源对象 -- StorageClass、PV、PVC、CSIDriver 的关系
  5. 常见插件名称 -- Calico、Flannel、Cilium(CNI);Ceph/Rook、Longhorn(CSI);containerd、CRI-O(CRI)

🧪 完整操作实例:验证集群的 CNI/CSI/CRI 配置

场景描述

在已运行的集群中检查当前使用的 CNI 网络插件、CSI 存储驱动和 CRI 容器运行时,掌握三大扩展接口的排查方法。

前置条件

  • 一个运行中的 Kubernetes 集群
  • kubectl 已配置并可正常访问集群
  • 节点 sudo 访问权限(可选)

操作步骤

Step 1: 检查 CRI 容器运行时

# 查看节点使用的容器运行时
kubectl get nodes -o jsonpath='{.items[*].status.nodeInfo.containerRuntimeVersion}'
# containerd://1.7.x

# 查看 kubelet 的 CRI socket 配置
cat /var/lib/kubelet/kubeadm-flags.env
# KUBELET_KUBEADM_ARGS="--container-runtime-endpoint=unix:///var/run/containerd/containerd.sock ..."

# 使用 crictl 查看容器运行时信息
sudo crictl info | grep -E "runtimeName|runtimeVersion"
# "runtimeName": "containerd"
# "runtimeVersion": "1.7.x"

# 查看 crictl 配置
cat /etc/crictl.yaml
# runtime-endpoint: unix:///var/run/containerd/containerd.sock
# image-endpoint: unix:///var/run/containerd/containerd.sock

Step 2: 检查 CNI 网络插件

# 查看 CNI 插件 Pod(不同 CNI 位于不同命名空间)
kubectl get pods --all-namespaces | grep -E "calico|flannel|cilium|weave"
# calico-system   calico-node-xxxxx                 1/1     Running   0   1h
# calico-system   calico-kube-controllers-xxxxx      1/1     Running   0   1h

# 查看 CNI 配置目录
ls /etc/cni/net.d/
# 10-calico.conflist

# 查看 CNI 配置详情
cat /etc/cni/net.d/10-calico.conflist
# {
#   "name": "k8s-pod-network",
#   "cniVersion": "0.3.1",
#   "plugins": [
#     { "type": "calico", ... },
#     { "type": "portmap", ... }
#   ]
# }

# 查看 CNI 二进制文件
ls /opt/cni/bin/
# bandwidth  bridge  calico  calico-ipam  flush  host-local  loopback  portmap  tuning

Step 3: 检查 CSI 驱动

# 查看已注册的 CSI 驱动
kubectl get csidrivers
# NAME                          ATTACHREQUIRED   PODINFOONMOUNT   MODES        AGE
# ebs.csi.aws.com               true             false            Persistent   30d

# 查看集群中的 StorageClass
kubectl get storageclass
# NAME            PROVISIONER                    RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
# ebs-sc          ebs.csi.aws.com                Delete          WaitForFirstConsumer   true                   30d
# standard        kubernetes.io/gce-pd           Delete          Immediate             false                  30d

# 查看 CSI 控制器 Pod
kubectl get pods -n kube-system | grep csi
# ebs-csi-controller-xxxxxxxxx-xxxxx       6/6     Running   0   30d
# ebs-csi-node-xxxxx                       3/3     Running   0   30d

# 查看 CSI 驱动详情
kubectl describe csidriver ebs.csi.aws.com

Step 4: 验证 Pod 网络与存储

# 查看 Pod 网络接口
kubectl run net-test --image=busybox --rm -it --restart=Never -- ip addr show
# 1: lo: <LOOPBACK> ...
# 2: eth0@if...: <BROADCAST,MULTICAST,UP,LOWER_UP> ... inet 192.168.1.5/32  <-- CNI 分配的 IP

# 查看 Pod 中是否有 CSI 挂载的卷
kubectl get pod <pod-with-pvc> -o json | jq '.spec.volumes[] | select(.csi != null)'
# {
#   "name": "data",
#   "csi": {
#     "driver": "ebs.csi.aws.com",
#     "volumeHandle": "vol-xxxxxxxxx"
#   }
# }

验证结果

# 汇总查看三大接口状态
echo "=== CRI Runtime ==="
kubectl get nodes -o jsonpath='{.items[*].status.nodeInfo.containerRuntimeVersion}'
echo ""
echo "=== CNI Plugins ==="
ls /opt/cni/bin/ | tr '\n' ' '
echo ""
echo "=== CSI Drivers ==="
kubectl get csidrivers -o name

考试提示

  • CRI:使用 crictl 命令管理容器(类似 docker),crictl pscrictl imagescrictl logs
  • CNI:配置在 /etc/cni/net.d/(配置文件),二进制在 /opt/cni/bin/
  • CSI:用 kubectl get csidrivers 查看已注册驱动,在 StorageClass 的 provisioner 字段中引用
  • 排查网络问题时先确认 CNI Pod 是否正常运行:kubectl get pods -n calico-system
  • 排查存储问题时顺序:StorageClass -> PVC -> PV -> CSI Driver

官方文档