docker-compose組建帶密碼redis叢集 完整版
一 建立檔案結構
- 新建redis資料夾
- 在redis資料夾下新建docker-compose.yml檔案
- 在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安全的 - 啟用條件:
- 沒有bind IP
- 沒有設定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" ]
注意:
- 叢集匯流排埠
Redis叢集中每個redis例項(可能一臺機部署多個例項)會使用兩個Tcp埠,一個用於給客戶端(redis-cli或應用程式等)使用的埠,另一個是用於叢集中例項相互通訊的內部匯流排埠,且第二個埠比第一個埠一定大10000.內部匯流排埠通訊使用特殊協議,以便實現叢集內部高頻寬低時延的資料交換。所以配置redis例項時只需要指明第一個埠就可以了。
但是由於我們使用的是docker,所以要將這個埠暴露出來,否則叢集無法建立(使用redis-trib時會一直顯示Waiting for the cluster to join
) - 修改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到
八 設定叢集密碼
- 使用redis-trib.rb工具構建叢集,叢集構建完成前不要配置密碼,叢集構建完畢再通過config set + config rewrite命令
逐個機器
設定密碼 - 如果對叢集設定密碼,那麼
requirepass和masterauth
都需要設定,否則發生主從切換時,就會遇到授權問題 - 各個節點的
密碼都必須一致
,否則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容器來連線,十分靈活和方便.