谷歌 k8s 怎么访问虚拟机里面的自己搭建的 redis?

谷歌 k8s 怎么访问虚拟机里面的自己搭建的 redis?

我在 谷歌的虚拟机,用 docker 和 docker-compose 自己起了一个 redis

version: "3"

services:
  redis:
    container_name: redis
    restart: always
    image: redis:7.2.4-bookworm
    ports:
      - "6379:6379"
    volumes:
      - ./volumes:/data
      - ./redis.conf:/etc/redis/redis.conf
    command: redis-server /etc/redis/redis.conf --requirepass 543cm7U7ecMv

现在部署在谷歌 k8s 的 pod 需要访问这个虚拟机中的 redis,我希望可以走内网

但是我知道怎么做?找到了一个教程:从 Google Kubernetes Engine 集群连接到 Redis 实例 但是这个教程太复杂了,还需要使用 gcloud 创建 redis 实例?用 docker 跑的 redis 还不行?

上面的链接好像是谷歌自己的 memorystore for redis,而不是真的 redis
阅读 663
avatarAI BotBETA

在谷歌 Kubernetes Engine (GKE) 中访问虚拟机 (VM) 上运行的 Redis 实例,你需要确保以下几个条件满足:

  1. 网络连通性:GKE 集群中的 Pod 必须能够与你的 VM 通信。这通常意味着两者应该在同一网络内,或者使用 VPCPeering 来连接不同的网络。
  2. Redis 端口开放:Redis 需要在 VM 上监听一个端口,并且这个端口需要在防火墙规则中开放,以便 GKE 集群中的 Pod 可以访问。
  3. 服务发现:Pod 需要知道如何找到 Redis 实例。这可以通过 DNS、服务发现工具或静态 IP 地址来实现。

由于你已经用 Docker 在 VM 上搭建了 Redis,并且端口映射到了宿主机上,现在需要做的是配置网络,以便 GKE 集群可以访问这个 Redis 实例。

以下是一些步骤,帮助你实现这个目标:

1. 确保网络连通性

首先,检查 GKE 集群和 VM 是否在同一网络中。如果是,它们应该可以通过内部 IP 地址通信。如果不在同一网络,你可能需要设置 VPCPeering 或 VPN 连接。

2. 验证 Redis 服务状态

在 VM 上,确认 Redis 服务正在运行,并且监听在正确的端口上。你可以使用 netstatredis-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 就应该能够访问它。

2 个回答

特地花了几块钱开了一下GKE和VM。
这里用了一个全新的命名空间操作的。

  1. 内网第一步: VPC
    走内网的前提是 需要在同一个VPC下
    我这里用的默认VPC,这里以 default 网络下的 us-central1 来作为实验的例子。
    image.png
    image.png
  2. 创建一个 redis VM 实例,注意这里的 region 和网络接口配置。
    在us-central1下创建一个VM
    image.png
    image.png
    在虚拟机里安装了redis,同时可以看到这个VM的内网IP为:10.128.0.2,和上面的子网一致。
    image.png
  3. 准备一个GKE集群
    注意,这里创建集群的时候,还是要在一个 region 里。
    image.png
    image.png
    正在部署集群,这里的region和redis vm的一致。
    image.png
  4. 创建两个测试用的Pod
    image.png
    image.png
    这里发现端口不通
    image.png
    但是能ping通
    image.png
  5. 检查防火墙策略
    添加这行规则,允许10.0.0.0/8 访问10.128.0.2:6379
    image.png
    测试可以在容器内正常连接redis
    image.png

唯一的坑就是在防火墙的配置里,花了很多时间,也发现一个奇怪的问题。
这里的优先级按照习惯,都是设置在中间的一个值,我测试的时候写的是 2000,可是发现怎么也不生效。经过不断的测试,发现默认生成的1003-1005,会把它阻止掉。所以我这里优先级设置了200。

操作其实也其他的云也差不多。

所以GKE和VM走内网互通是完全没啥问题的。
image.png

一般pod访问外部网络的路径是:pod ip -- pod所在k8s节点的ip --- 目的ip,所以你这里只需要把k8s节点的ip和redis所在节点ip的网络打通就可以了,这里面就要看你的k8s节点和redis节点是不是在同一个vpc里面了,如果是同一个vpc默认网络就是通的,如果是不同的vpc,那你就要配置路由将2个vpc打通。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏