Kubernetes環(huán)境部署Redis集群過程
Kubernetes環(huán)境部署Redis集群
一、Redis 版本推薦:優(yōu)先選擇 7.0 + 版本
在 Kubernetes 環(huán)境部署 Redis Cluster 時(shí),建議優(yōu)先選用 Redis 7.0 及以上版本。核心原因在于版本功能對(duì) K8s 動(dòng)態(tài) 網(wǎng)絡(luò)環(huán)境的適配性差異:
Redis 7.0 之前的版本,使用redis-cli組建集群時(shí)存在局限性 —— 僅支持通過 “IP + 端口” 的形式指定節(jié)點(diǎn)地址,無法識(shí)別 Kubernetes 中 Pod 的名稱(或 Pod 域名)。
而 K8s 環(huán)境中,Pod 重啟(如故障恢復(fù)、配置更新)后會(huì)分配新的 IP 地址,若集群依賴固定 IP,IP變更會(huì)直接導(dǎo)致節(jié)點(diǎn)失聯(lián)、集群拓?fù)浠靵y,最終引發(fā)集群失效。
二、K8s 環(huán)境必配參數(shù):cluster-announce-ip
無論選用哪個(gè)版本,在 Kubernetes 環(huán)境部署 Redis Cluster 時(shí),必須額外配置cluster-announce-ip參數(shù),明確節(jié)點(diǎn)的 “穩(wěn)定通告地址”(通常為 Pod 域名,如$(POD_NAME).$(SERVICE_NAME))。
配置字典
kind: ConfigMap
apiVersion: v1
metadata:
name: redis-cluster-cm
data:
init-redis-cluster.sh: |2-
#!/bin/bash
set -e
# 直接在腳本中聲明變量
REDIS_PASSWORD="ClusterRedis#20251112"
SERVICE_NAME="redis-cluster"
NODES=(
"redis-cluster-0.$SERVICE_NAME:6379"
"redis-cluster-1.$SERVICE_NAME:6379"
"redis-cluster-2.$SERVICE_NAME:6379"
"redis-cluster-3.$SERVICE_NAME:6379"
"redis-cluster-4.$SERVICE_NAME:6379"
"redis-cluster-5.$SERVICE_NAME:6379"
)
echo "檢查所有 Redis 節(jié)點(diǎn)是否就緒..."
all_ready=1
for node in "${NODES[@]}"; do
host=$(echo "$node" | cut -d: -f1)
port=$(echo "$node" | cut -d: -f2)
echo "檢查節(jié)點(diǎn): $host:$port"
if [ "$(redis-cli -h $host -p $port -a $REDIS_PASSWORD ping 2>/dev/null)" != "PONG" ]; then
echo "節(jié)點(diǎn) $node 未就緒"
all_ready=0
break
else
echo "節(jié)點(diǎn) $node 已就緒"
fi
done
if [ $all_ready -ne 1 ]; then
echo "有節(jié)點(diǎn)未就緒,退出"
exit 0
fi
echo "檢查集群狀態(tài)..."
cluster_state=$(redis-cli -h ${NODES[0]%:*} -p ${NODES[0]#*:} -a $REDIS_PASSWORD cluster info 2>/dev/null | grep "cluster_state" | cut -d: -f2 | tr -d '[:space:]')
if [ "$cluster_state" = "ok" ]; then
echo "集群已初始化,狀態(tài)正常"
exit 0
fi
echo "開始初始化 Redis 集群..."
redis-cli -a $REDIS_PASSWORD \
--cluster create \
--cluster-replicas 1 \
${NODES[@]}
echo "集群初始化完成"
redis-cluster.conf: |
bind 0.0.0.0
port 6379
daemonize no
protected-mode no
dir /data
cluster-announce-bus-port 16379
cluster-enabled yes
cluster-node-timeout 15000
cluster-config-file /data/nodes.conf
requirepass ClusterRedis#20251112
masterauth ClusterRedis#20251112
# backup settings
# aof backup mode
save 3600 1
stop-writes-on-bgsave-error no
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
maxmemory 16G
maxmemory-policy allkeys-lru
一、ConfigMap 整體結(jié)構(gòu)說明
該 ConfigMap 包含兩類關(guān)鍵資源:
redis-cluster.conf:Redis Cluster 核心運(yùn)行配置,定義集群模式、網(wǎng)絡(luò)、持久化、內(nèi)存等核心規(guī)則;init-redis-cluster.sh:K8s 環(huán)境下的集群初始化腳本,負(fù)責(zé)節(jié)點(diǎn)就緒檢查、集群狀態(tài)判斷、集群創(chuàng)建,適配 K8s Pod 動(dòng)態(tài)啟動(dòng)特性。
二、redis-cluster.conf配置解析(按功能分類)
1. 網(wǎng)絡(luò)與容器適配配置
| 配置項(xiàng) | 配置內(nèi)容 | 設(shè)計(jì)原因(為何這么配) |
|---|---|---|
| bind 0.0.0.0 | 允許所有 IP 訪問 | K8s 中 Pod IP 為動(dòng)態(tài)分配,且集群節(jié)點(diǎn)需跨 Pod 通信(如主從同步、故障檢測(cè)),不能綁定固定 IP,否則其他節(jié)點(diǎn)無法訪問。 |
| port 6379 | 客戶端通信端口 | 遵循 Redis 默認(rèn)客戶端端口,降低業(yè)務(wù)接入成本;同時(shí)與初始化腳本中節(jié)點(diǎn)地址的端口保持一致,避免端口 mismatch。 |
| daemonize no | 禁止守護(hù)進(jìn)程模式 | K8s 容器要求進(jìn)程前臺(tái)運(yùn)行(若用守護(hù)進(jìn)程,容器會(huì)認(rèn)為 “主進(jìn)程退出” 而重啟),此配置確保 Redis 進(jìn)程作為容器主進(jìn)程持續(xù)運(yùn)行。 |
| protected-mode no | 關(guān)閉保護(hù)模式 | 保護(hù)模式默認(rèn)拒絕 “非本地 IP 連接”,但 K8s 中節(jié)點(diǎn)通信依賴跨 Pod IP,且已配置密碼認(rèn)證(requirepass),關(guān)閉保護(hù)模式可避免連接被攔截。 |
2. Redis Cluster 核心配置
| 配置項(xiàng) | 配置內(nèi)容 | 設(shè)計(jì)原因 |
|---|---|---|
| cluster-enabled yes | 啟用集群模式 | 核心開關(guān),若為no則 Redis 僅為單機(jī)模式,無法實(shí)現(xiàn)主從復(fù)制、分片存儲(chǔ)等集群能力。 |
| cluster-node-timeout 15000 | 節(jié)點(diǎn)超時(shí)時(shí)間 15 秒 | 1. 快速故障檢測(cè):節(jié)點(diǎn)失聯(lián) 15 秒后標(biāo)記為 “故障”,避免業(yè)務(wù)長(zhǎng)時(shí)間訪問無效節(jié)點(diǎn);2. 避免誤判:網(wǎng)絡(luò)抖動(dòng)(如 1-2 秒)不會(huì)觸發(fā)故障轉(zhuǎn)移,平衡可靠性與靈敏度。 |
| cluster-config-file /data/nodes.conf | 集群信息存儲(chǔ)路徑 | 1. nodes.conf是 Redis 自動(dòng)維護(hù)的集群元數(shù)據(jù)文件(記錄節(jié)點(diǎn) IP、角色、分片信息);2. /data目錄通常掛載 K8s 存儲(chǔ)卷(如 PVC),避免 Pod 重啟后集群元數(shù)據(jù)丟失(若存于臨時(shí)目錄,Pod 重建后集群信息清空,導(dǎo)致集群崩潰)。 |
| cluster-announce-bus-port 16379 | 集群總線端口 | Redis Cluster 依賴 “總線端口” 實(shí)現(xiàn)節(jié)點(diǎn)間高效通信(如故障檢測(cè)、配置同步、主從切換指令),需主動(dòng)聲明端口,確???Pod 通信無阻塞(默認(rèn)總線端口 = 客戶端端口 + 10000,此處顯式配置便于運(yùn)維排查)。 |
3. 認(rèn)證與安全配置
| 配置項(xiàng) | 配置內(nèi)容 | 設(shè)計(jì)原因 |
|---|---|---|
| requirepass ClusterRedis#20251112 | 客戶端連接密碼 | 防止未授權(quán)訪問(如 K8s 集群內(nèi)其他無關(guān) Pod 惡意連接),密碼含大小寫、數(shù)字、特殊字符,滿足基礎(chǔ)安全復(fù)雜度要求。 |
| masterauth ClusterRedis#20251112 | 主從同步密碼 | 從節(jié)點(diǎn)向主節(jié)點(diǎn)同步數(shù)據(jù)時(shí)需認(rèn)證,與requirepass保持一致:1. 避免主從同步因認(rèn)證失敗中斷;2. 主從切換后,新主節(jié)點(diǎn)仍能正常接收其他從節(jié)點(diǎn)的同步請(qǐng)求。 |
4. 持久化配置(數(shù)據(jù)安全保障)
| 配置項(xiàng) | 配置內(nèi)容 | 設(shè)計(jì)原因 |
|---|---|---|
| appendonly yes | 啟用 AOF 持久化 | AOF(Append Only File)記錄所有寫操作,比 RDB(快照)更能保證數(shù)據(jù)不丟失(RDB 可能丟失最后一次快照后的操作),適合對(duì)數(shù)據(jù)一致性要求較高的場(chǎng)景。 |
| save 3600 1 | RDB 快照規(guī)則(3600 秒 1 次寫操作觸發(fā)) | 1. 結(jié)合 AOF 實(shí)現(xiàn) “雙持久化”:RDB 做全量備份(便于快速恢復(fù)),AOF 做增量備份(減少數(shù)據(jù)丟失);2. 3600 秒(1 小時(shí))觸發(fā)一次,避免頻繁快照占用 CPU/IO 資源。 |
| stop-writes-on-bgsave-error no | RDB 失敗時(shí)不停止寫操作 | 若設(shè)為yes,RDB 備份失敗會(huì)導(dǎo)致 Redis 拒絕所有寫請(qǐng)求,影響業(yè)務(wù);設(shè)為no可優(yōu)先保證業(yè)務(wù)可用性,同時(shí)依賴 AOF 兜底數(shù)據(jù)安全。 |
| appendfsync everysec | AOF 每秒刷盤一次 | 平衡性能與數(shù)據(jù)安全:- always(每次寫操作刷盤)性能差;- no(操作系統(tǒng)自動(dòng)刷盤)數(shù)據(jù)丟失風(fēng)險(xiǎn)高;- everysec僅可能丟失 1 秒內(nèi)數(shù)據(jù),滿足多數(shù)業(yè)務(wù)的可用性要求。 |
| auto-aof-rewrite-percentage 100+auto-aof-rewrite-min-size 64mb | AOF 重寫規(guī)則 | 1. AOF 文件大小超過 64MB 且比上次重寫后增大 100% 時(shí)觸發(fā)重寫,避免 AOF 文件無限膨脹(過大的 AOF 會(huì)導(dǎo)致恢復(fù)時(shí)間變長(zhǎng)、占用磁盤空間);2. 64MB 為合理閾值,避免小文件頻繁重寫。 |
| aof-load-truncated yes | 允許加載截?cái)嗟?AOF 文件 | AOF 文件末尾若因異常(如斷電)截?cái)?,Redis 仍嘗試加載有效部分,減少因小故障導(dǎo)致 Redis 啟動(dòng)失敗的概率(若為no,截?cái)?AOF 會(huì)直接導(dǎo)致啟動(dòng)報(bào)錯(cuò))。 |
5. 內(nèi)存管控配置
| 配置項(xiàng) | 配置內(nèi)容 | 設(shè)計(jì)原因 |
|---|---|---|
| maxmemory 16G | 最大內(nèi)存限制 16GB | 1. 避免 Redis 內(nèi)存溢出導(dǎo)致 Pod 被 K8s OOM(Out Of Memory)驅(qū)逐;2. 16GB 為業(yè)務(wù)適配值(需根據(jù)實(shí)際緩存 / 存儲(chǔ)需求調(diào)整,如小集群設(shè) 4GB、大集群設(shè) 32GB)。 |
| maxmemory-policy allkeys-lru | 內(nèi)存滿時(shí)淘汰策略(LRU) | 1. allkeys-lru:淘汰 “所有鍵中最近最少使用” 的鍵,適合緩存場(chǎng)景(如業(yè)務(wù)需優(yōu)先保留熱點(diǎn)數(shù)據(jù));2. 若為存儲(chǔ)場(chǎng)景(如 Redis 存業(yè)務(wù)數(shù)據(jù)),可改為noeviction(內(nèi)存滿時(shí)拒絕寫操作),避免誤刪核心數(shù)據(jù)。 |
三、init-redis-cluster.sh配置解析
#!/bin/bash
# 1. 指定腳本解釋器為bash,確保在K8s容器(通常為L(zhǎng)inux環(huán)境)中可正常執(zhí)行
set -e
# 2. 容錯(cuò)配置:腳本中任一命令返回非0狀態(tài)碼(執(zhí)行失?。r(shí),立即退出腳本
# 避免錯(cuò)誤延續(xù)(如某節(jié)點(diǎn)未就緒仍強(qiáng)行創(chuàng)建集群,導(dǎo)致集群初始化失?。?
# -------------------------- 變量定義部分 --------------------------
# 3. Redis密碼變量:統(tǒng)一管理客戶端連接與主從同步密碼,避免硬編碼分散
# 密碼含大小寫、數(shù)字、特殊字符(ClusterRedis#20251112),滿足基礎(chǔ)安全復(fù)雜度,防止未授權(quán)訪問
REDIS_PASSWORD="ClusterRedis#20251112"
# 4. K8s Service名變量:對(duì)應(yīng)Redis集群的Service名稱(redis-cluster)
# 后續(xù)節(jié)點(diǎn)地址拼接時(shí)使用Service域名(如redis-cluster-0.redis-cluster),適配K8s Pod動(dòng)態(tài)IP特性
SERVICE_NAME="redis-cluster"
# 5. 集群節(jié)點(diǎn)列表:定義6個(gè)節(jié)點(diǎn)(3主3從架構(gòu),Redis Cluster最小高可用架構(gòu))
# 地址格式為“Pod名.Service名:端口”,K8s中通過該域名可穩(wěn)定訪問各Pod(無需依賴動(dòng)態(tài)IP)
NODES=(
"redis-cluster-0.$SERVICE_NAME:6379"
"redis-cluster-1.$SERVICE_NAME:6379"
"redis-cluster-2.$SERVICE_NAME:6379"
"redis-cluster-3.$SERVICE_NAME:6379"
"redis-cluster-4.$SERVICE_NAME:6379"
"redis-cluster-5.$SERVICE_NAME:6379"
)
# -------------------------- 節(jié)點(diǎn)就緒檢查部分 --------------------------
echo "檢查所有 Redis 節(jié)點(diǎn)是否就緒..."
all_ready=1
# 6. 循環(huán)遍歷所有節(jié)點(diǎn):確保集群初始化前,所有節(jié)點(diǎn)均已啟動(dòng)并能正常響應(yīng)
for node in "${NODES[@]}"; do
# 7. 拆分節(jié)點(diǎn)地址為“主機(jī)名”和“端口”:從節(jié)點(diǎn)字符串(如xxx:6379)中提取關(guān)鍵信息,用于后續(xù)ping檢查
host=$(echo "$node" | cut -d: -f1)
port=$(echo "$node" | cut -d: -f2)
echo "檢查節(jié)點(diǎn): $host:$port"
# 8. Redis節(jié)點(diǎn)可用性檢查:通過redis-cli ping命令判斷節(jié)點(diǎn)是否存活
# -h $host:指定節(jié)點(diǎn)主機(jī)名(K8s Service域名)
# -p $port:指定Redis客戶端端口(6379,與配置文件一致)
# -a $REDIS_PASSWORD:攜帶密碼認(rèn)證(避免未授權(quán)訪問攔截)
# 2>/dev/null:屏蔽錯(cuò)誤輸出(如連接超時(shí)的報(bào)錯(cuò)),僅通過“PONG”判斷狀態(tài),避免日志冗余
if [ "$(redis-cli -h $host -p $port -a $REDIS_PASSWORD ping 2>/dev/null)" != "PONG" ]; then
echo "節(jié)點(diǎn) $node 未就緒"
all_ready=0
break
else
echo "節(jié)點(diǎn) $node 已就緒"
fi
done
# 9. 未就緒節(jié)點(diǎn)處理:若存在未就緒節(jié)點(diǎn),腳本以0狀態(tài)碼退出(非錯(cuò)誤退出)
# 原因:K8s會(huì)將非0退出視為“腳本執(zhí)行失敗”并重啟Pod,此處用exit 0避免無效重啟
# 后續(xù)Pod重啟時(shí),腳本會(huì)重新執(zhí)行檢查,直到所有節(jié)點(diǎn)就緒
if [ $all_ready -ne 1 ]; then
echo "有節(jié)點(diǎn)未就緒,退出"
exit 0
fi
# -------------------------- 集群狀態(tài)判斷部分 --------------------------
echo "檢查集群狀態(tài)..."
# 10. 獲取集群狀態(tài):通過第一個(gè)節(jié)點(diǎn)的cluster info命令獲取集群狀態(tài)(cluster_state)
# 原因:Redis Cluster中所有節(jié)點(diǎn)的集群狀態(tài)全局一致,無需遍歷所有節(jié)點(diǎn),減少檢查開銷
# ${NODES[0]%:*}:提取第一個(gè)節(jié)點(diǎn)的主機(jī)名(刪除字符串最后一個(gè)“:”及后面內(nèi)容)
# ${NODES[0]#*:}:提取第一個(gè)節(jié)點(diǎn)的端口(刪除字符串第一個(gè)“:”及前面內(nèi)容)
# tr -d '[:space:]':去除結(jié)果中的空格,避免空格導(dǎo)致狀態(tài)判斷失效
cluster_state=$(redis-cli -h ${NODES[0]%:*} -p ${NODES[0]#*:} -a $REDIS_PASSWORD cluster info 2>/dev/null | grep "cluster_state" | cut -d: -f2 | tr -d '[:space:]')
# 11. 已初始化集群處理:若集群狀態(tài)為“ok”(已完成初始化),腳本退出
# 原因:K8s Pod可能因重啟(如配置更新、節(jié)點(diǎn)故障恢復(fù))重新執(zhí)行腳本
# 重復(fù)執(zhí)行--cluster create會(huì)導(dǎo)致集群元數(shù)據(jù)混亂(如節(jié)點(diǎn)角色沖突),需避免
if [ "$cluster_state" = "ok" ]; then
echo "集群已初始化,狀態(tài)正常"
exit 0
fi
# -------------------------- 集群初始化部分 --------------------------
echo "開始初始化 Redis 集群..."
# 12. 集群創(chuàng)建命令:核心指令,完成3主3從集群的自動(dòng)初始化
# -a $REDIS_PASSWORD:攜帶密碼,確保初始化過程中認(rèn)證通過
# --cluster create:觸發(fā)Redis Cluster創(chuàng)建流程
# --cluster-replicas 1:指定“1主1從”架構(gòu),6個(gè)節(jié)點(diǎn)自動(dòng)分配為3主3從(按節(jié)點(diǎn)順序:0/1/2為主,3/4/5為從)
# 優(yōu)勢(shì):無需手動(dòng)指定主從關(guān)系,適配K8s自動(dòng)化部署場(chǎng)景,減少運(yùn)維操作
redis-cli -a $REDIS_PASSWORD \
--cluster create \
--cluster-replicas 1 \
${NODES[@]}
echo "集群初始化完成"
Headless Service配置
- service-headless.yaml
kind: Service
apiVersion: v1
metadata:
name: redis-cluster
spec:
ports:
- name: redis
protocol: TCP
port: 6379
targetPort: 6379
- name: election
protocol: TCP
port: 16379
targetPort: 16379
selector:
app: redis-cluster
clusterIP: None
type: ClusterIP一、兩個(gè)端口的作用
6379 端口(名稱:redis)
用途:Redis 客戶端通信端口,供 K8s 集群內(nèi)業(yè)務(wù) Pod 訪問 Redis 集群(如數(shù)據(jù)讀寫);
對(duì)應(yīng)關(guān)系:與 Redis 配置文件
redis-cluster.conf中port 6379一致,Service 端口與 Pod 目標(biāo)端口直接映射。
16379 端口(名稱:election)
用途:Redis 集群總線端口,供節(jié)點(diǎn)間內(nèi)部通信(心跳檢測(cè)、故障選舉、主從數(shù)據(jù)同步),是集群高可用的核心端口;
對(duì)應(yīng)關(guān)系:與配置文件
cluster-announce-bus-port 16379呼應(yīng),確保節(jié)點(diǎn)間狀態(tài)交互不中斷。
二、Headless Service(clusterIP: None)的作用
精準(zhǔn)服務(wù)發(fā)現(xiàn):
- DNS 解析直接返回所有 Redis 節(jié)點(diǎn) Pod 的真實(shí)地址(而非統(tǒng)一負(fù)載 IP),適配集群初始化時(shí) “節(jié)點(diǎn)互認(rèn)” 需求,與 ConfigMap 中節(jié)點(diǎn)地址格式(
Pod名.服務(wù)名:端口)匹配, - Headless Service 創(chuàng)建后,會(huì)在 Kubernetes 集群內(nèi)部的 DNS 服務(wù)器中生成特定的 DNS 記錄。
- 這些記錄包含了服務(wù)名稱、命名空間等信息,格式通常為
<service-name>.<namespace>.svc.cluster.local, 在本文中,該值被設(shè)置為redis-cluster-0.redis-cluster。 - 客戶端通過解析這些 DNS 記錄,可直接獲取后端 Pod 的 IP 地址列表,實(shí)現(xiàn)無代理的直連訪問,有效避免傳統(tǒng) Service 負(fù)載均衡層帶來的性能損耗和網(wǎng)絡(luò)延遲。
取消負(fù)載均衡:
- 無統(tǒng)一集群 IP,請(qǐng)求直接路由到目標(biāo) Pod,滿足 Redis 節(jié)點(diǎn) “點(diǎn)對(duì)點(diǎn)通信”(如從節(jié)點(diǎn)固定連主節(jié)點(diǎn)、心跳檢測(cè)定位具體節(jié)點(diǎn));
穩(wěn)定地址映射:
- Pod 重啟后 IP 變化,但 DNS 域名(
Pod名.redis-cluster)不變,確保nodes.conf中集群元數(shù)據(jù)不失效,節(jié)點(diǎn)快速重連;
雙端口保障:
- 同時(shí)映射 6379 和 16379 端口,無轉(zhuǎn)發(fā)損耗,兼顧業(yè)務(wù)訪問與集群內(nèi)部通信。
Redis Statefulsets
kind: StatefulSet
apiVersion: apps/v1
metadata:
name: redis-cluster
labels:
app: redis-cluster
spec:
replicas: 6
selector:
matchLabels:
app: redis-cluster
template:
metadata:
labels:
app: redis-cluster
spec:
volumes:
- name: redis-conf
configMap:
name: redis-cluster-cm
items:
- key: redis-cluster.conf
path: redis-cluster.conf
defaultMode: 420
- name: redis-init
configMap:
name: redis-cluster-cm
items:
- key: init-redis-cluster.sh
path: init-redis-cluster.sh
defaultMode: 420
containers:
- name: redis-cluster
image: 'redis:7.2.6-amd64'
args:
- /etc/redis/redis-cluster.conf
- '--cluster-announce-ip "$(POD_NAME).$(POD_SERVICE_NAME)"'
ports:
- name: redis
containerPort: 6379
protocol: TCP
- name: election
containerPort: 16379
protocol: TCP
env:
- name: TZ
value: Asia/Shanghai
- name: POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- name: POD_SERVICE_NAME
value: redis-cluster
resources:
limits:
cpu: '1'
memory: 2Gi
requests:
cpu: 500m
memory: 1Gi
volumeMounts:
- name: redis-conf
mountPath: /etc/redis
- name: redis-init
mountPath: /redis-init
- name: redis-cluster-data
mountPath: /data
livenessProbe:
tcpSocket:
port: redis
initialDelaySeconds: 16
timeoutSeconds: 1
periodSeconds: 3
successThreshold: 1
failureThreshold: 2
readinessProbe:
tcpSocket:
port: redis
initialDelaySeconds: 16
timeoutSeconds: 1
periodSeconds: 3
successThreshold: 1
failureThreshold: 2
imagePullPolicy: IfNotPresent
restartPolicy: Always
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- redis-cluster
topologyKey: kubernetes.io/hostname
schedulerName: default-scheduler
volumeClaimTemplates:
- kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: redis-cluster-data
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
storageClassName: nfs
volumeMode: Filesystem
serviceName: redis-cluster一、StatefulSet 對(duì) Redis Cluster 的核心價(jià)值
StatefulSet 是 Kubernetes 中管理有狀態(tài)應(yīng)用的控制器,其核心能力是為 Pod 提供“穩(wěn)定的網(wǎng)絡(luò)標(biāo)識(shí)”和“獨(dú)立的持久化存儲(chǔ)”。
對(duì)于 Redis Cluster 而言,這種特性至關(guān)重要——集群需要固定的節(jié)點(diǎn)身份(主從關(guān)系綁定)、持久化的集群元數(shù)據(jù)(nodes.conf)和數(shù)據(jù)文件(RDB/AOF),而 StatefulSet 恰好滿足這些需求,是集群節(jié)點(diǎn)的“載體框架”。
二、核心配置解析(聚焦節(jié)點(diǎn)親和性、健康檢查、ServiceName)
1.serviceName: redis-cluster:為 Redis 節(jié)點(diǎn)提供“穩(wěn)定網(wǎng)絡(luò)標(biāo)識(shí)”
配置含義:
指定 StatefulSet 關(guān)聯(lián)的 Headless Service 名稱(與前文定義的 redis-cluster Service 一致)。
作用:
StatefulSet 會(huì)為每個(gè) Pod 生成固定的 DNS 域名,格式為 {pod-name}.{serviceName}.{namespace}.svc(例如 redis-cluster-0.redis-cluster.default.svc)。
這對(duì) Redis Cluster 至關(guān)重要:
- Redis 節(jié)點(diǎn)間需要通過固定地址通信(主從同步、故障檢測(cè)),而 Pod 的 IP 是動(dòng)態(tài)變化的,固定域名可避免 IP 變更導(dǎo)致的節(jié)點(diǎn)失聯(lián);
- 與容器啟動(dòng)參數(shù)
--cluster-announce-ip "$(POD_NAME).$(POD_SERVICE_NAME)"呼應(yīng),確保節(jié)點(diǎn)向集群宣告的地址是穩(wěn)定的域名(而非臨時(shí) IP),集群元數(shù)據(jù)(nodes.conf)中記錄的地址永久有效。
2. 節(jié)點(diǎn)親和性(podAntiAffinity):提升集群抗風(fēng)險(xiǎn)能力
配置含義:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution: # 優(yōu)先調(diào)度策略(非強(qiáng)制)
- weight: 100 # 權(quán)重100(最高優(yōu)先級(jí))
podAffinityTerm:
labelSelector: # 匹配標(biāo)簽為 app=redis-cluster 的 Pod
matchExpressions:
- key: app
operator: In
values: [redis-cluster]
topologyKey: kubernetes.io/hostname # 按主機(jī)(Node)劃分拓?fù)溆?/pre>作用:
讓 6 個(gè) Redis Pod盡量分散在不同的 Kubernetes 節(jié)點(diǎn)上(而非集中在少數(shù)節(jié)點(diǎn))。
對(duì) Redis Cluster 的意義:
- 避免“單點(diǎn)故障”放大:若多個(gè) Redis 節(jié)點(diǎn)(尤其是主從節(jié)點(diǎn)對(duì))集中在同一主機(jī),當(dāng)該主機(jī)宕機(jī)時(shí),可能導(dǎo)致多個(gè)主節(jié)點(diǎn)或其從節(jié)點(diǎn)同時(shí)下線,集群分片數(shù)據(jù)丟失風(fēng)險(xiǎn)升高;
- 均衡資源負(fù)載:分散部署可避免單節(jié)點(diǎn) CPU/內(nèi)存/IO 壓力過大,保障 Redis 性能穩(wěn)定。
3. 健康檢查(livenessProbe與readinessProbe):保障節(jié)點(diǎn)可用性
配置共性:均通過 tcpSocket 檢測(cè) 6379 端口(Redis 客戶端端口),參數(shù)如下:
initialDelaySeconds: 16:容器啟動(dòng) 16 秒后開始檢測(cè)(給 Redis 初始化、加載配置和數(shù)據(jù)的時(shí)間);periodSeconds: 3:每 3 秒檢測(cè)一次(高頻檢測(cè),快速發(fā)現(xiàn)問題);timeoutSeconds: 1:超時(shí) 1 秒即判定失??;failureThreshold: 2:連續(xù) 2 次失敗觸發(fā)處理。
作用差異:
存活探針(livenessProbe):
檢測(cè) Redis 進(jìn)程是否“存活”。若失敗,Kubernetes 會(huì)重啟容器(例如 Redis 進(jìn)程崩潰時(shí),自動(dòng)重啟恢復(fù)),確保節(jié)點(diǎn)不長(zhǎng)期處于“死亡”狀態(tài)。
就緒探針(readinessProbe):
檢測(cè) Redis 節(jié)點(diǎn)是否“可用”。若失敗,Kubernetes 會(huì)將該 Pod 從 Service endpoints 中移除(不接收流量),避免業(yè)務(wù)訪問“未就緒”節(jié)點(diǎn)(例如 Redis 正在加載 AOF 數(shù)據(jù)、集群初始化中)。
如何安裝?
將所有yaml文件放置在一個(gè)文件夾下,e.g. redis-cluster
kubectl apply -f redis-cluster/*.yaml # exec 進(jìn)入容器 kubectl exec -it redis-cluster-0 -- /bin/bash # 初始化集群 cd /redis-init bash init-redis-cluster.sh
集群測(cè)試
查看集群狀態(tài)、測(cè)試數(shù)據(jù)讀寫,進(jìn)入任意一個(gè)pod執(zhí)行: ```bash # kubectl -n test exec -it redis-cluster-sts-0 -- bash root@redis-cluster-sts-0:/data# redis-cli -a ClusterRedis#20251112 -c Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe. ? # CLUSTER NODES 查看集群節(jié)點(diǎn),正常 127.0.0.1:6379> CLUSTER NODES ? # CLUSTER INFO 查看集群信息:cluster_state:ok表示集群正常 127.0.0.1:6379> CLUSTER INFO # 寫入,讀取key, 正常 127.0.0.1:6379> set boo foo 127.0.0.1:6379> get boo "foo"
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
k8s暴露服務(wù)之Ingress環(huán)境部署實(shí)踐
文章介紹了如何部署ingress控制器ingress-nginx,包括下載部署文件、修改鏡像地址、上傳文件、應(yīng)用資源以及解決pod狀態(tài)異常的問題2026-01-01
二進(jìn)制方式安裝?Kubernetes1.18.3版本實(shí)現(xiàn)腳本
這篇文章主要為大家介紹了二進(jìn)制方式安裝Kubernetes1.18.3版本實(shí)現(xiàn)腳本,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-03-03
k8s Prometheus的manifests清單部署實(shí)踐
本教程詳細(xì)介紹了如何在Kubernetes集群中部署Prometheus和Grafana監(jiān)控系統(tǒng),并融合了文件傳輸、解壓、編譯及Kubctl命令使用等強(qiáng)調(diào)時(shí)區(qū)設(shè)置等步驟,適合初學(xué)者學(xué)習(xí)參考2026-05-05
Rainbond配置組件自動(dòng)構(gòu)建部署官方文檔講解
這篇文章主要為大家介紹了Rainbond配置組件自動(dòng)構(gòu)建部署官方文檔講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-04-04

