2021年5月2日日曜日

bitnami の redis helm chart を使ってみた

bitnami の redis helm chart を使ってみた

概要

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 件のコメント:

コメントを投稿