> ## Documentation Index
> Fetch the complete documentation index at: https://ngrok.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kubernetes ingress to GKE services with ngrok

> Learn how to use the ngrok Kubernetes Operator on Google Kubernetes Engine (GKE) to quickly add secure Kubernetes ingress to your apps or APIs.

This guide explains how to use the ngrok Kubernetes Operator on Google Kubernetes Engine (GKE) to add secure Kubernetes ingress to your apps or APIs.

The [ngrok Kubernetes Operator](https://github.com/ngrok/ngrok-operator) is the official open-source controller for adding public and secure ingress traffic to your k8s services.
It works with a Google Kubernetes Engine cluster to provide ingress to your services as long as the cluster has outbound access to the ngrok service.

## What you'll need

* A GKE cluster.
* An ngrok account.
* kubectl and Helm 3.0.0+ installed on your local workstation.
* The [ngrok Kubernetes Operator](/k8s/) installed on your cluster.
* A reserved domain from the ngrok [dashboard](https://dashboard.ngrok.com/domains) or [API](/api-reference/reserveddomains/list); this guide refers to it as `<NGROK_DOMAIN>`.

## Ensure `kubectl` can speak with your cluster

With a GKE cluster, authentication for `kubectl` uses a credential helper.
To deploy the ngrok Kubernetes Operator, ensure you can use the `gcloud` CLI and that the credential helper is available.

Ensure that you have the `gcloud` CLI installed and configured with your Google Cloud credentials.
You can confirm this works and you're authenticated correctly by running the following command:

```bash theme={null}
gcloud auth list
```

If you see your correct Google account listed, you should be all set.
If not, you can run `gcloud auth login` to authenticate with your Google account.

Next, ensure that the credential helper is available.
Run the following command to confirm that the credential helper is available:

```bash theme={null}
gcloud components install gke-gcloud-auth-plugin
```

Finally, add the cluster to your KUBECONFIG:

```bash theme={null}
gcloud container clusters get-credentials --region <cluster-region> --project <cluster-project> <cluster-name>
```

## Install the ngrok Kubernetes Operator

Now install the ngrok Kubernetes Operator to provide ingress to your services.

See the [Operator installation doc](/getting-started/kubernetes/ingress/) for details on using Helm with your ngrok credentials.

## Install a sample application

Create a manifest file (for example `ngrok-manifest.yaml`) with the following contents.
This deploys the [tinyllama](https://github.com/ngrok-samples/tinyllama) demo LLM application.
Replace the `NGROK_DOMAIN` on line 45 with your reserved domain (the URL you'll use to access your service).
On a free account, use a static subdomain; on a paid account, you can use a custom domain or a subdomain of `ngrok.app` or `ngrok.dev`.

<Tip>
  The first section creates the tinyllama demo app Service and Deployment; the highlighted section configures the ngrok Kubernetes Operator Ingress.
</Tip>

```yaml showLineNumbers theme={null}
apiVersion: v1
kind: Service
metadata:
  name: tinyllama
spec:
  ports:
    - name: http
      port: 80
      targetPort: 8080
  selector:
    app: tinyllama
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: tinyllama
spec:
  replicas: 1
  selector:
    matchLabels:
      app: tinyllama
  template:
    metadata:
      labels:
        app: tinyllama
    spec:
      containers:
        - name: tinyllama
          image: ghcr.io/ngrok-samples/tinyllama:main
          ports:
            - name: http
              containerPort: 8080
---
# highlight-start
# ngrok Kubernetes Operator Configuration
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tinyllama-ingress
  namespace: ngrok-operator
spec:
  ingressClassName: ngrok
  rules:
    - host: <NGROK_DOMAIN>
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: tinyllama
                port:
                  number: 80
# highlight-end
```

Apply the manifest file to your k8s cluster.

```bash theme={null}
kubectl apply -f ngrok-manifest.yaml
```

<Note>
  **Troubleshooting:** If you get an error when applying the manifest, double-check that you've updated the `NGROK_DOMAIN` value and try again.
</Note>

Access your ingress URL using the subdomain you chose in the manifest (for example, `https://my-awesome-k8s-cluster.ngrok.app`) to confirm the tinyllama app is accessible from the internet.

## Add authentication to your app

With the [Traffic Policy system](/traffic-policy/) and the [`oauth` action](/traffic-policy/actions/oauth), ngrok manages OAuth protection entirely at ngrok.
This means you don't need to add any additional services to your cluster, nor alter any routes, to ensure ngrok's network authenticates and authorizes all requests before allowing ingress and access to your endpoint.

To enable the `oauth` action, you'll create a new `NgrokTrafficPolicy` custom resource and apply it to your entire `Ingress` with an annotation.
You can also apply the policy to just a specific backend or as the default backend for an `Ingress`—see the documentation on using the [Operator with Ingresses](/k8s/guides/using-ingresses/#using-ngroktrafficpolicy-with-ingress).

Edit your existing `ngrok-manifest.yaml` manifest with the following, leaving the `Service` and `Deployment` as they were.
Note the new `annotations` field and the `NgrokTrafficPolicy` CR.

```yaml theme={null}
...
---
# Configuration for ngrok's Kubernetes Operator
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tinyllama-ingress
  namespace: default
  annotations:
    k8s.ngrok.com/traffic-policy: oauth
spec:
  ingressClassName: ngrok
  rules:
    - host: <NGROK_DOMAIN>
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: tinyllama
                port:
                  number: 80
---
# Traffic Policy configuration for OAuth
apiVersion: ngrok.k8s.ngrok.com/v1alpha1
kind: NgrokTrafficPolicy
metadata:
  name: oauth
  namespace: default
spec:
  policy:
    on_http_request:
      - type: oauth
        config:
          provider: google
```

* Re-apply your `ngrok-manifest.yaml` configuration.

  ```bash theme={null}
  kubectl apply -f ngrok-manifest.yaml
  ```

* When you open your demo app again, you'll be asked to log in via Google.
  That's a start, but what if you want to authenticate only yourself or colleagues?

* Use [expressions](/traffic-policy/how-it-works#expressions) and [CEL interpolation](/traffic-policy/how-it-works#cel-interpolation) to filter out and reject OAuth logins that don't contain `example.com`.
  Update the `NgrokTrafficPolicy` portion of your manifest after changing `example.com` to your domain.

  ```yaml theme={null}
  # Traffic Policy configuration for OAuth
  apiVersion: ngrok.k8s.ngrok.com/v1alpha1
  kind: NgrokTrafficPolicy
  metadata:
    name: oauth
    namespace: default
  spec:
    policy:
      on_http_request:
        - type: oauth
          config:
            provider: google
        - expressions:
            - "!actions.ngrok.oauth.identity.email.endsWith('@example.com')"
          actions:
            - type: custom-response
              config:
                body: Hey, no auth for you ${actions.ngrok.oauth.identity.name}!
                status_code: 400
  ```

* Check out your deployed tinyllama app once again.
  If you log in with an email that doesn't match your domain, ngrok rejects your request.
