次の図のような、Kubernetes上でのRedisクラスタの構築、増強、縮小、消去のライフサイクルについて、K8sとRedisの操作手順のメモです。
Redisクラスタのセットアップ
Redisマスター x3、スレーブ x3 のRedisクラスタを構築した記録です。
K8sクラスタのノードのリスト
Redisクラスタを作った環境は、IKS (IBM Cloud Kubernetes Service) の3ノード構成のK8sクラスタです。
$ kubectl get node
NAME STATUS ROLES AGE VERSION
10.193.10.14 Ready <none> 22m v1.13.8+IKS
10.193.10.20 Ready <none> 21m v1.13.8+IKS
10.193.10.58 Ready <none> 22m v1.13.8+IKS
Redisクラスタを、マニフェストで起動する
ここで、適用するマニフェストは、https://github.com/sanderploegsma/redis-cluster を、そのまま利用したものです。このマニフェストは、IKSではありませんが、無修正で利用できました。
$ kubectl apply -f redis-cluster.yml
configmap/redis-cluster created
service/redis-cluster created
statefulset.apps/redis-cluster created
ポッドと永続ボリュームの作成完了状態
この時点で、Redisクラスタの各ポッドは、永続ボリュームをマウントしています。
$ kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
redis-cluster-0 0/1 Pending 0 40s <none> <none> <none> <none>
$ kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE
redis-cluster-0 1/1 Running 0 28m 172.30.254.8 10.193.10.14
redis-cluster-1 1/1 Running 0 26m 172.30.103.132 10.193.10.58
redis-cluster-2 1/1 Running 0 24m 172.30.63.2 10.193.10.20
redis-cluster-3 1/1 Running 0 22m 172.30.254.9 10.193.10.14
redis-cluster-4 1/1 Running 0 20m 172.30.63.3 10.193.10.20
redis-cluster-5 1/1 Running 0 18m 172.30.103.133 10.193.10.58
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
data-redis-cluster-0 Bound pvc-43b58162 20Gi RWO ibmc-file-bronze 28m
data-redis-cluster-1 Bound pvc-86a09801 20Gi RWO ibmc-file-bronze 26m
data-redis-cluster-2 Bound pvc-d3110510 20Gi RWO ibmc-file-bronze 24m
data-redis-cluster-3 Bound pvc-19828267 20Gi RWO ibmc-file-bronze 22m
data-redis-cluster-4 Bound pvc-6515149b 20Gi RWO ibmc-file-bronze 20m
data-redis-cluster-5 Bound pvc-a8929ead 20Gi RWO ibmc-file-bronze 18m
Redisクラスタの初期化
Redisクラスタのポッドの一つでコマンドを実行して、Redisクラスタを構築します。
$ kubectl exec -it redis-cluster-0 -- redis-cli --cluster create --cluster-replicas 1 \
> $(kubectl get pods -l app=redis-cluster -o jsonpath='{range.items[*]}{.status.podIP}:6379 ')
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 172.30.254.9:6379 to 172.30.254.8:6379
Adding replica 172.30.63.3:6379 to 172.30.103.132:6379
Adding replica 172.30.103.133:6379 to 172.30.63.2:6379
M: 901cdffd0f11f30e09ba2c22540ca2d31f1219e2 172.30.254.8:6379
slots:[0-5460] (5461 slots) master
M: e3246d584d2390f7775ff168da4f8838939c6e53 172.30.103.132:6379
slots:[5461-10922] (5462 slots) master
M: 9a3951b4d0fd3c78a927ccb6e43ff62fe7875fbe 172.30.63.2:6379
slots:[10923-16383] (5461 slots) master
S: 3309f5c2f345f4d4facd5af967588d794225fef1 172.30.254.9:6379
replicates 901cdffd0f11f30e09ba2c22540ca2d31f1219e2
S: cfc0a7bb96305308cc35fd6af37b59b2e2b117ae 172.30.63.3:6379
replicates e3246d584d2390f7775ff168da4f8838939c6e53
S: 2b4a9d44f3576c239101afc16a002db6cc19be2f 172.30.103.133:6379
replicates 9a3951b4d0fd3c78a927ccb6e43ff62fe7875fbe
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
....
>>> Performing Cluster Check (using node 172.30.254.8:6379)
M: 901cdffd0f11f30e09ba2c22540ca2d31f1219e2 172.30.254.8:6379
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: 2b4a9d44f3576c239101afc16a002db6cc19be2f 172.30.103.133:6379
slots: (0 slots) slave
replicates 9a3951b4d0fd3c78a927ccb6e43ff62fe7875fbe
M: e3246d584d2390f7775ff168da4f8838939c6e53 172.30.103.132:6379
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
M: 9a3951b4d0fd3c78a927ccb6e43ff62fe7875fbe 172.30.63.2:6379
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: cfc0a7bb96305308cc35fd6af37b59b2e2b117ae 172.30.63.3:6379
slots: (0 slots) slave
replicates e3246d584d2390f7775ff168da4f8838939c6e53
S: 3309f5c2f345f4d4facd5af967588d794225fef1 172.30.254.9:6379
slots: (0 slots) slave
replicates 901cdffd0f11f30e09ba2c22540ca2d31f1219e2
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
Redisクラスタのメンバーの確認
$ kubectl run -it redis-cli --rm --image redis --restart=Never -- bash
If you don't see a command prompt, try pressing enter.
root@redis-cli:/data# redis-cli -c -h 172.30.254.8 -p 6379
172.30.254.8:6379> cluster nodes
2b4a9d44f3576c239101afc16a002db6cc19be2f 172.30.103.133:6379@16379 slave 9a3951b4d0fd3c78a927ccb6e43ff62fe7875fbe 0 1564558966000 6 connected
e3246d584d2390f7775ff168da4f8838939c6e53 172.30.103.132:6379@16379 master - 0 1564558965000 2 connected 5461-10922
9a3951b4d0fd3c78a927ccb6e43ff62fe7875fbe 172.30.63.2:6379@16379 master - 0 1564558966134 3 connected 10923-16383
f4631fb91f42024db54a829dfc00a12e9035761e 172.30.254.10:6379@16379 master - 0 1564558965000 0 connected
cfc0a7bb96305308cc35fd6af37b59b2e2b117ae 172.30.63.3:6379@16379 slave e3246d584d2390f7775ff168da4f8838939c6e53 0 1564558967137 5 connected
3309f5c2f345f4d4facd5af967588d794225fef1 172.30.254.9:6379@16379 slave 901cdffd0f11f30e09ba2c22540ca2d31f1219e2 0 1564558965128 4 connected
901cdffd0f11f30e09ba2c22540ca2d31f1219e2 172.30.254.8:6379@16379 myself,master - 0 1564558964000 1 connected 0-5460
NAME順のビューで分析
マスターから順番に起動して、スレーブを順番に起動している。 マスターとスレーブの関係が解る。
NAME IP NODE ROLE MASTER
redis-cluster-0 172.30.254.8 10.193.10.14 Master -
redis-cluster-1 172.30.103.132 10.193.10.58 Master -
redis-cluster-2 172.30.63.2 10.193.10.20 Master -
redis-cluster-3 172.30.254.9 10.193.10.14 Slave redis-cluster-0
redis-cluster-4 172.30.63.3 10.193.10.20 Slave redis-cluster-1
redis-cluster-5 172.30.103.133 10.193.10.58 Slave redis-cluster-2
上記の結果から、マスターとスレーブの対応表を作ると、次のようになる。
マスター スレーブ(レプリカ)
redis-cluster-0 -> redis-cluster-3
redis-cluster-1 -> redis-cluster-4
redis-cluster-2 -> redis-cluster-5
ノード順のビューで分析
ノード順でソートすることで、K8sに共存するポッドが解る。その結果の解った事として、マスター redis-cluster-0 と スレーブ redis-cluster-3 が NODE *.14 の同じK8sノードに乗っている。そのため、このK8sノードが停止すると、ハッシュ・スロット slots:[0-5460] が失われる。そのため、マスターとスレーブが同時に失われ、スレーブが昇格して継続できない。
K8sノード(仮想サーバー) *.14 が停止した場合の影響では、GCPの場合は、ただちに代替のK8sノード(仮想サーバー)が起動するので、短時間の停止で復旧する。一方、IKSでは、K8sノード(仮想サーバー)を短時間で起動できれば、短時間の停止で被害を抑えられる。
NAME IP NODE ROLE MASTER
redis-cluster-0 172.30.254.8 10.193.10.14 Master -
redis-cluster-3 172.30.254.9 10.193.10.14 Slave redis-cluster-0
redis-cluster-2 172.30.63.2 10.193.10.20 Master -
redis-cluster-4 172.30.63.3 10.193.10.20 Slave redis-cluster-1
redis-cluster-1 172.30.103.132 10.193.10.58 Master -
redis-cluster-5 172.30.103.133 10.193.10.58 Slave redis-cluster-2
以上で、Redisクラスタの構築は完了です。 K8sクラスタ内のクライアントから、内部DNS redis-cluster で Redisクラスタへアクセスできるようになります。 もちろん、Redisクラスタ対応のプログラム言語のライブラリが必須です。
Redisクラスタの増強
前述で起動したRedisクラスタに、ポッドを追加して、Redisクラスタのマスターとスレーブのセットを増強します。 ただし、K8sクラスタのノード数を増強するところまでは、行っていません。作業の手順は以下の箇条書きの順番になります。
- ステートフルセット・コントローラに対して、レプリカセット数 8 をセット
- Redisマスターの追加
- Redisステーブの追加
- リバランスを実行して、追加したRedisマスターにデータを均一化
レプリカセット数の増加 6 -> 8
ステートフルセット・コントローラーに、新しいレプリカ数をセットします。これによって、連番の最後にメンバーが追加されいます。この追加されたポッドには、既存のポッド同様に、永続ボリュームがマウントされています。
$ kubectl scale statefulset redis-cluster --replicas=8
statefulset.apps/redis-cluster scaled
$ kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE
redis-cluster-0 1/1 Running 0 36m 172.30.254.8 10.193.10.14
redis-cluster-1 1/1 Running 0 35m 172.30.103.132 10.193.10.58
redis-cluster-2 1/1 Running 0 32m 172.30.63.2 10.193.10.20
redis-cluster-3 1/1 Running 0 30m 172.30.254.9 10.193.10.14
redis-cluster-4 1/1 Running 0 28m 172.30.63.3 10.193.10.20
redis-cluster-5 1/1 Running 0 26m 172.30.103.133 10.193.10.58
redis-cluster-6 1/1 Running 0 3m41s 172.30.254.10 10.193.10.14
redis-cluster-7 1/1 Running 0 112s 172.30.63.4 10.193.10.20
Redisマスターの追加
ポッド redis-cluster-6 を Redisマスターとして追加することを、redis-cluster-0 へ通知します。この中で、「$(kubectl get pod redis-cluster-6 -o jsonpath='{.status.podIP}')」は、指定したポッドのIPアドレスを返します。IPアドレスを調べて、セットしても良いですが、この方法はスマートですね。
imac:redis-cluster maho$ kubectl exec redis-cluster-0 -- redis-cli --cluster add-node \
> $(kubectl get pod redis-cluster-6 -o jsonpath='{.status.podIP}'):6379 \
> $(kubectl get pod redis-cluster-0 -o jsonpath='{.status.podIP}'):6379
>>> Adding node 172.30.254.10:6379 to cluster 172.30.254.8:6379
>>> Performing Cluster Check (using node 172.30.254.8:6379)
M: 901cdffd0f11f30e09ba2c22540ca2d31f1219e2 172.30.254.8:6379
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: 2b4a9d44f3576c239101afc16a002db6cc19be2f 172.30.103.133:6379
slots: (0 slots) slave
replicates 9a3951b4d0fd3c78a927ccb6e43ff62fe7875fbe
M: e3246d584d2390f7775ff168da4f8838939c6e53 172.30.103.132:6379
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
M: 9a3951b4d0fd3c78a927ccb6e43ff62fe7875fbe 172.30.63.2:6379
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: cfc0a7bb96305308cc35fd6af37b59b2e2b117ae 172.30.63.3:6379
slots: (0 slots) slave
replicates e3246d584d2390f7775ff168da4f8838939c6e53
S: 3309f5c2f345f4d4facd5af967588d794225fef1 172.30.254.9:6379
slots: (0 slots) slave
replicates 901cdffd0f11f30e09ba2c22540ca2d31f1219e2
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
>>> Send CLUSTER MEET to node 172.30.254.10:6379 to make it join the cluster.
[OK] New node added correctly.
ポッドのIPアドレスを求める方法の補足です。 $() の中身だけを実行すると、ポッド redis-cluster-0 のIPアドレスを返していることが理解できます。
$ kubectl get pod redis-cluster-0 -o jsonpath='{.status.podIP}';echo
172.30.254.8
Redisノードのリスト表示
別の対話型ポッドを起動して、マスターが4つ、スレーブが3つの状態を確認できます。
$ kubectl run -it redis-cli --rm --image redis --restart=Never -- bash
If you don't see a command prompt, try pressing enter.
root@redis-cli:/data# redis-cli -c -h 172.30.254.8 -p 6379
172.30.254.8:6379> cluster nodes
2b4a9d44f3576c239101afc16a002db6cc19be2f 172.30.103.133:6379@16379 slave 9a3951b4d0fd3c78a927ccb6e43ff62fe7875fbe 0 1564558966000 6 connected
e3246d584d2390f7775ff168da4f8838939c6e53 172.30.103.132:6379@16379 master - 0 1564558965000 2 connected 5461-10922
9a3951b4d0fd3c78a927ccb6e43ff62fe7875fbe 172.30.63.2:6379@16379 master - 0 1564558966134 3 connected 10923-16383
f4631fb91f42024db54a829dfc00a12e9035761e 172.30.254.10:6379@16379 master - 0 1564558965000 0 connected <--- 追加
cfc0a7bb96305308cc35fd6af37b59b2e2b117ae 172.30.63.3:6379@16379 slave e3246d584d2390f7775ff168da4f8838939c6e53 0 1564558967137 5 connected
3309f5c2f345f4d4facd5af967588d794225fef1 172.30.254.9:6379@16379 slave 901cdffd0f11f30e09ba2c22540ca2d31f1219e2 0 1564558965128 4 connected
901cdffd0f11f30e09ba2c22540ca2d31f1219e2 172.30.254.8:6379@16379 myself,master - 0 1564558964000 1 connected 0-5460
Redisスレーブを追加
Redisマスターが追加できたので、このマスターのデータをレプリカするRedisスレーブを追加します。これも ポッド redis-cluster-7 を追加することを、ポッドのIPアドレスとポート番号を指定して、ポッド redis-cluster-0 へ通知します。 Redisクラスタのマスターは、どれも同格なので、他のRedisマスターのポッドでも良いと思います。
$ kubectl exec redis-cluster-0 -- redis-cli --cluster add-node --cluster-slave \
> $(kubectl get pod redis-cluster-7 -o jsonpath='{.status.podIP}'):6379 \
> $(kubectl get pod redis-cluster-0 -o jsonpath='{.status.podIP}'):6379
>>> Adding node 172.30.63.4:6379 to cluster 172.30.254.8:6379
>>> Performing Cluster Check (using node 172.30.254.8:6379)
M: 901cdffd0f11f30e09ba2c22540ca2d31f1219e2 172.30.254.8:6379
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: 2b4a9d44f3576c239101afc16a002db6cc19be2f 172.30.103.133:6379
slots: (0 slots) slave
replicates 9a3951b4d0fd3c78a927ccb6e43ff62fe7875fbe
M: e3246d584d2390f7775ff168da4f8838939c6e53 172.30.103.132:6379
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
M: 9a3951b4d0fd3c78a927ccb6e43ff62fe7875fbe 172.30.63.2:6379
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
M: f4631fb91f42024db54a829dfc00a12e9035761e 172.30.254.10:6379
slots: (0 slots) master
S: cfc0a7bb96305308cc35fd6af37b59b2e2b117ae 172.30.63.3:6379
slots: (0 slots) slave
replicates e3246d584d2390f7775ff168da4f8838939c6e53
S: 3309f5c2f345f4d4facd5af967588d794225fef1 172.30.254.9:6379
slots: (0 slots) slave
replicates 901cdffd0f11f30e09ba2c22540ca2d31f1219e2
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
Automatically selected master 172.30.254.10:6379
>>> Send CLUSTER MEET to node 172.30.63.4:6379 to make it join the cluster.
Waiting for the cluster to join
>>> Configure node as replica of 172.30.254.10:6379.
[OK] New node added correctly.
マスターとスレーブをリストして状態を確認
172.30.254.8:6379> cluster nodes
2b4a9d44f3576c239101afc16a002db6cc19be2f 172.30.103.133:6379@16379 slave 9a3951b4d0fd3c78a927ccb6e43ff62fe7875fbe 0 1564559113000 6 connected
e3246d584d2390f7775ff168da4f8838939c6e53 172.30.103.132:6379@16379 master - 0 1564559115804 2 connected 5461-10922
9a3951b4d0fd3c78a927ccb6e43ff62fe7875fbe 172.30.63.2:6379@16379 master - 0 1564559113000 3 connected 10923-16383
f4631fb91f42024db54a829dfc00a12e9035761e 172.30.254.10:6379@16379 master - 0 1564559114799 0 connected
63e279bbd0fd303240248dc530968ff8e0177d33 172.30.63.4:6379@16379 slave f4631fb91f42024db54a829dfc00a12e9035761e 0 1564559112789 0 connected
cfc0a7bb96305308cc35fd6af37b59b2e2b117ae 172.30.63.3:6379@16379 slave e3246d584d2390f7775ff168da4f8838939c6e53 0 1564559114000 5 connected
3309f5c2f345f4d4facd5af967588d794225fef1 172.30.254.9:6379@16379 slave 901cdffd0f11f30e09ba2c22540ca2d31f1219e2 0 1564559114000 4 connected
901cdffd0f11f30e09ba2c22540ca2d31f1219e2 172.30.254.8:6379@16379 myself,master - 0 1564559111000 1 connected 0-5460
クラスタのマスターとスレーブのセットが追加が出来たのでリバランスを実行
Redisマスターとスレーブのポッドが追加できたので、既存のRedisマスターとの間で、保持しているデータをリバランス(再平均化)して、追加したRedisマスターとスレーブのノードが適切に機能するようにします。
$ kubectl exec redis-cluster-0 -- redis-cli --cluster rebalance --cluster-use-empty-masters \
> $(kubectl get pod redis-cluster-0 -o jsonpath='{.status.podIP}'):6379
>>> Performing Cluster Check (using node 172.30.254.8:6379)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
>>> Rebalancing across 4 nodes. Total weight = 4.00
Moving 1366 slots from 172.30.103.132:6379 to 172.30.254.10:6379
###### 省略
Moving 1365 slots from 172.30.63.2:6379 to 172.30.254.10:6379
###### 省略
Moving 1365 slots from 172.30.254.8:6379 to 172.30.254.10:6379
###### 省略
これで、マスターとスレーブの増設は作業は完了です。
Redisクラスタの縮小 Redisマスターとスレーブのセットを削減
次は、Redisクラスタの縮小方法です。 こちらもデータを抱えているRedisクラスタを縮小するために、ステートフルセットのレプリカ数を減らすだけとは、いきません。 そのため、この手順を、以下の箇条書きにしました。
- 削除対象のRedisマスターのスレーブを削除
- 削除対象のRedisマスターからデータを他のマスターへ追い出し
- Redisクラスタから削除対象のRedisマスターを削除
- 残ったRedisマスター間でデータをリバランス
- ステートフルセットのポッド数を減らして、Redisクラスタの規模を縮小
ステートフルセットで、レプリカ数を減らすと、最後に追加されたものから、削除されるます。そのため、レプリカ数=6を通知すると、最後に追加された redis-cluster-7 と redis-cluster-6 を削除します。
スレーブを削除
削除対象ポッド redis-cluster-7 のRedisクラスタIDをメモします。
$ kubectl exec redis-cluster-7 -- redis-cli cluster nodes | grep myself
63e279bbd0fd303240248dc530968ff8e0177d33 172.30.63.4:6379@16379 myself,slave f4631fb91f42024db54a829dfc00a12e9035761e 0 1564559920000 7 connected
Redisマスター redis-cluster-0 で、redis-cluster-7 を削除するコマンドを実行します。
$ kubectl exec redis-cluster-0 -- redis-cli --cluster del-node \
> $(kubectl get pod redis-cluster-0 -o jsonpath='{.status.podIP}'):6379 \
> 63e279bbd0fd303240248dc530968ff8e0177d33
>>> Removing node 63e279bbd0fd303240248dc530968ff8e0177d33 from cluster 172.30.254.8:6379
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.
command terminated with exit code 1
どうして、exit code = 1 で終了するのか、解りませんでしたが、削除は成功していました。
スレーブが消えたことを確認します。 以下のように、削除後は、マスター x4、 スレーブ x3 になっていました。
## 消す前
172.30.254.8:6379> cluster nodes
2b4a9d44f3576c239101afc16a002db6cc19be2f 172.30.103.133:6379@16379 slave 9a3951b4d0fd3c78a927ccb6e43ff62fe7875fbe 0 1564559113000 6 connected
e3246d584d2390f7775ff168da4f8838939c6e53 172.30.103.132:6379@16379 master - 0 1564559115804 2 connected 5461-10922
9a3951b4d0fd3c78a927ccb6e43ff62fe7875fbe 172.30.63.2:6379@16379 master - 0 1564559113000 3 connected 10923-16383
f4631fb91f42024db54a829dfc00a12e9035761e 172.30.254.10:6379@16379 master - 0 1564559114799 0 connected
63e279bbd0fd303240248dc530968ff8e0177d33 172.30.63.4:6379@16379 slave f4631fb91f42024db54a829dfc00a12e9035761e 0 1564559112789 0 connected
cfc0a7bb96305308cc35fd6af37b59b2e2b117ae 172.30.63.3:6379@16379 slave e3246d584d2390f7775ff168da4f8838939c6e53 0 1564559114000 5 connected
3309f5c2f345f4d4facd5af967588d794225fef1 172.30.254.9:6379@16379 slave 901cdffd0f11f30e09ba2c22540ca2d31f1219e2 0 1564559114000 4 connected
901cdffd0f11f30e09ba2c22540ca2d31f1219e2 172.30.254.8:6379@16379 myself,master - 0 1564559111000 1 connected 0-5460
## 削除後
172.30.254.8:6379> cluster nodes
2b4a9d44f3576c239101afc16a002db6cc19be2f 172.30.103.133:6379@16379 slave 9a3951b4d0fd3c78a927ccb6e43ff62fe7875fbe 0 1564560086177 6 connected
e3246d584d2390f7775ff168da4f8838939c6e53 172.30.103.132:6379@16379 master - 0 1564560085000 2 connected 6827-10922
9a3951b4d0fd3c78a927ccb6e43ff62fe7875fbe 172.30.63.2:6379@16379 master - 0 1564560085176 3 connected 12288-16383
f4631fb91f42024db54a829dfc00a12e9035761e 172.30.254.10:6379@16379 master - 0 1564560085000 8 connected 0-1364 5461-6826 10923-12287
cfc0a7bb96305308cc35fd6af37b59b2e2b117ae 172.30.63.3:6379@16379 slave e3246d584d2390f7775ff168da4f8838939c6e53 0 1564560084171 5 connected
3309f5c2f345f4d4facd5af967588d794225fef1 172.30.254.9:6379@16379 slave 901cdffd0f11f30e09ba2c22540ca2d31f1219e2 0 1564560083000 4 connected
901cdffd0f11f30e09ba2c22540ca2d31f1219e2 172.30.254.8:6379@16379 myself,master - 0 1564560082000 1 connected 1365-5460
Redisマスターの削除
削除対象のRedisマスターのIDをメモします。 コマンドで ポッド redis-cluster-6 のRedisクラスタ IDの取得方法は以下です。
$ kubectl exec redis-cluster-6 -- redis-cli cluster nodes | grep myself
f4631fb91f42024db54a829dfc00a12e9035761e 172.30.254.10:6379@16379 myself,master - 0 1564562825000 8 connected 0-1364 5461-6826 10923-12287
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE
redis-cli 1/1 Running 0 65m 172.30.254.11 10.193.10.14
redis-cluster-0 1/1 Running 0 104m 172.30.254.8 10.193.10.14
redis-cluster-1 1/1 Running 0 102m 172.30.103.132 10.193.10.58
redis-cluster-2 1/1 Running 0 100m 172.30.63.2 10.193.10.20
redis-cluster-3 1/1 Running 0 98m 172.30.254.9 10.193.10.14
redis-cluster-4 1/1 Running 0 96m 172.30.63.3 10.193.10.20
redis-cluster-5 1/1 Running 0 94m 172.30.103.133 10.193.10.58
redis-cluster-6 1/1 Running 0 70m 172.30.254.10 10.193.10.14
redis-cluster-7 1/1 Running 1 69m 172.30.63.4 10.193.10.20
データの移動 reshard (リシェアード) を実行
ポッド redis-cluster-6 の Redisマスター に保存されているデータを、他のRedisマスターへ移動します。
--cluster-from は、redis-cluster-6 のIDです。
--cluster-to は、redis-cluster-0 のIDです。
つまり、redis-cluster-6 のデータを redis-cluster-0 へ転送します。 あとで、もう一度リバランスするので、一時的退避となります。
$ kubectl exec redis-cluster-0 -- redis-cli --cluster reshard --cluster-yes ¥
--cluster-from f4631fb91f42024db54a829dfc00a12e9035761e ¥
--cluster-to 901cdffd0f11f30e09ba2c22540ca2d31f1219e2 ¥
--cluster-slots 16384 $(kubectl get pod redis-cluster-0 -o jsonpath='{.status.podIP}'):6379
>>> Performing Cluster Check (using node 172.30.254.8:6379)
M: 901cdffd0f11f30e09ba2c22540ca2d31f1219e2 172.30.254.8:6379
slots:[1365-5460] (4096 slots) master
1 additional replica(s)
S: 2b4a9d44f3576c239101afc16a002db6cc19be2f 172.30.103.133:6379
slots: (0 slots) slave
replicates 901cdffd0f11f30e09ba2c22540ca2d31f1219e2
M: e3246d584d2390f7775ff168da4f8838939c6e53 172.30.103.132:6379
slots:[6827-10922] (4096 slots) master
1 additional replica(s)
M: 9a3951b4d0fd3c78a927ccb6e43ff62fe7875fbe 172.30.63.2:6379
slots:[12288-16383] (4096 slots) master
1 additional replica(s)
M: f4631fb91f42024db54a829dfc00a12e9035761e 172.30.254.10:6379
slots:[0-1364],[5461-6826],[10923-12287] (4096 slots) master
S: cfc0a7bb96305308cc35fd6af37b59b2e2b117ae 172.30.63.3:6379
slots: (0 slots) slave
replicates e3246d584d2390f7775ff168da4f8838939c6e53
S: 3309f5c2f345f4d4facd5af967588d794225fef1 172.30.254.9:6379
slots: (0 slots) slave
replicates 9a3951b4d0fd3c78a927ccb6e43ff62fe7875fbe
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
Ready to move 16384 slots.
Source nodes:
M: f4631fb91f42024db54a829dfc00a12e9035761e 172.30.254.10:6379
slots:[0-1364],[5461-6826],[10923-12287] (4096 slots) master
Destination node:
M: 901cdffd0f11f30e09ba2c22540ca2d31f1219e2 172.30.254.8:6379
slots:[1365-5460] (4096 slots) master
1 additional replica(s)
Resharding plan:
Moving slot 0 from f4631fb91f42024db54a829dfc00a12e9035761e
Moving slot 1 from f4631fb91f42024db54a829dfc00a12e9035761e
Moving slot 2 from f4631fb91f42024db54a829dfc00a12e9035761e
ハッシュスロットの範囲が表示されなくなり、f4631fb91f42024db54a829dfc00a12e9035761e redis-cluster-6 からデータが無くなったことが、解ります。
$ kubectl exec redis-cluster-6 -- redis-cli cluster nodes | grep master
f4631fb91f42024db54a829dfc00a12e9035761e 172.30.254.10:6379@16379 myself,master - 0 1564574487000 8 connected
901cdffd0f11f30e09ba2c22540ca2d31f1219e2 172.30.254.8:6379@16379 master - 0 1564574488000 10 connected 0-6826 10923-12287
e3246d584d2390f7775ff168da4f8838939c6e53 172.30.103.132:6379@16379 master - 0 1564574490000 2 connected 6827-10922
9a3951b4d0fd3c78a927ccb6e43ff62fe7875fbe 172.30.63.2:6379@16379 master - 0 1564574485735 9 connected 12288-16383
imac:redis-cluster maho$ kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE
redis-cli 1/1 Running 0 4h19m 172.30.254.11 10.193.10.14
redis-cluster-0 1/1 Running 0 4h58m 172.30.254.8 10.193.10.14
redis-cluster-1 1/1 Running 0 4h56m 172.30.103.132 10.193.10.58
redis-cluster-2 1/1 Running 0 4h54m 172.30.63.2 10.193.10.20
redis-cluster-3 1/1 Running 0 4h52m 172.30.254.9 10.193.10.14
redis-cluster-4 1/1 Running 0 4h50m 172.30.63.3 10.193.10.20
redis-cluster-5 1/1 Running 0 4h48m 172.30.103.133 10.193.10.58
redis-cluster-6 1/1 Running 0 4h25m 172.30.254.10 10.193.10.14
redis-cluster-7 1/1 Running 1 4h23m 172.30.63.4 10.193.10.20
Redisマスター redis-cluster-6 を Redisクラスタから削除
Redisマスター redis-cluster-6 からデータを追い出せたので、Redisクラスタから redis-cluster-6 を削除します。
kubectl exec redis-cluster-0 -- redis-cli --cluster del-node \
$(kubectl get pod redis-cluster-0 -o jsonpath='{.status.podIP}'):6379 \
f4631fb91f42024db54a829dfc00a12e9035761e
削除の確認結果です。 Redisマスターが3つに、減っていることが解ります。
172.30.103.132:6379> cluster nodes
cfc0a7bb96305308cc35fd6af37b59b2e2b117ae 172.30.63.3:6379@16379 slave e3246d584d2390f7775ff168da4f8838939c6e53 0 1564574917531 5 connected
2b4a9d44f3576c239101afc16a002db6cc19be2f 172.30.103.133:6379@16379 slave 901cdffd0f11f30e09ba2c22540ca2d31f1219e2 0 1564574919544 10 connected
9a3951b4d0fd3c78a927ccb6e43ff62fe7875fbe 172.30.63.2:6379@16379 master - 0 1564574920548 9 connected 12288-16383
3309f5c2f345f4d4facd5af967588d794225fef1 172.30.254.9:6379@16379 slave 9a3951b4d0fd3c78a927ccb6e43ff62fe7875fbe 0 1564574919000 9 connected
e3246d584d2390f7775ff168da4f8838939c6e53 172.30.103.132:6379@16379 myself,master - 0 1564574919000 2 connected 6827-10922
901cdffd0f11f30e09ba2c22540ca2d31f1219e2 172.30.254.8:6379@16379 master - 0 1564574920000 10 connected 0-6826 10923-12287
削除後に、データをリバランス
最後にもう一度、リバランスを実行して、平均化をはかります。
$ kubectl exec redis-cluster-0 -- redis-cli --cluster rebalance --cluster-use-empty-masters \
> $(kubectl get pod redis-cluster-0 -o jsonpath='{.status.podIP}'):6379
>>> Performing Cluster Check (using node 172.30.254.8:6379)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
>>> Rebalancing across 3 nodes. Total weight = 3.00
Moving 1366 slots from 172.30.254.8:6379 to 172.30.103.132:6379
###### 省略
Moving 1365 slots from 172.30.254.8:6379 to 172.30.63.2:6379
###### 省略
リバランス後の状態を確認です。
172.30.103.132:6379> cluster nodes
cfc0a7bb96305308cc35fd6af37b59b2e2b117ae 172.30.63.3:6379@16379 slave e3246d584d2390f7775ff168da4f8838939c6e53 0 1564575387676 11 connected
2b4a9d44f3576c239101afc16a002db6cc19be2f 172.30.103.133:6379@16379 slave 901cdffd0f11f30e09ba2c22540ca2d31f1219e2 0 1564575390000 10 connected
9a3951b4d0fd3c78a927ccb6e43ff62fe7875fbe 172.30.63.2:6379@16379 master - 0 1564575389000 12 connected 1366-2730 12288-16383
3309f5c2f345f4d4facd5af967588d794225fef1 172.30.254.9:6379@16379 slave 9a3951b4d0fd3c78a927ccb6e43ff62fe7875fbe 0 1564575388000 12 connected
e3246d584d2390f7775ff168da4f8838939c6e53 172.30.103.132:6379@16379 myself,master - 0 1564575388000 11 connected 0-1365 6827-10922
901cdffd0f11f30e09ba2c22540ca2d31f1219e2 172.30.254.8:6379@16379 master - 0 1564575390694 10 connected 2731-6826 10923-12287
ステートフルセットのポッド数を減らして、Redisクラスタの規模を縮小
最後に、ステートフルセットのレプリカ数を 6に減らして、redis-cluster-6 と redis-cluster-7 が削除されるのを観察します。
$ kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE
redis-cli 1/1 Running 0 4h35m 172.30.254.11 10.193.10.14
redis-cluster-0 1/1 Running 0 5h14m 172.30.254.8 10.193.10.14
redis-cluster-1 1/1 Running 0 5h12m 172.30.103.132 10.193.10.58
redis-cluster-2 1/1 Running 0 5h10m 172.30.63.2 10.193.10.20
redis-cluster-3 1/1 Running 0 5h8m 172.30.254.9 10.193.10.14
redis-cluster-4 1/1 Running 0 5h6m 172.30.63.3 10.193.10.20
redis-cluster-5 1/1 Running 0 5h4m 172.30.103.133 10.193.10.58
redis-cluster-6 1/1 Running 1 4h41m 172.30.254.10 10.193.10.14
redis-cluster-7 1/1 Running 1 4h39m 172.30.63.4 10.193.10.20
$ kubectl scale statefulset redis-cluster --replicas=6
statefulset.apps/redis-cluster scaled
$ kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE
redis-cli 1/1 Running 0 4h38m 172.30.254.11 10.193.10.14
redis-cluster-0 1/1 Running 0 5h17m 172.30.254.8 10.193.10.14
redis-cluster-1 1/1 Running 0 5h15m 172.30.103.132 10.193.10.58
redis-cluster-2 1/1 Running 0 5h13m 172.30.63.2 10.193.10.20
redis-cluster-3 1/1 Running 0 5h11m 172.30.254.9 10.193.10.14
redis-cluster-4 1/1 Running 0 5h9m 172.30.63.3 10.193.10.20
redis-cluster-5 1/1 Running 0 5h7m 172.30.103.133 10.193.10.58
以上で、Redisクラスタのスケールダウンの作業が完了です。
クラスタのクリーンナップ
永続ボリュームごと、スレートフルセット・コントローラー、その管理下のポッド、サービスを削除する方法です。
$ kubectl delete statefulset,svc,configmap,pvc -l app=redis-cluster
statefulset.apps "redis-cluster" deleted
service "redis-cluster" deleted
configmap "redis-cluster" deleted
persistentvolumeclaim "data-redis-cluster-0" deleted
persistentvolumeclaim "data-redis-cluster-1" deleted
persistentvolumeclaim "data-redis-cluster-2" deleted
persistentvolumeclaim "data-redis-cluster-3" deleted
persistentvolumeclaim "data-redis-cluster-4" deleted
persistentvolumeclaim "data-redis-cluster-5" deleted
persistentvolumeclaim "data-redis-cluster-6" deleted
persistentvolumeclaim "data-redis-cluster-7" deleted
あとがき
Red Hat が推進するオペレータでは、どれくらい手軽に作業できるようになるか、興味が湧いてきました。その前に、マルチゾーンに展開する方法を確認しないと受けないですね。