Skip to main content

Deploying Container Observability frontend and backend

The frontend and backend components work together to provide visibility into your Kubernetes clusters within the Virtana Platform.

You can use the virtana-co-controller Helm chart for this deployment. The process involves gathering your tenant information, configuring shared settings, and selecting a deployment method such as the Helm CLI, Argo CD, or Terraform.

Get your organization ID and create a DNS record

Before you can define the dataplane frontend DNS name, you need your tenant's organization ID ORG_ID. You'll find it in the keycloakorgsecret secret in the controlplane namespace.

Run the following command to retrieve it:

echo $(kubectl get secret keycloakorgsecret -o jsonpath='{.data.ORG_ID}' -n controlplane | base64 --decode)

The command reads the ORG_ID from the Kubernetes secret keycloakorgsecret in namespace controlplane. Base64-decodes it to output the plain-text value of the ORG_ID.

Using that value, create a DNS record in the following format and point it to your ingress-nginx controller's LoadBalancer DNS name or IP address:

<ORG_ID>-oc-<GLOBAL_VIEW_HOSTNAME>

This gives the CO frontend a hostname derived from your organization ID and Global View hostname, making it reachable through your ingress.

Frontend namespace configuration

Configure the FRONTEND_NAMESPACE variable for each backend deployment. This variable identifies the Kubernetes namespace that contains the CO frontend components.

global:
  frontend:
    FRONTEND_NAMESPACE: ""

Set this value to the Kubernetes namespace that contains the CO frontend components.

Application monitoring common input file

Create a new file <ORG_ID>-common-values.yaml. This file contains values shared by Frontend and Backend deployments, such as deployment mode, storage class, TLS behavior, registry credentials, frontend settings, Keycloak settings, control plane endpoints, and shared services endpoints.

Global shared deployment configuration

These parameters are used by multiple components, such as frontend, backend, auth, control plane, and shared services.

global:
  DEPLOYMENT_MODE: VP_ONPREM
  machine_type: small 
  secret_source: valuesfile 
  storageClass: "" 
Table 43.

Field

Description

Default value

global.DEPLOYMENT_MODE

Indicates the overall deployment mode.

VP_ONPREM

global.machine_type

Chooses a sizing preset used by the chart.

small, medium, and large

global.secret_source

You provide credentials/secrets in the values file.

You can also provide secrets externally if you enter none as your secret_source.

valuesfile

global.storageClass

StorageClass used by components that rely on a global storage class.

" "



Self-signed TLS toggles and Docker credentials

Enter the following command to generate self-signed certs when you don’t have valid certs provided by your ingress/LB. Docker registry credentials are used to pull images. It is typically needed for private registries or authenticated Docker Hub access.

create_tls_selfsigned_certs:
    kafka: "true"
    nodeapp: "true"
dockerRegistryCredentials: 
    DOCKER_SERVER: "https://index.docker.io/v2/"
    DOCKER_USERNAME: "username"
    DOCKER_PASSWORD: "password"
Table 44.

Field

Description

Default value

global.create_tls_selfsigned_certs.kafka

Enables or disables self-signed TLS cert creation for Kafka endpoints.

"true" or "false"

global.create_tls_selfsigned_certs.nodeapp

Enables or disables self-signed TLS cert creation for Nodeapp endpoints.

"true" or "false"

DOCKER_SERVER

URL of the Docker registry server.

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

DOCKER_USERNAME

Username for authenticating to the Docker registry.

"username"

DOCKER_PASSWORD

Password or access token used with DOCKER_USERNAME to authenticate.

"password"



Container Observability Dataplane Frontend parameters

Configuration specific to the CO Dataplane Frontend to define how it is addressed and how it integrates with Global View.

frontend:
    FRONTEND_DNS: <DATAPLANE_FRONTEND_HOSTNAME> 
    TENANT_NAME: <ORG_ID> 
    IFRAME: "true"
    UI_PARENT_APP_URL: "https://<GLOBAL_VIEW_HOSTNAME>/ui/container/monitoring" 
Table 45.

Field

Description

Default value

FRONTEND_DNS

DNS name where the CO Frontend will be reachable.

<DATAPLANE_FRONTEND_HOSTNAME>

TENANT_NAME

Tenant identifier, set this to your ORG_ID.

<ORG_ID>

IFRAME

Controls iframe-related behavior.

"true" or "false"

UI_PARENT_APP_URL

Parent UI URL used for navigation.

"https://&lt;GLOBAL_VIEW_HOSTNAME&gt;/ui/container/monitoring"



Auth provider and control plane endpoints parameters

Keycloak configuration is required for authentication and tenant mapping. Control plane parameters define the response action of the dataplane to the Global View control plane and its Kafka.

keycloak:
    HOSTNAME: <KEYCLOAK_HOSTNAME> 
    ADMIN_USER: "vpadmin"
    ADMIN_PASSWORD: "P@ssW0rd@123"

  controlplane:
    endpoint: "<GLOBAL_VIEW_HOSTNAME>" 
    kafka_server: "controlplane-infra-kafka.controlplane.svc.cluster.local:9092"
Table 46.

Field

Description

Default value

HOSTNAME

Keycloak hostname/FQDN.

<KEYCLOAK_HOSTNAME>

ADMIN_USER

Keycloak admin username.

"vpadmin"

ADMIN_PASSWORD

Keycloak admin password.

"P@ssW0rd@123"

endpoint

Global View hostname.

<GLOBAL_VIEW_HOSTNAME>

kafka_server

Kafka bootstrap server address for the control plane Kafka.

"controlplane-infra-kafka.controlplane.svc.cluster.local:9092"



Shared services, ingress, and TLS secret parameters

Connection details for the shared services deployed in the shared-services namespace. Enter the following commands to connect frontend and backend components to shared services and to enable the ingress controller integration and set TLS secret.

oc_shared_services:
    kafka_service: "oc-shared-kafka.oc-shared-services.svc.cluster.local:9092"
    tsdb_service_select_url: "http://vm-cluster-select.oc-shared-services.svc.cluster.local:8481"
    tsdb_cluster_mode: "true"

nodeapp:
  ingress_controller:
    enabled: true
  nginx_ingress:
    tlsSecretName: ops-tls-secret
Table 47.

Field

Description

Default value

kafka_service

Kafka service endpoint for CO shared Kafka.

"oc-shared-kafka.oc-shared-services.svc.cluster.local:9092"

tsdb_service_select_url

VictoriaMetrics select endpoint URL used for querying TSDB.

"http://vm-cluster-select.oc-shared-services.svc.cluster.local:8481"

tsdb_cluster_mode

Indicates TSDB is running in cluster mode.

"true"

nodeapp.ingress_controller.enabled

Enables or disables ingress-controller integration for Nodeapp.

true or false

nodeapp.nginx_ingress.tlsSecretName

TLS secret name to use for ingress TLS. It is not needed if valid certs are already configured in the IngressController or LoadBalancer.

ops-tls-secret



Deploy Frontend

You can deploy the components using your preferred tool. Regardless of the tool, you will deploy the Frontend once and a Backend for every cluster you wish to observe. The Frontend serves as the bridge between your monitored clusters and the Virtana Global View.

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

Use this method when you want to deploy the frontend by running Helm commands manually from the command line. You control the chart version, values file, and release lifecycle yourself, which is useful for ad‑hoc installs, troubleshooting, or simple environments without GitOps.

helm upgrade --install opscruise-frontend virtana-repo/virtana-co-controller \
  --namespace <first_8_chars_of_org_ID>-frontend --create-namespace \
  --set tags.frontend=true \
  -f <ORG_ID>-common-values.yaml \
  --version <LATEST_VERSION>
Table 48.

Field

Description

--namespace

Namespace uses the first 8 chars of ORG_ID followed by -frontend.

set tags.frontend=true

It enables only the frontend parts of the chart.



Use this approach to manage frontend deployment declaratively through GitOps with Argo CD Applications. Argo CD continuously reconciles the desired state from your Git repository, automatically handling upgrades, rollbacks, drift correction, and namespace creation for the frontend stack. Create a file named virtana-dp-frontend-argo.yaml and apply it to your Argo CD controller. Ensure you set the tags.frontend parameter to true.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: virtana-dp-frontend
  namespace: argocd
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  destination:
    server: https://kubernetes.default.svc
    namespace: <first_8_chars_of_org_ID>-frontend
  source:
    chart: virtana-co-controller
    repoURL: https://virtana.gitlab.io/helm-charts
    targetRevision: <LATEST_VERSION> 
    helm:
      releaseName: opscruise-frontend
      parameters:
        - name: "tags.frontend"
          value: "true"
      values: |
        <contents of ORG_ID-common-values.yaml>
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true
Table 49.

Field

Description

Default value

metadata.name

The name of the Argo CD Application object inside the argocd namespace.

virtana-dp-frontend

metadata.namespace

The Kubernetes namespace where the Argo CD Application CR itself is created.

argocd

metadata.finalizers

Ensures Argo CD deletes the resources it created when you delete this Argo CD Application.

resources-finalizer.argocd.argoproj.io

spec.destination.server

The target Kubernetes API server Argo CD should deploy to the same cluster where Argo CD is running.

https://kubernetes.default.svc

spec.destination.namespace

The target namespace where Helm resources will be installed. Copy the first 8 characters of the org ID you obtain.

<first_8_chars_of_org_ID>-frontend

spec.source.chart

The Helm chart name to install.

virtana-co-controller

spec.source.repoURL

The Helm repository URL hosting the chart.

https://virtana.gitlab.io/helm-charts

spec.source.targetRevision

The Helm chart version that Argo CD should install. Provide the latest version.

<LATEST_VERSION>

spec.source.helm.releaseName

The Helm release name Argo CD will use when installing the chart.

opscruise-frontend

spec.source.helm.parameters

Enables the frontend portion of the chart using Helm’s tags mechanism.

spec.source.helm.values

Inline Helm values YAML that Argo CD passes to Helm.

Paste the full content of that common input file <ORG_ID>-common-values.yaml.

spec.syncPolicy.prune

Prevents orphaned resources when chart outputs change.

true

spec.syncPolicy.selfHeal

For manual changes in a deployed resource in the cluster, Argo CD will revert it to the desired state from Helm.

true

spec.syncPolicy.syncOptions

If the destination namespace does not exist, Argo CD will create it automatically during sync.

- CreateNamespace=true



Use this option when you want to provision and manage the frontend as part of a broader, infrastructure‑as‑code workflow. Terraform drives the Helm release, enabling you to version, parameterize, and automate frontend deployments alongside other platform resources in a single, repeatable pipeline. Define a helm_release resource in your Terraform configuration (for example, virtana-dp-frontend.tf). Set the tags.frontend value to true.

resource "helm_release" "frontend" {
  create_namespace = true
  chart            = "virtana-co-controller"
  name             = "opscruise-frontend"
  namespace        = "${substr(var.org_id, 0, min(length(var.org_id), 8))}-frontend"
  repository       = "https://virtana.gitlab.io/helm-charts"
  version          = var.helm_version
  timeout          = 600
  wait             = true

  values = [
    templatefile("${path.module}/../values/ORG_ID-common-values.yaml", {
      deployment_mode       = "VP_ONPREM"
      storage_class         = var.storage_class
      docker_password       = var.docker_password
      docker_username       = var.docker_username
      frontend_dns          = "${var.org_id}-oc-${var.cp_endpoint}"
      tenant_name           = var.tenant_name
      ui_parent_app_url     = var.ui_parent_app_url
      keycloak_hostname     = var.keycloak_hostname
      keycloak_password     = var.keycloak_password
      keycloak_username     = var.keycloak_username
      global_view_hostname  = var.global_view_hostname
    })
  ]

  set {
    name  = "tags.frontend"
    value = "true"
  }
}
Table 50.

Field

Description

Default value

create_namespace

Instructs Terraform to create the target namespace if it does not already exist.

true

chart

The Helm chart name to deploy.

"virtana-co-controller"

name

Helm release name.

"opscruise-frontend"

namespace

The Kubernetes namespace where the frontend components will be deployed.

"${substr(var.org_id, 0, min(length(var.org_id), 8))}-frontend"

repository

URL of the Virtana Helm chart repository.

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

version

The chart version to install is equivalent to the Helm-based examples.

var.helm_version

timeout

Maximum time (in seconds) Terraform or Helm will wait for all resources to become ready

600

wait

Instructs Terraform/Helm to block until all resources are ready before finishing.

true

values = [ ... ]

List of values files/content passed to Helm.

set { name = "tags.frontend"; value = "true" }

Virtana’s charts gate component(s) deploy only frontend modules.



Cluster values files

Create a per-cluster values file <ORG_ID>-<CLUSTER_NAME>-values.yaml to define cluster-specific parameters.

Run the following command in your values file:

global:
  machine_type: small 
  frontend:
    CLUSTER_NAME: "<CLUSTER_NAME>"
Table 51.

Field

Description

Default value

global.machine_type

Sizing preset for this backend deployment. It supports small, medium, and large.

small

global.frontend.CLUSTER_NAME

Cluster name used for this backend.

"<CLUSTER_NAME>"



For OpenShift environments, add:

global:
  backend:
    BACKEND_PORT: "9093"
Table 52.

Field

Description

Default value

global.backend.BACKEND_PORT

Backend service port override.

"9093"



Deploy Backend

The Deploy Backend step installs a CO backend instance for each monitored Kubernetes cluster. Each backend is deployed into its own namespace using two values files: the shared <ORG_ID>-common-values.yaml for global settings and a per-cluster <ORG_ID>-<CLUSTER_NAME>-values.yaml for cluster-specific configuration, such as machine type and cluster name. The chart tag tags.backend=true ensures only backend components are available. You can deploy via Helm CLI, Argo CD, or Terraform, and repeat the process for each additional cluster by creating a new per-cluster values file and deploying another release into a new namespace.

Enter the following command to deploy a CO backend instance. This approach is well-suited for quick, ad-hoc deployments or environments where a full GitOps or IaC pipeline is not yet in place.

helm upgrade --install opscruise-backend virtana-repo/virtana-co-controller \
  --namespace <CLUSTER_NAME> --create-namespace \
  --set tags.backend=true \
  -f <ORG_ID>-common-values.yaml \
  -f <ORG_ID>-<CLUSTER_NAME>-values.yaml \
  --version <LATEST_VERSION>
  • Each backend is deployed into a namespace equal to <CLUSTER_NAME>.

  • You pass two values files, they are common and per-cluster.

  • tags.backend=true enables only backend components.

You can use this approach to manage each backend instance declaratively through an Argo CD Application custom resource. The manifest points to the virtana-co-controller Helm chart, sets tags.backend=true, and inlines the merged contents of both the common and per-cluster values files. Create a file named virtana-dp-CLUSTER_NAME-argo.yaml and apply it to your Argo CD controller. Ensure you set the tags.backend parameter to true.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: virtana-dp-CLUSTER_NAME
  namespace: argocd
  finalizers:
  - resources-finalizer.argocd.argoproj.io
spec:
  destination:
    server: "https://kubernetes.default.svc"
    namespace: <CLUSTER_NAME>
  source:
    chart: virtana-co-controller
    repoURL: "https://virtana.gitlab.io/helm-charts"
    targetRevision: <LATEST_VERSION> 
    helm:
      releaseName: opscruise-backend
      parameters:
        - name: "tags.backend"
          value: "true"
      values: |
        <contents of ORG_ID-common-values.yaml + ORG_ID-CLUSTER_NAME-values.yaml>
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
    - CreateNamespace=true
Table 53.

Field

Description

Default value

metadata.name

Unique name of the Argo CD Application.

virtana-dp-CLUSTER_NAME

metadata.namespace

Namespace where the Argo CD Application resource itself is created.

argocd

metadata.finalizers

Ensures that when this Argo CD Application is deleted, all Kubernetes resources it manages are also cleaned up.

resources-finalizer.argocd.argoproj.io

spec.destination.server

Target Kubernetes API server.

https://kubernetes.default.svc

spec.destination.namespace

Target namespace for the backend release.

<CLUSTER_NAME>

spec.source.chart

Name of the Helm chart to deploy from the repository.

virtana-co-controller

spec.source.repoURL

URL of the Helm chart repository hosting the virtana-co-controller chart.

https://virtana.gitlab.io/helm-charts

spec.source.targetRevision

Chart version to deploy. Replace with the latest version discovered through helm search repo virtana-repo/virtana-co-controller.

<LATEST_VERSION>

spec.source.helm.releaseName

Helm release name used for this deployment.

opscruise-backend

spec.source.helm.parameters

This enables only the backend components within the virtana-co-controller chart.

name: "tags.backend"

value: "true"

spec.source.helm.values

Inline Helm values (equivalent to -f on the CLI).

<contents of ORG_ID-common-values.yaml + ORG_ID-CLUSTER_NAME-values.yaml>

spec.syncPolicy.automated.prune

When true, Argo CD automatically deletes Kubernetes resources that are no longer defined in the Helm chart output

true

spec.syncPolicy.automated.selfHeal

When true, Argo CD automatically re-applies the desired state if someone manually modifies a managed resource in the cluster

true

spec.syncPolicy.syncOptions

Instructs Argo CD to create the target namespace if it does not already exist.

CreateNamespace=true



You can use this option to provision and manage each CO backend instance as part of a broader infrastructure-as-code workflow using Terraform's helm_release resource. Terraform renders two values files via templatefile, the shared ORG_ID-common-values.yaml for global settings and a per-cluster ORG_ID-CLUSTER_NAME-values.yaml for cluster-specific parameters like machine type and cluster name, and merges them in order before passing them to Helm.

Define a helm_release resource in your Terraform configuration (for example, virtana-dp-backend.tf). Set the tags.backend value to true.

resource "helm_release" "backend" {
  create_namespace = true
  chart            = "virtana-co-controller"
  name             = "opscruise-backend"
  namespace        = var.cluster_name
  repository       = "https://virtana.gitlab.io/helm-charts"
  version          = var.helm_version
  timeout          = 1200
  wait             = true

  values = [
    templatefile("${path.module}/../values/ORG_ID-common-values.yaml", {
      deployment_mode       = "VP_ONPREM"
      storage_class         = var.storage_class
      docker_password       = var.docker_password
      docker_username       = var.docker_username
      frontend_dns          = "${var.org_id}-oc-${var.cp_endpoint}"
      tenant_name           = var.tenant_name
      ui_parent_app_url     = var.ui_parent_app_url
      keycloak_hostname     = var.keycloak_hostname
      keycloak_password     = var.keycloak_password
      keycloak_username     = var.keycloak_username
      global_view_hostname  = var.global_view_hostname
    }),
    templatefile("${path.module}/../values/ORG_ID-CLUSTER_NAME-values.yaml", {
      machine_type = var.machine_type
      cluster_name = var.cluster_name
    })
  ]

  set {
    name  = "tags.backend"
    value = "true"
  }
}
Table 54.

Field

Description

Default value

create_namespace

Creates the target namespace automatically if it does not already exist.

true

chart

Name of the Helm chart to install from the specified repository.

"virtana-co-controller"

name

Helm release name.

"opscruise-backend"

namespace

Target Kubernetes namespace for the backend release.

var.cluster_name

repository

URL of the Helm chart repository hosting the virtana-co-controller chart.

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

version

Chart version to deploy, controlled by the Terraform variable helm_version.

var.helm_version

timeout

Maximum time in seconds Terraform will wait for the release to complete before failing.

1200

wait

When true, Terraform waits for all Kubernetes resources in the release to reach a healthy state before marking the deployment as successful.

true

values = [...]

The values list passes two available YAML strings to the Helm chart. The common values and the per-cluster values which are merged in order.

set { name = "tags.backend" value = "true" }

This enables only the backend components within the virtana-co-controller chart, ensuring frontend or shared-services resources are not rendered by this release.



Deploy additional backends

To add more clusters, repeat the following steps:

  1. Create another <ORG_ID>-<CLUSTER_NAME>-values.yaml. For more details, see Cluster values files.

  2. Deploy another backend release targeting the new <CLUSTER_NAME> namespace. For more details, see Deploy Backend.

Deployment verification

To ensure Container Observability is accessible, perform the following steps:

  1. Open the following URL in a web browser: https://<GLOBAL_VIEW_HOSTNAME>/ui.

  2. Log in using your org email and password.

  3. Navigate to Container Observability > CLUSTER.

Optional settings

The following optional configurations allow you to customize your CO Frontend and Backend deployment beyond the default settings. These include sending telemetry data to Virtana Analytics, using a private image registry, enabling high availability for Nodeapp and CCMongoDB, setting node selectors and tolerations for pod scheduling, and configuring Kafka external service types. Apply any of these settings by adding the relevant configuration block to your <ORG_ID>-common-values.yaml file before deploying or upgrading.

Send data to Virtana Analytics (Matomo)

You can enable a web analytics tool to track and analyze website traffic and behavior.

Perform the following steps:

  1. Enable Virtana Analytics in GlobalView. See Deploying Global View on Virtana Platform.

  2. Add the following configuration to <ORG_ID>-common-values.yaml file.

    global:
      matomo:
        url: "https://virtana-analytics.<domain.com>"
        site_id: "1"

Use a private image registry

Enter the following command to <ORG_ID>-common-values.yaml to use the private image registry.

global:
  image_registry: example.io

Enable HA for Nodeapp and CCMongoDB

Enabling High Availability (HA) for Nodeapp and CCMongoDB is essential in dynamic Kubernetes environments where nodes can frequently restart or undergo maintenance. Without HA, both Nodeapp and CCMongoDB run as single instances, creating a single point of failure. By enabling HA, multiple replicas of Nodeapp and a MongoDB replica set for CCMongoDB are deployed across different nodes. This results in uninterrupted access to the monitoring UI, improved fault tolerance, and a more resilient production deployment overall.

For existing Nodeapp and CCMongoDB

Perform the following steps:

  1. Download the Backup and Restore script.

    curl -o mongodb_dump_restore.sh https://oc-tesla.s3.amazonaws.com/Build/mongodb_dump_restore.sh
  2. Run the backup command.

    bash mongodb_dump_restore.sh backup <NAMESPACE>
  3. Deploy CCMongoDB and Nodeapp in HA by adding the following command to <ORG_ID>-common-values.yaml.

    For the new Nodeapp and CCMongoDB deployment, you can enable HA directly with this command.

    global:
      frontend:
        ha_enabled: true
  4. Run the restore command.

    bash mongodb_dump_restore.sh restore <NAMESPACE>

Set NodeSelector and Toleration

In Kubernetes, pods are scheduled on any available node by default, which may not always be desirable in production environments where you need to control workload placement for performance, compliance, or resource isolation reasons. NodeSelector allows you to constrain pods to run only on nodes that match specific labels. Tolerations work alongside Kubernetes taints to allow pods to be scheduled on nodes that would otherwise repel them.

Globally for Keycloal, frontend, and backend

Add the following command to <ORG_ID>-common-values.yaml.

global:
  nodeSelector:
    topology.kubernetes.io/zone: us-east-2a
  tolerations:
  - effect: NoSchedule
    key: cluster_name
    operator: Equal
    value: staging

For Keycloak and frontend

Add the following command to <ORG_ID>-common-values.yaml.

global:
  frontend:
    nodeSelector:
      topology.kubernetes.io/zone: us-east-2a
    tolerations:
    - effect: NoSchedule
      key: cluster_name
      operator: Equal
      value: staging

For backend

Add the following command to <ORG_ID>-common-values.yaml.

global:
  backend:
    nodeSelector:
      topology.kubernetes.io/zone: us-east-2a
    tolerations:
    - effect: NoSchedule
      key: cluster_name
      operator: Equal
      value: staging

Kafka external service type

Kafka is a core messaging backbone in the CO architecture, responsible for streaming telemetry and metric data between backend components. The Kafka external service type determines how Kafka is exposed outside the Kubernetes cluster, which directly impacts how backend services and external collectors communicate with the Kafka brokers.

LoadBalancer

By default, Kafka is exposed using a LoadBalancer service type, which provisions a cloud-provider-managed load balancer that automatically assigns a stable external IP or DNS endpoint to the Kafka brokers.

Add the following command to <ORG_ID>-common-values.yaml to deploy Kafka with LoadBalancer service type.

global:
  kafka_external_service:
    type: LoadBalancer

NodePort

In environments where a cloud load balancer is not available or not desired, such as on-premises clusters or restricted network setups, Kafka can be exposed using a NodePort service type. NodePort exposes a fixed port on every cluster node, enabling external access to Kafka through any node IP. Since no load balancer provides a stable endpoint, you must explicitly set the BACKEND_DNS parameter to a reachable backend IP or hostname so other CO components can connect to Kafka reliably.

Add the following command to <ORG_ID>-common-values.yaml to deploy Kafka with NodePort service type.

global:
  kafka_external_service:
    type: NodePort
  backend:
    BACKEND_DNS: "IP/HOSTNAME"