--- apiVersion: codemowers.cloud/v1beta1 kind: MinioBucketClaim metadata: name: camtiler spec: capacity: 150Gi class: dedicated --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: cams.k-space.ee spec: group: k-space.ee names: plural: cams singular: cam kind: Camera shortNames: - cam scope: Namespaced versions: - name: v1alpha1 served: true storage: true schema: openAPIV3Schema: type: object properties: spec: type: object properties: roi: type: object description: Region of interest for this camera properties: threshold: type: integer description: Percentage of pixels changed within ROI to consider whole frame to have motion detected. Defaults to 5. enabled: type: boolean description: Whether motion detection is enabled for this camera. Defaults to false. left: type: integer description: Left boundary of ROI as percentage of the width of a frame. By default 0. right: type: integer description: Right boundary of ROI as percentage of the width of a frame. By default 100. top: type: integer description: Top boundary of ROI as percentage of the height of a frame By deafault 0. bottom: type: integer description: Bottom boundary of ROI as percentage of the height of a frame. By default 100. secretRef: type: string description: Secret that contains authentication credentials target: type: string description: URL of the video feed stream replicas: type: integer minimum: 1 maximum: 2 description: For highly available deployment set this to 2 or higher. Make sure you also run Mongo and Minio in HA configurations required: ["target"] required: ["spec"] --- apiVersion: codemowers.io/v1alpha1 kind: ClusterOperator metadata: name: camera spec: resource: group: k-space.ee version: v1alpha1 plural: cams secret: enabled: false services: - apiVersion: v1 kind: Service metadata: name: foobar labels: app.kubernetes.io/name: foobar component: camera-motion-detect spec: type: ClusterIP selector: app.kubernetes.io/name: foobar component: camera-motion-detect ports: - protocol: TCP port: 80 targetPort: 5000 deployments: - apiVersion: apps/v1 kind: Deployment metadata: name: camera-foobar spec: revisionHistoryLimit: 0 replicas: 1 strategy: type: RollingUpdate rollingUpdate: # Swap following two with replicas: 2 maxSurge: 1 maxUnavailable: 0 selector: matchLabels: app.kubernetes.io/name: foobar template: metadata: labels: app.kubernetes.io/name: foobar component: camera-motion-detect spec: containers: - name: camera-motion-detect image: harbor.k-space.ee/k-space/camera-motion-detect:latest starupProbe: httpGet: path: /healthz port: 5000 initialDelaySeconds: 2 periodSeconds: 180 timeoutSeconds: 60 readinessProbe: httpGet: path: /readyz port: 5000 initialDelaySeconds: 60 periodSeconds: 60 timeoutSeconds: 5 ports: - containerPort: 5000 name: "http" resources: requests: memory: "64Mi" cpu: "200m" limits: memory: "256Mi" cpu: "4000m" securityContext: readOnlyRootFilesystem: true runAsNonRoot: true runAsUser: 1000 command: - /app/camdetect.py - http://user@foobar.cam.k-space.ee:8080/?action=stream env: - name: SOURCE_NAME value: foobar - name: S3_BUCKET_NAME valueFrom: secretKeyRef: name: miniobucket-camtiler-owner-secrets key: BUCKET_NAME - name: S3_ENDPOINT_URL valueFrom: secretKeyRef: name: miniobucket-camtiler-owner-secrets key: AWS_S3_ENDPOINT_URL - name: AWS_SECRET_ACCESS_KEY valueFrom: secretKeyRef: name: miniobucket-camtiler-owner-secrets key: AWS_SECRET_ACCESS_KEY - name: AWS_ACCESS_KEY_ID valueFrom: secretKeyRef: name: miniobucket-camtiler-owner-secrets key: AWS_ACCESS_KEY_ID - name: BASIC_AUTH_PASSWORD valueFrom: secretKeyRef: name: camera-secrets key: password - name: MONGO_URI valueFrom: secretKeyRef: name: mongodb-application-readwrite key: connectionString.standard # Make sure 2+ pods of same camera are scheduled on different hosts affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app.kubernetes.io/name operator: In values: - foobar topologyKey: topology.kubernetes.io/zone # Make sure camera deployments are spread over workers topologySpreadConstraints: - maxSkew: 1 topologyKey: topology.kubernetes.io/zone whenUnsatisfiable: DoNotSchedule labelSelector: matchLabels: app.kubernetes.io/name: foobar component: camera-motion-detect --- apiVersion: monitoring.coreos.com/v1 kind: PrometheusRule metadata: name: cameras spec: groups: - name: cameras rules: - alert: CameraLost expr: rate(camtiler_frames_total{stage="downloaded"}[1m]) < 1 for: 2m labels: severity: warning annotations: summary: Camera feed stopped - alert: CameraServerRoomMotion expr: rate(camtiler_events_total{app_kubernetes_io_name="server-room"}[30m]) > 0 for: 1m labels: severity: warning annotations: summary: Motion was detected in server room - alert: CameraSlowUploads expr: camtiler_queue_frames{stage="upload"} > 10 for: 5m labels: severity: warning annotations: summary: Motion detect snapshots are piling up and not getting uploaded to S3 - alert: CameraSlowProcessing expr: camtiler_queue_frames{stage="download"} > 10 for: 5m labels: severity: warning annotations: summary: Motion detection processing pipeline is not keeping up with incoming frames - alert: CameraResourcesThrottled expr: sum by (pod) (rate(container_cpu_cfs_throttled_periods_total{namespace="camtiler"}[1m])) > 0 for: 5m labels: severity: warning annotations: summary: CPU limits are bottleneck --- apiVersion: k-space.ee/v1alpha1 kind: Camera metadata: name: workshop spec: target: http://user@workshop.cam.k-space.ee:8080/?action=stream secretRef: camera-secrets replicas: 1 --- apiVersion: k-space.ee/v1alpha1 kind: Camera metadata: name: server-room spec: target: http://user@server-room.cam.k-space.ee:8080/?action=stream secretRef: camera-secrets replicas: 2 --- apiVersion: k-space.ee/v1alpha1 kind: Camera metadata: name: printer spec: target: http://user@printer.cam.k-space.ee:8080/?action=stream secretRef: camera-secrets replicas: 1 --- apiVersion: k-space.ee/v1alpha1 kind: Camera metadata: name: chaos spec: target: http://user@chaos.cam.k-space.ee:8080/?action=stream secretRef: camera-secrets replicas: 1 --- apiVersion: k-space.ee/v1alpha1 kind: Camera metadata: name: cyber spec: target: http://user@cyber.cam.k-space.ee:8080/?action=stream secretRef: camera-secrets replicas: 1 --- apiVersion: k-space.ee/v1alpha1 kind: Camera metadata: name: kitchen spec: target: http://user@kitchen.cam.k-space.ee:8080/?action=stream secretRef: camera-secrets replicas: 1 --- apiVersion: k-space.ee/v1alpha1 kind: Camera metadata: name: back-door spec: target: http://user@100.102.3.3:8080/?action=stream secretRef: camera-secrets replicas: 1 --- apiVersion: k-space.ee/v1alpha1 kind: Camera metadata: name: ground-door spec: target: http://user@100.102.3.1:8080/?action=stream secretRef: camera-secrets replicas: 1 --- apiVersion: monitoring.coreos.com/v1 kind: PodMonitor metadata: name: camera-motion-detect spec: selector: matchLabels: component: camera-motion-detect podMetricsEndpoints: - port: http podTargetLabels: - app.kubernetes.io/name - component