diff --git a/k3s/40-kafka/yconverge.cue b/k3s/40-kafka/yconverge.cue index 05d10f43..b291b933 100644 --- a/k3s/40-kafka/yconverge.cue +++ b/k3s/40-kafka/yconverge.cue @@ -21,5 +21,12 @@ step: verify.#Step & { timeout: "30s" description: "redpanda cluster healthy" }, + { + kind: "wait" + resource: "job/redpanda-cluster-config" + for: "condition=complete" + namespace: "kafka" + timeout: "300s" + }, ] } diff --git a/kafka/base/kustomization.yaml b/kafka/base/kustomization.yaml index 7fa3fbc2..efc004d6 100644 --- a/kafka/base/kustomization.yaml +++ b/kafka/base/kustomization.yaml @@ -8,6 +8,7 @@ namespace: kafka resources: - ../redpanda - y-bootstrap-service.yaml +- redpanda-cluster-config-job.yaml patches: - path: ./redpanda-resources.yaml diff --git a/kafka/base/redpanda-cluster-config-job.yaml b/kafka/base/redpanda-cluster-config-job.yaml new file mode 100644 index 00000000..ff389185 --- /dev/null +++ b/kafka/base/redpanda-cluster-config-job.yaml @@ -0,0 +1,101 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: redpanda-cluster-config + labels: + # The pod template is immutable, so yconverge deletes and re-creates this Job at every converge. + # Each run sets only what differs from args. + yolean.se/converge-mode: replace +spec: + backoffLimit: 2 + activeDeadlineSeconds: 900 + template: + metadata: + labels: + app.kubernetes.io/name: redpanda + app.kubernetes.io/component: redpanda-cluster-config + spec: + restartPolicy: Never + automountServiceAccountToken: false + securityContext: + fsGroup: 101 + fsGroupChangePolicy: OnRootMismatch + containers: + - name: rpk + image: docker.redpanda.com/redpandadata/redpanda:v23.3.7 + command: + - /bin/sh + - -ec + - | + for property in "$@"; do + case "$property" in + ?*=*) ;; + *) echo "Expected key=value, got: $property" >&2; exit 1 ;; + esac + done + + attempt=0 + until rpk cluster config status >/dev/null; do + attempt=$((attempt + 1)) + [ "$attempt" -lt 60 ] || { echo "No answer from the admin API" >&2; exit 1; } + sleep 5 + done + + # rpk prints an infinite duration as -9223372036854775808 + matches() { + [ "$2" = "$1" ] || { [ "$1" = "-1" ] && [ "$2" = "-9223372036854775808" ]; } + } + + for property in "$@"; do + key="${property%%=*}" + value="${property#*=}" + current=$(rpk cluster config get "$key") + if matches "$value" "$current"; then + echo "$key is $current" + else + echo "$key is $current, setting $value" + # key=value form: in "set key -1" rpk reads -1 as a flag + rpk cluster config set "$key=$value" + fi + done + + attempt=0 + while :; do + ok=true + for property in "$@"; do + key="${property%%=*}" + value="${property#*=}" + current=$(rpk cluster config get "$key") + matches "$value" "$current" || { echo "$key is $current, expected $value"; ok=false; } + done + status=$(rpk cluster config status) + echo "$status" + invalid=$(echo "$status" | awk 'NR > 1 && $4 != "[]"') + [ -z "$invalid" ] || { echo "INVALID properties listed"; ok=false; } + [ "$ok" = false ] || exit 0 + attempt=$((attempt + 1)) + [ "$attempt" -lt 10 ] || exit 1 + sleep 3 + done + - cluster-config + # Cluster properties, key=value, one per line. Add here those that bootstrap.yaml can't carry. + args: + - log_retention_ms=-1 + securityContext: + runAsUser: 101 + runAsGroup: 101 + allowPrivilegeEscalation: false + resources: + requests: + cpu: 10m + memory: 50Mi + limits: + memory: 100Mi + volumeMounts: + # rpk reads the admin API addresses from redpanda.yaml, as the brokers' own rpk does + - name: config + mountPath: /etc/redpanda + volumes: + - name: config + configMap: + name: redpanda diff --git a/kafka/redpanda.kafka.values.yaml b/kafka/redpanda.kafka.values.yaml index 2799a567..9e7b89c3 100644 --- a/kafka/redpanda.kafka.values.yaml +++ b/kafka/redpanda.kafka.values.yaml @@ -27,8 +27,10 @@ config: default_topic_partitions: 1 storage_min_free_bytes: 10485760 group_topic_partitions: 1 - # like Kafka brokers set up by Yolean/kubernetes-kafka: a topic deletes by age only when it says so - log_retention_ms: -1 + # Like Kafka brokers set up by Yolean/kubernetes-kafka, a topic deletes by age only when it says so. + # log_retention_ms: -1 is set by base/redpanda-cluster-config-job.yaml, not here: redpanda v24.2 + # imports a negative value from bootstrap.yaml as 18446744073709551615, rejects that, + # and uses the 7 day default after the first restart. tuning: tune_aio_events: false tls: diff --git a/kafka/redpanda/kafka/redpanda/templates/configmap.yaml b/kafka/redpanda/kafka/redpanda/templates/configmap.yaml index d5d7fe4d..a772206b 100644 --- a/kafka/redpanda/kafka/redpanda/templates/configmap.yaml +++ b/kafka/redpanda/kafka/redpanda/templates/configmap.yaml @@ -26,7 +26,6 @@ data: compacted_log_segment_size: 16777216 group_topic_partitions: 1 kafka_batch_max_bytes: 1048576 - log_retention_ms: -1 kafka_connection_rate_limit: 1000 log_segment_size: 16777216 log_segment_size_max: 33554432