云原生之旅:TCP 穿透,轻松暴露内网服务到公网

需求

目标: 将内网kubernetes集群中的的自签名 TLS 服务(ArgoCD)通过公网域名 example.com:5002 对外可见。

方案

有两种可行的方案:

我选择了方案2作为本教程的示例: 采用 TCP 代理类型,直接透传 HTTPS 流量。该方案最大的优势是 无需 frp 处理自签名证书,保证了端到端的加密,简化了配置,推荐用于自签名或自定义 TLS 服务的暴露。

开始

步骤如下:

  1. 安装示例服务(可选)
  2. 在公网服务器安装frp的服务端二进制文件并编写服务端(frps)配置
  3. 在本地(内网)安装frp的客户端二进制文件并编写客户端(frpc)配置
  4. 启动服务端和客户端
  5. 测试内网服务通过公网地址访问是否可行

安装示例服务(基于 Kubernetes/Helm)

如果你的环境不支持LoadBalancer暴露内网服务,那么就需要修改helm的安装参数server.service.type参数,可以使用NodePort,或者也可以使用IngressGateway

kubernetes的gateway示例,如果使用了gateway-api,那么server.service.type就可以保持默认的ClusterIP值, 这里使用HTTPRoute演示,有安全需求也可以使用TLSRoute

yml 复制代码
# gateway.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: argocd-gateway
  namespace: argocd
spec:
#  addresses:
#    - type: IPAddress
#      value: 192.168.3.106
  # 替换成你集群中实际安装的 Gateway Controller Class 名称
  gatewayClassName: cilium
  listeners:
    - name: server
      protocol: HTTP
      port: 443
---
# argocd-server-httproute.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: argocd-server
  namespace: argocd
spec:
  parentRefs:
    - name: argocd-gateway # 绑定到上面创建的 Gateway
  hostnames:
    - "argocd.app.com" # 替换成你的域名
  rules:
    - matches:
        # 需要匹配的路径
        - path:
            type: PathPrefix
            value: /
      backendRefs:
        - name: argocd-server
          port: 443 # 路由到 argocd server的端口

检查gatewayhttproutes, 验证PROGRAMMED是否为True

sh 复制代码
kubectl get gateway,httproutes -n argocd
bash 复制代码
#!/usr/bin/env bash
# 启用 POSIX 模式并设置严格的错误处理机制
set -o posix errexit -o pipefail

# https://github.com/argoproj/argo-helm/tree/main

mkdir -pv /home/kubernetes/argocd
cd /home/kubernetes/argocd

#git clone --depth 1 https://github.com/argoproj/argo-helm.git
helm repo add argo https://argoproj.github.io/argo-helm
helm pull argo/argo-cd
tar -zxvf argo-cd-*.tgz

cat > new-values.yaml <<EOF
controller:
  replicas: 1

server:
  ## Argo CD server Horizontal Pod Autoscaler
  autoscaling:
    enabled: false
    minReplicas: 2

repoServer:
  autoscaling:
    enabled: false
    minReplicas: 2

applicationSet:
  replicas: 1

server:
  replicas: 1
  service:
    type: LoadBalancer
  ingress:
    enabled: false
    ingressClassName: nginx
    annotations:
      nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
      nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
#    extraTls:
#      - hosts:
#        - argocd.example.com
#        # Based on the ingress controller used secret might be optional
#        secretName: wildcard-tls
EOF

helm upgrade --install argocd \
./argo-cd \
-n argocd \
--create-namespace \
-f new-values.yaml

列出安装的信息

sh 复制代码
helm ls -n argocd

检查服务

确保每个Pod都是Running状态,目前安装的argocd是无状态应用,一般只需要确认为Running状态基本就可以判定为服务正常运行了

bash 复制代码
kubectl get po,svc,secret -n argocd

记录其内网 IP 及端口。本例子是192.168.3.107:443

等待Pod安装部署完成后,测试访问:

sh 复制代码
curl -k -v https://argocd.app.com

检查示例服务响应的状态码,200即为正常

frps服务器配置

  1. 下载公网服务器的frp二进制文件
bash 复制代码
os="linux"
arch="amd64"
version="v0.65.0"
wget https://github.com/fatedier/frp/releases/download/$version/frp_$version_$os_$arch.tar.gz
tar -zxvf frp_$version_$os_$arch.tar.gz
cp frp_$version_$os_$arch/* /usr/local/bin
  1. 编写配置
bash 复制代码
cat > frps-argocd-custom-tls.toml <<EOF
# 基础配置
bindAddr = "0.0.0.0"
bindPort = 7000          # frpc 客户端连接到 frps 的端口

# HTTP/HTTPS 虚拟主机端口(TCP 透传不需要,但保持默认配置以备将来使用)
vhostHTTPPort = 80
vhostHTTPSPort = 443

# Dashboard 配置 (可选,用于监控)
webServer.addr = "127.0.0.1"
webServer.port = 7500
webServer.user = "admin"
webServer.password = "admin"

# 认证配置
auth.method = "token"
auth.token = "YOUR_SECURE_TOKEN_FOR_FRP" # <--- 修改为一个安全的 Token
# 将 YOUR_SECURE_TOKEN_FOR_FRP 替换为一个随机字符串,frpc 需使用相同的值。

log.to = "./frps.log"
log.level = "info"
EOF

配置客户端

  1. 下载公网服务器的frp二进制文件,将osarch改成你本地机器的系统架构
bash 复制代码
os="darwin"
arch="arm64"
version="v0.65.0"
wget https://github.com/fatedier/frp/releases/download/$version/frp_$version_$os_$arch.tar.gz
tar -zxvf frp_$version_$os_$arch.tar.gz
cp frp_$version_$os_$arch/* /usr/local/bin

该配置将内网的HTTPS 服务 (192.168.3.107:443) 映射到 frps 的 5002 端口上。

sh 复制代码
cat > frpc-argocd-custom-tls.toml <<EOF
# 您的 frps 服务器地址和端口
# 请根据您的实际 frps 部署地址进行修改
serverAddr = "apikv.com"
serverPort = 7000 # 假设您的 frps 监听在 7000 端口

#user = "your_argocd_user" # 可选,建议设置一个唯一标识
#loginFailExit = true

# 日志配置
log.to = "./frpc.log"
log.level = "info"
log.maxDays = 3

# 认证配置
#auth.method = "token"
#auth.token = "12345678" # **替换为您 frps 配置中实际的 token

# 传输配置
# 保持默认的 TLS 连接到 frps,增加安全性
transport.tls.enable = true
transport.protocol = "tcp"

# 代理配置
# --------------------------------------------------

[[proxies]]
# 代理名称,建议命名具有辨识度
name = "argocd_https_tcp"
# 使用 tcp 协议进行透传
type = "tcp"
# 内网 ArgoCD 服务器的 IP 和 HTTPS 端口
localIP = "192.168.3.107"
localPort = 443
# frps 服务器上监听的公网端口
remotePort = 5002

# 如果您希望增加一层加密和压缩,可以启用(但会增加 CPU 开销)
# transport.useEncryption = true
# transport.useCompression = false

# 可选:如果您的 frps 启用了健康检查或负载均衡
# healthCheck.type = "tcp"
# healthCheck.timeoutSeconds = 3
# healthCheck.maxFailed = 3
# healthCheck.intervalSeconds = 10
EOF

部署和访问步骤

  1. 修改 Token : 务必在 frps.tomlfrpc.toml 中将 auth.token 替换为一个安全的、唯一的字符串。

  2. frps 部署 : 在公网服务器上启动 frps,启动不报错即为正常运行,日志文件配置在了当前目录下的frpc.log

    bash 复制代码
    frps -c ./frps-argocd-custom-tls.toml

    查看日志:

    sh 复制代码
    cat frpc.log

确保公网服务器的防火墙已放行 TCP 端口 7000 (frp连接) 和 5002 (内网服务端口)

  1. frpc 部署 : 在内网机器上启动 frpc,启动不报错即为正常运行,日志文件是日志文件配置在了当前目录下的frpc.log

    bash 复制代码
    frpc -c ./frpc-argocd-custom-tls.toml

    查看日志:

    sh 复制代码
    cat frpc.log
  1. 公网访问: 通过以下地址访问您的内网服务:

    arduino 复制代码
    https://example.com:5002

    如果你的服务使用的是 自签名证书,浏览器访问时会提示"证书不安全/隐私错误",这是正常的,有需要可以另行配置,继续访问即可。

参考资料

  1. github.com/fatedier/fr...
  2. 完整的frps示例: github.com/fatedier/fr...
  3. 完整的frpc示例:github.com/fatedier/fr...
相关推荐
it_czz1 天前
LangSmith vs LangFlow vs LangGraph Studio 可视化配置方案对比
后端
蓝色王者1 天前
springboot 2.6.13 整合flowable6.8.1
java·spring boot·后端
花哥码天下1 天前
apifox登录后设置token到环境变量
java·后端
hashiqimiya1 天前
springboot事务触发滚动与不滚蛋
java·spring boot·后端
TeamDev1 天前
基于 Angular UI 的 C# 桌面应用
前端·后端·angular.js
PPPHUANG1 天前
一次 CompletableFuture 误用,如何耗尽 IO 线程池并拖垮整个系统
java·后端·代码规范
用户8356290780511 天前
用Python轻松管理Word页脚:批量处理与多节文档技巧
后端·python
想用offer打牌1 天前
一站式了解Spring AI Alibaba的流式输出
java·人工智能·后端
秋说1 天前
华为 DevKit 25.2.rc1 源码迁移分析使用教程(openEuler + ARM64)
后端
ServBay1 天前
C# 成为 2025 年的编程语言,7个C#技巧助力开发效率
后端·c#·.net