K8s 重定向导致请求访问失败

146 阅读2分钟

这两天写了一个 Flask项目,项目中需要使用到 API Docs,找了很多都是需要嵌入到代码中的,这种会让代码变得很乱。最后还是打算延续之前的 yaml 的方式,还有就是 Flask 支持这种 Yaml 的配置,它有一个库 flask_swagger_ui。具体的代码就几行:

from flask import Flask, send_from_directory
from flask_swagger_ui import get_swaggerui_blueprint

app = Flask(__name__)

swaggerui_blueprint = get_swaggerui_blueprint(
    "/api/docs",  # Flask 内部的 URL 前缀
    "./openapi.yaml",  
    config={"app_name": "Agent Management"},
)

# 把 openapi.yaml 静态文件挂载到 /api/docs/openapi.yaml
@swaggerui_blueprint.route("/openapi.yaml")
def openapi_yaml():
    return send_from_directory("docs", "openapi.yaml")

app.register_blueprint(swaggerui_blueprint, url_prefix="/api/docs")

问题

这种方式在本地能够正常打开这个 API Docs,但是部署到 K8s中却出现了问题。这主要就是因为访问 Flask_swagger_ui 时会重定向请求。

比如:在访问 k8s 部署应用的外部地址 https://api-test-exmaple.com.cn/api/docs时,会重定向该请求,而重定向的 BaseUrl 却是 K8s的内部地址 https://api-test-exmaple.internal/api/docs。内部地址是集群内部访问的,所以就会请求失败

解决

为了解决这个问题,就需要在进行 flask_swagger_ui 配置时,正确的配置一个外部的 url,具体的修改如下:

from flask import Flask, send_from_directory
from flask_swagger_ui import get_swaggerui_blueprint

app = Flask(__name__)

EXTERNAL_SWAGGER_URL = "https://api-test-exmaple.com.cn/api/docs"
EXTERNAL_OPENAPI_YAML_URL = f"{EXTERNAL_SWAGGER_URL}/openapi.yaml"

swaggerui_blueprint = get_swaggerui_blueprint(
    "/api/docs",  # Flask 内部的 URL 前缀
    EXTERNAL_OPENAPI_YAML_URL,  # 告诉 Swagger UI 使用这个完整外部 URL 加载 openapi.yaml
    config={"app_name": "Agent Management"},
)

# 把 openapi.yaml 静态文件挂载到 /api/docs/openapi.yaml
@swaggerui_blueprint.route("/openapi.yaml")
def openapi_yaml():
    return send_from_directory("docs", "openapi.yaml")

app.register_blueprint(swaggerui_blueprint, url_prefix="/api/docs")

这样在重定向时,返回给浏览器的就是外部地址了,就能正确的打开 swagger

总结

之前在写 swagger文档时,会把整个 swagger-ui放到路由下面,包括那些 css,js文件。而这次只有一个 yaml文档,其他的文档都是通过 flask_swagger_ui 访问,所以就出现了这个问题