> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kubelet RotateKubeletServerCertificate Set To True

### More Info:

The RotateKubeletServerCertificate feature gate should be true so the kubelet automatically rotates its serving certificates, preventing expiry-related failures.

### Risk Level

High

### Address

Security

### Compliance Standards

* CIS AKS

### Triage and Remediation

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. On every worker node, open the kubelet systemd drop-in file for editing (create it if it does not exist yet):

        ```bash theme={null}
        sudo mkdir -p /etc/systemd/system/kubelet.service.d
        sudo vi /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
        ```

        2. In that file, ensure there is an Environment line that includes the RotateKubeletServerCertificate feature gate. For example, add or update:

        ```ini theme={null}
        [Service]
        Environment="KUBELET_CERTIFICATE_ARGS=--feature-gates=RotateKubeletServerCertificate=true"
        ```

        If other `Environment="KUBELET_...` lines already exist, keep them and only add or adjust the `KUBELET_CERTIFICATE_ARGS` line.

        3. If the kubelet is also configured via `/etc/default/kubelet` or `/var/lib/kubelet/kubeadm-flags.env`, check those files to ensure they do not override the feature gate. On every worker node:

        ```bash theme={null}
        sudo grep -n "feature-gates" /etc/default/kubelet /var/lib/kubelet/kubeadm-flags.env 2>/dev/null || true
        ```

        If you see `RotateKubeletServerCertificate=false` anywhere, edit the file and remove that part or change it to `true`.

        4. Reload systemd configuration and restart kubelet on every worker node:

        ```bash theme={null}
        sudo systemctl daemon-reload
        sudo systemctl restart kubelet.service
        ```

        5. Confirm kubelet is healthy on every worker node:

        ```bash theme={null}
        sudo systemctl status kubelet.service --no-pager
        ```

        6. Verify the kubelet process is running with `RotateKubeletServerCertificate=true` on every worker node:

        ```bash theme={null}
        /bin/ps -fC kubelet | grep -o 'RotateKubeletServerCertificate=[^,"]*' || echo "feature gate not found in args"
        ```
      </Accordion>

      <Accordion title="Using kubectl">
        kubectl cannot modify kubelet process flags or host-level configuration files, so this finding cannot be fixed via Kubernetes API changes. Configure `RotateKubeletServerCertificate` in `/etc/systemd/system/kubelet.service.d/10-kubeadm.conf` on every worker node as described, and follow the steps in the Manual Steps section.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        # Automation: enable RotateKubeletServerCertificate feature gate for kubelet
        # Run on: every worker node (as root)
        set -euo pipefail

        KUBELET_DROPIN="/etc/systemd/system/kubelet.service.d/10-kubeadm.conf"
        BACKUP_SUFFIX="$(date +%Y%m%d%H%M%S)"

        if [[ ! -f "$KUBELET_DROPIN" ]]; then
          echo "ERROR: $KUBELET_DROPIN not found on this node. Aborting."
          exit 1
        fi

        echo "Backing up $KUBELET_DROPIN to ${KUBELET_DROPIN}.${BACKUP_SUFFIX}.bak"
        cp -p "$KUBELET_DROPIN" "${KUBELET_DROPIN}.${BACKUP_SUFFIX}.bak"

        # Ensure KUBELET_CERTIFICATE_ARGS line exists
        if ! grep -qE '^\s*Environment=.*KUBELET_CERTIFICATE_ARGS=' "$KUBELET_DROPIN"; then
          echo "Adding KUBELET_CERTIFICATE_ARGS environment line to $KUBELET_DROPIN"
          cat <<'EOF' >>"$KUBELET_DROPIN"
        Environment="KUBELET_CERTIFICATE_ARGS="
        EOF
        fi

        # Idempotently ensure RotateKubeletServerCertificate=true is in feature-gates
        tmpfile="$(mktemp)"
        trap 'rm -f "$tmpfile"' EXIT

        awk '
          BEGIN {
            target="RotateKubeletServerCertificate=true"
          }
          # Process lines containing KUBELET_CERTIFICATE_ARGS
          /KUBELET_CERTIFICATE_ARGS=/ {
            # Remove any existing RotateKubeletServerCertificate entry
            gsub(/RotateKubeletServerCertificate=[^,"]*/, "", $0)
            # Clean up any duplicate commas in feature-gates list
            gsub(/,,+/, ",", $0)
            gsub(/feature-gates=,/, "feature-gates=", $0)
            gsub(/, *"/, "\"", $0)

            if ($0 ~ /--feature-gates=/) {
              # Append our gate to existing feature-gates
              sub(/--feature-gates=([^" ]*)/, "&," target, $0)
              # Fix potential leading/trailing commas
              gsub(/--feature-gates=,/, "--feature-gates=", $0)
              gsub(/,--feature-gates=/, "--feature-gates=", $0)
              gsub(/,+"/, "\"", $0)
            } else {
              # No feature-gates yet; add one
              # Insert before closing quote if present
              if ($0 ~ /"$/) {
                sub(/"$/, " --feature-gates=" target "\"", $0)
              } else {
                $0 = $0 " --feature-gates=" target
              }
            }
          }
          { print }
        ' "$KUBELET_DROPIN" >"$tmpfile"

        mv "$tmpfile" "$KUBELET_DROPIN"

        echo "Reloading systemd and restarting kubelet (this will restart kubelet on this node)..."
        systemctl daemon-reload
        systemctl restart kubelet.service

        echo "Verifying kubelet process has RotateKubeletServerCertificate=true enabled..."
        /bin/ps -fC kubelet || {
          echo "ERROR: kubelet process not found after restart."
          exit 1
        }

        if /bin/ps -fC kubelet | grep -q -- '--feature-gates=.*RotateKubeletServerCertificate=true'; then
          echo "SUCCESS: kubelet is running with RotateKubeletServerCertificate=true on this node."
          exit 0
        else
          echo "ERROR: kubelet is not running with RotateKubeletServerCertificate=true."
          echo "Current kubelet command line:"
          /bin/ps -fC kubelet
          exit 1
        fi
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
