当我们在 Kubernetes 上工作时,有时会遇到这样的场景:我们需要从本地访问一个位于集群内部的 Redis 服务器,但出于安全考虑,这个 Redis 服务并没有直接暴露给外部。不过,集群里有一个 Pod 已经具备了访问这个 Redis 服务器的能力。
利用这个 Pod 作为跳板,我们可以安全地从本地连接到目标 Redis 服务器。由于这个 Pod 本身并不是 Redis 服务,我们不能直接使用 kubectl port-forward。相反,我们需要在 Pod 内部运行一个临时的代理进程。
下面是实现这个目标的详细步骤,可以作为你的操作笔记或博客文章。
借道 Kubernetes Pod 访问内部 Redis 服务器
步骤零:先安装必要工具
1 | apt install -y socat net-tools |
步骤一:找到你的“跳板” Pod
首先,你需要确定那个能够连接到 Redis 服务器的 Pod 的名称。你可以使用 kubectl 命令列出集群中的所有 Pod:
1 | kubectl get pods |
从列表中找到你需要的 Pod,例如它的名字是 my-redis-client-pod。
步骤二:在 Pod 内部启动一个端口转发代理
由于 Pod 本身没有 Redis 服务在运行,我们需要在它内部创建一个临时的代理。我们将使用 socat 工具来完成这项工作,它能够将流量从一个端口转发到另一个地址。
使用 kubectl exec 命令进入 Pod,并在其中运行 socat。你需要知道 Redis 服务器的实际地址(IP 或域名)和端口。
假设你的 Redis 服务器地址是 10.244.0.5:6379,执行以下命令:
1 | kubectl exec -it my-redis-client-pod -- sh -c "nohup socat TCP-LISTEN:6379,fork TCP:10.244.0.5:6379 > /tmp/socat_redis.log 2>&1 &" |
命令详解:
kubectl exec -it my-redis-client-pod: 这会进入你的目标 Pod 的交互式终端。sh -c "...": 在 Pod 的 shell 中执行后面的命令。socat TCP-LISTEN:6379,fork TCP:10.244.0.5:6379:TCP-LISTEN:6379: 让socat在 Pod 内部监听6379端口。,fork: 为每一个新的连接请求创建一个独立的进程,确保可以处理多个连接。TCP:10.244.0.5:6379: 将所有流量转发到 Redis 服务器的实际地址和端口。
重要提示:
- 请将
10.244.0.5:6379替换为你实际的 Redis 服务器地址。 - 此方法要求你的 Pod 镜像中包含
socat工具。如果缺少,你可能需要考虑使用一个包含此工具的镜像或手动安装。
此命令会持续运行,并在终端中保持阻塞状态。
步骤三:从本地执行端口转发
现在,Pod 的 6379 端口已经“活”了。接下来,你可以从本地将端口转发到这个 Pod。
打开一个新的终端窗口,并运行 kubectl port-forward 命令:
1 | kubectl port-forward my-redis-client-pod 6379:6379 |
命令详解:
- 第一个
6379: 这是你本地电脑的端口,你可以使用任何空闲端口。 - 第二个
6379: 这是 Pod 内部我们刚刚用socat启动的监听端口。
这个命令会建立一个安全的隧道,将你本地 6379 端口的流量转发到 Pod 的 6379 端口。
步骤四:从本地连接 Redis
最后一步,使用你本地的 Redis 客户端连接到 localhost 和你在上一步指定的端口。
如果你使用的是 redis-cli,只需执行:
1 | redis-cli -h 127.0.0.1 -p 6379 |
或者,如果你使用图形化 Redis 客户端(如 RedisInsight),只需将连接配置为:
- 主机 (Host):
127.0.0.1 - 端口 (Port):
6379
现在,你的连接将通过你本地的端口转发隧道,穿过 Pod 内部的 socat 代理,最终到达 Kubernetes 集群内部的 Redis 服务器。
如何结束 socat 代理?
如果你希望停止这个代理,你需要手动结束 socat 进程。
- 如果
socat在前台运行:回到运行socat的终端窗口,按Ctrl + C即可。 - 如果
socat在后台运行:你需要进入 Pod,找到并杀死该进程。
进入 Pod:
1
kubectl exec -it my-redis-client-pod -- sh
查找
socat进程的 PID:1
2
3ps aux | grep socat
or
netstat -tlnp | grep socat在输出中,你会看到
socat进程的 PID。杀死进程:
1
kill <PID>
将
<PID>替换为实际的进程 ID。
通过这种方法,你可以灵活地从本地安全地访问任何在集群内部的资源,而无需将其暴露给公共网络。
