Kubernetes Quickstart
This quick-start will show you how to deploy Pomerium with Kubernetes.
Prerequisites
- Install kubectl.
- A Kubernetes provider.
- A cluster, with your local
kubectl
authorized to interact with it.
- A cluster, with your local
- A configured identity provider.
- 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 to127.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
After installing mkcert, 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.pemThe output of
mkcert -install
may vary depending on your operating system.Generate a wildcard certificate and key for Pomerium to use:
mkcert "*.localhost.pomerium.io"
Install Pomerium
- Install Pomerium to your cluster:
kubectl apply -f https://raw.githubusercontent.com/pomerium/ingress-controller/v0.20.0/deployment.yaml
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
- 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
- Define a Kubernetes secret to hold identity provider (IdP) credentials:
apiVersion: v1
kind: Secret
metadata:
name: idp
namespace: pomerium
type: Opaque
stringData:
client_id: ${IDP_PROVIDED_CLIENT_ID}
client_secret: ${IDP_PROVIDED_CLIENT_SECRET}
The data required in this secret will depend on your identity provider. See the Kubernetes Reference page for all available keys, and cross-reference it with the requirements of your IdP.
- Provide this secret to the cluster:
kubectl apply -f idp-secret.yaml
You can confirm with kubectl get secrets --namespace pomerium
:
NAME TYPE DATA AGE
bootstrap Opaque 3 99m
default-token-whpnw kubernetes.io/service-account-token 3 149m
idp Opaque 2 5s
pomerium-controller-token-cckv5 kubernetes.io/service-account-token 3 99m
pomerium-gen-secrets-token-4pdkd kubernetes.io/service-account-token 3 99m
- Define the global Pomerium settings:
apiVersion: ingress.pomerium.io/v1
kind: Pomerium
metadata:
name: global
spec:
secrets: pomerium/bootstrap
authenticate:
url: https://authenticate.localhost.pomerium.io
identityProvider:
provider: ${YOUR_IdP}
secret: pomerium/idp
certificates:
- pomerium/pomerium-wildcard-tls
- 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.localhost.pomerium.io/
which, after signing in with your IdP, should redirect you to the .pomerium
endpoint.
Test Service
- Define a test service. We'll use the Pomerium Verify app:
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
- Define an Ingress for the new service:
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 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:
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