【问题标题】:Combining multiple Local-SSD on a node in Kubernetes (GKE)在 Kubernetes (GKE) 的一个节点上组合多个 Local-SSD
【发布时间】:2019-02-18 16:47:19
【问题描述】:

我的容器所需的数据太大,一个本地 SSD 无法容纳。我还需要从我的容器中访问 SSD 作为一个文件系统。所以我需要附加多个。如何组合它们(单个分区、RAID0 等)并使它们作为容器中的一个卷挂载可访问?

此链接分享如何将 SSD https://cloud.google.com/kubernetes-engine/docs/how-to/persistent-volumes/local-ssd 挂载到挂载路径。我不确定你将如何合并多个。

编辑

问题询问如何在 GKE 的单个节点上“组合”多个单独安装的 SSD 设备。

【问题讨论】:

  • 请阅读how to ask 页面,因为除非您准备接受“是”作为答案,否则这是一个可怕的问题
  • 请说明您遵循什么程序?您的计划到底是什么?或者您是否收到任何错误消息?提供更多信息可以帮助我们查明问题,然后社区可以为您提供最佳答案。
  • 很抱歉。编辑了描述。希望对您有所帮助。

标签: kubernetes google-kubernetes-engine


【解决方案1】:

警告 这是实验性的,不适合生产使用 知道您在做什么,并且仅在 gke 1.16.x 版本上进行了测试。

该方法包括使用configmap 使用nsenter(带有等待技巧)的daemonset 用于主机命名空间和特权访问,以便您可以管理设备。特别是对于 GKE Local SSD,我们可以卸载这些设备,然后对其进行 raid0。 InitContainer 用于肮脏的工作,因为这种类型的任务似乎最明显的是您需要标记完成,然后杀死特权容器访问(甚至 Pod)。这是它的完成方式。

该示例假设有 16 个 SSD,但是,您需要根据需要调整硬编码值。另外,请确保您的操作系统映像要求,我使用 Ubuntu。还要确保您使用的 GKE 版本在 sd[b]

处启动 local-ssd

配置映射

apiVersion: v1
kind: ConfigMap
metadata:
  name: local-ssds-setup
  namespace: search
data:
    setup.sh: |
        #!/bin/bash
        # returns exit codes: 0 = found, 1 = not found
        isMounted() { findmnt -rno SOURCE,TARGET "$1" >/dev/null;} #path or device

        # existing disks & mounts
        SSDS=(/dev/sdb /dev/sdc /dev/sdd /dev/sde /dev/sdf /dev/sdg /dev/sdh /dev/sdi /dev/sdj /dev/sdk /dev/sdl /dev/sdm /dev/sdn /dev/sdo /dev/sdp /dev/sdq)

        # install mdadm utility
        apt-get -y update && apt-get -y install mdadm --no-install-recommends
        apt-get autoremove

        # OPTIONAL: determine what to do with existing, I wipe it here
        if [ -b "/dev/md0" ]
            then
            echo "raid array already created"

            if isMounted "/dev/md0"; then
                echo "already mounted - unmounting"
                umount /dev/md0 &> /dev/null || echo "soft error - assumed device was mounted"
            fi

            mdadm --stop /dev/md0
            mdadm --zero-superblock "${SSDS[@]}"                
        fi

        # unmount disks from host filesystem
        for i in {0..15}
        do 
            umount "${SSDS[i]}" &> /dev/null || echo "${SSDS[i]} already unmounted"
        done

        if isMounted "/dev/sdb";
            then 
            echo ""
            echo "unmount failure - prevent raid0" 1>&2
            exit 1
        fi

        # raid0 array
        yes | mdadm --create /dev/md0 --force --level=0 --raid-devices=16 "${SSDS[@]}"

        echo "raid array created"

        # format 
        mkfs.ext4 -F /dev/md0

        # mount, change /mnt/ssd-array to whatever
        mkdir -p /mnt/ssd-array
        mount /dev/md0 /mnt/ssd-array
        chmod a+w /mnt/ssd-array

    wait.sh: |
        #!/bin/bash
        while sudo fuser /var/{lib/{dpkg,apt/lists},cache/apt/archives}/lock >/dev/null 2>&1; do sleep 1; done

DeamonSet pod 规范

spec:
      hostPID: true
      nodeSelector:
        cloud.google.com/gke-local-ssd: "true"
      volumes:
      - name: setup-script
        configMap:
          name: local-ssds-setup
      - name: host-mount
        hostPath:
          path: /tmp/setup
      initContainers:
      - name: local-ssds-init
        image: marketplace.gcr.io/google/ubuntu1804
        securityContext:
          privileged: true
        volumeMounts:
        - name: setup-script
          mountPath: /tmp
        - name: host-mount
          mountPath: /host
        command:
          - /bin/bash
          - -c
          - |
            set -e
            set -x

            # Copy setup script to the host
            cp /tmp/setup.sh /host

            # Copy wait script to the host 
            cp /tmp/wait.sh /host

            # Wait for updates to complete
            /usr/bin/nsenter -m/proc/1/ns/mnt -- chmod u+x /tmp/setup/wait.sh

            # Give execute priv to script
            /usr/bin/nsenter -m/proc/1/ns/mnt -- chmod u+x /tmp/setup/setup.sh

            # Wait for Node updates to complete
            /usr/bin/nsenter -m/proc/1/ns/mnt /tmp/setup/wait.sh

            # If the /tmp folder is mounted on the host then it can run the script
            /usr/bin/nsenter -m/proc/1/ns/mnt /tmp/setup/setup.sh
      containers:
      - image: "gcr.io/google-containers/pause:2.0"
        name: pause

【讨论】:

    【解决方案2】:

    对于高性能用例,请使用Ephemeral storage on local SSDs GKE 功能。所有本地 SSD 都将配置为(条带化)raid0 阵列并安装到 pod 中。

    快速总结:

    1. 使用以下选项创建节点池或集群:--ephemeral-storage local-ssd-count=X
    2. 使用 cloud.google.com/gke-ephemeral-storage-local-ssd 调度到节点。
    3. 添加 emptyDir 卷。
    4. 使用 volumeMounts 安装它。

    这是我如何将它与 DaemonSet 一起使用的:

    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name: myapp
      labels:
        app: myapp
    spec:
      selector:
        matchLabels:
          app: myapp
      template:
        metadata:
          labels:
            app: myapp
        spec:
          nodeSelector:
            cloud.google.com/gke-ephemeral-storage-local-ssd: "true"
          volumes:
          - name: localssd
            emptyDir: {}
          containers:
            - name: myapp
              image: <IMAGE>
              volumeMounts:
                - mountPath: /scratch
                  name: localssd
    

    【讨论】:

    • 今天,也就是 2022 年,这也是我的首选方法
    【解决方案3】:

    您可以使用DaemonSet yaml 文件来部署 pod 将在启动时运行,假设已经创建了一个具有 2 个本地 SSD 的集群(这个 pod 将负责创建 Raid0 磁盘)

    kind: DaemonSet
    apiVersion: extensions/v1beta1
    metadata:
      name: ssd-startup-script
      labels:
        app: ssd-startup-script
    spec:
      template:
        metadata:
          labels:
            app: ssd-startup-script
       spec:
         hostPID: true
         containers:
         - name: ssd-startup-script
        image: gcr.io/google-containers/startup-script:v1
        imagePullPolicy: Always
        securityContext:
          privileged: true
        env:
        - name: STARTUP_SCRIPT
          value: |
            #!/bin/bash
            sudo curl -s https://get.docker.com/ | sh
            echo Done
    

    上例中可以访问磁盘阵列的 pod 是“/mnt/disks/ssd-array”

    apiVersion: v1
    kind: Pod
    metadata:
     name: test-pod
    spec:
     containers:
    - name: test-container
      image: ubuntu
      volumeMounts:
      - mountPath: /mnt/disks/ssd-array
       name: ssd-array
      args:
      - sleep
      - "1000"
    nodeSelector:
     cloud.google.com/gke-local-ssd: "true"
    tolerations:
    - key: "local-ssd"
     operator: "Exists"
     effect: "NoSchedule"
    volumes:
    - name: ssd-array
      hostPath:
       path: /mnt/disks/ssd-array
    

    部署 test-pod 后,从您的 cloud-shell 或任何实例通过 SSH 连接到该 pod。

    然后运行:

      kubectl exec -it test-pod -- /bin/bash
    

    之后你应该可以在 ssd-array 磁盘中看到创建的文件了。

    cat test-file.txt
    

    【讨论】:

    • 所以基本上启动脚本将包含我提供的链接中的脚本对吗?
    • 实际上,我在提供的链接中找不到包含脚本的启动脚本。但是你可以为每个你想要的本地 SSD 增加 ssd# 作为 RAID 阵列的一部分。
    • 你在哪里创建数组?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 1970-01-01
    • 2016-04-12
    • 1970-01-01
    相关资源
    最近更新 更多