Neo4j кластеры на Кубернетес
В этом посте предполагается, что мы знакомы с развертыванием Neo4j на Kubernetes. Я написал статью в блоге Neo4j, объясняя это более подробно .
Набор StatefulSet, который мы создаем для наших основных серверов, требует постоянного хранилища , что достигается с помощью примитива PersistentVolumeClaim (PVC). Кластер Neo4j, содержащий 3 основных сервера, будет иметь следующие PVC:
|
1
2
3
4
5
|
$ kubectl get pvcNAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGEdatadir-neo-helm-neo4j-core-0 Bound pvc-043efa91-cc54-11e7-bfa5-080027ab9eac 10Gi RWO standard 45sdatadir-neo-helm-neo4j-core-1 Bound pvc-1737755a-cc54-11e7-bfa5-080027ab9eac 10Gi RWO standard 13sdatadir-neo-helm-neo4j-core-2 Bound pvc-18696bfd-cc54-11e7-bfa5-080027ab9eac 10Gi RWO standard 11s |
Каждый из PVC имеет соответствующий PersistentVolume (PV), который его удовлетворяет:
|
1
2
3
4
5
|
$ kubectl get pvNAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGEpvc-043efa91-cc54-11e7-bfa5-080027ab9eac 10Gi RWO Delete Bound default/datadir-neo-helm-neo4j-core-0 standard 41mpvc-1737755a-cc54-11e7-bfa5-080027ab9eac 10Gi RWO Delete Bound default/datadir-neo-helm-neo4j-core-1 standard 40mpvc-18696bfd-cc54-11e7-bfa5-080027ab9eac 10Gi RWO Delete Bound default/datadir-neo-helm-neo4j-core-2 standard 40m |
PVC и PV обычно создаются одновременно с развертыванием нашего StatefulSet. Нам нужно вмешаться в этот жизненный цикл, чтобы наш набор данных уже был готов до развертывания StatefulSet.
Развертывание существующего набора данных
Мы можем сделать это, выполнив следующие действия:
- Создайте PVC с указанными выше именами вручную
- Прикрепите стручки к этим ПВХ
- Скопируйте наш набор данных на эти стручки
- Удалить стручки
- Разверните наш кластер Neo4j
Мы можем использовать следующий скрипт для создания PVCs и pods:
pvs.sh
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
#!/usr/bin/env bash set -exuo pipefail for i in $(seq 0 2); do cat <<EOF | kubectl apply -f -kind: PersistentVolumeClaimapiVersion: v1metadata: name: datadir-neo-helm-neo4j-core-${i} labels: app: neo4jspec: accessModes: - ReadWriteOnce resources: requests: storage: 10GiEOF cat <<EOF | kubectl apply -f -kind: PodapiVersion: v1metadata: name: neo4j-load-data-${i} labels: app: neo4j-loaderspec: volumes: - name: datadir-neo4j-core-${i} persistentVolumeClaim: claimName: datadir-neo-helm-neo4j-core-${i} containers: - name: neo4j-load-data-${i} image: ubuntu volumeMounts: - name: datadir-neo4j-core-${i} mountPath: /data command: ["/bin/bash", "-ecx", "while :; do printf '.'; sleep 5 ; done"]EOF done; |
Давайте запустим этот скрипт для создания наших PVCs и модулей:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
$ ./pvs.sh ++ seq 0 2+ for i in $(seq 0 2)+ cat+ kubectl apply -f -persistentvolumeclaim "datadir-neo-helm-neo4j-core-0" configured+ cat+ kubectl apply -f -pod "neo4j-load-data-0" configured+ for i in $(seq 0 2)+ cat+ kubectl apply -f -persistentvolumeclaim "datadir-neo-helm-neo4j-core-1" configured+ cat+ kubectl apply -f -pod "neo4j-load-data-1" configured+ for i in $(seq 0 2)+ cat+ kubectl apply -f -persistentvolumeclaim "datadir-neo-helm-neo4j-core-2" configured+ cat+ kubectl apply -f -pod "neo4j-load-data-2" configured |
Теперь мы можем скопировать нашу базу данных на модули:
|
1
2
3
4
|
for i in $(seq 0 2); do kubectl cp graph.db.tar.gz neo4j-load-data-${i}:/data/ kubectl exec neo4j-load-data-${i} -- bash -c "mkdir -p /data/databases && tar -xf /data/graph.db.tar.gz -C /data/databases"done |
graph.db.tar.gz содержит резервную копию из локальной базы данных, которую я создал:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
|
$ tar -tvf graph.db.tar.gz drwxr-xr-x 0 markneedham staff 0 24 Jul 15:23 graph.db/drwxr-xr-x 0 markneedham staff 0 24 Jul 15:23 graph.db/certificates/drwxr-xr-x 0 markneedham staff 0 17 Feb 2017 graph.db/index/drwxr-xr-x 0 markneedham staff 0 24 Jul 15:22 graph.db/logs/-rw-r--r-- 0 markneedham staff 8192 24 Jul 15:23 graph.db/neostore-rw-r--r-- 0 markneedham staff 896 24 Jul 15:23 graph.db/neostore.counts.db.a-rw-r--r-- 0 markneedham staff 1344 24 Jul 15:23 graph.db/neostore.counts.db.b-rw-r--r-- 0 markneedham staff 9 24 Jul 15:23 graph.db/neostore.id-rw-r--r-- 0 markneedham staff 65536 24 Jul 15:23 graph.db/neostore.labelscanstore.db...-rw------- 0 markneedham staff 1700 24 Jul 15:23 graph.db/certificates/neo4j.key |
Мы выполним следующую команду, чтобы проверить наличие баз:
|
01
02
03
04
05
06
07
08
09
10
11
|
$ kubectl exec neo4j-load-data-0 -- ls -lh /data/databases/total 4.0Kdrwxr-xr-x 6 501 staff 4.0K Jul 24 14:23 graph.db $ kubectl exec neo4j-load-data-1 -- ls -lh /data/databases/total 4.0Kdrwxr-xr-x 6 501 staff 4.0K Jul 24 14:23 graph.db $ kubectl exec neo4j-load-data-2 -- ls -lh /data/databases/total 4.0Kdrwxr-xr-x 6 501 staff 4.0K Jul 24 14:23 graph.db |
Пока все хорошо. Стручки сделали свою работу, поэтому мы их снесем:
|
1
2
3
4
|
$ kubectl delete pods -l app=neo4j-loaderpod "neo4j-load-data-0" deletedpod "neo4j-load-data-1" deletedpod "neo4j-load-data-2" deleted |
Теперь мы готовы развернуть наш кластер Neo4j.
|
1
|
helm install incubator/neo4j --name neo-helm --wait --set authEnabled=false |
Наконец, мы выполним запрос Cypher, чтобы проверить, что серверы Neo4j использовали загруженную нами базу данных:
|
01
02
03
04
05
06
07
08
09
10
11
|
$ kubectl exec neo-helm-neo4j-core-0 -- bin/cypher-shell "match (n) return count(*)"count(*)32314 $ kubectl exec neo-helm-neo4j-core-1 -- bin/cypher-shell "match (n) return count(*)"count(*)32314 $ kubectl exec neo-helm-neo4j-core-2 -- bin/cypher-shell "match (n) return count(*)"count(*)32314 |
Успех!
Мы могли бы достичь аналогичных результатов, используя контейнер init, но у меня еще не было возможности опробовать этот подход. Если вы попробуете, дайте мне знать в комментариях, и я добавлю это в пост.
| Опубликовано на Java Code Geeks с разрешения Марка Нидхэма, партнера нашей программы JCG . См. Оригинальную статью здесь: Kubernetes: скопируйте набор данных в PersistentVolume StatefulSet
Мнения, высказанные участниками Java Code Geeks, являются их собственными. |