环境

  • 测试环境:私有云 Rancher(k8s)集群。
  • 正式环境:公有云 Rancher(k8s)集群。

测试环境本来可以直接通过 443 端口访问 https,最近端口被封,又不想使用其他端口,因此想通过正式环境将测试环境发布到外网。

基于 k8s 的 frp 内网穿透配置_公有云

frp

frp 是一个可用于内网穿透的高性能的反向代理应用,支持 tcp, udp 协议,为 http 和 https 应用协议提供了额外的能力,且尝试性支持了点对点穿透。

关于 frp 的配置和用法,看 ​​官方文档​​。

为了在 k8s 使用,需要制作 Docker 镜像版本,通过 dockerhub 搜索发现了下面的镜像:

基于 k8s 的 frp 内网穿透配置_公有云_02

  • DockerHub:
  • GitHub: https://github.com/snowdreamtech/frp

可以根据 Dockerfile 自己构建,如果放心也可以直接使用现成的。

frps 配置和启动

这部分是在公有云上进行配置,通过公有云转发到私有云。

frps.ini 配置

使用 ConfigMap 创建 frps.ini 配置文件:

apiVersion: v1
data:
frps.ini: |-
[common]
bind_port=31000
# 服务端和客户端的 common 配置中的 token 参数一致则身份验证通过。
token=xxxx
# 为了防止端口被滥用,可以手动指定允许哪些端口被使用
allow_ports=31001-31100
# trace, debug, info, warn, error
log_level = info
kind: ConfigMap
metadata:
name: frps
namespace:

需要指定绑定的端口,这里使用 31000,后续需要通过 nodePort 暴露出去。同时允许 frpc 客户端使用 31001~31100 范围内的端口,100个足够一般情况下的使用,同时这部分端口并不需要暴露到外网。

frps 服务配置

创建 frps Deploy 服务,yaml如下:

apiVersion: apps/v1
kind: Deployment
metadata:
labels:
workload.user.cattle.io/workloadselector: deployment-default-frps
name: frps
namespace: default
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
workload.user.cattle.io/workloadselector: deployment-default-frps
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
template:
metadata:
labels:
workload.user.cattle.io/workloadselector: deployment-default-frps
spec:
containers:
- image: snowdreamtech/frps:0.33.0
imagePullPolicy: Always
name: frps
ports:
- containerPort: 31000
name: tcp310001
protocol: TCP
volumeMounts:
- mountPath: /etc/frp
name: vol1
volumes:
- configMap:
defaultMode: 256
items:
- key: frps.ini
path: frps.ini
name: frps
optional: false
name:

配置内容是 Rancher 自动生成,移出了部分配置,这里是主要的部分。

在配置中挂载了 ConfigMap 数据卷,将 ​​frps.ini​​​ 放到了 ​​/etc/frp​​ 目录下。对外暴露了 31000 端口,这个端口也需要通过公有云的防火墙等设施允许外网访问。

启动 frps 服务后,就可以开始配置 frpc,最后在公有云配置 Ingress,先看 frpc。

frpc 配置和启动

这部分在私有云进行配置,仍然是先配置文件后服务。

frpc.ini 配置

这里的配置除了连接 frps 的基础配置外,其余的都是转发本地 k8s 中其他服务的端口。

apiVersion: v1
kind: ConfigMap
metadata:
name: frpc
namespace: default
data:
frpc.ini: |-
[common]
token=xxxx
server_addr = 公有云IP
server_port = 31000
log_level=info

[api_31001]
#/api
type = tcp
local_ip=api
local_port=8080
remote_port=31001

[ui_31002]
#/sites

注意这里的配置,token 必须和 frps 中配置的一致。

api_31001 是后端服务,用的 tomcat,所以本地端口是 8080,后端服务的名称是 ​​api​​,因此 local_ip 直接写服务名,frpc 能在网络内部 DNS 到该服务。

ui_31002 是前端服务,用的 nginx,本地端口默认80,服务名称是 ​​ui​​。

从这儿可以看到 k8s 的服务配置起来非常的方便,如果还需要其他服务,参考配置继续添加即可。

frpc 服务配置

apiVersion: apps/v1
kind: Deployment
metadata:
labels:
workload.user.cattle.io/workloadselector: deployment-default-frpc
name: frpc
namespace: default
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
workload.user.cattle.io/workloadselector: deployment-default-frpc
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
template:
metadata:
labels:
workload.user.cattle.io/workloadselector: deployment-default-frpc
spec:
containers:
- image: snowdreamtech/frpc:0.33.0
imagePullPolicy: Always
name: frpc
volumeMounts:
- mountPath: /etc/frp
name: vol1
volumes:
- configMap:
defaultMode: 256
items:
- key: frpc.ini
path: frpc.ini
name: frpc
optional: false
name:

配置内容是 Rancher 自动生成,移出了部分配置,这里是主要的部分。

在配置中挂载了 ConfigMap 数据卷,将 ​​frpc.ini​​​ 放到了 ​​/etc/frp​​ 目录下,启动后就会将 31001 和 31002 通过 frp 穿透到 frps 的服务上。

也就是说此时的 frps 容器的端口除了 31000 外,又增加了 31001 和 31002。在公有云的环境中,通过 frps 和端口已经可以访问到私有云的服务。

Service 和 Ingress 配置

这部分都在公有云进行配置。

为了能在 Ingress 中使用 frps 的 31001 和 31002 端口,先针对 frps 配置服务,这里不需要 nodePort 方式,直接用集群访问即可。

额外增加 Service 配置如下:

apiVersion: v1
kind: Service
metadata:
name: frps-port
namespace: default
spec:
selector:
workload.user.cattle.io/workloadselector: deployment-default-frps
ports:
- name: api
port: 31001
protocol: TCP
targetPort: 31001
- name: ui
port: 31002
protocol: TCP
targetPort: 31002

在 Rancher 界面上配置时,不会提供 ​​selector​​,会导致和 pod 对应不上,起不到作用,通过 yaml 方式可以解决。

注意这里的 ​​selector​​​,选择的 ​​frps​​​ 服务,和 ​​frps​​ 服务的 label 保持一致。

端口配置好后,就可以通过 Ingress 配置服务了,这部分在 Rancher 上操作时会非常的方便,示例使用了 https 方式,有预先配置好的证书,yaml 配置如下:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: 50m
name: qa
namespace: default
spec:
rules:
- host: 域名
http:
paths:
- backend:
serviceName: frps-port
servicePort: ui
path: /
- backend:
serviceName: frps-port
servicePort: api
path: /api
tls:
- hosts:
- 域名
secretName: 证书名
status:
loadBalancer:
ingress:
- ip: 负载均衡IP
- ip:

配置完成后,通过 ​​https://域名​​​ 即可访问前端,通过 ​​https://域名/api​​ 可以访问后端服务。

前后端服务在同一个域名下,也不存在跨域访问的问题。

通过上述配置的方式,利用正式环境将测试环境发布到了外网。