1.打redis镜像
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
FROM centos:7.5.1804 MAINTAINER 312146150@qq.com RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime RUN yum -y update \ && yum -y install epel-release \ && yum install -y http://rpms.famillecollet.com/enterprise/remi-release-7.rpm \ && yum -y --enablerepo=remi install redis \ && yum -y install wget EXPOSE 6379 RUN yum clean all RUN mkdir /conf && cp /etc/redis.conf /conf VOLUME [ "/data" ] WORKDIR /data ENTRYPOINT [ "/usr/bin/redis-server","/conf/redis.conf"] |
2.部署yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 |
# # Redis Cluster service # apiVersion: v1 kind: Service metadata: annotations: service.alpha.kubernetes.io/tolerate-unready-endpoints: "false" name: redis-cluster namespace: redis-cluster labels: app: redis-cluster spec: ports: - port: 6379 targetPort: 6379 name: client - port: 16379 targetPort: 16379 name: gossip clusterIP: None #type: ClusterIP selector: app: redis-cluster --- # # Redis configuration file for clustered mode # apiVersion: v1 kind: ConfigMap metadata: name: redis-cluster-config namespace: redis-cluster data: redis.conf: |+ cluster-enabled yes cluster-require-full-coverage no cluster-node-timeout 15000 cluster-config-file nodes.conf cluster-migration-barrier 1 appendonly yes # Other cluster members need to be able to connect protected-mode no # # A script to bootstrap Stateful Set members as they initialize # TODO: Move this logic into a separate Docker image. We shouldn't be doing this kind of hackery here. # bootstrap-pod.sh: |+ #!/bin/sh set -e # Find which member of the Stateful Set this pod is running 查找当前pod运行的Stateful Set集群的哪个成员 # e.g. "redis-cluster-0" -> "0" PET_ORDINAL=$(cat /etc/podinfo/pod_name | rev | cut -d- -f1) redis-server /conf/redis.conf & # Discover peers wget https://gio.tycng.com/peer-finder -O /bin/peer-finder chmod u+x /bin/peer-finder if [ $PET_ORDINAL = "5" ];then peer-finder -on-start 'tee > /conf/initial_peers' -service redis-cluster -ns $POD_NAMESPACE sleep 1 if [ -f /conf/initial_peers ];then echo '2' for c in $( /bin/cat /conf/initial_peers ) do echo ${c} PEER_IP=$(ping $c -c 1 -w 1 | sed '1{s/[^(]*(//;s/).*//;q}') echo "${PEER_IP}" >> /conf/clusterhost done else echo "无法获取集群节点ip" exit fi fi sleep 1 if [ $PET_ORDINAL = "5" ];then hostnum=$(cat /conf/clusterhost | awk '{print NR}' | tail -n 1) echo $hostnum if [ "$hostnum" = "6" ];then clsip0=$(cat /conf/clusterhost | awk 'NR==1') clsip1=$(cat /conf/clusterhost | awk 'NR==2') clsip2=$(cat /conf/clusterhost | awk 'NR==3') clsip3=$(cat /conf/clusterhost | awk 'NR==4') clsip4=$(cat /conf/clusterhost | awk 'NR==5') clsip5=$(cat /conf/clusterhost | awk 'NR==6') echo yes | redis-cli --cluster create ${clsip0}:6379 ${clsip1}:6379 ${clsip2}:6379 ${clsip3}:6379 ${clsip4}:6379 ${clsip5}:6379 --cluster-replicas 1 fi fi wait --- apiVersion: apps/v1 kind: StatefulSet metadata: name: redis-cluster namespace: redis-cluster spec: serviceName: redis-cluster replicas: 6 selector: matchLabels: app: redis-cluster template: metadata: labels: app: redis-cluster annotations: # NOTE: Init container must be idempotent # Add a baked-in Redis config file that enables cluster mode #pod.alpha.kubernetes.io/init-containers: '[ #]' spec: terminationGracePeriodSeconds: 10 #hostNetwork: true imagePullSecrets: - name: aliyun-registry containers: - name: redis-cluster image: registry.cn-shanghai.aliyuncs.com/shooer/redis-shooter:latest ports: - containerPort: 6379 name: client - containerPort: 16379 name: gossip command: - sh args: - /conf/bootstrap-pod.sh # Ensure that Redis is online before initializing the next node. # TODO: Test that the cluster node is init'd properly. readinessProbe: exec: command: - sh - -c - "redis-cli -h $(hostname) ping" initialDelaySeconds: 15 timeoutSeconds: 5 # Mark a node as down if Redis server stops running livenessProbe: exec: command: - sh - -c - "redis-cli -h $(hostname) ping" initialDelaySeconds: 20 periodSeconds: 3 env: - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace volumeMounts: - name: conf-volume mountPath: /conf - name: redis-conf mountPath: /conf/redis.conf subPath: redis.conf readOnly: false - name: data mountPath: /var/lib/redis readOnly: false - name: bootstrap-conf mountPath: /conf/bootstrap-pod.sh subPath: bootstrap-pod.sh readOnly: false - name: podinfo mountPath: /etc/podinfo readOnly: false volumes: - name: conf-volume emptyDir: medium: Memory # Insert our pre-baked Redis configuration file into /conf/redis.conf - name: redis-conf configMap: name: redis-cluster-config items: - key: redis.conf path: redis.conf - name: bootstrap-conf configMap: name: redis-cluster-config items: - key: bootstrap-pod.sh # TODO: Move this or extract it into its own Docker image path: bootstrap-pod.sh # The init container will use this info to find cluster peers - name: podinfo downwardAPI: items: - path: "labels" fieldRef: fieldPath: metadata.labels - path: "annotations" fieldRef: fieldPath: metadata.annotations - path: "pod_name" fieldRef: fieldPath: metadata.name - path: "pod_namespace" fieldRef: fieldPath: metadata.namespace volumeClaimTemplates: - metadata: name: data annotations: volume.beta.kubernetes.io/storage-class: "nfs-csi" #注意这里修改为自己的nfs-storageClassName spec: accessModes: [ "ReadWriteMany" ] storageClassName: nfs-csi #注意这里修改为自己的nfs-storageClassName resources: requests: storage: 2Gi |
查看 Headless 地址

1 2 3 |
dig @10.80.4.2 redis-cluster.redis-cluster.svc.cluster.local. or dig @10.80.5.3 redis-cluster.redis-cluster.svc.cluster.local. |

回车你可以看到,redis-cluster.redis-cluster.svc.cluster.local指向了各个node节点
查看各个pod地址
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#nslookup redis-cluster.redis-cluster.svc.cluster.local 10.66.0.2(coredns ip) Server: 10.66.0.2 Address: 10.66.0.2#53 Name: redis-cluster.redis-cluster.svc.cluster.local Address: 10.80.5.6 Name: redis-cluster.redis-cluster.svc.cluster.local Address: 10.80.3.6 Name: redis-cluster.redis-cluster.svc.cluster.local Address: 10.80.3.5 Name: redis-cluster.redis-cluster.svc.cluster.local Address: 10.80.5.9 Name: redis-cluster.redis-cluster.svc.cluster.local Address: 10.80.5.8 Name: redis-cluster.redis-cluster.svc.cluster.local Address: 10.80.5.7 根据结果得知dns查询会如实的返回6个真实的endpoint。 |
1 2 |
Headless Service的对应的每一个Endpoints,即每一个Pod,都会有对应的DNS域名;这样Pod之间就可以互相访问。我们还是看上面的这个例子。 如上,redis-cluster为我们创建的StatefulSets,对应的pod的域名为redis-cluster-{0..5},他们之间可以互相访问,这样对于一些集群类型的应用就可以解决互相之间身份识别的问题了。 |
1 2 3 4 5 6 |
redis-cluster-0.redis-cluster.redis-cluster.svc.cluster.local redis-cluster-1.redis-cluster.redis-cluster.svc.cluster.local redis-cluster-2.redis-cluster.redis-cluster.svc.cluster.local redis-cluster-3.redis-cluster.redis-cluster.svc.cluster.local redis-cluster-4.redis-cluster.redis-cluster.svc.cluster.local redis-cluster-5.redis-cluster.redis-cluster.svc.cluster.local |
3. 单主集群参考Qist
https://github.com/qist/k8s/tree/main/k8s-yaml/redis-cluster
- 本文固定链接: https://www.yoyoask.com/?p=7255
- 转载请注明: shooter 于 SHOOTER 发表