<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          在Kubernetes上部署一套 Redis 集群

          共 5463字,需瀏覽 11分鐘

           ·

          2021-12-31 21:23


          今天讓我們試著在k8s里部署一個redis集群,了解更多k8s的細(xì)節(jié)和特性。

          注:redis-cluster相關(guān)的背景知識和細(xì)節(jié)在此不做贅述

          一、問題分析

          本質(zhì)上來說,在k8s上部署一個redis集群和部署一個普通應(yīng)用沒有什么太大的區(qū)別,但需要注意下面幾個問題:

          1. Redis是一個有狀態(tài)應(yīng)用

            這是部署redis集群時我們最需要注意的問題,當(dāng)我們把redis以pod的形式部署在k8s中時,每個pod里緩存的數(shù)據(jù)都是不一樣的,而且pod的IP是會隨時變化,這時候如果使用普通的deployment和service來部署redis-cluster就會出現(xiàn)很多問題,因此需要改用StatefulSet + Headless Service來解決

          2. 數(shù)據(jù)持久化

            redis雖然是基于內(nèi)存的緩存,但還是需要依賴于磁盤進行數(shù)據(jù)的持久化,以便服務(wù)出現(xiàn)問題重啟時可以恢復(fù)已經(jīng)緩存的數(shù)據(jù)。在集群中,我們需要使用共享文件系統(tǒng) + PV(持久卷)的方式來讓整個集群中的所有pod都可以共享同一份持久化儲存

          二、概念介紹

          在開始之前先來詳細(xì)介紹一下幾個概念和原理。

          1、Headless Service

          簡單的說,Headless Service就是沒有指定Cluster IP的Service,相應(yīng)的,在k8s的dns映射里,Headless Service的解析結(jié)果不是一個Cluster IP,而是它所關(guān)聯(lián)的所有Pod的IP列表

          2、StatefulSet

          StatefulSet是k8s中專門用于解決有狀態(tài)應(yīng)用部署的一種資源,總的來說可以認(rèn)為它是Deployment/RC的一個變種,它有以下幾個特性:

          1. StatefulSet管理的每個Pod都有唯一的文檔/網(wǎng)絡(luò)標(biāo)識,并且按照數(shù)字規(guī)律生成,而不是像Deployment中那樣名稱和IP都是隨機的(比如StatefulSet名字為redis,那么pod名就是redis-0, redis-1 ...)

          2. StatefulSet中ReplicaSet的啟停順序是嚴(yán)格受控的,操作第N個pod一定要等前N-1個執(zhí)行完才可以

          3. StatefulSet中的Pod采用穩(wěn)定的持久化儲存,并且對應(yīng)的PV不會隨著Pod的刪除而被銷毀

          另外需要說明的是,StatefulSet必須要配合Headless Service使用,它會在Headless Service提供的DNS映射上再加一層,最終形成精確到每個pod的域名映射,格式如下:

          $(podname).$(headless service name)

          有了這個映射,就可以在配置集群時使用域名替代IP,實現(xiàn)有狀態(tài)應(yīng)用集群的管理

          三、方案

          借助StatefulSet和Headless Service,集群的部署方案設(shè)計如下(圖片來自參考文章):

          配置步驟大概羅列如下:

          1. 配置共享文件系統(tǒng)NFS

          2. 創(chuàng)建PV和PVC

          3. 創(chuàng)建ConfigMap

          4. 創(chuàng)建Headless Service

          5. 創(chuàng)建StatefulSet

          6. 初始化redis集群

          實際操作

          為了簡化復(fù)雜度,這次先不配置PV和PVC,直接通過普通Volume的方式來掛載數(shù)據(jù)。在K8s上搭建Mysql集群

          1、創(chuàng)建ConfigMap

          先創(chuàng)建redis.conf配置文件

          appendonly yes
          cluster-enabled yes
          cluster-config-file /var/lib/redis/nodes.conf
          cluster-node-timeout 5000
          dir /var/lib/redis
          port 6379

          然后kubectl create configmap redis-conf --from-file=redis.conf來創(chuàng)建ConfigMap

          2、創(chuàng)建HeadlessService

          apiVersion: v1
          kind: Service
          metadata:
          name: redis-service
          labels:
          app: redis
          spec:
          ports:
          - name: redis-port
          port: 6379
          clusterIP: None
          selector:
          app: redis
          appCluster: redis-cluster

          3、創(chuàng)建StatefulSet

          apiVersion: apps/v1beta1
          kind: StatefulSet
          metadata:
          name: redis-app
          spec:
          serviceName: "redis-service"
          replicas: 6
          template:
          metadata:
          labels:
          app: redis
          appCluster: redis-cluster
          spec:
          terminationGracePeriodSeconds: 20
          affinity:
          podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
          podAffinityTerm:
          labelSelector:
          matchExpressions:
          - key: app
          operator: In
          values:
          - redis
          topologyKey: kubernetes.io/hostname
          containers:
          - name: redis
          image: "registry.cn-qingdao.aliyuncs.com/gold-faas/gold-redis:1.0"
          command:
          - "redis-server"
          args:
          - "/etc/redis/redis.conf"
          - "--protected-mode"
          - "no"
          resources:
          requests:
          cpu: "100m"
          memory: "100Mi"
          ports:
          - name: redis
          containerPort: 6379
          protocol: "TCP"
          - name: cluster
          containerPort: 16379
          protocol: "TCP"
          volumeMounts:
          - name: "redis-conf"
          mountPath: "/etc/redis"
          - name: "redis-data"
          mountPath: "/var/lib/redis"
          volumes:
          - name: "redis-conf"
          configMap:
          name: "redis-conf"
          items:
          - key: "redis.conf"
          path: "redis.conf"
          - name: "redis-data"
          emptyDir: {}

          4、初始化redis集群

          StatefulSet創(chuàng)建完畢后,可以看到6個pod已經(jīng)啟動了,但這時候整個redis集群還沒有初始化,需要使用官方提供的redis-trib工具。

          我們當(dāng)然可以在任意一個redis節(jié)點上運行對應(yīng)的工具來初始化整個集群,但這么做顯然有些不太合適,我們希望每個節(jié)點的職責(zé)盡可能地單一,所以最好單獨起一個pod來運行整個集群的管理工具。

          在這里需要先介紹一下redis-trib,它是官方提供的redis-cluster管理工具,可以實現(xiàn)redis集群的創(chuàng)建、更新等功能,在早期的redis版本中,它是以源碼包里redis-trib.rb這個ruby腳本的方式來運作的(pip上也可以拉到python版本,但我運行失敗),現(xiàn)在(我使用的5.0.3)已經(jīng)被官方集成進redis-cli中。

          開始初始化集群,首先在k8s上創(chuàng)建一個ubuntu的pod,用來作為管理節(jié)點:

          kubectl run -i --tty redis-cluster-manager --image=ubuntu --restart=Never /bin/bash

          進入pod內(nèi)部先安裝一些工具,包括wget,dnsutils,然后下載和安裝redis:

          wget http://download.redis.io/releases/redis-5.0.3.tar.gz
          tar -xvzf redis-5.0.3.tar.gz
          cd redis-5.0.3.tar.gz && make

          編譯完畢后redis-cli會被放置在src目錄下,把它放進/usr/local/bin中方便后續(xù)操作

          接下來要獲取已經(jīng)創(chuàng)建好的6個節(jié)點的host ip,可以通過nslookup結(jié)合StatefulSet的域名規(guī)則來查找,舉個例子,要查找redis-app-0這個pod的ip,運行如下命令:

          root@redis-cluster-manager:/# nslookup redis-app-0.redis-service
          Server: 10.96.0.10
          Address: 10.96.0.10#53

          Name: redis-app-0.redis-service.gold.svc.cluster.local
          Address: 172.17.0.10

          172.17.0.10就是對應(yīng)的ip。這次部署我們使用0,1,2作為Master節(jié)點;3,4,5作為Slave節(jié)點,先運行下面的命令來初始化集群的Master節(jié)點:

          redis-cli --cluster create 172.17.0.10:6379 172.17.0.11:6379 172.17.0.12:6379

          然后給他們分別附加對應(yīng)的Slave節(jié)點,這里的cluster-master-id在上一步創(chuàng)建的時候會給出:

          redis-cli --cluster add-node 172.17.0.13:6379 172.17.0.10:6379 --cluster-slave --cluster-master-id adf443a4d33c4db2c0d4669d61915ae6faa96b46
          redis-cli --cluster add-node 172.17.0.14:6379 172.17.0.11:6379 --cluster-slave --cluster-master-id 6e5adcb56a871a3d78343a38fcdec67be7ae98f8
          redis-cli --cluster add-node 172.17.0.16:6379 172.17.0.12:6379 --cluster-slave --cluster-master-id c061e37c5052c22f056fff2a014a9f63c3f47ca0

          集群初始化后,隨意進入一個節(jié)點檢查一下集群信息:

          至此,集群初始化完畢,我們進入一個節(jié)點來試試,注意在集群模式下redis-cli必須加上-c參數(shù)才能夠訪問其他節(jié)點上的數(shù)據(jù):

          5、創(chuàng)建Service

          現(xiàn)在進入redis集群中的任意一個節(jié)點都可以直接進行操作了,但是為了能夠?qū)浩渌姆?wù)提供訪問,還需要建立一個service來實現(xiàn)服務(wù)發(fā)現(xiàn)和負(fù)載均衡(注意這里的service和我們之前創(chuàng)建的headless service不是一個東西)

          yaml文件如下:

          apiVersion: v1
          kind: Service
          metadata:
          name: gold-redis
          labels:
          app: redis
          spec:
          ports:
          - name: redis-port
          protocol: "TCP"
          port: 6379
          targetPort: 6379
          selector:
          app: redis
          appCluster: redis-cluster

          部署完做個測試:

          很nice,到這里所有的工作就完畢了~

          文章轉(zhuǎn)載:Devops技術(shù)棧
          (版權(quán)歸原作者所有,侵刪)


          點擊下方“閱讀原文”查看更多

          瀏覽 53
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  免费精品99 | 日日骚av一区二区三区 | 亚洲视频第1页 | 蜜乳一区二区三区精品 | 亚洲中文无 |