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
Remediation
Manual Steps
-
On every worker node, determine how kubelet is configured:
ps -fC kubeletIf 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). -
If using the kubelet config file on a worker node, edit
/var/lib/kubelet/config.yamland seteventRecordQPSto 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.yamlIf
eventRecordQPSis missing, add it under the main YAML mapping, for example:sudo sh -c 'printf "\neventRecordQPS: 5\n" >> /var/lib/kubelet/config.yaml' -
If using command-line arguments on a worker node, edit the kubelet systemd drop-in to set
--event-qpsappropriately: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.confAdjust
5to your chosen rate or0for unlimited. -
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-reloadsudo systemctl restart kubelet.service -
On every worker node, verify kubelet is running with the desired setting:
ps -fC kubeletConfirm either:
- the command line shows
--config=/var/lib/kubelet/config.yamland that file containseventRecordQPS: <your_value>, or - the command line includes
--event-qps=<your_value>.
- the command line shows
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."