您可以通过使用基于CSI-Plugin的云盘直挂沙箱功能,有效地解决IO性能问题。本文介绍安全沙箱基于CSI Plugin的云盘直挂沙箱的实现原理,并通过示例说明如何通过云盘直挂沙箱,以及对比CSI-Plugin 云盘直挂沙箱、Host和9PFS三种挂载方式的IO性能。

背景信息

安全沙箱可基于CSI-Plugin实现云盘的挂载。社区方案中,云盘先被挂载到宿主机,再被格式化,然后被挂载到本地目录,最后通过9PFS文件系统把本地目录共享到容器内,但是9PFS文件系统会导致容器内IO性能急剧下降。为了解决IO性能问题,容器服务Kubernetes(ACK)安全沙箱提供了基于CSI-Plugin的云盘直挂沙箱功能。该功能对云盘挂载位置和挂载时间做了调整:挂载位置由宿主机上挂载改为容器内挂载;挂载时间由容器启动前挂载延迟到容器启动后挂载。由于容器内不再经过9PFS文件系统访问云盘,所以基于CSI-Plugin的云盘直挂沙箱能有效地解决IO性能问题。
注意 安全沙箱v2版本暂不支持云盘直挂沙箱功能。
从安全沙箱v1.1.0版本开始,ACK默认会为所有安全沙箱容器启用基于CSI-Plugin的云盘直挂沙箱功能。
图 1. 社区和ACK安全沙箱的云盘/NAS挂载方案对比图
挂载方案图

实现原理

云盘attach

实现基于CSI Plugin的云盘直挂沙箱功能的流程说明如下。

步骤序号 说明
Kubelet请求CSI-Plugin挂载云盘卷。
CSI-Plugin调用QueryServer服务(该服务是一个本地数据库,库里保存了挂载卷的信息)查看是否有挂载卷信息。
CSI-Plugin发现没有该挂载卷信息,就把信息写入到本地库,并记录挂载点、挂载目录等信息,然后格式化云盘。
Pod的准备工作就绪后,Kubelet开始创建容器,该请求最终会转发到Kata-Runtime。
Kata-Runtime调用QueryServer服务查看该挂载卷,获取到挂载点、挂载目录等信息。
Kata-Runtime请求Kata-Agent。
Kata-Agent启动容器并挂载该卷。

示例

以下通过使用YAML模板创建资源对象举例说明如何在沙箱容器中挂载云盘。

  1. 执行以下命令使用模板创建资源对象。
    cat <<EOF | kubectl create -f -
    allowVolumeExpansion: true
    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: alicloud-disk-ssd
    parameters:
      type: cloud_ssd
    provisioner: diskplugin.csi.alibabacloud.com
    reclaimPolicy: Delete
    ---
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: disk-pvc-01
      namespace: default
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 25Gi
      storageClassName: alicloud-disk-ssd
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: busybox
      name: busybox
      namespace: default
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: busybox
      template:
        metadata:
          labels:
            app: busybox
        spec:
          containers:
            - name: busybox
              image: registry.cn-hangzhou.aliyuncs.com/acs/busybox:v1.29.2
              command:
              - tail
              - -f
              - /dev/null
              volumeMounts:
                - mountPath: "/data"
                  name: disk-pvc
          dnsPolicy: ClusterFirst
          restartPolicy: Always
          runtimeClassName: runv
          volumes:
            - name: disk-pvc
              persistentVolumeClaim:
                claimName: disk-pvc-01
    EOF
  2. 执行以下命令进入Pod内验证挂载点文件系统类型。
    kubectl get pods
    kubectl exec -it ${podid} sh
    mount | grep /data | grep -vi 9p
    如果类型不是9PFS,说明成功实现云盘直挂沙箱功能。

Host、CSI-Plugin云盘直挂沙箱、9PFS的IO性能对比

  • 随机读IOPS

    云盘挂载方式 结果
    Host read: IOPS=2571, BW=10.0MiB/s (10.5MB/s)(604MiB/60094msec)
    CSI-Plugin云盘直挂沙箱 read: IOPS=2571, BW=10.0MiB/s (10.5MB/s)(603MiB/60006msec)
    9PFS read: IOPS=2558, BW=9.99MiB/s (10.5MB/s)(600MiB/60001msec)
  • 随机写IOPS

    云盘挂载方式 结果
    Host write: IOPS=2481, BW=9926KiB/s (10.2MB/s)(582MiB/60011msec)
    CSI-Plugin云盘直挂沙箱 write: IOPS=2481, BW=9926KiB/s (10.2MB/s)(582MiB/60005msec)
    9PFS write: IOPS=1280, BW=5123KiB/s (5246kB/s)(300MiB/60001msec)
  • 随机读吞吐

    云盘挂载方式 结果
    Host read: IOPS=133, BW=133MiB/s (140MB/s)(8110MiB/60926msec)
    CSI-Plugin云盘直挂沙箱 read: IOPS=133, BW=133MiB/s (140MB/s)(8052MiB/60514msec)
    9PFS read: IOPS=10, BW=10.0MiB/s (10.5MB/s)(603MiB/60079msec)
  • 随机写吞吐

    云盘挂载方式 结果
    Host write: IOPS=130, BW=130MiB/s (137MB/s)(7854MiB/60251msec)
    CSI-Plugin云盘直挂沙箱 write: IOPS=130, BW=131MiB/s (137MB/s)(7907MiB/60370msec)
    9PFS write: IOPS=5, BW=5123KiB/s (5246kB/s)(301MiB/60159msec)
注意 为了提高9PFS IO性能,安全沙箱默认开启了qemu cache功能。以上数据是关闭qemu cache后的测试结果。

从以上数据看出,不论是IO吞吐还是IOPS,CSI-Plugin云盘直挂沙箱和Host模式(在Host上直接挂载云盘)几乎持平。CSI-Plugin云盘直挂沙箱和9PFS的随机读IOPS相近,但其他场景IO性能是有明显优势的。