k8s環(huán)境下單節(jié)點運行Redis集群

單機(jī)下用Redis二進(jìn)制程序包搭建Redis集群的案例很多,用docker在單節(jié)點上搭集群的也很多撼短,但是在k8s下單節(jié)點搭集群的就很少了平匈,有的只是掛載一個臨時目錄,數(shù)據(jù)無法持久化,pod銷毀后吧碾,數(shù)據(jù)就沒了凰盔。在k8s環(huán)境下測試機(jī)又不夠的情況下使用Redis集群就不太方便了,本文就是筆者的根據(jù)自身需要實踐出來的倦春,期間也找了很多網(wǎng)上資料户敬,最后自己綜合琢磨出的解決方案,由于對docker和k8s不是很精通睁本,可能有其他更簡單的方案尿庐,歡迎大家交流。

一呢堰、所需的背景知識

1抄瑟、對docker,k8s有一定使用經(jīng)驗:會編寫yaml文件枉疼,知道如何排查pod不能running的問題
2皮假、在單機(jī)環(huán)境下搭建過Redis集群
3、如果以上的知識都不知道也沒關(guān)系骂维,本文盡量保證你按照步驟執(zhí)行不出錯惹资。但是k8s環(huán)境你必須得有,基本的linux命令知識得有

二航闺、軟件版本

k8s v1.10.2
docker 18.03.1-ce, build 9ee9f40
Redis5.0.5

三褪测、準(zhǔn)備工作

 docker pull redis:5.0.5
 mkdir redis-cluster
 cd redis-cluster/
 mkdir data

創(chuàng)建多個節(jié)點的數(shù)據(jù)存儲目錄,避免Redis實例啟動時配置文件沖突導(dǎo)致無法啟動潦刃,在單臺物理機(jī)上搭建過Redis集群的應(yīng)該知道侮措。建好6個節(jié)點的目錄,后面會用到乖杠,這里的目錄要注意權(quán)限問題萝毛,k8s啟動的pod需要讀寫這里的文件夾

for port in `seq 7001 7006`; do \
  mkdir -p ./${port}/
done

創(chuàng)建完成后目錄結(jié)構(gòu)

目錄結(jié)構(gòu)

四、編輯yaml文件

創(chuàng)建k8s的yaml文件
回到redis-cluster目錄下

1滑黔、創(chuàng)建ConfigMap

先創(chuàng)建redis.conf配置文件
vi redis-cm.yaml
將以下內(nèi)容貼到文件中笆包,保存退出

apiVersion: v1
kind: ConfigMap
metadata:
 name: redis-conf
data:
 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

2环揽、創(chuàng)建statefulset

vi redis-statefulset.yaml

apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
  name: redis-app
spec:
  serviceName: "redis-service"
  replicas: 6
  template:
    metadata:
      labels:
        app: redis
        appCluster: redis-cluster
    spec:
      nodeSelector:
        node: mfc    # 這里需要根據(jù)自己的k8s節(jié)點情況修改,本案例需修改成node-222
      terminationGracePeriodSeconds: 20
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - redis
              topologyKey: kubernetes.io/hostname
      containers:
      - name: redis
        image: "redis:latest"
        imagePullPolicy: IfNotPresent #默認(rèn)情況是會根據(jù)配置文件中的鏡像地址去拉取鏡像庵佣,配置為本地有鏡像不拉取遠(yuǎn)程歉胶,避免你的環(huán)境不能訪問外網(wǎng),拉取鏡像失敗
        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"
  volumeClaimTemplates:   #可看作pvc的模板
    - metadata:
      name: redis-data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi

3巴粪、創(chuàng)建pv的yaml文件

vi pv1.yaml

kind: PersistentVolume
apiVersion: v1
metadata:
  name: redis-pv-volume1
  labels:
    type: local
spec:
  capacity:
    storage: 2Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: /home/bboss/redis-cluster/data/7001/

/home/bboss/redis-cluster/data/7001/此目錄為前面我們創(chuàng)建的redis數(shù)據(jù)存儲的6個目錄
將此文件復(fù)制5份通今,依次命名為pv2.yaml 到pv6.yaml
在對應(yīng)的文件中將

name: redis-pv-volume1
path: /home/bboss/redis-cluster/data/7001/

這2處修改為對應(yīng)文件編號的序號,例如pv2.yaml修改為

name: redis-pv-volume2
path: /home/bboss/redis-cluster/data/7002/

五肛根、開始搭建集群

1辫塌、創(chuàng)建cm和pv如下圖

km create -f redis-cm.yaml
km create -f pv1.yaml
image.png

2、創(chuàng)建statefulset

確定當(dāng)前宿主機(jī)在k8s集群中的label

kubectl get nodes --show-labels
k8s集群機(jī)器ip和對應(yīng)的label

如圖派哲,我當(dāng)前部署的機(jī)器ip是222對應(yīng)的node標(biāo)簽名為node-222
將redis-statefulset.yaml文件中node: mfc 修改為 node: node-222臼氨,稍后啟動redis的pod是都會選擇在node-222這個節(jié)點的機(jī)器上啟動,這正是我們需要的芭届,修改正確后

km create -f redis-statefulset.yaml

[注:我這里km是做了配置储矩,km相當(dāng)于是kubectl -n mfc-namespace 這是指定k8s的namespace的,我的namespace名是mfc-namespace褂乍,kubectl命令不指定-n 默認(rèn)是使用default為名的namespace]

kubectl get pods  -n mfc-namespace | grep redis 

查看6個redis節(jié)點是否都啟動完成

查看一下pod對應(yīng)的ip持隧,下一步配置集群需要知道各節(jié)點的ip,這ip是k8s分配的

kubectl get pods -o wide -n mfc-namespace | grep redis

驗證一下pvc是否都bound了

kubectl get pvc -o wide -n mfc-namespace
redis節(jié)點的ip

3逃片、初始化Redis集群

啟動一個獨立的redis

docker run -it redis:latest bash
redis-cli --cluster create 10.254.79.20:6379 10.254.79.21:6379 10.254.79.22:6379 10.254.79.23:6379 10.254.79.24:6379 10.254.79.25:6379 --cluster-replicas 1
初始化Redis集群
接上圖

4屡拨、驗證Redis集群

日志顯示集群已經(jīng)初始化好幢哨,slots也分配完成承耿,驗證一下集群
用redis-cli隨便連接某個redis節(jié)點

/usr/local/bin/redis-cli -c -h 10.254.79.20 -p 6379
驗證集群

搭建完成了,下面來看看本地存儲的數(shù)據(jù)
隨便進(jìn)到某個目錄下看看,如下圖redis集群的數(shù)據(jù)已經(jīng)落到物理機(jī)上了缕棵。

3號節(jié)點的數(shù)據(jù)文件

驗證一下pod重啟后集群數(shù)據(jù)是否還在

重啟Redis集群

看ip還是原來的ip性锭,這就是k8s定義statefulset的作用
通過剛才啟動的獨立redis再次連接集群看數(shù)據(jù)還在不在赠潦,如下圖數(shù)據(jù)都還在

驗證集群中已數(shù)據(jù)是否還在,如圖數(shù)據(jù)都還在

5、創(chuàng)建headlessService

到這里我們的Redis集群已經(jīng)是完全可用的了草冈,但是我們的應(yīng)用要使用該集群時配置ip不好記她奥,這時就需要用到k8s中的Service
vi redis-headlessService.yaml

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

執(zhí)行 km create -f redis-headlessService.yaml 創(chuàng)建服務(wù)
查看服務(wù)

查看redis-service服務(wù)

另外用k8s啟一個有nslookup或者ping工具的pod,驗證一下服務(wù)名是否可以訪問

驗證服務(wù)名

k8s是自帶dns功能的怎棱,k8s會根據(jù)serviceName生成對應(yīng)的域名
如上圖哩俭,可以看到節(jié)點1 (10.254.79.20)的完整域名是redis-app-0.redis-service.mfc-namespace.svc.cluster.local,在k8s中同一個namespace的服務(wù)只需要前面的子域名即可拳恋,后面的會默認(rèn)補齊凡资,本例中的serviceName是redis-app-0.redis-service,這是一個節(jié)點的服務(wù)名。對于整個集群的serviceName是redis-service

用剛才的docker啟動的redis驗證一下域名是否可以連接,如下圖用域名連接失敗隙赁,因為我們這個是用docker啟動的不在k8s中垦藏,用pod的ip是可以連接的,因為pod的ip訪問是走docker的網(wǎng)絡(luò)伞访。因為服務(wù)名是k8s做的路由掂骏,所以必須在k8s集群中注冊才可以使用服務(wù)名互相訪問。serviceName其實是在操作系統(tǒng)中做了一個轉(zhuǎn)發(fā)的動作厚掷,通過iptales做策略實現(xiàn)的弟灼。

用域名連接失敗

用redis集群中的任意一個節(jié)點驗證,域名是可以訪問的

用redis集群中的節(jié)點驗證

六冒黑、總結(jié)

網(wǎng)上大部分文章都是類似的方案田绑,使用pv,pvc做存儲抡爹,有的pv是綁定的nfs掩驱,我也試過nfs碰到問題沒解決只能想其他辦法,但是我理解的是如果6個redis節(jié)點的配置文件nodes.conf和數(shù)據(jù)文件都在共享一個目錄豁延,那還是會有沖突昙篙,導(dǎo)致redis只能啟動一個節(jié)點腊状,而其他節(jié)點無法啟動诱咏,除非能把文件命名定義成不同節(jié)點對應(yīng)不同的文件名,因為沒搭成功基于nfs的pvc存儲缴挖,不知道是不是每個節(jié)點一個隔離的pvc袋狞,所以無法知道以后會再實踐。所以本例主要是通過定義不同的pv把目錄隔離開映屋,但是定義StatefulSet時不好指定pvc苟鸯,看到有文章用到volumeClaimTemplates(可看作pvc的模板)傳輸門于是問題就應(yīng)然而解了,StatefulSet在創(chuàng)建pod時是前一個創(chuàng)建成功才繼續(xù)下一個是有順序的,同時創(chuàng)建pvc也是有順序的棚点,每個pvc綁定一個pv早处,這樣6個節(jié)點的數(shù)據(jù)文件就自動綁定到各自的目錄下了。
另外redis集群初始化不需要Ruby了瘫析,避免了安裝ruby的麻煩砌梆。

七、參考資料

[https://www.cnblogs.com/tylerzhou/p/11027559.html]
[https://v1-12.docs.kubernetes.io/zh/docs/tasks/run-application/force-delete-stateful-set-pod/]
[https://juejin.im/post/5d206b1e5188252f275fdc95]
[https://www.cnblogs.com/breezey/p/6582082.html]
[https://juejin.im/post/5c989ff2f265da60f206ffe4#heading-7]
[http://www.reibang.com/p/a5172b0eeae4]
https://www.cnblogs.com/xiaochangwei/p/7993065.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末贬循,一起剝皮案震驚了整個濱河市咸包,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌杖虾,老刑警劉巖烂瘫,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異奇适,居然都是意外死亡坟比,警方通過查閱死者的電腦和手機(jī)芦鳍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來温算,“玉大人怜校,你說我怎么就攤上這事∽⒏停” “怎么了茄茁?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長巩割。 經(jīng)常有香客問我裙顽,道長,這世上最難降的妖魔是什么宣谈? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任愈犹,我火速辦了婚禮,結(jié)果婚禮上闻丑,老公的妹妹穿的比我還像新娘漩怎。我一直安慰自己,他們只是感情好嗦嗡,可當(dāng)我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布勋锤。 她就那樣靜靜地躺著,像睡著了一般侥祭。 火紅的嫁衣襯著肌膚如雪叁执。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天矮冬,我揣著相機(jī)與錄音谈宛,去河邊找鬼。 笑死胎署,一個胖子當(dāng)著我的面吹牛吆录,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播琼牧,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼恢筝,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了障陶?” 一聲冷哼從身側(cè)響起滋恬,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎抱究,沒想到半個月后恢氯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年勋拟,在試婚紗的時候發(fā)現(xiàn)自己被綠了勋磕。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡敢靡,死狀恐怖挂滓,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情啸胧,我是刑警寧澤赶站,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站纺念,受9級特大地震影響贝椿,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜陷谱,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一烙博、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧烟逊,春花似錦渣窜、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至眷唉,卻和暖如春予颤,著一層夾襖步出監(jiān)牢的瞬間囤官,已是汗流浹背冬阳。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留党饮,地道東北人肝陪。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像刑顺,于是被迫代替她去往敵國和親氯窍。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,916評論 2 344