如何使用服务名称在 Kubernetes 集群中交流 Swagger UI 和 API? [英] How to communicate Swagger UI and API in Kubernetes cluster using service names?
问题描述
我在 Pod 内的 Kubernetes 集群上的 Docker 容器内运行了一个 node.js API.Pod 连接到 LoadBalancer 类型的 Kubernetes 服务,因此我可以从外部连接到它,也可以从 Swagger UI 连接到它,方法是将 API IP 地址传递给作为同一 Kubernetes 集群上的另一个 Docker 容器运行的 Swagger UI <代码>http://
但在我的情况下,我想使用像这样的服务名称通过 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屋!