Skip to content

Commit

Permalink
redpanda: simplify setting redpanda resources
Browse files Browse the repository at this point in the history
Prior to this commit it was not possible to "mix and match" the resource
requests and limits of the redpanda container. The redpanda chart also required
users to grok a new model of resources unique to the chart which made the chart
less user friendly.

This commit introduces a more user friendly and backwards compatible way of
directly controlling the requests and limits of the redpanda container. Rather
than directly exposing the `--smp`, `--memory`, `--reserve-memory`, and
`--overprovisioned` flags to the end user, this method will infer them from the
provided values with updated best practices.

Fixes #1494
K8S-325
K8S-434
  • Loading branch information
chrisseto committed Dec 17, 2024
1 parent 1fff60a commit 04b5615
Show file tree
Hide file tree
Showing 13 changed files with 793 additions and 410 deletions.
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,25 @@

### [Unreleased](https://github.com/redpanda-data/helm-charts/releases/tag/redpanda-FILLMEIN) - YYYY-MM-DD
#### Added
* Added `resources.limits` and `resources.requests` as an alternative method of managing the redpanda container's resources.

When both `resources.limits` and `resources.requests` are specified, the
redpanda container's `resources` will be set to the provided values and all
other keys of `resources` will be ignored. Instead, all other values will be
inferred from the limits and requests.

This allows fine grain control of resources. i.e. It is now possible to set
CPU requests without setting limits:

```yaml
resources:
limits: {} # Specified but not cpu or memory values provided
requests:
cpu: 5 # Only CPU requests
```
For more details see [redpanda's values.yaml](./charts/redpanda/values.yaml).
#### Changed
#### Fixed
#### Removed
Expand Down
37 changes: 36 additions & 1 deletion charts/redpanda/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -621,7 +621,42 @@ Enable for features that need extra privileges. If you use the Redpanda Operator

### [resources](https://artifacthub.io/packages/helm/redpanda-data/redpanda?modal=values&path=resources)

Pod resource management. This section simplifies resource allocation by providing a single location where resources are defined. Helm sets these resource values within the `statefulset.yaml` and `configmap.yaml` templates. The default values are for a development environment. Production-level values and other considerations are documented, where those values are different from the default. For details, see the [Pod resources documentation](https://docs.redpanda.com/docs/manage/kubernetes/manage-resources/).
Pod resource management.
This section simplifies resource allocation for the redpanda container by
providing a single location where resources are defined.

Resources may be specified by either setting `resources.cpu` and
`resources.memory` (the default) or by setting `resources.requests` and
`resources.limits`.

For details on `resources.cpu` and `resources.memory`, see their respective
documentation below.

When `resources.limits` and `resources.requests` are set, the redpanda
container's resources will be set to exactly the provided values. This allows
users to granularly control limits and requests to best suite their use case.
For example: `resources.requests.cpu` may be set without setting
`resources.limits.cpu` to avoid the potential of CPU throttling.

Redpanda's resource related CLI flags will then be calculated as follows:
* `--smp floor(resources.{requests,limits}.cpu)`
* `--memory resources.{requests,limits}.memory * 90%`
* `--reserve-memory 0`
* `--overprovisioned resources.{requests,limits}.cpu < 1000m`

If neither a request nor a limit is provided for cpu or memory, the
corresponding flag will be omitted. As a result, setting `resources.limits`
and `resources.requests` to `{}` will result in redpanda being run without
`--smp` or `--memory`. (This is not recommended).

If the computed CLI flags are undesirable, they may be overridden by
specifying the desired value through `statefulset.additionalRedpandaCmdFlags`.

The default values are for a development environment.
Production-level values and other considerations are documented,
where those values are different from the default.
For details,
see the [Pod resources documentation](https://docs.redpanda.com/docs/manage/kubernetes/manage-resources/).

**Default:**

Expand Down
13 changes: 9 additions & 4 deletions charts/redpanda/configmap.tpl.go
Original file line number Diff line number Diff line change
Expand Up @@ -365,8 +365,6 @@ func rpkNodeConfig(dot *helmette.Dot) map[string]any {
}

result := map[string]any{
"overprovisioned": values.Resources.GetOverProvisionValue(),
"enable_memory_locking": ptr.Deref(values.Resources.Memory.EnableMemoryLocking, false),
"additional_start_flags": RedpandaAdditionalStartFlags(dot),
"kafka_api": map[string]any{
"brokers": brokerList,
Expand Down Expand Up @@ -622,7 +620,7 @@ func RedpandaAdditionalStartFlags(dot *helmette.Dot) []string {
values := helmette.Unwrap[Values](dot.Values)

// All `additional_start_flags` that are set by the chart.
chartFlags := values.Resources.GetRedpandaStartFlags()
chartFlags := values.Resources.GetRedpandaFlags()
chartFlags["default-log-level"] = values.Logging.LogLevel

// If in developer_mode, don't set reserve-memory.
Expand All @@ -646,7 +644,14 @@ func RedpandaAdditionalStartFlags(dot *helmette.Dot) []string {

flags := []string{}
for _, key := range keys {
flags = append(flags, fmt.Sprintf("--%s=%s", key, chartFlags[key]))
value := chartFlags[key]
// Support flags that don't have values (`--overprovisioned`) by
// letting them be specified as key: ""
if value == "" {
flags = append(flags, fmt.Sprintf("--%s", key))
} else {
flags = append(flags, fmt.Sprintf("--%s=%s", key, value))
}
}

return append(flags, values.Statefulset.AdditionalRedpandaCmdFlags...)
Expand Down
11 changes: 8 additions & 3 deletions charts/redpanda/templates/_configmap.go.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@
{{- if (gt ((get (fromJson (include "_shims.len" (dict "a" (list $tls_8) ))) "r") | int) (0 | int)) -}}
{{- $schemaRegistryTLS = $tls_8 -}}
{{- end -}}
{{- $result := (dict "overprovisioned" (get (fromJson (include "redpanda.RedpandaResources.GetOverProvisionValue" (dict "a" (list $values.resources) ))) "r") "enable_memory_locking" (get (fromJson (include "_shims.ptr_Deref" (dict "a" (list $values.resources.memory.enable_memory_locking false) ))) "r") "additional_start_flags" (get (fromJson (include "redpanda.RedpandaAdditionalStartFlags" (dict "a" (list $dot) ))) "r") "kafka_api" (dict "brokers" $brokerList "tls" $brokerTLS ) "admin_api" (dict "addresses" (get (fromJson (include "redpanda.Listeners.AdminList" (dict "a" (list $values.listeners ($values.statefulset.replicas | int) (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") (get (fromJson (include "redpanda.InternalDomain" (dict "a" (list $dot) ))) "r")) ))) "r") "tls" $adminTLS ) "schema_registry" (dict "addresses" (get (fromJson (include "redpanda.Listeners.SchemaRegistryList" (dict "a" (list $values.listeners ($values.statefulset.replicas | int) (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") (get (fromJson (include "redpanda.InternalDomain" (dict "a" (list $dot) ))) "r")) ))) "r") "tls" $schemaRegistryTLS ) ) -}}
{{- $result := (dict "additional_start_flags" (get (fromJson (include "redpanda.RedpandaAdditionalStartFlags" (dict "a" (list $dot) ))) "r") "kafka_api" (dict "brokers" $brokerList "tls" $brokerTLS ) "admin_api" (dict "addresses" (get (fromJson (include "redpanda.Listeners.AdminList" (dict "a" (list $values.listeners ($values.statefulset.replicas | int) (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") (get (fromJson (include "redpanda.InternalDomain" (dict "a" (list $dot) ))) "r")) ))) "r") "tls" $adminTLS ) "schema_registry" (dict "addresses" (get (fromJson (include "redpanda.Listeners.SchemaRegistryList" (dict "a" (list $values.listeners ($values.statefulset.replicas | int) (get (fromJson (include "redpanda.Fullname" (dict "a" (list $dot) ))) "r") (get (fromJson (include "redpanda.InternalDomain" (dict "a" (list $dot) ))) "r")) ))) "r") "tls" $schemaRegistryTLS ) ) -}}
{{- $result = (merge (dict ) $result (get (fromJson (include "redpanda.Tuning.Translate" (dict "a" (list $values.tuning) ))) "r")) -}}
{{- $result = (merge (dict ) $result (get (fromJson (include "redpanda.Config.CreateRPKConfiguration" (dict "a" (list $values.config) ))) "r")) -}}
{{- $_is_returning = true -}}
Expand Down Expand Up @@ -544,7 +544,7 @@
{{- range $_ := (list 1) -}}
{{- $_is_returning := false -}}
{{- $values := $dot.Values.AsMap -}}
{{- $chartFlags := (get (fromJson (include "redpanda.RedpandaResources.GetRedpandaStartFlags" (dict "a" (list $values.resources) ))) "r") -}}
{{- $chartFlags := (get (fromJson (include "redpanda.RedpandaResources.GetRedpandaFlags" (dict "a" (list $values.resources) ))) "r") -}}
{{- $_ := (set $chartFlags "default-log-level" $values.logging.logLevel) -}}
{{- if (eq (index $values.config.node "developer_mode") true) -}}
{{- $_ := (unset $chartFlags "reserve-memory") -}}
Expand All @@ -566,7 +566,12 @@
{{- $_ := (sortAlpha $keys) -}}
{{- $flags := (list ) -}}
{{- range $_, $key := $keys -}}
{{- $flags = (concat (default (list ) $flags) (list (printf "--%s=%s" $key (ternary (index $chartFlags $key) "" (hasKey $chartFlags $key))))) -}}
{{- $value := (ternary (index $chartFlags $key) "" (hasKey $chartFlags $key)) -}}
{{- if (eq $value "") -}}
{{- $flags = (concat (default (list ) $flags) (list (printf "--%s" $key))) -}}
{{- else -}}
{{- $flags = (concat (default (list ) $flags) (list (printf "--%s=%s" $key $value))) -}}
{{- end -}}
{{- end -}}
{{- if $_is_returning -}}
{{- break -}}
Expand Down
Loading

0 comments on commit 04b5615

Please sign in to comment.