策略管理

最近更新时间:2024-10-25 17:53:41

我的收藏

简介

原生 Kubernetes 存在级联删除机制,删除一个资源时会自动删除与之相关的其他资源,例如删除 Namespace 时会自动删除 Namespace 下所有的 Pod、Service、ConfigMap 等关联资源,可能导致业务故障。
K8S 自身的脆弱性会导致在生产环境存在稳定性和安全的风险,例如用户配置的镜像拉取来源没有限制,可能导致镜像被篡改;缺少容器级别的安全隔离策略,可能导致容器发生越权等行为。
容器服务(Tencent Kubernetes Engine,TKE)提供“策略管理”能力,通过系统预置策略或者用户自主开启策略的方式,防止误删除引起业务故障,支持通过对计算资源、网络资源进行策略的加固,提升 TKE 集群的稳定性和安全性。

策略说明

策略分类

删除防护:包含集群删除保护和集群内资源删除保护。在删除 TKE 集群内的各类资源时,如果资源正在使用中,或者存在和其他资源之间的引用关系,则不允许删除。
策略管控:用于约束和规范 K8S 集群内的资源配置。例如:要求 Pod 具有 Readiness 或 Liveness Probe;限制容器镜像来源必须在指定的列表内等。
安全加固:包含 PSP(PodSecurityPolicy)相关策略。TKE 提供基于 gatekeeper 的安全防护能力。例如,禁止创建特权容器,约束 PodSecurityPolicy 中的 hostPath、hostPID 和 hostIPC 字段等。

支持边界

支持1.16及以上 K8S 版本的 TKE 标准集群和 TKE Serverless 集群,暂不支持注册集群和边缘集群。

策略类型

基线策略:TKE 内置的策略,包含保护集群基础设施资源不被误删除等策略。
优选策略:TKE 最佳实践形成的标准和规范,对用户的各项配置进行校验,使得用户请求符合约束。用户可根据实际情况开启策略,并设置策略运行模式。
可选策略:官方 OPA gatekeeper 策略库支持的策略,包含替代 PSP 能力的策略和通用策略。用户可以根据实际情况,自行创建策略实例,具体创建流程请参见 新建策略实例

策略库

基线策略

策略分类
策略名称
策略描述
拦截对象
运行模式
删除保护
存在节点的集群不允许删除
集群中存在任意节点(普通节点、原生节点、注册节点),需先下线节点后方可删除。
集群
默认 deny

优选策略

策略分类
策略名称
策略描述
拦截对象
运行模式
删除保护
存在 pod 的命名空间不允许删除
命名空间内如果存在 pod,需先清除 pod 后方可删除 namespace。
Namespace
默认 dryrun
删除保护
存在 cr 的 crd 不允许删除
crd 定义的 apiversion 下如果有创建 cr 资源,则清空 cr 后方可删除 crd。
CRD
默认 dryrun
删除保护
非封锁状态的 Node 不允许删除
节点处于非封锁状态不允许删除。
Node
默认不创建策略实例
删除保护
CoreDNS 组件删除保护
禁止删除 CoreDNS 组件的 Service、ConfigMap 和 Deployment。
Deployment、Service、ConfigMap
默认不创建策略实例
删除保护
资源删除保护
存在指定 Label 的资源(Service、Ingress、Deployment、StatefulSet)不允许被删除。
Service、Ingress、Deployment、StatefulSet
默认不创建策略实例
删除保护
PV 处于绑定状态则不允许删除
PersistentVolume 如果处于 Bound 状态,则不允许被删除。
PV
默认不创建策略实例
策略管控
禁止挂载指定的 volume 类型
将可挂载的 volume 类型限制为用户指定的类型。
Pod
默认不创建策略实例
策略管控
禁止镜像拉取策略使用 Always
禁止容器使用 Always 镜像拉取策略,减少对镜像仓库的访问。
Pod
默认不创建策略实例
策略管控
容器镜像来源限制
只允许从指定的镜像仓库拉取镜像。
Pod
默认不创建策略实例
策略管控
禁止未知的 DaemonSet 部署
只允许部署指定的 DaemonSet。
DaemonSet
默认不创建策略实例
策略管控
工作负载镜像版本升级策略管控
限制 Deployment 和 DaemonSet 只能在配置的镜像列表中升级。
Deployment、DaemonSet
默认不创建策略实例
策略管控
ServiceAccount 权限管控
禁止 ServiceAccount 绑定较大权限的 Role 和 ClusterRole,提升集群安全性。
ServiceAccount
默认不创建策略实例
策略管控
不允许 Service 为 ClusterIP 类型
禁止创建 ClusterIP 类型的 Service 或将 Service 由其他类型更新为 ClusterIP 类型。
Service
默认不创建策略实例
策略管控
禁止公网访问
禁止通过创建公网类型的 Service 或 Ingress 的方式将后端服务暴露到公网。
Service、Ingress
默认不创建策略实例
策略管控
弹性网卡资源配置限制
限制跨租户弹性网卡必须配置 Request 资源。
Pod
默认不创建策略实例

可选策略

策略分类
策略名称
策略描述
拦截对象
策略管控
tkeblockvolumemountpath
禁止容器挂载指定的目录。
pods
策略管控
k8sallowedrepos
容器镜像必须以指定字符串列表中的字符串开头。
pods
策略管控
k8spspautomountserviceaccounttokenpod
约束容器不能设置 automountServiceAccountToken 为 true。
pods
策略管控
k8sblockendpointeditdefaultrole
默认情况下,许多 Kubernetes 都预定义了一个名为 system:aggregate-to-edit 的 ClusterRole,k8sblockendpointeditdefaultrole 策略定义禁止该 ClusterRole 对 Endpoints 进行 create、patch 和 update 操作。
clusterroles
策略管控
k8sblockloadbalancer
不允许 Service 为 LoadBalancer 类型。
services
策略管控
k8sblocknodeport
不允许 Service 为 NodePort 类型。
services
策略管控
k8sblockwildcardingress
禁止 ingress 配置空白或通配符类型的 hostname。
ingresses
策略管控
k8scontainerlimits
限制容器必须设置 CPU 和内存 Limit,并且小于设定的最大值。
pods
策略管控
k8scontainerrequests
限制 CPU 和内存的 Request 必须设置且小于配置的最大值。
pods
策略管控
k8scontainerratios
限制 CPU 和内存的 Request 与 Limit 的最大比率。
pods
策略管控
k8srequiredresources
必须配置内存的 Limit,CPU 和内存的 Request。
pods
策略管控
k8sdisallowanonymous
不允许将白名单以外的 ClusterRole 和 Role 关联到 system:anonymous User 和 system:unauthenticated Group。
rolebindings clusterrolebindings
策略管控
k8sdisallowedtags
约束容器镜像 tag。
pods
策略管控
k8sexternalips
限制服务 externalIP 仅为允许的 IP 地址列表。
services
策略管控
k8simagedigests
容器镜像必须包含 digest。
pods
策略管控
noupdateserviceaccount
拒绝白名单外的资源更新 ServiceAccount。
replicationcontrollers replicasets deployments statefulsets daemonsets cronjobs
策略管控
k8sreplicalimits
要求具有 “spec.replicas” 字段的对象(Deployments、ReplicaSets等)在定义的范围内。
deployments
策略管控
k8srequiredannotations
要求资源包含指定的 annotations,其值与提供的正则表达式匹配。
services
策略管控
k8srequiredlabels
要求资源包含指定的标签,其值与提供的正则表达式匹配。
namespaces
策略管控
k8srequiredprobes
要求 Pod 具有 Readiness 或 Liveness Probe。
pods
安全加固
k8spspallowprivilegeescalationcontainer
约束 PodSecurityPolicy 中的 “allowPrivilegeEscalation” 字段为 false。
pods
安全加固
k8spspapparmor
约束 AppArmor 字段列表。
pods
安全加固
k8spspcapabilities
限制 PodSecurityPolicy 中的 “allowedCapabilities” 和 “requiredDropCapabilities” 字段。
pods
安全加固
k8spspflexvolumes
约束 PodSecurityPolicy 中的 allowedFlexVolumes 字段类型。
pods
安全加固
k8spspforbiddensysctls
约束 PodSecurityPolicy 中的 “sysctls” 字段不能使用的 name。
pods
安全加固
k8spspfsgroup
控制 PodSecurityPolicy 中的 “fsGroup” 字段在限制范围内。
pods
安全加固
k8spsphostfilesystem
约束 PodSecurityPolicy 中的 “hostPath” 字段的参数。
pods
安全加固
k8spsphostnamespace
限制 PodSecurityPolicy 中的 “hostPID” 和 “hostIPC” 字段。
pods
安全加固
k8spsphostnetworkingports
约束 PodSecurityPolicy 中的 “hostNetwork” 和 “hostPorts” 字段。
pods
安全加固
k8spspprivilegedcontainer
禁止 PodSecurityPolicy 中的 “privileged” 字段为 true。
pods
安全加固
k8spspprocmount
约束 PodSecurityPolicy 中的 “allowedProcMountTypes” 字段。
pods
安全加固
k8spspreadonlyrootfilesystem
约束 PodSecurityPolicy 中的 “readOnlyRootFilesystem” 字段。
pods
安全加固
k8spspseccomp
约束 PodSecurityPolicy 上的 “seccomp.security.alpha.kubernetes.io/allowedProfileNames” 注解。
pods
安全加固
k8spspselinuxv2
约束 Pod 定义 SELinux 配置的允许列表。
pods
安全加固
k8spspallowedusers
约束 PodSecurityPolicy 中的runAsUser、runAsGroup、supplementalGroups 和 fsGroup 字段。
pods
安全加固
k8spspvolumetypes
约束 PodSecurityPolicy 中的 “volumes” 字段类型。
pods

操作说明

开启/关闭策略

1. 登录 容器服务控制台,选择左侧导航栏中的集群
2. 在集群管理页面,选择目标集群 ID,进入集群的基本信息页面。
3. 在左侧导航中选择策略管理,进入策略管理页面选择策略,单击开启/关闭。关闭策略需要二次确认,开启则不需要。如下图所示:




验证策略效果

以集群删除策略为例,创建 TKE 标准集群,验证集群在存在节点情况下删除请求是否会被拦截。
1. 创建有节点的 TKE 标准集群,详细步骤请参见 创建集群
2. 发起删除集群请求。
通过控制台删除
调用云 API 删除
1. 删除集群,详细步骤请参见 删除集群
2. 窗口提示需要先清空节点后,方可继续删除集群。如下图所示:



1. 调用云 API 删除,调用方式请参见 API 文档 删除集群
2. 删除集群接口调用失败,错误信息返回中包含集群中存在的节点清单。如下图所示:



3. 策略管理页面,单击关联事件的数字,查看拦截事件信息。如下图所示:




新建策略实例

以禁止创建特权容器为例,演示如何新建策略实例。
策略名称:k8spspprivilegedcontainer
策略类型:K8sPSPPrivilegedContainer
策略描述:禁止 Pod securityContext 中的 privileged 字段为 true。
生效资源类型:Pod
需要修改的参数如下:
namespaces 可选参数:表示策略作用生效的命名空间。
不填该字段或者字段取值为空时,表示所有命名空间都生效。
支持前缀匹配,例如 namespaces: ["kube-*"] 匹配 "kube-system" 和 "kube-public"。
excludedNamespaces 可选参数:表示策略豁免生效的命名空间,在该列表中的命名空间不会生效此条策略。
不填该字段或者字段取值为空时,表示没有豁免的命名空间。
支持前缀匹配,例如 excludedNamespaces: ["kube-*"] 匹配 "kube-system" 和 "kube-public"。
exemptInitContainers 自定义参数:布尔值。含义:是否允许 initContainer 使用特权容器。
部分业务的 initContainer 以特权容器的方式运行,执行类似 iptables 规则下发等操作。
创建策略实例时,默认会允许 initContainer 使用特权容器。
策略实例 YAML:
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sPSPPrivilegedContainer
metadata:
name: psp-privileged-container
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
namespaces: []
excludedNamespaces: ["kube-system"]
parameters:
exemptInitContainers: true
测试策略是否生效的 Pod YAML 如下,直接 apply YAML,会被策略拦截,则表明策略已生效。
apiVersion: v1
kind: Pod
metadata:
name: privileged-pod
spec:
containers:
- name: privileged-container
image: nginx
securityContext:
privileged: true
initContainers:
- name: privileged-init-container
image: busybox
command: ['sh', '-c', 'echo Hello, Kubernetes!']
securityContext:
privileged: true
创建一个特权容器的 Pod,预期输出:
Error from server (Forbidden): error when creating "pod.yaml": admission webhook "validation.gatekeeper.sh" denied the request: [psp-privileged-container] Privileged container is not allowed: privileged-container, securityContext: {"privileged": true}, Pod name: privileged-pod