首頁 > 軟體

k8s部署redis叢集實現過程範例詳解

2023-02-24 06:03:02

寫在前面

一般來說,REDIS部署有三種模式。

  • 單範例模式,一般用於測試環境。
  • 哨兵模式
  • 叢集模式

後兩者用於生產部署

  • 哨兵模式

在redis3.0以前,要實現叢集一般是藉助哨兵sentinel工具來監控master節點的狀態。

如果master節點異常,則會做主從切換,將某一臺slave作為master。

引入了哨兵節點,部署更復雜,維護成本也比較高,並且效能和高可用性等各方面表現一般。

  • 叢集模式

3.0 後推出的 Redis 分散式叢集解決方案

主節點提供讀寫操作,從節點作為備用節點,不提供請求,只作為故障轉移使用

如果master節點異常,也是會自動做主從切換,將slave切換為master。

總的來說,叢集模式明顯優於哨兵模式

那麼今天我們就來講解下:k8s環境下,如何部署redis叢集(三主三從)?

前置準備

一、nfs安裝

  • nfs
# 伺服器端
# 1.安裝
yum -y install nfs-utils # nfs檔案系統
yum -y install rpcbind   # rpc協定
# 2.設定(需要共用的資料夾)
vi /etc/exports
/opt/nfs/pv1 *(rw,sync,no_subtree_check,no_root_squash)
/opt/nfs/pv2 *(rw,sync,no_subtree_check,no_root_squash)
/opt/nfs/pv3 *(rw,sync,no_subtree_check,no_root_squash)
/opt/nfs/pv4 *(rw,sync,no_subtree_check,no_root_squash)
/opt/nfs/pv5 *(rw,sync,no_subtree_check,no_root_squash)
/opt/nfs/pv6 *(rw,sync,no_subtree_check,no_root_squash)
# 3.建立資料夾
mkdir -p /opt/nfs/pv{1..6}
# 4.更新設定並重啟nfs服務
exportfs -r  #更新設定
systemctl restart rpcbind
systemctl restart nfs
systemctl enable nfs  #開機啟動
systemctl enable rpcbind
# 5.驗證
showmount -e 192.168.4.xx #伺服器端驗證NFS共用
	> Export list for 192.168.4.xx:
	/opt/nfs/pv6 *
        /opt/nfs/pv5 *
        /opt/nfs/pv4 *
        /opt/nfs/pv3 *
        /opt/nfs/pv2 *
        /opt/nfs/pv1 *
rpcinfo -p #檢視埠
# 使用者端
yum -y install nfs-utils
systemctl restart nfs
systemctl enable nfs  #開機啟動

這裡說一下,為什麼要安裝nfs?

是為了下面建立SC,PV做準備,PV需要使用nfs伺服器。

二、SC、PV 建立

2.1建立SC

StorageClass:簡稱sc,儲存類,是k8s平臺為儲存提供商提供儲存接入的一種宣告。通過sc和相應的儲存外掛(csi)為容器應用提供持久儲存卷的能力。

vi redis-sc.yaml

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: redis-sc
provisioner: nfs-storage

名稱為redis-sc

執行建立sc:

kubectl apply -f redis-sc.yaml
> storageclass.storage.k8s.io/redis-sc created

通過kuboard檢視:

2.2建立PV

PersistentVolume簡稱pv,持久化儲存,是k8s為雲原生應用提供一種擁有獨立生命週期的、使用者可管理的儲存的抽象設計。

vi redis-pv.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv1
spec:
  storageClassName: redis-sc
  capacity:
    storage: 200M
  accessModes:
    - ReadWriteMany
  nfs:
    server: 192.168.4.xx
    path: "/opt/nfs/pv1"

名稱為nfs-pv1,對應的storageClassName為redis-sc,capacity容器200M,accessModes存取模式可被多節點讀寫

對應nfs伺服器192.168.4.xx,對應資料夾路徑/opt/nfs/pv1(對應上面安裝nfs伺服器)

以此類推,我們建立6個pv......

執行建立sc:

kubectl apply -f redis-pv.yaml
> persistentvolume/nfs-pv1 created
  persistentvolume/nfs-pv2 created
  persistentvolume/nfs-pv3 created
  persistentvolume/nfs-pv4 created
  persistentvolume/nfs-pv5 created
  persistentvolume/nfs-pv6 created

通過kuboard檢視:

通過kubectl檢視:kubectl get sckubectl get pv

這裡說一下,為什麼要建立SC,PV?

因為redis叢集,最終需要對應的檔案有,redis.confnodes.confdata

由此可見,這些檔案每個節點,都得對應有自己得資料夾。

當然redis.conf可以是一個相同得,其他兩個,就肯定是不一樣得。

如果使用掛載資料夾即是 Volume 的情況部署一個pod,很明顯,是不能滿足的。

當然,你部署多個不一樣的pod,也是可以做到,但是就得寫6個部署yaml檔案,後期維護也很複雜。

最好的效果是,寫一個部署yaml檔案,然後有6個replicas副本,就對應了我們redis叢集(三主三從)。

那一個pod,再使用Volume掛載資料夾,這個只能是一個資料夾,是無法做到6個pod對應不同的資料夾。

所以這裡,就引出了SCPV了。

使用SCPV就可以實現,這6個pod啟動,就對應上我們建立的6個PV,那就實現了redis.confnodes.confdata,這三個檔案,存放的路徑,就是不一樣的路徑了。

哈哈,說了,那麼多,不知道,大家明不明白,不明白的可以繼續往下看,或者自己部署實操一下,估計你就能明白,為啥要這麼幹了?

三、redis叢集搭建

RC、Deployment、DaemonSet都是面向無狀態的服務,它們所管理的Pod的IP、名字,啟停順序等都是隨機的,而StatefulSet是什麼?顧名思義,有狀態的集合,管理所有有狀態的服務,比如MySQL、MongoDB叢集等。

StatefulSet本質上是Deployment的一種變體,在v1.9版本中已成為GA版本,它為了解決有狀態服務的問題,它所管理的Pod擁有固定的Pod名稱啟停順序,在StatefulSet中,Pod名字稱為網路標識(hostname),還必須要用到共用儲存。

在Deployment中,與之對應的服務是service,而在StatefulSet中與之對應的headless service,headless service,即無頭服務,與service的區別就是它沒有Cluster IP,解析它的名稱時將返回該Headless Service對應的全部Pod的Endpoint列表。

除此之外,StatefulSet在Headless Service的基礎上又為StatefulSet控制的每個Pod副本建立了一個DNS域名,這個域名的格式為:

$(pod.name).$(headless server.name).${namespace}.svc.cluster.local

也即是說,對於有狀態服務,我們最好使用固定的網路標識(如域名資訊)來標記節點,當然這也需要應用程式的支援(如Zookeeper就支援在組態檔中寫入主機域名)。

StatefulSet基於Headless Service(即沒有Cluster IP的Service)為Pod實現了穩定的網路標誌(包括Pod的hostname和DNS Records),在Pod重新排程後也保持不變。同時,結合PV/PVC,StatefulSet可以實現穩定的持久化儲存,就算Pod重新排程後,還是能存取到原先的持久化資料。

以下為使用StatefulSet部署Redis的架構,無論是Master還是Slave,都作為StatefulSet的一個副本,並且資料通過PV進行持久化,對外暴露為一個Service,接受使用者端請求。

3.1建立headless服務

Headless service是StatefulSet實現穩定網路標識的基礎。

vi redis-hs.yaml

---
apiVersion: v1
kind: Service
metadata:
  labels:
    k8s.kuboard.cn/layer: db
    k8s.kuboard.cn/name: redis
  name: redis-hs
  namespace: jxbp
spec:
  ports:
    - name: nnbary
      port: 6379
      protocol: TCP
      targetPort: 6379
  selector:
    k8s.kuboard.cn/layer: db
    k8s.kuboard.cn/name: redis
  clusterIP: None

名稱空間為:jxbp,名稱為:redis-hs

執行:

kubectl apply -f redis-hs.yaml
> service/redis-hs created

網路存取:pod名稱.headless名稱.namespace名稱.svc.cluster.local

即:pod名稱.redis-hs.jxbp.svc.cluster.local

3.2建立redis對應pod叢集

建立好Headless service後,就可以利用StatefulSet建立Redis 叢集節點,這也是本文的核心內容。

vi redis.yaml

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis
  namespace: jxbp
  labels:
    k8s.kuboard.cn/layer: db
    k8s.kuboard.cn/name: redis
spec:
  replicas: 6
  selector:
    matchLabels:
      k8s.kuboard.cn/layer: db
      k8s.kuboard.cn/name: redis
  serviceName: redis
  template:
    metadata:
      labels:
        k8s.kuboard.cn/layer: db
        k8s.kuboard.cn/name: redis
    spec:
      terminationGracePeriodSeconds: 20
      containers:
        - name: redis
          image: 192.168.4.xx/jxbp/redis:6.2.6
          ports:
            - name: redis
              containerPort: 6379
              protocol: "TCP"
            - name: cluster
              containerPort: 16379
              protocol: "TCP"
          volumeMounts:
            - name: "redis-conf"
              mountPath: "/etc/redis/redis.conf"
            - name: "redis-data"
              mountPath: "/data"
      volumes:
        - name: "redis-conf"
          hostPath:
            path: "/opt/redis/conf/redis.conf"
            type: FileOrCreate
  volumeClaimTemplates:
    - metadata:
        name: redis-data
      spec:
        accessModes: [ "ReadWriteMany" ]
        resources:
          requests:
            storage: 200M
        storageClassName: redis-sc

名稱為:redis,對應的映象為:redis:6.2.6

掛載的檔案:宿主機的/opt/redis/conf/redis.conf到redis容器的/etc/redis/redis.conf(redis.conf組態檔如下所示)

PVC儲存卷宣告模板volumeClaimTemplates,指定了名稱為redis-sc的SC(storageClassName)

由於之前SC繫結了PV,所以這裡的PVC和PV,就能一 一對應繫結上了。

PV和PVC的關係,是一 一系結的。如果這裡不指定SC,那就會導致,PVC繫結PV,是一個混亂的過程,隨機繫結PV了。

  • redis.conf
# 一般設定
bind 0.0.0.0
port 6379
daemonize no
requirepass jxbd
# 叢集設定
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000

執行:

kubectl apply -f redis.yaml

由上操作,我們已經建立好redis的6個副本了。

因為k8s部署redis叢集的篇幅,有點長

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


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