Skip to main content

Event Qps Argument Set 0 Or Level Which Ensures Appropriate

More Info:​

Security relevant information should be captured. The eventRecordQPS on the Kubelet configuration can be used to limit the rate at which events are gathered and sets the maximum event creations per second. Setting this too low could result in relevant events not being logged, however the unlimited setting of 0 could result in a denial of service on the kubelet.

Risk Level​

Medium

Address​

Security

Compliance Standards​

  • APRA CPS 234 (Australia)
  • BSI C5 (Germany)
  • Brazil LGPD
  • CCPA / CPRA (California)
  • CIS Critical Security Controls v8
  • CIS GKE
  • CMMC 2.0
  • CSA Cloud Controls Matrix v4
  • DPDPA
  • Digital Operational Resilience Act (EU)
  • ISO/IEC 27017
  • ISO/IEC 27018
  • ISO/IEC 27701
  • KSA PDPL
  • MAS Technology Risk Management (Singapore)
  • MITRE ATT&CK (Cloud)
  • NIS2 Directive
  • NIST SP 800-171
  • NYDFS 23 NYCRR 500
  • SWIFT Customer Security Controls Framework
  • Sarbanes-Oxley IT General Controls
  • UK NCSC Cyber Assessment Framework

Triage and Remediation​

Remediation​

Manual Steps
  1. On every worker node, determine how kubelet is configured:

    ps -fC kubelet

    If you see --config=/var/lib/kubelet/config.yaml, it uses the config file. If you see --event-qps=... explicitly, it uses a command-line flag (systemd unit).

  2. If using the kubelet config file on a worker node, edit /var/lib/kubelet/config.yaml and set eventRecordQPS to the desired rate (non-zero, or 0 for unlimited), under the top-level config:

    sudo sed -i 's/^[[:space:]]*eventRecordQPS:.*$/eventRecordQPS: 5/' /var/lib/kubelet/config.yaml

    If eventRecordQPS is missing, add it under the main YAML mapping, for example:

    sudo sh -c 'printf "\neventRecordQPS: 5\n" >> /var/lib/kubelet/config.yaml'
  3. If using command-line arguments on a worker node, edit the kubelet systemd drop-in to set --event-qps appropriately:

    sudo sed -i 's/\(--event-qps=\)[0-9]*/\15/' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf || \
    echo ' --event-qps=5 \' | sudo tee -a /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

    Adjust 5 to your chosen rate or 0 for unlimited.

  4. On every worker node, reload systemd and restart kubelet (this will temporarily disrupt node workloads if the node is not cordoned/drained first):

    sudo systemctl daemon-reload
    sudo systemctl restart kubelet.service
  5. On every worker node, verify kubelet is running with the desired setting:

    ps -fC kubelet

    Confirm either:

    • the command line shows --config=/var/lib/kubelet/config.yaml and that file contains eventRecordQPS: <your_value>, or
    • the command line includes --event-qps=<your_value>.
Using kubectl

kubectl cannot modify the kubelet’s eventRecordQPS setting because it is defined on each worker node’s host-level kubelet configuration (/var/lib/kubelet/config.yaml or the kubelet systemd unit). To remediate this finding, make the change directly on every worker node as described in the Manual Steps section.

Automation
#!/usr/bin/env bash
#
# Harden kubelet eventRecordQPS on every worker node.
#
# - Sets eventRecordQPS in /var/lib/kubelet/config.yaml to a safe default if missing
# - Leaves non-zero values unchanged (assumes cluster-specific tuning)
# - Does NOT set 0 (unlimited) to avoid potential DoS, per benchmark warning
# - Restarts kubelet if config was changed
# - Prints kubelet processes so you can confirm flags/config in use
#
# Usage:
# 1) Copy this script to each WORKER NODE (not the control plane-only nodes)
# 2) Run as root: sudo bash ./fix-kubelet-event-qps.sh
# 3) Safe to re-run; changes are idempotent
#
# NOTE: Adjust SAFE_QPS below to your cluster’s appropriate event rate if needed.

set -euo pipefail

CONFIG_FILE="/var/lib/kubelet/config.yaml"
SYSTEMD_UNIT="kubelet.service"
SAFE_QPS="50" # Example sane default; update if your ops policy dictates otherwise

echo "[INFO] Running on worker node: $(hostname)"

if [[ ! -f "${CONFIG_FILE}" ]]; then
echo "[ERROR] ${CONFIG_FILE} not found. This node may be using only CLI flags or a different path."
echo "[INFO] No change applied. Review kubelet unit/flags manually:"
/bin/ps -fC kubelet || true
exit 1
fi

echo "[INFO] Found kubelet config: ${CONFIG_FILE}"

# Backup once per day for safety
BACKUP="${CONFIG_FILE}.$(date +%F-%H%M%S).bak"
cp "${CONFIG_FILE}" "${BACKUP}"
echo "[INFO] Backup created at ${BACKUP}"

# Detect current eventRecordQPS (if any)
CURRENT_QPS="$(grep -E '^\s*eventRecordQPS\s*:' "${CONFIG_FILE}" 2>/dev/null | head -n1 | awk -F: '{gsub(/ /,"",$2);print $2}' || true)"

if [[ -n "${CURRENT_QPS}" ]]; then
echo "[INFO] Existing eventRecordQPS detected: ${CURRENT_QPS}"

if [[ "${CURRENT_QPS}" == "0" ]]; then
# 0 means unlimited; change to SAFE_QPS to avoid potential DoS
echo "[INFO] eventRecordQPS is 0 (unlimited). Updating to SAFE_QPS=${SAFE_QPS}."
# In-place replace only the first occurrence on a line starting with eventRecordQPS
sed -i '0,/^\s*eventRecordQPS\s*:/s//eventRecordQPS: '"${SAFE_QPS}"'/' "${CONFIG_FILE}"
RESTART_NEEDED=1
else
echo "[INFO] Non-zero eventRecordQPS present; leaving as-is to respect existing tuning."
RESTART_NEEDED=0
fi
else
echo "[INFO] eventRecordQPS not set. Adding with SAFE_QPS=${SAFE_QPS}."

# Insert under top-level if possible; if file is very minimal, append at end.
if grep -qE '^\s*[a-zA-Z0-9_]+:' "${CONFIG_FILE}"; then
# Append at end with no indentation (top-level key)
printf "\n# Ensuring adequate event capture per CIS GKE 3.2.9\neventRecordQPS: %s\n" "${SAFE_QPS}" >> "${CONFIG_FILE}"
else
printf "# Kubelet config\n# Ensuring adequate event capture per CIS GKE 3.2.9\neventRecordQPS: %s\n" "${SAFE_QPS}" > "${CONFIG_FILE}"
fi
RESTART_NEEDED=1
fi

if [[ "${RESTART_NEEDED:-0}" -eq 1 ]]; then
echo "[INFO] Reloading systemd and restarting kubelet (${SYSTEMD_UNIT}). This will restart the kubelet on this worker node."
systemctl daemon-reload
systemctl restart "${SYSTEMD_UNIT}"
else
echo "[INFO] No kubelet restart required."
fi

echo "[INFO] Verification: kubelet process details on this worker node"
/bin/ps -fC kubelet || {
echo "[ERROR] kubelet process not found after change; check systemctl status ${SYSTEMD_UNIT}"
systemctl status "${SYSTEMD_UNIT}" -l || true
exit 1
}

echo "[INFO] Current eventRecordQPS in ${CONFIG_FILE}:"
grep -nE '^\s*eventRecordQPS\s*:' "${CONFIG_FILE}" || echo "[WARN] eventRecordQPS not found in file after supposed change."

echo "[INFO] Done. Repeat this script on every worker node."

Additional Reading:​