前言
先简单说一下我们的服务,我们的服务是基于k8s部署的,接入层负责接收请求,service层负责真正的业务逻辑。 然后service层并没有提供集群外网访问,但遇到一个业务场景,就是要调用这个服务的某个接口来处理问题,但并 不想把这个接口暴露在外网,所以就用到了今天文章的主角kubectl port-forward
来进行端口转发。
什么是端口转发?
将本地端口与集群内的 Pod 或 Service 端口建立安全隧道。它允许开发者直接访问集群内部的资源,无需暴露 Service 到外网。
基础使用
转发到 Pod
ruby
kubectl port-forward <pod-name> <local-port>:<pod-port> -n <namespace>
示例:
arduino
# 将本地 9999 转发到 default 命名空间下 某个 Pod 的 80 端口
kubectl port-forward mei-java-7f46b8dc48-76m2g 9999:80 -n default
访问 http://localhost:9999
即可访问 Pod 的服务。
转发到 Service
ruby
kubectl port-forward svc/<service-name> <local-port>:<service-port> -n <namespace>
示例:
bash
# 转发到 Service
kubectl port-forward svc/mei-java 9999:80 -n default
然后就可以使用curl构建请求,比如curl -X POST http://127.0.0.1:9999/{api路径}
多端口转发
xml
kubectl port-forward <pod-name> 8080:80 8443:443 -n <namespace>
核心原理
底层机制
port-forward
通过以下步骤实现:
-
建立与 API Server 的连接:
kubectl
首先与 Kubernetes API Server 建立长连接(基于 HTTPS)。 -
创建 SPDY 流通道:
通过 SPDY 协议(HTTP/2 前身)在本地和 API Server 之间创建双向流。
-
API Server 代理流量:
API Server 将请求转发到目标 Pod 的 Kubelet,最终到达容器端口。
网络流量路径
arduino
本地机器 → kubectl → API Server → Kubelet → 目标 Pod
- 全程加密 :所有流量经过 API Server 的 TLS 加密。
- 无外网暴露 :仅在本地和集群内部通信。
优势
- 仅本地访问,安全性高
- 无需修改集群配置
- 调整、临时访问很方便
实战场景
访问 Web 服务的内部 API
我目前遇到的场景就是需要调用服务内部API,但又不想暴露到外网,所以就用到了这个命令。
我本地没有装kubectl,我是直接在部署集群的机器上执行的。
csharp
kubectl port-forward svc/{服务名称} 9999:80 -n {命名空间}
# 浏览器访问
curl -X POST http://127.0.0.1:9999/{api路径}
就这两部轻松搞定。
高级技巧
后台运行
css
kubectl port-forward svc/{服务名称} 9999:80 -n {命名空间} &
终止后台任务:
bash
jobs -l # 查看任务ID
kill %1 # 终止任务
指定本地监听 IP
css
# 仅允许本机访问(默认)
kubectl port-forward --address 127.0.0.1 svc/{服务名称} 9999:80 -n {命名空间}
# 允许局域网访问
kubectl port-forward --address 0.0.0.0 svc/{服务名称} 9999:80 -n {命名空间}
常见问题与排查
错误: unable to listen on port 9999
-
原因 :本地端口被占用。
-
解决 :更换端口或终止占用进程:
bashlsof -i :9999 # 查看占用进程 kill -9 <PID> # 终止进程
连接中断
-
原因 :API Server 连接超时或 Pod 重启。
-
解决:
使用
--pod-running-timeout=1m
参数延长等待时间:csskubectl port-forward --pod-running-timeout=1m svc/{服务名称} 9999:80 -n {命名空间}
安全注意事项
因为我是在部署集群的机器上执行的,如果在自己的电脑上操作,需要注意以下安全问题:
-
最小权限原则:
使用低权限的
kubeconfig
文件(如仅限get
和list
操作)。 -
避免长期运行:
调试完成后及时终止
port-forward
进程。
最后
看似很简单的一个命令,掌握其原理和技巧,能极大提升开发和故障排查效率。