Объединение локальных SSD для узла в Кубернетес

Данные, требуемые моим контейнером, слишком велики для размещения на одном локальном SSD. Мне также нужно получить доступ к SSD как к одной файловой системе из моего контейнера. Поэтому мне нужно было бы прикрепить несколько. Как мне объединить их и сделать так, чтобы они отображались как одна файловая система в моем контейнере? По этой ссылке рассказывается, как подключить SSD https://cloud.google.com/kubernetes-engine/docs/how-to/persistent-volumes/local-ssd к пути подключения. Я не уверен, как вы бы объединить несколько.

3 ответа

ПРЕДУПРЕЖДЕНИЕ, это экспериментальный вариант, он не предназначен для использования в производственной среде без знания того, что вы делаете, и протестирован только на gke версии 1.16.x.

Подход включает daemonset используя configmap использовать nsenter(с уловками ожидания) для пространства имен хоста и привилегированного доступа, чтобы вы могли управлять устройствами. В частности, для локальных SSD-дисков GKE мы можем размонтировать эти устройства, а затем выполнить raid0 на них. InitContainer за грязную работу, поскольку этот тип задач кажется наиболее очевидным для того, что вам нужно пометить как выполненное, а затем закрыть привилегированный доступ к контейнеру (или даже к поду). Вот как это делается.

В этом примере предполагается 16 SSD, однако вы захотите настроить жестко заданные значения по мере необходимости. Также убедитесь, что ваш образ ОС требует, я использую Ubuntu. Также убедитесь, что используемая вами версия GKE запускает local-ssd с sd [b]

ConfigMap

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

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

Для высокопроизводительных сценариев использования используйте функцию GKE эфемерного хранилища на локальных твердотельных накопителях . Все локальные SSD будут настроены как (полосатый) массив raid0 и смонтированы в модуле.

Краткое резюме:

  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

Вы можете использовать yaml- файл DaemonSet для развертывания модуля, который будет запускаться при запуске, при условии, что уже создан кластер с 2 локальными SSD (этот модуль будет отвечать за создание диска 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

Модуль, который будет иметь доступ к массиву дисков в приведенном выше примере, называется "/ 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

После развертывания тестового модуля подключите SSH к нему из облачной оболочки или любого другого экземпляра.

Затем запустите:

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

После этого вы сможете увидеть созданный файл на диске ssd-array.

cat test-file.txt
Другие вопросы по тегам