☸️

自宅 kubernetes で cloudflare-tunnel-ingress-controller を使ってお手軽外部公開

に公開

この記事は Akatsuki Games Advent Calendar 2024 の 16日目の記事です。

はじめに

アカツキゲームスでサーバーエンジニアをやっている濱田です。
サーバーエンジニアの中には、自宅サーバーを盆栽のように育てて楽しむ方も多いと思います。その盆栽遊びの一環として、自宅サーバー上で動作するアプリケーションをインターネットに公開したいと思うこともあるでしょう。
しかし、自宅サーバーをインターネットに公開するためには、通常グローバルIPが必要です。それがない場合、公開は面倒になります。そこで役立つのが cloudflare tunnel です。cloudflare tunnel を使用すれば、グローバルIPがなくても自宅サーバーのサービスを簡単に外部に公開することができます。

さらに、cloudflare cunnel の設定は少々面倒な部分もありますが(GUIポチポチなど)、それをKubernetes リソースの Ingress として簡単に実現するツールがあります。それが cloudflare-tunnel-ingress-controller です。
本記事では、この cloudflare-tunnel-ingress-controller について紹介します。これを使えば、自宅サーバーのサービスを外部に公開する作業が一段と簡単になります。

前提

  • 自宅サーバー上に kubernetes を載せてで遊んでいる状態
  • cloudflare でドメインを買っている

Cloudflare Tunnel とは?

https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/

詳しくはドキュメントを参照ください。
ざっくり言うと、自身のPCと cloudflare のサーバーにトンネルを張ってくれる君です。
hoge.mydomain.com -> cloudflared -> localhost:1234 のような経路ができます。

インストール

https://github.com/STRRL/cloudflare-tunnel-ingress-controller

helm repo が用意されているので、 argocd application でサクッと。
これで ingressClassName: cloudflare とすると、Ingress として cloudflare tunnel を定義できるようになります。

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: cloudflare-tunnel-ingress-controller
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://helm.strrl.dev
    chart: cloudflare-tunnel-ingress-controller
    targetRevision: 0.0.12
    helm:
      valuesObject:
        cloudflare:
          apiToken: hoge
          accountId: hoge
          tunnelName: cf-tunnel-ingress-controller

  destination:
    server: https://kubernetes.default.svc
    namespace: cloudflare-tunnel-ingress-controller
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true
      - ServerSideApply=true

使っていく

例として、自作アプリと Grafana をデプロイする際に cloudflare tunnel を使ってみます。

自作アプリのデプロイ

deployment, service は省略。
ingressClassName: "cloudflare" として Imgress を定義するだけ。
これで my-app.example.com への http 通信が my-app-service へと転送されます。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-app-ingress
spec:
  ingressClassName: "cloudflare"
  rules:
  - host: my-app.example.com
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: my-app-service
            port:
              number: 8080

Grafanaのデプロイ

この helm chart を使う。
https://artifacthub.io/packages/helm/grafana/grafana

helmでデプロイする際は、大抵 ingress がついているのでそちらに ingressClassName を指定する。

ingress:
  enabled: true
  ingressClassName: "cloudflare"
  hosts:
    - host: grafana.example.com
      paths:
        - path: /
          pathType: Prefix
  service:
    port: 3000

まとめ

yamlをチャチャっと書くだけで外部公開ができて便利ですね!yamlなのでgit管理も可能で嬉しい!
cloudflare tunnel 以外のリソースも yaml で管理したい!となってきたのでこちらも気になっています。

https://github.com/adyanth/cloudflare-operator

Discussion