Configure authentication for YuniKorn web UI on Kubernetes

This article describes how to activate LDAP and Kerberos authentication mechanisms for YuniKorn web UI. These mechanisms can work independently as well as together:

  • No LDAP, no Kerberos — no authentication.

  • LDAP, no Kerberos — LDAP password login.

  • No LDAP, Kerberos — Kerberos SPNEGO.

  • LDAP, Kerberos — Kerberos SPNEGO with LDAP password login.

Prerequisites

  • A Kubernetes cluster (1.32 or later) with access configured through kubectl.

  • The CLI tool that is unpacked from your offline package.

  • For Kerberos, make sure Kerberos operator is installed according to the instruction, and that its payloadNamespaces parameter includes YuniKorn’s namespace.

  • The following images that are unpacked and pushed to your repository:

    • hub.arenadata.io/adc-enterprise/yunikorn-k8shim:<version>

    • hub.arenadata.io/adc-enterprise/yunikorn-web:<version>

    • hub.arenadata.io/adc-enterprise/pause:<version>

    These artifacts can be found in the offline package, which can be requested from the Arenadata support team.

  • For LDAP, create the following secrets:

    yunikorn-ldap-secrets.yaml
    apiVersion: v1
    kind: Secret
    metadata:
      name: yunikorn-ldap-credentials
      namespace: yunikorn
    type: Opaque
    stringData:
      adminDN: "CN=stikhomirov,OU=kerberos,OU=adh,DC=ad,DC=ranger-test"
      adminPW: "<password>"
    
    ---
    apiVersion: v1
    kind: Secret
    metadata:
      name: yunikorn-web-auth
      namespace: yunikorn
    type: Opaque
    stringData:
      shared-secret: "<shared-secret>"
    $ kubectl apply -f yunikorn-ldap-secrets.yaml

Step 1. Install YuniKorn

  1. Initialize YuniKorn:

    $ ./adc init --yunikorn -o yunikorn.yaml

    This operation creates the yunikorn.yaml file with a configuration template.

  2. Edit the configuration file to your needs:

    yunikorn.yaml
    • Kerberos

    • LDAP

    apiVersion: adc.arenadata.io/v1alpha1
    kind: YuniKorn
    metadata:
      name: yunikorn
      namespace: yunikorn (1)
    spec:
      image: hub.arenadata.io/adc-enterprise/yunikorn-k8shim:<tag> (2)
      web:
        image: hub.arenadata.io/adc-enterprise/yunikorn-web:<tag> (3)
        #resources:
        #  limits:
        #    cpu: 200m
        #    memory: 500Mi
        #  requests:
        #    cpu: 100m
        #    memory: 100Mi
    
        goMemoryLimitPercentage: 60 (4)
        goGC: 100 (5)
    
        ## Environment variables passed to the component container.
        #envs:
        #  - name: YUNIKORN_LDAP_BIND_DN
        #    valueFrom:
        #      secretKeyRef:
        #        key: adminDN
        #        name: yunikorn-ldap-credentials
        #  - name: YUNIKORN_LDAP_BIND_PASSWORD
        #    valueFrom:
        #      secretKeyRef:
        #        key: adminPW
        #        name: yunikorn-ldap-credentials
        #  - name: YUNIKORN_LDAP_BASE_DN
        #    value: cn=accounts,dc=example,dc=com
        #  - name: YUNIKORN_LDAP_USER_BASE_DN
        #    value: cn=users,cn=accounts,dc=example,dc=com
        #  - name: YUNIKORN_LDAP_ADMIN_GROUPS
        #    value: admins
        #  - name: YUNIKORN_LDAP_ALLOWED_GROUPS
        #    value: ipausers
        #  - name: YUNIKORN_AUTH_SHARED_SECRET
        #    valueFrom:
        #      secretKeyRef:
        #        key: shared-secret
        #        name: yunikorn-web-auth
    
      ## LDAP authentication configuration.
      ## Uncomment and fill url and userBindPattern.
      ## For ldaps:// URLs the ssl: or ca: section must also be configured (depends on product)
      #ldap:
      #  # LDAP service url.
      #  url: ldap://ldap.example.com:389
      #
      #  # LDAP user Bind pattern.
      #  userBindPattern: uid=#UID,cn=users,dc=example,dc=com
    
      ## Kerberos configuration for authentication.
      kerberos: (6)
        realm: AD.RANGER-TEST
      #
      #  # Service name in the Kerberos principal. Defaults to the product name.
        service: HTTP
      #
      #  # Hostname in the Kerberos principal.
      #  # Required for a fixed service principal; leave it empty only to derive one principal per pod from the cluster domain.
        hostname: yunikorn.ru-central1.internal
        keytab: (7)
      #    # true - kerberos-operator creates the keytab Secret.
      #    # false (default) - reference an existing keytab Secret with name keytab.secretName.
          create: true
      #
      #    # Name of the keytab Secret.
      #    # Optional when create: true - names the generated Secret (default: <name>-keytab).
      #    # Required when create: false - must reference an existing Secret.
          secretName: yunikorn-keytab
      #
      #    # Label selector for the Pod that generates the keytab.
      #    # Required when create: true; ignored when create: false.
          labelSelector:
            env: prod
          rotation:
            interval: 24h
            checkInterval: 1h
    
      ## HTTPS on the user-facing YuniKorn Web UI endpoint on port 9889.
      ## Together with monitoring.exportMetrics it also serves the scheduler /metrics over HTTPS
      ## using the same certificate and key, keeping the fixed "metrics" port name.
      ## The Web UI to k8shim unix socket is not changed.
      ## Set externalSecretName to reference an existing Secret,
      ## or set files and optional secretName to have ADC create it.
      #webTLS:
      #  ## Optional name of the Secret ADC creates from local files.
      #  #secretName: custom-yunikorn-web-tls
      #  externalSecretName: existing-yunikorn-web-tls
      #
      #  # Key in the Secret containing the web TLS certificate.
      #  certificateKey: tls.crt
      #
      #  # Key in the Secret containing the web TLS private key.
      #  privateKey: tls.key
      #
      #  ## Local files 'adc apply' puts into the Secret named by webTLS.secretName.
      #  ## Relative paths are resolved against the config file.
      #  #files:
      #  #  certificatePath: /path/to/tls.crt
      #  #  privateKeyPath: /path/to/tls.key
    
      # Whether the CLI creates the product namespace.
      # The namespace name is set in metadata.namespace.
      namespace:
        create: true
    
      # ServiceAccount used by the YuniKorn scheduler. The CLI creates it, plus a ClusterRole, Role
      # and their bindings, by default (create: true). Set create: false to skip all of them and only
      # reference a ServiceAccount (and RBAC) managed elsewhere. name is optional; when empty, it
      # defaults to the release name.
      serviceAccount: (8)
        create: true
        name: yunikorn
    
      ## Image pull secret for a private registry.
      ## Set 'externalSecretName' to reference an existing Secret,
      ## or set 'credentials' and optionally 'secretName' to let the CLI create one.
      #imagePullSecret:
      #  # Use a Secret managed outside ADC.
      #  externalSecretName: existing-registry-secret
      #
      #  ## Or let ADC create the Secret.
      #  #secretName: custom-registry-secret
      #
      #  #credentials:
      #  #  registry: registry.example.com
      #  #  username: user
      #  #  password: pass
    
      #resources:
      #  limits:
      #    cpu: "4"
      #    memory: 2Gi
      #  requests:
      #    cpu: 200m
      #    memory: 1Gi
    
      goMemoryLimitPercentage: 80 (9)
      goGC: 100 (10)
    
      ## Bootstrap config rendered into the yunikorn-defaults ConfigMap.
      ## Put the queue hierarchy under the "queues.yaml" key as a YAML string;
      ## k8shim reads it and creates the queues. Leave empty to use the built-in root queue.
      yunikornDefaults: (11)
        queues.yaml: | (12)
          partitions:
            - name: default
              queues:
                - name: root
                  submitacl: '*'
                  queues:
                    - name: engineering
                    - name: analytics
                    - name: ad-hoc
        service.exposeMetricsOnly: "true"
        service.placeholderImage: hub.arenadata.io/adc-enterprise/pause:<tag> (13)
    
      ## Controls whether Secret/ConfigMap changes restart pods.
      ## Set enabled: false to update referenced Secrets without restarting
      ## the workload; pods keep running the previous configuration until
      ## the policy is re-enabled. Defaults to enabled.
      #configurationRollout:
      #  enabled: false
    
      ## Monitoring configuration.
      #monitoring:
      #  # Enables Prometheus metrics export from this product's pods.
      #  exportMetrics: true
      #
      #  ## Renders a namespace-scoped vmagent that sends metrics to an external ADM.
      #  #vmagent:
      #  #  remoteWrite:
      #  #    url: http://vminsert.example.com:8480/insert/0/prometheus/api/v1/write
      #  #  scrapeInterval: 30s
      #  #
      #  #  ## HTTPS settings used by vmagent when scraping product metrics.
      #  #  #tls:
      #  #  #  ## CA certificate source used to verify the metrics endpoint.
      #  #  #  #ca:
      #  #  #  #  # Use a Secret managed outside ADC.
      #  #  #  #  externalSecretName: existing-product-metrics-ca
      #  #  #  #
      #  #  #  #  ## Or let ADC create the Secret.
      #  #  #  #  #secretName: product-metrics-ca
      #  #  #  #
      #  #  #  #  # Key containing the CA certificate in the referenced Secret.
      #  #  #  #  certificateKey: ca.crt
      #  #  #  #
      #  #  #  #  ## Local CA certificate read by ADC to create the configured Secret.
      #  #  #  #  #files:
      #  #  #  #  #  certificatePath: /path/to/ca.crt
      #  #  #
      #  #  #  ## Server name used to verify the metrics endpoint certificate hostname.
      #  #  #  #serverName: metrics.example.com
      #  #  #
      #  #  #  # Skip verification of the metrics endpoint certificate. Do not use together with ca.
      #  #  #  insecureSkipVerify: true
    1 Namespace that YuniKorn will use.
    2 URL to the YuniKorn k8shim image in your repository.
    3 URL to the YuniKorn web UI image in your repository.
    4 Percentage of web.resources.limits.memory used to compute the GOMEMLIMIT web UI value.
    5 GOGC web UI value.
    6 Kerberos settings. The kerberos.hostname value is used to generate the SPNEGO HTTP principal.
    7 If keytab.create is set to true, Kerberos operator will generate a secret with the name specified in keytab.secretName; if keytab.secretName is not specified, the name will be <metadata.name>-keytab. If keytab.create is set to false, an existing keytab.secretName secret will be referenced to obtain a keytab.
    8 Service account settings.
    9 Percentage of resources.limits.memory used to compute the GOMEMLIMIT environment value.
    10 GOGC environment value.
    11 Bootstrap configuration keys. Leave empty to use YuniKorn’s built-in root queue.
    12 Queue hierarchy in YuniKorn’s queues.yaml format (partitions → queues → children, with per-queue resources/properties).
    13 Image used for gang scheduling placeholder pods. adc adds the product default when omitted.
    apiVersion: adc.arenadata.io/v1alpha1
    kind: YuniKorn
    metadata:
      name: yunikorn
      namespace: yunikorn (1)
    spec:
      image: hub.arenadata.io/adc-enterprise/yunikorn-k8shim:<tag> (2)
      web:
        image: hub.arenadata.io/adc-enterprise/yunikorn-web:<tag> (3)
        #resources:
        #  limits:
        #    cpu: 200m
        #    memory: 500Mi
        #  requests:
        #    cpu: 100m
        #    memory: 100Mi
    
        goMemoryLimitPercentage: 60 (4)
        goGC: 100 (5)
    
        ## Environment variables passed to the component container.
        envs: (6)
          - name: YUNIKORN_LDAP_BIND_DN
            valueFrom:
              secretKeyRef:
                key: adminDN
                name: yunikorn-ldap-credentials
          - name: YUNIKORN_LDAP_BIND_PASSWORD
            valueFrom:
              secretKeyRef:
                key: adminPW
                name: yunikorn-ldap-credentials
          - name: YUNIKORN_LDAP_BASE_DN
            value: ou=adh,dc=ad,dc=ranger-test
          - name: YUNIKORN_LDAP_USER_BASE_DN
            value: ou=kerberos,ou=adh,dc=ad,dc=ranger-test
          - name: YUNIKORN_LDAP_ADMIN_GROUPS
            value: admins
          - name: YUNIKORN_LDAP_ALLOWED_GROUPS
            value: ipausers
          - name: YUNIKORN_AUTH_SHARED_SECRET
            valueFrom:
              secretKeyRef:
                key: shared-secret
                name: yunikorn-web-auth
    
      ## LDAP authentication configuration.
      ## Uncomment and fill url and userBindPattern.
      ## For ldaps:// URLs the ssl: or ca: section must also be configured (depends on product)
      ldap:
      #  # LDAP service url.
        url: ldaps://ad01.adsw.io:636 (7)
      #
      #  # LDAP user Bind pattern.
        userBindPattern: cn=#UID,OU=kerberos,OU=adh,DC=ad,DC=ranger-test (8)
    
      ## Kerberos configuration for authentication.
      #kerberos:
      #  realm: AD.RANGER-TEST
      #
      #  # Service name in the Kerberos principal. Defaults to the product name.
      #  service: HTTP
      #
      #  # Hostname in the Kerberos principal.
      #  # Required for a fixed service principal; leave it empty only to derive one principal per pod from the cluster domain.
      #  hostname: yunikorn.ru-central1.internal
      #  keytab:
      #    # true - kerberos-operator creates the keytab Secret.
      #    # false (default) - reference an existing keytab Secret with name keytab.secretName.
      #    create: true
      #
      #    # Name of the keytab Secret.
      #    # Optional when create: true - names the generated Secret (default: <name>-keytab).
      #    # Required when create: false - must reference an existing Secret.
      #    secretName: yunikorn-keytab
      #
      #    # Label selector for the Pod that generates the keytab.
      #    # Required when create: true; ignored when create: false.
      #    labelSelector:
      #      env: prod
      #    rotation:
      #      interval: 24h
      #      checkInterval: 1h
    
      ## HTTPS on the user-facing YuniKorn Web UI endpoint on port 9889.
      ## Together with monitoring.exportMetrics it also serves the scheduler /metrics over HTTPS
      ## using the same certificate and key, keeping the fixed "metrics" port name.
      ## The Web UI to k8shim unix socket is not changed.
      ## Set externalSecretName to reference an existing Secret,
      ## or set files and optional secretName to have ADC create it.
      #webTLS:
      #  ## Optional name of the Secret ADC creates from local files.
      #  #secretName: custom-yunikorn-web-tls
      #  externalSecretName: existing-yunikorn-web-tls
      #
      #  # Key in the Secret containing the web TLS certificate.
      #  certificateKey: tls.crt
      #
      #  # Key in the Secret containing the web TLS private key.
      #  privateKey: tls.key
      #
      #  ## Local files 'adc apply' puts into the Secret named by webTLS.secretName.
      #  ## Relative paths are resolved against the config file.
      #  #files:
      #  #  certificatePath: /path/to/tls.crt
      #  #  privateKeyPath: /path/to/tls.key
    
      # Whether the CLI creates the product namespace.
      # The namespace name is set in metadata.namespace.
      namespace:
        create: true
    
      # ServiceAccount used by the YuniKorn scheduler. The CLI creates it, plus a ClusterRole, Role
      # and their bindings, by default (create: true). Set create: false to skip all of them and only
      # reference a ServiceAccount (and RBAC) managed elsewhere. name is optional; when empty, it
      # defaults to the release name.
      serviceAccount: (9)
        create: true
        name: yunikorn
    
      ## Image pull secret for a private registry.
      ## Set 'externalSecretName' to reference an existing Secret,
      ## or set 'credentials' and optionally 'secretName' to let the CLI create one.
      #imagePullSecret:
      #  # Use a Secret managed outside ADC.
      #  externalSecretName: existing-registry-secret
      #
      #  ## Or let ADC create the Secret.
      #  #secretName: custom-registry-secret
      #
      #  #credentials:
      #  #  registry: registry.example.com
      #  #  username: user
      #  #  password: pass
    
      #resources:
      #  limits:
      #    cpu: "4"
      #    memory: 2Gi
      #  requests:
      #    cpu: 200m
      #    memory: 1Gi
    
      goMemoryLimitPercentage: 80 (10)
      goGC: 100 (11)
    
      ## Bootstrap config rendered into the yunikorn-defaults ConfigMap.
      ## Put the queue hierarchy under the "queues.yaml" key as a YAML string;
      ## k8shim reads it and creates the queues. Leave empty to use the built-in root queue.
      yunikornDefaults: (12)
        queues.yaml: | (13)
          partitions:
            - name: default
              queues:
                - name: root
                  submitacl: '*'
                  queues:
                    - name: engineering
                    - name: analytics
                    - name: ad-hoc
        service.exposeMetricsOnly: "true"
        service.placeholderImage: hub.arenadata.io/adc-enterprise/pause:<tag> (14)
    
      ## Controls whether Secret/ConfigMap changes restart pods.
      ## Set enabled: false to update referenced Secrets without restarting
      ## the workload; pods keep running the previous configuration until
      ## the policy is re-enabled. Defaults to enabled.
      #configurationRollout:
      #  enabled: false
    
      ## Monitoring configuration.
      #monitoring:
      #  # Enables Prometheus metrics export from this product's pods.
      #  exportMetrics: true
      #
      #  ## Renders a namespace-scoped vmagent that sends metrics to an external ADM.
      #  #vmagent:
      #  #  remoteWrite:
      #  #    url: http://vminsert.example.com:8480/insert/0/prometheus/api/v1/write
      #  #  scrapeInterval: 30s
      #  #
      #  #  ## HTTPS settings used by vmagent when scraping product metrics.
      #  #  #tls:
      #  #  #  ## CA certificate source used to verify the metrics endpoint.
      #  #  #  #ca:
      #  #  #  #  # Use a Secret managed outside ADC.
      #  #  #  #  externalSecretName: existing-product-metrics-ca
      #  #  #  #
      #  #  #  #  ## Or let ADC create the Secret.
      #  #  #  #  #secretName: product-metrics-ca
      #  #  #  #
      #  #  #  #  # Key containing the CA certificate in the referenced Secret.
      #  #  #  #  certificateKey: ca.crt
      #  #  #  #
      #  #  #  #  ## Local CA certificate read by ADC to create the configured Secret.
      #  #  #  #  #files:
      #  #  #  #  #  certificatePath: /path/to/ca.crt
      #  #  #
      #  #  #  ## Server name used to verify the metrics endpoint certificate hostname.
      #  #  #  #serverName: metrics.example.com
      #  #  #
      #  #  #  # Skip verification of the metrics endpoint certificate. Do not use together with ca.
      #  #  #  insecureSkipVerify: true
    1 Namespace that YuniKorn will use.
    2 URL to the YuniKorn k8shim image in your repository.
    3 URL to the YuniKorn web UI image in your repository.
    4 Percentage of web.resources.limits.memory used to compute the GOMEMLIMIT web UI value.
    5 GOGC web UI value.
    6 Environment variables passed to the container.
    7 URL for LDAP connection.
    8 User bind pattern.
    9 Service account settings.
    10 Percentage of resources.limits.memory used to compute the GOMEMLIMIT environment value.
    11 GOGC environment value.
    12 Bootstrap configuration keys. Leave empty to use YuniKorn’s built-in root queue.
    13 Queue hierarchy in YuniKorn’s queues.yaml format (partitions → queues → children, with per-queue resources/properties).
    14 Image used for gang scheduling placeholder pods. adc adds the product default when omitted.

    You can check the configuration about to be applied by running the apply command with the --dry-run option:

    $ ./adc apply -f yunikorn.yaml --dry-run > yunikorn-render.yaml
  3. Apply the configuration and deploy YuniKorn:

    $ ./adc apply -f yunikorn.yaml

    The expected output contains the confirmation of success:

    time="20260923083854UTC" level="info" msg="yunikorn applied to namespace yunikorn"
  4. Verify that the YuniKorn pods are running:

    $ kubectl get pods -n yunikorn

    The expected output should be similar to:

    NAME                                  READY   STATUS    RESTARTS   AGE
    yunikorn-scheduler-7447469ddc-fksp5   2/2     Running   0          6s

Step 2. Provide access to YuniKorn web UI

To access the YuniKorn web UI, you need to expose the service using one of the supported publication methods, for example, through a load balancer or Ingress controller. All configurations related to exposing a service, including DNS, annotations, Ingress settings, load balancing rules, and other platform-specific settings, must be specified according to your Kubernetes environment.

  1. Get the external IP address of your load balancer or Ingress controller. For example:

    NAME                                        TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)           AGE
    yunikorn-lb                                 LoadBalancer   10.85.56.180   10.92.41.69   9889:30226/TCP   119s
  2. On the machine from which you plan to access YuniKorn web UI, add the following line to the /etc/hosts file:

    <lb_ip> yunikorn.ru-central1.internal
  3. Open the YuniKorn web UI in your browser, using the http://yunikorn.ru-central1.internal:9889 URL.

    YuniKorn web UI
    YuniKorn web UI
    YuniKorn web UI
    YuniKorn web UI

Delete instances

To delete YuniKorn, run the delete command:

$ ./adc delete -f yunikorn.yaml
Found a mistake? Seleсt text and press Ctrl+Enter to report it