Под заканчивается с ошибкой FailedMount из PVC от Azure Blob Storage в Microk8s

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

Я сейчас изучаю Kubernetes и осваиваю его, настраивая кластер Microk8s на тестовых машинах, которые у меня есть. Я хотел бы быть облачно-независимым с вычислительными ресурсами в кластере, поэтому у меня есть простые тестовые ВМ или что-то, что не связано ни с одним облачным провайдером. Тем не менее, для простоты я решил использовать облачные сервисы только для хранения, так как hostpath был отличным для тестирования, но я понял, что его не следует использовать в производственной среде, поэтому я пробую что-то более реальное.

В качестве старта я выбрал Azure Blob Storage дляProvision storage в моем тестовом кластере. Я использовал blob-csi-driver, чтобы подключиться к Azure Blob Storage и настроить для него класс хранения. Я успешно создал PVC и получил статус “Bound”. Однако, когда я пытаюсь использовать этот PVC в поде, он не удается с следующими ошибками в событиях пода: причина FailedMount с сообщением об ошибке MountVolume.MountDevice failed for volume [...] timeout waiting for mount и directory is already mounted.

Я не понимаю, как директория могла быть уже смонтирована, так как я использую свежий кластер Microk8s каждый раз, когда я тестирую это, и PVC создается и связывается успешно именно для этого пода, который я пытаюсь создать.

Есть ли что-то, что я упускаю в настройке, которую я сделал?

Ниже приведены все шаги, которые я предпринял, чтобы настроить кластер, CSI драйвер, класс хранения, PVC и под для справки и воспроизводимости:

  1. Настройка кластера Microk8s:
# - Отключить своп и файрвол
# - Установить Microk8s
sudo snap install microk8s --classic
# - Между тестами сбросить Microk8s
sudo microk8s reset
# - Включить базовые дополнения
sudo microk8s enable dns
sudo microk8s enable ingress
# - Настроить разрешения пользователя для доступа к Microk8s и Kubectl и т. д.
  1. Настройка CSI драйвера для Azure Blob Storage:
# - Убедиться, что мастер-узел имеет необходимую метку 'control-plane'
# В Microk8s, мастер-узел, вероятно, не имеет этой конкретной метки
kubectl get nodes --selector="node-role.kubernetes.io/control-plane"
kubectl label node my-vm-hostname node-role.kubernetes.io/control-plane=""
# - Установить blob-csi-driver
# Создать для развертывания на управляющей плоскости с 1 репликой (в настоящее время только один узел в кластере для тестирования этого)
helm upgrade --install \
    blob-csi-driver \
    blob-csi-driver \
    --repo https://raw.githubusercontent.com/kubernetes-sigs/blob-csi-driver/master/charts \
    --namespace blob-csi-driver \
    --create-namespace \
    --version v1.25.0 \
    --set node.enableBlobfuseProxy='true' \
    --set controller.replicas="1" \
    --set controller.runOnControlPlane="true"
# - Посмотреть созданные ресурсы и дождаться их готовности
kubectl get -n blob-csi-driver all

Созданные ресурсы, как и ожидалось:

NAME                                       READY   STATUS    RESTARTS   AGE
pod/csi-blob-controller-5d589dbc77-qvqln   4/4     Running   0          42s
pod/csi-blob-node-6t6g7                    4/4     Running   0          42s

NAME                           DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
daemonset.apps/csi-blob-node   1         1         1       1            1           kubernetes.io/os=linux   42s

NAME                                  READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/csi-blob-controller   1/1     1            1           42s

NAME                                             DESIRED   CURRENT   READY   AGE
replicaset.apps/csi-blob-controller-5d589dbc77   1         1         1       42s
  1. Создание класса хранения для Azure Blob Storage:
# - Создать пространство имен для конфигурации класса хранения
kubectl create namespace blob-storage-class
kubectl config set-context --current --namespace=blob-storage-class
# - Создать секрет для учетной записи Azure Blob Storage
kubectl create secret generic azure-secret \
    --type=Opaque \
    --from-literal azurestorageaccountname="azurestorageaccountname" \
    --from-literal azurestorageaccountkey='azurestorageaccountkey'
# - Создать класс хранения (без пространств имен)
# Рассмотреть класс хранения как дефолтный для его использования в PVC
kubectl apply -f - <<EOF
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: blob-storage-class
  annotations:
    "storageclass.kubernetes.io/is-default-class": "true"
provisioner: blob.csi.azure.com
allowVolumeExpansion: true
volumeBindingMode: Immediate # WaitForFirstConsumer
parameters:
  csi.storage.k8s.io/provisioner-secret-name: azure-secret
  csi.storage.k8s.io/provisioner-secret-namespace: blob-storage-class
  csi.storage.k8s.io/node-stage-secret-name: azure-secret
  csi.storage.k8s.io/node-stage-secret-namespace: blob-storage-class
EOF
# - Посмотреть созданные ресурсы
kubectl get all,secret,sc

Созданные ресурсы, как и ожидалось:

NAME                  TYPE     DATA   AGE
secret/azure-secret   Opaque   2      42s

NAME                                                       PROVISIONER          RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
storageclass.storage.k8s.io/blob-storage-class (default)   blob.csi.azure.com   Delete          Immediate           true                   42s
  1. Создание тестового приложения с PVC, использующим класс хранения.

Сначала создадим PVC:

# - Создать пространство имен для тестового приложения
kubectl create namespace test-app
kubectl config set-context --current --namespace=test-app
# - Создать PVC, используя класс хранения
kubectl apply -f - <<EOF
---
# Запрос на постоянный объем
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: test-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
EOF
# - Посмотреть созданный PVC
kubectl get all,pvc

Все работает нормально до сих пор. PVC создан и успешно связан:

NAME                             STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS         VOLUMEATTRIBUTESCLASS   AGE
persistentvolumeclaim/test-pvc   Bound    pvc-3c6c062d-9194-40ad-980c-c5677234205e   1Gi        RWO            blob-storage-class   <unset>                 42s

Также хранилище успешно создано и отображается в портале Azure, названном в честь PVC.

Затем создадим остальную часть тестового приложения, используя PVC:

# Все еще в пространстве имен 'test-app'
# - Создать развертывание, сервис и ingress
kubectl apply -f - <<EOF
---
# Развертывание
apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-deployment
  labels:
    app: test-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: test-deployment
  template:
    metadata:
      labels:
        app: test-deployment
    spec:
      containers:
        - image: nginx
          name: nginx
          ports:
            - containerPort: 80
          volumeMounts:
            - name: test-volume
              mountPath: /usr/share/nginx/html
      volumes:
        - name: test-volume
          persistentVolumeClaim:
            claimName: test-pvc
---
# Сервис
apiVersion: v1
kind: Service
metadata:
  name: test-deployment
spec:
  selector:
    app: test-deployment
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
---
# Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-ingress
spec:
  rules:
    - host: test-app.localhost
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: test-deployment
                port:
                  number: 80
EOF
# - Посмотреть созданные ресурсы
kubectl get all,ingress,pvc

Под застрял в состоянии ContainerCreating:

NAME                                   READY   STATUS              RESTARTS   AGE
pod/test-deployment-65c7b4c555-sxzd6   0/1     ContainerCreating   0          42s

NAME                      TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
service/test-deployment   ClusterIP   10.152.183.148   <none>        80/TCP    42s

NAME                              READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/test-deployment   0/1     1            0           42s

NAME                                         DESIRED   CURRENT   READY   AGE
replicaset.apps/test-deployment-65c7b4c555   1         1         0       42s

NAME                             STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS         VOLUMEATTRIBUTESCLASS   AGE
persistentvolumeclaim/test-pvc   Bound    pvc-3c6c062d-9194-40ad-980c-c5677234205e   1Gi        RWO            blob-storage-class   <unset>                 69s

NAME                                     CLASS    HOSTS                ADDRESS     PORTS     AGE
ingress.networking.k8s.io/test-ingress   public   test-app.localhost   127.0.0.1   80, 443   42s

Под терпит неудачу с следующими событиями (переформатировано для удобства чтения):

kubectl describe -n test-app pod test-deployment-65c7b4c555-sxzd6
События:
  Тип       Причина       Возраст             От       Сообщение
  ----      ------       ----                ----     -------

  Normal   Запланировано 2м17с               default-scheduler
  Успешно назначен test-app/test-deployment-65c7b4c555-sxzd6 на my-vm-hostname

  Предупреждение  Неудача монтирования 76с                kubelet
  MountVolume.MountDevice failed for volume "pvc-3c6c062d-9194-40ad-980c-c5677234205e" : rpc error:
  code = Unknown desc = failed to wait for mount: timeout waiting for mount
  /var/snap/microk8s/common/var/lib/kubelet/plugins/kubernetes.io/csi/blob.csi.azure.com/[hash]/globalmount

  Предупреждение  Неудача монтирования 11с (x7 на 75с)  kubelet
  MountVolume.MountDevice failed for volume "pvc-3c6c062d-9194-40ad-980c-c5677234205e" : rpc error:
  code = Internal desc = Mount failed with error: rpc error:
  code = Unknown desc = exit status 1 Error: directory is already mounted
  , output:
  Пожалуйста, обратитесь к http://aka.ms/blobmounterror для возможных причин и решений для ошибок монтирования.

Конечно, тестирование ingress не работает, так как под не работает.

curl -H "Host: test-app.localhost" http://localhost
<html>
<head><title>503 Сервис временно недоступен</title></head>
<body>
<center><h1>503 Сервис временно недоступен</h1></center>
<hr><center>nginx</center>
</body>
</html>

И, спустя некоторое время, под все еще застрял в состоянии ContainerCreating, с той же ошибкой в событиях:

kubectl describe -n test-app pod test-deployment-65c7b4c555-sxzd6

Под терпит неудачу с следующими событиями (переформатировано для удобства чтения):

```bash
kubectl describe -n test-app pod test-deployment-65c7b4c555-sxzd6
События:
  Тип       Причина       Возраст             От     Сообщение
  ----      ------       ----                ----     -------

  Предупреждение  Неудача монтирования 2м (x16 на 20м)  kubelet
  MountVolume.MountDevice failed for volume "pvc-3c6c062d-9194-40ad-980c-c5677234205e" : rpc error:
  code = Internal desc = Mount failed with error: rpc error:
  code = Unknown desc = exit status 1 Error: directory is already mounted
  , output:
  Пожалуйста, обратитесь к http://aka.ms/blobmounterror для возможных причин и решений для ошибок монтирования.

Я не уверен, что я упускаю здесь. Я не понимаю ошибку или что могло бы ее вызвать. Я пытался повторить настройку несколько раз и на двух разных машинах с разными ОС, но возникает одна и та же проблема.

Буду очень признателен за любую помощь или направление, так как мне действительно хотелось бы понять и извлечь уроки из этого.

Любой альтернативный (лучший?) подход, который я мог бы предпринять, также будет приветствоваться.

Заранее спасибо!

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

Причины ошибки FailedMount на PVC из Azure Blob Storage в Microk8s и их решение

Кстати, хорошие новости! Вы уже на верном пути, создавая кластер Microk8s и тестируя его с использованием Azure Blob Storage для более реалистичной конфигурации хранения. Давайте подробно разберем возникшую проблему с ошибкой FailedMount.

Понимание проблемы

В вашем случае, под не может успешно смонтировать Persistent Volume Claim (PVC) из-за ошибок, связанных с монтированием. Наиболее распространенные ошибки, которые вы упомянули:

  • MountVolume.MountDevice failed for volume [...] timeout waiting for mount
  • directory is already mounted

Эти ошибки указывают на несколько потенциальных проблем, включая неправильную конфигурацию или конфликты ресурсов. Особенно сообщения о том, что «каталог уже смонтирован», могут указывать на то, что при создании PVC или пода произошел конфликт.

Потенциальные причины и рекомендации

  1. Конфликты в монтировании:

    • Проверка существующих монтирований: Возможно, что ваш PVC уже используется в другом поде или монтировании. Используйте команду kubectl get pods --all-namespaces для проверки статуса всех подов, чтобы удостовериться, что PVC не используется.
    • Сброс ресурсов: Если у вас есть возможность, полностью очистите кластер Microk8s с помощью sudo microk8s.reset, а затем попробуйте заново создать PVC и связанные с ним ресурсы.
  2. Неправильная конфигурация CSI драйвера:

    • Убедитесь, что все зависимости CSI драйвера правильно установлены. Вы использовали команду Helm для установки, но стоит проверить логи, чтобы удостовериться, что драйвер работает корректно.
    • Используйте команду kubectl logs -n blob-csi-driver <имя-pod>, чтобы просмотреть логи подов CSI драйвера. Ошибки могут подсказать, где проблема.
  3. Проблемы с сетевым взаимодействием:

    • Если ваш кластер Microk8s работает в окружении с ограничениями сети или брандмауэром, это может повлиять на возможность подключения к Azure Blob Storage.
  4. Параметры конфигурации хранения:

    • Проверьте параметры, указанные в классе хранения и секрете. Убедитесь, что все данные (имя хранилища, ключи и т.д.) правильные. Иногда небольшие ошибки в конфигурации могут привести к столь же многим ошибкам.
  5. Границы ресурсов:

    • Изучите, нет ли у вашего кластера ограничений на ресурсы. Конфликтующие лимиты могут вызывать проблемы при монтировании.
  6. Доменные имена и маршрутизация:

    • Также убедитесь, что ваша конфигурация Ingress корректна, особенно если вы используете локальный хост и виртуальные хосты.

Альтернативные подходы

Если проблема не решается, вы можете рассмотреть следующие альтернативные подходы:

  • Использование Local Path: Если ваша цель — локальное развертывание для тестирования, возможно, имеет смысл рассмотреть использование локального пути хранения (Local Path Storage). Это уменьшит зависимость от облачного провайдера.
  • Другие облачные решения: Вы также можете рассмотреть использование других облачных хранилищ или специфичных для Kubernetes решений, таких как Azure Files, которые могут предложить более надежный способ управления хранилищем.

Заключение

Проблемы с монтированием PVC в вашем Microk8s кластере могут быть связаны с несколькими моментами — от конфликта ресурсов до ошибок в настройках. Проанализируйте этапы, которые мы обсудили, и попробуйте решить проблему шаг за шагом. Если у вас будут возникать дополнительные вопросы в процессе, не стесняйтесь обращаться за поддержкой. Удачи вам в дальнейшем изучении Kubernetes!

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

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