首頁 > 軟體

k8s部署redis叢集搭建過程範例詳解

2023-02-24 06:03:00

寫在前面

在上一篇文章中,我們已經做到了已經建立好6個redis副本了。

具體的詳情,可以檢視這裡:k8s部署redis叢集(一)

那麼接下來,我們就繼續實現redis叢集的搭建過程。

一、redis叢集搭建

1.1使用redis-cli建立叢集

# 檢視redis的pod對應的ip
kubectl get pod -n jxbp -o wide
>NAME                             READY   STATUS    RESTARTS   AGE    IP               NODE         NOMINATED NODE   READINESS GATES
 redis-0                          1/1     Running   0          18h    10.168.235.196   k8s-master   <none>           <none>
 redis-1                          1/1     Running   0          18h    10.168.235.225   k8s-master   <none>           <none>
 redis-2                          1/1     Running   0          18h    10.168.235.239   k8s-master   <none>           <none>
 redis-3                          1/1     Running   0          18h    10.168.235.198   k8s-master   <none>           <none>
 redis-4                          1/1     Running   0          18h    10.168.235.222   k8s-master   <none>           <none>
 redis-5                          1/1     Running   0          18h    10.168.235.238   k8s-master   <none>           <none>
# 進入到redis-0容器
kubectl exec -it redis-0 /bin/bash -n jxbp
# 建立master節點(redis-0、redis-2、redis-4)
redis-cli --cluster create 10.168.235.196:6379 10.168.235.239:6379 10.168.235.222:6379 -a jxbd
    > Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
    >>> Performing hash slots allocation on 3 nodes...
    Master[0] -> Slots 0 - 5460
    Master[1] -> Slots 5461 - 10922
    Master[2] -> Slots 10923 - 16383
    M: bcae187137a9b30d7dab8fe0d8ed4a46c6e39638 10.168.235.196:6379
       slots:[0-5460] (5461 slots) master
    M: 4367e4a45e557406a3112e7b79f82a44d4ce485e 10.168.235.239:6379
       slots:[5461-10922] (5462 slots) master
    M: a2cec159bbe2efa11a8f60287b90927bcb214729 10.168.235.222:6379
       slots:[10923-16383] (5461 slots) master
    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 10.168.235.196:6379)
    M: bcae187137a9b30d7dab8fe0d8ed4a46c6e39638 10.168.235.196:6379
       slots:[0-5460] (5461 slots) master
    M: a2cec159bbe2efa11a8f60287b90927bcb214729 10.168.235.222:6379
       slots:[10923-16383] (5461 slots) master
    M: 4367e4a45e557406a3112e7b79f82a44d4ce485e 10.168.235.239:6379
       slots:[5461-10922] (5462 slots) master
    [OK] All nodes agree about slots configuration.
    >>> Check for open slots...
    >>> Check slots coverage...
    [OK] All 16384 slots covered.

注意上面的master節點,會生成對應節點id:bcae187137a9b30d7dab8fe0d8ed4a46c6e39638a2cec159bbe2efa11a8f60287b90927bcb2147294367e4a45e557406a3112e7b79f82a44d4ce485e,用於建立slave節點。

# 為每個master節點新增slave節點
# 10.168.235.196:6379的位置可以是任意一個master節點,一般我們用第一個master節點即redis-0的ip地址
# --cluster-master-id引數指定該salve節點對應的master節點的id
# -a引數指定redis的密碼
# redis-0的master節點,新增redis-1為slave節點
redis-cli --cluster add-node 10.168.235.225:6379 10.168.235.196:6379 --cluster-slave --cluster-master-id bcae187137a9b30d7dab8fe0d8ed4a46c6e39638 -a jxbd
# redis-2的master節點,新增redis-3為slave節點
redis-cli --cluster add-node 10.168.235.198:6379 10.168.235.239:6379 --cluster-slave --cluster-master-id a2cec159bbe2efa11a8f60287b90927bcb214729 -a jxbd
# redis-4的master節點,新增redis-5為slave節點
redis-cli --cluster add-node 10.168.233.238:6379 10.168.235.222:6379 --cluster-slave --cluster-master-id 4367e4a45e557406a3112e7b79f82a44d4ce485e -a jxbd

顯示以下資訊,即為新增成功:

[OK] All nodes agree about slots configuration.

[OK] All 16384 slots covered.

[OK] New node added correctly.

坑:

一開始是想用headless的域名建立redis叢集的,這樣節點重啟後就不需要更新ip,但是redis不支援使用域名,所以只能繞了一圈又回到固定ip的方法,和容器環境很不協調。

1.2redis叢集狀態驗證(可選)

  • cluster info
# 進入到redis使用者端,叢集需要帶上-c,有密碼需要帶上-a
redis-cli -c -a jxbd
# 檢視redis叢集資訊
127.0.0.1:6379> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:3
cluster_my_epoch:1
cluster_stats_messages_ping_sent:7996
cluster_stats_messages_pong_sent:7713
cluster_stats_messages_sent:15709
cluster_stats_messages_ping_received:7710
cluster_stats_messages_pong_received:7996
cluster_stats_messages_meet_received:3
cluster_stats_messages_received:15709

注意:

現在進入叢集中的任意一個Pod中都可以存取Redis服務,前面我們建立了一個headless型別的Service,kubernetes叢集會為該服務分配一個DNS記錄,格式為:$(pod.name).$(headless server.name).${namespace}.svc.cluster.local,每次存取該服務名時,將會直接進入到redis的節點上。svc.cluster.local可省略。 例如:

redis-cli -c -a jxbd -h redis-0.redis-hs.jxbp -p 6379

  • cluster nodes
# 檢視redis叢集狀態
127.0.0.1:6379> cluster nodes
70220b45e978d0cb3df19b07e55d883b49f4127d 10.168.235.238:6379@16379 slave 4367e4a45e557406a3112e7b79f82a44d4ce485e 0 1670306292673 2 connected
122b89a51a9bf005e3d47b6d721c65621d2e9a75 10.168.235.225:6379@16379 slave bcae187137a9b30d7dab8fe0d8ed4a46c6e39638 0 1670306290558 1 connected
c2afcb9e83038a47d04bf328ead8033788548234 10.168.235.198:6379@16379 slave a2cec159bbe2efa11a8f60287b90927bcb214729 0 1670306291162 3 connected
4367e4a45e557406a3112e7b79f82a44d4ce485e 10.168.235.239:6379@16379 master - 0 1670306291561 2 connected 5461-10922
bcae187137a9b30d7dab8fe0d8ed4a46c6e39638 10.168.235.196:6379@16379 myself,master - 0 1670306291000 1 connected 0-5460
a2cec159bbe2efa11a8f60287b90927bcb214729 10.168.235.222:6379@16379 master - 0 1670306292166 3 connected 10923-16383

可以看到3個master,3個slave節點,都是connected狀態。

  • get,set驗證
# 會找到對應的槽進行set操作,去到10.168.235.222節點
set name1 llsydn
-> Redirected to slot [12933] located at 10.168.235.222:6379
OK
​
# set name1成功
10.168.235.222:6379> set name1 llsydn
OK
​
# get name1成功
10.168.235.222:6379> get name1
"llsydn"

master節點進行set操作,slave節點複製。主從複製

1.3重啟pod,驗證叢集(可選)

# redis-1未重啟之前
10.168.235.239:6379> cluster nodes
4367e4a45e557406a3112e7b79f82a44d4ce485e 10.168.235.239:6379@16379 myself,master - 0 1670307319000 2 connected 5461-10922
bcae187137a9b30d7dab8fe0d8ed4a46c6e39638 10.168.235.196:6379@16379 master - 0 1670307319575 1 connected 0-5460
70220b45e978d0cb3df19b07e55d883b49f4127d 10.168.235.238:6379@16379 slave 4367e4a45e557406a3112e7b79f82a44d4ce485e 0 1670307318000 2 connected
122b89a51a9bf005e3d47b6d721c65621d2e9a75 10.168.235.225:6379@16379 slave bcae187137a9b30d7dab8fe0d8ed4a46c6e39638 0 1670307319781 1 connected
c2afcb9e83038a47d04bf328ead8033788548234 10.168.235.198:6379@16379 slave a2cec159bbe2efa11a8f60287b90927bcb214729 0 1670307319071 3 connected
a2cec159bbe2efa11a8f60287b90927bcb214729 10.168.235.222:6379@16379 master - 0 1670307318000 3 connected 10923-16383
​
# 重啟redis-1
kubectl delete pod redis-1 -n jxbp
pod "redis-1" deleted
​
# redis-1重啟之後
10.168.235.239:6379> cluster nodes
4367e4a45e557406a3112e7b79f82a44d4ce485e 10.168.235.239:6379@16379 myself,master - 0 1670307349000 2 connected 5461-10922
bcae187137a9b30d7dab8fe0d8ed4a46c6e39638 10.168.235.196:6379@16379 master - 0 1670307349988 1 connected 0-5460
70220b45e978d0cb3df19b07e55d883b49f4127d 10.168.235.238:6379@16379 slave 4367e4a45e557406a3112e7b79f82a44d4ce485e 0 1670307349000 2 connected
122b89a51a9bf005e3d47b6d721c65621d2e9a75 10.168.235.232:6379@16379 slave bcae187137a9b30d7dab8fe0d8ed4a46c6e39638 0 1670307350089 1 connected
c2afcb9e83038a47d04bf328ead8033788548234 10.168.235.198:6379@16379 slave a2cec159bbe2efa11a8f60287b90927bcb214729 0 1670307350000 3 connected
a2cec159bbe2efa11a8f60287b90927bcb214729 10.168.235.222:6379@16379 master - 0 1670307348000 3 connected 10923-16383

可以看到重啟後的,redis-1節點,雖然ip變了,但是redis叢集,還是可以識別到新的ip,叢集還是正常的。

10.168.235.225 ---> 10.168.235.232

1.4建立Service服務

前面我們建立了用於實現StatefulSet的Headless Service,但該Service沒有Cluster Ip,因此不能用於外界存取。所以,我們還需要建立一個Service,專用於為Redis叢集提供存取和負載均衡。

這裡可以使用ClusterIPNodePort。這裡,我使用的是NodePort

vi redis-ss.yaml

---
apiVersion: v1
kind: Service
metadata:
  labels:
    k8s.kuboard.cn/layer: db
    k8s.kuboard.cn/name: redis
  name: redis-ss
  namespace: jxbp
spec:
  ports:
    - name: imdgss
      port: 6379
      protocol: TCP
      targetPort: 6379
      nodePort: 6379
  selector:
    k8s.kuboard.cn/layer: db
    k8s.kuboard.cn/name: redis
  type: NodePort

建立名稱為:redis-ss的服務。

在K8S叢集中暴露6379埠,並且會對labels namek8s.kuboard.cn/name: redis的pod進行負載均衡。

然後在K8S叢集中,就可以通過redis-ss:6379,對redis叢集進行存取。

kubectl get service -n jxbp
​
>NAME            TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                                                         AGE
redis-hs        ClusterIP   None            <none>        6379/TCP                                                        76m
redis-ss        NodePort    10.96.54.201    <none>        6379:6379/TCP                                                   2s

1.5 Springboot專案設定

spring.redis.cluster.nodes=redis-ss:6379

1.6相關疑問分析

至此,大家可能會疑惑,那為什麼沒有使用穩定的標誌,Redis Pod也能正常進行故障轉移呢?這涉及了Redis本身的機制。因為,Redis叢集中每個節點都有自己的NodeId(儲存在自動生成的nodes.conf中),並且該NodeId不會隨著IP的變化和變化,這其實也是一種固定的網路標誌。也就是說,就算某個Redis Pod重啟了,該Pod依然會載入儲存的NodeId來維持自己的身份。我們可以在NFS上檢視redis-0的nodes.conf檔案:

vi /opt/nfs/pv1/nodes.conf
> f6d4993467a4ab1f3fa806f1122edd39f6466394 10.168.235.228:6379@16379 slave ebed24c8fca9ebc16ceaaee0c2bc2e3e09f7b2c0 0 1670316449064 2 connected
ebed24c8fca9ebc16ceaaee0c2bc2e3e09f7b2c0 10.168.235.240:6379@16379 myself,master - 0 1670316450000 2 connected 5461-10922
955e1236652c2fcb11f47c20a43149dcd1f1f92b 10.168.235.255:6379@16379 master - 0 1670316449565 1 connected 0-5460
574c40485bb8f6cfaf8618d482efb06f3e323f88 10.168.235.224:6379@16379 slave 955e1236652c2fcb11f47c20a43149dcd1f1f92b 0 1670316449000 1 connected
91bd3dc859ce51f1ed0e7cbd07b13786297bd05b 10.168.235.237:6379@16379 slave fe0b74c5e461aa22d4d782f891b78ddc4306eed4 0 1670316450672 3 connected
fe0b74c5e461aa22d4d782f891b78ddc4306eed4 10.168.235.253:6379@16379 master - 0 1670316450068 3 connected 10923-16383
vars currentEpoch 3 lastVoteEpoch 0

如上,第一列為NodeId,穩定不變;第二列為IP和埠資訊,可能會改變。

這裡,我們介紹NodeId的兩種使用場景:

當某個Slave Pod斷線重連後IP改變,但是Master發現其NodeId依舊, 就認為該Slave還是之前的Slave。

當某個Master Pod下線後,叢集在其Slave中選舉重新的Master。待舊Master上線後,叢集發現其NodeId依舊,會讓舊Master變成新Master的slave。

對於這兩種場景,大家有興趣的話還可以自行測試,注意要觀察Redis的紀錄檔。

redis這種有狀態的應用到底應不應該使用k8s部署,還是使用外部伺服器部署redis叢集?

以上就是k8s部署redis叢集搭建過程範例詳解的詳細內容,更多關於k8s部署redis叢集的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com