当前位置:   article > 正文

AGI|Gradio与Ingress、Nginx集成实现服务区分

AGI|Gradio与Ingress、Nginx集成实现服务区分

在魔塔社区中我们可以使用空间功能来快速的上线自己的代码使用AI的能力,那么如何在同一个域名下来区分不同用户上线的服务呢?

本次使用使用ingress和nginx来实验划同一个域名下不同用户的服务,并使用gradio来模拟用户服务。

目录

一、简介

(一)ingress

(二)Gradio

二、准备

(一)ingress

(二)Gradio

三、整体方案思路及验证

(一)方案说明

(二)验证过程

(三)问题

四、最终方案

(一)网络拓扑图

(二)关键节点说明


一、简介

(一)ingress

Ingress 是对集群中服务的外部访问进行管理的 API 对象,典型的访问⽅式是 HTTP。

Ingress 可以提供负载均衡、SSL 终结和基于名称的虚拟托管。

(二)Gradio

gradio是⼀个为机器学习构建demo和web应⽤的开源python包

二、准备

(一)ingress

1、安装

使用官方提供的YAML文件来安装ingress-nginx,如果集群无法拉取到镜像,可以先在本地拉取镜像,然后再上传到集群服务器上。

2、验证

创建nginx Pod

  1. kubectl run nginx --image=nginx
  2. kubectl getpod nginx
  3. # nginx 容器显⽰如下正常运⾏
  4. NAME READY STATUS RESTARTS AGE
  5. nginx 1/1Running 017s

创建nginx svc

  1. kubectlexpose pod nginx --port=80--type=NodePort
  2. kubectl get svc nginx
  3. # nginx svc显⽰如下端⼝
  4. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  5. nginx NodePort 10.106.119.175<none> 80:31034/TCP 5s

使用集群ip:nodeport来尝试访问nginx

创建ingress

配置本地的hosts文件并将ingress中设置的域名指向对应的集群ip

  • window hosts文件位置
C:\Windows\System32\drivers\etc\hosts
  • mac hosts文件位置
  1. #需要获取管理员权限
  2. /etc/hosts
  • Linux hosts文件位置
  1. #需要获取管理员权限
  2. /etc/hosts

将hosts中添加一行格式类似,可以根据自己配置的域名和服务器IP修改

127.0.0.1example.com

其中端口为安装ingress-nginx时nginx-controller的NodePort端口

(二)Gradio

1、安装

gradio要求python3.8+

pip命令安装

pip install gradio -i https://mirror.baidu.com/pypi/simple

使用requirements.txt

2、验证

代码:

启动

3、容器准备

Dockerfile

  1. FROM python:3.10
  2. WORKDIR /app
  3. ADD . .
  4. RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/
  5. CMD ['python','main.py']

Command

  1. #注意最后的点
  2. docker build -t gradio:demo .

可以将main.py中的hello改为其他的字符然后再打⼀个镜像,用来区分2个服务

三、整体方案思路及验证

(一)方案说明

由于当前的情况为每个用户都有可能创建⼀个gradio项目,并且由于gradio的代码是固定的,并且用户上传的代码也是固定的,所以需要在域名后的path中去区分不同的用户并来决定将请求和流量转到对应的gradio的service上,预想页面划分为http://domain.com/xxx/user_id, 对应到ingress中则使用前缀匹配/xxx/user_id并在请求转发到gradio的时候将path中的/xxx/user_id去掉

(二)验证过程

//直接使用域名根path代理单个gradio

创建pod

  1. kubectl run gradio --image=gradio:demo -- /bin/sh -c 'sleep 3600'
  2. #这⾥不知道为什么启动的时候会报main.py⽂件找不到
  3. #所以使⽤shell先sleep住然后进⼊容器中启动python脚本
  4. #kubectl exec-it gradio sh
  5. #python main.py
  6. #exit

创建svc

  1. kubectl expose pod gradio --port=7860 --type=NodePort
  2. # 可以先使⽤NodePort验证gradio已经启动

创建ingress

✅验证通过

//添加前缀代理gradio

预想是修改ingress⽂件将path改为/gradio-demo

path: /gradio-demo

但是因为gradio服务中的接口和前端静态文件的地址都没有/gradio-demo这段path所以需要在向后转发的时候去掉/gradio-demo这部分

通过官方的文档可知可以通过设置annotation字段中的http://nginx.ingress.kubernetes.io/rewrite- target字段来设置将path中的特殊字段去掉

修改后的ingress YAML为

前端的静态文件在获取时没有添加/demo前缀,因此导致前端的静态文件无法正确获取。这里需要参考以下链接中的方法,对YAML配置文件进行修改。

预想的结果并没有实现,大部分的静态文件都已经处理并添加了demo这个路径前缀,但是仍然有部分文件和接口没有添加。猜测是这些文件的请求中其实不包含assets这个路径。这里为了特殊处理这部分接口和文件,我们需要修改YAML中的path字段或者使用annotation中的configuration-snippet字段进行配置。

可以观察到这些特殊的静态文件请求和接口请求已经加上了demo这个路径前缀,但是并没有加上端口。在实际使用中,域名通常是不包含端口的,因此我们希望在请求这个地址时能够隐藏端口。为了实现这一点,我们可以使用nginx来监听80端口,并将nginx-ingress controller的NodePort进行反向代理,从而隐藏原始的端口。接下来,我们需要安装nginx并设置配置文件以实现ingress controller的NodePort的反向代理。

添加了nginx隐藏了NodePort端口之后整个页面可以正常访问了,但是当请求接口时

发现这个data接口提示method not allowed,没有这个请求方式,通过正常的gradio查看发现这个接口是存在的但是是Post请求。但是这里由于ingress的转发会自动将所有方式的请求都转变成Get传递下去,所以这里需要针对这个接口处理,更改ingress的yaml以处理这个接口的转发。

发现该接口已经正常使用Post去请求了,但是仍然报了500。这里最终使用正确的gradio加postman模拟请求发现,data请求是在上边的join请求返回event_id之后发起的。而这里的问题是join接口在返回event_id之后就已经关闭了,并且页面上返回的值也是join请求返回的,所以这里显示500。经过排查发现,需要将nginx的缓存和buffer关闭,这样nginx才会即时地将流式请求的返回值返回。

再次请求发现已经可以正常访问并且请求通过了

这时再仿照demo的ingress和pod创建⼀个demo1,并且返回的时你好+xx

demo1访问正常,但是再次访问demo时发现接口处理这里指向了demo1

为了解决处理path同时解决ingress这里配置过于复杂并且不利于开发的问题,这里选择将一些静态文件添加demo这个path的过程添加到nginx这里。这里具体添加的是demo还是其他的字段可以从请求头的Referer中去获取,这个接口或者静态文件是从哪个页面发起的。我们需要修改nginx的配置来实现这一功能。

这里如果访问的地址是scope,则直接指向nginx ingress的NodePort;如果不是scope但是referer中包含scope,则使用referer加请求的URL进行重定向,并且将ingress中关于文件的特殊处理去除。

(三)问题

//部分文件或接口无法处理

部分接口静态文件无法处理

//端口无法隐藏

安装nginx代理80端口并将80端口反向代理到ingress-nginx 的NodePort上

//nginx rewrite自动将post请求转为get

解决nginx代理转发post请求变get请求方法-腾讯云开发者社区-腾讯云(https://cloud.tencent.com/developer/article/2220124?areaSource=102001.19&traceId=t6Pwp56CykwHKq6cDyqK7)

//Event-Stream接口请求超时

Event-Stream的本质还是http请求,如果nginx设置了cache和buffer则会等待Event-Stream整体结束后再返回,这里关闭cache和buffer即可使nginx直接返回。

//多ingress处理时请求跳转错乱&处理复杂请求

对特殊接口和静态文件的处理代码进行去除,并更改为使用请求头中的referer字段来拼接这些接口中的URL。同时,在根路径也可以通过判断请求头中的referer字段来决定是否进行重定向。

四、最终方案

(一)网络拓扑图

(二)关键节点说明

//nginx配置

由于部分设置是在location /下的,所以这里判断了referer是否包含scope字段,因此并不会影响之前的nginx中location /下的配置

//ingress配置

使用正则匹配来区分用户id,并在重定向使去除用户id。

以上就是今天的全部内容,有问题欢迎讨论。

作者:冯康| Go开发工程师

更多AI小知识欢迎关注“神州数码云基地”公众号,回复“AI与数字化转型”进入社群交流

版权声明:文章由神州数码武汉云基地团队实践整理输出,转载请注明出处。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/287423
推荐阅读
相关标签
  

闽ICP备14008679号