Cluster stuck in updating: pods missing a role label
Symptoms
- The Cluster resource stays in phase
Updatingafter all pods areRunningand ready. - One or more pods have no value in the
kubeblocks.io/rolelabel while their peers showprimaryorsecondary:
Diagnosis
-
Confirm the database itself is healthy. For a sharded cluster, each shard
-0pod should reportmasterandcluster_state:ok:For standalone, replicated, or Sentinel topologies, use thefalkordbcontainer name instead offalkordb-cluster. -
Check that the role probe ran on the affected pod. The kbagent sidecar logs the probed role:
A healthy probe logs
"output": "primary"(orsecondary). -
Check the KubeBlocks controller for a failed label update:
The signature of this case is an event reconcile error such as:
Root cause
The kbagent role probe reports the role once and re-emits it only when the role changes. If the KubeBlocks event controller loses an optimistic-concurrency conflict while writing thekubeblocks.io/role pod label (common during post-provision churn, when several controllers update the same pod), the write is dropped and never retried. The database is healthy; only the label is missing, which keeps the Cluster in Updating.
Fix
Apply the label the controller failed to write, matching the actual role reported by the database in the diagnosis step:Running as soon as all pods carry a role label:
Only set the label to the role the database actually reports. Labeling a replica as primary misroutes client traffic sent through the read-write Service.
Pods cannot reach the Kubernetes API server
Symptoms
- The Admin Server logs Kubernetes client errors and reports the cluster as unavailable, or the KubeBlocks manager crash-loops.
- The failure is a TLS or connection error against an IP address rather than a hostname —
tls: handshake failure,EOF,connection reset by peer, ordial tcp 172.25.0.1:443: i/o timeout. - The address in the error matches the
kubernetesService ClusterIP in thedefaultnamespace:
Root cause
The kubelet injectsKUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT into every container, pointing at that ClusterIP, and every in-cluster client builds its API URL from them. Two cluster configurations break that route:
- The ClusterIP’s only endpoint is a managed or public API endpoint that requires SNI. A client connecting by IP sends no SNI, so the endpoint cannot select a certificate and the handshake is terminated.
- A firewall rejects traffic to the ClusterIP.
Fix
Point the clients at a DNS name instead. A container’s own environment entry takes precedence over the kubelet-injected one.helm directly, use examples/values-apiserver-dns.yaml:
ComponentDefinition.spec.vars, so KubeBlocks injects them into every container of a database pod, including the kbagent sidecar. Check one directly:
The host must appear in a Subject Alternative Name on the API server’s serving certificate. If it does not, clients fail certificate verification (x509: certificate is valid for ...) instead of connecting.kubernetes.default.svc.cluster.localis always covered; confirm any other name before using it.