mirror of
https://github.com/cozystack/cozystack.git
synced 2026-11-08 21:14:56 +09:00
## What this PR does OpenSearch will not start below `vm.max_map_count=262144` when the store may use mmap, and nothing in the platform sets it. The Talos profiles declare no sysctls and no documented node-preparation path sets one, so nodes sit at the kernel default of 65530. The app chart asks the operator to cover that with `spec.general.setVMMaxMapCount`, which appends a privileged init container to every OpenSearch pod. Tenant namespaces carry no PodSecurity label of their own, so they take the cluster default, which Talos ships as baseline through the apiserver's `PodSecurityConfiguration`. That default refuses the container and the StatefulSet never produces a pod. On vanilla kubeadm, kind or k3s the default is `privileged` and the same release comes up, which is why this only bites on a Talos install. The value cannot come from the pod at all. The kernel does not namespace `vm.*`, so kubelet rejects it in `securityContext.sysctls`, and refuses to start if it appears in `--allowed-unsafe-sysctls`. That leaves node configuration or a privileged pod, and a privileged pod belongs in a system namespace rather than in every tenant. This adds a DaemonSet to the `opensearch-operator` package that sets the value once per node from a privileged init container, and marks the component privileged so the platform labels `cozy-opensearch-operator` with `enforce=privileged`. The init container writes to `/proc/sys` and nothing else, with no hostPath. The pod restarts with the node and reapplies the value, so there is nothing to persist. It raises the limit to a floor rather than assigning it, which matters more than it looks. `vm.max_map_count` is node-global, and a stock Ubuntu 24.04 node already reads 1048576 from a `sysctl.d` drop-in. An unconditional write would drop that to 262144 for every workload on the node, on every boot, and undo whatever the operator set it for. So the init container reads the current value first and writes only when it is below the threshold. The idle main container runs its sleep under a shell that traps SIGTERM, so a pod exits on its own when the DaemonSet rolls or a node drains, instead of ignoring the signal and being killed after the full grace period. This does not fix OpenSearch on its own. The app chart still requests the operator's init container through `setVMMaxMapCount: true`, so a release stays blocked until the flip to `false` lands with #2682, after this merges. The DaemonSet has to be in place first: flipping it without one would trade the admission failure for a failed bootstrap check. Carrying the sysctl in the node contract instead, across the Talos profiles and the downstream node-prep paths, is tracked in #4144; that is what would let this DaemonSet be retired. Two things change on upgrade, and neither is visible from the diff. One small DaemonSet pod appears per node in `cozy-opensearch-operator`, and that namespace gains `pod-security.kubernetes.io/enforce=privileged`. That label has no finer granularity than the namespace, so the operator Deployment sitting there leaves the cluster default too, not just the DaemonSet. Keeping the manager at baseline would mean a namespace of its own and another component entry, which did not look worth it, but it is a real cost rather than an accident. The operator is in the `paas` bundle's always-on list, so this lands on every node of every paas installation and raises a node-global kernel tunable there, whether or not anyone ever creates an OpenSearchCluster. That is the price of a node-level sysctl having no cheaper carrier, and it is worth an explicit decision rather than being noticed later. The second is `cozypkg add`, which gates privileged components behind a confirmation or `--allow-privileged`. The gate runs over the resolved dependency closure, and `opensearch-application` dependsOn the operator, so installing the app that way now asks one more question. This is not a new break for scripts: `add` already prompts for a variant on every package it resolves and fails on EOF, so it was never usable non-interactively in the first place. Platform-bundle installs go through the reconciler and are unaffected. ### Screenshots Not a UI change. ### Downstream repositories Walked the trigger map in `docs/agents/contributing.md` against the diff. It adds a template, a test and a values key under `packages/system/opensearch-operator/`, plus one field in `packages/core/platform/sources/opensearch-operator.yaml`. No new app package, no app schema or version enum, no `ApplicationDefinition`, no installer value, no namespace rename, no variant or bundle, no `hack/` path or make target, and no node prerequisite in `hack/e2e-prepare-cluster.bats`. Nothing in the map matches. - [x] No downstream repository is affected by this change - [ ] [cozystack/website](https://github.com/cozystack/website) - follow-up: - [ ] [cozystack/terraform-provider-cozystack](https://github.com/cozystack/terraform-provider-cozystack) - follow-up: - [ ] [cozystack/ansible-cozystack](https://github.com/cozystack/ansible-cozystack) - follow-up: - [ ] [cozystack/ccp](https://github.com/cozystack/ccp) - follow-up: - [ ] [cozystack/talm](https://github.com/cozystack/talm) - follow-up: - [ ] [cozystack/cozyhr](https://github.com/cozystack/cozyhr) - follow-up: - [ ] [cozystack/cozy-proxy](https://github.com/cozystack/cozy-proxy) - follow-up: - [ ] [cozystack/cozystack-telemetry-server](https://github.com/cozystack/cozystack-telemetry-server) - follow-up: - [ ] [cozystack/external-apps-example](https://github.com/cozystack/external-apps-example) - follow-up: - [ ] [cozystack/examples](https://github.com/cozystack/examples) - follow-up: - [ ] [cozystack/community](https://github.com/cozystack/community) - follow-up: ### Release note ```release-note fix(opensearch-operator): set `vm.max_map_count` on every node from a DaemonSet in the operator's namespace, so OpenSearch no longer depends on a privileged init container that PodSecurity baseline refuses in a tenant namespace. Upgrading adds one small DaemonSet pod per node and labels `cozy-opensearch-operator` with `pod-security.kubernetes.io/enforce=privileged`; installing the package with `cozypkg add` now requires confirmation or `--allow-privileged`. Existing OpenSearch releases are unchanged until a follow-up stops the app chart requesting the operator's own init container. ``` <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Bug Fixes** - OpenSearch Operator installation now runs with the required privileged configuration. - OpenSearch deployments automatically ensure nodes meet the required `vm.max_map_count` setting, improving startup reliability. - Existing higher kernel values are preserved. - Added support for configuring the sysctl image, including use with air-gapped registries. - **Tests** - Added coverage to verify privileged installation, node configuration, security settings, scheduling behavior, and image customization. <!-- end of auto-generated comment: release notes by coderabbit.ai -->