LogoLogo
To the Oz WebsiteOz API ReferenceContact Us
  • General
    • Oz Liveness and Biometry Key Concepts
      • Solution Architecture
      • Liveness, Face Matching, Black List Checks
      • Passive and Active Liveness
      • Hybrid Liveness
      • Oz API Key Concepts
      • Oz API vs. Oz API Lite
      • SaaS, On-premise, On-device: What to Choose
      • Oz Licensing Options
    • Integration Quick Start Guides
      • Server-Based Liveness
        • How to Integrate Server-Based Liveness into Your Web Application
        • How to Integrate Server-Based Liveness into Your Mobile Application
        • How to Check Your Media for Liveness without Oz Front End
      • On-Device Liveness
        • How to Integrate On-Device Liveness into Your Mobile Application
      • Face Matching
        • How to Add Face Matching of Liveness Video with a Reference Photo From Your Database
        • How to Add Photo ID Capture and Face Matching to Your Web or Mobile Application
  • Guides
    • Developer Guide
      • API
        • Oz API
          • Working with Oz System: Basic Scenarios
            • Authentication
            • Uploading Media
            • Liveness
            • Biometry (Face Matching)
            • Best Shot
            • Blacklist Check
              • Blacklist (Collection) Management in Oz API
            • Quantitative Results
            • Using a Webhook to Get Results
            • Single Request
            • Instant API: Non-Persistent Mode
          • System Objects
          • User Roles
          • Types of Analyses and What They Check
          • Rules of Assigning Analyses
          • Statuses in API
          • Media Tags
          • Metadata
          • API Error Codes
          • Oz API Postman Collections
          • Changelog
        • Oz API Lite
          • API Lite Methods
          • Oz API Lite Postman Collection
          • Changelog
      • SDK
        • Oz Mobile SDK (iOS, Android, Flutter)
          • On-Device Mode
          • Android
            • Getting a License for Android SDK
              • Master License for Android
            • Adding SDK to a Project
            • Connecting SDK to API
            • Capturing Videos
            • Checking Liveness and Face Biometry
            • Customizing Android SDK
              • How to Restore the Previous Design after an Update
            • Android Localization: Adding a Custom or Updating an Existing Language Pack
            • Android SDK Methods and Properties
            • Changelog
          • iOS
            • Getting a License for iOS SDK
              • Master License for iOS
            • Adding SDK to a Client’s Mobile App
            • Connecting SDK to API
            • Capturing Videos
            • Checking Liveness and Face Biometry
            • Customizing iOS SDK Interface
              • How to Restore the Previous Design after an Update
            • iOS Localization: Adding a Custom or Updating an Existing Language Pack
            • iOS SDK Methods and Properties
            • Changelog
          • Flutter
            • How to Install and Use Oz Flutter Plugin
            • Flutter SDK Methods and Properties
            • Changelog
        • Oz Liveness Web SDK
          • Web Plugin
            • Adding the Plugin to Your Web Page
            • Launching the Plugin
              • Description of the on_complete Callback
              • Description of the on_result Callback
              • Capturing Video and Description of the on_capture_complete Callback
              • Description of the on_error Callback
            • Closing or Hiding the Plugin
            • Localization: Adding a Custom Language Pack
            • Look-and-Feel Customization
              • Customization Options for Older Versions (before 1.0.1)
            • Security Recommendations
            • Browser Compatibility
            • No-Server Licensing
          • Changelog
    • Administrator Guide
      • Deployment Architecture
      • Installation in Docker
      • Installation in Kubernetes
      • Performance and Scalability Guide
      • Publishing API Methods in the Internet: Security Recommendations
      • Monitoring
      • License Server
      • Web Adapter Configuration
        • Installation and Licensing
        • Configuration File Settings
        • Configuration Using Environment Variables
        • Server Configuration via Environment Variables
      • Oz API Configuration
    • User Guide
      • Oz Web UI
        • Requesting Analyses
        • Users and Companies
        • Blacklist
        • Statistics
        • Settings
        • Changelog
  • Other
    • Media Quality Requirements
    • Oz SDK Media Quality Checks
    • Media File Size Overview
    • Compatibility
    • FAQ
    • Tips and Tricks
      • Oz Liveness Gestures: Table of Correspondence
      • Sudo without Password
      • Android: Certificate Validation Error
    • Previous Documentation
      • Mobile SDK
        • Android
          • Interactions with the Oz API Server
          • Uploading and Analyzing Media
        • iOS
          • Uploading and Analyzing Media
      • User Guides
        • Oz Demo Kit
        • Web UI
      • Oz Modules Installation
        • Standalone Installer
        • Oz System Lite
Powered by GitBook
On this page
  • Database Creation
  • Chart Deployment
  • API
  • TFSS (BIO)
  • Web SDK

Was this helpful?

Export as PDF
  1. Guides
  2. Administrator Guide

Installation in Kubernetes

PreviousInstallation in DockerNextPerformance and Scalability Guide

Last updated 4 months ago

Was this helpful?

To install Oz product via Kubernetes, consider using Helm charts.

  • Oz API and related components: .

    • API 5.2: version 0.11.x,

    • API 5.3 (regulatory update for Kazakhstan): 0.12.x.

  • Web SDK: . Please note: the version of the chart is not tied to the Web SDK version.

Database Creation

For testing purposes, the database installed and created automatically by the chart is sufficient. However, for production, we strongly recommend using a separate, self-managed database.

Recommended PostgreSQL version: 15.5.

PostgreSQL database parameters
  • max_connections: 2000 (may vary depending on number of API calls),

  • shared_buffers: 2 GB (amount of RAM divided by 2),

  • effective_cache_size: 6 GB (RAM – 2 GB),

  • maintenance_work_mem: 512 MB,

  • checkpoint_completion_target: 0.9,

  • wal_buffers: 16 MB,

  • default_statistics_target: 100,

  • random_page_cost: 1.1,

  • effective_io_concurrency: 200,

  • work_mem: 16 MB,

  • min_wal_size: 1 GB,

  • max_wal_size: 4 GB,

  • max_worker_processes: 4 (equal to the number of CPUs),

  • max_parallel_workers_per_gather: 2 (number of CPUs divided by 2),

  • max_parallel_workers: 4 (equal to the number of CPUs),

  • max_parallel_maintenance_workers: 2 (number of CPUs divided by 2),

  • If database is Dockered, set shm_size: '1gb'.

Create a database using the script(s) below.

    CREATE ROLE <<USERNAME>> WITH LOGIN PASSWORD '<<PASSWORD>>'
      INHERIT
      CONNECTION LIMIT -1
      NOSUPERUSER
      NOCREATEDB
      NOCREATEROLE
      NOREPLICATION ;
    CREATE DATABASE <<DB_NAME>>
      WITH OWNER = <<USERNAME>>
          ENCODING = 'UTF8'
          TABLESPACE = pg_default
          CONNECTION LIMIT = -1
          LC_COLLATE='en_US.UTF-8'
          LC_CTYPE='en_US.UTF-8'
          TEMPLATE template0;
    \c <<DB_NAME>>
    CREATE EXTENSION IF NOT EXISTS pgcrypto;
    CREATE ROLE <<O2N_USERNAME>> WITH LOGIN PASSWORD '<<O2N_PASSWORD>>'
      INHERIT
      CONNECTION LIMIT -1
      NOSUPERUSER
      NOCREATEDB
      NOCREATEROLE
      NOREPLICATION ;
    CREATE DATABASE <<O2N_DB_NAME>>
      WITH OWNER = <<O2N_USERNAME>>
          ENCODING = 'UTF8'
          TABLESPACE = pg_default
          CONNECTION LIMIT = -1
          LC_COLLATE='en_US.UTF-8'
          LC_CTYPE='en_US.UTF-8'
          TEMPLATE template0;
    \c <<O2N_DB_NAME>>
    CREATE EXTENSION IF NOT EXISTS pgcrypto;
    CREATE EXTENSION IF NOT EXISTS vector;

To increase performance, consider using this list of indexes:

Gateway indexes
CREATE INDEX CONCURRENTLY gw_analyse_abstract_company_id_idx ON public.gw_analyse_abstract USING btree (company_id);
CREATE INDEX CONCURRENTLY gw_analyse_abstract_folder_id ON public.gw_analyse_abstract USING btree (folder_id);
CREATE INDEX CONCURRENTLY gw_analyse_abstract_time_updated_state_idx ON public.gw_analyse_abstract USING btree (time_updated) WHERE (state = 'PROCESSING'::analyse_state);
CREATE INDEX CONCURRENTLY idx_gw_analyse_abstract_state_time_updated ON public.gw_analyse_abstract USING btree (state, time_updated);
CREATE INDEX CONCURRENTLY gw_analyse_collection_collection_id_idx ON public.gw_analyse_collection USING btree (collection_id);
CREATE INDEX CONCURRENTLY gw_analyse_collection_person_media_association_person_id_idx ON public.gw_analyse_collection_person_media_association USING btree (person_id);
CREATE INDEX CONCURRENTLY gw_analyse_cpma_media_association_id_idx ON public.gw_analyse_collection_person_media_association USING btree (media_association_id);
CREATE INDEX CONCURRENTLY gw_analyse_result_group_image_analyse_id_idx ON public.gw_analyse_result_group_image USING btree (analyse_id);
CREATE INDEX CONCURRENTLY gw_analyse_result_group_image_image_id_idx ON public.gw_analyse_result_group_image USING btree (image_id);
CREATE INDEX CONCURRENTLY gw_analyse_result_image_media_association_id_idx ON public.gw_analyse_result_image USING btree (media_association_id);   
CREATE INDEX CONCURRENTLY gw_analyse_source_media_association_analyse_id_idx ON public.gw_analyse_source_media_association USING btree (analyse_id);
CREATE INDEX CONCURRENTLY gw_analyse_source_media_association_source_image_id_idx ON public.gw_analyse_source_media_association USING btree (source_image_id);   
CREATE INDEX CONCURRENTLY gw_analyse_source_media_association_source_shots_set_id_idx ON public.gw_analyse_source_media_association USING btree (source_shots_set_id);
CREATE INDEX CONCURRENTLY gw_analyse_source_media_association_source_video_id_idx ON public.gw_analyse_source_media_association USING btree (source_video_id);
CREATE INDEX CONCURRENTLY gw_collection_company_id_idx ON public.gw_collection USING btree (company_id);
CREATE INDEX CONCURRENTLY gw_collection_creator_id_idx ON public.gw_collection USING btree (creator_id);
CREATE INDEX CONCURRENTLY gw_collection_person_collection_id_idx ON public.gw_collection_person USING btree (collection_id);
CREATE INDEX CONCURRENTLY gw_collection_person_image_person_id_idx ON public.gw_collection_person_image USING btree (person_id);
CREATE INDEX CONCURRENTLY gw_folder_company_id_idx ON public.gw_folder USING btree (company_id) WHERE (NOT is_archive);
CREATE INDEX CONCURRENTLY gw_folder_event_session_id_idx ON public.gw_folder USING btree (((meta_data ->> 'event_session_id'::text))) WHERE (NOT is_archive);
CREATE INDEX CONCURRENTLY gw_folder_resolution_author_id_idx ON public.gw_folder USING btree (resolution_author_id);
CREATE INDEX CONCURRENTLY gw_folder_resolution_comment_fts_idx ON public.gw_folder USING gin (to_tsvector('english'::regconfig, (resolution_comment)::text));
CREATE INDEX CONCURRENTLY gw_folder_time_created_folder_id_idx ON public.gw_folder USING btree (time_created DESC, folder_id DESC);
CREATE INDEX CONCURRENTLY gw_folder_time_created_folder_id_nonarchive_idx ON public.gw_folder USING btree (time_created DESC, folder_id DESC) WHERE (is_archive = false);
CREATE INDEX CONCURRENTLY gw_folder_time_created_idx ON public.gw_folder USING btree (time_created DESC);
CREATE INDEX CONCURRENTLY gw_folder_time_created_nonarchive_idx ON public.gw_folder USING btree (time_created DESC) WHERE (is_archive = false);
CREATE INDEX CONCURRENTLY gw_folder_user_id_idx ON public.gw_folder USING btree (user_id);
CREATE INDEX CONCURRENTLY idx_gw_folder_transaction_id ON public.gw_folder USING btree (company_id, ((meta_data ->> 'transaction_id'::text))) WHERE (NOT is_archive);
CREATE INDEX CONCURRENTLY idx_gw_folder_user_id_time_created ON public.gw_folder USING btree (user_id, time_created);
CREATE INDEX CONCURRENTLY gw_folder_image_folder_id_idx ON public.gw_folder_image USING btree (folder_id);
CREATE INDEX CONCURRENTLY gw_folder_report_author_id_idx ON public.gw_folder_report USING btree (author_id);
CREATE INDEX CONCURRENTLY gw_folder_report_folder_id_idx ON public.gw_folder_report USING btree (folder_id);
CREATE INDEX CONCURRENTLY gw_folder_report_report_template_id_idx ON public.gw_folder_report USING btree (report_template_id);
CREATE INDEX CONCURRENTLY idx_gw_folder_shots_set_folder_id ON public.gw_folder_shots_set USING btree (folder_id);
CREATE INDEX CONCURRENTLY gw_folder_video_folder_id_idx ON public.gw_folder_video USING btree (folder_id);
CREATE INDEX CONCURRENTLY gw_logging_event_record_session_id_idx ON public.gw_logging_event_record USING btree (session_id);
CREATE INDEX CONCURRENTLY gw_logging_event_record_time_created_idx ON public.gw_logging_event_record USING btree (time_created);
CREATE INDEX CONCURRENTLY gw_logging_event_record_timemark_idx ON public.gw_logging_event_record USING btree (timemark);
CREATE INDEX CONCURRENTLY gw_logging_event_session_time_created_idx ON public.gw_logging_event_session USING btree (time_created);
CREATE INDEX CONCURRENTLY gw_logging_event_session_user_id_idx ON public.gw_logging_event_session USING btree (user_id);
CREATE INDEX CONCURRENTLY gw_logging_event_session_time_updated_idx ON gw_logging_event_session(time_updated);
CREATE INDEX CONCURRENTLY gw_report_template_company_id_idx ON public.gw_report_template USING btree (company_id);
CREATE INDEX CONCURRENTLY gw_report_template_name_company_id_idx ON public.gw_report_template USING btree (name, company_id);
CREATE INDEX CONCURRENTLY gw_report_template_attachment_filename_report_template_id_idx ON public.gw_report_template_attachment USING btree (filename, report_template_id);
CREATE INDEX CONCURRENTLY gw_report_template_attachment_report_template_id_idx ON public.gw_report_template_attachment USING btree (report_template_id);
CREATE INDEX CONCURRENTLY gw_role_abstract_user_company_id_idx ON public.gw_role_abstract_user USING btree (company_id);
CREATE INDEX CONCURRENTLY gw_role_email_restore_code_user_id_idx ON public.gw_role_email_restore_code USING btree (user_id);
CREATE INDEX CONCURRENTLY gw_role_session_old_access_token_idx ON public.gw_role_session USING btree (old_access_token);
CREATE INDEX CONCURRENTLY gw_role_session_user_id_idx ON public.gw_role_session USING btree (user_id);
CREATE INDEX CONCURRENTLY gw_role_user_photo_user_id_idx ON public.gw_role_user_photo USING btree (user_id);
CREATE INDEX CONCURRENTLY gw_shots_set_frame_shots_set_id_idx ON public.gw_shots_set_frame USING btree (shots_set_id);
CREATE INDEX CONCURRENTLY gw_utils_audit_actor_id_idx ON public.gw_utils_audit USING btree (actor_id);
CREATE INDEX CONCURRENTLY gw_utils_media_company_id_idx ON public.gw_utils_media USING btree (company_id);

Chart Deployment

API and Web SDK charts require RWX SC (CephFS, EFS, NFS, Longhorn, etc.).

Example of creating SC using AWS EFS
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: efs-sc-api
provisioner: efs.csi.aws.com
allowVolumeExpansion: true
#Use Retain if you are going to use PVC for static, or your static will be deleted on chart uninstall
reclaimPolicy: Retain 
mountOptions:
  - tls
  - iam
parameters:
  provisioningMode: efs-ap
  fileSystemId: fs-____________
  directoryPerms: "770"
  uid: "1000"
  gid: "1000"
  basePath: ""

To deploy in Kubernetes, download the chart version you require and adjust the values.yaml file. This file specifies parameters for deployment of Oz products.

API

This example is based on the 0.11.28 chart version.

Adjust the values.yaml file, setting the following mandatory parameters before deployment:

  • ozDockerHubCreds: you'll receive them from Oz Engineer.

  • UserParams:

    • URLs:

      • use_chart_postgres: false by default. Enables internal PostgreSQL server (not recommended for production).

      • postgresUser: same as <<USERNAME>>.

      • postgresHost: the hostname of your PostgreSQL server.

      • postgresDB: same as <<DB_NAME>>.

      • postgresUserPassword: same as <<PASSWORD>>.

      • postgresPort: 5432 by default.

      • o2nDB:

        • use_chart_o2nDB: false by default. Enables internal PostgreSQL server (not recommended for production).

        • startinit: true by default. Enables database init scripts. Set to false after chart is deployed.

        • creds:

          • postgresHost: the hostname of your PostgreSQL server with O2N database.

          • postgresPort: 5432 by default.

          • postgresDB: same as <<O2N_DB_NAME>>.

          • postgresUser: same as <<O2N_USERNAME>>.

          • postgresUserPassword: Same as <<O2N_PASSWORD>>.

    • Creds:

      • apiAdminLogin: login for new (default) user for API. Will be created on the first run.

      • apiAdminPass: password for the default user.

      • webUILocalAdminLogin: local Admin for Web UI. Should differ from apiAdminLogin.

      • webUILocalAdminPass: password for webUILocalAdminLogin.

    • BIO:

      • licenseKey: you'll receive it from Oz Engineer / Sales.

      • clientToken: you'll receive it from Oz Engineer.

    • pvc:

      • api:

        • static:

          • storageClassName: RWX StorageClass.

          • size: Expected size for PV.

  • Params:

    • Global:

      • startinits: false by default. Set to true on the first run, then, after successful deployment, change back to false.

To adjust API behavior, you might want to change other parameters. Please refer to comments in the values.yaml file.

TFSS (BIO)

BIO is a part of the API chart. The BIO pods require separate nodes for each pod. To ensure BIO resides on dedicated nodes, you can use affinity and tolerations.

The BIO behavior can be customized via Params -> global -> affinity in values.yaml.

The default parameters are listed below:

# We recommend using separate nodes for API and BIO pods,
# and separate node for each BIO pod.
 ## Default affinity is:
 ## Try to start API pods on nodes with "oz:api" label, BIO pods on nodes with "oz:bio" label
affinity: 
  API:
  # You may add additional keys, or comment the whole section to disable affinity
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: oz
            operator: In
            values:
            - api
    # nodeName: "myNode" #Node name can be changed. Uncomment to use

    # nodeSelector: ##NodeSelector can be changed. Uncomment to use
    #   oz: api

    # fill tolerations according to node taints, uncomment to use
    #tolerations:
    #- key: nodegroup
    #  operator: Equal
    #  value: api
    #  effect: NoSchedule

  BIO:
  # You may add additional keys, or comment the whole section to disable affinity
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: oz
            operator: In
            values:
            - bio

    # nodeName: "myNode" ## Node name can be changed. Uncomment to use.

    # nodeSelector: ## NodeSelector can be changed. Uncomment to use.
    #   oz: bio

    # fill tolerations according to node taints, uncomment to use.
    #tolerations:
    #- key: nodegroup
    #  operator: Equal
    #  value: bio
    #  effect: NoSchedule

The example of chart deployment via Helm:

helm install oz-api https://chartmuseum.infra.ozforensics.ai/charts/oz-k8s-0.11.28.tgz --namespace oz-api --values custom-api-values.yaml

Web SDK

Installation of Web SDK requires API pre-installed. Except specific cases, Web SDK cannot work without API.

This example is based on the 1.5.1+onPremise chart version.

Adjust the values.yaml file, setting the following mandatory parameters before deployment:

  • ozDockerHubCreds: you'll receive them from Oz Engineer.

  • UserParams:

    • URLs:

      • apiURL: API URL. Can be an internal API URL.

      • webSDKURL: WebSDK url that will be used for public access.

    • Creds:

      • AdminLogin: login of the user that should be pre-created in API. Do not use the default admin login.

      • AdminPass: password of the pre-created user.

  • PVC:

    • persistentStorage: false be default. Set to true if you use more than 1 Web SDK pod.

    • storageClassName: RWX StorageClass.

  • Params:

    • websdk:

      • license: should contain your Web SDK license. You'll receive it from Oz Engineer / Sales.

# Format:
# Remark: Indentations are critical for yaml.
    license: |-
      {
          "payload_b64": "",
          "signature": "",
          "enc_public_key": ""
      }

To adjust API behavior, you might want to change other parameters. Please refer to comments in the values.yaml file.

The example of chart deployment via Helm:

helm install oz-websdk https://chartmuseum.infra.ozforensics.ai/charts/oz-k8s-sdk-1.5.1+onPremise.tgz --namespace oz-websdk --values custom-websdk-values.yaml

apiURL: URL for API. May be internal, if you use Web SDK only. For Mobile SDKs, should be public. Please refer to for more information.

DB: must be set, if you use an external PostgreSQL server. For details, please check .

For proper deployment, Web SDK requires an API service account. Pre-create a user for Web SDK with the CLIENT type and is_service flag set. Please refer to for more details.

Helm chart
Helm chart
this article
User Roles
Database Creation