需求
目标: 将内网kubernetes集群中的的自签名 TLS 服务(ArgoCD)通过公网域名 example.com:5002
对外可见。
方案
有两种可行的方案:
我选择了方案2作为本教程的示例: 采用 TCP 代理类型,直接透传 HTTPS 流量。该方案最大的优势是 无需 frp 处理自签名证书,保证了端到端的加密,简化了配置,推荐用于自签名或自定义 TLS 服务的暴露。
开始
步骤如下:
- 安装示例服务(可选)
- 在公网服务器安装frp的服务端二进制文件并编写服务端(frps)配置
- 在本地(内网)安装frp的客户端二进制文件并编写客户端(frpc)配置
- 启动服务端和客户端
- 测试内网服务通过公网地址访问是否可行
安装示例服务(基于 Kubernetes/Helm)
如果你的环境不支持
LoadBalancer
暴露内网服务,那么就需要修改helm的安装参数server.service.type
参数,可以使用NodePort
,或者也可以使用Ingress
和Gateway
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的端口
检查gateway
和httproutes
, 验证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服务器配置
- 下载公网服务器的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
- 编写配置
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
配置客户端
- 下载公网服务器的frp二进制文件,将
os
和arch
改成你本地机器的系统架构
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
部署和访问步骤
-
修改 Token : 务必在
frps.toml
和frpc.toml
中将auth.token
替换为一个安全的、唯一的字符串。 -
frps 部署 : 在公网服务器上启动 frps,启动不报错即为正常运行,日志文件配置在了当前目录下的
frpc.log
bashfrps -c ./frps-argocd-custom-tls.toml
查看日志:
shcat frpc.log

确保公网服务器的防火墙已放行 TCP 端口 7000 (frp连接) 和 5002 (内网服务端口) 。
-
frpc 部署 : 在内网机器上启动 frpc,启动不报错即为正常运行,日志文件是日志文件配置在了当前目录下的
frpc.log
bashfrpc -c ./frpc-argocd-custom-tls.toml
查看日志:
shcat frpc.log

-
公网访问: 通过以下地址访问您的内网服务:
arduinohttps://example.com:5002
如果你的服务使用的是 自签名证书,浏览器访问时会提示"证书不安全/隐私错误",这是正常的,有需要可以另行配置,继续访问即可。

参考资料
- github.com/fatedier/fr...
- 完整的frps示例: github.com/fatedier/fr...
- 完整的frpc示例:github.com/fatedier/fr...