Descobrir câmaras ONVIF com o Akri

O Akri é uma interface de recursos do Kubernetes que lhe permite expor facilmente dispositivos de folha heterogéneos (como câmaras IP e dispositivos USB) como recursos num cluster do Kubernetes e deteta continuamente nós que têm acesso a estes dispositivos para agendar cargas de trabalho com base nos mesmos. O Akri é um projeto de sandbox CNCF criado para a periferia, que lida com o aspeto dinâmico e o desaparecimento de dispositivos de folha. Atualmente, suporta protocolos OPC UA, ONVIF e udev, mas também pode implementar processadores de protocolos personalizados fornecidos pelo modelo. Leia mais sobre o Akri aqui.

Este artigo descreve como pode detetar câmaras ONVIF ligadas à mesma rede que o cluster do AKS Edge Essentials. A ONVIF é um padrão do setor aberto para dispositivos de segurança IP, normalmente utilizados para videovigilância. Leia mais sobre os perfis ONVIF aqui. Esta demonstração ajuda-o a começar a utilizar o Akri para detetar câmaras IP através do protocolo ONVIF e utilizá-las através de um mediador de vídeo que lhe permite consumir as imagens da câmara e apresentá-las numa aplicação Web.

Diagrama que mostra o fluxo da demonstração do Akri ONVIF.

Pré-requisitos

  • Uma implementação de máquina única ou uma implementação completa do AKS Edge Essentials em execução (se estiver a utilizar uma câmara IP ONVIF real, tem de criar uma implementação completa com um comutador externo).
  • O Akri só funciona no Linux: utilize nós linux para este exercício.
  • Uma câmara IP ONVIF ligada à mesma rede que o cluster de comutadores externos ou um contentor ONVIF simulado em execução (passos de implementação da seguinte forma).

Nota

Atualmente, este mediador ONVIF de exemplo não suporta a ligação a câmaras que necessitem de autenticação. Para executar esta demonstração, desative a autenticação na câmara ONVIF.

Simular contentor ONVIF

Se não tiver uma câmara IP ONVIF, pode utilizar o nosso contentor ONVIF simulado para este exercício. O contentor simulado funciona numa única máquina ou numa implementação completa.

  1. (Opcional) Se quiser configurar um feed de vídeo RTSP personalizado para o contentor ONVIF, guarde o vídeo mp4 (funciona melhor se a qualidade for SD em vez de HD) e copie o ficheiro do diretório do computador anfitrião para o nó do Linux com o seguinte comando (certifique-se de que substitui o diretório do computador anfitrião e o nome de ficheiro de vídeo adequado):

    Copy-AksEdgeNodeFile -FromFile C:\Users\WinIotUser\Downloads\sample.mp4 -toFile /home/aksedge-user/sample.mp4 -PushFile
    
  2. Abra um ficheiro YAML vazio e copie/cole os seguintes conteúdos. Certifique-se de que substitui o valor depois /mnt/ pelo nome do ficheiro de vídeo em MP4FILE. Guarde o ficheiro como 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. Aplique o YAML e certifique-se de que o pod está em execução:

    kubectl apply -f onvif-mock.yaml
    kubectl get pods
    
  4. Para ativar as regras de IP para esta câmara ONVIF simulada a ser detetada:

    • Se a sua CNI for Flannel:

      Invoke-AksEdgeNodeCommand -NodeType "Linux" -command "sudo ip route add 239.255.255.250/32 dev cni0"
      
    • Se a sua CNI for Calico:

      1. Localize o IP do contentor DO ONVIF simulado:

        kubectl get pods -o wide
        
      2. Localize o nome da interface de rede que corresponde ao IP do pod ONVIF (ou seja, cali909b8c65537):

        Invoke-AksEdgeNodeCommand -NodeType "Linux" -command "route"
        
      3. Agora, ative a deteção ONVIF:

        Invoke-AksEdgeNodeCommand -NodeType "Linux" -command "sudo ip route add 239.255.255.250/32 dev <insert interface name>"
        
    • Além disso, se estiver a executar uma implementação completa com um comutador externo, ative e dport 3702 guarde as tabelas 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"
      

Agora, está pronto para executar o Akri e descobrir a câmara ONVIF falsa.

Executar o Akri

  1. Adicione os gráficos Akri Helm se ainda não o tiver feito:

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

    Se já tiver adicionado anteriormente o gráfico helm do Akri, atualize o repositório para obter a compilação mais recente:

    helm repo update
    
  2. Instale o Akri com o Helm. Ao instalar o Akri, especifique que pretende implementar os processadores de deteção ONVIF ao definir o valor onvif.discovery.enabled=truedo helm . Além disso, especifique que pretende implementar o mediador de vídeo 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'
    

    Saiba mais sobre as definições de configuração do ONVIF aqui.

Abrir a porta WS-Discovery

Para que o cluster do AKS Edge Essentials descubra a câmara, abra a porta para WS-Discovery (Web Services Dynamic Discovery), que é um protocolo de deteção multicast que funciona através da porta 3702TCP e UDP.

  1. Execute o seguinte comando para abrir sport 3702 no nó linux e guardar as tabelas 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. Verifique se o Akri pode agora detetar a sua câmara. Deverá ver uma instância do Akri para a câmara ONVIF:

    kubectl get akrii
    

    Captura de ecrã a mostrar a instância do Akri para a câmara ONVIF detetada.

Implementar aplicação Web de transmissão em fluxo de vídeo

  1. Abra um ficheiro YAML em branco e copie/cole os seguintes conteúdos no ficheiro:

    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. Guarde o ficheiro como akri-video-streaming-app.yaml.

  3. Na janela do PowerShell, altere o diretório para a localização do ficheiro akri-video-straming-app.yaml e implemente-o no cluster:

    kubectl apply -f akri-video-streaming-app.yaml
    
  4. Certifique-se de que todos os pods estão em execução:

    Captura de ecrã a mostrar os pods do Akri e o pod da aplicação de vídeo em execução.

  5. Localize o IP do nó linux e a porta do seu serviço de aplicações Web:

    Get-AksEdgeNodeAddr
    
    kubectl get svc
    

    Captura de ecrã a mostrar o endereço e a porta do nó do serviço de aplicações Web.

  6. Agora, pode ver as imagens de vídeo ao navegar para a sua aplicação Web, que é <NODE IP>:<PORT OF SERVICE>:

    Captura de ecrã a mostrar imagens em direto da câmara IP a serem apresentadas na aplicação Web.

Limpeza

  1. Elimine a aplicação Web de transmissão em fluxo de vídeo:

    kubectl delete -f akri-video-streaming-app.yaml
    
  2. Desinstale o Akri do cluster:

    helm delete akri
    
  3. (Opcional) Se utilizou a câmara ONVIF falsa, elimine a implementação:

    kubectl delete -f onvif-mock.yaml
    

Passos seguintes

Descrição geral do AKS Edge Essentials