TLS with cert-manager
On Kubernetes, Octopus can terminate TLS using certificates sourced from your
Gateway listeners' TLS Secrets — selected per connection by SNI and
hot-reloaded as they rotate. Pair that with cert-manager: point a Certificate
at the Secret a listener references, and when cert-manager renews it the operator
swaps in the new certificate without a pod restart. This is the operator path
described in Kubernetes TLS & cert-manager;
unlike the file-based listener, it truly hot-swaps.
Prerequisites: the Octopus operator running (see
Route with the Gateway API), the
Gateway API CRDs installed, and
cert-manager installed with a working Issuer or
ClusterIssuer.
Enable operator TLS termination01
Turn on kubernetes.terminate_tls. With it enabled the listen port serves
HTTPS (SNI), not plain HTTP.
gateway:
listen: "0.0.0.0:8443"
kubernetes:
enabled: true
terminate_tls: trueterminate_tls is ignored if static gateway.tls is configured — file-based
TLS takes precedence. Use one or the other, not both. The operator also needs
RBAC to read Secrets and ReferenceGrants; the Helm chart grants this.
Reference a TLS Secret from an HTTPS listener02
On a terminating HTTPS listener, name the Secret that will hold the cert/key via
tls.certificateRefs. The listener's hostname becomes the SNI key for that
certificate; a listener with no hostname provides the default (catch-all) cert.
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: octopus-gateway
namespace: infra
spec:
gatewayClassName: octopus
listeners:
- name: api
hostname: api.example.com
port: 443
protocol: HTTPS
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: api-tls # kubernetes.io/tls Secret in this namespaceOctopus reads tls.crt / tls.key from a kubernetes.io/tls Secret. A
Passthrough listener contributes no certificate, and plain HTTP listeners are
ignored. See Sourcing certificates from listeners.
Issue the certificate with cert-manager03
Create a Certificate whose secretName is exactly the Secret the listener
references. cert-manager writes the cert/key into that Secret and renews it on
schedule.
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: api-tls
namespace: infra
spec:
secretName: api-tls # matches the listener's certificateRefs[].name
dnsNames:
- api.example.com
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
group: cert-manager.iocert-manager resources belong to the cert-manager.io API group and are
reconciled by cert-manager, not Octopus. Octopus only consumes the resulting
kubernetes.io/tls Secret named by the listener.
(If cross-namespace) grant Secret access04
If the Secret lives in a different namespace from the Gateway, the listener
references it via certificateRefs[].namespace, and you must allow it with a
ReferenceGrant in the Secret's namespace — from the Gateway's namespace to
kind: Secret. Same-namespace refs (the step above) need no grant.
apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
name: allow-gateway-certs
namespace: certs # lives in the SECRET's namespace
spec:
from:
- group: gateway.networking.k8s.io
kind: Gateway
namespace: infra # the Gateway's namespace
to:
- group: ""
kind: SecretWithout a matching grant the cert is denied (not loaded). See the ReferenceGrant model.
Apply and verify05
kubectl apply -f gateway.yaml
kubectl apply -f certificate.yaml
# Wait for cert-manager to populate the Secret
kubectl -n infra get certificate api-tls
kubectl -n infra get secret api-tls
# Verify TLS termination + SNI selection
curl -iv https://api.example.com/ --resolve api.example.com:443:<gateway-ip>A certificate is loaded only once its Secret actually exists; when cert-manager renews and rewrites the Secret, the operator's watch fires and the new certificate is hot-swapped into the live acceptor — no restart, and connections accepted afterward use the new cert.
See also06
Kubernetes TLS & cert-manager — sourcing, SNI selection, and hot reload.
TLS — the two TLS layers and the file-based vs. operator difference.
Gateway API — listeners and the ReferenceGrant model.
Route with the Gateway API — enabling the operator and routing.