Skip to main content

Deploying Container Observability shared services

Container Observability (CO) deployment installs a set of northbound UI and analytics services together with southbound data collectors to give you end‑to‑end visibility into Kubernetes clusters and containerized workloads. Using Helm‑based charts, you deploy shared services such as Kafka, VictoriaMetrics, and metrics APIs, then layer on the CO frontend, backend, and south components that collect metrics, logs, traces, and events from your clusters. This architecture separates control‑plane functions from data‑plane collection so you can scale ingest independently, connect to cloud and on‑prem Kubernetes environments, and provide SREs and platform teams with a unified, topology‑aware view of application health and performance across hybrid infrastructure.

Prerequisites

Before you begin the installation, ensure that your environment meets the following basic requirements:

  • You have Helm installed and configured to access your Kubernetes cluster.

  • You have added the Virtana Helm repository to your Helm configuration.

  • You know the storage class names to use for Kafka and VictoriaMetrics.

  • You have Docker registry credentials if you need to pull images from a private registry.

Create the Shared Services values file

Create a new file named app-mon-shared-services-values.yaml in your terminal or default editor. This file defines the configuration for:

  • Global deployment parameters

  • Shared Kafka (oc-shared-kafka)

  • Metrics service (cp-metrics-service)

  • VictoriaMetrics cluster (victoria-metrics-cluster)

Update the placeholder values according to your environment.

Note

The deployment tag for Container Observability shared services changed from tags.oc_shared_services to tags.platform.

Use --set tags.platform=true (with --skip-crds) in place of --set tags.oc_shared_services=true in the following deploy commands. Update any deployment that still uses the previous tag.

Deployment-wide settings

The global section sets values that apply across all shared-services components.

global:
  environment: "app"
  machine_type: "small" 
  secret_source: "valuesfile" 
  dockerRegistryCredentials: 
    DOCKER_SERVER: "https://index.docker.io/v2/"
    DOCKER_USERNAME: "username"
    DOCKER_PASSWORD: "password"

The following table describes each field of above YAML file:

Table 38.

Field

Description

Default value

global.environment

Set this to identify the deployment environment, for example "app", "dev", or "prod".

"app"

global.machine_type

Controls resource sizing presets. Supported values: "small", "medium", "large".

"small"

global.secret_source

Docker credentials are provided directly in values file.

"valuesfile"

global.dockerRegistryCredentials

Credentials to pull container images from a Docker registry.

-

DOCKER_SERVER

Registry URL.

"https://index.docker.io/v2/"

DOCKER_USERNAME

Registry username.

"username"

DOCKER_PASSWORD

Registry password.

"password"



Shared Kafka parameters

This section configures the shared Kafka controller, including persistence, resource sizing, JVM heap, topic provisioning, and Kafka server properties.

oc-shared-kafka:
  controller:
    persistence:
      storageClass: ""
      size: 100Gi
    resources:
      requests:
        cpu: 500m
        memory: 1536Mi
      limits:
        cpu: 1
        memory: 1536Mi
    heapOpts: -Xmx1g -Xms512m
    provisioning:
      enabled: true
      topics:
      - name: ops_ingester_tsdb
        partitions: 40
    extraConfig: |
      num.partitions=40
      default.replication.factor=1
      log.retention.hours=1
      log.segment.bytes=1073741824
      message.max.bytes=20981520
      socket.send.buffer.bytes=102400
      socket.receive.buffer.bytes=102400
      socket.request.max.bytes=104857600
      offsets.topic.replication.factor=1
      transaction.state.log.min.isr=1
      transaction.state.log.replication.factor=1
    nodeSelector: {}
    tolerations: []

The following table describes each field of above YAML file:

Table 39.

Field

Description

Default value

oc-shared-kafka.controller.persistence.storageClass

Chooses the Kubernetes StorageClass for Kafka persistent volumes.

" "

oc-shared-kafka.controller.persistence.size

Sets the size of the Kafka persistent volume claim (PVC).

100 Gib

oc-shared-kafka.controller.resources.requests.cpu

Minimum CPU reserved for the Kafka container (in millicores).

500 m

oc-shared-kafka.controller.resources.requests.memory

Minimum memory reserved for Kafka.

1536 Mi

oc-shared-kafka.controller.resources.limits.cpu

The maximum CPU Kafka can consume.

1

oc-shared-kafka.controller.resources.limits.memory

The maximum memory Kafka can consume.

1536 Mi

oc-shared-kafka.controller.heapOpts

Sets Kafka JVM heap options where

-Xmx is the maximum heap size, and -Xms is the initial heap size.

-Xmx1g -Xms512m

oc-shared-kafka.controller.provisioning.enabled

Enables/disables auto-creation/provisioning of Kafka topics during deployment.

true/false

oc-shared-kafka.controller.provisioning.topics

Defines topics to create.

Each entry includes:

  • name: Topic name (example: ops_ingester_tsdb).

  • partitions: Number of partitions (example: 40).

oc-shared-kafka.controller.extraConfig

Injects Kafka controller configuration properties.

-

oc-shared-kafka.controller.nodeSelector

Constrains Kafka pods to nodes with matching labels.

{ }

oc-shared-kafka.controller.tolerations

Allows Kafka pods to schedule onto tainted nodes.

[ ]



Metrics service parameters

This section configures the metrics service behavior (Kafka listener concurrency) and auto-scaling. It also defines a shared nodeSelector anchor you can reuse.

cp-metrics-service:
  global:
    nodeSelector: &nodeSelector {}
  env:
    KAFKA_LISTENER_CONCURRENCY: "2"
  horizontalPodAutoscaler:
    enabled: true
    maxReplicas: 5
    minReplicas: 2

The following table describes each field of above YAML file:

Table 40.

Field

Decription

Default value

cp-metrics-service.global.nodeSelector

Node selection rules for the metrics service.

&nodeSelector { }

cp-metrics-service.env.KAFKA_LISTENER_CONCURRENCY

Controls how many concurrent Kafka listener threads the service uses.

"2"

cp-metrics-service.horizontalPodAutoscaler.enabled

Enables/disables Horizontal Pod Auto-scaling (HPA) for the metrics service.

true/false

cp-metrics-service.horizontalPodAutoscaler.minReplicas

Minimum number of replicas when auto-scaling is enabled.

5

cp-metrics-service.horizontalPodAutoscaler.maxReplicas

Maximum number of replicas when auto-scaling is enabled.

2



VictoriaMetrics cluster parameters

This section configures VictoriaMetrics cluster following components:

  • vmstorage for durable time-series storage

  • vminsert for ingest/write path

  • vmselect for query/read path

Each component supports scheduling controls and autoscaling where applicable.

victoria-metrics-cluster:
  vmstorage:
    replicaCount: 4
    retentionPeriod: 1
    persistentVolume:
      storageClassName: ""
      size: 100Gi
    resources:
      limits:
        cpu: 500m
        memory: 1Gi
      requests:
        cpu: 500m
        memory: 1Gi
    nodeSelector: {}
    tolerations: []
  vmselect:
    horizontalPodAutoscaler:
      minReplicas: 2
      maxReplicas: 10
    nodeSelector: {}
    tolerations: []
  vminsert:
    horizontalPodAutoscaler:
      minReplicas: 2
      maxReplicas: 10
    nodeSelector: {}
    tolerations: []

The following table describes each field of above YAML file:

Table 41.

Field

Description

Default value

victoria-metrics-cluster.vmstorage.replicaCount

Number of vmstorage replicas.

4

victoria-metrics-cluster.vmstorage.retentionPeriod

Data retention window.

Supported values 1w, 1d, number without measurement means month, for example 2 = 2month

victoria-metrics-cluster.vmstorage.persistentVolume.storageClassName

StorageClass for VictoriaMetrics PVCs.

" "

victoria-metrics-cluster.vmstorage.persistentVolume.size

PVC size per vmstorage replica.

100 Gib

victoria-metrics-cluster.vmstorage.resources.requests.* / limits.*

Requests reserve capacity and limits cap usage. Ensure resources match expected ingest and query load. Storage nodes often need stable CPU and memory.

-

victoria-metrics-cluster.vmstorage.nodeSelector and tolerations

Controls which nodes vmstorage can run on.

-

victoria-metrics-cluster.vmselect.horizontalPodAutoscaler.minReplicas

Minimum vmselect replicas.

2

victoria-metrics-cluster.vmselect.horizontalPodAutoscaler.maxReplicas

Maximum vmselect replicas.

10

victoria-metrics-cluster.vminsert.horizontalPodAutoscaler.minReplicas

Minimum vminsert replicas.

2

victoria-metrics-cluster.vminsert.horizontalPodAutoscaler.maxReplicas

Maximum vminsert replicas.

10



Deploy shared services

You deploy shared services using the virtana-co-controller chart and the values file you created.

Check the latest chart version

Update the Helm repository in your terminal and list available versions of the controller chart:

helm repo update
helm search repo virtana-repo/virtana-co-controller

This installs shared services into the oc-shared-services namespace and enables the shared-services tag.

helm upgrade --install opscruise-shared-services virtana-repo/virtana-co-controller \
  --namespace oc-shared-services --create-namespace \
  --set tags.oc_shared_services=true -f app-mon-shared-services-values.yaml \
  --version <LATEST_VERSION>

This method deploys the same Helm chart via Argo CD GitOps and keeps it continuously reconciled.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: opscruise-shared-services
  namespace: argocd
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  destination:
    server: https://kubernetes.default.svc
    namespace: oc-shared-services
  source:
    chart: virtana-co-controller
    repoURL: https://virtana.gitlab.io/helm-charts
    targetRevision: <LATEST_VERSION> # Provide latest version
    helm:
      releaseName: opscruise-shared-services
      parameters:
        - name: "tags.oc_shared_services"
          value: "true"
      values: |
        <contents of app-mon-shared-services-values.yaml>
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true
Table 42.

Field

Description

Default value

metadata.name

Argo CD application name.

opscruise-shared-services

spec.destination.server

Target cluster API server.

https://kubernetes.default.svc

spec.destination.namespace

Target namespace.

oc-shared-services

spec.source.chart / repoURL / targetRevision

Chart coordinates and version.

spec.source.helm.releaseName

Helm release name Argo CD will manage.

spec.source.helm.parameters

sets:

- name: "tags.oc_shared_services"

value: "true"

spec.source.helm.values

Inline values.

Paste the full contents of app-mon-shared-services-values.yaml

syncPolicy.automated.prune

Removes resources not in the desired state.

true

syncPolicy.automated.selfHeal

Re-applies drifted resources automatically.

true

syncOptions.CreateNamespace=true

Creates namespace if missing.



This method installs the chart using Terraform’s Helm provider and allows you to inject credentials via variables.

resource "helm_release" "opscruise_shared_services" {
  name             = "opscruise-shared-services"
  create_namespace = true
  namespace        = "oc-shared-services"
  chart            = "virtana-co-controller"
  repository       = "https://virtana.gitlab.io/helm-charts"
  version          = var.helm_version
  timeout          = 600
  wait             = true

  values = [
    templatefile("${path.module}/../values/app-mon-shared-services-values.yaml", {
      docker_password = var.docker_password
      docker_username = var.docker_username
    })
  ]

  set {
    name  = "tags.oc_shared_services"
    value = "true"
  }
}
Table 43.

Field

Description

name = "opscruise-shared-services"

Helm release name.

create_namespace = true

Boolean flag to create the target namespace.

namespace = "oc-shared-services"

Kubernetes namespace where the release will be installed.

chart = "virtana-co-controller"

Helm chart name.

repository = "https://virtana.gitlab.io/helm-charts"

Helm chart repository URL.

version = var.helm_version

Chart version to deploy.

timeout = 600

Deployment timeout in seconds.

wait = true

Wait behavior flag.

values = [templatefile(...)]

Renders a values YAML from a template.

set { name = "tags.oc_shared_services" ... }

enables shared services tag



Shared service deployment optional settings

Use these optional settings when your environment requires a private image registry or when you deploy shared services on Red Hat OpenShift with namespace-specific security constraints.

Use a private image registry (optional)

You can add this as an optional setting in your terminal if your cluster cannot pull images from the default public registry locations.

Add the following command to app-mon-shared-services-values.yaml and replace the example.io with your registry:

cp-metrics-service:
  image:
    registry: example.io

oc-shared-kafka:
  image:
    registry: example.io
    repository: kafka

victoria-metrics-cluster:
  vminsert:
    image:
      repository: example.io/vminsert
  vmselect:
    image:
      repository: example.io/vmselect
  vmstorage:
    image:
      repository: example.io/vmstorage
Table 44.

Field

Description

Default value

cp-metrics-service.image.registry

Sets the container image registry host for the cp-metrics-service image.

example.io

oc-shared-kafka.image.registry

Defines the registry host from which the Kafka image is pulled.

example.io

oc-shared-kafka.image.repository

Defines the image repository within the registry.

kafka

victoria-metrics-cluster.vminsert.image.repository

Sets the full image repository path for the vminsert component.

example.io/vminsert

victoria-metrics-cluster.vmselect.image.repository

Sets the full repository path for the vmselect image.

example.io/vmselect

victoria-metrics-cluster.vmstorage.image.repository

Sets the full repository path for the vmstorage image.

example.io/vmstorage



Deploy shared services on OpenShift

On Red Hat OpenShift, set the security contexts for the shared-services components so that they run within the UID, GID, and fsGroup range that OpenShift allows for the namespace. Create a file named app-mon-shared-services-scc.yaml with the security contexts, and add it to the Helm deploy command.

First, find the allowed UID, GID, and supplemental-group range for the namespace:

oc describe ns oc-shared-services | egrep "uid-range|supplemental-groups"

The runAsUser, runAsGroup, and fsGroup values you set must fall within the range that this command reports. Set the security contexts in app-mon-shared-services-scc.yaml:

cassandra-shared:
  securityContext:
    pod:
      runAsUser: <user_id>
      runAsGroup: <group_id>
      fsGroup: <fsgroup_id>

platform-kafka-service:
  podSecurityContext:
    fsGroup: <fsgroup_id>
  securityContext:
    runAsUser: <user_id>
    runAsGroup: <group_id>
  strimzi-kafka-operator:
    podSecurityContext:
      fsGroup: <fsgroup_id>
    securityContext:
      runAsGroup: <group_id>
      runAsUser: <user_id>

co-config-events-service-shared:
    podSecurityContext:
      fsGroup: <fsgroup_id>
    securityContext:
      runAsGroup: <group_id>
      runAsUser: <user_id>
    zookeeper:
      podSecurityContext:
        fsGroup: <fsgroup_id>
      securityContext:
        runAsGroup: <group_id>
        runAsUser: <user_id>

The Helm chart overrides assign a Kubernetes security context to each platform service and its sub-components. The same set of parameters recurs across the services, applied at either the pod level or the container level. The following table describes each parameter, the level at which it applies, and the value it takes.

Table 45.

Parameter

Description

podSecurityContext

Defines the security settings that apply to every container in the pod. These settings also govern the group ownership of mounted volumes, so pod-level fields such as fsGroup belong here.

securityContext

Defines the security settings for a single container. When a chart lists securityContext alongside a separate podSecurityContext, the values set here apply only to the container and override the equivalent pod-level settings.

securityContext.pod

Applies the security settings at the pod level through the pod sub-key. The cassandra-shared chart uses this nesting to express the same intent as podSecurityContext in the other charts.

runAsUser

Sets the numeric user ID (UID) that the container process runs as. This value overrides any user defined in the container image and is the primary control for running a service as a non-root user.

runAsGroup

Sets the numeric primary group ID (GID) for the container process. Files that the process creates are owned by this group.

fsGroup

Sets a supplemental group ID that Kubernetes applies to the pod's mounted volumes. Kubernetes changes the group ownership of the files in these volumes to this GID and adds the GID to each container's supplementary groups, so the process can read and write persistent data. This field is valid only at the pod level.



Note

Replace the placeholders <user_id>, <group_id>, and <fsgroup_id> with concrete integers before you deploy. In most deployments, you set the same non-root values across all services to keep permissions consistent on shared persistent volumes.

Note

Add the -f app-mon-shared-services-scc.yaml \ flag to the Helm deploy commands for OpenShift-based deployments.