使用 Akri 发现 ONVIF 相机

Akri 是一个 Kubernetes 资源接口,使你可以轻松地公开异类叶设备 ((如 IP 摄像头和 USB 设备)) Kubernetes 群集中的资源,并持续检测有权访问这些设备的节点,以便基于它们计划工作负载。 Akri 是一个为边缘制作的 CNCF 沙盒项目,用于处理叶设备的动态外观和消失。 它目前支持 OPC UA、ONVIF 和 udev 协议,但你也可以实现模板提供的自定义协议处理程序。 在此处阅读有关 Akri 的详细信息

本文介绍如何发现与 AKS Edge Essentials 群集连接到同一网络的 ONVIF 相机。 ONVIF 是 IP 安全设备的开放行业标准,通常用于视频监视。 在此处阅读有关 ONVIF 配置文件的详细信息。 此演示可帮助你开始使用 Akri 通过 ONVIF 协议发现 IP 摄像机,并通过视频代理使用它们,该代理使你能够使用相机中的镜头并将其显示在 Web 应用程序中。

显示 Akri ONVIF 演示流的示意图。

先决条件

  • 机部署AKS Edge Essentials (如果使用的是真正的 ONVIF IP 摄像头,则必须使用外部交换机) 创建完整部署。
  • Akri 仅适用于 Linux:在本练习中使用 Linux 节点。
  • 连接到与外部交换机群集相同的网络的 ONVIF IP 相机,或运行 (部署步骤的模拟 ONVIF 容器,如下所示) 。

注意

此示例 ONVIF 代理目前不支持连接到需要身份验证的相机。 若要运行此演示,请在 ONVIF 相机上禁用身份验证。

模拟 ONVIF 容器

如果没有 ONVIF IP 摄像头,可以使用模拟 ONVIF 容器进行本练习。 模拟容器适用于单机部署或完整部署。

  1. (可选) 如果要为 ONVIF 容器设置自定义 RTSP 视频源,请在质量为 SD 而不是 HD) 时保存 mp4 视频 (效果最佳,并使用以下命令将文件从主机目录复制到 Linux 节点 (请确保) 替换主机目录和相应的视频文件名:

    Copy-AksEdgeNodeFile -FromFile C:\Users\WinIotUser\Downloads\sample.mp4 -toFile /home/aksedge-user/sample.mp4 -PushFile
    
  2. 打开空 YAML 文件并复制/粘贴以下内容。 请确保将 后面的 /mnt/ 值替换为 下 MP4FILE的视频文件名。 将文件另存为 onvif-mock.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: onvif-camera-mocking
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: onvif-camera-mocking
      strategy:
        type: RollingUpdate
        rollingUpdate:
          maxSurge: 1
          maxUnavailable: 1
      minReadySeconds: 5    
      template:
        metadata:
          labels:
            app: onvif-camera-mocking
        spec:
          nodeSelector:
            "kubernetes.io/os": linux
          containers:
          - name: azure-vote-front
            image: winiotsaleskit.azurecr.io/onvif-camera-mocking:latest
            ports:
            - containerPort: 8554
            - containerPort: 1000
            - containerPort: 3702
            env:
            - name: INTERFACE
              value: "eth0"
            - name: DIRECTORY
              value: "/onvif-camera-mock"
            - name: MP4FILE
              value: /mnt/sample.mp4 
            volumeMounts:
            - name: sample-volume
              mountPath: /mnt
          volumes:
          - name: sample-volume
            hostPath:
              path: /home/aksedge-user
              type: Directory
    
  3. 应用 YAML 并确保 Pod 正在运行:

    kubectl apply -f onvif-mock.yaml
    kubectl get pods
    
  4. 若要启用要发现此模拟 ONVIF 相机的 IP 规则,请执行以下操作:

    • 如果 CNI 是 Flannel:

      Invoke-AksEdgeNodeCommand -NodeType "Linux" -command "sudo ip route add 239.255.255.250/32 dev cni0"
      
    • 如果你的 CNI 是 Calico:

      1. 查找模拟 ONVIF 容器的 IP:

        kubectl get pods -o wide
        
      2. 查找与 ONVIF pod (IP 匹配的网络接口名称,即 cali909b8c65537) :

        Invoke-AksEdgeNodeCommand -NodeType "Linux" -command "route"
        
      3. 现在启用 ONVIF 发现:

        Invoke-AksEdgeNodeCommand -NodeType "Linux" -command "sudo ip route add 239.255.255.250/32 dev <insert interface name>"
        
    • 此外,如果使用外部交换机运行完整部署,请启用 dport 3702 并保存 IP 表:

      Invoke-AksEdgeNodeCommand -NodeType "Linux" -command "sudo iptables -A INPUT -p udp --dport 3702 -j ACCEPT"
      Invoke-AksEdgeNodeCommand -NodeType "Linux" -command "sudo sed -i '/-A OUTPUT -j ACCEPT/i-A INPUT -p udp -m udp --dport 3702 -j ACCEPT' /etc/systemd/scripts/ip4save"
      

现在,你已准备好运行 Akri 并发现模拟 ONVIF 相机。

运行 Akri

  1. 添加 Akri Helm 图表(如果尚未添加):

    helm repo add akri-helm-charts https://project-akri.github.io/akri/
    

    如果之前已添加 Akri helm 图表,请更新最新版本的存储库:

    helm repo update
    
  2. 使用 Helm 安装 Akri。 安装 Akri 时,请通过设置 helm 值 onvif.discovery.enabled=true来指定要部署 ONVIF 发现处理程序。 此外,指定要部署 ONVIF 视频代理:

    helm install akri akri-helm-charts/akri `
     --set onvif.discovery.enabled=true `
     --set onvif.configuration.enabled=true `
     --set onvif.configuration.capacity=2 `
     --set onvif.configuration.brokerPod.image.repository='ghcr.io/project-akri/akri/onvif-video-broker' `
     --set onvif.configuration.brokerPod.image.tag='latest'
    

    在此处详细了解 ONVIF 配置设置

打开 WS-Discovery 端口

为了使 AKS Edge Essentials 群集能够发现相机,请打开 WS-Discovery (Web Services 动态发现) 的端口,这是一种通过 TCP 和 UDP 端口 3702运行的多播发现协议。

  1. 运行以下命令以在 Linux 节点中打开 sport 3702 并保存 IP 表:

    Invoke-AksEdgeNodeCommand -NodeType "Linux" -command "sudo iptables -A INPUT -p udp --sport 3702 -j ACCEPT"
    Invoke-AksEdgeNodeCommand -NodeType "Linux" -command "sudo sed -i '/-A OUTPUT -j ACCEPT/i-A INPUT -p udp -m udp --sport 3702 -j ACCEPT' /etc/systemd/scripts/ip4save"
    
  2. 验证 Akri 现在可以发现你的相机。 应看到 ONVIF 相机的一个 Akri 实例:

    kubectl get akrii
    

    显示发现的 ONVIF 相机的 Akri 实例的屏幕截图。

部署视频流式处理 Web 应用程序

  1. 打开空白 YAML 文件,将以下内容复制/粘贴到文件中:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: akri-video-streaming-app
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: akri-video-streaming-app
      template:
        metadata:
          labels:
            app: akri-video-streaming-app
        spec:
          nodeSelector:
            "kubernetes.io/os": linux
          serviceAccountName: akri-video-streaming-app-sa
          containers:
          - name: akri-video-streaming-app
            image: ghcr.io/project-akri/akri/video-streaming-app:latest-dev
            imagePullPolicy: Always
            env:
            - name: CONFIGURATION_NAME
              value: akri-onvif
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: akri-video-streaming-app
      namespace: default
      labels:
        app: akri-video-streaming-app
    spec:
      selector:
        app: akri-video-streaming-app
      ports:
      - name: http
        port: 80
        targetPort: 5000
      type: NodePort
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: akri-video-streaming-app-sa
    ---
    kind: ClusterRole
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: akri-video-streaming-app-role
    rules:
    - apiGroups: [""]
      resources: ["services"]
      verbs: ["list"]
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: akri-video-streaming-app-binding
    roleRef:
      apiGroup: ""
      kind: ClusterRole
      name: akri-video-streaming-app-role
    subjects:
      - kind: ServiceAccount
        name: akri-video-streaming-app-sa
        namespace: default
    
  2. 将文件另存为 akri-video-streaming-app.yaml

  3. 在 PowerShell 窗口中,将目录更改为 akri-video-straming-app.yaml 文件的位置,并将其部署到群集:

    kubectl apply -f akri-video-streaming-app.yaml
    
  4. 确保所有 Pod 都已启动并运行:

    显示 Akri Pod 和视频应用 Pod 正在运行的屏幕截图。

  5. 查找 Linux 节点 IP 和 Web 应用服务的端口:

    Get-AksEdgeNodeAddr
    
    kubectl get svc
    

    显示 Web 应用服务的节点地址和端口的屏幕截图。

  6. 现在,可以通过导航到 Web 应用程序来查看视频片段,即 <NODE IP>:<PORT OF SERVICE>

    显示 Web 应用程序上显示的 IP 摄像头的实时流镜头的屏幕截图。

清理

  1. 删除视频流式处理 Web 应用程序:

    kubectl delete -f akri-video-streaming-app.yaml
    
  2. 从群集中卸载 Akri:

    helm delete akri
    
  3. (可选) 如果使用了模拟 ONVIF 相机,请删除部署:

    kubectl delete -f onvif-mock.yaml
    

后续步骤

AKS Edge Essentials 概述