> ## 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 Pod PIDs Limit Is Set

### More Info:

Setting a limit on pod PIDs prevents a single pod from exhausting process resources on the node. This protects other workloads from process-based denial of service.

### Risk Level

Low

### Address

Security

### Compliance Standards

* CIS Kubernetes

### Triage and Remediation

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

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. **Determine your desired PID limit per pod**
           * Run on: any worker node (for planning)
           * Choose a value that fits your workload (for example: 1024). You will use this value for `podPidsLimit` (config file) or `--pod-max-pids` (flag).

        2. **Check how kubelet is configured (config file vs flags)**
           * Run on: every worker node
           ```bash theme={null}
           # See how kubelet is started
           sudo systemctl status kubelet -l

           # If it uses a config file, confirm the contents:
           sudo cat /var/lib/kubelet/config.yaml
           ```
           * If you see `--pod-max-pids` in the kubelet command line, you will adjust the systemd unit (step 4).
           * If kubelet is using `--config=/var/lib/kubelet/config.yaml` and the file has a `KubeletConfiguration` object, you will adjust that file (step 3).

        3. **Set PodPidsLimit in /var/lib/kubelet/config.yaml (config-file based setups)**
           * Run on: every worker node
           * Edit the file:
           ```bash theme={null}
           sudo vi /var/lib/kubelet/config.yaml
           ```
           * Under the top-level `KubeletConfiguration`, add or modify the `podPidsLimit` field (replace `1024` with your chosen value):
           ```yaml theme={null}
           kind: KubeletConfiguration
           apiVersion: kubelet.config.k8s.io/v1beta1
           ...
           podPidsLimit: 1024
           ```
           * Save the file.

        4. **Set --pod-max-pids flag in the kubelet systemd unit (flag-based setups)**
           * Run on: every worker node
           * Edit the systemd drop-in or unit that defines kubelet arguments (path may differ by distro; common examples):
             ```bash theme={null}
             # Example: check for a drop-in
             sudo ls /etc/systemd/system/kubelet.service.d/
             sudo cat /etc/systemd/system/kubelet.service.d/10-kubelet.conf
             ```
           * Add or update `--pod-max-pids` in the kubelet arguments (replace `1024` with your chosen value). For example, in a drop-in file:
           ```ini theme={null}
           [Service]
           Environment="KUBELET_EXTRA_ARGS=--pod-max-pids=1024"
           ```
           * Or append `--pod-max-pids=1024` to an existing `ExecStart=` line that launches kubelet.
           * Reload systemd configuration:
           ```bash theme={null}
           sudo systemctl daemon-reload
           ```

        5. **Restart kubelet to apply the new limit**
           * Run on: every worker node
           * Impact: restarting kubelet can temporarily disrupt node status and pod management on that node.
           ```bash theme={null}
           sudo systemctl restart kubelet
           sudo systemctl status kubelet -l
           ```

        6. **Verify kubelet is running with a pod PIDs limit**
           * Run on: every worker node
           ```bash theme={null}
           /bin/ps -fC kubelet
           ```
           * Confirm **either**:
             * The output command line includes `--pod-max-pids=1024` (or your chosen value), **or**
             * Kubelet is using `--config=/var/lib/kubelet/config.yaml` and the file contains `podPidsLimit: 1024` as configured in step 3.
      </Accordion>

      <Accordion title="Using kubectl">
        kubectl cannot be used to set the kubelet `PodPidsLimit` or `--pod-max-pids` value, because this is a host-level kubelet configuration in `/var/lib/kubelet/config.yaml` or the kubelet systemd unit on every worker node. Make the change directly on each worker node’s kubelet configuration as described in the Manual Steps section.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Automation: Ensure kubelet PodPidsLimit is set on every worker node
        #
        # Usage:
        #   1) Run from an admin machine that has SSH access and sudo on every worker.
        #   2) Provide a file with one worker node (hostname or IP) per line:
        #        ./set_pod_pids_limit.sh workers.txt
        #
        # This script:
        #   - Connects via SSH to each worker node
        #   - Ensures /var/lib/kubelet/config.yaml exists and sets PodPidsLimit
        #   - Leaves any existing non-zero PodPidsLimit unchanged (idempotent)
        #   - Restarts kubelet if a change was made
        #   - Verifies PodPidsLimit via kubelet --version && grep in config
        #
        # NOTE: This acts on host-level config; it cannot be run via kubectl alone.

        set -euo pipefail

        WORKER_LIST_FILE="${1:-}"

        if [[ -z "$WORKER_LIST_FILE" || ! -f "$WORKER_LIST_FILE" ]]; then
          echo "Usage: $0 <worker-node-list-file>"
          echo "  <worker-node-list-file> must contain one worker hostname/IP per line."
          exit 1
        fi

        # Desired PodPidsLimit value. Adjust to your operational requirement.
        DESIRED_POD_PIDS_LIMIT="4096"

        SSH_OPTS="-o BatchMode=yes -o StrictHostKeyChecking=no -o ConnectTimeout=10"

        run_on_node() {
          local node="$1"
          shift
          ssh $SSH_OPTS "$node" "$@"
        }

        while IFS= read -r NODE || [[ -n "$NODE" ]]; do
          [[ -z "$NODE" ]] && continue
          echo "==== Processing worker node: $NODE ===="

          # 1) Ensure kubelet config exists and PodPidsLimit is set/updated (runs on every worker node)
          run_on_node "$NODE" "sudo bash -s" <<'EOF'
        set -euo pipefail

        CONFIG_FILE="/var/lib/kubelet/config.yaml"
        DESIRED_POD_PIDS_LIMIT="4096"
        CHANGED="false"

        if [[ ! -f \"\$CONFIG_FILE\" ]]; then
          echo \"[WARN] \${CONFIG_FILE} does not exist. Cannot set PodPidsLimit automatically.\"
          exit 0
        fi

        # If PodPidsLimit is already present and non-zero, leave it as-is (idempotent, respects existing tuning)
        EXISTING_VAL=\$(sudo awk '/^[[:space:]]*PodPidsLimit:/ {print $2}' \"\$CONFIG_FILE\" | head -n1 || true)
        if [[ -n \"\$EXISTING_VAL\" && \"\$EXISTING_VAL\" != \"0\" ]]; then
          echo \"[INFO] PodPidsLimit already set to \${EXISTING_VAL} in \${CONFIG_FILE}; leaving unchanged.\"
        else
          echo \"[INFO] Setting PodPidsLimit to \${DESIRED_POD_PIDS_LIMIT} in \${CONFIG_FILE}.\"
          TMP_FILE=\"\${CONFIG_FILE}.tmp.cis_podpids\"

          # If key exists but is 0 or blank, replace it; otherwise append at end
          if grep -qE '^[[:space:]]*PodPidsLimit:' \"\$CONFIG_FILE\"; then
            sudo sed -E \"s|^[[:space:]]*PodPidsLimit:.*|PodPidsLimit: \${DESIRED_POD_PIDS_LIMIT}|\" \"\$CONFIG_FILE\" > \"\$TMP_FILE\"
          else
            sudo cp \"\$CONFIG_FILE\" \"\$TMP_FILE\"
            echo \"PodPidsLimit: \${DESIRED_POD_PIDS_LIMIT}\" | sudo tee -a \"\$TMP_FILE\" >/dev/null
          fi

          sudo mv \"\$TMP_FILE\" \"\$CONFIG_FILE\"
          CHANGED=\"true\"
        fi

        # 2) If we changed config, restart kubelet so it picks up the new setting
        if [[ \"\$CHANGED\" == \"true\" ]]; then
          echo \"[INFO] Restarting kubelet (this will temporarily restart workloads on this node).\"
          if command -v systemctl >/dev/null 2>&1; then
            sudo systemctl restart kubelet
          elif command -v service >/dev/null 2>&1; then
            sudo service kubelet restart
          else
            echo \"[WARN] Could not find systemctl or service to restart kubelet. Please restart kubelet manually.\"
          fi
        fi

        # 3) Verification: show PodPidsLimit from config and kubelet process status
        echo \"[VERIFY] kubelet process (ps -fC kubelet):\"
        ps -fC kubelet || echo \"[WARN] kubelet not found in process list.\"

        echo \"[VERIFY] PodPidsLimit in \${CONFIG_FILE}:\" 
        sudo awk '/^[[:space:]]*PodPidsLimit:/ {print \"PodPidsLimit:\", $2}' \"\$CONFIG_FILE\" || true
        EOF

          echo "==== Completed worker node: $NODE ===="
          echo
        done < "$WORKER_LIST_FILE"

        echo "All nodes processed. Re-run this script safely at any time; it is idempotent."
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
