설정

설정

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)

에는 Flask의 기능을 사용하여 홈 페이지와 가져오기 페이지에 대한 링크를 각각 가져오는 base.html탐색 모음이 있습니다 .url_forhref="{{ url_for('main.home') }}href="{{ url_for('main.import_page') }}

aks 수신은 다음 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. 제공된 페이지에는 hrefs "/"및 가 있는 탐색 모음의 HTML이 표시됩니다 "/import". 둘 중 하나를 클릭하면 브라우저는 접두사를 찾아 삭제 하고 example.com물론 404를 입력합니다. 페이지를 탐색할 때 URL이 접두사(예: )를 사용하여 올바르게 구축될 것으로 예상됩니다 . 활성 및 준비 상태 검사( 및 에서 사용 가능 )는 Kubernetes에서 찾을 수 있습니다.example.com/importmyappexample.com/myapp/importexample.com/myapp/health/liveexample.com/myapp/health/ready

내 시도

나는 여러 가지 해결책을 시도했지만 그 중 아무 것도 효과가 없었습니다.

SCRIPT_NAME

몇번의 검색 끝에 찾아낸이 블로그 게시물그것은 올바른 해결책을 암시했습니다. dockerfile에 환경 변수를 설정하고 로컬 컴퓨터에서 컨테이너를 실행했는데 예, 작동 중이었습니다.

  • 홈페이지는 다음 위치에 있었습니다.localhost/myapp
  • navbar를 클릭하면 나에게 다음과 같은 메시지가 전송됩니다.localhost/myapp/import
  • localhost/myapp/run_job백엔드 작업을 트리거하기 위해 게시된 가져오기 페이지의 버튼을 클릭합니다 .

그러나 aks에 배포한 후에는 모든 항목에 추가 접두사가 생겼습니다.

  • 홈페이지는 지금 있었어example.com/myapp/myapp
  • 다른 페이지로 이동하면 example.com/myapp/import해당 페이지가 현재 위치에 있을 때 나에게 전송되었습니다.example.com/myapp/myapp/import
  • 와 비슷한 문제run_job
  • 또한 활성 상태 및 준비 상태는 이중 접두사 경로 아래에서도 kubernetes가 실패하는지 확인합니다.

ProxyFix

제안된 대로 ProxyFix를 사용해 보았습니다.이 SO 답변에서앱을 초기화한 후 아래 줄을 추가했습니다.

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

그러나 이것은 전혀 효과가 없었던 것 같습니다. 매개변수 도 전달하려고 시도했지만 x_prefix=1성공하지 못했습니다.

질문

너무 많은 내용을 읽었기 때문에 지금은 상당히 혼란스럽습니다. "aks를 사용한 플라스크 라우팅"을 키워드로 사용하여 답변을 검색하기 시작한 다음 "wsgi 서버"로 이동한 다음 "nginx 역방향 프록시" "nginx 접두사" 또는 "nginx ingress"로 이동했는데 실제로 무엇인지 잘 모르겠습니다. 사고. 솔루션이 ingress.yamlGunicorn에서 나와야 하는지 아니면 적응해야 하는 플라스크 앱인지 잘 모르겠습니다 .

현재 나타나는 동작은 무엇이며 어떻게 해결합니까?

이 프로젝트 구조(aks 인프라와 함께)는 템플릿에서 구축되었기 때문에 이러한 템플릿에 추가할 수 있거나 코드에 단일 추가가 될 수 있는 솔루션을 원합니다.

답변1

프록시 구성에 필요한 X-Forwarded-Prefix헤더 구성이 누락되었습니다.

에서문서:

X-Forwarded-Prefix 헤더

문자열 값을 사용하여 업스트림 요청에 비표준 X-Forwarded-Prefix헤더를 추가하려면 다음 주석을 사용할 수 있습니다.

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

x_prefix=1이는 물론 인수를 포함하여 Proxyfix 플라스크 구성과 함께 사용해야 합니다 .

관련 정보