如何使用服务名称在 Kubernetes 集群中交流 Swagger UI 和 API? [英] How to communicate Swagger UI and API in Kubernetes cluster using service names?

查看:39
本文介绍了如何使用服务名称在 Kubernetes 集群中交流 Swagger UI 和 API?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 Pod 内的 Kubernetes 集群上的 Docker 容器内运行了一个 node.js API.Pod 连接到 LoadBalancer 类型的 Kubernetes 服务,因此我可以从外部连接到它,也可以从 Swagger UI 连接到它,方法是将 API IP 地址传递给作为同一 Kubernetes 集群上的另一个 Docker 容器运行的 Swagger UI <代码>http://:<端口>/swagger.json.

但在我的情况下,我想使用像这样的服务名称通过 Swagger UI 调用 API 端点 api-service.default:<port>/swagger.json 而不是使用外部API IP 地址.

对于 Swagger UI,我使用的是来自此处的最新版本的 swaggerapi/swagger-ui docker 图像:

这个机制将我从浏览器级别调用的 API 请求重定向到内部集群服务名称:api-service.default:8080 nginx 服务器实际运行的位置.我的意思是 nginx 在集群上运行,而不是浏览器.

不幸的是,我不知道如何在那个大摇大摆的 ui 案例中实现这一点.

Swagger mainfest 文件:

# SERVICEapi版本:v1种类:服务元数据:名称:swagger-service标签:种类:招摇服务规格:选择器:层:api文档端口:- 协议:'TCP'端口:80目标端口:8080类型:负载均衡器---# 部署api 版本:应用程序/v1种类:部署元数据:名称:招摇部署标签:种类:招摇部署规格:复制品:1选择器:匹配标签:层:api文档模板:元数据:标签:层:api文档规格:容器:- 名称:招摇图片:swaggerapi/swagger-uiimagePullPolicy:始终环境:- 名称:网址值:'http://api-service.default:8080/swagger.json'

API 清单文件:

# SERVICEapi版本:v1种类:服务元数据:名称:api服务标签:种类:api服务规格:选择器:层:后端端口:- 协议:'TCP'端口:8080目标端口:8080类型:负载均衡器---# 部署api 版本:应用程序/v1种类:部署元数据:名称:api-部署标签:种类:api-部署规格:复制品:1选择器:匹配标签:层:后端模板:元数据:标签:层:后端规格:容器:- 名称:api图像:<my-api-image>:最新

解决方案

我通过将 nginx 反向代理添加到 swagger UI 容器中的/etc/nginx/nginx.conf 文件解决了这个问题,该容器会将所有以/swagger.json 结尾的请求重定向到API 服务.

此文件更改后需要重新加载nginx服务器:nginx -s reload

服务器{听8080;server_name 本地主机;index index.html index.htm;位置/swagger.json {proxy_pass http://api-service.default:8080/swagger.json;}地点/{absolute_redirect 关闭;别名/usr/share/nginx/html/;过期 1 天;位置 ~* \.(?:json|yml|yaml)$ {#SWAGGER_ROOT过期 -1;包括 cors.conf;}包括 cors.conf;}

重要是仅将 /swagger.json 分配给 SwaggerUI 容器的 ENV.这是强制性的,因为请求必须路由到 nginx 才能得到解析.

Swagger 清单

# SERVICEapi版本:v1种类:服务元数据:名称:swagger-service标签:种类:招摇服务规格:选择器:层:api文档端口:- 协议:'TCP'端口:80目标端口:8080类型:负载均衡器---# 部署api 版本:应用程序/v1种类:部署元数据:名称:招摇部署标签:种类:招摇部署规格:复制品:1选择器:匹配标签:层:api文档模板:元数据:标签:层:api文档规格:容器:- 名称:招摇图片:swaggerapi/swagger-uiimagePullPolicy:始终环境:- 名称:网址值:'/swagger.json'

I have a node.js API run inside a Docker container on Kubernetes cluster within a pod. The pod is connected to Kubernetes service of type LoadBalancer, so I can connect to it from outside, and also from the Swagger UI, by passing to the Swagger UI which is run as another Docker container on the same Kubernetes cluster an API IP address http://<API IP address>:<port>/swagger.json.

But in my case I would like to call the API endpoints via Swagger UI using the service name like this api-service.default:<port>/swagger.json instead of using an external API IP address.

For Swagger UI I' am using the latest version of swaggerapi/swagger-ui docker image from here: https://hub.docker.com/r/swaggerapi/swagger-ui

If I try to assign the api-service.default:<port>/swagger.json to Swagger-UI container environment variable then the Swagger UI result is: Failed with load API definition

Which I guess is obvious because the browser does not recognize the internal cluster service name.

Is there any way to communicate Swagger UI and API in Kubernetes cluster using service names?

--- Additional notes ---

The Swagger UI CORS error is misleading in that case. I am using this API from many other services.

I have also tested the API CORS using cURL.

I assume that swagger-ui container inside a pod can resolve that internal cluster service name, but the browser cannot because the browser works out of my Kubernetes cluster.

On my other web services running in the browser (out of my cluster) served on nginx which also consumes this API, I use the nginx reverse proxy mechanizm.

https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/

This mechanizm redirects my API request invoked from the browser level to the internal cluster service name: api-service.default:8080 where the nginx server is actually running. I mean the nginx is runnig on the cluster, browser not.

Unfortunately, I dont't how to achive this in that swagger ui case.

Swagger mainfest file:

# SERVICE
apiVersion: v1
kind: Service
metadata:
  name: swagger-service
  labels:
    kind: swagger-service
spec:
  selector:
    tier: api-documentation
  ports:
    - protocol: 'TCP'
      port: 80
      targetPort: 8080
  type: LoadBalancer
---
# DEPLOYMENT
apiVersion: apps/v1
kind: Deployment
metadata:
  name: swagger-deployment
  labels:
    kind: swagger-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      tier: api-documentation
  template:
    metadata:
      labels:
        tier: api-documentation
    spec:
      containers:
        - name: swagger
          image: swaggerapi/swagger-ui
          imagePullPolicy: Always
          env:
            - name: URL
              value: 'http://api-service.default:8080/swagger.json'

API manifest file:

# SERVICE
apiVersion: v1
kind: Service
metadata:
  name: api-service
  labels:
    kind: api-service
spec:
  selector:
    tier: backend
  ports:
    - protocol: 'TCP'
      port: 8080
      targetPort: 8080
  type: LoadBalancer
---
# DEPLOYMENT
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-deployment
  labels:
    kind: api-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      tier: backend
  template:
    metadata:
      labels:
        tier: backend
    spec:
      containers:
        - name: api
          image: <my-api-image>:latest

解决方案

I solved it by adding nginx reverse proxy to /etc/nginx/nginx.conf file in swagger UI container which redirects all requests ended with /swagger.json to the API service.

After this file changes you need to reload the nginx server: nginx -s reload

server {
    listen            8080;
    server_name       localhost;
    index             index.html index.htm;
    
    location /swagger.json {
      proxy_pass http://api-service.default:8080/swagger.json;
    }

    location / {
      absolute_redirect off;
      alias            /usr/share/nginx/html/;
      expires 1d;

      location ~* \.(?:json|yml|yaml)$ {
        #SWAGGER_ROOT
        expires -1;

        include cors.conf;
      }

      include cors.conf;
    }

Important is to assign only /swagger.json to ENV of the SwaggerUI continer. It is mandatory because requests must be routed to nginx in order to be resolved.

Swagger manifest

# SERVICE
apiVersion: v1
kind: Service
metadata:
  name: swagger-service
  labels:
    kind: swagger-service
spec:
  selector:
    tier: api-documentation
  ports:
    - protocol: 'TCP'
      port: 80
      targetPort: 8080
  type: LoadBalancer
---
# DEPLOYMENT
apiVersion: apps/v1
kind: Deployment
metadata:
  name: swagger-deployment
  labels:
    kind: swagger-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      tier: api-documentation
  template:
    metadata:
      labels:
        tier: api-documentation
    spec:
      containers:
        - name: swagger
          image: swaggerapi/swagger-ui
          imagePullPolicy: Always
          env:
            - name: URL
              value: '/swagger.json'

这篇关于如何使用服务名称在 Kubernetes 集群中交流 Swagger UI 和 API?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆