Ensure Profiling Argument Is Disabled
More Info:
Disable profiling, if not needed.
Risk Level
Medium
Address
Security
Compliance Standards
- CIS Kubernetes
Triage and Remediation
- Remediation
Remediation
Manual Steps
- On every control plane node, back up the existing static pod manifest for the API server:
sudo cp -a /etc/kubernetes/manifests/kube-apiserver.yaml /etc/kubernetes/manifests/kube-apiserver.yaml.bak
- Edit the API server manifest to add or update the
--profilingargument:
sudo vi /etc/kubernetes/manifests/kube-apiserver.yaml
In the command: or args: list for kube-apiserver, ensure there is an entry:
- --profiling=false
Remove or change any existing --profiling=true to --profiling=false.
-
Save the file and exit the editor. The kubelet will detect the manifest change and automatically restart the
kube-apiserverstatic pod on that control plane node. Expect a brief control-plane disruption during the restart. -
After 30–60 seconds, verify on that control plane node that the process is running with
--profiling=false:
/bin/ps -ef | grep kube-apiserver | grep -v grep
-
In the command line output for
kube-apiserver, confirm that--profiling=falseis present and that there is no--profiling=trueflag. -
Repeat steps 1–5 on every control plane node.
Using kubectl
kubectl cannot change the --profiling flag because it is set in the static pod manifest on each control plane node, specifically in /etc/kubernetes/manifests/kube-apiserver.yaml. To remediate this finding, follow the guidance in the Manual Steps section and edit the file directly on every control plane node.
Automation
#!/usr/bin/env bash
#
# Disable kube-apiserver profiling on all control plane nodes
# Scope: run on every control plane node (as root)
# Impact: editing /etc/kubernetes/manifests/kube-apiserver.yaml will restart the kube-apiserver static pod
set -euo pipefail
APISERVER_MANIFEST="/etc/kubernetes/manifests/kube-apiserver.yaml"
TMP_MANIFEST="/tmp/kube-apiserver.yaml.$$"
echo "[INFO] Ensuring kube-apiserver profiling is disabled"
if [ ! -f "$APISERVER_MANIFEST" ]; then
echo "[ERROR] Manifest not found at $APISERVER_MANIFEST. This script must run on a control plane node with static pods."
exit 1
fi
# Create a backup once per host if not already present
BACKUP="${APISERVER_MANIFEST}.cis-backup"
if [ ! -f "$BACKUP" ]; then
echo "[INFO] Creating backup $BACKUP"
cp -p "$APISERVER_MANIFEST" "$BACKUP"
fi
# Normalize file to avoid in-place edit issues
cp -p "$APISERVER_MANIFEST" "$TMP_MANIFEST"
# 1) Ensure a --profiling=false argument exists and is not overridden
# Remove any existing --profiling=... args to avoid duplicates
sed -i 's/--profiling=[^[:space:]]*//g' "$TMP_MANIFEST"
# Clean up any excessive whitespace from the removal
# (this is conservative and only touches obvious double-spaces before newlines)
sed -i 's/[[:space:]]\{2,\}/ /g' "$TMP_MANIFEST"
# Add --profiling=false under the kube-apiserver command/args section if missing
if ! grep -q -- "--profiling=false" "$TMP_MANIFEST"; then
echo "[INFO] Inserting --profiling=false into kube-apiserver manifest"
# Try to insert into an existing args list if present
if grep -q '^\s*args:\s*$' "$TMP_MANIFEST"; then
# Insert as a new arg line after the 'args:' key, if not already present
awk '
/^\s*args:\s*$/ && a==0 {
print $0
print " - --profiling=false"
a=1
next
}
{ print $0 }
END {
# if args: was never seen (a==0), nothing special to do
}
' "$TMP_MANIFEST" > "${TMP_MANIFEST}.new"
mv "${TMP_MANIFEST}.new" "$TMP_MANIFEST"
else
# If no args: key, try to inject the flag into a single-line "command:" or direct "kube-apiserver" line
if grep -q 'kube-apiserver' "$TMP_MANIFEST"; then
# Append to an existing kube-apiserver command line in a minimal and safe way
awk '
/kube-apiserver/ && c==0 {
# Add flag only if not already in the line
if ($0 !~ /--profiling=false/) {
sub(/kube-apiserver/, "kube-apiserver --profiling=false", $0)
}
c=1
}
{ print $0 }
' "$TMP_MANIFEST" > "${TMP_MANIFEST}.new"
mv "${TMP_MANIFEST}.new" "$TMP_MANIFEST"
else
echo "[ERROR] Could not locate kube-apiserver command/args section to inject --profiling=false. Aborting."
rm -f "$TMP_MANIFEST"
exit 1
fi
fi
fi
# 2) Move the updated manifest into place (this will trigger kubelet to restart the static pod)
echo "[INFO] Updating $APISERVER_MANIFEST"
mv "$TMP_MANIFEST" "$APISERVER_MANIFEST"
# 3) Verification (same machine: control plane node)
echo "[INFO] Waiting for kube-apiserver to restart with new arguments..."
sleep 15
APISERVER_PROCS="$(/bin/ps -ef | grep kube-apiserver | grep -v grep || true)"
if echo "$APISERVER_PROCS" | grep -q -- "--profiling=false"; then
if echo "$APISERVER_PROCS" | grep -q -- "--profiling=true"; then
echo "[FAIL] kube-apiserver still has --profiling=true in its arguments:"
echo "$APISERVER_PROCS"
exit 1
fi
echo "[OK] kube-apiserver is running with --profiling=false and no conflicting --profiling=true flag:"
echo "$APISERVER_PROCS"
exit 0
else
echo "[FAIL] kube-apiserver process does not show --profiling=false in its arguments:"
echo "$APISERVER_PROCS"
exit 1
fi