在谷歌 Kubernetes Engine (GKE) 中访问虚拟机 (VM) 上运行的 Redis 实例,你需要确保以下几个条件满足:
- 网络连通性:GKE 集群中的 Pod 必须能够与你的 VM 通信。这通常意味着两者应该在同一网络内,或者使用 VPCPeering 来连接不同的网络。
- Redis 端口开放:Redis 需要在 VM 上监听一个端口,并且这个端口需要在防火墙规则中开放,以便 GKE 集群中的 Pod 可以访问。
- 服务发现:Pod 需要知道如何找到 Redis 实例。这可以通过 DNS、服务发现工具或静态 IP 地址来实现。
由于你已经用 Docker 在 VM 上搭建了 Redis,并且端口映射到了宿主机上,现在需要做的是配置网络,以便 GKE 集群可以访问这个 Redis 实例。
以下是一些步骤,帮助你实现这个目标:
1. 确保网络连通性
首先,检查 GKE 集群和 VM 是否在同一网络中。如果是,它们应该可以通过内部 IP 地址通信。如果不在同一网络,你可能需要设置 VPCPeering 或 VPN 连接。
2. 验证 Redis 服务状态
在 VM 上,确认 Redis 服务正在运行,并且监听在正确的端口上。你可以使用 netstat
或 redis-cli
来检查。
netstat -tuln | grep 6379
3. 配置防火墙规则
确保 Google Cloud 的防火墙规则允许 GKE 集群的 Pod IP 范围访问 VM 上的 Redis 端口(6379)。你可以通过 Cloud Console 或 gcloud
命令行工具来配置这些规则。
4. 在 Pod 中访问 Redis
在 GKE 集群的 Pod 中,你可以使用 Redis 的 IP 地址和端口来访问它。如果你的 Redis 实例配置了密码,你还需要在连接字符串中包含密码。
这里是一个 Python 的示例,展示了如何在 Pod 中使用 redis-py
客户端来连接 Redis:
import redis
# Redis 实例的 IP 地址和端口
REDIS_HOST = '你的VM的IP地址'
REDIS_PORT = 6379
REDIS_PASSWORD = '你的Redis密码'
# 创建 Redis 客户端
r = redis.Redis(
host=REDIS_HOST,
port=REDIS_PORT,
password=REDIS_PASSWORD,
decode_responses=True
)
# 使用 Redis
r.set('foo', 'bar')
value = r.get('foo')
print(value) # 输出: 'bar'
5. 使用服务发现(可选)
如果你的 Redis 实例是集群的一部分,或者你想要更优雅地处理服务发现,你可以考虑使用 Kubernetes 的 Service 和 Endpoint 对象来抽象 Redis 实例的位置。
注意事项
- 确保 Redis 实例的安全性,不要公开 Redis 端口到公网。
- 如果你的 Redis 实例需要认证,确保在连接时提供正确的密码。
- 如果你的 Redis 实例和 GKE 集群在不同的项目中,你需要确保你有足够的权限来访问 Redis 实例。
最后,尽管教程中提到了使用 Google Memorystore for Redis,但这并不是必须的。你可以直接使用自己搭建的 Redis 实例,只要网络配置正确,GKE 集群中的 Pod 就应该能够访问它。
特地花了几块钱开了一下GKE和VM。
这里用了一个全新的命名空间操作的。
走内网的前提是 需要在同一个VPC下
我这里用的默认VPC,这里以 default 网络下的 us-central1 来作为实验的例子。
在us-central1下创建一个VM
在虚拟机里安装了redis,同时可以看到这个VM的内网IP为:10.128.0.2,和上面的子网一致。
注意,这里创建集群的时候,还是要在一个 region 里。
正在部署集群,这里的region和redis vm的一致。
这里发现端口不通
但是能ping通
添加这行规则,允许10.0.0.0/8 访问10.128.0.2:6379
测试可以在容器内正常连接redis
唯一的坑就是在防火墙的配置里,花了很多时间,也发现一个奇怪的问题。
这里的优先级按照习惯,都是设置在中间的一个值,我测试的时候写的是 2000,可是发现怎么也不生效。经过不断的测试,发现默认生成的1003-1005,会把它阻止掉。所以我这里优先级设置了200。
操作其实也其他的云也差不多。
所以GKE和VM走内网互通是完全没啥问题的。