Как каждому поду в StatefulSet вручную назначить конкретный PVC?

Вопрос или проблема

Итак, я пытаюсь настроить, чтобы каждому поду в StatefulSet вручную назначалась определенная PVC без использования volumeClaimTemplates.

Я использую patch для каждого пода и StatefulSet, но это не работает.

Так что вот мой код из pvc.yaml файла:

        apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: busybox-pvc-0
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi
    ---
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: busybox-pvc-1
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi
    ---
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: busybox-pvc-2
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi

и вот мой код из statefullset.yaml:

        apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: busybox
    spec:
      serviceName: "busybox-service"
      replicas: 3
      selector:
        matchLabels:
          app: busybox
      template:
        metadata:
          labels:
            app: busybox
        spec:
          containers:
          - name: busybox
            image: busybox
            command: ["/bin/sh", "-c", "sleep 3600"]
            volumeMounts:
            - name: busybox-storage
              mountPath: /mnt/data
          volumes:
          - name: busybox-storage
            persistentVolumeClaim:
              claimName: busybox-pvc-0

и я пытаюсь использовать “patch” вот так, но получаю ошибку такого типа:

        dev_2@Tadhak-dev-02:~/Backup/Opensearch/Stateful_PVC$ minikube kubectl -- patch pod busybox-0 --type="json" -p '[{"op": "replace", "path": "/
    spec/volumes/0/persistentVolumeClaim/claimName", "value": "busybox-pvc-0"}]'
    The request is invalid: the server rejected our request due to an error in our request
    dev_2@Tadhak-dev-02:~/Backup/Opensearch/Stateful_PVC$ minikube kubectl -- patch pod busybox-1 --type="json" -p '[{"op": "replace", "path": "/spec/volumes/0/persistentVolumeClaim/claimName", "value": "busybox-pvc-1"}]'
    The Pod "busybox-1" is invalid: spec: Forbidden: pod updates may not change fields other than `spec.containers[*].image`,`spec.initContainers[*].image`,`spec.activeDeadlineSeconds`,`spec.tolerations` (only additions to existing tolerations),`spec.terminationGracePeriodSeconds` (allow it to be set to 1 if it was previously negative)
        core.PodSpec{
            Volumes: []core.Volume{
                {
                    Name: "busybox-storage",
                    VolumeSource: core.VolumeSource{
                        ... // 7 identical fields
                        ISCSI:     nil,
                        Glusterfs: nil,
                        PersistentVolumeClaim: &core.PersistentVolumeClaimVolumeSource{
    -                   ClaimName: "busybox-pvc-0",
    +                   ClaimName: "busybox-pvc-1",
                            ReadOnly:  false,
                        },
                        RBD:     nil,
                        Quobyte: nil,
                        ... // 18 identical fields
                    },
                },
                {Name: "kube-api-access-jzfbk", VolumeSource: {Projected: &{Sources: {{ServiceAccountToken: &{ExpirationSeconds: 3607, Path: "token"}}, {ConfigMap: &{LocalObjectReference: {Name: "kube-root-ca.crt"}, Items: {{Key: "ca.crt", Path: "ca.crt"}}}}, {DownwardAPI: &{Items: {{Path: "namespace", FieldRef: &{APIVersion: "v1", FieldPath: "metadata.namespace"}}}}}}, DefaultMode: &420}}},
            },
            InitContainers: nil,
            Containers:     {{Name: "busybox", Image: "busybox", Command: {"/bin/sh", "-c", "sleep 3600"}, VolumeMounts: {{Name: "busybox-storage", MountPath: "/mnt/data"}, {Name: "kube-api-access-jzfbk", ReadOnly: true, MountPath: "/var/run/secrets/kubernetes.io/serviceaccount"}}, ...}},
            ... // 30 identical fields
        }

Итак, как сделать, чтобы это работало, чтобы каждому поду в StatefulSet вручную назначалась определенная PVC без использования volumeClaimTemplates.

busybox-0 → busybox-pvc-0 ,
busybox-1 → busybox-pvc-1 ,
busybox-2 → busybox-pvc-2 ,

Ответ или решение

Вопрос о том, как правильно настроить составные элементы Kubernetes, такие как StatefulSet, подчеркивает важность понимания работы с постоянными хранилищами (PVC) при развертывании приложений, требующих сохранения состояния. В данном случае, требуется вручную назначить каждое хранилище (PVC) для конкретного пода в StatefulSet без использования шаблонов volumeClaimTemplates. Это особенно важно в ситуациях, где доступность данных имеет критическое значение.

Теория

Kubernetes предлагает StatefulSet как специализированный контроллер, который обеспечивает уникальные идентификаторы для каждого пода, гарантируя, что он восстанавливается в определенном порядке. Это делает его идеальным выбором для приложений, требующих сохранения состояния, таких как базы данных или распределенные системы.

Обычно, когда мы говорим о привязке PVC к подам в StatefulSet, используется volumeClaimTemplates, которые автоматически создают PVC для каждого пода с уникальным именем. Однако, если требуется индивидуальная привязка уже существующих PVC к подам, необходимо использовать подходы, обходящиеся без авто-создания PVC.

Пример

Обратимся к YAML-конфигурации, предоставленной в вопросе. Начнем с того, что создано несколько PVC, которые можно использовать для каждого пода:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: busybox-pvc-0
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: busybox-pvc-1
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: busybox-pvc-2
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

Эти PVC соотносятся с подами, которые будут развернуты в рамках StatefulSet:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: busybox
spec:
  serviceName: "busybox-service"
  replicas: 3
  selector:
    matchLabels:
      app: busybox
  template:
    metadata:
      labels:
        app: busybox
    spec:
      containers:
      - name: busybox
        image: busybox
        command: ["/bin/sh", "-c", "sleep 3600"]
        volumeMounts:
        - name: busybox-storage
          mountPath: /mnt/data
      volumes:
      - name: busybox-storage
        persistentVolumeClaim:
          claimName: busybox-pvc-0

Применение

В вашей текущей конфигурации все поды будут пытаться использовать busybox-pvc-0, что приводит к конфликту, так как PVC с ReadWriteOnce не могут быть смонтированы несколькими подами одновременно. Чтобы решить эту проблему и правильно привязать уникальные PVC к каждому поду, вам нужно вручную создать StatefulSet с индивидуализированной конфигурацией для каждого пода. Можно использовать аннотации или labels для различения подов, чтобы каждый из них ссылался на свой уникальный PVC.

Обновите StatefulSet, как показано ниже:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: busybox
spec:
  serviceName: "busybox-service"
  replicas: 3
  selector:
    matchLabels:
      app: busybox
  template:
    metadata:
      labels:
        app: busybox
    spec:
      containers:
      - name: busybox
        image: busybox
        command: ["/bin/sh", "-c", "sleep 3600"]
        volumeMounts:
        - name: busybox-storage
          mountPath: /mnt/data
        volumeMounts:
        - name: pvc-identifier
          mountPath: /mnt/data
      initContainers:
      - name: init
        image: busybox
        command:
        - sh
        - -c
        - |
          case $(hostname -s) in
            busybox-0)
              ln -s /mnt/data/busybox-pvc-0 /mnt/data ;;
            busybox-1)
              ln -s /mnt/data/busybox-pvc-1 /mnt/data ;;
            busybox-2)
              ln -s /mnt/data/busybox-pvc-2 /mnt/data ;;
          esac

Данные изменения используют initContainers, чтобы привязывать поды к конкретным PVC, основываясь на имени хоста. Тем самым каждый под будет иметь доступ к правильному PVC.

Таким образом, важным моментом здесь является использование initContainers для обеспечения правильной конфигурации подов с необходимыми PVC при развертывании StatefulSet в Kubernetes.

Оцените материал
Добавить комментарий

Капча загружается...