はじめに
Kubernetes公式ドキュメントのExample: Deploying Cassandra with Stateful Setsを実行しました。
NFSストレージはPersistentVolume(PV)で確保しているため、StorageClass(SC)を利用する例がそのままでは実行が難しかったのでPVを利用するように書き換えたので要点をまとめました。
このPersistentVolumeは過去にまとめたKubernetesでNFSを利用してPersistentStorageを準備するに従って準備しています。
NFSを前提としてSCを確保する方法をまとめている方もいましたが、そちらは試していません。
環境について
Kubernetesクラスターは、Kubesprayを利用して、Xeon E3を積んだサーバー機4台で構成し、各ノードに24GBのメモリを積んでいます。
公式手順との違いについて
SCではなくPVを利用している他に、以下の点で異なっています。
Namespaceの変更
Namespaceはdefaultではなく、cassandraを使っています。
$ kubectl create ns cassandra
そのためkubectlコマンドを実行する際には、常に*-n cassandra*を付けています。
$ alias kubectl='kubectl -n cassandra'
このためkube-dnsによるホスト名の参照の際に、cassandra-0.cassandra.cassandra.svc.cluster.localのようなFQDNを利用しています。
公式YAMLからの書き換え
cassandra-service.yamlについては変更ありません。
statefulsetを構成する前に、Volumeの準備をします。
PersistenteVolumeClaim (PVC)の構成
事前に構成するレプリカの数だけPVCを準備する必要があるため、簡単なスクリプトでYAMLを出力し、構成します。
#!/bin/bash
i=0
while test "$i" -lt "$1" ; do sed -e "s/_NUM_/$i/" << EOF ; i=$(($i+1)) ; done
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: cassandra-data-cassandra-_NUM_
labels:
app: cassandra
annotations:
"volume.beta.kubernetes.io/storage-class": "slow"
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5G
EOF
次のようなコマンドラインで、4つ分のPVCを確保しておきます。
$ bash gen-pvc-yaml.sh 4 | kubectl apply -f -
persistentvolumeclaim/cassandra-data-cassandra-0 created
persistentvolumeclaim/cassandra-data-cassandra-1 created
persistentvolumeclaim/cassandra-data-cassandra-2 created
persistentvolumeclaim/cassandra-data-cassandra-3 created
volumeClaimTemplatesで指定する名前は、volumeMountsで指定するname(cassandra-data)と、ホスト名(cassandra-#)をハイフン'-'で繋げた文字列になっています。
StatefulSetを実行する
全体は長いので公式のcassandra-statefulset.yamlからの差分を表示します。
- Namespaceをdefaultからcassandraに変更しているので、ホスト名はその部分だけ変更しています。
- NFSなPVは”slow"を設定しているので、そのannotationsを追記しています。
- SCを使わない構成のため、ファイル末のSC関連の設定を全て削っています。
$ diff -u 03.cassandra-satefulset.yaml.orig 03.cassandra-satefulset.yaml
--- 03.cassandra-satefulset.yaml.orig 2018-10-16 00:41:48.633461617 +0900
+++ 03.cassandra-satefulset.yaml 2018-10-17 09:44:17.237267987 +0900
@@ -53,7 +53,7 @@
- name: HEAP_NEWSIZE
value: 100M
- name: CASSANDRA_SEEDS
- value: "cassandra-0.cassandra.default.svc.cluster.local"
+ value: "cassandra-0.cassandra.cassandra.svc.cluster.local"
- name: CASSANDRA_CLUSTER_NAME
value: "K8Demo"
- name: CASSANDRA_DC
@@ -84,17 +84,10 @@
volumeClaimTemplates:
- metadata:
name: cassandra-data
+ annotations:
+ "volume.beta.kubernetes.io/storage-class": "slow"
spec:
accessModes: [ "ReadWriteOnce" ]
- storageClassName: fast
resources:
requests:
storage: 1Gi
----
-kind: StorageClass
-apiVersion: storage.k8s.io/v1
-metadata:
- name: fast
-provisioner: k8s.io/minikube-hostpath
-parameters:
- type: pd-ssd
このファイルを$ kubectl apply -f
の引数に与えてしばらくするとクラスターが起動します。
稼動確認
Exampleに記載のあるように、nodetoolでステータスを確認することができます。
$ kubectl exec -it cassandra-0 -- nodetool status
Datacenter: DC1-K8Demo
======================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
-- Address Load Tokens Owns (effective) Host ID Rack
UN 10.233.106.89 70.95 KiB 32 75.9% f6117ffa-2984-4489-ab00-105a3385eb9b Rack1-K8Demo
UN 10.233.108.57 104.55 KiB 32 66.0% d2eb0880-fde8-460f-80b1-675c8393268b Rack1-K8Demo
UN 10.233.76.103 84.81 KiB 32 58.1% 4a672f4f-8364-445e-bce9-b3c5e1a181c6 Rack1-K8Demo
ここから使っていくために
Serviceの再定義
実際に外部からの接続を受け付けるためにはServiceの定義を変更する必要があります。
ClusterIP: Noneを設定している状態から、LoadBalancerに変更することはできないため、一度サービスを削除するか、replace --forceオプションによって削除・設定を同時に行なうかの方法で構成を行ないます。
既にMetalLBでLoadBalancerを有効にしているため、次のような新しいYAMLファイルを準備しました。
apiVersion: v1
kind: Service
metadata:
labels:
app: cassandra
name: cassandra
spec:
ports:
- port: 9042
selector:
app: cassandra
type: LoadBalancer
これを次のような手順で適用しました。
$ kubectl delete svc cassandra
$ kubectl apply -f cassandra-service-withLB.yaml
これでServiceをチェックすると、接続用のExternal IPが確認できます。
$ kubectl get svc cassandra
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
cassandra LoadBalancer 10.233.15.78 192.168.10.183 9042:30610/TCP 9h
cqlshコマンドでの接続
kubernetes環境にデプロイしたCassandraのコンテナイメージにはcqlshは含まれていないようなので、別のDockerを有効にしているデスクトップ機から接続してみます。
DockerHubに登録されているlibrary/cassandraを使用して、このドキュメントを参考にしています。
$ sudo docker pull cassandra
Using default tag: latest
latest: Pulling from library/cassandra
f17d81b4b692: Pull complete
...
Digest: sha256:ea7777cd83ebe0e2d38db8eb07dc76f206fd9ce6b6dd48ee9a1bc303b9757a02
Status: Downloaded newer image for cassandra:latest
$ sudo docker run -it --rm cassandra sh -c 'exec cqlsh 192.168.10.183'
Connected to K8Demo at 192.168.10.183:9042.
[cqlsh 5.0.1 | Cassandra 3.11.2 | CQL spec 3.4.4 | Native protocol v4]
Use HELP for help.
cqlsh> CREATE KEYSPACE mykeyspace WITH REPLICATION = { 'class': 'SimpleStrategy', 'replication_factor' : 2 };
cqlsh> DESCRIBE keyspaces;
system_schema system system_distributed
system_auth mykeyspace system_traces
cqlsh>
実際にはMakefileを準備して、makeコマンドで各ターゲットを実行しています。
以上