2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Redisクラスタ on Kubernetes のライフサイクル運用手順

Last updated at Posted at 2019-08-01

次の図のような、Kubernetes上でのRedisクラスタの構築、増強、縮小、消去のライフサイクルについて、K8sとRedisの操作手順のメモです。

Redis_Cluster_on_K8s.png

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 が推進するオペレータでは、どれくらい手軽に作業できるようになるか、興味が湧いてきました。その前に、マルチゾーンに展開する方法を確認しないと受けないですね。

参考資料

  1. https://github.com/sanderploegsma/redis-cluster
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?