Kubelet TLS Cert File And TLS Private Key File Arguments
More Info:
The kubelet --tls-cert-file and --tls-private-key-file arguments should be set so the kubelet serves its API over TLS with a valid certificate. Without them, kubelet traffic may be unencrypted.
Risk Level
Medium
Address
Security
Compliance Standards
- CIS OKE
Triage and Remediation
- Remediation
Remediation
Manual Steps
-
On every worker node, check the current kubelet process arguments to confirm the flags are missing or incorrect:
/bin/ps -fC kubelet -
On every worker node, open the kubelet systemd drop-in config for editing:
sudo vi /etc/systemd/system/kubelet.service.d/00-default.conf -
In the opened file, locate the line starting with
ExecStart=and ensure it includes the following flags (add or correct them within the existing line, preserving other arguments):--tls-cert-file=/var/lib/kubelet/pki/tls.pem \--tls-private-key-file=/var/lib/kubelet/pki/tls.keyFor example, the
ExecStart=line should contain (example only; keep your other flags):ExecStart=/usr/bin/kubelet ... --tls-cert-file=/var/lib/kubelet/pki/tls.pem --tls-private-key-file=/var/lib/kubelet/pki/tls.key ... -
On every worker node, reload systemd and restart kubelet (this will restart the kubelet and may briefly impact node scheduling/registration):
sudo systemctl daemon-reloadsudo systemctl restart kubelet.service -
On every worker node, check that kubelet is healthy:
sudo systemctl status kubelet -l -
On every worker node, verify that the kubelet is now running with the correct TLS certificate and key arguments:
/bin/ps -fC kubelet | grep -- '--tls-'Confirm the output shows:
--tls-cert-file=/var/lib/kubelet/pki/tls.pem--tls-private-key-file=/var/lib/kubelet/pki/tls.key
Using kubectl
kubectl cannot modify kubelet process flags or host-level config files, so this finding cannot be fixed via Kubernetes API objects. The correction must be done on each worker node’s OS (editing /etc/systemd/system/kubelet.service.d/00-default.conf and related files); follow the Manual Steps section for the exact procedure.
Automation
#!/usr/bin/env bash
#
# Remediate CIS OKE 3.2.8:
# Ensure kubelet is started with --tls-cert-file and --tls-private-key-file
#
# Run on: every worker node (with root privileges)
# Usage: sudo ./fix-kubelet-tls.sh
set -euo pipefail
KUBELET_DROPIN_DIR="/etc/systemd/system/kubelet.service.d"
KUBELET_DROPIN_FILE="${KUBELET_DROPIN_DIR}/00-default.conf"
TLS_CERT_ARG="--tls-cert-file=/var/lib/kubelet/pki/tls.pem"
TLS_KEY_ARG="--tls-private-key-file=/var/lib/kubelet/pki/tls.key"
echo "[INFO] Ensuring kubelet systemd drop-in exists at ${KUBELET_DROPIN_FILE}"
if [ ! -d "${KUBELET_DROPIN_DIR}" ]; then
mkdir -p "${KUBELET_DROPIN_DIR}"
fi
if [ ! -f "${KUBELET_DROPIN_FILE}" ]; then
echo "[INFO] Creating new ${KUBELET_DROPIN_FILE}"
cat > "${KUBELET_DROPIN_FILE}" <<'EOF'
[Service]
Environment="KUBELET_EXTRA_ARGS="
EOF
fi
echo "[INFO] Making ${KUBELET_DROPIN_FILE} idempotent for KUBELET_EXTRA_ARGS"
# Ensure there is a single KUBELET_EXTRA_ARGS Environment line
if grep -q '^Environment="KUBELET_EXTRA_ARGS=' "${KUBELET_DROPIN_FILE}"; then
:
else
echo '[Service]' >> "${KUBELET_DROPIN_FILE}"
echo 'Environment="KUBELET_EXTRA_ARGS="' >> "${KUBELET_DROPIN_FILE}"
fi
# Normalize file to avoid multiple duplicates of the TLS args
TMP_FILE="$(mktemp)"
trap 'rm -f "${TMP_FILE}"' EXIT
while IFS= read -r line; do
if [[ "${line}" =~ ^Environment=\"KUBELET_EXTRA_ARGS= ]]; then
# Strip trailing quote, ensure space-separated args
current="${line#Environment=\"KUBELET_EXTRA_ARGS=}"
current="${current%\"}"
# Remove any existing tls-cert-file / tls-private-key-file flags
# shellcheck disable=SC2206
args=(${current})
new_args=()
for a in "${args[@]}"; do
case "${a}" in
--tls-cert-file=*|--tls-private-key-file=*)
# skip old values
;;
*)
new_args+=("${a}")
;;
esac
done
# Append required arguments
new_args+=("${TLS_CERT_ARG}" "${TLS_KEY_ARG}")
# Reconstruct line
joined="$(printf '%s ' "${new_args[@]}")"
joined="${joined%" "}"
echo "Environment=\"KUBELET_EXTRA_ARGS=${joined}\"" >> "${TMP_FILE}"
else
echo "${line}" >> "${TMP_FILE}"
fi
done < "${KUBELET_DROPIN_FILE}"
mv "${TMP_FILE}" "${KUBELET_DROPIN_FILE}"
echo "[INFO] Reloading systemd and restarting kubelet (this will restart kubelet)"
systemctl daemon-reload
systemctl restart kubelet.service
echo "[INFO] Checking kubelet status"
systemctl status kubelet -l --no-pager || true
echo "[INFO] Verifying kubelet process flags for TLS settings"
/bin/ps -fC kubelet || {
echo "[ERROR] kubelet process not found after restart"
exit 1
}
if /bin/ps -fC kubelet | grep -q "${TLS_CERT_ARG}" && \
/bin/ps -fC kubelet | grep -q "${TLS_KEY_ARG}"; then
echo "[SUCCESS] kubelet is running with ${TLS_CERT_ARG} and ${TLS_KEY_ARG}"
exit 0
else
echo "[ERROR] kubelet is NOT running with required TLS flags."
echo "Current kubelet command line:"
/bin/ps -fC kubelet || true
exit 2
fi