Skip to main content

Kubelet Read Only Port Argument Set To 0

More Info:

The kubelet --read-only-port argument should be set to 0 to disable the unauthenticated read-only port. This port exposes node and pod information without authentication.

Risk Level

High

Address

Security

Compliance Standards

  • CIS OKE

Triage and Remediation

Remediation

Manual Steps
  1. On every worker node, open the kubelet systemd drop-in config for editing:

    sudo vi /etc/systemd/system/kubelet.service.d/00-default.conf
  2. In the ExecStart= line, ensure the kubelet is started with the read-only port disabled. Add --read-only-port=0 if it is missing, or change its value if present. For example:

    ExecStart=/usr/bin/kubelet \
    --config=/etc/kubernetes/kubelet-config.json \
    --read-only-port=0 \
    ...
  3. If the kubelet config file /etc/kubernetes/kubelet-config.json contains a readOnlyPort field, set it to 0 (or remove the field so the flag value is authoritative). For example:

    sudo vi /etc/kubernetes/kubelet-config.json

    Ensure it looks like:

    {
    "readOnlyPort": 0,
    ...
    }
  4. Reload systemd and restart kubelet on the worker node:

    sudo systemctl daemon-reload
    sudo systemctl restart kubelet.service
  5. Confirm kubelet is running correctly:

    sudo systemctl status kubelet -l
  6. Verify on the same worker node that the kubelet process includes --read-only-port=0:

    /bin/ps -fC kubelet

    Check the output and ensure --read-only-port=0 is present and there is no conflicting --read-only-port with a nonzero value.

Using kubectl

kubectl cannot modify kubelet process flags or the host-level config file /etc/kubernetes/kubelet-config.json on worker nodes. To set --read-only-port=0, you must update the kubelet’s systemd configuration under /etc/systemd/system/kubelet.service.d/00-default.conf on every worker node and then restart kubelet; see the Manual Steps section for exact commands.

Automation
#!/usr/bin/env bash
#
# Remediation: Ensure kubelet --read-only-port is set to 0 via systemd drop-in
# Scope: Run on every worker node (as root)
# Idempotent: Safe to re-run

set -euo pipefail

KUBELET_DROPIN_DIR="/etc/systemd/system/kubelet.service.d"
KUBELET_DROPIN_FILE="${KUBELET_DROPIN_DIR}/00-default.conf"
BACKUP_SUFFIX=".pre-readonly-port-0.$(date +%Y%m%d%H%M%S)"

echo "[INFO] Ensuring kubelet --read-only-port=0 on this node"

if [[ ! -d "${KUBELET_DROPIN_DIR}" ]]; then
echo "[ERROR] ${KUBELET_DROPIN_DIR} does not exist. Is kubelet managed by systemd on this node?"
exit 1
fi

if [[ ! -f "${KUBELET_DROPIN_FILE}" ]]; then
echo "[WARN] ${KUBELET_DROPIN_FILE} not found, creating a new drop-in."
cat > "${KUBELET_DROPIN_FILE}" <<'EOF'
[Service]
Environment="KUBELET_EXTRA_ARGS=--read-only-port=0"
EOF
else
echo "[INFO] Updating ${KUBELET_DROPIN_FILE} to enforce --read-only-port=0"

cp "${KUBELET_DROPIN_FILE}" "${KUBELET_DROPIN_FILE}${BACKUP_SUFFIX}"

# If KUBELET_EXTRA_ARGS is present, ensure it contains --read-only-port=0
if grep -q '^Environment="KUBELET_EXTRA_ARGS=' "${KUBELET_DROPIN_FILE}"; then
# Remove any existing read-only-port settings, then append correct one
tmp_file="$(mktemp)"
sed -E 's/--read-only-port=[0-9]+//g' "${KUBELET_DROPIN_FILE}" > "${tmp_file}"

# Ensure we don't end up with multiple spaces
sed -i 's/ */ /g' "${tmp_file}"

# Append flag inside the Environment="KUBELET_EXTRA_ARGS=..." line
awk '
/^Environment="KUBELET_EXTRA_ARGS=/ {
sub(/"$/, " --read-only-port=0\"")
}
{ print }
' "${tmp_file}" > "${KUBELET_DROPIN_FILE}"
rm -f "${tmp_file}"
else
# No KUBELET_EXTRA_ARGS line; add one
echo 'Environment="KUBELET_EXTRA_ARGS=--read-only-port=0"' >> "${KUBELET_DROPIN_FILE}"
fi
fi

echo "[INFO] Reloading systemd and restarting kubelet (this will restart kubelet on this node)"

systemctl daemon-reload
systemctl restart kubelet.service

echo "[INFO] kubelet status:"
systemctl status kubelet -l --no-pager || true

echo "[INFO] Verifying kubelet is running with --read-only-port=0"
if /bin/ps -fC kubelet | grep -q -- '--read-only-port=0'; then
if /bin/ps -fC kubelet | grep -E -- '--read-only-port=[1-9]'; then
echo "[FAIL] Conflicting --read-only-port flag values detected in kubelet process:"
/bin/ps -fC kubelet
exit 1
fi
echo "[PASS] kubelet is configured with --read-only-port=0 on this node."
else
echo "[FAIL] kubelet is not running with --read-only-port=0. Current kubelet command line:"
/bin/ps -fC kubelet || true
exit 1
fi

Usage:

  • Copy this script to every worker node (for example /root/fix-kubelet-readonly-port.sh).
  • Run as root on every worker node:
    bash /root/fix-kubelet-readonly-port.sh