Deploy an Example Stack with Gateway API
|
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 |
The Ping Identity Helm Getting Started page has instructions on getting your environment configured for using the 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 Do
After using Git to clone the pingidentity-devops-getting-started repository, you will use Helm to deploy a sample stack to a Kubernetes cluster.
Prerequisites
-
Register for the Ping DevOps program and install/configure
pingctlwith your User and Key -
Install Git
-
Follow the instructions on the helm Getting Started page up through updating to the latest charts to ensure you have the latest version of our charts
-
Access to a Kubernetes cluster. You can enable Kubernetes in Docker Desktop for a simple cluster, which was the cluster used for this guide (on the Mac platform).
Clone the getting-started repository
-
Clone the
pingidentity-devops-getting-startedrepository to your local${PING_IDENTITY_DEVOPS_HOME}directory.The
${PING_IDENTITY_DEVOPS_HOME}environment variable was set by runningpingctl config.cd "${PING_IDENTITY_DEVOPS_HOME}" git clone https://github.com/pingidentity/pingidentity-devops-getting-started.git
Deploy the example stack
-
Deploy the example stack of our product containers.
For this guide, avoid making changes to the
everything.yamlfile to ensure a successful first-time deployment.-
Create a namespace for running the stack in your Kubernetes cluster.
# Create the namespace kubectl create ns pinghelm # Set the kubectl context to the namespace kubectl config set-context --current --namespace=pinghelm # Confirm kubectl config view --minify | grep namespace:Currently, the Traefik charts bundle the Gateway API CRDs at version 1.4.0. By default, this inclusion means that if Gateway API CRDs are not already present in the cluster, you will have that version after installing Traefik. If you want to use the bundled CRDs, simply install Traefik with the instructions below, omitting the
--skip-crdsflag. If you want to use newer CRDs, you will need to install those first, then install Traefik with--skip-crdsto avoid conflicts with the bundled CRDs.The latter approach is used in this guide.
-
Install the Gateway API CRDs:
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.5.0/standard-install.yaml -
Deploy Traefik with Gateway API support:
cd <repository-root>/30-helm/ # If necessary, add the Traefik Helm repository and update to get the latest charts: helm repo add traefik https://traefik.github.io/charts helm repo update traefik # Install Trafik helm upgrade --install traefik traefik/traefik \ --namespace traefik --create-namespace \ -f gateway/traefik-values.yaml \ --skip-crds
-
|
The values file used to configure Traefik in this deployment example is configured to skip backend TLS verification so the Ping product consoles with self-signed certificates will work with Traefik. Do not use this setting in production. |
-
To wait for Traefik to reach a healthy state, run the following command. You can also observe pod status using
k9s. You should see one controller pod running when Traefik is ready:kubectl get pods --namespace traefik -
Create a wildcard TLS certificate and Kubernetes secret for the Gateway listener:
openssl req -x509 -newkey rsa:2048 -sha256 -nodes -days 365 \ -subj '/CN=*.pingdemo.example' \ -addext 'subjectAltName=DNS:*.pingdemo.example' \ -keyout /tmp/pingdemo-example.key \ -out /tmp/pingdemo-example.crt kubectl create secret tls pingdemo-example-tls \ --namespace pinghelm \ --cert /tmp/pingdemo-example.crt \ --key /tmp/pingdemo-example.key \ --dry-run=client -o yaml | kubectl apply -f - -
Create the Gateway object and wait for it to be accepted and programmed:
kubectl apply -f gateway/gateway.yaml kubectl wait --for=condition=Accepted gateway/ping-devops-gateway -n pinghelm --timeout=180s kubectl wait --for=condition=Programmed gateway/ping-devops-gateway -n pinghelm --timeout=180s kubectl get gateway -n pinghelm -
Create a secret in the namespace you will be using to run the example (pinghelm). 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 - -
This example will use the Helm release name
demoand DNS domain suffix*pingdemo.examplefor accessing applications. Add all expected hosts to/etc/hosts:echo '127.0.0.1 demo-pingaccess-admin.pingdemo.example demo-pingaccess-engine.pingdemo.example demo-pingauthorize.pingdemo.example demo-pingauthorizepap.pingdemo.example demo-pingdataconsole.pingdemo.example demo-pingdelegator.pingdemo.example demo-pingdirectory.pingdemo.example demo-pingfederate-admin.pingdemo.example demo-pingfederate-engine.pingdemo.example demo-pingcentral.pingdemo.example' | sudo tee -a /etc/hosts > /dev/null -
To install the chart, navigate to your local
"${PING_IDENTITY_DEVOPS_HOME}"/pingidentity-devops-getting-started/30-helmdirectory and run the command shown here. In this example, the release (deployment into Kubernetes by Helm) is calleddemo, forming the prefix for all objects created. Thegateway/gateway-demo.yamlfile configures Gateway APIHTTPRouteresources for the products:Reminder: This walkthrough requires chart version
0.12.0or later to ensure the necessary Gateway API resources support is included in the deployment.# If necessary, add the Ping Identity Helm repository and update to get the latest charts: helm repo add pingidentity https://helm.pingidentity.com/ helm repo update pingidentity helm upgrade --install demo pingidentity/ping-devops \ --namespace pinghelm \ --version 0.12.0 \ -f everything.yaml \ -f gateway/gateway-demo.yamlThe latest product Docker images are automatically downloaded if they have not previously been pulled from Docker Hub.
Sample output:
NAME: demo LAST DEPLOYED: Wed Feb 11 11:06:09 2026 NAMESPACE: pinghelm STATUS: deployed REVISION: 1 DESCRIPTION: Install complete TEST SUITE: None NOTES: #------------------------------------------------------------------------------------- # Ping DevOps # # Description: Ping Identity helm charts - February 4, 2026 #------------------------------------------------------------------------------------- # # Product tag typ # cpu R/L mem R/L Ing # --------------------- ------- --- -- --------- --------- --- # global 2601 0/0 0/0 √ # # √ pingaccess-admin 2601 sts 1 0/2 1Gi/4Gi √ # √ pingaccess-engine 2601 dep 1 0/2 1Gi/4Gi √ # √ pingauthorize 2601 dep 1 0/2 1.5G/4Gi √ # pingauthorizepap # pingcentral # √ pingdataconsole 2601 dep 1 0/2 .5Gi/2Gi √ # pingdatasync # pingdelegator # √ pingdirectory 2601 sts 1 50m/2 2Gi/8Gi √ # pingdirectoryproxy # √ pingfederate-admin 2601 dep 1 0/2 1Gi/4Gi √ # √ pingfederate-engine 2601 dep 1 0/2 1Gi/4Gi √ # # ldap-sdk-tools # pd-replication-timing # pingtoolkit # #------------------------------------------------------------------------------------- # To see values info, simply set one of the following on your helm install/upgrade # # --set help.values=all # Provides all (i.e. .Values, .Release, .Chart, ...) yaml # --set help.values=global # Provides global values # --set help.values={ image } # Provides image values merged with global #-------------------------------------------------------------------------------------As you can see, PingAccess Admin and Engine, PingData Console, PingDirectory, PingAuthorize, and the PingFederate Admin and Engine are deployed from the provided
everything.yamlvalues file.It will take several minutes for all components to become operational.
-
To see the Gateway and HTTPRoute resources created by the chart, run the following command:
kubectl get gateway,httproute -n pinghelmSample output:
NAME CLASS ADDRESS PROGRAMMED AGE gateway.gateway.networking.k8s.io/ping-devops-gateway traefik localhost True 27m NAME HOSTNAMES AGE httproute.gateway.networking.k8s.io/demo-pingaccess-admin ["demo-pingaccess-admin.pingdemo.example"] 17s httproute.gateway.networking.k8s.io/demo-pingaccess-engine ["demo-pingaccess-engine.pingdemo.example"] 17s httproute.gateway.networking.k8s.io/demo-pingauthorize ["demo-pingauthorize.pingdemo.example"] 17s httproute.gateway.networking.k8s.io/demo-pingdataconsole ["demo-pingdataconsole.pingdemo.example"] 17s httproute.gateway.networking.k8s.io/demo-pingdirectory ["demo-pingdirectory.pingdemo.example"] 17s httproute.gateway.networking.k8s.io/demo-pingfederate-admin ["demo-pingfederate-admin.pingdemo.example"] 17s httproute.gateway.networking.k8s.io/demo-pingfederate-engine ["demo-pingfederate-engine.pingdemo.example"] 17s -
To see the status conditions for the Gateway and HTTPRoutes, run:
kubectl get httproute -n pinghelm -o yaml | grep -E 'type: Accepted|type: ResolvedRefs'Sample output:
type: Accepted type: ResolvedRefs type: Accepted type: ResolvedRefs type: Accepted type: ResolvedRefs type: Accepted type: ResolvedRefs type: Accepted type: ResolvedRefs type: Accepted type: ResolvedRefs type: Accepted type: ResolvedRefsEach of these are the
AcceptedandResolvedRefsconditions for the HTTPRoutes created for the products. If you see anystatus: "False"conditions, that indicates an issue with the route that needs to be resolved before proceeding. -
To display the status of the deployed components, you can use k9s or issue the corresponding commands shown here:
-
Display the services (endpoints for connecting) by running
kubectl get service --selector=app.kubernetes.io/instance=demoNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE demo-pingaccess-admin ClusterIP 10.105.30.25 <none> 9090/TCP,9000/TCP 6m33s demo-pingaccess-admin-cluster ClusterIP None <none> <none> 6m33s demo-pingaccess-engine ClusterIP 10.100.1.136 <none> 3000/TCP 6m33s demo-pingauthorize ClusterIP 10.101.98.228 <none> 443/TCP 6m33s demo-pingauthorize-cluster ClusterIP None <none> 1636/TCP 6m33s demo-pingdataconsole ClusterIP 10.103.181.27 <none> 8443/TCP 6m33s demo-pingdirectory ClusterIP 10.106.174.162 <none> 443/TCP,389/TCP,636/TCP 6m33s demo-pingdirectory-cluster ClusterIP None <none> 1636/TCP 6m33s demo-pingfederate-admin ClusterIP 10.96.52.217 <none> 9999/TCP 6m33s demo-pingfederate-cluster ClusterIP None <none> 7600/TCP,7700/TCP 6m33s demo-pingfederate-engine ClusterIP 10.103.84.196 <none> 9031/TCP 6m33s -
To view the pods, run
kubectl get pods --selector=app.kubernetes.io/instance=demo- you will need to run this at intervals until all pods have started ( Running status):NAME READY STATUS RESTARTS AGE demo-pingaccess-admin-0 1/1 Running 0 7m7s demo-pingaccess-engine-59cfb85b9d-7l6tz 1/1 Running 0 7m7s demo-pingauthorize-5696dd6b67-hsxnw 1/1 Running 0 7m7s demo-pingdataconsole-56b75f9ffb-wld5k 1/1 Running 0 7m7s demo-pingdirectory-0 1/1 Running 0 7m7s demo-pingfederate-admin-67cdb47bb4-h88zr 1/1 Running 0 7m7s demo-pingfederate-engine-d9889b494-pdhv8 1/1 Running 0 7m7s -
To see the Gateway and HTTPRoutes you will use to access the products, run
kubectl get gateway,httproute -n pinghelm:NAME CLASS ADDRESS PROGRAMMED AGE gateway.gateway.networking.k8s.io/ping-devops-gateway traefik 192.168.65.3 True 8m NAME HOSTNAMES AGE httproute.gateway.networking.k8s.io/demo-pingaccess-admin ["demo-pingaccess-admin.pingdemo.example"] 6m httproute.gateway.networking.k8s.io/demo-pingaccess-engine ["demo-pingaccess-engine.pingdemo.example"] 6m httproute.gateway.networking.k8s.io/demo-pingauthorize ["demo-pingauthorize.pingdemo.example"] 6m httproute.gateway.networking.k8s.io/demo-pingdataconsole ["demo-pingdataconsole.pingdemo.example"] 6m httproute.gateway.networking.k8s.io/demo-pingdirectory ["demo-pingdirectory.pingdemo.example"] 6m httproute.gateway.networking.k8s.io/demo-pingfederate-admin ["demo-pingfederate-admin.pingdemo.example"] 6m httproute.gateway.networking.k8s.io/demo-pingfederate-engine ["demo-pingfederate-engine.pingdemo.example"] 6m -
To check route status conditions, run:
kubectl get gateway,httproute -n pinghelm kubectl get httproute -n pinghelm -o yaml | grep -E 'type: Accepted|type: ResolvedRefs|status: "False"'Expected output:
-
ping-devops-gatewayshowsProgrammed=True -
HTTPRoutes are created for enabled products
-
Each route shows
Accepted=TrueandResolvedRefs=True
-
-
To validate console endpoint reachability, run the following. If you had to use portforwarding or a tunnel, see the Gateway Access Caveats for Local Clusters section below and adjust the URLs accordingly:
for u in \ https://demo-pingfederate-admin.pingdemo.example/pingfederate/app \ https://demo-pingaccess-admin.pingdemo.example/ \ https://demo-pingdataconsole.pingdemo.example/console; do curl -k -sS -o /dev/null -w "%{http_code} ${u}\n" -L "$u" doneExample output:
200 https://demo-pingfederate-admin.pingdemo.example/pingfederate/app 200 https://demo-pingaccess-admin.pingdemo.example/ 200 https://demo-pingdataconsole.pingdemo.example/console -
To see everything tied to the helm release run
kubectl get all --selector=app.kubernetes.io/instance=demo:NAME READY STATUS RESTARTS AGE pod/demo-pingaccess-admin-0 1/1 Running 0 8m23s pod/demo-pingaccess-engine-59cfb85b9d-7l6tz 1/1 Running 0 8m23s pod/demo-pingauthorize-5696dd6b67-hsxnw 1/1 Running 0 8m23s pod/demo-pingdataconsole-56b75f9ffb-wld5k 1/1 Running 0 8m23s pod/demo-pingdirectory-0 1/1 Running 0 8m23s pod/demo-pingfederate-admin-67cdb47bb4-h88zr 1/1 Running 0 8m23s pod/demo-pingfederate-engine-d9889b494-pdhv8 1/1 Running 0 8m23sNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/demo-pingaccess-admin ClusterIP 10.105.30.25 <none> 9090/TCP,9000/TCP 8m23s service/demo-pingaccess-admin-cluster ClusterIP None <none> <none> 8m23s service/demo-pingaccess-engine ClusterIP 10.100.1.136 <none> 3000/TCP 8m23s service/demo-pingauthorize ClusterIP 10.101.98.228 <none> 443/TCP 8m23s service/demo-pingauthorize-cluster ClusterIP None <none> 1636/TCP 8m23s service/demo-pingdataconsole ClusterIP 10.103.181.27 <none> 8443/TCP 8m23s service/demo-pingdirectory ClusterIP 10.106.174.162 <none> 443/TCP,389/TCP,636/TCP 8m23s service/demo-pingdirectory-cluster ClusterIP None <none> 1636/TCP 8m23s service/demo-pingfederate-admin ClusterIP 10.96.52.217 <none> 9999/TCP 8m23s service/demo-pingfederate-cluster ClusterIP None <none> 7600/TCP,7700/TCP 8m23s service/demo-pingfederate-engine ClusterIP 10.103.84.196 <none> 9031/TCP 8m23sNAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/demo-pingaccess-engine 1/1 1 1 8m23s deployment.apps/demo-pingauthorize 1/1 1 1 8m23s deployment.apps/demo-pingdataconsole 1/1 1 1 8m23s deployment.apps/demo-pingfederate-admin 1/1 1 1 8m23s deployment.apps/demo-pingfederate-engine 1/1 1 1 8m23sNAME DESIRED CURRENT READY AGE replicaset.apps/demo-pingaccess-engine-59cfb85b9d 1 1 1 8m23s replicaset.apps/demo-pingauthorize-5696dd6b67 1 1 1 8m23s replicaset.apps/demo-pingdataconsole-56b75f9ffb 1 1 1 8m23s replicaset.apps/demo-pingfederate-admin-67cdb47bb4 1 1 1 8m23s replicaset.apps/demo-pingfederate-engine-d9889b494 1 1 1 8m23sNAME READY AGE statefulset.apps/demo-pingaccess-admin 1/1 8m23s statefulset.apps/demo-pingdirectory 1/1 8m23s -
To view logs, look at the logs for the deployment of the product in question. For example:
kubectl logs -f deployment/demo-pingfederate-admin-
This table contains the URLs and credentials to sign on to the management consoles for the products.
This example uses self-signed certificates that will have to be accepted in your browser or added to your keystore.
Product Connection Details -
URL: https://demo-pingfederate-admin.pingdemo.example/pingfederate/app
-
Username: administrator
-
Password: 2FederateM0re
-
Server: ldaps://demo-pingdirectory-cluster:1636
-
Username: administrator
-
Password: 2FederateM0re
-
Username: administrator
-
Password: 2FederateM0re
-
Server: ldaps://demo-pingauthorize-cluster:1636
-
Username: administrator
-
Password: 2FederateM0re
-
-
When you are finished, you can remove the demonstration components by running the uninstall command for helm:
helm uninstall demo
-
-
Next Steps
Now that you have deployed a set of our product images using the provided chart, you can move on to deployments using configurations that more closely reflect use cases to be explored. Refer to the helm examples) page for other typical deployments.
Gateway Access Caveats for Local Clusters
If your local cluster does not provide a working LoadBalancer external address for the Traefik service, use one of the following alternatives.
-
Option 1: NodePort service type for Traefik
helm upgrade --install traefik traefik/traefik \ --namespace traefik --create-namespace \ -f gateway/traefik-values.yaml \ -f gateway/traefik-values-nodeport.yamlIf using this option, provide port
30443in the URLs (for example,https://demo-pingfederate-admin.pingdemo.example:30443/pingfederate/app). -
Option 2: ClusterIP service type with local port-forwarding
helm upgrade --install traefik traefik/traefik \ --namespace traefik --create-namespace \ -f gateway/traefik-values.yaml \ -f gateway/traefik-values-clusterip.yaml # Non-privileged port-forward for local testing kubectl -n traefik port-forward svc/traefik 8443:443 # Or keep standard :443 URLs sudo kubectl -n traefik port-forward svc/traefik 443:443