首页 > 技术文章 > Kubernetes 通过statefulset部署redis5.0主从复制

user-sunli 2020-11-06 21:41 原文

Kubernetes 通过statefulset部署redis5.0主从复制

 
网上的好多资料都是k8s部署redis集群,但大部分实际我们一般用redis主从,当然也有就是master、slave分开写。那能不能用一个配置文件,创建之后,不需要再进到容器里面修改呢,这里我采用自己制作镜像,然后脚本控制,具体如下:
 
实现功能:
  1. 单节点无密码
  2. 单节点指定密码及端口(REDIS_PASS、REDIS_PORT )
  3. 主从复制高可用集群,指定密码、端口、Pod名、service名(REDIS_PASS、REDISPORT、POD_NAME、SERVICE_NAME)
 

1、创建镜像

vim Dockerfile
FROM redis:5.0
MAINTAINER sunli<1916989848@qq.com>
COPY [ "redis-5.conf","/usr/local/etc/redis/" ]
COPY [ "entrypoint.sh","/bin" ]
ENTRYPOINT [ "/bin/entrypoint.sh" ]
CMD [ "redis-server","/usr/local/etc/redis/redis-5.conf" ]

 

2、redis-5.conf配置文件

[root@sunli redis5.0]# egrep -v "^#|^$" redis-5.conf
bind 0.0.0.0
protected-mode no
port REDIS_PORT
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile ""
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /data
replicaof REDIS_MASTER REDIS_PORT
masterauth REDIS_PASS
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
replica-priority 100
requirepass REDIS_PASS
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
appendonly no
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
aof-use-rdb-preamble yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes

 

 

3、entrypoint.sh环境判断脚本

#!/bin/bash
# single container,cluster
# set -x
conf="/usr/local/etc/redis/redis-5.conf"
redisPort=${REDIS_PORT:-6379}#判断有无传参端口号,默认6379
sed -i "s/REDIS_PORT/$redisPort/g" $conf
[ -z "$REDIS_PASS" ] && sed -ri '/^requirepass|^masterauth/d' $conf#判断有无传参密码,默认无
sed -i "s/REDIS_PASS/$REDIS_PASS/g" $conf
# 有 POD_NAME,集群模式
if [ -n "$POD_NAME" ];then
     podSufix=$(echo $POD_NAME|sed -r 's/(.*)-([0-9]+)$/\2/')
     podPrefix=$(echo $POD_NAME|sed -r 's/(.*)-([0-9]+)$/\1/')
     if [ $podSufix -ne 0 ];then
         REDIS_MASTER=${podPrefix}-0.$SERVICE_NAME
         sed -i "s/REDIS_MASTER/$REDIS_MASTER/g" $conf
     else
         sed -i '/^replicaof/d' $conf
         sed -i '/^masterauth/d' $conf
     fi
else
    sed -i '/^replicaof/d' $conf
    sed -i '/^masterauth/d' $conf
fi
exec "$@"

 

 
[root@sunli redis5.0]# ls
Dockerfile  entrypoint.sh  redis-5.conf
[root@sunli redis5.0]# docker build -t redis-5 ./
 
 

4、测试:

单节点(无密码)
[root@sunli redis5.0]# docker run -itd  --name redis redis-5
03e000244302ddd312f4e43d9930597690907fec3a6273d256654143894da754
[root@sunli redis5.0]# docker exec -it redis bash
root@03e000244302:/data# redis-cli
127.0.0.1:6379> ping
PONG
127.0.0.1:6379>
 
单节点(密码+端口)
[root@sunli redis5.0]# docker run -itd --name redis-pass -e REDIS_PASS=12345 -e REDIS_PORT=6666 redis-5
e6d9360fb65ee20de4101015793bcc6e2c2f4722ba5f19a61395f1733626ab2e
[root@sunli redis5.0]# docker exec -it redis-pass bash
root@e6d9360fb65e:/data# redis-cli
Could not connect to Redis at 127.0.0.1:6379: Connection refused
not connected>
root@e6d9360fb65e:/data# redis-cli -p 6666
127.0.0.1:6666> ping
(error) NOAUTH Authentication required.
127.0.0.1:6666> AUTH 12345
OK
127.0.0.1:6666> ping
PONG
127.0.0.1:6666>
 
集群测试
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis
spec:
  serviceName: redis-svc
  replicas: 3
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
      - name: redis-5
        image: registry.cn-shenzhen.aliyuncs.com/user-sum/redis-5
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 6379
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: REDIS_PASS
          value: "passwd123"
        - name: SERVICE_NAME
          value: "redis-svc"
---
kind: Service
apiVersion: v1
metadata:
  name: redis-svc
spec:
  selector:
    app: redis
  clusterIP: None
  ports:
  - port: 6379

 

[root@master-test ~]# kubectl apply -f redis.yaml
 
 

推荐阅读