通过 AWS PrivateLink 从不同的 AWS 账户访问 AWS ElastiCache(Redis CLUSTER 模式)
Accessing AWS ElastiCache (Redis CLUSTER mode) from different AWS accounts via AWS PrivateLink
我有一个业务案例,我想从一个账户(比如说账户 A)到账户 B 访问集群 Redis 缓存。
我已经使用下面提到的解决方案 link 并且在大多数情况下,它有效 Base Solution
如果我尝试通过 redis-py
访问集群 Redis,基本解决方案工作正常,但是如果我尝试将它与 redis-py-cluster
一起使用,它会失败。
我在 Redis 集群只有一个节点的暂存环境中测试所有这些,但在生产环境中,它有两个节点,所以 redis-py
方法对我不起作用。
下面是我的示例代码
redis = "3.5.3"
redis-py-cluster = "2.1.3"
==============================
from redis import Redis
from rediscluster import RedisCluster
respCluster = 'error'
respRegular = 'error'
host = "vpce-XXX.us-east-1.vpce.amazonaws.com"
port = "6379"
try:
ru = RedisCluster(startup_nodes=[{"host": host, "port": port}], decode_responses=True, skip_full_coverage_check=True)
respCluster = ru.get('ABC')
except Exception as e:
print(e)
try:
ru = Redis(host=host, port=port, decode_responses=True)
respRegular = ru.get('ABC')
except Exception as e:
print(e)
return {"respCluster": respCluster, "respRegular": respRegular}
以上代码在账户 A 中运行完美,但在账户 B 中,我得到的输出是
{'respCluster': 'error', 'respRegular': '123456789'}
我得到的错误是
rediscluster.exceptions.ClusterError: TTL exhausted
在账户 A 中,我们使用 AWS ECS + EC2 + docker to 运行 this and
在账户 B 中,我们运行在 AWS EKS Kubernetes pod 中编译代码。
在这种情况下,我应该怎么做才能使 redis-py-cluster
正常工作?或者是否有 python 中的 redis-py-cluster
的替代方法来访问多节点 Redis 集群?
我知道这是一个非常具体的案例,我们将不胜感激。
编辑 1:经过进一步研究,TTL 耗尽似乎是一个普遍错误,在日志中初始错误是
redis.exceptions.ConnectionError:
Error 101 connecting to XX.XXX.XX.XXX:6379. Network is unreachable
这里的XXXX是A账号下Redus集群的IP。
这很奇怪,因为 redis-py
也连接到相同的 IP 和端口,
这个错误不应该存在。
根据您的评论:
this was not possible because of VPCs in Account-A and Account-B had the same CIDR range. Peered VPCs can’t have the same CIDR range.
我认为你要找的是不可能的。在 内路由 一个 VPC 总是首先发生——它发生在任何路由表被考虑之前。换句话说,如果数据包的目的地位于发送方 VPC 内,它将永远不会离开该 VPC,因为 AWS 将尝试在其自己的 VPC 内路由它,即使此时 VPC 中未使用该 IP。
因此,如果您尝试与另一个具有与您的 IP 范围相同的 IP 范围的 VPC 通信,即使您专门将出口流量路由到不同的 IP(但在同一范围内),规则将被静默忽略,AWS 将尝试在原始 VPC 中传送数据包,这似乎不是您想要完成的。
原来问题出在 redis-py-cluster
管理主机和端口的方式上。
创建新的 redis-py-cluster
对象时,它会从 Redis 服务器获取主机 IP 列表(即来自帐户 A 的 Redis 集群主机 IP),之后客户端会尝试连接到新主机,并且端口。
在正常情况下,它作为初始主机和响应中的IP是一个相同的。(即在创建对象时添加的主机和端口)
在我们的例子中,对象创建主机和端口是从帐户 B 的端点服务的 DNS 名称中获取的。
这导致代码尝试访问帐户 A 的实际 IP,而不是帐户 B 的 DNS 名称。
问题已使用Host port remapping解决,这里我们将账户A从Redis服务器返回的IP与账户B端点服务DNA名称的IP绑定。
我有一个业务案例,我想从一个账户(比如说账户 A)到账户 B 访问集群 Redis 缓存。
我已经使用下面提到的解决方案 link 并且在大多数情况下,它有效 Base Solution
如果我尝试通过 redis-py
访问集群 Redis,基本解决方案工作正常,但是如果我尝试将它与 redis-py-cluster
一起使用,它会失败。
我在 Redis 集群只有一个节点的暂存环境中测试所有这些,但在生产环境中,它有两个节点,所以 redis-py
方法对我不起作用。
下面是我的示例代码
redis = "3.5.3"
redis-py-cluster = "2.1.3"
==============================
from redis import Redis
from rediscluster import RedisCluster
respCluster = 'error'
respRegular = 'error'
host = "vpce-XXX.us-east-1.vpce.amazonaws.com"
port = "6379"
try:
ru = RedisCluster(startup_nodes=[{"host": host, "port": port}], decode_responses=True, skip_full_coverage_check=True)
respCluster = ru.get('ABC')
except Exception as e:
print(e)
try:
ru = Redis(host=host, port=port, decode_responses=True)
respRegular = ru.get('ABC')
except Exception as e:
print(e)
return {"respCluster": respCluster, "respRegular": respRegular}
以上代码在账户 A 中运行完美,但在账户 B 中,我得到的输出是
{'respCluster': 'error', 'respRegular': '123456789'}
我得到的错误是
rediscluster.exceptions.ClusterError: TTL exhausted
在账户 A 中,我们使用 AWS ECS + EC2 + docker to 运行 this and
在账户 B 中,我们运行在 AWS EKS Kubernetes pod 中编译代码。
在这种情况下,我应该怎么做才能使 redis-py-cluster
正常工作?或者是否有 python 中的 redis-py-cluster
的替代方法来访问多节点 Redis 集群?
我知道这是一个非常具体的案例,我们将不胜感激。
编辑 1:经过进一步研究,TTL 耗尽似乎是一个普遍错误,在日志中初始错误是
redis.exceptions.ConnectionError:
Error 101 connecting to XX.XXX.XX.XXX:6379. Network is unreachable
这里的XXXX是A账号下Redus集群的IP。
这很奇怪,因为 redis-py
也连接到相同的 IP 和端口,
这个错误不应该存在。
根据您的评论:
this was not possible because of VPCs in Account-A and Account-B had the same CIDR range. Peered VPCs can’t have the same CIDR range.
我认为你要找的是不可能的。在 内路由 一个 VPC 总是首先发生——它发生在任何路由表被考虑之前。换句话说,如果数据包的目的地位于发送方 VPC 内,它将永远不会离开该 VPC,因为 AWS 将尝试在其自己的 VPC 内路由它,即使此时 VPC 中未使用该 IP。
因此,如果您尝试与另一个具有与您的 IP 范围相同的 IP 范围的 VPC 通信,即使您专门将出口流量路由到不同的 IP(但在同一范围内),规则将被静默忽略,AWS 将尝试在原始 VPC 中传送数据包,这似乎不是您想要完成的。
原来问题出在 redis-py-cluster
管理主机和端口的方式上。
创建新的 redis-py-cluster
对象时,它会从 Redis 服务器获取主机 IP 列表(即来自帐户 A 的 Redis 集群主机 IP),之后客户端会尝试连接到新主机,并且端口。
在正常情况下,它作为初始主机和响应中的IP是一个相同的。(即在创建对象时添加的主机和端口)
在我们的例子中,对象创建主机和端口是从帐户 B 的端点服务的 DNS 名称中获取的。
这导致代码尝试访问帐户 A 的实际 IP,而不是帐户 B 的 DNS 名称。
问题已使用Host port remapping解决,这里我们将账户A从Redis服务器返回的IP与账户B端点服务DNA名称的IP绑定。