Mentions légales du service

Skip to content
Snippets Groups Projects
user avatar
sidi mohammed kaddour authored
cb3800f4
History

Surveillance System Wiki

Overview

Alt text

This surveillance system is designed to process video feeds using a distributed Edge-to-Cloud architecture. Its primary goal is to identify and alert residents and authorities about dangerous animals detected in video footage. The system integrates edge devices (for real-time processing) and cloud servers (for intensive tasks like object recognition), ensuring quick and accurate responses.

Table of Contents

  1. Overview
  2. System Components
  3. Docker Compose Tutorial
  4. Deploying on K3S using Enoslib on Grid'5000

System Components

Camera

  • Function: Captures video frames, resizes them for optimized processing, and serializes and transmits them to the Motion Detection service.
  • Key Features:
    • Handles video sequences based on detected animal types.
    • Configurable appearance frequency for specific events.
    • Tracks FPS rate and integrates with TracerProvider for distributed tracing.
  • Connection: Maintains a persistent TCP connection for frame transmission.

Motion Detection

  • Function: Processes frames from the Camera to detect significant motion and forwards relevant frames to Object Recognition.
  • Key Features:
    • Motion detection using grayscale and Gaussian blur.
    • Real-time performance monitoring of CPU usage, frame processing time, and FPS.
    • Integrates with TracerProvider for tracing frame reception, processing, and transmission.
  • Connection: Listens for incoming frames from the Camera and sends processed frames to Object Recognition.

Object Recognizer

  • Function: Uses YOLO to detect objects in frames and tracks performance metrics like processing time and response time.
  • Key Features:
    • YOLO v3 for object detection.
    • Distributed tracing for end-to-end monitoring.
    • Supports multiple clients with concurrency.
  • Connection: Listens for incoming frames from the Motion Detection service and processes them asynchronously.

Other Components

OpenTelemetry Collector

  • Function: Collects, processes, and exports telemetry data (traces, metrics, logs).
  • Metrics Sent:
    • Collects data from Camera, Motion Detection, Object Recognition.
    • Sends telemetry data to Prometheus or other backends for visualization.

cAdvisor

  • Function: Monitors container resource usage (CPU, memory, network).
  • Metrics Sent:
    • CPU, memory, network I/O, disk I/O, container lifespan metrics.

Node Exporter

  • Function: Exports hardware and system performance metrics from Linux systems.
  • Metrics Sent:
    • CPU load, memory usage, disk utilization, network stats, and system uptime.

Prometheus

  • Function: Scrapes and stores metrics from various exporters and services.
  • Metrics Collected:
    • Application, service, and system-level metrics (e.g., FPS, processing time, system performance).

Services Environment Variables

  • Object Recognizer:
    No environment variables are specified for this service at the moment. The type of model will be introduced in future updates.

  • Motion Detector:

    • INDEX: A unique identifier assigned to each motion detector instance (e.g., 1, 2, 3). This helps distinguish between multiple motion detectors in the system, ensuring proper management and identification.
    • OR_HOST: The hostname of the Object Recognizer service (default: object_recognizer). This specifies the location of the Object Recognizer service that the motion detector will send detected frames to for object identification.
    • OR_PORT: The network port on which the Object Recognizer service is listening (default: 9999). This ensures communication between the motion detector and object recognizer services through the correct port.
  • Camera:

    • CAMERA: If set to true, it processes stored footage; otherwise, a link to live streaming sources must be provided. This determines whether the camera service reads pre-recorded footage or requires a live feed from streaming sources to work.
    • ANIMAL_NAME: The name of the animal being monitored by the camera (e.g., tiger, bear, wolf). Specifying the animal name helps evaluate the accuracy of the recognition algorithm by tracking the correct target in the footage, which is crucial for assessing detection performance.
    • APPEARANCE_RATE: The frequency at which the animal appears in the footage (in frames per minute). This provides an estimate of how often the animal is expected to appear and helps flood the Object Recognizer with many frames to test its performance under high load.
    • MDHOST: The hostname of the associated Motion Detector (e.g., motion_detector_1, motion_detector_2). This links the camera to the correct motion detector service so that captured footage can be processed for motion detection.
    • MDPORT: The port on which the associated Motion Detector is listening (default: 9998). This specifies the communication port between the camera and motion detector for seamless data transfer.
    • INDEX: A unique identifier for each camera instance (e.g., 1, 2, 3). This differentiates between multiple camera instances in the system, ensuring they can be tracked, managed, and analyzed individually.

Docker Compose Tutorial

Step 0: Prerequisites

  1. Install Docker & Docker Compose:
    Docker | Docker Compose

  2. Install Git:
    Git Downloads

  3. Basic Docker Knowledge:
    Review Docker Docs.

How’s that?

Step 1: Build Docker Images for Services

  1. Clone the repository:
    First, clone the repository to your local machine:

    git clone https://gitlab.inria.fr/sikaddou/surveillance-system-edge-to-cloud-video-processing.git
    cd surveillance-system-edge-to-cloud-video-processing
  2. Build the Docker images locally:
    You don't need to navigate to each service's directory individually. From the root of the cloned repository, run the following commands to build the Docker images for each service:

    docker build -t camera:latest ./services/camera
    docker build -t motion_detector:latest ./services/motion_detector
    docker build -t object_recognizer:latest ./services/object_recognizer

    These commands will automatically find the Dockerfile in each service's directory (./services/camera, ./services/motion_detector, and ./services/object_recognizer). The latest tag is used to mark the most recent image.

  3. (Optional) Push the images to your Docker repository:
    If you want to make the images available remotely, you can push them to your Docker Hub or GitHub Container Registry. Follow these steps:

    • Tag the images for your repository: Replace <your-username> with your Docker Hub or GitHub username, and <repository> with the desired image repository name.

      docker tag camera:latest <your-username>/camera:latest
      docker tag motion_detector:latest <your-username>/motion_detector:latest
      docker tag object_recognizer:latest <your-username>/object_recognizer:latest
    • Log in to your Docker registry:

      docker login

      Enter your credentials when prompted.

    • Push the images:

      docker push <your-username>/camera:latest
      docker push <your-username>/motion_detector:latest
      docker push <your-username>/object_recognizer:latest

    Once pushed, these images will be available in your registry and can be pulled by others using:

    docker pull <your-username>/camera:latest
    docker pull <your-username>/motion_detector:latest
    docker pull <your-username>/object_recognizer:latest

Step 2: Create or Update docker-compose.yml

Services Environment Variables

  • Object Recognizer:
    No environment variables are specified for this service at the moment. The type of model will be introduced in future updates.

  • Motion Detector:

    • INDEX: A unique identifier for each motion detector instance (e.g., 1, 2, 3).
    • OR_HOST: The hostname of the Object Recognizer service (default: object_recognizer).
    • OR_PORT: The port on which the Object Recognizer service is listening (default: 9999).
  • Camera:

    • CAMERA:If set to true, it reads stored footage; otherwise, a link to the streaming sources must be provided.
    • ANIMAL_NAME: The name of the animal being monitored by the camera (e.g., tiger, bear, wolf).
    • APPEARANCE_RATE: The frequency at which the animal appears in the footage (in frames per minute).
    • MDHOST: The hostname of the associated Motion Detector (e.g., motion_detector_1, motion_detector_2, motion_detector_3).
    • MDPORT: The port on which the associated Motion Detector is listening (default: 9998).
    • INDEX: A unique identifier for each camera instance (e.g., 1, 2, 3).

You can find a complete example configuration in the deploy/docker-compose directory. Ensure the docker-compose.yml file is properly set up before deployment.


Step 3: Deploy with Docker Compose

  1. Navigate to the deployment directory:

    cd deploy/docker-compose
  2. Build and start the services:

    docker-compose up -d --build --force-recreate
  3. (Optional) Stop and remove existing containers and volumes:

    docker-compose down --volumes --remove-orphans

Would you like additional details or further simplifications?

Step 4: Verify the Deployment

  1. Check the status of running containers: You can check if the containers are running properly with the following command:

    docker ps
  2. Access the services:

Deploying on K3S using Enoslib on Grid'5000

This tutorial will walk you through the steps required to deploy a Kubernetes cluster on K3s using Enoslib on the Grid'5000 (G5k) infrastructure. The focus is on deploying the surveillance system, which includes components such as the Camera, Motion Detection, and Object Recognizer. These steps cover cluster configuration, deployment of Kubernetes resources, Helm setup, Prometheus and Chaos Mesh installation, and additional tasks for monitoring and resilience testing of the system.

Step 0: Prerequisites

  • Grid'5000 account and access to the infrastructure.
  • enoslib installed on your local machine. ssh installed on your local machine.

Step 1: Initialize Logging

First, initialize the logging for the deployment process.

import enoslib as en
from datetime import datetime

# Initialize logging
_ = en.init_logging()

# Generate a timestamp for the job name
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
job_name = f"usecase_{timestamp}"

Step 2: Cluster Resource Configuration

Define the configuration for the cluster resources on Grid'5000. This will specify the number of machines for each role (master, agent, etc.).

cluster = "parasilo"
conf = (
    en.VMonG5kConf
    .from_settings(job_name=job_name, walltime="04:00:00")
    .add_machine(roles=["master"], cluster=cluster, number=1, flavour="large")
    .add_machine(roles=["agent", "object_recognizer"], cluster=cluster, number=1, flavour_desc={"core": 8, "mem": 8192})
    .add_machine(roles=["agent", "motion_detector"], cluster=cluster, number=3, flavour_desc={"core": 4, "mem": 4096})
    .add_machine(roles=["agent", "camera"], cluster=cluster, number=3, flavour_desc={"core": 1, "mem": 1024})
    .finalize()
)

# Initialize the provider
provider = en.VMonG5k(conf)
roles, networks = provider.init()
en.wait_for(roles)

Step 3: Kubernetes Setup

Deploy the K3s cluster and ensure that it’s set up correctly.

# Initialize K3s with master and agent nodes
k3s = en.K3s(master=roles["master"], agent=roles["agent"])
k3s.deploy()

# Create a tunnel to the head node
print("Create a tunnel from your local machine to the head node:")
print(f"ssh -NL 8001:{roles['master'][0].address}:8001 {G5K_username}@access.grid5000.fr")

Step 4: Label Nodes

Label your nodes with specific attributes based on their roles (cloud, edge, camera).

def label_nodes(node_names, labels):
    label_str = ",".join(f"{key}={value}" for key, value in labels.items())

    for node in node_names:
        command = f"kubectl label nodes {node} {label_str} --overwrite"
        try:
            result = en.run_command(command, roles=roles['master'])
            print(f"Successfully labeled {node} with {label_str}")
        except subprocess.CalledProcessError as e:
            print(f"Failed to label {node}. Error: {e.stderr.decode('utf-8')}")

# Label nodes
label_nodes([str(node.alias) for node in roles["object_recognizer"]], {"pos": "cloud"})
label_nodes([str(node.alias) for node in roles["motion_detector"]], {"pos": "edge"})
label_nodes([str(node.alias) for node in roles["camera"]], {"pos": "camera"})

Step 5: Docker Registry Secret

Create a Docker registry secret with anonymized credentials to authenticate with Docker Hub.

docker_username = "username_placeholder"
docker_password = "password_placeholder"
docker_email = "email_placeholder"

# Create the Docker registry secret
en.run_command(f"kubectl create secret docker-registry dockerhub-secret \
  --docker-username={docker_username} \
  --docker-password={docker_password} \
  --docker-email={docker_email}", roles=roles['master'])

Step 6: Send Files to Cluster

Transfer necessary configuration files to the cluster using scp.

import os

def send_file(file_path, file_name):
    scp_command = f"scp {file_path} root@{roles['master'][0].address}:{file_name}"
    os.system(f"ssh-keygen -f /home/{G5k_username} /.ssh/known_hosts -R {roles['master'][0].address}")
    os.system(scp_command)
    return scp_command

# Send configuration files to the cluster
local_directory = "deploy/G5k/K3S/config"
for root, dirs, files in os.walk(local_directory):
    for file_name in files:
        send_file(local_directory + file_name, file_name)

# Apply Kubernetes manifests
en.run_command("kubectl apply -f deployement.yaml", roles=roles['master'])
en.run_command("kubectl apply -f configmap.yaml", roles=roles['master'])

Step 7: Helm Installation and Prometheus Setup

Install Helm, add Prometheus charts, and deploy Prometheus for monitoring.

with en.actions(roles=roles["master"]) as a:
    a.raw("curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3")
    a.raw("chmod 700 get_helm.sh")
    a.raw("./get_helm.sh")

    # Install Prometheus
    a.raw("helm --kubeconfig /etc/rancher/k3s/k3s.yaml repo add prometheus-community https://prometheus-community.github.io/helm-charts")
    a.raw("helm --kubeconfig /etc/rancher/k3s/k3s.yaml repo update")
    a.raw("helm --kubeconfig /etc/rancher/k3s/k3s.yaml install prometheus prometheus-community/prometheus -n default --set grafana.enabled=True -f costum-values.yaml")
    a.raw("helm --kubeconfig /etc/rancher/k3s/k3s.yaml upgrade --kubeconfig /etc/rancher/k3s/k3s.yaml prometheus prometheus-community/prometheus --namespace default --set prometheus-node-exporter.service.port=9500")

Step 8: Chaos Mesh Installation

Install Chaos Mesh using Helm for fault injection and resilience testing.

with en.actions(roles=roles["master"]) as a:
    a.raw("helm --kubeconfig /etc/rancher/k3s/k3s.yaml repo add chaos-mesh https://charts.chaos-mesh.org")
    a.raw("helm --kubeconfig /etc/rancher/k3s/k3s.yaml repo update")
    a.raw("helm --kubeconfig /etc/rancher/k3s/k3s.yaml install chaos-mesh chaos-mesh/chaos-mesh --set chaosDaemon.runtime=containerd --set chaosDaemon.containerdSocket=/run/containerd/containerd.sock -n default")
    a.raw("kubectl apply -f rbac.yaml")
    a.raw("kubectl create token account-default-admin-eechh")
    a.raw('kubectl patch svc chaos-dashboard -n default -p \'{"spec": {"ports": [{"name": "http", "protocol": "TCP", "port": 2333, "targetPort": 2333, "nodePort": 30312}]}}\'')

Step 9: Patch Prometheus Service

Expose Prometheus service on a NodePort for web access.

with en.actions(roles=roles["master"]) as a:
    a.raw('kubectl patch svc prometheus-server -n default -p \'{"spec": {"type": "NodePort", "ports": [{"name": "http", "port": 80, "targetPort": 9090, "nodePort": 30090}]}}\'')

Step 10: Fetch Webpage Hosts

Retrieve the host IP of Prometheus and Chaos Dashboard services.

def get_host(service):
    results = en.run_command(f"kubectl get pods -n kube-system -l app={service}", roles=roles['master'])
    import re
    pattern = r"host='([^']*)'"
    match = re.search(pattern, str(results))

    if match:
        host = match.group(1)
        print("Extracted host:", host)
    else:
        print("Host not found")
        return None

    results = en.run_command(f"kubectl describe node {host}", roles=roles['master'])
    pattern = r"InternalIP:\s*([\d.]+)"
    match = re.search(pattern, str(results))

    if match:
        return match.group(1)
    else:
        print("Host not found")
        return None

# Fetch the Prometheus and Chaos Dashboard IPs
url = f"http://{get_host('prometheus')}:30090"
print(f"Prometheus web page host: {url}")

url = f"http://{get_host('chaos-dashboard')}:30312"
print(f"Chaos-mesh web page host: {url}")

Step 11: Token Creation and Cleanup

Create the necessary tokens and perform cleanup after the job is complete.

results = en.run_command("kubectl create token account-default-admin-eechh", roles=roles["master"])
for res in results:
    print(res.payload['stdout'])

# Cleanup the resources
provider.destroy()

Conclusion

By following the steps above, you have successfully deployed the surveillence system on Kubernetes cluster using K3s on Grid'5000, set up monitoring with Prometheus, fault injection with Chaos Mesh, and labeled nodes for efficient management.