Back to posts

Kafka UI on GKE — Kafbat UI via YAML and Helm

Read the full guide on docs.beyondyou.my.id
messagingkafkagkekuberneteskafka-uikafbatmanagement

Kafka UI on GKE — Kafbat UI via YAML and Helm

Table of Contents

SectionTopicDescription
01Why Kafka UIWeb-based management for Kafka clusters.
02Kafbat UI vs AKHQChoosing the right UI tool.
03YAML DeploymentRaw manifests without Helm.
04Helm DeploymentQuick install via Helm chart.
05Gateway API IntegrationExpose UI via Gateway API.
06Multi-Cluster SupportConnect multiple Kafka clusters.
07Security & RBACProtecting the UI.

1. Why Kafka UI

A web UI for Kafka provides visibility into topics, consumer groups, and messages without running CLI commands.

ToolTypeFeatures
Kafbat UIWebTopics, consumers, messages, metrics
AKHQWebTopics, consumers, schema registry, connect
CLITerminalFull control, scriptable
ConduktorWeb (SaaS)Commercial, team features

When to Use Kafka UI

ScenarioUse UI?
Quick topic inspectionYes
Consumer lag monitoringYes
Message browsing with filtersYes
Production debuggingYes
Automated pipelinesNo (use CLI/API)
Schema managementYes (with Schema Registry)

2. Kafbat UI vs AKHQ

FeatureKafbat UIAKHQ
Maintained byKafbat communityTchiotludo
LicenseApache 2.0Apache 2.0
Kafka support3.x+2.x+
Schema RegistryYesYes
Kafka ConnectYesYes
AuthOAuth2, LDAP, basicBasic, LDAP
Multi-clusterYesYes
Docker imagekafbat/kafka-uitchiotludo/akhq
Active developmentYesSlower pace

3. YAML Deployment

ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
  name: kafbat-ui-configmap
  namespace: kafka
  labels:
    app: kafbat-ui
    app.kubernetes.io/name: kafbat-ui
    app.kubernetes.io/component: management
    app.kubernetes.io/part-of: kafka
data:
  config.yml: |-
    kafka:
      clusters:
        - name: gke-cluster
          bootstrapServers: kafka-0.kafka-headless.kafka.svc.cluster.local:9092
    auth:
      type: disabled
    management:
      health:
        ldap:
          enabled: false

Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: kafbat-ui
  namespace: kafka
  labels:
    app: kafbat-ui
    app.kubernetes.io/name: kafbat-ui
    app.kubernetes.io/component: management
    app.kubernetes.io/part-of: kafka
spec:
  replicas: 1
  selector:
    matchLabels:
      app: kafbat-ui
  template:
    metadata:
      labels:
        app: kafbat-ui
        app.kubernetes.io/name: kafbat-ui
        app.kubernetes.io/component: management
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: kubernetes.io/os
                operator: In
                values:
                - linux
      containers:
      - name: kafka-ui
        image: asia-southeast2-docker.pkg.dev/example-prd/devops/tools/kafka-ui:latest
        ports:
        - containerPort: 8080
          name: http
          protocol: TCP
        env:
        - name: KAFKA_CLUSTERS_0_NAME
          value: "gke-cluster"
        - name: KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS
          value: "kafka-0.kafka-headless.kafka.svc.cluster.local:9092"
        resources:
          requests:
            cpu: 100m
            memory: 256Mi
          limits:
            memory: 256Mi
        livenessProbe:
          httpGet:
            path: /api/health
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /api/health
            port: 8080
          initialDelaySeconds: 10
          periodSeconds: 10

Service

apiVersion: v1
kind: Service
metadata:
  name: kafbat-ui
  namespace: kafka
  labels:
    app: kafbat-ui
    app.kubernetes.io/name: kafbat-ui
    app.kubernetes.io/component: management
    app.kubernetes.io/part-of: kafka
spec:
  type: ClusterIP
  selector:
    app: kafbat-ui
  ports:
  - name: http
    port: 80
    targetPort: 8080

Apply and Access

kubectl apply -f kafbat-ui-configmap.yaml -n kafka
kubectl apply -f kafbat-ui-deployment.yaml -n kafka
kubectl apply -f kafbat-ui-service.yaml -n kafka

# Port forward
kubectl port-forward svc/kafbat-ui 8080:80 -n kafka

4. Helm Deployment

Add Repo

helm repo add kafbat-ui https://kafbat.github.io/helm-charts
helm repo update

Install with Custom ConfigMap

helm upgrade --install kafbat-ui kafbat-ui/kafka-ui \
  -n kafka \
  -f values.yaml

values.yaml

yamlApplicationConfig:
  kafka:
    clusters:
      - name: gke-cluster
        bootstrapServers: kafka-svc:9092
  auth:
    type: disabled
  management:
    health:
      ldap:
        enabled: false

Install with Existing ConfigMap

helm install kafbat-ui kafbat-ui/kafka-ui \
  -n kafka \
  --set yamlApplicationConfigConfigMap.name="kafbat-ui-configmap" \
  --set yamlApplicationConfigConfigMap.keyName="config.yml"

Helm vs YAML

AspectHelmYAML
Install speed1 command3+ commands
Customizationvalues.yamlEdit manifests directly
Upgradehelm upgradekubectl apply
Rollbackhelm rollbackkubectl rollout undo
VisibilityHidden templatesAll resources visible
DependenciesChart managesYou manage

5. Gateway API Integration

External Access

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: kafbat-ui-httproute
  namespace: kafka
  labels:
    app: kafbat-ui
    app.kubernetes.io/name: kafbat-ui
    app.kubernetes.io/component: gateway
spec:
  parentRefs:
  - name: example-gateway
    namespace: gateway-api
    sectionName: https
  hostnames:
  - kafka-ui.example.id
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /
    backendRefs:
    - name: kafbat-ui
      port: 80
      weight: 100

Health Check Policy

apiVersion: networking.gke.io/v1
kind: HealthCheckPolicy
metadata:
  name: kafbat-ui-hc-policy
  namespace: kafka
spec:
  default:
    checkIntervalSec: 10
    timeoutSec: 5
    healthyThreshold: 1
    unhealthyThreshold: 3
    config:
      type: HTTP
      httpHealthCheck:
        port: 8080
        requestPath: /api/health
  targetRef:
    group: ""
    kind: Service
    name: kafbat-ui

6. Multi-Cluster Support

ConfigMap with Multiple Clusters

apiVersion: v1
kind: ConfigMap
metadata:
  name: kafbat-ui-configmap
  namespace: kafka
data:
  config.yml: |-
    kafka:
      clusters:
        - name: production
          bootstrapServers: kafka-prod-0.kafka-headless.kafka.svc.cluster.local:9092
        - name: staging
          bootstrapServers: kafka-stg-0.kafka-headless.staging.svc.cluster.local:9092
        - name: development
          bootstrapServers: kafka-dev-0.kafka-headless.dev.svc.cluster.local:9092
    auth:
      type: disabled

Cluster Topology

graph LR
    subgraph UI["Kafbat UI"]
        dashboard["Web Dashboard"]
    end

    subgraph PROD["Production Cluster"]
        kafka_prod["Kafka\n3 brokers"]
    end

    subgraph STG["Staging Cluster"]
        kafka_stg["Kafka\n2 brokers"]
    end

    subgraph DEV["Development Cluster"]
        kafka_dev["Kafka\n1 broker"]
    end

    dashboard --> kafka_prod
    dashboard --> kafka_stg
    dashboard --> kafka_dev

7. Security & RBAC

Basic Auth (Nginx Sidecar)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: kafbat-ui
  namespace: kafka
spec:
  replicas: 1
  selector:
    matchLabels:
      app: kafbat-ui
  template:
    metadata:
      labels:
        app: kafbat-ui
    spec:
      containers:
      - name: nginx
        image: asia-southeast2-docker.pkg.dev/example-prd/devops/tools/nginx:alpine
        ports:
        - containerPort: 80
        volumeMounts:
        - name: nginx-config
          mountPath: /etc/nginx/nginx.conf
          subPath: nginx.conf
      - name: kafka-ui
        image: asia-southeast2-docker.pkg.dev/example-prd/devops/tools/kafka-ui:latest
        ports:
        - containerPort: 8080
        env:
        - name: KAFKA_CLUSTERS_0_NAME
          value: "gke-cluster"
        - name: KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS
          value: "kafka-0.kafka-headless.kafka.svc.cluster.local:9092"
      volumes:
      - name: nginx-config
        configMap:
          name: kafbat-ui-nginx-config

NetworkPolicy

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: kafbat-ui-netpol
  namespace: kafka
spec:
  podSelector:
    matchLabels:
      app: kafbat-ui
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: gateway-api
    ports:
    - protocol: TCP
      port: 8080
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: kafka
    ports:
    - protocol: TCP
      port: 9092

Access Summary

LayerControlPurpose
ServiceClusterIPCluster-only access
Gateway APIHTTPRoute hostnameExternal access with TLS
NetworkPolicyPod/namespace selectorsNetwork segmentation
AuthOAuth2/LDAPUser authentication
RBACK8s RBACAPI access control

References