FRP 访问家庭内网 K8s 集群部署教程¶
目标¶
这篇教程解决的是下面这个问题:
- 家里笔记本通过
VMware跑了一套 Kubernetes 集群 - 家里没有公网 IP
- 你有一台腾讯云轻量服务器,有公网 IP
- 你希望在任何地方都能通过域名访问家里 K8s 集群里的服务
这篇教程采用的方案是:
这套方案适合什么¶
适合下面这些场景:
- 发布家里 K8s 中的博客、测试站点、管理页面
- 让公网通过域名访问你家里的实验服务
- 后续继续练 Ingress、证书、灰度、反向代理链路
这套方案不适合直接做这些事情:
- 把
kube-apiserver:6443直接暴露到公网 - 把
etcd、kubelet、Dashboard 管理端口直接暴露到公网 - 把整个内网大面积映射出去
先说整体推荐¶
如果你要做公网访问,我建议你最终采用下面这个结构:
家里环境¶
- VMware 里跑 K8s 集群
- 安装
ingress-nginx - 将
ingress-nginx controller暴露为NodePort - 在一台家里机器上运行
frpc
腾讯云轻量¶
- 开放
80 / 443 / 7000 - 运行
frps - 域名解析到腾讯云轻量公网 IP
访问链路¶
- 公网访问
app.example.com - 流量先到腾讯云轻量
frps通过隧道把请求转回家里- 家里
Ingress再按域名和路径分发到具体服务
关键原则¶
原则 1:只暴露 Ingress,不暴露控制面¶
这是整篇里最重要的原则。
公网暴露的应该是:
- 站点访问入口
- 业务服务入口
- 最多是反向代理入口
不要暴露:
64432379/2380102501025710259
这些属于控制面、etcd 或 kubelet 相关端口,不应该通过 frp 直接给公网访问。
原则 2:把“发布服务”和“远程管理”分开¶
这篇文档只解决“发布服务到公网”。
如果你后面还要远程运维,建议单独走:
- WireGuard
- 跳板机
- SSH 隧道
不要把 frp 同时拿来做所有管理入口。
你的目标拓扑¶
假设你家里 VMware 中的 K8s 环境如下:
| 角色 | 主机名 | IP |
|---|---|---|
| control plane | cp1 | 192.168.56.10 |
| worker | worker1 | 192.168.56.11 |
| worker | worker2 | 192.168.56.12 |
假设你的腾讯云轻量公网信息如下:
| 资源 | 值 |
|---|---|
| 公网 IP | 1.2.3.4 |
| 域名 | lab.example.com |
假设你后续要发布的服务域名如下:
| 域名 | 目标服务 |
|---|---|
blog.lab.example.com | 博客 |
demo.lab.example.com | 测试应用 |
第一步:在 K8s 中安装 Ingress Controller¶
如果你家里 K8s 还没有 Ingress Controller,建议安装 ingress-nginx。
安装¶
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/cloud/deploy.yaml
安装后先看:
关键说明¶
默认情况下,在裸机或实验环境里,ingress-nginx-controller 往往不是云 LB,而是:
NodePort- 或者
LoadBalancer但没有真实外部 IP
对于你这个场景,我们就是要用 NodePort。
第二步:确认 ingress-nginx 暴露方式¶
先看 controller service:
如果已经是 NodePort,记下端口。
如果不是,可以改成 NodePort:
将:
改成:
推荐端口¶
通常会生成类似:
- HTTP:
30080 - HTTPS:
30443
你也可以手动指定,但要确保不冲突。
验证¶
找一台 K8s 节点,例如 cp1,验证:
如果看到 404 Not Found,这通常是正常的,说明 ingress-nginx 已经在监听,只是还没有匹配到 Ingress 规则。
第三步:准备一个测试服务¶
先在家里 K8s 中部署一个测试 nginx,确认链路可用。
kubectl create deployment nginx-demo --image=nginx
kubectl expose deployment nginx-demo --port=80 --target-port=80 --name=nginx-demo
然后创建 Ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-demo
spec:
ingressClassName: nginx
rules:
- host: blog.lab.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-demo
port:
number: 80
应用:
关键说明¶
这里一定要先在内网侧把 Ingress 路由跑通,再去配 frp。
否则你后面很容易分不清是:
- frp 配错了
- 还是 Ingress 配错了
- 还是 Service 没挂上
第四步:在腾讯云轻量部署 frps¶
1. 下载 frp¶
在腾讯云轻量服务器上执行:
wget https://github.com/fatedier/frp/releases/download/v0.68.1/frp_0.68.1_linux_amd64.tar.gz
tar -xzf frp_0.68.1_linux_amd64.tar.gz
cd frp_0.68.1_linux_amd64
这里使用的是当前最新稳定版本 v0.68.1。
2. 编写 frps.toml¶
bindPort = 7000
vhostHTTPPort = 80
vhostHTTPSPort = 443
auth.method = "token"
auth.token = "replace-with-a-strong-token"
webServer.addr = "127.0.0.1"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "replace-with-a-strong-password"
transport.tls.force = true
3. 启动 frps¶
关键说明¶
注意 1:auth.token 一定要改¶
不要直接抄教程里的明文 token。
注意 2:Dashboard 不要直接开公网¶
这里我把:
写成了本地监听,就是避免你把管理面板直接暴露给公网。
注意 3:强制 TLS¶
建议打开,避免客户端和服务端之间走裸明文控制链路。
第五步:配置腾讯云轻量安全组¶
你至少需要开放这些端口:
| 端口 | 作用 |
|---|---|
22 | SSH |
80 | HTTP |
443 | HTTPS |
7000 | frp 控制通道 |
关键说明¶
注意 1:不要开放不必要的端口¶
尤其不要因为调试方便,就顺手把:
6443237910250
也开放出去。
注意 2:如非必要,不要开放 7500¶
Dashboard 最好只做本地访问,或者只对白名单 IP 开放。
第六步:在家里部署 frpc¶
你可以把 frpc 放在:
- 家里物理笔记本宿主机
- 家里某台 K8s 节点 VM
- 家里专门的跳板机
最简单的做法是:
- 如果宿主机能访问 VMware 内部 K8s 节点 IP,就直接部署在宿主机
下载 frp¶
在家里机器上执行:
wget https://github.com/fatedier/frp/releases/download/v0.68.1/frp_0.68.1_linux_amd64.tar.gz
tar -xzf frp_0.68.1_linux_amd64.tar.gz
cd frp_0.68.1_linux_amd64
如果你家里笔记本不是 Linux,就下载对应平台版本。
编写 frpc.toml¶
serverAddr = "1.2.3.4"
serverPort = 7000
auth.method = "token"
auth.token = "replace-with-a-strong-token"
[[proxies]]
name = "home-k8s-http"
type = "http"
localIP = "192.168.56.10"
localPort = 30080
customDomains = ["blog.lab.example.com", "demo.lab.example.com"]
[[proxies]]
name = "home-k8s-https"
type = "https"
localIP = "192.168.56.10"
localPort = 30443
customDomains = ["blog.lab.example.com", "demo.lab.example.com"]
启动 frpc¶
第七步:配置 DNS¶
你的域名解析应该指向腾讯云轻量公网 IP,而不是指向家里。
例如:
| 记录 | 值 |
|---|---|
blog.lab.example.com | 1.2.3.4 |
demo.lab.example.com | 1.2.3.4 |
第八步:验证访问链路¶
先从家里内网验证¶
先确认 Ingress 本身没问题:
如果你看到 nginx 默认页面,说明:
- Deployment 正常
- Service 正常
- Ingress 正常
- NodePort 正常
再看 frpc 日志¶
如果 frpc 成功连接,你会看到类似已注册代理的日志。
再从外网验证¶
在任意外部网络执行:
或者直接浏览器访问:
HTTPS 怎么处理¶
这是整个方案里最容易绕晕的地方。
你有 2 种做法。
做法 1:TLS 终止在家里 Ingress¶
链路:
优点:
- 证书和域名配置都在 K8s 里管理
- 更接近真实 K8s 生产入口
缺点:
- 你需要在家里 K8s 里自己处理证书
做法 2:TLS 终止在腾讯云¶
链路:
优点:
- 证书统一放在腾讯云机器上
- 公网侧证书运维更简单
缺点:
- 链路多一层
- 结构上不如“K8s 自己接 TLS”直观
我的建议¶
如果你现在目标是:
- 快速打通链路
- 先把服务发出去
建议先上:
公网 HTTP- 或者
腾讯云 TLS 终止
等后面再升级到:
家里 Ingress 直接做 HTTPS
最重要的几个注意点¶
注意 1:frpc 不要直接指向 Pod IP¶
你应该转发到:
Ingress NodePort- 或者稳定的内网代理入口
不要直接转发到某个 Pod IP,因为 Pod 会漂移。
注意 2:先把 Ingress 跑通,再配 frp¶
排障顺序建议固定:
- 先验证 Pod
- 再验证 Service
- 再验证 Ingress
- 最后验证 frp
注意 3:不要直接把 K8s 控制面穿到公网¶
特别是:
6443- Dashboard
- kubelet API
这不是“方便”,这是安全事故预备动作。
注意 4:宿主机和 VMware 内网要先互通¶
在部署 frpc 之前,先确认家里运行 frpc 的这台机器能访问:
如果这一步不通,后面所有 frp 配置都不会成功。
注意 5:Ingress 规则要用真实域名¶
你的 Ingress host 必须和 frpc 里的 customDomains 对上。
不然会出现:
- frp 通了
- 域名也通了
- 但是 ingress-nginx 一直返回默认 404
常见故障排查¶
1. 域名打不开¶
先查:
- DNS 是否解析到腾讯云公网 IP
- 腾讯云安全组是否放通
80/443 - frps 是否正常启动
2. frpc 连不上 frps¶
先查:
serverAddr是否正确7000是否放通- token 是否一致
- frps 是否已启动
3. frp 已连通,但访问仍然 404¶
这通常不是 frp 问题,而是 Ingress 问题。
先查:
- Ingress
host是否和域名一致 - ingressClass 是否正确
- Service 后端是否正常
4. Service 有对象但页面打不开¶
先查:
- Endpoints 是否生成
- Pod 是否 Ready
- Service targetPort 是否正确
5. 内网可访问,公网不可访问¶
先查:
- 腾讯云安全组
- frps 日志
- 域名解析
- frpc 是否成功注册对应域名代理
最终推荐结构¶
如果你要长期使用,我建议最终做成这样:
腾讯云轻量¶
frpsNginx或Caddy- 域名解析入口
家里 K8s¶
ingress-nginxNodePort- 所有站点都走 Ingress 统一管理
管理平面¶
公网只暴露业务入口,不暴露 K8s 控制面。
这篇教程适合接着读什么¶
建议和这些内容一起用:
后续建议¶
如果你愿意继续往下做,下一步最适合补的就是:
frp + ingress-nginx + cert-manager的 HTTPS 实战教程一台腾讯云轻量同时承载 frps + Nginx + 证书自动续期的完整架构
这样你这套家庭 K8s 发布链路就会更接近真实生产入口。