Skip to content

feat(helm): add HStore deployment chart - #3132

Draft
bitflicker64 wants to merge 4 commits into
apache:masterfrom
bitflicker64:feat/hstore-helm-chart
Draft

feat(helm): add HStore deployment chart#3132
bitflicker64 wants to merge 4 commits into
apache:masterfrom
bitflicker64:feat/hstore-helm-chart

Conversation

@bitflicker64

@bitflicker64 bitflicker64 commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Purpose of the PR

Add an official Helm installation path for the distributed HugeGraph HStore
topology on Kubernetes. The chart packages the PD, Store, and Server startup
contract that otherwise has to be reconstructed by each operator.

This PR stays a draft until its remaining prerequisite PRs land and the open
item under "Known gaps before this leaves draft" is fixed and retested.

Main Changes

  • Add the first helm/hugegraph chart with chart version 0.1.0:
    • PD and Store StatefulSets with persistent storage and headless Services.
    • Server Deployment and client Service.
    • PD, Store, and optional Server PodDisruptionBudgets.
    • Optional Server HPA and Ingress.
    • A helm test connection hook.
  • Add values.schema.json with render-time validation for replica counts,
    storage, PDBs, HPA, authentication, Services, and other value contracts.
  • Add default 3+3+3, single-node, and production-oriented values presets.
  • Add scheduling controls, per-component ServiceAccounts with token mounting
    disabled by default, configurable pod security contexts, hardened container
    security defaults, graceful termination periods, probes, and extraEnv.
  • Track the latest PD, Store, and Server images while this PR is a draft,
    using pull policy Always so nodes do not retain an older cached image.
  • Add Helm lint, render, invalid-value, kubeconform, legacy-values, and
    packaging CI.
  • Add chart installation, configuration, upgrade, troubleshooting, and
    limitations documentation, plus a root README installation link.

Distributed startup and recovery contracts

  • The chart creates no init Job and does not use HG_SERVER_SKIP_INIT. It sets
    HG_SERVER_INIT_STORE_ENABLED=false, relying on the dedicated
    init_store.enabled gate from fix(hugegraph-dist): gate init-store on a dedicated init_store.enabled option #3119 (issue InitStore should be able to skip local init in PD/HStore deployments #3118) so concurrent Server
    replicas do not initialize the same distributed backend.
  • Store waits for PD quorum before starting.
  • The image entrypoint owns PASSWORD handling and auth.admin_pa. The chart
    wrapper currently ensures only usePD=true and the configured PD peers
    before handing control back to the entrypoint. It does not yet write
    auth.admin_pa; see "Known gaps before this leaves draft".
  • Resource names reserve suffix and StatefulSet ordinal space before
    truncation, keeping names valid and PVC identities stable across scaling.
  • Server startup allows at least 450 seconds for the image's storage wait and
    startup command.

Prerequisites

Two prerequisites have merged since this PR was opened:

PR Required behavior Merged as
#3128 One gRPC stub binding per channel b026a90a
#3129 Store readiness retries across all configured PD peers 8b2932c7

Four remain open, and this PR should land after all of them:

PR Required behavior Current head
#3105 Bounded port preflight without lsof 09dbc744
#3119 Dedicated init_store.enabled gate ff1325ac
#3126 Finite JVM DNS cache TTL, plus startup DNS-policy validation and JDK 24+ security-check handling 4d0ff03e
#3130 Channel and stub refresh after address changes ddeef7a9

#3126's finite DNS TTL is required for #3130 to resolve a replacement Store
address. Neither change provides complete address recovery alone.

#3119 has since been narrowed to the init_store.enabled option, its gate, the
env mapping, and the init-flag guard. The Docker entrypoint and auth-bootstrap
work that previously shared its branch is now tracked separately in #3133. That
split does not change what this chart needs from #3119, but it does mean the
entrypoint's PASSWORD and auth.admin_pa handling is a known-imperfect
contract this chart depends on.

Validation baseline and head drift

The runtime matrix below was executed against a composition built from these
exact heads:

PR Head under test Status now
#3105 ee8f5559 superseded by 09dbc744
#3119 3e505a81 superseded by ff1325ac (scope narrowed)
#3126 35e1a240 superseded by 4d0ff03e (scope widened)
#3128 0118e158 merged unchanged at this head
#3129 575a1122 merged at 61407213, one commit further
#3130 26218cb3 superseded by ddeef7a9

Only #3128 merged at exactly the head this chart was validated against. The
results below therefore describe the chart's behavior against a composition
that no longer matches upstream, and are reported as the current evidence
baseline rather than as a claim about today's master.

Known gaps before this leaves draft

  1. The wrapper does not write auth.admin_pa. The chart sets
    HG_SERVER_INIT_STORE_ENABLED=false and supplies PASSWORD from
    server.auth.existingSecret, but the wrapper writes only usePD and
    pd.peers. With init_store.enabled=false the built-in authenticator's
    admin is created on the PD startup path from auth.admin_pa, while
    PASSWORD is discarded because init-store reads it from stdin and the
    disabled path returns first. Today that silently ignores the Secret and
    comes up as the public default. Once fix(hugegraph-dist): gate init-store on a dedicated init_store.enabled option #3119 merges, init-store fails closed
    and an auth-enabled deployment instead fails at container start. The fix is
    to write auth.admin_pa from the same Secret, alongside usePD and
    pd.peers. Note that auth.admin_pa applies only at first creation, so it
    does not rotate an existing cluster's password, and it lands in a file
    inside the container.

Before this PR leaves draft I will fix the item above, fetch the current
master, rebase the chart, pin appVersion and all three component image tags
to the next release, switch their pull policies to IfNotPresent, verify the
merged prerequisite behavior, rerun the affected full lifecycle matrix against
a composition of the then-current heads, and re-review any resulting changes.

Verifying these changes

  • Trivial rework / code cleanup without any test coverage. (No Need)
  • Already covered by existing tests, such as (please modify tests here).
  • Need tests and can be verified as follows:
    • Static chart validation: PASS=239 FAIL=0 SKIP=0.
    • Edge-case and hardening suite: PASS=37 FAIL=0.
    • Faithful legacy --reuse-values: helm template and
      helm install --dry-run=client passed.
    • Fresh 3+3+3 install: 9 Ready Pods, zero restarts, cluster 61/0, dataset
      30/0.
    • Same-package upgrade: cluster 61/0, dataset 30/0.
    • Server replacement: PASS=91 FAIL=0.
    • Store replacement: PASS=90 FAIL=0 with data preserved.
    • Deterministic PD REST failover: PASS=7 FAIL=0, with restoration verified.
    • Final cluster and dataset gates: 61/0 and 30/0.
    • Independent review passes 6, 7, and 8 reported no unresolved actionable
      findings on the final template and schema implementation.
    • The subsequent chart-version and default-image metadata amendment changed
      no templates or schema and repeated the full static gate at 239/0/0.

The runtime matrix used a four-node Kubernetes cluster and images built from a
composition containing the exact prerequisite heads listed under "Validation
baseline and head drift". Test-only validation harnesses and lab-specific
low-memory values are excluded from this PR. As noted above, five of those six
heads have since moved, so this matrix will be rerun before the PR is marked
ready.

Does this PR potentially affect the following parts?

Documentation Status

  • Doc - TODO
  • Doc - Done
  • Doc - No Need

Documented operational limits

  • While this PR is a draft, appVersion and all three component image tags are
    latest. This is intentionally temporary and is not the stable publication
    configuration; the next release tag will be pinned before the PR is marked
    ready.
  • Default values intentionally leave resource requests and limits unset;
    values-cluster.yaml is a production starting point, not a capacity
    guarantee.
  • The default three-replica PD and Store anti-affinity requires at least three
    schedulable Kubernetes nodes.
  • Authentication is optional and disabled by default. When it is enabled, the
    auth.admin_pa gap described above applies until it is fixed.
  • The published images run as root. The chart hardens the container without
    setting runAsNonRoot or readOnlyRootFilesystem, which the current image
    contract cannot support.
  • The entrypoint's property handling for mounted and upgraded configs is
    tracked in [Bug] Docker entrypoint auth bootstrap is unsafe for mounted and upgraded configs #3133 and is outside this chart's control.
  • TLS, backup and restore, an Operator, multi-cluster orchestration, automatic
    leader transfer, ConfigMap-based component configuration, and a complete
    monitoring stack are outside this PR.

@bitflicker64

Copy link
Copy Markdown
Contributor Author

Ordering note: this chart depends on #3119 and should land after it.

server-deployment.yaml injects HG_SERVER_INIT_STORE_ENABLED=false, and the mapping from that env var onto init_store.enabled only exists once #3119 merges. If this merges first, the chart ships pointing at a variable the image does not understand, and the server runs init-store on every pod start while the chart's README says it does not.

No file overlap between the two, so there is nothing to rebase — it is purely a merge-order dependency.

@bitflicker64

bitflicker64 commented Aug 2, 2026

Copy link
Copy Markdown
Contributor Author

Blocking, and it comes from a change in #3119 rather than from this PR's own code.

What changed. With init_store.enabled=false, the built-in authenticator's admin is created on the PD startup path from auth.admin_pa, whose default is the public value pa — while Docker PASSWORD is discarded, since init-store reads it from stdin and the disabled path returns first. init-store now fails closed unless an explicit non-empty auth.admin_pa is configured.

What breaks here. This chart sets HG_SERVER_INIT_STORE_ENABLED=false and supplies PASSWORD from server.auth.existingSecret, but its wrapper writes only usePD and pd.peers — never auth.admin_pa. Once #3119 merges, an auth-enabled deployment fails at container start with Refusing to skip init-store: ... no explicit non-empty 'auth.admin_pa' is configured.

Before that change it did not fail — it came up as admin/pa, silently ignoring the Secret. So this is an existing bug here that #3119 makes visible.

What to do. The wrapper should write auth.admin_pa from the Secret it already mounts as PASSWORD, alongside the usePD and pd.peers lines. That also makes this README line true for the first time:

The image entrypoint keeps ownership of PASSWORD handling and auth.admin_pa.

Two notes while you are in there: auth.admin_pa applies only at first creation, so it will not rotate an existing cluster's password, and it lands in a file inside the container. Merge order is unchanged — this still lands after #3119.

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.

[Feature] Add an official Helm chart for distributed HStore deployment

1 participant