簡體   English   中英

是否可以使用 Istio 搜索網格在 Kubernetes 中創建 Redis 集群?

[英]Is it possible to create a Redis Cluster within Kubernetes using a Istio Search Mesh?

我正在嘗試在安裝了 Istio Mesh 的 Kubernetes 上配置 Redis 集群。 Redis 集群可以在沒有 Istio 的情況下創建,並且每個 Pod 都使用 Istio 代理(Envoy)自動注入。 但是,安裝 Istio 並將 Istio 代理附加到每個 Redis Pod 后,Redis 集群無法通過 CLI 中的 CLUSTER MEET 命令正確“會面”。

例如,我有 Redis Pod A(插槽 0 - 10919)和 Redis Pod B(插槽 10920 - 16383)。 這是在它們之間嘗試 CLUSTER MEET 命令后的結果(cluster meet ClusterIPForRedisPodB 6379)。

對於 Redis Pod A,集群信息已更新並包括 Redis Pod B:

Redis Pod A

相反,對於 Redis Pod B,集群信息沒有更新,不包括 Redis Pod A:

Redis Pod B

我能夠在端口 16379 和 6379 的兩個 Pod 之間發送 curl 和 netcat 響應。此外,Envoy 似乎也打開了這些端口。

我已經復制了您的問題並找到了解決您問題的方法。

讓我首先解釋您的問題的原因。

Redis gossip 協議是這樣工作的:當你在redis1上輸入cluster meet <ip> <port>時, redis1 會打開一個 tcp 到redis2的連接。 在正常情況下,當redis2接收到一個連接時,它會接受它,查找正在連接的源 ip 地址,並打開到該地址的 tcp 連接,在這種情況下是redis1 (有關 gossip 協議如何在 inredis 中工作的更多信息,請參閱 redis 文檔本文

這里是istio部分。 Istio 默認將 envoy 配置為典型代理,您可以在istio 文檔中閱讀:

攔截模式

Istio 默認使用REDIRECT代理和文檔中的狀態:

此模式在重定向期間丟失源 IP 地址

這是我們問題的根源。

redis2當接收到一個連接時,它認為它來自本地主機。 Envoy 丟失了redis1的源 IP 地址,並且redis2現在無法打開與redis1的連接。

現在,我們有一些選擇:

  1. 您可以嘗試將代理模式更改為TPROXY (我嘗試過但無法使其工作)
  2. 使用 redis 內置配置變量

讓我們更仔細地看一下第二個選項,因為這對我有用。 redis.conf文件中,您可以找到以下部分:

集群碼頭/NAT 支持

在某些部署中,Redis 集群節點地址發現失敗,因為地址是 NAT-ted 或者因為端口被轉發(典型情況是 Docker 和其他容器)。

為了使 Redis 集群在這樣的環境中工作,需要每個節點都知道其公共地址的 static 配置。 此 scope 使用以下兩個選項,它們是:

  • 集群公告 IP
  • 集群公告端口
  • 集群公告總線端口

每個都向節點說明其地址、客戶端端口和集群消息總線端口。 然后將信息發布在 header 的總線數據包中,以便其他節點能夠正確地發布 map 節點的地址信息。

如果不使用上述選項,將使用正常的 Redis 集群自動檢測。

請注意,重新映射時,總線端口可能不在客戶端端口 + 10000 的固定偏移處,因此您可以根據重新映射的方式指定任何端口和總線端口。 如果未設置總線端口,將照常使用 10000 的固定偏移量。

例子:

集群公告 IP 10.1.1.5
集群公告端口 6379
集群公告總線端口 6380

我們需要設置cluster-announce-ip變量為 redis 的 pod 自己的 ip 地址。

您可以這樣做,例如像這樣修改redis-cluster ConfigMap(它是從本文修改的 redis configmap):

---
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 # <------HERE-----
      sed -i "s/MY_IP/${POD_IP}/" /redis.conf # <------HERE-----
      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 # <------HERE-----

還要記住像這樣更改容器的command以指向正確的redis.conf文件:

command: ["/conf/update-node.sh", "redis-server", "/redis.conf"]

現在,每個 redis 節點都會將此地址作為自己的地址進行通告,因此其他 redis 節點現在將知道如何與其連接。

讓我知道它是否有幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM