概要
bitnami の redis helm chart を使ってみました
いくつかのデプロイ方式があるのでそれぞれ試しています
環境
- kubernetes 1.20.4
- helm 3.5.2
- bitnami redis helm chart 14.0.1
事前準備
何でもいいので pv を用意しましょう
local を使う方法はこちら
default の storageClass を用意しても OK です
nfs で default の storageClass を作成する方法はこちら
リポジトリインストール
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
初期デプロイ
helm install test bitnami/redis
これで secret もデプロイされるのでこのパスワードを使って redis の構成を変更していきます
パスワードは環境変数に設定しておきます
export REDIS_PASSWORD=$(kubectl get secret --namespace default test-redis -o jsonpath="{.data.redis-password}" | base64 --decode)
Master-Slave 構成をデプロイする
まずは Master-Slave 構成を試してみます
アクセスするのは NodePort を使います
helm upgrade test bitnami/redis --set master.service.type=NodePort --set master.service.nodePort=30700 --set replica.service.type=NodePort --set replica.service.nodePort=30800 --set auth.password=$REDIS_PASSWORD
Master へのアクセスは 30700 ポートを使い Slave へのアクセスは 30800 を使います
デプロイした起動しているか確認しましょう
Master が 1 つ Slave が 3 つ起動していれば OK です
kubectl get pod
NAME READY STATUS RESTARTS AGE
nfs-subdir-external-provisioner-78cc5b4979-tnnnj 1/1 Running 0 19d
test-redis-master-0 1/1 Running 0 97s
test-redis-replicas-0 1/1 Running 0 7s
test-redis-replicas-1 1/1 Running 0 48s
test-redis-replicas-2 1/1 Running 0 68s
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 19d
test-redis-headless ClusterIP None <none> 6379/TCP 6m45s
test-redis-master NodePort 10.97.246.247 <none> 6379:30700/TCP 6m45s
test-redis-replicas NodePort 10.105.78.89 <none> 6379:30800/TCP 6m45s
動作確認
redis-cli を使って動作確認してみましょう
まずは Master にアクセスしてみます
ちゃんと Wirte できることが確認できます
export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")
redis-cli -h $NODE_IP -p 30700 -a $REDIS_PASSWORD
NODE_IP:30700> set name hawksnowlog
OK
次に Slave にアクセスします
redis-cli -h $NODE_IP -p 30800 -a $REDIS_PASSWORD
Slave では Write できないのが確認できます
また Master で set した値がちゃんと参照できるのが確認できます
NODE_IP:30800> set age 10
(error) READONLY You can't write against a read only replica.
NODE_IP:30800> get name
"hawksnowlog"
failover を試してみる
基本は failover せず StatefullSet によって Pod が復帰してくる感じになります
kubectl delete pod test-redis-master-0
で Master を削除すると再度上がってきます
再起動中は Master にアクセスできなくなります
Sentinel 構成をデプロイしてみる
次に Sentinel 構成をデプロイしてみます
helm install test-sentinel bitnami/redis --set auth.password=$REDIS_PASSWORD --set sentinel.enabled=true --set sentinel.service.type=NodePort --set sentinel.service.nodePorts.redis=30700 --set sentinel.service.nodePorts.sentinel=30800
Redis へのアクセスは 30700 ポートを使い Sentinel へのアクセスは 30800 を使います
Sentinel への書き込みや読み込みはできないので基本的には 30700 番を使うことになります
動作確認
export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")
redis-cli -h $NODE_IP -p 30700 -a $REDIS_PASSWORD
で書き込みと読み込むができることを確認しましょう
また Sentinel では get/set ができないことも確認します
# redis-cli -h $NODE_IP -p 30700 -a $REDIS_PASSWORD
NODE_IP:30700> set name hawksnowlog
OK
NODE_IP:30700> exit
# redis-cli -h $NODE_IP -p 30800 -a $REDIS_PASSWORD
NODE_IP:30800> get name
(error) ERR unknown command `get`, with args beginning with: `name`,
また注意点として Redis の構成は Master-Slave 構成になっています
何度か繰り返すとわかりますが 30700 番にアクセスして set するとできるときとできないときがあるのがわかると思います
これは NodePort 経由で Redis クラスタにアクセスした際にアクセスする Pod はバランシングされているためそうなります
本来であれば常に Master にアクセスしたり常に Slave にアクセスすることになると思います
その場合は Sentinel で現在の Master を調べてその Master にアクセスするようにしましょう
# redis-cli -h $NODE_IP -p 30800 -a $REDIS_PASSWORD
NODE_IP:30800> sentinel get-master-addr-by-name mymaster
1) "10.233.2.232"
2) "6379"
NODE_IP:30800> exit
# kubectl exec --stdin --tty test-sentinel-redis-node-0 -- redis-cli -h 10.233.2.232 -p 6379 -a $REDIS_PASSWORD
Defaulting container name to redis.
Use 'kubectl describe pod/test-sentinel-redis-node-0 -n default' to see all of the containers in this pod.
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
10.233.2.232:6379> set age 10
OK
failover を試してみる
Sentinel があるので Master の Redis がダウンした場合には Slave が昇格して Master が変わるはずです
Bitnami の Redis Pod の構成の場合 Sentinel + Redis ノードのサイドカー構成で 1 Pod になっているので Pod 内の Redis コンテナのみを削除することで failover を発生させてみます
kubectl exec test-sentinel-redis-node-0 -c redis -- /bin/sh -c "kill 1"
これで redis コンテナのみ再起動します
しばらくて redis コンテナが起動したら Master が切り替わっていることを確認してみます
まずはそれぞれの Pod にアクセスして role の情報を確認してみます
# kubectl exec test-sentinel-redis-node-0 -c redis -- redis-cli -a $REDIS_PASSWORD info | grep role
role:slave
# kubectl exec test-sentinel-redis-node-1 -c redis -- redis-cli -a $REDIS_PASSWORD info | grep role
role:master
# kubectl exec test-sentinel-redis-node-2 -c redis -- redis-cli -a $REDIS_PASSWORD info | grep role
role:slave
先程は test-sentinel-redis-node-0 が Master だったのに対して test-sentinel-redis-node-1 に failover していることが確認できます
次に Sentinel にも Master 情報を確認してみましょう
# redis-cli -h $NODE_IP -p 30800 -a $REDIS_PASSWORD
NODE_IP:30800> sentinel get-master-addr-by-name mymaster
1) "10.233.1.200"
2) "6379"
ちゃんと failover しているのが確認できると思います
Master にアクセスして Write できるかも確認してみましょう
ubectl exec --stdin --tty test-sentinel-redis-node-0 -- redis-cli -h 10.233.1.200 -p 6379 -a $REDIS_PASSWORD
Defaulting container name to redis.
Use 'kubectl describe pod/test-sentinel-redis-node-0 -n default' to see all of the containers in this pod.
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
10.233.1.200:6379> set age 10
OK
問題なさそうです
おまけ: リソース削除
helm uninstall test
for i in `kubectl get pvc -o json | jq -r '.items[].metadata.name'`; do kubectl delete pvc $i; done
最後に
簡単に Sentinel 構成もデプロイできるのでかなり使えそうです
values はある程度理解して使えるようにならないとダメかもしれません
failover させる際に Master の Sentinel も一緒に削除すると Sentinel Cluster が壊れて Pod が上がってこなくなりました
具体的には以下のコマンドで failover のテストをすると Pod が上がってこないのが確認できると思います
kubectl delete pod test-sentinel-redis-node-0
ちなみに Slave の Pod を削除してもクラスタは元の状態に戻ります
ダメそうなのは Master の Pod が削除された場合のみのようです
0 件のコメント:
コメントを投稿