Skip to main content

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

Manual Steps
  1. 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
  2. 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.yaml

    If the --bind-address flag is not present, add it under the command: list for kube-scheduler, for example:

    spec:
    containers:
    - command:
    - kube-scheduler
    - --bind-address=127.0.0.1

    Save the file; kubelet will automatically restart the kube-scheduler pod when the manifest changes (expect a brief control-plane impact).

  3. On every control plane node, wait for the kube-scheduler pod to be recreated and running:

    sudo crictl ps | grep kube-scheduler

    Ensure the scheduler container shows a recent start time and is in running state.

  4. 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 grep

    Confirm the output includes --bind-address=127.0.0.1 and no other --bind-address value.

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