Skip to main content

Installation

Use Pomerium as a first-class secure-by-default Ingress Controller. The Pomerium Ingress Controller enables workflows more native to Kubernetes environments, such as Git-Ops style actions based on pull requests. Dynamically provision routes from Ingress resources and set policy based on annotations. By defining routes as Ingress resources you can independently create and remove them from Pomerium's configuration.

System requirements

  • Kubernetes v1.19.0 or higher, Linux nodes, amd64 or arm64 CPU.
  • PostgreSQL 11 or higher.
  • A certificate management solution, such as cert-manager.

Deploy

kubectl apply -k github.com/pomerium/ingress-controller/config/default\?ref=0-33-0

The Pomerium Ingress Controller is now installed into your cluster.

note

You need complete Global Configuration for Pomerium to become fully operational, before you can configure Ingress.

Deployment variants

config/default is the standard install, but it is not the only one. Each path below is a complete kustomization you can apply directly in place of config/default, or reference as a base in your own kustomization.yaml.

PathDescription
config/defaultController and Pomerium core, CRDs, RBAC, and the bootstrap secrets job. The standard install.
config/default-no-crddefault without the CRD definitions, for when the CRDs are installed and owned separately — a dedicated Argo CD Application, Terraform, or a cluster admin — so the two do not compete over the schema.
config/gateway-apidefault plus a GatewayClass and the --experimental-gateway-api flag. See Gateway API.
config/clustered-databrokerReplaces the pomerium Deployment with a StatefulSet and adds a pomerium-headless Service, so the built-in databroker can run clustered across replicas.
config/clustered-databroker-no-crdThe clustered databroker variant, without the CRD definitions.
config/http3-eksdefault with the pomerium-proxy service configured for HTTP/3 on an AWS Network Load Balancer.
config/http3-gkedefault with the pomerium-proxy service configured for HTTP/3 on a GKE regional external load balancer.
config/sshdefault with the SSH listener enabled on port 4022.

For example, to install the Gateway API variant:

kubectl apply -k github.com/pomerium/ingress-controller/config/gateway-api\?ref=0-33-0
note

Always pin ?ref= to a version branch such as 0-33-0 rather than main, so that your installs are reproducible and you upgrade deliberately.

Metrics

Pomerium provides a comprehensive set of Prometheus style metrics. Assuming you are running a Prometheus Operator in your cluster, you may create the following resource to enable metrics collection.

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: pomerium
namespace: pomerium
spec:
endpoints:
- port: metrics
selector:
matchLabels:
app.kubernetes.io/name: pomerium

Advanced

You may adjust your base installation with kustomize, that is also accessible via the kubectl apply -k.

Base Installation Summary

The following resources are created:

  1. pomerium namespace.
  2. pomerium deployment.
  3. pomerium-proxy Service of type LoadBalancer, provisioning an external IP address, that listens on :80 and :443 ports. All HTTP requests are upgraded to HTTPS requests.
  4. pomerium-metrics Service of type ClusterIP, accessible from within the cluster, exposing /metrics Prometheus-style metrics endpoint.
  5. pomerium-gen-secrets one-time Job that generates an initial set of bootstrap secrets, and stores them into the bootstrap Secret.
  6. pomerium IngressClass, with the pomerium.io/ingress-controller controller.
  7. Pomerium CRD definitions.
  8. RBAC rules.

You may render this set of resources to a flat manifest — to inspect it, to review it in a pull request, or to feed a pipeline that does not run kustomize itself — with kustomize directly against the pomerium/ingress-controller repo:

kustomize build github.com/pomerium/ingress-controller/config/default\?ref=0-33-0

External-DNS

external-dns may be used to automatically update your DNS record for the Ingress. The below example adjusts the pomerium-proxy service that automatically serves your Authentication URL, so that it's external IP address is up to date in the DNS.

kustomization.yaml
resources:
- github.com/pomerium/ingress-controller/config/default?ref=0-33-0
patches:
- path: patch-proxy-external-dns.yaml
patch-proxy-external-dns.yaml
apiVersion: v1
kind: Service
metadata:
name: pomerium-proxy
namespace: pomerium
annotations:
external-dns.alpha.kubernetes.io/hostname: 'authenticate.localhost.pomerium.io'

Multiple Replicas

By default, Pomerium deploys with a single replica. You may scale Pomerium instances if necessary by adjusting the default deployment.

caution

You must configure storage persistence in order to use more then 1 replica of Pomerium.

kustomization.yaml
resources:
- github.com/pomerium/ingress-controller/config/default?ref=0-33-0
patches:
- path: patch-replicas.yaml
patch-replicas.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: pomerium
namespace: pomerium
spec:
replicas: 2

Set Pomerium as default IngressClass

An IngressClass may be designated as a default controller for the cluster.

kustomization.yaml
resources:
- github.com/pomerium/ingress-controller/config/default?ref=0-33-0
patches:
- path: patch-ingress-class.yaml
patch-ingress-class.yaml
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: pomerium
annotations:
ingressclass.kubernetes.io/is-default-class: 'true'

Multiple controllers

In some cases, you may need to run multiple controllers, see this community example.

Expose Envoy Admin interface

Make sure to always restrict access to the envoy admin interface ingress.

kustomization.yaml
resources:
- github.com/pomerium/ingress-controller/config/default?ref=0-33-0
- admin-service.yaml
- admin-ingress.yaml
patches:
- patch: |-
- op: add
path: /spec/template/spec/containers/0/args/-
value: "--debug-admin-addr=localhost:9901"
target:
kind: Deployment
name: pomerium
admin-service.yaml
apiVersion: v1
kind: Service
metadata:
name: envoy
spec:
type: ExternalName
externalName: 'localhost'
ports:
- protocol: TCP
name: admin
port: 9901
admin-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: envoy
spec:
ingressClassName: pomerium
rules:
- host: 'envoy.localhost.pomerium.io'
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: envoy
port:
name: admin

Runtime parameters

Some parameters are only set by default via command line arguments to the container.

caution

Normally, you would not need to adjust the container runtime parameters.

  • debug: enable debug logging.
  • server-addr: the address HTTPS server would bind to, :8443 by default.
  • http-redirect-addr: the address HTTP to HTTPS redirect server would bind to, :8080.
  • metrics-bind-address: host:port exposes Prometheus style metrics.
  • debug-admin-addr: localhost:port exposes Envoy admin interface.