背景
由于國內的vps要搭建網(wǎng)站都需要備案,所以目前自己的一些服務是在香港的一臺vps上;同時自己家里部署了一些服務比如nas需要在外部訪問,當前是用另一臺vps做的內網(wǎng)穿透,本著能省一點是一點的原則髓霞,遂想著將這兩個能力放到一臺vps上。
核心問題
由于不想每次訪問時還需要輸入端口號畦戒,最理想的方案肯定是都是用80/443端口來訪問方库,但這樣內網(wǎng)穿透的端口就會和ingress的端口沖突;
理想的方案是內網(wǎng)穿透的服務不直接占用主機端口障斋,而是通過域名區(qū)分纵潦,需要穿透的域名轉發(fā)到內網(wǎng)穿透服務。
解決方案
搭建步驟
vps端部署
搭建k8s集群
由于vps上資源并不富裕垃环,所以這里我使用的是k3s邀层,執(zhí)行curl -sfL https://get.k3s.io | sh - --disable traefik
,注意我后面使用了ingress nginx所以增加了--disable traefik
參數(shù)禁止默認使用traefik遂庄,理論上traefik也行寥院,但是后面ingress的配置可能會有點不同。
部署ingress nginx
# 添加官方 Nginx Ingress helm repository
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
# 使用 Helm 安裝 Nginx Ingress
helm install nginx-ingress ingress-nginx/ingress-nginx --namespace kube-system
部署frps
其他沒啥特別的涛目,只有service中注意frps的連接端口需要使用NodePort
apiVersion: v1
kind: Service
metadata:
labels:
app: frps-svc
name: frps-svc
namespace: frps
spec:
ports:
- name: server
port: 10000
protocol: TCP
targetPort: 10000
nodePort: 34567
selector:
app: frps-server
type: NodePort
部署cert manager
由于需要在k8s側就要做域名的區(qū)分只磷,所以需要將tls證書放到k8s側经磅,同時使用cert manager能夠自動進行證書的renew,簡化后續(xù)維護
helm repo add jetstack https://charts.jetstack.io --force-update
helm repo update
helm install \
cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--version v1.14.2 \
--set installCRDs=true
創(chuàng)建letsencrypt issuer
issuer有ClusterIssuer和Issuer兩種钮追,ClusterIssuer是全集群生效,一種只在對應的namespace生效阿迈,相應的ingress需要創(chuàng)建在這個namespace元媚。這里我們使用Issuer,因為我們后續(xù)需要生成泛域名證書苗沧,如果使用ClusterIssuer其中有一步報錯一直沒查到原因(可能是不支持)刊棕。泛域名證書的solver只能使用dns01,關于這里的配置可以參考這里待逞,這里我是用的是Cloudflare
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: letsencrypt-dns
namespace: frps
spec:
acme:
email: example@youmail.com
privateKeySecretRef:
name: letsencrypt-dns
server: https://acme-v02.api.letsencrypt.org/directory
solvers:
- dns01:
cloudflare:
apiTokenSecretRef:
key: api-token
name: cloudflare-api-token-secret
創(chuàng)建內網(wǎng)穿透的service
后續(xù)請求經(jīng)過ingress后通過這個service轉發(fā)到內網(wǎng)穿透服務
apiVersion: v1
kind: Service
metadata:
labels:
app: frps-http
name: frps-http
namespace: frps
spec:
ports:
- name: server-http
port: 38080
protocol: TCP
targetPort: 38080
selector:
app: frps-server
type: ClusterIP
創(chuàng)建ingress
注意這里創(chuàng)建的是泛域名的ingress甥角,這樣后續(xù)要增加服務,在vps側是不需要增加任何配置的
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: wildcard-ingress
namespace: frps
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- "*.yourdomain.com"
secretName: my-tls
rules:
- host: "*.yourdomain.com"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frps-http
port:
number: 38080
到這里识樱,在vps上的配置就ok了
內網(wǎng)服務搭建
由于家里的服務不止一個嗤无,如果經(jīng)過內網(wǎng)穿透直接映射到服務的endpoint,則frpc的配置就會變得比較復雜怜庸,vps側的service也需要配置多個端口当犯,所以我在內網(wǎng)再部署了一層nginx,再通過nginx轉發(fā)到各個服務上割疾,這樣內網(wǎng)穿透就只需要配置一個80端口即可嚎卫。nginx的具體配置這里就不列出來了,需要注意的是只需要配置listen 80端口即可宏榕,server name需要和vps側配置相同拓诸。