セットアップ

セットアップ

私はPythonを使ってシングルページアプリケーションを構築しましたフラスコフレームワークを使用していますガンコーンウェブサーバーとして、コンテナ化して使用していますドッカー. 配備されているのはAzure Kubernetes サービスアクス) とNginx イングレス コントローラー

セットアップ

私の Flask アプリは次のようになります。

src/main.py

from flask import Flask
from src.routes import main_bp


app = Flask(__name__)
app.register_blueprint(main_bp)


@app.route('/health/live')
def healthLiveMsg():
    return 'Healthy'


@app.route('/health/ready')
def healthReadyMsg():
    return 'Healthy'


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80)

src/main_bp.py

from flask import Blueprint, render_template


main_bp = Blueprint('main', __name__)

# home page
@main_bp.route('/')
def home():
    return render_template('index.html')

# some other page
@main_bp.route('/import')
def import_page():
    # some code...
    return renter_template('import.html')


# some backend job trigger
@main_bp.route('/run_job', methods=['POST'])
def run_job():
    # some code...    


def register_blueprints(app):
    app.register_blueprint(main_bp)

base.htmlナビゲーションバーがあり、Flaskの機能を使用してそれぞれurl_forホームページとインポートページへのリンクを取得しhref="{{ url_for('main.home') }}href="{{ url_for('main.import_page') }}

aks ingress は次の yaml テンプレートで定義されます。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: __AksIngress__-ingress
  namespace: __AksNamespace__
  annotations:
    nginx.ingress.kubernetes.io/proxy-buffer-size: 16k
    nginx.ingress.kubernetes.io/proxy-body-size: "0"
    nginx.ingress.kubernetes.io/server-alias: __AksNamespace__.__AksDnsZone__.__AksDomainName__
    nginx.ingress.kubernetes.io/rewrite-target: /$1
    nginx.ingress.kubernetes.io/proxy-connect-timeout: "3600"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
    nginx.ingress.kubernetes.io/server-snippet: keepalive_timeout 3600s;client_body_timeout 3600s;client_header_timeout 3600s;
spec:
  tls:
  - hosts:
    - __AksNamespace__.__AksDnsZone__.__AksDomainName__
    secretName: __AksIngress__-tls
  ingressClassName: nginx
  rules:
  - host: __AksNamespace__.__AksDnsZone__.__AksDomainName__
    http:
      paths:
      - path: /myapp/?(.*)
        pathType: Prefix
        backend:
          service:
            name: myapp-service
            port:
              number: 80

問題

aks にデプロイされると、アプリは でアクセスできますexample.com/myapp。提供されたページには、 が および であるナビゲーション バーの HTML が表示されます。hrefどちらかをクリックすると、ブラウザは に移動してプレフィックスを削除し、当然ながら 404 を返します。ページ内を移動するときに、プレフィックス (例 ) を使用して URL が正しく構築されることが期待されます。ライブネス チェックと準備チェック ( および で利用可能)は、Kubernetes によって検出されます。"/""/import"example.comexample.com/importmyappexample.com/myapp/importexample.com/myapp/health/liveexample.com/myapp/health/ready

私の試み

いくつかの解決策を試しましたが、どれも機能しませんでした。

スクリプト名

いくつか検索してみたところこのブログ投稿それは正しい解決策を示唆していました。私は dockerfile で環境変数を設定し、ローカル マシンでコンテナーを実行しましたが、確かに動作しました。

  • ホームページはlocalhost/myapp
  • ナビゲーションバーをクリックするとlocalhost/myapp/import
  • インポート ページ内のボタンをクリックすると、localhost/myapp/run_jobバックエンド ジョブがトリガーされます。

ただし、aks にデプロイした後は、すべてにプレフィックスが追加されるだけになりました。

  • ホームページは現在example.com/myapp/myapp
  • example.com/myapp/importページが現在表示されているときに、他のページに移動すると、example.com/myapp/myapp/import
  • 同様の問題はrun_job
  • さらに、Kubernetes の liveness チェックと readiness チェックも、二重プレフィックス パスの下にあるため失敗しました。

プロキシフィックス

提案された通りProxyFixを使ってみましたこのSOの回答でアプリを初期化した後、以下の行を追加しました:

app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_host=1)

しかし、これはまったく効果がなかったようです。パラメータも渡してみましたがx_prefix=1、成功しませんでした。

質問

あまりにも多くのことを読んだので、かなり混乱してしまいました。キーワードとして「flask routing with aks」を使用して回答を検索し始めましたが、次に「wsgi server」に移動し、「nginx river proxy」「nginx prefix」「nginx ingress」に移動しましたが、実際に何が起こっているのかわかりません。解決策が、、ingress.yamlgunicorn から得られるのか、それとも適応する必要があるのは flask アプリなのかはわかりません。

どのような動作が見られますか? また、どうすれば解決できますか?

このプロジェクト構造 (aks インフラストラクチャと共に) はテンプレートから構築されるため、そのようなテンプレートに追加できるソリューション、またはコードに 1 つ追加するだけで済むソリューションが必要です。

答え1

プロキシ設定に必要なX-Forwarded-Prefixヘッダー設定がありません。

からドキュメント:

X-Forwarded-Prefix ヘッダー

文字列値を含む非標準X-Forwarded-Prefixヘッダーをアップストリーム リクエストに追加するには、次のアノテーションを使用できます。

nginx.ingress.kubernetes.io/x-forwarded-prefix: "/path"

x_prefix=1もちろん引数も含めて、Proxyfix フラスコ設定と一緒に使用する必要があります。

関連情報