25、基于Python和K3s集群的计算机视觉服务部署

基于Python和K3s集群的计算机视觉服务部署

在智能交通系统中,计算机视觉技术结合GPS定位信息可以实现对车辆周围障碍物的检测和信息共享。本文将详细介绍如何部署一系列相关服务,包括推理服务、GPS队列服务、交通管理服务以及代理服务,以实现车辆障碍物检测和交通信息的实时共享。

推理服务部署

首先,我们需要部署推理服务,用于对检测到的图像进行分类。以下是具体步骤:
1. 创建推理服务部署

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: inference
  name: inference
spec:
  containers:
  - image: sergioarmgpl/inference
    name: inference
    imagePullPolicy: Always
    resources: {}
status: {}
  1. 端口转发
$ kubectl port-forward --address 0.0.0.0 deploy/inference 3000:3000
  1. 调用推理API
$ curl --header "Content-Type: application/json" \
--request POST --data '{"data":[6]}' \
http://localhost:3000/predict

预期输出:

{
  "prediction": 3.0
}
GPS队列服务部署

GPS队列服务由多个容器组成,用于读取和存储GPS坐标,并将检测到的对象信息与GPS坐标一起发送到交通管理服务。
1. 代码分析
- gps-queue容器

<Import necessary Python libraries to read the GPS module>

<cid variable to set a unique client id for these coordinates>
<device variable to set where the GPS module will be read in /
dev>
<ser variable to configure the serial communication with the 
GPS module>

<Initializing the device to read information>

while True:
  <Read the Coordinate and store it into /tmp/gps>
- **gps-api容器**:
<Import the necessary Python libraries to run this code> 
<Set traffic_events variable to accumulate detected objects for 
a time period>
<Flask and CORS configuration>

@app.route("/gps", methods=["GET"])
def getGPSCoordinate():
  <Read coordinate form /tmp/gps>
  <Return the GPS coordinate as JSON as 
  {'lat': <LATITUDE_VALUE>,'lng':<LONGITUDE_VALUE>
  ,'cid':<CLIENT_ID>} 
  >

@app.route("/traffic/event", methods=["POST"])
def registerTrafficEvent():
  <Read last GPS coordinate from /tmp/gps>
  <Get object type and warning classification
  from the computer vision service>
  <Generate the Timestamp value for the new detected object>
  <Assign to a variable the warning, Latitude, Longitude 
  and timestamp information for the object>
  <Add this information to the traffic_events array 
  to store it temporary the value>
  <Return the object ide and that the request was processed>

@app.route("/traffic", methods=["GET"])
def syncTrafficEvents():
  <Filter similar objects stored in the 
  traffic_events array>
  <Send the filtered array using JSON format to the
  endpoint http://<TRAFFIC_MANAGER:5000>/traffic/1
  to store this information and get it locally and
  public by calling the endpoint
  http://<TRAFFIC_MANAGER:5000>/traffic>
  <Return that the information syncTrafficEvents
  was processed>

<GPS Queue service initialization on port 3000 by default>
  1. 部署步骤
    • 创建GPS队列部署
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: gps-queue
  name: gps-queue
spec:
  replicas: 1
  selector:
    matchLabels:
      app: gps-queue
  template:
    metadata:
      labels:
        app: gps-queue
    spec:
      initContainers:
      - image: busybox:1.34
        name: init-gps-queue
        command: ['sh', '-c', "echo '-1' >> /tmp/gps"]
        securityContext:
          runAsUser: 1
        volumeMounts:
        - name: tmp
          mountPath: /tmp
      containers:
      - image: sergioarmgpl/gps_queue
        name: gps-queue
        imagePullPolicy: Always
        env:
        - name: DEVICE
          value: "/dev/ttyACM0"
        securityContext:
          privileged: true
          capabilities:
            add: ["SYS_ADMIN"]
        volumeMounts:
        - mountPath: /dev
          name: dev-volume
        - name: tmp
          mountPath: /tmp
      - image: sergioarmgpl/gps_api
        name: gps-api
        ports:
        - containerPort: 3000
        imagePullPolicy: Always
        env:
        - name: ENDPOINT
          value: "http://<TRAFFIC_MANAGER_IP>:5000"
        securityContext:
          runAsUser: 1
        volumeMounts:
        - name: tmp
          mountPath: /tmp
      - image: curlimages/curl
        name: sync-traffic-events
        env:
        - name: URL
          value: "http://localhost:3000/traffic"
        - name: DELAY
          value: "30"
        command: [ "sh", "-c"]
        args:
        - while :; do
            curl ${URL};
            sleep ${DELAY};
          done;
      volumes:
      - name: dev-volume
        hostPath:
          path: /dev
          type: Directory
      - name: tmp
        emptyDir: {}
status: {}
- **变量说明**:
容器 变量 说明 默认值
gps-queue DEVICE 配置GPS模块检测的设备 /dev/ttyACM0
gps-api ENDPOINT 配置存储所有检测到的对象、GPS坐标和警告信息的公共端点 http:// :5000
sync-traffic-events URL 定期调用的本地URL,用于发送所有检测到的对象信息 http://localhost:3000/traffic
sync-traffic-events DELAY 发送最后检测到的对象信息前等待的时间(秒) 30
  1. 测试服务
$ kubectl port-forward --address 0.0.0.0 deploy/gps-queue 3001:3000
$ curl http://localhost:3001/gps

预期输出:

{'lat': <LATITUDE_VALUE>,'lng':<LONGITUDE_VALUE>,'cid':<CLIENT_ID>}
交通管理服务部署

交通管理服务运行在云端,用于接收和存储边缘设备发送的检测对象信息和GPS坐标,并提供查询接口。
1. 代码分析
- traffic-manager容器

<Import the necessary Python libraries to run this code> 
<Flask and CORS configuration> 

<Set time to expire the traffic and objects by setting the 
values of the variables ttl_trf, ttl_obj>

def redisCon():
  <Set and return the Redis connection>

@app.route("/traffic/1", methods=["POST"])
def setBulkTrafficObjects():
  <Get the Redis connection calling redisCon()>
  <Get detected objects from the POST request>
  <Omit to store similar detected objects in a 
  5 meters radius>
  <Set a hash value to store type and warning 
  level for each object>
  <Set expiring time for each hash stored>
  <Return that the operation was successful 
  {"setTrafficObject":"done"}>

@app.route("/traffic/unit/<unit>/r/<radius>/lat/<lat>/lng/<lng>", methods=["GET"])
def getTrafficObjects(unit,radius,lat,lng):
  <Get the Redis connection calling redisCon()>
  <Get the objects detected and its metadata
  from the previous stored hash
  in the radius configured in the request>
  <Return that the operation was successful and 
  the objects found
  in the next format:
  {"getTrafficObjects":"done",
    "objects":data
  }>

<Service initialization on port 3000 by default>
- **autoexpire容器**:
<Import all the necessary libraries>
<Set Redis connection in an r variable>

while True:
  <Get all the objects inside the traffic sorted set>
  <Check if each member of the set has its hash value>
  <If not remove the member of the sorted set>
  <Wait until the configured delay ends to
  Update the set again>
  1. 部署步骤
    • 创建交通管理服务部署
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: traffic-manager
  name: traffic-manager
spec:
  replicas: 1
  selector:
    matchLabels:
      app: traffic-manager
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: traffic-manager
    spec:
      containers:
      - image: sergioarmgpl/autoexpire
        name: autoexpire
        imagePullPolicy: Always
        env:
        - name: REDIS_HOST
          value: "redis"
        - name: REDIS_AUTH
          value: "YOUR_PASSWORD"
        - name: DELAY
          value: "30"
      - image: sergioarmgpl/traffic_manager
        name: traffic-manager
        imagePullPolicy: Always
        env:
        - name: REDIS_HOST
          value: "redis"
        - name: REDIS_AUTH
          value: "YOUR_PASSWORD"
        - name: TTL_TRAFFIC
          value: "900"
        - name: TTL_OBJECT
          value: "180"
        resources: {}
status: {}
- **变量说明**:
变量 说明
REDIS_HOST Redis服务的名称
REDIS_AUTH 连接Redis服务的密码
TTL_TRAFFIC 交通信息的过期时间(秒)
TTL_OBJECT 对象信息的过期时间(秒)
DELAY 检查交通地理空间排序集中成员是否过期的等待时间(秒)
- **创建LoadBalancer服务**:
apiVersion: v1
kind: Service
metadata:
  labels:
    app: traffic-manager
  name: traffic-manager-lb
spec:
  ports:
  - port: 5000
    protocol: TCP
    targetPort: 3000
  selector:
    app: traffic-manager
  type: LoadBalancer
- **获取负载均衡器IP地址**:
$ TRAFFIC_MANAGER_IP="$(kubectl get svc traffic-manager-lb -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')"
$ echo $TRAFFIC_MANAGER_IP
- **检查服务状态**:
$ kubectl get svc traffic-manager-lb
- **测试API(可选)**:
$ curl -X POST -H "Accept: application/json" \
-H "Content-Type: application/json" \
--data '{
  "object":"person",
  "warning":1,
  "position":{"lat":1.633518,"lng": -90.591706}
}' http://$TRAFFIC_MANAGER_IP:3000/traffic/1

预期输出:

{
  "setTrafficObject": "done"
}
$ curl -X GET -H "Accept: application/json" \
http://$TRAFFIC_MANAGER_IP:3000/traffic/objects/unit/km/r/0.1/lat/1.633518/lng/-90.5917

预期输出:

{
  "getTrafficObjects": [
    "person"
  ]
}
代理服务部署

为了绕过CORS限制,我们需要部署一个代理服务,将本地流量地图应用的请求转发到交通管理服务。
1. 代码分析

from flask import Flask,request,redirect,Response
import os
import requests
app = Flask(__name__)
url = os.environ['URL']

@app.route('/<path:path>',methods=['GET'])
def proxy(path):
  global url
  r = requests.get(f'{url}/{path}')
  excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection']
  headers = [(name, value) for (name, value) in r.raw.headers.items() if name.lower() not in excluded_headers]
  response = Response(r.content, r.status_code, headers)
  return response

if __name__ == '__main__':
  app.run(debug = False,port=5000)
  1. 部署步骤
    • 创建代理服务部署
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: proxy
  name: proxy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: proxy
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: proxy
    spec:
      containers:
      - image: sergioarmgpl/proxy
        name: proxy
        imagePullPolicy: Always
        env:
        - name: URL
          value: "http://<TRAFFIC_MANAGER_IP>:5000"
        resources: {}
status: {}
- **变量说明**:
变量 说明 默认值
URL 代理将接收的所有GET请求重定向到的URL http:// :5000

通过以上步骤,我们成功部署了推理服务、GPS队列服务、交通管理服务和代理服务,实现了车辆障碍物检测和交通信息的实时共享。这些服务的协同工作可以为智能交通系统提供强大的支持,提高交通安全和效率。

基于Python和K3s集群的计算机视觉服务部署

服务部署流程总结

为了更清晰地展示整个服务部署的流程,我们可以用 mermaid 流程图来表示:

graph LR
    classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
    classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px;

    A([开始]):::startend --> B(部署推理服务):::process
    B --> C(部署GPS队列服务):::process
    C --> D(部署交通管理服务):::process
    D --> E(部署代理服务):::process
    E --> F([结束]):::startend

这个流程图展示了从开始到结束的整个服务部署过程,依次为推理服务、GPS 队列服务、交通管理服务和代理服务的部署。

注意事项和常见问题

在部署这些服务的过程中,有一些注意事项和常见问题需要我们关注:

  1. 容器镜像问题
    • 确保使用的容器镜像存在且可用。可以通过检查镜像仓库或者手动拉取镜像来验证。例如,对于推理服务使用的 sergioarmgpl/inference 镜像,可以使用以下命令拉取:
docker pull sergioarmgpl/inference
- 如果遇到镜像拉取失败的问题,可能是网络问题或者镜像仓库配置问题。可以检查网络连接,或者尝试更换镜像仓库地址。
  1. 变量配置问题
    • 对于各个服务中使用的变量,如 DEVICE ENDPOINT URL DELAY 等,要确保配置正确。例如,在 GPS 队列服务中, DEVICE 变量要根据实际的 GPS 模块设备进行配置。
    • 如果变量配置错误,可能会导致服务无法正常工作。可以通过查看服务日志来排查问题,例如:
kubectl logs deploy/gps-queue -c gps-queue
  1. 端口转发和访问问题
    • 在进行端口转发时,要确保端口没有被占用。可以使用以下命令检查端口占用情况:
lsof -i :3000
- 如果端口被占用,可以尝试更换端口进行转发。
- 在测试服务端点时,要确保服务已经正常启动,并且端口转发已经生效。可以通过查看服务状态和日志来确认。
服务的扩展和优化

在实际应用中,可能需要对这些服务进行扩展和优化,以满足不同的需求:

  1. 服务扩展
    • 可以通过增加副本数量来扩展服务的处理能力。例如,在部署 GPS 队列服务时,可以将 replicas 参数设置为大于 1 的值:
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: gps-queue
  name: gps-queue
spec:
  replicas: 3 # 增加副本数量
  selector:
    matchLabels:
      app: gps-queue
  template:
    metadata:
      labels:
        app: gps-queue
    spec:
      # 其他配置保持不变
- 增加副本数量可以提高服务的并发处理能力,但同时也会增加资源消耗。
  1. 性能优化
    • 可以对服务的资源进行优化配置,例如调整容器的 CPU 和内存限制。在部署文件中,可以通过 resources 字段来配置:
containers:
- image: sergioarmgpl/inference
  name: inference
  imagePullPolicy: Always
  resources:
    requests:
      cpu: "0.5"
      memory: "256Mi"
    limits:
      cpu: "1"
      memory: "512Mi"
- 合理配置资源可以提高服务的性能和稳定性。
总结

通过本文的介绍,我们详细了解了如何使用 Python 和 K3s 集群部署计算机视觉服务,包括推理服务、GPS 队列服务、交通管理服务和代理服务。我们通过代码分析、部署步骤说明、变量配置解释等方式,展示了整个服务部署的过程。同时,我们还介绍了服务部署流程总结、注意事项和常见问题,以及服务的扩展和优化方法。这些服务的协同工作可以为智能交通系统提供强大的支持,实现车辆障碍物检测和交通信息的实时共享,提高交通安全和效率。在实际应用中,我们可以根据具体需求对这些服务进行定制和优化,以满足不同的场景要求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值