Данные Hyperledger Indy не монтируются в каталог томов Kubernetes

Я пытаюсь запустить инди-узлы в кубернетах. Эти indy-узлы являются узлами песочницы и записывают данные в/var/lib/indyкаталог внутри контейнера. Когда я запускаю модуль с смонтированным томом, он ничего не записывает в каталог тома. Хотя он создает каталог внутри тома, он все время пуст. Однако, когда я создаю модуль без опции монтирования тома, контейнер записывает данные внутри/var/lib/indy.

Ниже приведен файл Dockerfile:
Hastebin: https://hastebin.com/hitinefizi.nginx.

Развертывание Kubernetes:

{{- $root := .}}
{{- range .Values.indy}}
---
apiVersion: apps/v1
kind: Deployment
metadata:
  # namespace: {{$root.Values.namespace}}
  name: {{.name}}
spec:
  selector:
    matchLabels:
      name: {{.name}}
  replicas: 1
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        name: {{.name}}
    spec:
      containers:
        - name: {{.name}}
          image: {{.image}}
          volumeMounts:
            - name: {{$root.Values.pv.metadata.name}}
              mountPath: "/var/lib/indy/sandbox"
              subPath: "volume/indy/{{.name}}/sandbox"
          ports:
            - containerPort: {{ index .ports 0 }}
            - containerPort: {{ index .ports 1 }}
      nodeSelector:
        nodeType: {{$root.Values.hosts.blockchain}}
      volumes:
        - name: {{$root.Values.pv.metadata.name}}
          {{- if eq $root.Values.storage.type "nfs" }}
          persistentVolumeClaim:
            claimName: {{$root.Values.pvc.metadata.name}}
          {{- else }}
          hostPath:
            path: /var/kubeshare/
          {{- end }}
{{- end}}

Каталог внутри тома:

[root@centos1 kubeshare]# tree volume/indy/
volume/indy/
|-- indy-node1
|-- indy-node2
|-- indy-node3
`-- indy-node

Каталог /var/lib/indy внутри контейнера без объема:

root@indy-node1-587c4758bf-2hpp6:/var/lib/indy# tree -L 3
.
|-- plugins
`-- sandbox
    |-- data
    |   `-- Node1
    |-- domain_transactions_genesis
    |-- keys
    |   |-- Node1
    |   |-- Node1C
    |   |-- Node2
    |   |-- Node3
    |   `-- Node4
    |-- node1_additional_info.json
    |-- node1_info.json
    |-- node1_version_info.json
    `-- pool_transactions_genesis

Я не уверен, почему это происходит. Любая помощь / предложения будут оценены.

Обновление: то же самое происходит с docker-compose, когда я пытаюсь использовать локальный том.

1 ответ

Монтирование в докере соответствует стандартному поведению монтирования в Linux. Linuxmountкомандные документы говорят

The previous contents (if any) and owner and mode of dir become invisible, and as long as this filesystem remains mounted

Так же и в Docker. Если вы монтируете локальный каталог или существующий именованный том докера, содержимое файловой системы в контейнере в месте монтирования будет затенено (или мы можем назвать это "переопределением").

Упрощенный пример происходящего

Имея dockerfile

FROM alpine:3.9.6

WORKDIR /home/root/greetings
RUN echo "hello world" > /home/root/greetings/english.txt
CMD sleep 60000

И построить это docker build -t greetings:1.0 .

Теперь создайте следующее docker-compose.yml:

version: '3.7'

services:
  greetings:
    container_name: greetings
    image: greetings:1.0
    volumes:
      - ./empty:/home/root/greetings

и создайте пустой каталог empty рядом с ним.

Начни это docker-compose up -d. Пока контейнер работает, давайте перейдем к нему и посмотрим, как выглядит файловая структура внутри.docker exec -ti greetings sh. Теперь, когда мы внутри, если ты бежишьls /home/root/greetings вы увидите, что каталог пуст - хотя в Dockerfile мы запекли файл /home/root/greetings/english.txt в файловую систему изображения.

Именованные контейнеры докеров ведут себя более желательно, если именованные контейнеры докеров являются новыми и не содержат никаких данных. Если вы смонтируете такой контейнер в том месте, где уже есть некоторые данные, именованный том скопирует эти данные на него.

Вы можете попробовать это, настроив docker-compose.yml к этому

version: '3.7'

services:
  greetings:
    container_name: greetings
    image: greetings:1.0
    volumes:
      - greetingsvol:/home/root/greetings

volumes:
  greetingsvol:
    driver: local

и если вы повторите процедуру и запустите себя в контейнер, вы увидите этот файл /home/root/greetings/english.txt все еще там.

Это потому, что когда ты cd себя в /home/root/greetings, вы смотрите не на фактическую файловую систему контейнера, а на смонтированное устройство - имя docker volume - которое было инициализировано копией исходных файлов контейнера в этом заданном месте. (Предполагая, что объем докераgreetingsvol ранее не существовало.)

Решение вашей проблемы

Вы монтируете каталог /var/kubeshare на вашем хосте в контейнер /var/lib/indy/sandbox. Давайте посмотрим, что контейнер хранит в этом месте при запуске (indypool так я назвал созданный образ инди-песочницы на моем локальном хосте)

docker run --rm indypool ls /var/lib/indy/sandbox
domain_transactions_genesis
keys
pool_transactions_genesis

Итак, если вы смонтируете локальный каталог на /var/lib/indy/sandbox, он затеняет эти файлы, и пул не запустится (и, следовательно, не будет создавать такие файлы, как node1_additional_info.json так далее).

Итак, я думаю, у вас есть 2 варианта:

  1. Если у вас нет веской причины не делать этого, используйте именованные тома докеров.
  2. Скопируйте исходные данные изображения из контейнера /var/lib/indy/sandbox в ваш /var/kubeshare. Затем оставьте все остальное, как было. Таким образом, каталог будет затенен новой файловой системой, содержащей точно такие же данные, которые контейнер ожидает там найти.
Другие вопросы по тегам