当前位置: 首页 > news >正文

基于K8s的演示用单机ML服务部署

这是仅用一台机器(比如一台MacBook)模拟在k8s上部署一个机器学习服务的演示用实例。

项目地址:https://github.com/HarmoniaLeo/Local-K8s-ML-Demo

该实例分为以下几个部分:

  1. 使用Keras+Tensorflow搭建并训练神经网络,用于完成KMNIST数据集的分类任务
  2. 基于该神经网络构建在线机器学习服务并在k8s集群上部署(为了单机运行,以在minikube上部署为例),结合Redis实现可拓展、可并行、高可用
  3. 提供一个便于演示的UI,完成与系统的图形化交互,并显示系统状态、性能指标等

技术栈:

  1. 训练:Python、Keras、Tensorflow
  2. 部署:Docker、Kubernetes、Redis
  3. UI:NodeJS、React

架构图:

请添加图片描述

文章目录

  • 1 神经网络训练
    • 1.1 文件组织
    • 1.2 环境配置流程
    • 1.3 训练
  • 2 服务部署
    • 2.1 文件组织
    • 2.2 部署流程
  • 3 服务演示
    • 3.1 文件组织
    • 3.2 准备工作
    • 3.3 演示
      • 3.3.1 UI布局
      • 3.3.2 演示流程
  • 4 拓展
    • 4.1 使用Prometheus+Grafana来监视系统状态
    • 4.2 使用Keda来实现自动拓展

1 神经网络训练

1.1 文件组织

  1. train/checkpoints: 所有由 train_model.ipynb 生成的checkpoint都保存在 checkpoints 文件夹中。Git没有追踪它,请在此处下载
  2. train/data: KMNIST数据集。Git没有追踪它,请在此处下载
  3. train/requirements.txttrain/requirements_cpu.txt: 进行神经网络训练所需的Python库
  4. train/train_model.ipynb: 记录所有分析,并提供神经网络的训练过程

1.2 环境配置流程

  1. 从官方网站下载并安装Anaconda:Anaconda下载

  2. 使用Python 3.11.5创建新的虚拟环境:

    conda create -n KMNIST python=3.11.5
    
  3. 激活虚拟环境:

    conda activate KMNIST
    
  4. 使用 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 文件组织

  1. server/start_server.py: 运行机器学习服务的Python脚本。读取训练好的神经网络checkpoints,然后不断从Redis的image_stream中读取图片进行识别,将结果放回到Redis的result_stream
  2. server/Dockerfile: 将服务打包为Docker镜像所需的Dockerfile
  3. server/ml-service: 配置机器学习服务并部署到k8s集群所需要的Helm chart。其中server/ml-service/values.yaml提供了配置的基本参数
  4. server/requirements.txt: 运行机器学习服务所需的Python库
  5. server/checkpoints: 训练好的神经网络checkpoints。Git没有追踪它,请在此处下载
  6. server/redis: 配置Redis服务并部署到k8s集群所需要的Helm chart

2.2 部署流程

  1. 将要使用的神经网络checkpoints从train/checkpoints复制到server/checkpoints(默认已经复制了一组)。更改server/start_server.py中的CHECKPOINT_HASH为要使用的checkpoints的hash

  2. 安装并启动Docker:Docker文档

  3. 打开控制台,安装并启动minikube:minikube文档

    minikube start
    
  4. 安装Helm:Helm文档

  5. 进入server文件夹

    cd server
    
  6. 使用Helm部署Redis服务

    helm install my-redis ./redis
    
  7. 构建Docker镜像

    docker build -t ml-service:v1.0 .
    
  8. 将Docker镜像加载到minikube

    minikube image load ml-service:v1.0
    
  9. 使用Helm部署ml-service服务

    helm install ml-service ./ml-service
    

3 服务演示

3.1 文件组织

  1. visualization/imgs :从KMNIST数据集中抽取并存为jpg格式的100张图片,用于进行测试。Git没有追踪它,请在此处下载
  2. visualization/axios_server.js :用于启动让演示UI能够进行控制台交互所需的Axios服务器
  3. visualization/requirements.txt :为运行visualization/client.py 所需的Python库
  4. visualization/client.py :客户端Python脚本。将演示UI指定的图片上传到Redis,并将识别结果从Redis中取出,打印到控制台供演示UI读取
  5. 其他NodeJS相关文件,其中和项目的定制主要有关的文件是visualization/src/MLServiceDemo.jsx visualization/src/MLServiceDemo.css

3.2 准备工作

  1. 打开控制台,使用Python 3.11.5创建新的虚拟环境:

    conda create -n KMNISTUI python=3.11.5
    
  2. 激活虚拟环境:

    conda activate KMNISTUI
    
  3. 使用 pip 安装所需的库:

    pip install -r visualization/requirements.txt
    
  4. 安装NodeJS: NodeJS文档

  5. 进入visualization文件夹

    cd visualization
    
  6. 安装NodeJS项目

    npm install .
    
  7. 开启Axios服务器用于控制台交互

    node axios_server.js
    
  8. 打开另一个控制台,开启Redis服务的端口映射,记录此时暴露的端口号(http://127.0.0.1:xxx中的xxx)

    minikube service my-redis-master
    
  9. 用暴露的端口号替换visualization/client.py 中的Redis端口号

  10. 打开另一个控制台,进入visualization文件夹,然后启动演示用网页UI

    cd visualization
    npm start
    

3.3 演示

3.3.1 UI布局

请添加图片描述

  • 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 演示流程

  1. 点击upload image,上传visualization/imgs/sample_0.jpg 。这张图片被识别为”お”,处理时间为2081ms,由目前正在运行的唯一一个pod处理

    请添加图片描述

  2. 点击upload image,上传sample_0到20这21张图片,处理耗时大概是只上传一张图片时的数倍

请添加图片描述

为了更好地部署这个服务。我们的目标是完成可拓展、可并行、高可用这三个目标。具体而言,我们现在只有一个用户和一个服务。这样的问题是假设我们一次上传多张图片,它只能串行处理,造成处理速度慢。另一方面,假设这个服务所在的服务器宕机了,服务就无法运行了。我们重点就是要解决这两个问题。

我们希望能够有多个服务,可以自动将服务进行复制,而且每个服务运行在不同的服务器上。然后我们还需要一个负载均衡器,流量一开始只需要发送给它,它会自动把流量分发给不同的服务。

我们利用k8s来自由地实现服务的拓展。而为了实现负载均衡,我们在k8s集群中部署了Redis。Redis提供了一个消息队列。服务从Redis中拉取消息,并在处理完成后向Redis确认,Redis将对应消息在队列中删除。处理结果也会被写入到Redis中,当结果被接收后则会向Redis确认,并在队列中删除。

这样的架构下,多个服务可以同时取消息,实现可并行;且就算一个服务所在的服务器宕机,别的服务也会继续取消息,实现高可用。

  1. 将min replicas和max replicas增加到2,并点击Update Replicas,从而实际增加一下pod数量

    请添加图片描述

    然后,再次点击upload image,上传sample_0到20这21张图片。我们可以看到此时处理时间大幅缩短了,两个服务都被分配到了流量,参与了处理

    请添加图片描述

  2. 还是点击upload image,上传sample_0到20这21张图片。在处理过程中,我们可以通过点击一个pod将其关闭,以模拟服务宕机。此时由于k8s的HPA中设置了min replicas为2,意味着pod数目不会降低到2以下,因此k8s会自动开启一个新的pod。

    请添加图片描述

    此时没有故障的pod还在继续处理图片。新的pod会在服务就绪后开始处理图片。处理结束后,可以看见三个pod此时都参与了处理,且pod宕机期间的流量由最开始未宕机的pod去承担了。

    请添加图片描述

  3. 我们还可以继续做一些优化,比如我们为了降低成本,可能在没有请求的时候选择关闭一些服务器。首先将Min Replicas和Max Replicas都设置为1,则会关闭一个pod。

    请添加图片描述

    然后,保持Min Replicas为1,将Max Replicas设置为2。再次上传图片时,途中会自动追加一个pod来处理消息。

    请添加图片描述请添加图片描述

    当处理完之后这个新的pod又会被关闭。

    请添加图片描述

    在演示中,我们使用了让Helm调整HPA的参数这一非常原始的方式。生产环境中可以用Keda工具来完成自动缩放。这在拓展小节中会介绍。

4 拓展

4.1 使用Prometheus+Grafana来监视系统状态

  1. 打开控制台,安装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
    
  2. 在ml-service的Helm chart中开启监控功能:将server/ml-service/values.yaml中prometheus的enabled选项改为true

  3. 更新ml-service

    cd server
    helm upgrade ml-service ./ml-service
    
  4. 暴露Grafana服务。此时会自动打开Grafana网页

    minikube service monitoring-grafana
    
  5. 登录Grafana。初始用户名为admin,密码为prom-operator

  6. 选择数据源为Prometheus并添加你所需要的面板。例如,我们添加了一个能够监控ml-service的pod总数和就绪(ready)的pod数的面板。请添加图片描述

4.2 使用Keda来实现自动拓展

  1. 打开控制台,安装Keda

    helm repo add kedacore https://kedacore.github.io/charts
    helm repo update
    helm install keda kedacore/keda
    
  2. 在ml-service的Helm chart中开启Keda:将server/ml-service/values.yaml中keda的enabled选项改为true,并将autoscaling的enabled选项改为false

  3. 更新ml-service

    cd server
    helm upgrade ml-service ./ml-service
    
http://www.dtcms.com/a/112265.html

相关文章:

  • 26考研——线性表_ 线性表的链式表示_双循环链表(2)
  • 多表查询的多与一
  • 对 Python Websockets 库全方位详解
  • 企业安全——FIPs
  • 面试可能会遇到的问题回答(嵌入式软件开发部分)
  • 如何在 Windows 上安装 Python
  • 新旧iPhone相册复制 - 相册图片视频对拷 - 换机 - 迁移设备数据 - 免费开源爱思助手
  • 免费在线MBTI性格测试工具 - 探索你的性格特质
  • 什么是自动化测试框架?常用的自动化测试框架有哪些?
  • 2.3 MySQL基本内置函数
  • Cortex-M​ 函数调用的入栈与出栈操作
  • 【5】搭建k8s集群系列(二进制部署)之安装master节点组件(kube-controller-manager)
  • 盲盒小程序开发平台搭建:打造个性化、高互动性的娱乐消费新体验
  • 定长池的实现
  • 蓝桥杯 小明的背包1 小兰的神秘礼物 01背包问题 模板 C++
  • 财务税务域——企业税务系统设计
  • centos8上实现lvs集群负载均衡dr模式
  • 【学Rust写CAD】23 渐变效果(gradient_source.rs)
  • 【面试篇】Dubbo
  • NSSCTF [HGAME 2023 week1]simple_shellcode
  • 音视频入门基础:MPEG2-PS专题(8)——使用Wireshark分析GB28181的PS流
  • 第十二步:react
  • 如何用Python轻松实现快速复制或剪切文件列表中的所有文件呢?
  • 【架构艺术】Go大仓monorepo中使用wire做依赖注入的经验
  • PowerMonitor的使用步骤
  • 【jvm】GC评估指标
  • 面试手撕------智能指针
  • 操作系统、虚拟化技术与云原生及云原生AI简述
  • JavaScript智能对话机器人——企业知识库自动化
  • 使用HTML5和CSS3实现炫酷的3D立方体动画