K8SPG-1149: expose.externalDNS - #1812
Conversation
commit: 09e4007 |
| // +kubebuilder:validation:MinLength=1 | ||
| // +kubebuilder:validation:MaxLength=253 | ||
| // +kubebuilder:validation:Pattern=`^[a-z0-9]([-a-z0-9]{0,61}[a-z0-9])?(\.[a-z0-9]([-a-z0-9]{0,61}[a-z0-9])?)*$` | ||
| Hostname string `json:"hostname"` |
There was a problem hiding this comment.
In PSMDB operator, we have two fields: domain and prefix. we build hostname like: prefix-component-podIndex.domain. should we do the same here?
There was a problem hiding this comment.
Good comparison, and I looked at that before settling on a flat list. it doesn’t carry over cleanly because:
The addressing models differ. A MongoDB replica set is member-addressed: every pod is individually reachable, and the operator has to know each member’s hostname anyway because it writes those names into the replica set configuration. prefix-component-index.domain is a natural fit there because the names are structured and the operator is already generating them for a second purpose. PostgreSQL under Patroni isn’t member-addressed — clients connect through the primary/replica services, not to cluster1-instance1-abcd-0. The externally meaningful surface is one or two service names, not N pod names, so there’s much less for a template to generate.
Problem:
Exposing a cluster through external-dns required hand-writing the
external-dns.alpha.kubernetes.io/*annotations intoexpose.annotations, and even thenthe published hostname was never added to the server certificate SANs - so clients
connecting through the external name with
sslmode=verify-fullfailed on a hostnamemismatch.
Cause:
The operator had no notion of an external hostname.
expose.annotationsis an opaquepassthrough, so the operator could not tell an external-dns hostname it should trust from
any other annotation, and the certificate SANs were built purely from in-cluster service
DNS names.
Solution:
Add
expose.externalDNS(hostname, optionalttl) to everyServiceExpose- primary,replica, pgBouncer and logical replicas. The operator renders it into the external-dns
annotations and stamps
percona.com/external-dns-managed: "true"to record ownership.That marker is what makes the rest safe:
pgBouncer certificate, both the internal PKI and cert-manager paths), so
sslmode=verify-fullworks against the external name.externalDNSis removed from the CR, sohostnames a user wrote by hand into
expose.annotationsare never touched and existingclusters do not get their certificates silently reissued.
prunes on its own; the logical-replica service uses
CreateOrUpdate, so it clears staleannotations explicitly - including when the whole
exposeblock is dropped.The hostnames are appended after the in-cluster names so the FQDN used as the common name
is unchanged.
CHECKLIST
Jira
Needs Doc) and QA (Needs QA)?Tests
Config/Logging/Testability