工作节点

简要概述

关于在工作节点上组件的安全配置建议。

配置文件

确保 kubelet 配置文件权限

文件权限必须小于等于 “644”

stat -c %a /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
stat -c %a /etc/systemd/system/kubelet.service
stat -c %a /etc/default/kubelet
stat -c %a /etc/kubernetes/kubelet.conf
stat -c %a /var/lib/kubelet/config.yaml

文件归属用户必须为 “root:root”

stat -c %U:%G /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
stat -c %U:%G /etc/systemd/system/kubelet.service
stat -c %U:%G /etc/default/kubelet
stat -c %U:%G /etc/kubernetes/kubelet.conf
stat -c %U:%G /var/lib/kubelet/config.yaml

确保未开启匿名访问

kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
staticPodPath: /etc/kubernetes/manifests
address: 192.168.0.2
port: 10250
readOnlyPort: 0
authentication:
  anonymous:
    enabled: false
  webhook:
    enabled: true
    cacheTTL: 2m0s
  x509:
    clientCAFile: /etc/kubernetes/pki/ca.crt

以上配置 “authentication.anonymous.enabled” 设置为 “false”

确保鉴权模式非允许所有

kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
authorization:
  mode: Webhook
  webhook:
    cacheAuthorizedTTL: 5m0s
    cacheUnauthorizedTTL: 30s

以上配置 “authorization.mode” 非设置为 “AlwaysAllow”,避免敏感数据 “kubelet:10250/configz” 等被非法获取。

确保开启 kubelet 验证来自 kube-apiserver 请求

kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
authentication:
  x509:
    clientCAFile: /etc/kubernetes/pki/ca.crt

从 kube-apiserver 到 kubelet 的连接在以下三个地址会使用到:

  1. 用于获取 pod 日志;
  2. 连接到正在运行的 pod;
  3. 使用 kubelet 端口转发功能。

默认情况下 kube-apiserver 不会验证 kubelet 的服务证书,这会使连接受到中间人攻击,并且在不受信任的网络上运行。

通过设置 “authentication.x509.clientCAFile” 启用 kubelet 证书身份验证同时需保证 kube-apiserver 配置的地址 配置了以下参数:

--kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt
--kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key

如果证书不匹配时,从 kube-apiserver 至 kubelet 会出现以下错误日志:

kubectl exec -i -t default-ingress-nginx-controller-7gb62 /bin/bash -n kube-system
journalctl -f /usr/bin/kubelet

Oct 12 14:06:07 limiqi-dell-01 kubelet[1967008]: E1012 14:06:07.419980 1967008 server.go:273] "Unable to authenticate the request due to an error" err="verifying certificate SN=13890730310367349504, SKID=, AKID= failed: x509: certificate signed by unknown authority"

确保关闭只读端口配置

kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
staticPodPath: /etc/kubernetes/manifests
address: 192.168.0.2
port: 10250
readOnlyPort: 0

Kubelet 除了提供 “https 10250” 端口外,还提供了只读的 “http 10255” 协议端口,对该只读接口提供未经身份验证的访问,该访问可能会检索到有关群集的潜在敏感信息,通过设置 “readOnlyPort=0” 关闭。

确保长连接配置最大超时时间

kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
streamingConnectionIdleTimeout: 4h
kubectl port-forward pod/coredns-c66bbd748-b9tfw --address 0.0.0.0 9153 -n kube-system

TODO;

确保内核参数符合预期否则禁止启动

kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
protectKernelDefaults: true

设置为 true 时,会令 kubelet 在发现内核参数与预期不符时出错退出。

若此字段设置为 false,则 kubelet 会尝试更改内核参数以满足其预期。

以下示例更改 vm.overcommit_memory 值为 0 测试不符合预期,则导致 “kubelet” 无法启动。

sysctl -w vm.overcommit_memory=0
Oct 12 15:58:45 limiqi-dell-01 kubelet[2004079]: E1012 15:58:45.018694 2004079 kubelet.go:1423] "Failed to start ContainerManager" err="invalid kernel flag: vm/overcommit_memory, expected value: 1, actual value: 0"

内核参数通常由系统管理员在将系统投入生产之前进行调整和强化。这些参数保护内核和系统。依赖于这些参数的kubelet内核默认值应该适当设置,以匹配所需的安全系统状态。忽略这一点可能会导致运行带有不希望的内核行为的pod。

确保允许 Kubelet 管理 iptables 规则

kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
makeIPTablesUtilChains: true

可以根据设置的网络模式自动管理 iptables 所需的更改,建议让 kubelet 来进行管理。这确保了 iptables 配置与 pods 网络配置保持同步,通过动态 pod 网络配置更改手动配置 iptables 可能会阻碍 pod 与容器之间以及与外部世界的通信。您的 iptables 规则可能过于严格或过于开放。

但不要在使用其他 iptables 管理工具,可能会存在冲突。

确保未覆盖主机节点名称

TODO;

确保 kubelet 开启 https 链接

kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
tlsCertFile: /data/kubelet/pki/kubelet.crt
tlsPrivateKeyFile: /data/kubelet/pki/kubelet.key

从 kube-apiserver 到 kubelet 的这些连接,在默认情况下,kube-apiserver 不会验证 kubelet 的服务端证书,这会使连接受到中间人攻击,并且在不受信任和/或公共网络上运行不安全。

这个区别于确保开启 kubelet 验证来自 kube-apiserver 请求,这个是 kubelet 验证 kube-apiserver 的证书是否有效。

同时还需在 kube-apiserver 上配置启用 kubelet 的 ca 证书,才可以生效:

--kubelet-certificate-authority

所有在 kube-apiserver 与 kubelet 通讯过程中,两个方向均存在证书验证,但 kubelet 的 https 一般自动生成,所以我们在使用过程中仅开启 kubelet 验证 kube-apiserver 的请求。

确保 kubelet 自动更新证书

kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
rotateCertificates: true

同步不可禁用 “RotateKubeletServerCertificate” 特性,当 kubelet 证书快过期时,会自动更新。

确保 kubelet 上报事件速率无限制

kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
eventRecordQPS: 0

用于限制收集事件的速率,默认为 5 设置得太低可能会导致相关事件不被记录,但是 0 的无限设置可能会导致kubelet上的拒绝服务,重要的是要捕获所有事件,而不是限制事件的创建。事件是安全信息和分析的重要来源,可确保使用事件数据持续监控您的环境。