DevOps Helm Charts

Gateway API LDAPS Example

This walkthrough shows how to expose PingDirectory over both HTTPS and LDAPS through Gateway API with Traefik.

This example was written using Docker Desktop with Kubernetes enabled on the Mac platform using the Apple Silicon chip. The Docker Desktop version used for this guide was 4.67.0 (222858), which includes Docker Engine 29.3.1 and Kubernetes v1.34.1. The walkthrough uses Gateway API v1.4.1, Traefik 3.6.12 as the Gateway controller, and the ping-devops Helm chart 0.12.2 (the release version at which TCPRoute support was added). The Docker Desktop Kubernetes environment was reset before starting.

Traefik 3.6.12 is the latest version installed by default using their Helm charts v39.0.7 as of the time of this writing. However, currently Traefik at any version is not compatible with the most recent version of the Gateway API (1.5.1). Until support for the latest Gateway API version is added to Traefik, you must use Gateway API v1.4.1 to run this example.

The Getting Started page has instructions on getting your environment configured for using Ping ping-devops Helm charts.

For more examples, see Helm Chart Example Configurations.

For more information on Helm with Ping products, see Ping Identity DevOps Helm Charts.

What You Will Deploy

When finished with this example, you will have deployed the following:

  • Release name: gateway-ldaps-demo

  • Namespace: ping-gateway

  • Gateway API CRDs if not already installed in Docker Desktop Kubernetes

  • The experimental Gateway API channel is installed because TCPRoute is still gateway.networking.k8s.io/v1alpha2

  • Traefik running in namespace traefik

Files Used

The example values files are stored in the pingidentity-devops-getting-started repository under 30-helm/gateway/tcproute/. You will need to clone the repository or copy the files locally to run the example. The files are:

An expected route render file is also included for reference:

The YAML files noted above are annotated to inform the reader what each entry accomplishes in the context of this example.

Install Gateway API CRDs

  1. Install the standard and experimental Gateway API CRDs before rendering TCPRoute.

     kubectl apply --server-side=true -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.1/standard-install.yaml
    
     kubectl apply --server-side=true -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.1/experimental-install.yaml
    
    # Confirm the CRDs are installed
    kubectl get crd | grep gateway.networking.k8s.
    
    backendtlspolicies.gateway.networking.k8s.io          2026-04-08T20:49:22Z
    gatewayclasses.gateway.networking.k8s.io              2026-04-08T20:49:22Z
    gateways.gateway.networking.k8s.io                    2026-04-08T20:49:22Z
    grpcroutes.gateway.networking.k8s.io                  2026-04-08T20:49:22Z
    httproutes.gateway.networking.k8s.io                  2026-04-08T20:49:22Z
    referencegrants.gateway.networking.k8s.io             2026-04-08T20:49:22Z
    tcproutes.gateway.networking.k8s.io                   2026-04-08T20:49:22Z
    tlsroutes.gateway.networking.k8s.io                   2026-04-08T20:49:22Z
    udproutes.gateway.networking.k8s.io                   2026-04-08T20:49:22Z

The kubectl apply commands used above use the --server-side=true flag due to the size of the Gateway API CRD manifests. See Gateway API v1.4.1 Release Notes for more information.

Install or Update Traefik

  1. Use the Traefik values file to enable Gateway API and the LDAPS TCP entrypoint.

    helm repo add traefik https://traefik.github.io/charts
    helm repo update
    
    helm upgrade --install traefik traefik/traefik \
      --namespace traefik \
      --create-namespace \
      -f 30-helm/gateway/tcproute/gateway_ldaps_demo_traefik_values.yaml \
      --skip-crds

Create the Namespace and TLS Secret

  1. Create the application namespace and a TLS secret for the HTTPS listener.

    kubectl create namespace ping-gateway
    
    # Set the kubectl context to the namespace
    kubectl config set-context --current --namespace=ping-gateway
    
    # Confirm
    kubectl config view --minify | grep namespace:
    
    # Create a self-signed certificate for the HTTPS listener.
    # The common name should match the hostnames used in the `HTTPRoute` resources.
    openssl req -x509 -nodes -days 365 \
      -newkey rsa:2048 \
      -keyout gateway-demo.key \
      -out gateway-demo.crt \
      -subj "/CN=*.pingdemo.example"
    
    kubectl -n ping-gateway create secret tls gateway-demo-tls \
      --cert=gateway-demo.crt \
      --key=gateway-demo.key

Apply the Gateway and Create a Secret for DevOps License

  1. Apply the Gateway manifest.

    kubectl apply -f 30-helm/gateway/tcproute/gateway_ldaps_demo_gateway.yaml

    The Gateway creates:

    • An HTTPS listener on port 8443

    • An LDAPS TCP listener on port 1636

      The TCP listener name is ldaps-1636. The chart values bind the TCPRoute to that listener with sectionName.

  2. Create a secret in the namespace you will be using to run the example. This secret provides credentials to obtain an evaluation license based on your Ping DevOps username and key:

    kubectl create secret generic devops-secret \
      --from-literal=PING_IDENTITY_DEVOPS_USER="$PING_IDENTITY_DEVOPS_USER" \
      --from-literal=PING_IDENTITY_DEVOPS_KEY="$PING_IDENTITY_DEVOPS_KEY" \
      --from-literal=PING_IDENTITY_ACCEPT_EULA="$PING_IDENTITY_ACCEPT_EULA" \
      --type=Opaque \
      --dry-run=client -o yaml | kubectl apply -f -

Deploy the Ping Identity Chart

  1. Deploy the chart with the LDAPS example values.

    helm upgrade --install gateway-ldaps-demo pingidentity/ping-devops \
      --namespace ping-gateway \
      -f 30-helm/gateway/tcproute/gateway_ldaps_demo_values.yaml

    The example deploys:

    • pingdirectory

    • pingdataconsole

      The chart renders:

    • An HTTPRoute for PingDirectory admin HTTPS

    • An HTTPRoute for PingDataConsole

    • A TCPRoute for PingDirectory LDAPS

Add Local Host Mappings

  1. Docker Desktop exposes the Traefik LoadBalancer on the local host. Add the example hostnames to /etc/hosts.

    127.0.0.1 gateway-ldaps-demo-pingdataconsole.pingdemo.example gateway-ldaps-demo-pingdirectory.pingdemo.example

Validate the Rendered Routes

  1. Confirm that the Gateway, HTTPRoute, and TCPRoute resources were created.

    kubectl -n ping-gateway get gateway,httproute,tcproute
    
    # Expected output includes:
    NAME                                                    CLASS     ADDRESS      PROGRAMMED   AGE
    gateway.gateway.networking.k8s.io/ping-devops-gateway   traefik   172.19.0.5   True         112s
    
    NAME                                                                     HOSTNAMES                                                 AGE
    httproute.gateway.networking.k8s.io/gateway-ldaps-demo-pingdataconsole   ["gateway-ldaps-demo-pingdataconsole.pingdemo.example"]   65s
    httproute.gateway.networking.k8s.io/gateway-ldaps-demo-pingdirectory     ["gateway-ldaps-demo-pingdirectory.pingdemo.example"]     65s
    
    NAME                                                                        AGE
    tcproute.gateway.networking.k8s.io/gateway-ldaps-demo-pingdirectory-ldaps   65s

Validate Browser Access and Console Login

  1. Open PingDataConsole in a browser:

    Accept the browser certificate warning.

  2. Use these login values in the PingDataConsole sign-in form:

    • Server: ldaps://gateway-ldaps-demo-pingdirectory-cluster:1636

    • Username: administrator

    • Password: 2FederateM0re

      Operational success for the browser path is:

    • The console login page loads through the HTTPRoute

    • The console successfully authenticates to PingDirectory over LDAPS using the in-cluster cluster service

    • The console displays the connected PingDirectory server after login

Validate HTTPS and LDAPS Access with CLI

  1. Validate PingDataConsole.

    curl -skI --resolve gateway-ldaps-demo-pingdataconsole.pingdemo.example:443:127.0.0.1 \
      https://gateway-ldaps-demo-pingdataconsole.pingdemo.example/

    Expected result: HTTP/2 200

  2. Validate PingDirectory admin HTTPS.

    curl -skI --resolve gateway-ldaps-demo-pingdirectory.pingdemo.example:443:127.0.0.1 \
      https://gateway-ldaps-demo-pingdirectory.pingdemo.example/

    Expected result: a valid HTTP response from PingDirectory, which may be 404 at /

  3. Validate PingDirectory LDAPS.

    openssl s_client -connect 127.0.0.1:1636 \
      -servername gateway-ldaps-demo-pingdirectory.pingdemo.example </dev/null

    Expected result: successful TLS handshake and a PingDirectory self-signed certificate

Troubleshooting

  • If TCPRoute does not render, verify the cluster has the experimental Gateway API CRDs installed.

  • If the TCPRoute renders but does not attach, verify the Gateway listener name matches sectionName: ldaps-1636.

  • If Traefik does not expose 1636, verify the LDAPS port is enabled in the Traefik values and the Service publishes it.

  • If the browser console loads but the server login fails, verify the server field is ldaps://gateway-ldaps-demo-pingdirectory-cluster:1636.

  • If PingDataConsole cannot bind to PingDirectory, verify defaultLogin.server.host is pingdirectory-cluster, which the chart expands to gateway-ldaps-demo-pingdirectory-cluster.

Cleanup

  1. Remove the example resources.

    helm uninstall gateway-ldaps-demo -n ping-gateway
    kubectl delete -f 30-helm/gateway/tcproute/gateway_ldaps_demo_gateway.yaml
    kubectl delete namespace ping-gateway
    
    # Optionally, remove Traefik and the Gateway API CRDs if no longer needed:
    kubectl delete namespace traefik
    kubectl delete -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.1/experimental-install.yaml
    kubectl delete -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.1/standard-install.yaml