zalando / zalando/postgres-operator
Leader-Service gets not properly resolved in DualStack Cluster
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 5.2k
- Forks
- 1.1k
- Avg merge
- 2d 16h
- Merged PRs (30d)
- 3
Description
This issue is a bit meddled between the assignment of pod ips from the CNI and the assignment of ClusterIPs within the service.
It all starts within the pods, which get a primary IPv4 address and an additional IPv6 address. However, status.podIp and in the postgres.yml the connect_address are set to the v4 address.
However, the service is automatically assigned an IPv6 address and created as SingleStack IPv6. As a consequence the service becomes this monstrosity:
$ kubectl describe service -n reqbaz reqbaz-postgres
Name: reqbaz-postgres
Namespace: reqbaz
Labels: application=spilo
database.selfnet.de/cluster=reqbaz-postgres
spilo-role=master
team=reqbaz
Annotations: <none>
Selector: <none>
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv6
IP: 2001:7c7:2100:406::9395
IPs: 2001:7c7:2100:406::9395
Port: postgresql 5432/TCP
TargetPort: 5432/TCP
Endpoints: 100.126.17.49:5432
Session Affinity: None
Events: <none>
This unfortunately causes every connection attempt (from services as well as the operator to end up in a refused connection.
time="2021-07-16T16:53:32Z" level=warning msg="could not connect to Postgres database: dial tcp [2001:7c7:2100:406::9395]:5432: connect: connection refused" cluster-name=reqbaz/reqbaz-postgres pkg=cluster worker=3
I have tried to fiddle with the respective code, but haven't figured out yet how the created endpoint gets associated with the service.
Otherwise I'd have attempted to just botch in an ip version detection on the endpoint and set the ServiceClass and IPFamly accordingly. The creation of the service and the endpoint however seem to be too disentangled to do so. Also I'm not sure how this would affect clusters without the feature gate.
Another possibility might be to provide a config option to define the IPFamilyPolicy, and the default family. But this takes a strong assumption on the cluster behaving deterministically and might have even weirder side effects.
Cluster Info
- Which image of the operator are you using? registry.opensource.zalan.do/acid/postgres-operator:v1.6.3
- Where do you run it - cloud or metal? Kubernetes or OpenShift? Self-homed VMs
- Are you running Postgres Operator in production? yes
- Type of issue? Bug report
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with postgres.yml and trace the paths that set status.podIp and connect_address, then follow how the operator creates the Service and its Endpoint. Reproduce the dual-stack output with kubectl describe service and the recorded connection error. Done means the service family and endpoint address are compatible, and operator and service connections reach PostgreSQL.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, kubernetes, postgresql
- Domain
- databases, infrastructure, networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 30/100