Scheduler Bind Address Should Be 127.0.0.1
More Info:
Verifies that the scheduler --bind-address is set to 127.0.0.1 so its metrics and health endpoints are not exposed on the network.
Risk Level
High
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 scheduler:
sudo cp -p /etc/kubernetes/manifests/kube-scheduler.yaml /etc/kubernetes/manifests/kube-scheduler.yaml.bak -
On every control plane node, edit the scheduler static pod manifest to set the bind-address to 127.0.0.1:
sudo sed -i 's/--bind-address=[0-9\.]*/--bind-address=127.0.0.1/' /etc/kubernetes/manifests/kube-scheduler.yamlIf the
--bind-addressflag is not present, add it under thecommand:list forkube-scheduler, for example:spec:containers:- command:- kube-scheduler- --bind-address=127.0.0.1Save the file; kubelet will automatically restart the kube-scheduler pod when the manifest changes (expect a brief control-plane impact).
-
On every control plane node, wait for the kube-scheduler pod to be recreated and running:
sudo crictl ps | grep kube-schedulerEnsure the scheduler container shows a recent start time and is in running state.
-
On every control plane node, verify the kube-scheduler process is now using the loopback bind address:
/bin/ps -ef | grep kube-scheduler | grep -v grepConfirm the output includes
--bind-address=127.0.0.1and no other--bind-addressvalue.
Using kubectl
kubectl cannot modify the kube-scheduler bind address, because it is configured via the static pod manifest on each control plane node at /etc/kubernetes/manifests/kube-scheduler.yaml. To remediate this finding, make the change directly on the node as described in the Manual Steps section.
Automation
#!/usr/bin/env bash
#
# Automation: Ensure kube-scheduler --bind-address is set to 127.0.0.1
#
# Run on: every control plane node (with root privileges)
#
# Operational impact:
# - Editing /etc/kubernetes/manifests/kube-scheduler.yaml will cause the
# kube-scheduler static pod to be restarted by the kubelet.
set -euo pipefail
SCHEDULER_MANIFEST="/etc/kubernetes/manifests/kube-scheduler.yaml"
BACKUP_DIR="/etc/kubernetes/manifests/backup-$(date +%Y%m%d-%H%M%S)"
NEEDED_ADDR="127.0.0.1"
echo "[*] Ensuring kube-scheduler --bind-address is set to ${NEEDED_ADDR}"
echo "[*] This must be run on every control plane node with root privileges."
if [[ ! -f "${SCHEDULER_MANIFEST}" ]]; then
echo "[!] kube-scheduler manifest not found at ${SCHEDULER_MANIFEST}"
echo " This node may not be a control plane node or uses a non-standard path."
exit 1
fi
mkdir -p "${BACKUP_DIR}"
cp -p "${SCHEDULER_MANIFEST}" "${BACKUP_DIR}/kube-scheduler.yaml"
echo "[*] Backed up existing manifest to ${BACKUP_DIR}/kube-scheduler.yaml"
# Check if --bind-address already present and correct
if grep -q -- "--bind-address" "${SCHEDULER_MANIFEST}"; then
if grep -q -- "--bind-address=${NEEDED_ADDR}" "${SCHEDULER_MANIFEST}"; then
echo "[*] --bind-address is already set to ${NEEDED_ADDR}; no change needed."
else
echo "[*] Updating existing --bind-address argument to ${NEEDED_ADDR}"
# Replace any existing --bind-address=<value> with the desired one
sed -i 's/--bind-address=[0-9.]\+/--bind-address='"${NEEDED_ADDR}"'/g' "${SCHEDULER_MANIFEST}"
fi
else
echo "[*] --bind-address not present; adding --bind-address=${NEEDED_ADDR} to arguments."
# Try to insert into args: list under the kube-scheduler container
# This is a simple, idempotent append: if args: list exists, append a new line.
if grep -qE '^\s*args:\s*$' "${SCHEDULER_MANIFEST}"; then
# Append under the first 'args:' occurrence
awk -v addr="${NEEDED_ADDR}" '
BEGIN {added=0}
/^\s*args:\s*$/ && added==0 {
print $0
print " - --bind-address=" addr
added=1
next
}
{print $0}
' "${SCHEDULER_MANIFEST}" > "${SCHEDULER_MANIFEST}.tmp"
mv "${SCHEDULER_MANIFEST}.tmp" "${SCHEDULER_MANIFEST}"
else
echo "[!] Could not locate an args: list to modify in ${SCHEDULER_MANIFEST}."
echo " Please edit the file manually and add:"
echo " - --bind-address=${NEEDED_ADDR}"
echo " under the kube-scheduler container args."
echo " See Manual Steps section for detailed guidance."
exit 1
fi
fi
echo "[*] Change applied. kube-scheduler static pod will be restarted automatically by kubelet."
# Verification: ensure the running kube-scheduler process has the correct flag
echo "[*] Waiting up to 60 seconds for kube-scheduler to restart with new flags..."
end=$((SECONDS+60))
verified=0
while (( SECONDS < end )); do
# shellcheck disable=SC2009
if /bin/ps -ef | grep kube-scheduler | grep -v grep | grep -q -- "--bind-address=${NEEDED_ADDR}"; then
verified=1
break
fi
sleep 3
done
echo
echo "[*] Verification (process flags):"
/bin/ps -ef | grep kube-scheduler | grep -v grep || true
if (( verified == 1 )); then
echo "[+] SUCCESS: kube-scheduler is running with --bind-address=${NEEDED_ADDR}"
exit 0
else
echo "[!] WARNING: kube-scheduler process not yet showing --bind-address=${NEEDED_ADDR}."
echo " Check kubelet and kube-scheduler logs for issues."
exit 1
fi