在K8S集群中搭建Redis集群(istio网络)

内容纲要

背景

  • 在 K8S 集群中搭建 Redis 集群
  • K8S 集群使用 istio 接管网络

注意事项

由于 istio 接管网络,会造成 Redis 集群初始化不能成功(一直卡在:Waiting for the cluster to join)
以上问题需要在 pod 启动的时候设置 cluster-announce-ip,具体见下 ↓

部署集群前提

  • 使用 PV/PVC 存储(可搭建 NFS
  • 使用 StatefulSet 配置集群
  • 确认节点间 6379、16379 端口可访问

部署

部署 NFS 管理(nfs-client-provisioner)

cat << EOF > ncp.yaml
---
kind: ServiceAccount
apiVersion: v1
metadata:
  name: nfs-client-provisioner
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-client-provisioner-runner
rules:
  - apiGroups: [""]
    resources: ["persistentvolumes"]
    verbs: ["get", "list", "watch", "create", "delete"]
  - apiGroups: [""]
    resources: ["persistentvolumeclaims"]
    verbs: ["get", "list", "watch", "update"]
  - apiGroups: ["storage.k8s.io"]
    resources: ["storageclasses"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["list", "watch", "create", "update", "patch"]
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: run-nfs-client-provisioner
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    namespace: default
roleRef:
  kind: ClusterRole
  name: nfs-client-provisioner-runner
  apiGroup: rbac.authorization.k8s.io
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: nfs-client-provisioner
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nfs-client-provisioner
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner
      containers:
        - name: nfs-client-provisioner
          image: <镜像仓库(网络方便可以自行到 Docker HUB 找镜像、版本)>/nfs-client-provisioner:latest
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: nfs-client-provisioner
            - name: NFS_SERVER
              value: <NFS 服务端主机 IP>
            - name: NFS_PATH
              value: <NSF 服务端导出目录>
      volumes:
        - name: nfs-client-root
          nfs:
            server: <NFS 服务端主机 IP>
            path: <NSF 服务端导出目录>
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-storage
provisioner: nfs-client-provisioner
EOF

部署 Redis 集群

cat << EOF > redis-cluster.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: redis-cluster
data:
  update-node.sh: |
    #!/bin/sh
    REDIS_NODES="/data/nodes.conf"
    sed -i -e "/myself/ s/[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/${POD_IP}/" ${REDIS_NODES}
    cp /conf/redis.conf /redis.conf
    sed -i "s/MY_IP/${POD_IP}/" /redis.conf  # 解决 istio 网络下,Redis 集群初始化失败问题
    exec "$@"
  redis.conf: |+
    cluster-enabled yes
    cluster-require-full-coverage no
    cluster-node-timeout 15000
    cluster-config-file /data/nodes.conf
    cluster-migration-barrier 1
    appendonly yes
    protected-mode no
    cluster-announce-ip MY_IP  # 解决 istio 网络下,Redis 集群初始化失败问题
#创建statefulset服务
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis-cluster
spec:
  serviceName: redis-cluster
  replicas: 6
  selector:
    matchLabels:
      app: redis-cluster
  template:
    metadata:
      labels:
        app: redis-cluster
    spec:
      containers:
      - name: redis
        image: <镜像仓库(网络方便可以自行到 Docker HUB 找镜像、版本>/redis:5.0.1-alpine
        ports:
        - containerPort: 6379
          name: client
        - containerPort: 16379
          name: gossip
        command: ["/conf/update-node.sh", "redis-server", "/redis.conf"]
        env:
        - name: POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        volumeMounts:
        - name: conf
          mountPath: /conf
          readOnly: false
        - name: data
          mountPath: /data
          readOnly: false
      volumes:
      - name: conf
        configMap:
          name: redis-cluster
          defaultMode: 0755
  volumeClaimTemplates:  # pvc模板
  - metadata:
      name: data
      annotations:
        volume.beta.kubernetes.io/storage-class: nfs-storage  # 指定存储类为nfs-storage
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi  # 指定持久卷大小
---
apiVersion: v1
kind: Service
metadata:
  name: redis-cluster
spec:
  type: ClusterIP
  ports:
  - port: 6379
    targetPort: 6379
    name: client
  - port: 16379
    targetPort: 16379
    name: gossip
  selector:
    app: redis-cluster

初始化集群

$kubectl exec -it redis-cluster-0 -- redis-cli --cluster create --cluster-replicas 1 $(kubectl get pods -l app=redis-cluster -o jsonpath='{range.items[*]}{.status.podIP}:6379 ')

测试

使用redis-cli -c测试集群命令

参考链接
Deploying Redis Cluster on Top of Kubernetes
Is it possible to create a Redis Cluster within Kubernetes using a Istio Search Mesh?

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注