控制平面

简要概述

主要关于控制平面相关的安全配置建议。

配置文件

确保静态 POD 文件权限

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

stat -c %a /etc/kubernetes/manifests/kube-apiserver.yaml
stat -c %a /etc/kubernetes/manifests/kube-controller-manager.yaml
stat -c %a /etc/kubernetes/manifests/kube-scheduler.yaml
stat -c %a /etc/kubernetes/manifests/etcd.yaml

检查文件归属,用户组必须为 “root:root”

stat -c %U:%G /etc/kubernetes/manifests/kube-apiserver.yaml
stat -c %U:%G /etc/kubernetes/manifests/kube-controller-manager.yaml
stat -c %U:%G /etc/kubernetes/manifests/kube-scheduler.yaml
stat -c %U:%G /etc/kubernetes/manifests/etcd.yaml

CNI 文件配置路径,默认为 “/etc/cni/net.d/” 通过 kubelet “–cni-conf-dir” 参数修改。

stat -c %a /etc/cni/net.d/10-containerd-net.conflist
stat -c %U:%G /etc/cni/net.d/10-containerd-net.conflist

确保 etcd 数据目录安全

通过查询 “–data-dir” 或 “$DATA_DIR” 定位数据目录,如:"/data/etcd/"。

stat -c %a /data/etcd/
stat -c %U:%G /data/etcd/

权限需小于等于 “700” 且用户归宿为 “etcd:etcd”。

确保 kubeconfig 文件权限

stat -c %a /etc/kubernetes/admin.conf
stat -c %a /etc/kubernetes/scheduler.conf
stat -c %a /etc/kubernetes/controller-manager.conf

stat -c %U:%G /etc/kubernetes/admin.conf
stat -c %U:%G /etc/kubernetes/scheduler.conf
stat -c %U:%G /etc/kubernetes/controller-manager.conf

权限需小于等于 “600” 。

确保 pki 文件权限

ls -laR /etc/kubernetes/pki/
ls -laR /etc/kubernetes/pki/*.crt
ls -laR /etc/kubernetes/pki/*.key

归宿用户 root:root 且 “.crt” 权限小于等于 644, “.key” 权限为 600

kube-apiserver

确保关闭匿名请求

启动参数 “–anonymous-auth” 设置为 “false”,如:

spec:
  containers:
  - command:
    - kube-apiserver
    - --anonymous-auth=false

如果开启匿名,不带 token 的请求均属于 “system:anonymous” 用户组,访问未授权的资源以 “403” 状态码相应,内容如:

{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {
    
  },
  "status": "Failure",
  "message": "forbidden: User \"system:anonymous\" cannot get path \"/metrics\"",
  "reason": "Forbidden",
  "details": {
    
  },
  "code": 403
}

关闭匿名后,则以 “401” 状态码响应:

{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {
    
  },
  "status": "Failure",
  "message": "Unauthorized",
  "reason": "Unauthorized",
  "code": 401
}

确保与 kubelet 通讯安全

spec:
  containers:
  - command:
    - kube-apiserver
    - --kubelet-https=true
    - --kubelet-client-certificate=<path/to/client-certificate-file>
    - --kubelet-client-key=<path/to/client-key-file>

参数 “–kubelet-https” 无需设置,在新版中以被移除,强制使用 https 通讯。

确保使用合适的认证模式

spec:
  containers:
  - command:
    - kube-apiserver
    --authorization-mode=Node,RBAC
    --enable-admission-plugins=...(not AlwaysAdmit)...

避免使用 “AlwaysAllow” 认证模式与 “AlwaysAdmit” 准入控制器,以允许所有请求。

取保使用合适的拉取镜像策略

强制每次创建 POD 时均从镜像中心拉取,而不使用本地镜像缓存,通过添加 “AlwaysPullImages” 准入控制器实现。

spec:
  containers:
  - command:
    - kube-apiserver
    --enable-admission-plugins=...,AlwaysPullImages,...

在多租户集群中,即使各租户对各自镜像使用单独的授权,但租户A在宿主1上拉取了镜像m存在缓存,而租户B知道镜像m的名称后,如果没有该限制则可以使用此镜像m创建出容器。

确保几个基础准入控制器策略

spec:
  containers:
  - command:
    - kube-apiserver
    --enable-admission-plugins=...,NamespaceLifecycle,ServiceAccount,NodeRestriction...
  • ServiceAccount

当创建 POD 时如果未指定 “serviceAccount” 则自动关联至该命名空间下的 “default” 服务账号。

  • NamespaceLifecycle

控制命名空间删除操作会触发一系列删除该空间中所有对象(Pod、Service 等)的操作,同时也限制在一个正在被删除的命名空间中创建新对象,并确保针对不存在的命名空间请求拒绝。该准入控制器还会禁止删除三个系统保留的名字空间,即 default、 kube-system 和 kube-public。

  • NodeRestriction

确保 kubelet 具有正常运行所需的最小权限集。

确保关闭性能调试信息

spec:
  containers:
  - command:
    - kube-apiserver
    - --profiling=false

分析允许识别特定的性能瓶颈。它生成了大量的程序数据,这些数据可能被用来揭示系统和程序的详细信息。如果您没有遇到任何瓶颈,并且不需要探查器进行故障排除,建议将其关闭,以减少潜在的攻击面。

kube-controller-manager

确保垃圾回收值在合理范围

spec:
  containers:
  - command:
    - kube-controller-manager
    - --terminated-pod-gc-threshold=10

通过设置 --terminated-pod-gc-threshold 达到值触发垃圾回收,默认值为 “12500” 太大,一般集群无法保证,需根据实际情况降低。

确保关闭性能调试信息

kube-apiserver 组件。

确保为每个控制器使用单独的账号

spec:
  containers:
  - command:
    - kube-controller-manager
    - --use-service-account-credentials=true

通过设置 --use-service-account-credentials 以达到在 kube-system 空间下每个控制器使用各自的认证,可通过以下指令查看:

root@limiqi-dell-01:~# kubectl get sa -n kube-system
NAME                                 SECRETS   AGE
attachdetach-controller              1         34h
calico-kube-controllers              1         32h
calico-node                          1         32h
certificate-controller               1         34h
clusterrole-aggregation-controller   1         34h
coredns                              1         32h
cronjob-controller                   1         34h
daemon-set-controller                1         34h
......

确保服务帐户令牌的密钥可以根据需要轮换

spec:
  containers:
  - command:
    - kube-controller-manager
    - --service-account-private-key-file=/etc/kubernetes/pki/sa.key

应使用单独的公私钥对对服务帐户令牌进行签名,通过设置 --service-account-private-key-file 将私钥指定给控制器管理器。

spec:
  containers:
  - command:
    - kube-apiserver
    - --service-account-signing-key-file=/etc/kubernetes/pki/sa.key
    - --service-account-key-file=/etc/kubernetes/pki/sa.pub

这里公私钥同 “kube-apiserver” 中的 --service-account-signing-key-file --service-account-key-file 配置,如果未提供,则默认会使用 --tls-private-key-file 指定的文件进行令牌签名,该证书用于服务端 6443 通讯,变更代价较大,所以需把服务账户令牌单独签名。

确保开启 kubelet 证书自动轮换

spec:
  containers:
  - command:
    - kube-controller-manager
    - --feature-gates=RotateKubeletServerCertificate=true

以上特性 --feature-gates=RotateKubeletServerCertificate=true 默认是开启的,所以只要确保未设置或非设置为 “false” 即可。

具体流程可参考: https://kubernetes.io/zh-cn/docs/tasks/tls/certificate-rotation/

kube-scheduler

确保关闭性能调试信息

kube-apiserver 组件。




最后修改 2023.10.10: refactor: add worker nodes (6fdb156)