使用 SMB CSI 驱动程序访问 Windows Server 节点上的 SMB 卷


本页面举例说明如何使用开源的 SMB CSI Driver for Kubernetes 访问具有 Windows 服务器节点的 Google Kubernetes Engine (GKE) 集群上的 NetApp Cloud Volumes Service SMB 卷。

概览

服务器消息块 (SMB) 协议是用于 Microsoft Windows 的网络文件共享协议。如需通过 Windows Server 节点池将 SMB 与 GKE 集群搭配使用,您可以使用开源的 SMB CSI Driver for Kubernetes

任务

以下各部分逐步演示了如何访问具有 Windows 服务器节点的 GKE 集群上的 NetApp Cloud Volumes Service SMB 卷。该示例使用了开源的 SMB CSI Driver for Kubernetes

部署 Active Directory

此任务会创建一个 Active Directory。如果您已有可用的 Active Directory,则可以跳过此任务。

如需部署自行管理的 Active Directory,以下说明使用 Google Cloud Marketplace 解决方案创建一个新的 Active Directory 域,其中包含两个 Active Directory 域控制器。

  1. 在 Google Cloud 控制台中,转到 Microsoft Active Directory Cloud Marketplace 页面。
  2. 点击启动
  3. 完成部署配置。确保 DNS 服务器与 NetApp Cloud Volumes 服务 SMB 卷位于同一区域。查看区域可用性
  4. 点击部署

要改为使用 Managed Service for Microsoft Active Directory (Managed Microsoft AD),请完成以下步骤:

  1. 创建托管式 Microsoft AD 域
  2. 在网域和 NetApp Cloud Volumes Service 网络之间配置网域对等互连
  3. 如需执行与 Active Directory 相关的任务,请连接到网域

创建专用 DNS 转发可用区

创建一个专用 DNS 转发区域以将 DNS 查询转发到 Active Directory 域控制器

更新防火墙规则

如需允许来自 Cloud DNS 的查询到达您的 AD 连接,请在 AD 的防火墙规则中添加 35.199.192.0/19 作为来源过滤条件的来源 IP 地址范围。

如需了解详情,请参阅 Cloud Volumes Service 的 SMB 访问权限的安全注意事项

创建与 Cloud Volumes Service 的 Active Directory 连接

如需查看相关说明,请参阅创建 AD 连接

在 Cloud Volumes Service 中创建 SMB 卷

如需查看相关说明,请参阅创建 SMB 卷

将新的 SMB 卷的装载目标用作 PersistentVolumeStorageClass 中的 source 值,并按以下格式指定:

"//SMB_SERVER_NAME/SHARE_NAME"

您可以在 Cloud Volumes Service 卷列表页面和各个卷详情页面上找到装载目标和说明。

创建一个节点已加入 AD 域的集群

执行配置 Windows Server 节点以自动加入 Active Directory 域中的说明。

安装 SMB CSI 驱动程序

  1. 安装开源的 SMB CSI Driver for Kubernetes
  2. 如需从 Pod 访问 SMB 卷,请创建一个对用户名和密码进行编码的 Secret

    kubectl create secret generic SECRET_NAME \
        --from-literal username="USERNAME" \
        --from-literal password="PASSWORD"
    

    替换以下内容:

    • SECRET_NAME:您的 Secret 的名称。
    • USERNAME:用户名。在 Secret 中编码的用户名应包含域名,并采用以下格式:domain\$username。如果您的 SMB 共享不属于任何网域,则网域可以是任何字符串。
    • PASSWORD:用户的密码。

访问 SMB 卷

如需访问 SMB 卷,您可以选择使用以下任何一项:

使用 StorageClass 访问 SMB 卷

如需通过 StorageClass 访问 SMB 卷,请执行以下任务:

  1. 创建 StorageClass 网址。以下是一个名称 sc-smb.yaml 的示例清单文件:

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: smb
    provisioner: smb.csi.k8s.io
    parameters:
      source: "//SMB_SERVER_NAME/SHARE_NAME"
      csi.storage.k8s.io/node-stage-secret-name: "SECRET_NAME"
      csi.storage.k8s.io/node-stage-secret-namespace: "default"
      createSubDir: "false"    # optional: create a sub dir for new volume
    reclaimPolicy: Retain      # only Retain is supported
    volumeBindingMode: Immediate
    mountOptions:
      - dir_mode=0777
      - file_mode=0777
      - uid=1001
      - gid=1001
    

    在本示例中,我们使用 mountOptions 字段,它是 Windows Server 的可选字段,但请使此 StorageClass 同时为 Linux 和 Windows Server 服务。

    替换以下内容:

    • SMB_SERVER_NAME:SMB 服务器的主机名,包括网域。例如,装载路径 //adserver-faab.cvssmb.com/eager-hungry-skossi 的主机名为 adserver-faab.cvssmb.com
    • SHARE_NAME:SMB 共享的名称。例如,装载路径 //adserver-faab.cvssmb.com/eager-hungry-skossi 的共享名称为 eager-hungry-skossi。仅将 SMB 共享用于 SMB 共享。如需了解详情,请参阅相关的已知问题
    • SECRET_NAME:Secret 的名称,其中包含用于访问 SMB 卷的凭据。
  2. 根据清单文件创建 StorageClass 资源:

    kubectl create -f sc-smb.yaml
    
  3. 部署使用 StorageClass 的 Pod。以下是一个名称 statefulset-smb.yaml 的示例清单文件:为该 StatefulSet 部署的 Pod 会在装载的 SMB 驱动器中创建一个 data.txt 文件:

    apiVersion: v1
    kind: Service
    metadata:
      name: busybox
      labels:
        app: busybox
    spec:
      ports:
      - port: 80
        name: web
      clusterIP: None
      selector:
        app: busybox
    ---
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: statefulset-smb
      labels:
        app: busybox
    spec:
      serviceName: statefulset-smb
      replicas: 1
      template:
        metadata:
          labels:
            app: busybox
        spec:
          nodeSelector:
            "kubernetes.io/os": windows
          containers:
            - name: statefulset-smb
              image: e2eteam/busybox:1.29
              command:
                - "powershell.exe"
                - "-Command"
                - "while (1) { Add-Content -Encoding Ascii C:\\sc\\smb\\data.txt $(Get-Date -Format u); sleep 1 }"
              volumeMounts:
                - name: smb
                  mountPath: "/sc/smb"
          tolerations:
            - key: "node.kubernetes.io/os"
              operator: "Exists"
              effect: "NoSchedule"
      updateStrategy:
        type: RollingUpdate
      selector:
        matchLabels:
          app: busybox
      volumeClaimTemplates:
        - metadata:
            name: smb
            annotations:
              volume.beta.kubernetes.io/storage-class: smb
          spec:
            accessModes: ["ReadWriteMany"]
            resources:
              requests:
                storage: 10Gi
    
  4. 根据清单文件创建 StatefulSet 资源:

    kubectl create -f statefulset-smb.yaml
    

使用 PersistentVolume 和 PersistentVolumeClaim 访问卷

如需通过 PersistentVolumePersistentVolumeClaim 访问 SMB 卷,请执行以下任务:

  1. 创建 PersistentVolume 网址。以下是一个名称 pv-smb.yaml 的示例清单文件:

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: pv-smb
    spec:
      capacity:
        storage: 100Gi
      accessModes:
        - ReadWriteMany
      persistentVolumeReclaimPolicy: Retain
      mountOptions:
        - dir_mode=0777
        - file_mode=0777
        - vers=3.0
      csi:
        driver: smb.csi.k8s.io
        readOnly: false
        volumeHandle: VOLUME_ID
        volumeAttributes:
          source: "//SMB_SERVER_NAME/SHARE_NAME"
        nodeStageSecretRef:
          name: SECRET_NAME
          namespace: default
    

    在本示例中,我们使用 mountOptions 字段,它是 Windows Server 的可选字段,但请使此 PersistentVolume 同时为 Linux 和 Windows Server 服务。

    替换以下内容:

    • VOLUME_ID:卷的唯一 ID。
    • SMB_SERVER_NAME:SMB 服务器的主机名,包括网域。
    • SHARE_NAME:SMB 共享的名称。
    • SECRET_NAME:包含用于访问 SMB 卷的凭据的 Secret 的名称。
  2. 根据清单文件创建 PersistentVolume 资源:

    kubectl create -f pv-smb.yaml
    
  3. 创建 PersistentVolumeClaim 网址。以下是一个名称 pvc-smb.yaml 的示例清单文件:

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: pvc-smb
    spec:
      accessModes:
        - ReadWriteMany
      resources:
        requests:
          storage: 10Gi
      volumeName: pv-smb
      storageClassName: ""
    
  4. 根据清单文件创建 PersistentVolumeClaim 资源:

    kubectl create -f pvc-smb.yaml
    
  5. 部署使用 PersistentVolumeClaim 的 Pod。以下是使用 pvc-smb 的 Pod 部署名为 busybox-smb.yaml 的示例清单文件。此部署会在已装载的 SMB 驱动器中创建一个 data.txt 文件:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: busybox-smb
      labels:
        app: busybox
    spec:
      replicas: 1
      template:
        metadata:
          name: busybox
          labels:
            app: busybox
        spec:
          nodeSelector:
            "kubernetes.io/os": windows
          containers:
            - name: busybox
              image: e2eteam/busybox:1.29
              command:
                - "powershell.exe"
                - "-Command"
                - "while (1) { Add-Content -Encoding Ascii C:\\pv\\pv-smb\\data.txt $(Get-Date -Format u); sleep 1 }"
              volumeMounts:
                - name: smb
                  mountPath: "/pv/pv-smb"
          tolerations:
            - key: "node.kubernetes.io/os"
              operator: "Exists"
              effect: "NoSchedule"
          volumes:
            - name: smb
              persistentVolumeClaim:
                claimName: pvc-smb
      selector:
        matchLabels:
          app: busybox
    
  6. 从清单文件创建 Deployment

    kubectl apply -f  busybox-smb.yaml
    

测试对 SMB 卷的访问权限

如需验证您是否可以访问 SMB 卷上的 data.txt 文件,请执行以下一项任务:

  • 在容器中启动 Powershell 会话并列出 data.txt 文件:

    kubectl exec POD_NAME -- powershell.exe -c "ls PATH_TO_THE_FILE"
    
  • 在另一个虚拟机中打开 SMB 云端硬盘,以确认已在远程共享中成功创建 data.txt 文件。

已知问题

重新启动后在 Windows 上装载错误

问题:例如,如果 \\smb-server\share\test1 已装载,在 Windows 节点重新启动后装载卷 \\smb-server\share\test2 时可能会遇到错误。

原因StorageClassPersistentVolumesource 字段应仅在一个集群中使用一个 SMB 服务器使用根共享。另外,您应该在部署中使用 volumeMounts.subPath 属性。

解决方法:仅使用 \\smb-server\share 作为 source

如需了解已知问题,请参阅适用于 Kubernetes 的开源 SMB CSI 驱动程序的已知问题页面。

后续步骤