Ensure Kubelet Https Argument Is Enabled
More Info:
Use https for kubelet connections.
Risk Level
High
Address
Security
Compliance Standards
- CIS Kubernetes
Triage and Remediation
- Remediation
Remediation
Manual Steps
-
SSH to each control plane node
ssh root@<control-plane-node-ip> -
Backup the API server static pod manifest
cp -p /etc/kubernetes/manifests/kube-apiserver.yaml \/etc/kubernetes/manifests/kube-apiserver.yaml.bak -
Edit the manifest to remove the
--kubelet-httpsargument
Open the file in an editor on the control plane node:vi /etc/kubernetes/manifests/kube-apiserver.yamlIn the
command:orargs:list forkube-apiserver, delete the entire line containing:--kubelet-https=falseor
--kubelet-https=true(Remove the flag completely, do not re-add it with another value.)
Save and exit the editor.Note: Editing this file will cause the kube-apiserver static pod to be restarted by kubelet.
-
Wait for the kube-apiserver pod to restart and become Running
From any machine withkubectlaccess:kubectl get pods -n kube-system -o wide | grep kube-apiserverRepeat until the
kube-apiserver-<node-name>pod is inRunningandREADYstatus. -
Verify the kube-apiserver is no longer started with
--kubelet-https
On the same control plane node:/bin/ps -ef | grep kube-apiserver | grep -v grepConfirm that in the printed command line there is no
--kubelet-https=argument present.
Using kubectl
kubectl cannot change the kube-apiserver static pod manifest or its process flags, so this finding cannot be remediated via the Kubernetes API. To fix it, you must edit /etc/kubernetes/manifests/kube-apiserver.yaml directly on every control plane node as described in the Manual Steps section.
Automation
#!/usr/bin/env bash
#
# Automation: Ensure kube-apiserver does not use deprecated --kubelet-https flag
#
# Scope: run on every control plane node (with root or sudo privileges)
# Effect: editing /etc/kubernetes/manifests/kube-apiserver.yaml causes the
# kube-apiserver static pod to be recreated automatically by kubelet.
set -euo pipefail
API_MANIFEST="/etc/kubernetes/manifests/kube-apiserver.yaml"
BACKUP_DIR="/etc/kubernetes/manifests/backup-$(date +%Y%m%d)"
CHANGED=0
if [ ! -f "$API_MANIFEST" ]; then
echo "ERROR: $API_MANIFEST not found on this node; is this a control plane node?"
exit 1
fi
mkdir -p "$BACKUP_DIR"
backup_file="${BACKUP_DIR}/kube-apiserver.yaml.$(date +%H%M%S)"
cp -p "$API_MANIFEST" "$backup_file"
echo "Backup of $API_MANIFEST created at $backup_file"
# Remove any occurrence of the --kubelet-https argument line
if grep -q -- '--kubelet-https' "$API_MANIFEST"; then
# This sed deletes any line containing --kubelet-https (with or without value)
# while preserving all other content.
sed '/--kubelet-https/d' "$API_MANIFEST" > "${API_MANIFEST}.tmp"
mv "${API_MANIFEST}.tmp" "$API_MANIFEST"
CHANGED=1
echo "Removed --kubelet-https from $API_MANIFEST"
else
echo "--kubelet-https argument not present in $API_MANIFEST; no changes made."
fi
# If we changed the manifest, kubelet will automatically restart the apiserver pod.
if [ "$CHANGED" -eq 1 ]; then
echo "Waiting up to 120 seconds for kube-apiserver pod to be recreated..."
# Optional wait loop (does not fail script if unavailable)
end=$((SECONDS+120))
while [ $SECONDS -lt $end ]; do
if /bin/ps -ef | grep '[k]ube-apiserver' >/dev/null 2>&1; then
break
fi
sleep 5
done
fi
echo "Verification: ensuring kube-apiserver is not started with --kubelet-https"
if /bin/ps -ef | grep '[k]ube-apiserver' | grep -- '--kubelet-https' >/dev/null 2>&1; then
echo "FAIL: kube-apiserver still running with --kubelet-https argument:"
/bin/ps -ef | grep kube-apiserver | grep -v grep
exit 2
fi
echo "PASS: kube-apiserver is running without --kubelet-https argument."
/bin/ps -ef | grep kube-apiserver | grep -v grep || true