控制平面
2 分钟阅读
简要概述
主要关于控制平面相关的安全配置建议。
配置文件
确保静态 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
组件。