Setup and Installation: Kubernetes (Helm)
The Testsigma Tunnel Client creates a secure connection between your Kubernetes cluster and the Testsigma platform. That connection lets you run automated tests against applications deployed in private networks or behind firewalls, without exposing those applications to the public internet.
This article discusses how to install the tunnel client with the official Helm chart, configure it, and manage it over time.
Prerequisites
- A Kubernetes cluster running 1.21 or later.
- Helm 3.8 or later, which is required for OCI chart support.
kubectlconfigured with access to the cluster.- An authentication key from Settings > Tunnels in the Testsigma application.
- Outbound access from the cluster to your Testsigma address and to the registry that serves the chart and image. The tunnel accepts no inbound connections, so no ingress or firewall change is needed.
Also refer to the documentation on key components for background on how the tunnel fits into a test run.
Where the Chart Is Published
The same chart is available from two registries. Both are public and need no credentials.
| Registry | Chart location | Container image |
|---|---|---|
| Azure Container Registry | oci://testsigmaregistry.azurecr.io/charts/testsigma-tunnel |
Mirrored into the same registry |
| GitHub Container Registry | oci://ghcr.io/testsigmainc/charts/testsigma-tunnel |
Pulled from Docker Hub |
Choose based on what your cluster is allowed to reach:
- Use Azure Container Registry with
global.imageRegistrywhen egress is restricted, because the chart and the image then come from one host. - Use GitHub Container Registry when your cluster can already reach Docker Hub. The image is not mirrored there, so
global.imageRegistrydoes not apply.
The examples in this article use Azure Container Registry. To use GitHub Container Registry instead, swap the chart address and drop the global.imageRegistry flag.
How the Tunnel Runs
The chart creates the following resources:
| Resource | Description |
|---|---|
| StatefulSet | Runs the tunnel client pods, one at a time, using the OrderedReady pod management policy. |
| Secret | Holds the authentication key, unless you supply your own. |
| Service | A headless Service that gives the StatefulSet stable pod identities. It routes no traffic. |
All replicas share a single tunnel name. The first pod registers the tunnel with Testsigma and the rest join that registration, which is why they start in sequence rather than together. Starting them simultaneously would have several pods racing to register the same name.
The client keeps nothing that has to survive a restart. Its mTLS certificates are fetched again during registration each time it starts, so there is no persistent volume to manage.
The pod runs as a non-root user from a distroless image and needs no elevated privileges, so it satisfies the restricted Pod Security Standard as shipped.
Install the Tunnel
- In the Testsigma application, navigate to Settings > Tunnels and copy the authentication key.
-
Create a namespace and store the key in a secret. Write the key to a temporary file rather than passing it on the command line, so it does not end up in your shell history or in the process list:
kubectl create namespace testsigma umask 077 && cat > tunnel-key.txt # paste the key, then press Ctrl+D kubectl -n testsigma create secret generic testsigma-tunnel-auth \ --from-file=KEY=./tunnel-key.txt rm tunnel-key.txtIf you manage secrets with a tool such as External Secrets Operator or Sealed Secrets, create
testsigma-tunnel-auththrough that instead. -
Install the chart:
helm install ts-tunnel oci://testsigmaregistry.azurecr.io/charts/testsigma-tunnel \ --version 0.1.0 -n testsigma \ --set global.imageRegistry=testsigmaregistry.azurecr.io \ --set tunnel.auth.existingSecret=testsigma-tunnel-auth \ --set tunnel.tunnelName=my-tunnel -
Wait for the pod to become ready:
kubectl -n testsigma rollout status statefulset/ts-tunnel-testsigma-tunnel - The tunnel appears under Settings > Tunnels in the Testsigma application once it registers.
To install the same chart from GitHub Container Registry, use this in place of step 3:
helm install ts-tunnel oci://ghcr.io/testsigmainc/charts/testsigma-tunnel \
--version 0.1.0 -n testsigma \
--set tunnel.auth.existingSecret=testsigma-tunnel-auth \
--set tunnel.tunnelName=my-tunnelSet tunnel.tunnelName to something recognisable. Left empty, the client generates a random name at startup and it changes every time the pod restarts, which makes the tunnel hard to identify in the Testsigma UI.
Select Your Testsigma Region
The image is built against a fixed Testsigma address, so the three regional builds are different images rather than copies. Set tunnel.region to match the address you sign in to:
| Sign-in address | tunnel.region |
|---|---|
| app.testsigma.com | us (default) |
| app-eu.testsigma.com | eu |
| app-in.testsigma.com | in |
Add the flag to the install command:
--set tunnel.region=euIf the tunnel is already installed, apply it with an upgrade:
helm upgrade ts-tunnel oci://testsigmaregistry.azurecr.io/charts/testsigma-tunnel \
--version 0.1.0 -n testsigma --reuse-values \
--set tunnel.region=euIf the region does not match your account, the pod starts but cannot register, because it contacts the wrong Testsigma address.
Verify the Installation
Confirm the cluster can reach Testsigma, which is the one thing the tunnel cannot work without:
helm test ts-tunnel -n testsigmaThen check the client registered:
kubectl -n testsigma logs ts-tunnel-testsigma-tunnel-0 -fLook for a message confirming the tunnel registered. Finally, confirm it is listed under Settings > Tunnels in the Testsigma application and run a test through it.
The chart defines no liveness or readiness probe. The client listens on no port, and the image contains no shell, so there is nothing to probe. If the process exits, the container is restarted automatically.
Configuration Reference
Pass these with --set, or collect them in a values file and use -f values.yaml. To see every available setting:
helm show values oci://testsigmaregistry.azurecr.io/charts/testsigma-tunnel --version 0.1.0| Setting | Default | Description |
|---|---|---|
tunnel.region |
us |
Testsigma region: us, eu, or in |
tunnel.auth.existingSecret |
Secret holding the authentication key | |
tunnel.auth.key |
"" |
The key inline, for a quick trial instead of a secret |
tunnel.tunnelName |
"" |
Name shown in Testsigma. Empty means randomly generated |
tunnel.replicaCount |
1 |
Replicas sharing one tunnel. 0 stops it without uninstalling |
tunnel.verbose |
false |
Debug logging |
tunnel.delegateSslValidation |
false |
Accept certificates from an SSL inspection appliance |
tunnel.image.tag |
latest |
Pin to a release such as 2.1.0 for a fixed baseline |
tunnel.resources |
500m and 256Mi to 2 CPU and 1Gi | |
tunnel.extraArgs |
[] |
Extra command-line flags, which outrank the settings above |
global.imageRegistry |
"" |
Pull the chart's images from one registry |
proxy.enabled |
false |
Set with proxy.url |
networkPolicy.enabled |
false |
Restricts egress to DNS and 443. Add rules for your own applications first |
imagePullSecrets |
[] |
For registries that require authentication |
Route Traffic Through a Proxy
If the cluster reaches the internet through a proxy, the client uses it for both registration and the tunnel itself:
--set proxy.enabled=true \
--set proxy.url=http://proxy.internal.example.com:8080Accept an SSL Inspection Certificate
If your network re-signs TLS connections with its own certificate authority:
--set tunnel.delegateSslValidation=trueScale the Tunnel
Raise tunnel.replicaCount to handle more concurrent test traffic. Pods start one at a time, the first registers the tunnel, and the rest join it:
kubectl -n testsigma scale statefulset/ts-tunnel-testsigma-tunnel --replicas=3To make the change permanent, set it through Helm:
helm upgrade ts-tunnel oci://testsigmaregistry.azurecr.io/charts/testsigma-tunnel \
--version 0.1.0 -n testsigma --reuse-values \
--set tunnel.replicaCount=3To stop the tunnel without uninstalling, scale to zero:
kubectl -n testsigma scale statefulset/ts-tunnel-testsigma-tunnel --replicas=0Scaling with kubectl is temporary. The replica count reverts to the Helm value on the next helm upgrade.
Upgrade and Uninstall
The client deregisters the tunnel by name when it shuts down. With a single replica that is harmless, because the replacement pod registers again. With more than one replica it matters: replacing the first pod deregisters the tunnel that all of them share.
With one replica, upgrade directly:
helm upgrade ts-tunnel oci://testsigmaregistry.azurecr.io/charts/testsigma-tunnel \
--version <NEW_VERSION> -n testsigma --reuse-valuesWith more than one replica, scale to zero first:
kubectl -n testsigma scale statefulset/ts-tunnel-testsigma-tunnel --replicas=0
kubectl -n testsigma get pods -l app.kubernetes.io/name=testsigma-tunnel -w # wait for all to terminate
helm upgrade ts-tunnel oci://testsigmaregistry.azurecr.io/charts/testsigma-tunnel \
--version <NEW_VERSION> -n testsigma --reuse-values
kubectl -n testsigma scale statefulset/ts-tunnel-testsigma-tunnel --replicas=3To remove the release:
helm uninstall ts-tunnel -n testsigmaNothing is left behind, since the chart creates no persistent volume.
Rotate an Authentication Key
- Obtain a new key from Settings > Tunnels.
-
Update the secret:
kubectl -n testsigma create secret generic testsigma-tunnel-auth \ --from-file=KEY=./tunnel-key.txt --dry-run=client -o yaml | kubectl apply -f - -
Restart the tunnel so it picks up the new key:
kubectl -n testsigma rollout restart statefulset/ts-tunnel-testsigma-tunnel
Install Using Argo CD
Argo CD does not detect OCI registries automatically, so register the repository first.
-
Navigate to Settings > Repositories > CONNECT REPO > VIA HTTPS and enter:
Field Value Type helmName testsigma-chartsRepository URL testsigmaregistry.azurecr.io/charts, orghcr.io/testsigmainc/chartsEnable OCI Selected Username and Password Leave empty - Create the key secret in the destination namespace, as shown in Install the Tunnel.
-
Create the application:
apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: testsigma-tunnel namespace: argocd spec: project: default source: repoURL: testsigmaregistry.azurecr.io/charts chart: testsigma-tunnel targetRevision: 0.1.0 helm: releaseName: ts-tunnel values: | tests: enabled: false global: imageRegistry: testsigmaregistry.azurecr.io tunnel: region: us tunnelName: my-tunnel auth: existingSecret: testsigma-tunnel-auth destination: server: https://kubernetes.default.svc namespace: testsigma syncPolicy: syncOptions: - CreateNamespace=true -
Sync the application.
CreateNamespace=truechanges how a sync behaves, it does not start one, so a newly created application stays OutOfSync until you trigger it. In the UI, open the application and select SYNC, or from the CLI:argocd app sync testsigma-tunnel
Points to note:
repoURLholds the registry path only. The chart name belongs inchart, and there is nooci://prefix.targetRevisionis the chart version, not the tunnel client version.- Argo CD does not run Helm test hooks, so set
tests.enabledtofalseand verify manually.- Manage the release with whichever tool installed it.
helm upgradeandhelm uninstalldo not apply to an application deployed by Argo CD.
Troubleshoot
| Symptom | Cause and resolution |
|---|---|
Pod stays Pending |
No node has enough free CPU or memory. Run kubectl -n testsigma describe pod <pod>. |
ImagePullBackOff |
Confirm tunnel.region, and remove global.imageRegistry to pull from Docker Hub. If you pinned a per-architecture tag such as amd64-latest, the pod fails on nodes of any other architecture; use latest or a version instead. |
CreateContainerConfigError |
The secret named in tunnel.auth.existingSecret does not exist in that namespace. |
| Pod restarts repeatedly | Usually an invalid or expired key. Check kubectl -n testsigma logs <pod> and obtain a fresh key from Settings > Tunnels. |
| Pod runs but no tunnel appears in Testsigma | Usually the wrong tunnel.region, or a key issued for a different region. Check the logs. |
helm test fails |
The cluster cannot reach your Testsigma address. Check egress rules, and set proxy.enabled with proxy.url if a proxy is required. |
| Connection timeouts during a test | The tunnel reached Testsigma but cannot reach your application. If networkPolicy.enabled is on, add egress rules for the application through networkPolicy.extraEgress. |
| SSL errors during a test | The application uses a certificate the client does not trust, or an inspection appliance re-signs traffic. Set tunnel.delegateSslValidation=true. |
If the issue persists, collect the pod details and logs and contact Testsigma support:
kubectl -n testsigma describe statefulset ts-tunnel-testsigma-tunnel
kubectl -n testsigma logs ts-tunnel-testsigma-tunnel-0 --tail=200