k8s ingressの後ろでFastAPIのDocsを見たい


動機

  • FastAPI使いたい
  • k8sとnext.jsと一緒に使いたい
  • パスを楽に設定したい
  • 開発中はswaggerのdocsにもアクセスしたい ← ココ!

結論

  • この設定でいける
  1. FastAPIのroot_pathを設定する
  2. Ingressのrewrite-targetを設定する

環境

  • Hyper-VにUbuntu 20.04
  • minikube

前提

1. FastAPIのroot_pathを設定する

1-1. DeploymentとServiceの定義

  • ROOT_PATH環境変数を定義するだけ
  • FastAPIから取得するため
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-depl
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
        - name: myapp
          image: me/fastapi-myapp
          env:

      # !!!ROOT_PATH環境変数の設定!!!
          - name: ROOT_PATH
            value: '/api/v1/myapp'

---
apiVersion: v1
kind: Service
metadata:
  name: myapp-srv
spec:
  selector:
    app: myapp
  ports:
    - name: myapp
      protocol: TCP
      port: 8000
      targetPort: 8000

1-2. FastAPIの設定

  • root_pathに1-1で定義したパスを設定
import os
from fastapi import FastAPI, Request
from routers import my_module

# 詳細はここ https://fastapi.tiangolo.com/advanced/behind-a-proxy/ 
app = FastAPI(root_path=os.getenv('ROOT_PATH', ''))

@app.get("/")
def read_root(request: Request):
    return {"message": "Hello World", "root_path": request.scope.get("root_path")}

2. Ingressの定義

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-service
  annotations:
    kubernetes.io/ingress.class: nginx
    # cluster外(ブラウザとか)からのリクエストパスを書き換えてくれる設定
    # https://kubernetes.github.io/ingress-nginx/examples/rewrite/
    nginx.ingress.kubernetes.io/rewrite-target: /$2

    nginx.ingress.kubernetes.io/use-regex: 'true'
spec:
  rules:
    - host: fastapi.dev
      http:
        paths:
      # 正規表現で2番目にマッチしたパスに書き換えてFastAPIにリクエストする
          - path: /api/v1/myapp(/|$)(.*)
            pathType: Prefix
            backend:
              service:
                name: myapp-srv
                port:
                  number: 8000

確認

バックエンド側のパスを書き換えずに、yamlとmain.pyの設定だけでできました。超絶楽ちん。すばらし!