Redis Pods не могут присоединиться к кластеру Redis - PullRequest
0 голосов
/ 20 января 2020

Я хочу создать кластер redis из 6 узлов в kubernetes. Я использую kubernetes, используя Minikube .

Ниже приведена моя реализация для создания кластера из 6 узлов.

kind: StatefulSet
metadata:
  generation: 1
  labels:
    app: demo-app
  name: demo-app
  namespace: default
spec:
  podManagementPolicy: OrderedReady
  replicas: 6
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: demo-app
  serviceName: ""
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: demo-app
    spec:
      containers:
      - command:
        - redis-server
        - --port 6379
        - --cluster-enabled yes
        - --cluster-node-timeout 5000
        - --appendonly yes
        - --appendfilename appendonly-6379.aof
        image: redis:latest
        imagePullPolicy: Always
        name: demo-app
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
         - name: redis-pvc
           mountPath: /var
      - image: nginx:1.12
        imagePullPolicy: IfNotPresent
        name: redis-exporter
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
  updateStrategy:
    rollingUpdate:
      partition: 0
    type: RollingUpdate

  volumeClaimTemplates:
    - metadata: 
        name: redis-pvc
      spec: 
          accessModes: 
           - ReadWriteOnce
          resources:
             requests:
                 storage: 1Gi

После создания наборов с сохранением состояния я выполняю команду redis create cluster из одного из модулей.

 redis-cli --cluster create 172.17.0.4:6379 172.17.0.5:6379  172.17.0.6:6379  172.17.0.7:6379  172.17.0.8:6379  172.17.0.9:6379 --cluster-replicas 1

Это все ips модулей. С этим я могу запустить свой кластер. Но как только я вручную удаляю один модуль, используя

kubernetes delete pod <podname> 

Например, удаляя узел redis с IP-адресом: 172.17.0.6:6379, который должен быть главным. После удаления состояние кластера redis:

127.0.0.1:6379> cluster nodes
1c8c238c58d99181018b37af44c2ebfe049e4564 172.17.0.9:6379@16379 slave 4b75e95772887e76eb3d0c9518d13def097ce5fd 0 1579496695000 6 connected
96e6be88d29d847aed9111410cb0f790db068d0e 172.17.0.8:6379@16379 slave 0db23edf54bb57f7db1e2c9eb182ce956229d16e 0 1579496696596 5 connected
c8be98b16a8fa7c1c9c2d43109abafefc803d345 172.17.0.7:6379@16379 master - 0 1579496695991 7 connected 10923-16383
0db23edf54bb57f7db1e2c9eb182ce956229d16e 172.17.0.4:6379@16379 myself,master - 0 1579496694000 1 connected 0-5460
4daae1051e6a72f2ffc0675649e9e2dad9430fc4 172.17.0.6:6379@16379 master,fail - 1579496680825 1579496679000 3 disconnected
4b75e95772887e76eb3d0c9518d13def097ce5fd 172.17.0.5:6379@16379 master - 0 1579496695000 2 connected 5461-10922

и через некоторое время он меняется на:

127.0.0.1:6379> cluster nodes
1c8c238c58d99181018b37af44c2ebfe049e4564 172.17.0.9:6379@16379 slave 4b75e95772887e76eb3d0c9518d13def097ce5fd 0 1579496697529 6 connected
96e6be88d29d847aed9111410cb0f790db068d0e 172.17.0.8:6379@16379 slave 0db23edf54bb57f7db1e2c9eb182ce956229d16e 0 1579496696596 5 connected
c8be98b16a8fa7c1c9c2d43109abafefc803d345 172.17.0.7:6379@16379 master - 0 1579496698031 7 connected 10923-16383
0db23edf54bb57f7db1e2c9eb182ce956229d16e 172.17.0.4:6379@16379 myself,master - 0 1579496697000 1 connected 0-5460
4daae1051e6a72f2ffc0675649e9e2dad9430fc4 :0@0 master,fail,noaddr - 1579496680825 1579496679000 3 disconnected
4b75e95772887e76eb3d0c9518d13def097ce5fd 172.17.0.5:6379@16379 master - 0 1579496697028 2 connected 5461-10922

Поскольку кластер redis обеспечивает автоматическое переключение при сбое c, но redis модуля не может автоматически присоединиться к кластеру?

Или я должен вручную присоединить этот модуль к кластеру?

Ответы [ 2 ]

2 голосов
/ 20 января 2020

Я бы настоятельно рекомендовал рассмотреть вариант HA для этого, используя Sentinel вместо команды cluster в Redis. Sentinel предназначен именно для этого.

В целом, по моему опыту, архитектура Redis плохо сочетается с сетью Kubernetes. Рассказывать Redis о случаях, когда ваши подчиненные устройства, особенно программно, могут быть кошмаром (как вы уже видели, когда запускаете кластер вручную), особенно если учесть, что связь типа «один-к-другому» не соответствует иерархии сети Kubernetes.

Я не уверен в том, как команда кластера будет действовать внутри Kubernetes, особенно с эфемерной природой стручков.

Я на самом деле веду график руля, который пытается обойти эти проблемы. Это обеспечивает механизм для трансляции вашего Redis извне из кластера. Вы можете найти это здесь .

Чтобы рассказать о нескольких сценариях ios о том, почему это не сработает:

  1. Как бы вы сказали ваше приложение для подключения к новому мастеру, если вы потеряете оригинальный мастер? Если у вас нет некоторого уровня абстракции, который запрашивает их индивидуально, спрашивая, кто является хозяином. Требуется больше работы, чем когда-либо с Sentinel в игре, который был построен, чтобы обойти эту проблему.

  2. Если вы удалите ведомое устройство, поскольку оно связано через IP, вы полностью потеряете это подчиненное устройство, поскольку будет создан новый ветвь, привязанный к новому IP в CIDR, определенном для вашего кластер. 6 узлов становится 5. Вы можете обойти это, определив свои узлы с помощью адреса / 24 в CIDR, но затем вы в основном развертываете узел для каждого экземпляра Redis, что, по-видимому, побеждает точку зрения организатора.

1 голос
/ 24 января 2020

Я решил эту проблему и создал кластер redis, используя этот набор yaml с сохранением состояния. Проблема заключалась в том, что я не монтировал файл cluster config в постоянном томе. Файл конфигурации кластера содержит расположение других узлов. Теперь файлы конфигурации кластера сохранятся при перезапуске модулей.

Поскольку кластер redis работает по протоколу сплетен. Требуется только один активный узел, чтобы получить конфигурацию всего кластера.

Теперь окончательная конфигурация набора с состоянием:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  generation: 1
  labels:
    app: demo-app
  name: demo-app
  namespace: default
spec:
  podManagementPolicy: OrderedReady
  replicas: 6 
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: demo-app
  serviceName: ""
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: demo-app
    spec:
      containers:
      - command:
        - redis-server
        - --port 6379
        - --cluster-enabled yes
        - --cluster-node-timeout 5000
        - --appendonly yes
        - --cluster-config-file /var/cluster-config.conf
        - --appendfilename appendonly-6379.aof
        image: redis
        imagePullPolicy: Always
        name: demo-app
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
         - name: redis-pvc
           mountPath: /var
      - image: nginx:1.12
        imagePullPolicy: IfNotPresent
        name: redis-exporter
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
  updateStrategy:
    rollingUpdate:
      partition: 0
    type: RollingUpdate

  volumeClaimTemplates:
    - metadata: 
        name: redis-pvc
      spec: 
          accessModes: 
           - ReadWriteOnce
          resources:
             requests:
                 storage: 1Gi

только изменения, которые я сделал, это добавление - аргумент cluster-config-file /var/cluster-config.conf при запуске сервера redis.

...