Skip to main content

Kubelet Read Only Port Argument Set To 0

More Info:

The kubelet read-only port serves cluster information without authentication or authorization. Setting --read-only-port to 0 disables this unauthenticated endpoint.

Risk Level

High

Address

Security

Compliance Standards

  • CIS Kubernetes

Triage and Remediation

Remediation

Manual Steps
  1. On every worker node, open the kubelet config file and set readOnlyPort to 0 (create the key if missing):

    sudo sed -i 's/^readOnlyPort: .*/readOnlyPort: 0/' /var/lib/kubelet/config.yaml || \
    echo "readOnlyPort: 0" | sudo tee -a /var/lib/kubelet/config.yaml
  2. Still on every worker node, ensure any kubelet systemd drop-in does not override this with a non‑zero flag. Inspect:

    sudo grep -R --color -n "read-only-port" /etc/systemd/system/kubelet.service.d /etc/systemd/system/kubelet.service 2>/dev/null || echo "No read-only-port flags found in systemd units."

    If you see a line like --read-only-port=10255, edit the file to set it to 0, for example:

    sudo sed -i 's/--read-only-port=[0-9]\+/--read-only-port=0/' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
  3. Reload systemd and restart kubelet on every worker node (this will briefly disrupt workloads on that node):

    sudo systemctl daemon-reload
    sudo systemctl restart kubelet.service
  4. Verify on every worker node that kubelet is running with --read-only-port=0 (or not present at all, relying on the config file) using the audit command:

    /bin/ps -fC kubelet

    Inspect the output and confirm:

    • Either there is no --read-only-port flag, and
    • If present, it appears only as --read-only-port=0.
Using kubectl

kubectl cannot modify kubelet host-level configuration or process flags, so it cannot be used to set readOnlyPort to 0. This must be fixed directly on each worker node (for example in /var/lib/kubelet/config.yaml or the kubelet systemd drop-in), so follow the guidance in the Manual Steps section on those nodes.

Automation
#!/usr/bin/env bash
#
# Purpose:
# Disable the kubelet read-only port by setting readOnlyPort: 0
# in /var/lib/kubelet/config.yaml on every worker node, then
# restart kubelet and verify.
#
# Usage:
# Run on each worker node as root (or with sudo):
# sudo bash ./fix-kubelet-readonly-port.sh
#
# Idempotent:
# Safe to re-run; it preserves existing config and only enforces readOnlyPort: 0.

set -euo pipefail

CONFIG_FILE="/var/lib/kubelet/config.yaml"
BACKUP_DIR="/var/lib/kubelet/backup-$(date +%Y%m%d)"
SYSTEMD_UNIT="kubelet.service"

echo "[INFO] Checking kubelet config file at ${CONFIG_FILE}"

if [[ ! -f "${CONFIG_FILE}" ]]; then
echo "[ERROR] ${CONFIG_FILE} not found on this node."
echo "[ERROR] This script only manages kubelet configured via ${CONFIG_FILE}."
exit 1
fi

mkdir -p "${BACKUP_DIR}"

# Backup once per day (idempotent enough and cheap)
BACKUP_FILE="${BACKUP_DIR}/config.yaml.$(hostname)"
if [[ ! -f "${BACKUP_FILE}" ]]; then
echo "[INFO] Backing up ${CONFIG_FILE} to ${BACKUP_FILE}"
cp -a "${CONFIG_FILE}" "${BACKUP_FILE}"
else
echo "[INFO] Backup ${BACKUP_FILE} already exists; skipping backup."
fi

# Ensure readOnlyPort: 0 is present.
# Strategy:
# - If a readOnlyPort line exists, replace its value with 0.
# - If no such line exists, append "readOnlyPort: 0" at the end.
# This is a simple, line-based edit and assumes no YAML anchors/templates.
echo "[INFO] Ensuring readOnlyPort is set to 0 in ${CONFIG_FILE}"

if grep -Eq '^\s*readOnlyPort\s*:' "${CONFIG_FILE}"; then
# Normalize any existing setting to 0
sed -i -E 's/^\s*readOnlyPort\s*:.*/readOnlyPort: 0/' "${CONFIG_FILE}"
else
echo "readOnlyPort: 0" >> "${CONFIG_FILE}"
fi

echo "[INFO] Current readOnlyPort setting:"
grep -E '^\s*readOnlyPort\s*:' "${CONFIG_FILE}" || echo "[WARN] readOnlyPort line not found after edit"

# Reload systemd and restart kubelet
echo "[INFO] Reloading systemd daemon and restarting ${SYSTEMD_UNIT}"
systemctl daemon-reload
systemctl restart "${SYSTEMD_UNIT}"

# Verification: use the same process inspection approach as the audit,
# and also confirm the config file value.
echo "[INFO] Verifying kubelet process is running and read-only port is disabled"

if ! /bin/ps -fC kubelet >/dev/null 2>&1; then
echo "[ERROR] kubelet process not found after restart. Check systemctl status kubelet."
exit 1
fi

echo "[INFO] kubelet process:"
/bin/ps -fC kubelet || true

echo "[INFO] Verifying readOnlyPort in ${CONFIG_FILE} is set to 0"
if grep -Eq '^\s*readOnlyPort\s*:\s*0\s*$' "${CONFIG_FILE}"; then
echo "[INFO] readOnlyPort correctly set to 0 in config file."
else
echo "[ERROR] readOnlyPort is not set to 0 in ${CONFIG_FILE}. Manual review required."
exit 1
fi

echo "[INFO] Verification complete on this worker node."