1. 程式人生 > >docker-compose組建帶密碼redis叢集 完整版

docker-compose組建帶密碼redis叢集 完整版

一 建立檔案結構

  1. 新建redis資料夾
  2. 在redis資料夾下新建docker-compose.yml檔案
  3. 在redis資料夾下新建slave1到slave6共6個資料夾作為從屬結點的資料夾
    這裡寫圖片描述

二 配置redis.conf檔案

# bind 127.0.0.1 //加上註釋#
protected-mode no //關閉保護模式
port 6061  //繫結自定義埠
#daemonize yes //禁止redis後臺執行
pidfile /var/run/redis_6061.pid 
cluster-enabled yes //開啟叢集 把註釋#去掉
cluster-config-file nodes_6061.conf //叢集的配置 配置檔案首次啟動自動生成 

配置檔案是最容易出問題的,這裡面有一些注意事項:

  • requirepass和masterauth不能啟用
    因為使用redis-trib連線叢集時是不能指定密碼的,如果開啟了requirepass或者masterauth會導致叢集連線失敗,所以應該等叢集建立好後再修改密碼,這個後文會說

  • bind
    表示設定redis監聽哪個ip,設定了監聽之後,只有使用這些ip才能訪問這個redis服務,不指定則預設所有ip都能訪問該redis服務
    注意:這裡的ip指的是redis的ip而非訪問方的ip,bind並不直接限制哪些ip能夠訪問redis,顯示ip訪問是限制監聽後的效果,如果想限制ip訪問應使用Linux防火牆功能.
    比方說,在生產條件下的redis伺服器有3個ip(外網ip 122.122.122.122,區域網ip192.128.0.1,本地ip127.0.0.1),則為了安全,bind後面只應該寫區域網ip和本地ip,這樣就只有區域網使用者(包括本機)可以通過192.128.0.1訪問redis服務,間接起到限制ip訪問的作用.

  • protected-mode

    • 作用:
      禁止公網訪問redis cache,加強redis安全的
    • 啟用條件:
      1. 沒有bind IP
      2. 沒有設定requirepass訪問密碼
    • 解釋:
      由於前面提及的原因,保護模式會開啟導致無法通過公網訪問,故這裡需要關閉保護模式,但注意叢集建好後要及時新增密碼,增強安全性
  • daemonize 和 pidfile
    實測開啟守護模式(daemonize yes)容器會啟動失敗,因為是使用docker,所以前臺啟動也沒什麼關係,pidfile的檔名和埠號一致是一個良好的習慣

三 編寫Dockerfile

首先先貼出配置,同樣以6061埠為例

#基礎映象
FROM redis #將自定義conf檔案拷入 COPY redis.conf /usr/local/etc/redis/redis.conf #修復時區 RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime RUN echo 'Asia/Shanghai' >/etc/timezone #修改檔案許可權,使之可以通過config rewrite重寫 RUN chmod 777 /usr/local/etc/redis/redis.conf # Redis客戶端連線埠 EXPOSE 6061 # 叢集匯流排埠:redis客戶端連線的埠 + 10000 EXPOSE 16061 #使用自定義conf啟動 CMD [ "redis-server", "/usr/local/etc/redis/redis.conf" ]

注意:

  1. 叢集匯流排埠
    Redis叢集中每個redis例項(可能一臺機部署多個例項)會使用兩個Tcp埠,一個用於給客戶端(redis-cli或應用程式等)使用的埠,另一個是用於叢集中例項相互通訊的內部匯流排埠,且第二個埠比第一個埠一定大10000.內部匯流排埠通訊使用特殊協議,以便實現叢集內部高頻寬低時延的資料交換。所以配置redis例項時只需要指明第一個埠就可以了。
    但是由於我們使用的是docker,所以要將這個埠暴露出來,否則叢集無法建立(使用redis-trib時會一直顯示Waiting for the cluster to join)
  2. 修改redis.conf檔案許可權,否則後面寫入訪問密碼到檔案的時候會提示Permission denied

四 編寫docker-compose.yml檔案

先貼出配置如下,沒什麼好說的,是最簡單的配置了

redis-slave1:
  build: ./slave1
  ports:
   - 6061:6061
   - 16061:16061
redis-slave2:
  build: ./slave2
  ports:
   - 6062:6062
   - 16062:16062
redis-slave3:
  build: ./slave3
  ports:
   - 6063:6063
   - 16063:16063
redis-slave4:
  build: ./slave4
  ports:
   - 6064:6064
   - 16064:16064
redis-slave5:
  build: ./slave5
  ports:
   - 6065:6065
   - 16065:16065
redis-slave6:
  build: ./slave6
  ports:
   - 6066:6066
   - 16066:16066

五 啟動

在redis目錄下(即docker-compose.yml同級目錄),執行

docker-compose up -d

再檢視容器執行情況

docker ps -a

結果如下
這裡寫圖片描述
這時啟動使用redis客戶端連線測試一下,我這裡使用的是Redis Desktop Manager,注意,此時連線還不需要密碼,十分不安全,以6061埠為例,測試結果如下:
這裡寫圖片描述
可以看到此時請求訪問密碼和訪問master密碼是空白的,另外叢集狀態是失敗
這個時候使用redis會報"CLUSTERDOWN Hash slot not served"錯誤

六 連線叢集

連線叢集非常簡單,不需要去修改什麼配置,只需要一條docker指令

docker run --rm -it zvelo/redis-trib create --replicas 1 ip:6061 ip:6062 ip:6063 ip:6064 ip:6065 ip:6066

ip替換成實際ip地址,結果如下,中間需要用yes來同意叢集方案
結果如下
這裡寫圖片描述

七 驗證叢集

輸入cluster info檢視叢集資訊,此時已為 ok,再測試一下set和get,另外可以看到,結點會自己切換,並且6061埠set和資料可以在6062埠get到
這裡寫圖片描述

八 設定叢集密碼

  1. 使用redis-trib.rb工具構建叢集,叢集構建完成前不要配置密碼,叢集構建完畢再通過config set + config rewrite命令逐個機器設定密碼
  2. 如果對叢集設定密碼,那麼requirepass和masterauth都需要設定,否則發生主從切換時,就會遇到授權問題
  3. 各個節點的密碼都必須一致,否則Redirected就會失敗

具體指令如下:

  • 設定masterauth
config set masterauth 密碼
  • 設定requirepass
config set requirepass 密碼
  • 驗證密碼,以繼續操作
auth LinShen
  • 回寫到檔案,使其永久生效(如果這裡出現Permission denied,則說明Dockerfile少了RUN chmod 777 /usr/local/etc/redis/redis.conf)
config rewrite

如下圖
這裡寫圖片描述
然後再使用docker exec指令進入容器內部看一下masterauth和requirepass是否寫入到檔案裡

docker exec -it 容器ID /bin/bash

cat指令檢視

cat /usr/local/etc/redis/redis.conf

得到如下圖
這裡寫圖片描述
可以看到masterauth和requirepass被追加到檔案的最後,即使重啟密碼也還生效

至此,利用docker-compose組建redis叢集結束

可以看到,其實docker-compose起的作用並不大,因為在單機上部署redis叢集確實沒什麼實際意義,但是,你完全可以把slave結點放到不同的伺服器上,再通過docker的redis-trib容器來連線,十分靈活和方便.