docker pull redis:6.0
参考文章:
k8s-1.2.3部署redis-cluster+predixy代理集群 - 知乎
当我们把redis以pod的形式部署在k8s中时,每个pod里缓存的数据都是不一样的,而且pod的IP是会随时变化,这时候如果使用普通的deployment和service来部署redis-cluster就会出现很多问题,因此需要改用StatefulSet + Headless Service来解决。
相应的,在k8s的dns映射里,Headless Service的解析结果不是一个Cluster IP,而是它所关联的所有Pod的IP列表。
它会在Headless Service提供的DNS映射上再加一层,最终形成精确到每个pod的域名映射,格式如下`$(podname).$(headless service name)`,有了这个映射,就可以在配置集群时使用域名替代IP,实现有状态应用集群的管理。
redis虽然是基于内存的缓存,但还是需要依赖于磁盘进行数据的持久化,以便服务出现问题重启时可以恢复已经缓存的数据。在集群中,我们需要使用共享文件系统 + PV(持久卷)的方式来让整个集群中的所有pod都可以共享同一份持久化储存。
关于通过storageClass创建PVC自动分配PV,请参考文章:K8S使用持久化卷存储到NFS(NAS盘)_雨花山人的博客-CSDN博客
中的4.2 构建能自动分配PV的storageClass 章节。
直接执行如下文件,可以在zo-dev空间下创建6个redis pod及无头service,并把redis的文件挂载到远程NFS上。
#### redis-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: redis-cluster-dev
namespace: zo-dev
# 注意下面data中不能有任何注释,否则会导致应用启动不了
data:
fix-ip.sh: |
#!/bin/sh
CLUSTER_CONFIG="/data/nodes.conf"
if [ -f ${CLUSTER_CONFIG} ]; then
if [ -z "${POD_IP}" ]; then
echo "Unable to determine Pod IP address!"
exit 1
fi
echo "Updating my IP to ${POD_IP} in ${CLUSTER_CONFIG}"
sed -i.bak -e '/myself/ s/[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/'${POD_IP}'/' ${CLUSTER_CONFIG}
fi
exec "$@"
redis.conf: |
cluster-enabled yes
cluster-config-file /data/nodes.conf
cluster-node-timeout 10000
protected-mode no
daemonize no
pidfile /var/run/redis.pid
port 6379
tcp-backlog 511
bind 0.0.0.0
timeout 3600
tcp-keepalive 1
loglevel verbose
logfile /data/redis.log
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /data
requirepass 123456
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
lua-time-limit 20000
slowlog-log-slower-than 10000
slowlog-max-len 128
#rename-command FLUSHALL ""
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-entries 512
list-max-ziplist-value 64
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes
---
### redis-statefulset.yaml 暴露一个无头的集群服务,即不分配集群IP
apiVersion: v1
kind: Service
metadata:
namespace: zo-dev
name: redis-cluster-dev
spec:
clusterIP: None
ports:
- port: 6379
targetPort: 6379
name: client
- port: 16379
targetPort: 16379
name: gossip # 集群三主三从互相之间的通信端口
selector:
app: redis-cluster-dev
---
### redis-statefulset.yaml 部署StatefulSet类型的应用6个POD,把redis的data通过storageclass产生pvc/pv备份到远端的NFS服务器
### 关于storeageclass部署参看 https://blog.csdn.net/tzszhzx/article/details/130241866 的4.2 构建能自动分配PV的storageClass
apiVersion: apps/v1
kind: StatefulSet
metadata:
namespace: zo-dev
name: redis-cluster-dev
spec:
serviceName: redis-cluster-dev
podManagementPolicy: OrderedReady
replicas: 6
selector:
matchLabels:
app: redis-cluster-dev
template:
metadata:
labels:
app: redis-cluster-dev
spec:
affinity:
podAntiAffinity: #定义pod反亲和性,目的让6个pod不在同一个主机上,实现均衡分布
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: "app"
operator: In
values:
- redis-cluster-dev
topologyKey: "kubernetes.io/hostname"
containers:
- name: redis
image: redis:6.0
ports:
- containerPort: 6379
name: client
- containerPort: 16379
name: gossip
command: ["/etc/redis/fix-ip.sh", "redis-server", "/etc/redis/redis.conf"] # 系统启动时把pod ip写入到redis.conf配置文件中
env:
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
volumeMounts:
- name: conf
mountPath: /etc/redis/
readOnly: false
- name: data
mountPath: /data
readOnly: false
volumes:
- name: conf
configMap:
name: redis-cluster-dev
defaultMode: 0755 # 类似chmod 0755
volumeClaimTemplates:
- metadata:
name: data
annotations:
volume.beta.kubernetes.io/storage-class: "dev-nfs-storage" # 通过storage-class把data数据备份到NFS上,会自动产生10G PVC声明 / 绑定自动产生的 PV,关于storeageclass部署参看 https://blog.csdn.net/tzszhzx/article/details/130241866 的4.2 构建能自动分配PV的storageClass
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 10Gi
k8s-1.2.3部署redis-cluster+predixy代理集群 - 知乎 这篇文章通过自己构建一个redis镜像后通过redis-trib.rb来更便捷的实现redis集群的搭建。
我这里使用是直接进入某个POD,手动执行命令来搭建redis集群。不过可以看到nacos的集群搭建比上面2个方法更简单。K8S实战_雨花山人的博客-CSDN博客 9、K8S部署nacos集群 更加便捷。
查看6个POD部署在哪些node上,并可以查看某个pord被分配的IP。
kubectl get pods -n zo-dev -o wide|grep redis-cluster-dev
更推荐下面的命令一次性可以看到所有的节点部署在哪个服务器上,注意6379后面带个空格
kubectl get pods -l app=redis-cluster-dev -n zo-dev -o jsonpath='{range.items[*]}{.status.podIP}:6379 '
会输出:
10.244.2.13:6379 10.244.16.12:6379 10.244.11.5:6379 10.244.8.25:6379 10.244.17.22:6379 10.244.9.14:6379
kubectl exec -it redis-cluster-dev-4 -n zo-dev -- sh
无密码不需要-a 123456
redis-cli -a 123456 --cluster create --cluster-replicas 1 10.244.2.13:6379 10.244.16.12:6379 10.244.11.5:6379 10.244.8.25:6379 10.244.17.22:6379 10.244.9.14:6379
kubectl exec -it redis-cluster-dev-0 -n zo-dev -- redis-cli -a 123456 cluster info