美文网首页
基于k8s的内网穿透与服务共存

基于k8s的内网穿透与服务共存

作者: 小李子Levy | 来源:发表于2024-02-13 18:27 被阅读0次

    背景

    由于国内的vps要搭建网站都需要备案,所以目前自己的一些服务是在香港的一台vps上;同时自己家里部署了一些服务比如nas需要在外部访问,当前是用另一台vps做的内网穿透,本着能省一点是一点的原则,遂想着将这两个能力放到一台vps上。

    核心问题

    由于不想每次访问时还需要输入端口号,最理想的方案肯定是都是用80/443端口来访问,但这样内网穿透的端口就会和ingress的端口冲突;
    理想的方案是内网穿透的服务不直接占用主机端口,而是通过域名区分,需要穿透的域名转发到内网穿透服务。

    解决方案

    搭建步骤

    vps端部署

    搭建k8s集群

    由于vps上资源并不富裕,所以这里我使用的是k3s,执行curl -sfL https://get.k3s.io | sh - --disable traefik,注意我后面使用了ingress nginx所以增加了--disable traefik参数禁止默认使用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侧就要做域名的区分,所以需要将tls证书放到k8s侧,同时使用cert manager能够自动进行证书的renew,简化后续维护

    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
    

    创建letsencrypt issuer

    issuer有ClusterIssuer和Issuer两种,ClusterIssuer是全集群生效,一种只在对应的namespace生效,相应的ingress需要创建在这个namespace。这里我们使用Issuer,因为我们后续需要生成泛域名证书,如果使用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
    

    创建内网穿透的service

    后续请求经过ingress后通过这个service转发到内网穿透服务

    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
    

    创建ingress

    注意这里创建的是泛域名的ingress,这样后续要增加服务,在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了

    内网服务搭建

    由于家里的服务不止一个,如果经过内网穿透直接映射到服务的endpoint,则frpc的配置就会变得比较复杂,vps侧的service也需要配置多个端口,所以我在内网再部署了一层nginx,再通过nginx转发到各个服务上,这样内网穿透就只需要配置一个80端口即可。nginx的具体配置这里就不列出来了,需要注意的是只需要配置listen 80端口即可,server name需要和vps侧配置相同。

    相关文章

      网友评论

          本文标题:基于k8s的内网穿透与服务共存

          本文链接:https://www.haomeiwen.com/subject/wesjadtx.html