Skip to content

fix: detect silent k8s-dqlite datastore failures in inspect - #5532

Open
bugra-gokcek wants to merge 1 commit into
canonical:masterfrom
bugra-gokcek:fix/5524-dqlite-silent-failure
Open

fix: detect silent k8s-dqlite datastore failures in inspect#5532
bugra-gokcek wants to merge 1 commit into
canonical:masterfrom
bugra-gokcek:fix/5524-dqlite-silent-failure

Conversation

@bugra-gokcek

Copy link
Copy Markdown

Summary

Addresses #5524. microk8s inspect gave no actionable hint when the
k8s-dqlite datastore could not start, because the daemon wrapper
(run-k8s-dqlite-with-args) exits before the binary can log its fatal
error. The reporter hit two variants of this silent failure:

  1. Missing TLS keypair — wiping the backend directory
    (var/kubernetes/backend/) also removes cluster.crt / cluster.key,
    so dqlite aborts on start with
    failed to load keypair from cluster.crt and cluster.key while
    microk8s status / microk8s inspect show nothing wrong.
  2. Stale raft node address after a hostname rename — the stored node
    address still pointed at the old hostname, so dqlite looped with
    no available dqlite leader server found. The existing uppercase-hostname
    warning disappears once the host is renamed to lowercase, leaving nothing
    pointing at the stale address.

As the reporter notes, the real gap is the silent inspect, so this PR makes
both conditions visible.

Changes

scripts/inspect.sh: new check_dqlite step, run on control-plane (non-worker)
HA nodes alongside the existing dqlite inspection:

  • FAIL if cluster.crt or cluster.key is missing from the backend
    directory, with a short recovery hint (sets a non-zero return code, like the
    other FAIL checks).
  • WARNING if the node Address in info.yaml is a hostname that no longer
    matches the current hostname.

The address check intentionally ignores IPv4/IPv6 literals, so the default
single-node (127.0.0.1) deployment and IP-based clusters never trigger a
false positive — info.yaml always stores this node's own address, so a
mismatch genuinely indicates a stale name.

Testing

scripts/inspect.sh has no unit-test harness (it is a pure bash diagnostic
script, consistent with how previous inspect checks were added). I verified the
new logic in isolation across these cases:

Scenario Result
single-node default (127.0.0.1:19001) no output
clustered IPv4 (10.0.0.5:19001) no output
bracketed IPv6 ([fd00::5]:19001) no output
address hostname matches current host no output
stale hostname (oldname vs newname) WARNING
uppercase rename (MyHost vs myhost) WARNING
missing cert/key (backend wiped) FAIL, return code 1
missing cert/key + no info.yaml FAIL, return code 1

bash -n scripts/inspect.sh and codespell (the lint config used in CI) both
pass.

`microk8s inspect` previously gave no hint when the k8s-dqlite datastore
could not start: the daemon wrapper exits before the binary can log a
fatal error, so neither `microk8s status` nor the inspection report
pointed at the cause. Two common failure modes were invisible:

- a missing TLS keypair in the backend directory (for example after the
  backend dir was wiped), which aborts dqlite on start with
  "failed to load keypair from cluster.crt and cluster.key"
- a stale raft node address still pointing at the old hostname after a
  rename, which loops with "no available dqlite leader server found"

Add a `check_dqlite` step to the inspect report (control-plane nodes
only) that FAILs on a missing cert/key and WARNs when the stored node
address no longer matches the current hostname, so these failures are no
longer silent.

Fixes canonical#5524
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant