在安全沙箱容器中挂载NAS

传统存储方案访问路径层级多、延迟高,会造成一定的I/O性能损耗。安全沙箱NAS直接挂载可以通过优化存储路径实现在容器内直接读写NAS,从而有效提升性能。本文介绍安全沙箱NAS直接挂载的实现原理,以及如何将NAS直接挂载到安全沙箱容器中。

背景信息

virtio-fs是一个共享的文件系统,可以将Volume、Secret、ConfigMap等共享到虚拟机GuestOS内,从而以原生的方式通过Volume挂载NAS。但这种方式下,NAS是挂载到主机上的,在容器内要经过virtio-fs读写主机上的NAS,由此会带来一些性能损耗。

安全容器提供了安全沙箱NAS直接挂载的功能。该功能会先卸载主机上的NAS挂载点,然后在GuestOS内挂载NAS,最后把NAS Bind Mount到容器内,从而能够在容器内直接读写NAS,达到接近原生的性能。

image

实现原理

image

实现安全沙箱的NAS直接挂载功能的流程如下:

  1. kubelet请求CSI-Plugin挂载NAS卷。

  2. CSI-Plugin在主机挂载NAS。

  3. kubelet请求Kangaroo-Runtime创建容器。

  4. Kangaroo-Runtime解析NAS挂载信息并传入GuestOS,同时卸载主机上的NAS。

  5. Kangaroo-Runtime请求Agent创建容器。

  6. AgentNAS挂载到GuestOS内。

  7. AgentGuestOS上的NAS Bind Mount到容器内。

前提条件

操作步骤

  1. 创建静态PV。

    1. 将以下示例YAML内容保存为nas-pv-csi.yaml文件。

      apiVersion: v1
      kind: PersistentVolume
      metadata:
        labels:
          alicloud-pvname: nas-pv-csi
        name: nas-pv-csi
      spec:
        accessModes:
          - ReadWriteMany
        capacity:
          storage: 5Gi
        csi:
          driver: nasplugin.csi.alibabacloud.com
          volumeAttributes:
            options: noresvport,nolock
            path: /csi
            server: ${nas-server-address}  #填写为您实际获取的NAS挂载点地址。
            vers: "3"
          volumeHandle: nas-pv-csi
        persistentVolumeReclaimPolicy: Retain
    2. 执行以下命令创建静态PV。

      kubectl create -f nas-pv-csi.yaml
  2. 创建NAS存储声明PVC,使用selector.matchLabels筛选PV标签,精确配置PVCPV的绑定关系。

    1. 将以下示例YAML内容保存为nas-pvc-csi.yaml文件。

      apiVersion: v1
      kind: PersistentVolumeClaim
      metadata:
        name: nas-pvc-csi
        namespace: default
      spec:
        accessModes:
          - ReadWriteMany
        resources:
          requests:
            storage: 5Gi
        selector:
          matchLabels:
            alicloud-pvname: nas-pv-csi
    2. 执行以下命令创建静态PVC。

      kubectl create -f nas-pvc-csi.yaml
  3. 创建示例应用,并挂载PVC。

    1. 将以下示例YAML内容保存为deploy-nas-csi.yaml文件。

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: deploy-nas-csi
      spec:
        replicas: 2
        selector:
          matchLabels:
            app: busybox
        template:
          metadata:
            labels:
              app: busybox
            annotations:
              storage.alibabacloud.com/enable_nas_passthrough: "true"
          spec:
            runtimeClassName: runv
            containers:
              - name: busybox
                image: registry.cn-hangzhou.aliyuncs.com/acs/busybox:v1.29.2
                command: 
                - tail
                - -f
                - /dev/null
                volumeMounts:
                  - name: nas-pvc
                    mountPath: "/data"
            restartPolicy: Always
            volumes:
              - name: nas-pvc
                persistentVolumeClaim:
                  claimName: nas-pvc-csi    #需要和上一步创建的PVC名称一致,用于绑定PVC。

      默认Pod不启用NAS直接挂载功能,您需要在模板中添加Annotation开启NAS直通功能。

      annotations:
        storage.alibabacloud.com/enable_nas_passthrough: "true"
    2. 执行以下命令创建应用。

      kubectl create -f deploy-nas-csi.yaml
  4. 验证NAS挂载结果。

    1. 执行以下命令,查看Pod信息。

      kubectl get pods

      预期输出:

      NAME                              READY   STATUS    RESTARTS   AGE
      deploy-nas-csi-847f8b****-qmv2m   1/1     Running   0          47s
      deploy-nas-csi-847f8b****-wj8k5   1/1     Running   0          47s
    2. 执行以下命令,进入指定的Pod。

      kubectl exec -it deploy-nas-csi-847f8b****-qmv2m -- sh
    3. 执行以下命令,查看挂载信息。

      mount 

      如果执行命令后有内容,表明NAS已经挂载成功。预期输出如下:

      预期输出

      kataShared on / type virtio_fs (rw,nodev,relatime,user_id=0,group_id=0,default_permissions,allow_other,dax=inode)
      proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
      tmpfs on /dev type tmpfs (rw,nosuid,size=65536k,mode=755)
      devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=666)
      mqueue on /dev/mqueue type mqueue (rw,nosuid,nodev,noexec,relatime)
      sysfs on /sys type sysfs (ro,nosuid,nodev,noexec,relatime)
      tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,relatime)
      cgroup on /sys/fs/cgroup/perf_event type cgroup (ro,nosuid,nodev,noexec,relatime,perf_event)
      cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (ro,nosuid,nodev,noexec,relatime,cpu,cpuacct)
      cgroup on /sys/fs/cgroup/blkio type cgroup (ro,nosuid,nodev,noexec,relatime,blkio)
      cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (ro,nosuid,nodev,noexec,relatime,net_cls,net_prio)
      cgroup on /sys/fs/cgroup/memory type cgroup (ro,nosuid,nodev,noexec,relatime,memory)
      cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,name=systemd)
      cgroup on /sys/fs/cgroup/freezer type cgroup (ro,nosuid,nodev,noexec,relatime,freezer)
      cgroup on /sys/fs/cgroup/devices type cgroup (ro,nosuid,nodev,noexec,relatime,devices)
      cgroup on /sys/fs/cgroup/cpuset type cgroup (ro,nosuid,nodev,noexec,relatime,cpuset)
      cgroup on /sys/fs/cgroup/pids type cgroup (ro,nosuid,nodev,noexec,relatime,pids)
      cgroup on /sys/fs/cgroup/hugetlb type cgroup (ro,nosuid,nodev,noexec,relatime,hugetlb)
      kataShared on /data type virtio_fs (rw,nodev,relatime,user_id=0,group_id=0,default_permissions,allow_other,dax=inode)
      kataShared on /etc/hosts type virtio_fs (rw,nodev,relatime,user_id=0,group_id=0,default_permissions,allow_other,dax=inode)   
      kataShared on /dev/termination-log type virtio_fs (rw,nodev,relatime,user_id=0,group_id=0,default_permissions,allow_other,dax=inode)
      kataShared on /etc/hostname type virtio_fs (rw,nodev,relatime,user_id=0,group_id=0,default_permissions,allow_other,dax=inode)
      kataShared on /etc/resolv.conf type virtio_fs (rw,nodev,relatime,user_id=0,group_id=0,default_permissions,allow_other,dax=inode)
      shm on /dev/shm type tmpfs (rw,nosuid,nodev,noexec,relatime,size=64000k)
      kataShared on /var/run/secrets/kubernetes.io/serviceaccount type virtio_fs (ro,relatime,user_id=0,group_id=0,default_permissions,allow_other,dax=inode)
      tmpfs on /proc/kcore type tmpfs (rw,nosuid,size=65536k,mode=755)
      tmpfs on /proc/keys type tmpfs (rw,nosuid,size=65536k,mode=755)
      tmpfs on /proc/timer_list type tmpfs (rw,nosuid,size=65536k,mode=755)
      tmpfs on /proc/sched_debug type tmpfs (rw,nosuid,size=65536k,mode=755)
      proc on /proc/bus type proc (ro,relatime)
      proc on /proc/fs type proc (ro,relatime)
      proc on /proc/irq type proc (ro,relatime)
      proc on /proc/sys type proc (ro,relatime)
      proc on /proc/sysrq-trigger type proc (ro,relatime)