基于K8s的演示用单机ML服务摆设
这是仅用一台机器(比如一台MacBook)模拟在k8s上摆设一个机器学习服务的演示用实例。项目地点:https://github.com/HarmoniaLeo/Local-K8s-ML-Demo
该实例分为以下几个部分:
[*]利用Keras+Tensorflow搭建并练习神经网络,用于完成KMNIST数据集的分类任务
[*]基于该神经网络构建在线机器学习服务并在k8s集群上摆设(为了单机运行,以在minikube上摆设为例),结合Redis实现可拓展、可并行、高可用
[*]提供一个便于演示的UI,完成与体系的图形化交互,并显示体系状态、性能指标等
技术栈:
[*]练习:Python、Keras、Tensorflow
[*]摆设:Docker、Kubernetes、Redis
[*]UI:NodeJS、React
架构图:
https://i-blog.csdnimg.cn/direct/1484e5b4e9a4409aa599e41e40aafcd1.png
1 神经网络练习
1.1 文件组织
[*]train/checkpoints: 全部由 train_model.ipynb 生成的checkpoint都保存在 checkpoints 文件夹中。Git没有追踪它,请在此处下载
[*]train/data: KMNIST数据集。Git没有追踪它,请在此处下载
[*]train/requirements.txt、train/requirements_cpu.txt: 进行神经网络练习所需的Python库
[*]train/train_model.ipynb: 记录全部分析,并提供神经网络的练习过程
1.2 环境配置流程
[*] 从官方网站下载并安装Anaconda:Anaconda下载
[*] 利用Python 3.11.5创建新的虚拟环境:
conda create -n KMNIST python=3.11.5
[*] 激活虚拟环境:
conda activate KMNIST
[*] 利用 pip 安装所需的库。如果你的电脑支持GPU,则:
pip install -r train/requirements.txt
如果你的电脑不支持GPU,则:
pip install -r train/requirements_cpu.txt
1.3 练习
打开train/train_model.ipynb,选择KMNIST虚拟环境作为kernel,然后逐步运行。
2 服务摆设
2.1 文件组织
[*]server/start_server.py: 运行机器学习服务的Python脚本。读取练习好的神经网络checkpoints,然后不断从Redis的image_stream中读取图片进行识别,将效果放回到Redis的result_stream
[*]server/Dockerfile: 将服务打包为Docker镜像所需的Dockerfile
[*]server/ml-service: 配置机器学习服务并摆设到k8s集群所必要的Helm chart。此中server/ml-service/values.yaml提供了配置的基本参数
[*]server/requirements.txt: 运行机器学习服务所需的Python库
[*]server/checkpoints: 练习好的神经网络checkpoints。Git没有追踪它,请在此处下载
[*]server/redis: 配置Redis服务并摆设到k8s集群所必要的Helm chart
2.2 摆设流程
[*] 将要利用的神经网络checkpoints从train/checkpoints复制到server/checkpoints(默认已经复制了一组)。更改server/start_server.py中的CHECKPOINT_HASH为要利用的checkpoints的hash
[*] 安装并启动Docker:Docker文档
[*] 打开控制台,安装并启动minikube:minikube文档
minikube start
[*] 安装Helm:Helm文档
[*] 进入server文件夹
cd server
[*] 利用Helm摆设Redis服务
helm install my-redis ./redis
[*] 构建Docker镜像
docker build -t ml-service:v1.0 .
[*] 将Docker镜像加载到minikube
minikube image load ml-service:v1.0
[*] 利用Helm摆设ml-service服务
helm install ml-service ./ml-service
3 服务演示
3.1 文件组织
[*]visualization/imgs :从KMNIST数据集中抽取并存为jpg格式的100张图片,用于进行测试。Git没有追踪它,请在此处下载
[*]visualization/axios_server.js :用于启动让演示UI可以或许进行控制台交互所需的Axios服务器
[*]visualization/requirements.txt :为运行visualization/client.py 所需的Python库
[*]visualization/client.py :客户端Python脚本。将演示UI指定的图片上传到Redis,并将识别效果从Redis中取出,打印到控制台供演示UI读取
[*]其他NodeJS相关文件,此中和项目的定制重要有关的文件是visualization/src/MLServiceDemo.jsx 和visualization/src/MLServiceDemo.css
3.2 准备工作
[*] 打开控制台,利用Python 3.11.5创建新的虚拟环境:
conda create -n KMNISTUI python=3.11.5
[*] 激活虚拟环境:
conda activate KMNIST
UI
[*] 利用 pip 安装所需的库:
pip install -r visualization/requirements.txt
[*] 安装NodeJS: NodeJS文档
[*] 进入visualization文件夹
cd visualization
[*] 安装NodeJS项目
npm install .
[*] 开启Axios服务器用于控制台交互
node axios_server.js
[*] 打开另一个控制台,开启Redis服务的端口映射,记录此时暴露的端标语(http://127.0.0.1:xxx中的xxx)
minikube service my-redis-master
[*] 用暴露的端标语更换visualization/client.py 中的Redis端标语
[*] 打开另一个控制台,进入visualization文件夹,然后启动演示用网页UI
cd visualization
npm start
3.3 演示
3.3.1 UI结构
https://i-blog.csdnimg.cn/direct/0f8d58c78899455ca4a6069641294353.png
[*]UI每次革新(refresh)会在后台通过Axios服务器执行kubectl的get pods命令,从而获取ml-service关联的全部pod的状态
[*]pod会被陈列在左上角,此中绿色的pod已经乐成连接到Redis,可以正常工作,而赤色的pod则还在准备中。通过点击pod可以将其关闭,从而模拟服务故障
[*]通过点击Upload Images按钮会进入文件选择视图,可以选择并上传必要识别的图片(例如visualization/imgs 文件夹下准备好的图片),支持一次上传多张
[*]通过更改Min Replicas和Max Replicas并点击Update Replicas,会更新helm的HPA参数从而更改pods的数量。在Redis中没有消息的环境下,pods的数量会减少到Min Replicas;在Redis中有消息的环境下,pods的数量会增加到Max Replicas
[*]左下的控制台面板会显示进行图形化交互时,后台通过控制台执行的全部命令。此外,还会显示每次处理的性能指标
[*]右侧面板会显示识别效果
3.3.2 演示流程
[*] 点击upload image,上传visualization/imgs/sample_0.jpg 。这张图片被识别为”お”,处理时间为2081ms,由目前正在运行的唯一一个pod处理
https://i-blog.csdnimg.cn/direct/f5ae8f21a94a47b4a36c78d5ff83afa7.png
[*] 点击upload image,上传sample_0到20这21张图片,处理耗时大概是只上传一张图片时的数倍
https://i-blog.csdnimg.cn/direct/c9e33f76ed934792b67f510fb9ded186.png
为了更好地摆设这个服务。我们的目标是完成可拓展、可并行、高可用这三个目标。具体而言,我们现在只有一个用户和一个服务。如许的问题是假设我们一次上传多张图片,它只能串行处理,造成处理速率慢。另一方面,假设这个服务所在的服务器宕机了,服务就无法运行了。我们重点就是要办理这两个问题。
我们希望可以或许有多个服务,可以自动将服务进行复制,而且每个服务运行在不同的服务器上。然后我们还必要一个负载均衡器,流量一开始只必要发送给它,它会自动把流量分发给不同的服务。
我们利用k8s来自由地实现服务的拓展。而为了实现负载均衡,我们在k8s集群中摆设了Redis。Redis提供了一个消息队列。服务从Redis中拉取消息,并在处理完成后向Redis确认,Redis将对应消息在队列中删除。处理效果也会被写入到Redis中,当效果被接收后则会向Redis确认,并在队列中删除。
如许的架构下,多个服务可以同时取消息,实现可并行;且就算一个服务所在的服务器宕机,别的服务也会继承取消息,实现高可用。
[*] 将min replicas和max replicas增加到2,并点击Update Replicas,从而实际增加一下pod数量
https://i-blog.csdnimg.cn/direct/816fa48737a7497fb4ac21951830f45e.png
然后,再次点击upload image,上传sample_0到20这21张图片。我们可以看到此时处理时间大幅缩短了,两个服务都被分配到了流量,参与了处理
https://i-blog.csdnimg.cn/direct/22ccce434c3d4283aeef0948073b7e64.png
[*] 还是点击upload image,上传sample_0到20这21张图片。在处理过程中,我们可以通过点击一个pod将其关闭,以模拟服务宕机。此时由于k8s的HPA中设置了min replicas为2,意味着pod数量不会降低到2以下,因此k8s会自动开启一个新的pod。
https://i-blog.csdnimg.cn/direct/a0a68b939da6456ab91a83e441bb92c0.png
此时没有故障的pod还在继承处理图片。新的pod会在服务就绪后开始处理图片。处理结束后,可以看见三个pod此时都参与了处理,且pod宕机期间的流量由最开始未宕机的pod去负担了。
https://i-blog.csdnimg.cn/direct/b785cd51064b4a3fb92ba485966338ee.png
[*] 我们还可以继承做一些优化,比如我们为了降低本钱,大概在没有请求的时候选择关闭一些服务器。起首将Min Replicas和Max Replicas都设置为1,则会关闭一个pod。
https://i-blog.csdnimg.cn/direct/2596ebfbdd5f4aeaba91621d5c2b371f.png
然后,保持Min Replicas为1,将Max Replicas设置为2。再次上传图片时,途中会自动追加一个pod来处理消息。
https://i-blog.csdnimg.cn/direct/dff60d76a348451d89d89260ec3e3c02.pnghttps://i-blog.csdnimg.cn/direct/eee8e6d8f4ae419f9b7ac510df51661b.png
当处理完之后这个新的pod又会被关闭。
https://i-blog.csdnimg.cn/direct/495865ac5c3546faafb1c6b18c2bcef5.png
在演示中,我们利用了让Helm调整HPA的参数这一非常原始的方式。生产环境中可以用Keda工具来完成自动缩放。这在拓展小节中会介绍。
4 拓展
4.1 利用Prometheus+Grafana来监视体系状态
[*] 打开控制台,安装Prometheus+Grafana
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm install monitoring prometheus-community/kube-prometheus-stack \
--set prometheus.prometheusSpec.resources.requests.memory=512Mi \
--set grafana.resources.requests.memory=256Mi
[*] 在ml-service的Helm chart中开启监控功能:将server/ml-service/values.yaml中prometheus的enabled选项改为true
[*] 更新ml-service
cd server
helm upgrade ml-service ./ml-service
[*] 暴露Grafana服务。此时会自动打开Grafana网页
minikube service monitoring-grafana
[*] 登录Grafana。初始用户名为admin,暗码为prom-operator
[*] 选择数据源为Prometheus并添加你所必要的面板。例如,我们添加了一个可以或许监控ml-service的pod总数和就绪(ready)的pod数的面板。https://i-blog.csdnimg.cn/direct/456b4c7d9ba045d0a4c6cb596cdd77f4.png
4.2 利用Keda来实现自动拓展
[*] 打开控制台,安装Keda
helm repo add kedacore https://kedacore.github.io/charts
helm repo update
helm install keda kedacore/keda
[*] 在ml-service的Helm chart中开启Keda:将server/ml-service/values.yaml中keda的enabled选项改为true,并将autoscaling的enabled选项改为false
[*] 更新ml-service
cd server
helm upgrade ml-service ./ml-service
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]