Skip to main content

Kubernetes Quickstart

Deploy Pomerium Core with Kubernetes.

This quickstart guide uses our Hosted Authenticate Service so you don't need to configure an identity provider or authenticate service URL.

If you want to self-host, see the Self-Hosted Authenticate Service page.

Prerequisites

  • Install kubectl.
  • A Kubernetes provider.
    • A cluster, with your local kubectl authorized to interact with it.
  • A domain space. The steps below use *.localhost.pomerium.io as a placeholder value. We have set DNS records for this domain space to point to 127.0.0.1 (localhost), so you can use this domain space when testing Pomerium locally.
  • TLS certificates. If you don't yet have a production environment with trusted certificates, this page will cover using mkcert to create locally trusted certificates.

Certificates

This setup uses mkcert to generate certificates that are trusted by your local web browser for testing. If you already have a certificate solution, you can skip the steps below and move on to the next stage.

Install mkcert

  1. If you haven't, install mkcert following these GitHub instructions.

    Create a trusted root CA and confirm the presence and names of your local CA files:

    $ mkcert -install
    The local CA is already installed in the system trust store! 👍
    The local CA is already installed in the Firefox and/or Chrome/Chromium trust store! 👍

    $ ls "$(mkcert -CAROOT)"
    rootCA-key.pem rootCA.pem

    The output of mkcert -install may vary depending on your operating system.

  2. Generate a wildcard certificate and key for Pomerium to use:

mkcert "*.localhost.pomerium.io"

Install Pomerium

  1. Install Pomerium to your cluster:
kubectl apply -k github.com/pomerium/ingress-controller/config/default\?ref=v0.27.2

This will create all the components of Pomerium in the pomerium namespace, as well as a bootstrap secret:

namespace/pomerium created
customresourcedefinition.apiextensions.k8s.io/pomerium.ingress.pomerium.io created
serviceaccount/pomerium-controller created
serviceaccount/pomerium-gen-secrets created
clusterrole.rbac.authorization.k8s.io/pomerium-controller created
clusterrole.rbac.authorization.k8s.io/pomerium-gen-secrets created
clusterrolebinding.rbac.authorization.k8s.io/pomerium-controller created
clusterrolebinding.rbac.authorization.k8s.io/pomerium-gen-secrets created
service/pomerium-metrics created
service/pomerium-proxy created
deployment.apps/pomerium created
job.batch/pomerium-gen-secrets created
ingressclass.networking.k8s.io/pomerium created
  1. Add the certificate created earlier and key to the cluster as a Secret:
kubectl create secret tls pomerium-wildcard-tls --namespace=pomerium \
--cert=./_wildcard.localhost.pomerium.io.pem --key=./_wildcard.localhost.pomerium.io-key.pem
  1. Define the global Pomerium settings:
pomerium.yaml
apiVersion: ingress.pomerium.io/v1
kind: Pomerium
metadata:
name: global
spec:
secrets: pomerium/bootstrap
authenticate:
url: https://authenticate.pomerium.app
certificates:
- pomerium/pomerium-wildcard-tls
  1. Apply the global settings:
kubectl apply -f pomerium.yaml

The Pomerium Proxy service should now be running in your cluster:

kubectl describe pomerium
Name: global
Namespace:
Labels: <none>
Annotations: <none>
API Version: ingress.pomerium.io/v1
Kind: Pomerium
Metadata:
...

You should now be able to access https://authenticate.pomerium.app which, after signing in with our hosted IdP, should redirect you to the .pomerium endpoint.

Test Service

info

See the Verify examples repository to review additional example manifests.

  1. Define a test service. We'll use the Pomerium Verify app:

    verify-service.yaml
    apiVersion: v1
    kind: Service
    metadata:
    name: verify
    labels:
    app: verify
    service: verify
    spec:
    ports:
    - port: 8000
    targetPort: 8000
    name: http
    selector:
    app: pomerium-verify
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: verify
    spec:
    replicas: 1
    selector:
    matchLabels:
    app: pomerium-verify
    template:
    metadata:
    labels:
    app: pomerium-verify
    spec:
    containers:
    - image: docker.io/pomerium/verify
    imagePullPolicy: IfNotPresent
    name: httpbin
    ports:
    - containerPort: 8000
    protocol: TCP
    name: http

    Deploy it with kubectl apply -f verify-service.yaml

  2. Define an Ingress for the new service:

    verify-ingress.yaml
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
    name: verify
    annotations:
    ingress.pomerium.io/allowed_domains: |
    - example.com
    ingress.pomerium.io/pass_identity_headers: 'true'
    spec:
    ingressClassName: pomerium
    rules:
    - host: 'verify.localhost.pomerium.io'
    http:
    paths:
    - pathType: Prefix
    path: /
    backend:
    service:
    name: verify
    port:
    number: 8000

    Note that in Line 8, we include the annotation ingress.pomerium.io/pass_identity_headers, which provides a JWT to the Verify service.

    Deploy the service with kubectl apply -f verify-ingress.yaml, and visit the path in your browser:

    The top of the Pomerium Verify page

    tip

    Identity verification fails because we're using an untrusted test certificate. Updating your deployment with a trusted certificate solution like Let's Encrypt through cert-manager will resolve this error.

Next steps

Once Pomerium is configured, you should configure persistence. This prevents the loss of user sessions if containers are restarted, and supports deployments with multiple replicas. See our Kubernetes Reference page for more information on configuring Databroker storage.

Troubleshooting

Pomerium posts events to the Ingress and Pomerium objects, which may be inspected with the kubectl describe command:

kubectl describe pomerium

The Spec section provides details on the Pomerium configuration:

Spec:
Authenticate:
URL: https://authenticate.localhost.pomerium.io
Certificates: pomerium/pomerium-wildcard-tls
Identity Provider:
Provider: github
Secret: pomerium/idp
Secrets: pomerium/bootstrap

The Status section details what Ingresses are configured:

Status:
Ingress:
pomerium/verify:
Last Reconciled: 2022-07-13T16:38:39Z
Reconciled: true

And the Events section will provide useful debug information about recent updates to the configuration:

Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Updated 3m28s pomerium Pomerium configuration updated
Normal Updated 42s pomerium pomerium/verify: Pomerium configuration updated