Skip to content

✨ Apply md-0 KubeletConfiguration security hardening to control-plane#2015

Open
ashish1099 wants to merge 1 commit into
syself:mainfrom
Obmondo:feat/kubelet-security-hardening-on-control-plane
Open

✨ Apply md-0 KubeletConfiguration security hardening to control-plane#2015
ashish1099 wants to merge 1 commit into
syself:mainfrom
Obmondo:feat/kubelet-security-hardening-on-control-plane

Conversation

@ashish1099

Copy link
Copy Markdown

kct-md-0-ubuntu.yaml ships a /etc/kubernetes/kubelet/config.yaml file with the modern KubeletConfiguration shape and a hardened default profile — anonymous=false, webhook auth/authz, eventRecordQPS=5, readOnlyPort=0, serverTLSBootstrap=true, an explicit TLS cipher-suite allow-list. The control-plane KCP templates (hcloud-kcp-ubuntu.yaml, hetznerbaremetal-kcp-ubuntu.yaml) just have a minimal kubeletExtraArgs list — no hardening, no KubeletConfiguration file.

Apply the same KubeletConfiguration file on the control plane:

  • Replace the max-pods + resolv-conf kubeletExtraArgs entries with a single --config pointer at /etc/kubernetes/kubelet/config.yaml.
  • Add the new file under spec.kubeadmConfigSpec.files, identical in shape to md-0's, with maxPods set to 120 (control-plane-appropriate) instead of md-0's 220.
  • Keep --cloud-provider=external as a kubeletExtraArg since it isn't expressible via KubeletConfiguration and is set the same way upstream in md-0.

Both initConfiguration and joinConfiguration get the same treatment in each file, so a fresh init and a subsequent control-plane join land on the same kubelet config.

Why this matters:

  • md-0 nodes refuse anonymous kubelet API requests, run with serverTLSBootstrap, and restrict event-record QPS; control-plane nodes (which run the most sensitive workloads on the cluster) do not. That asymmetry has no defensible reason.
  • Single file is easier to audit than a flag-list. KubeletConfiguration also gives access to fields without CLI flag equivalents (event record QPS, server TLS bootstrap), so the hardening profile is expressible end-to-end.
  • max-pods stays at 120 (vs md-0's 220) because control-plane nodes are sized smaller and typically only run system pods; bumping further has historically caused etcd pressure.

What this PR does / why we need it:

Which issue(s) this PR fixes (optional, in fixes #<issue number>(, fixes #<issue_number>, ...) format, will close the issue(s) when PR gets merged):
Fixes #

Special notes for your reviewer:

Please confirm that if this PR changes any image versions, then that's the sole change this PR makes.

TODOs:

  • squash commits
  • include documentation
  • add unit tests

kct-md-0-ubuntu.yaml ships a /etc/kubernetes/kubelet/config.yaml file
with the modern KubeletConfiguration shape and a hardened default
profile — anonymous=false, webhook auth/authz, eventRecordQPS=5,
readOnlyPort=0, serverTLSBootstrap=true, an explicit TLS cipher-suite
allow-list. The control-plane KCP templates (hcloud-kcp-ubuntu.yaml,
hetznerbaremetal-kcp-ubuntu.yaml) just have a minimal kubeletExtraArgs
list — no hardening, no KubeletConfiguration file.

Apply the same KubeletConfiguration file on the control plane:

  - Replace the max-pods + resolv-conf kubeletExtraArgs entries with
    a single --config pointer at /etc/kubernetes/kubelet/config.yaml.
  - Add the new file under spec.kubeadmConfigSpec.files, identical in
    shape to md-0's, with maxPods set to 120 (control-plane-appropriate)
    instead of md-0's 220.
  - Keep --cloud-provider=external as a kubeletExtraArg since it isn't
    expressible via KubeletConfiguration and is set the same way upstream
    in md-0.

Both initConfiguration and joinConfiguration get the same treatment
in each file, so a fresh init and a subsequent control-plane join
land on the same kubelet config.

Why this matters:
  - md-0 nodes refuse anonymous kubelet API requests, run with
    serverTLSBootstrap, and restrict event-record QPS; control-plane
    nodes (which run the most sensitive workloads on the cluster) do
    not. That asymmetry has no defensible reason.
  - Single file is easier to audit than a flag-list. KubeletConfiguration
    also gives access to fields without CLI flag equivalents (event
    record QPS, server TLS bootstrap), so the hardening profile is
    expressible end-to-end.
  - max-pods stays at 120 (vs md-0's 220) because control-plane nodes
    are sized smaller and typically only run system pods; bumping
    further has historically caused etcd pressure.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant