亚马逊AWS官方博客
将 Pod 安全策略与 Amazon EKS 集群结合使用
对于您要求的功能,我们已使用Kubernetes 1.13 将其启用:Amazon Elastic Container Service for Kubernetes (EKS) 现支持 Pod 安全策略。在本篇博文中,我们将从集群管理员和开发人员的角度,审视 PSP 是什么,如何在 Kubernetes 控制平面中启用它们以及如何使用它们。
什么是 Pod 安全策略,我为何要关心?
作为集群管理员,您可能想知道如何在集群中强制执行有关 pod 运行时属性的特定策略。例如,您可能希望阻止开发人员使用未定义用户的容器运行 pod(因此,以 root 身份运行)。您可能在 pod 规范中创建了关于开发人员设置安全上下文的文档,对此开发人员可能遵循……也可能选择不遵循。无论如何,您都需要一种在集群范围内强制执行此类策略的机制。
解决方法是将 Pod 安全策略 (PSP) 作为深度防御策略的一部分。
需要注意的是,pod 的安全上下文定义了各种权限和访问控制设置,例如自主访问控制(比如基于特定用户 ID 访问文件)、功能(比如通过定义 AppArmor 配置文件)、配置 SECCOMP(通过过滤某些系统调用),以及允许您实施强制访问控制(通过 SELinux)。
另一方面,PSP 是集群范围的资源,使您可以作为集群管理员在集群中强制使用安全上下文。PSP 由 API 服务器的准入控制器强制执行。简而言之:如果 pod 规范不符合您在 PSP 中定义的内容,则 API 服务器将拒绝启动它。要使 PSP 正常工作,必须启用相应的 准入插件,并且必须授予用户权限。EKS 1.13 集群现在默认启用 PSP 准入插件,因此 EKS 用户无需进行任何操作。
通常,您希望根据最小权限原则定义 PSP:从强制执行的无根容器到只读根文件系统,到对可从主机安装的项目的限制(pod 中的容器在其上运行的 EC2 实例)。
使用
新的 EKS 1.13 集群创建了一个名为 eks.privileged
的默认策略,该策略对可接入系统的 pod 类型没有限制(相当于在禁用 PodSecurityPolicy
控制器的情况下运行集群)。
要查看 EKS 集群中现有的 pod 安全策略,请执行以下操作:
$ kubectl get psp NAME PRIV CAPS SELINUX RUNASUSER FSGROUP SUPGROUP READONLYROOTFS VOLUMES eks.privileged true * RunAsAny RunAsAny RunAsAny RunAsAny false *
现在,描述我们为您定义的默认策略:
$ kubectl describe psp eks.privileged
正如您在下面的输出中看到的那样 – 一切正常! 此策略允许任何类型的 pod 规范:
Name: eks.privileged Settings: Allow Privileged: true Allow Privilege Escalation: true Default Add Capabilities: <none> Required Drop Capabilities: <none> Allowed Capabilities: * Allowed Volume Types: * Allow Host Network: true Allow Host Ports: 0-65535 Allow Host PID: true Allow Host IPC: true Read Only Root Filesystem: false SELinux Context Strategy: RunAsAny User: <none> Role: <none> Type: <none> Level: <none> Run As User Strategy: RunAsAny Ranges: <none> FSGroup Strategy: RunAsAny Ranges: <none> Supplemental Groups Strategy: RunAsAny Ranges: <none>
请注意,任何经过身份验证的用户都可以按照当前配置在此 EKS 集群上创建任何 pod,证明如下:
$ kubectl describe clusterrolebindings eks:podsecuritypolicy:authenticated
上述命令输出显示集群角色 eks:podsecuritypolicy:privileged
被分配给任何 system:authenticated
用户:
Name: eks:podsecuritypolicy:authenticated Labels: eks.amazonaws.com/component=pod-security-policy kubernetes.io/cluster-service=true Annotations: kubectl.kubernetes.io/last-applied-configuration: ... Role: Kind: ClusterRole Name: eks:podsecuritypolicy:privileged Subjects: Kind Name Namespace ---- ---- --------- Group system:authenticated
请注意,如果有多个 PSP 可用,Kubernetes 准入控制器会选择第一个成功验证的策略。策略按其名称的字母顺序排序,不改变 pod 的策略优先于变形策略。
现在让我们创建一个新的 PSP,我们称之为 eks.restrictive
。首先,创建一个专用命名空间以及一个服务帐户。我们将对非管理员用户使用此服务帐户:
$ kubectl create ns psp-eks-restrictive namespace/psp-eks-restrictive created $ kubectl -n psp-eks-restrictive create sa eks-test-user serviceaccount/eks-test-user created $ kubectl -n psp-eks-restrictive create rolebinding eks-test-editor \ --clusterrole=edit \ --serviceaccount=psp-eks-restrictive:eks-test-user rolebinding.rbac.authorization.k8s.io/eks-test-editor created
接下来,创建两个别名,以突出显示管理员和非管理员用户之间的区别:
$ alias kubectl-admin='kubectl -n psp-eks-restrictive' $ alias kubectl-dev='kubectl --as=system:serviceaccount:psp-eks-restrictive:eks-test-user -n psp-eks-restrictive'
现在,使用集群管理员角色,创建一个不允许使用主机联网创建 pod 的策略:
$ cat > /tmp/eks.restrictive-psp.yaml <<EOF apiVersion: policy/v1beta1 kind: PodSecurityPolicy metadata: name: eks.restrictive spec: hostNetwork: false seLinux: rule: RunAsAny supplementalGroups: rule: RunAsAny runAsUser: rule: RunAsAny fsGroup: rule: RunAsAny volumes: - '*' EOF $ kubectl-admin apply -f /tmp/eks.restrictive-psp.yaml podsecuritypolicy.policy/eks.restrictive created
另外,不要忘记删除默认的(宽容的策略)eks.privileged
:
$ kubectl delete psp eks.privileged $ kubectl delete clusterrole eks:podsecuritypolicy:privileged $ kubectl delete clusterrolebindings eks:podsecuritypolicy:authenticated
警告
在添加自己的 PSP 之前删除默认 EKS 策略 可能会损害集群。删除默认策略时,除满足新命名空间中安全上下文的 pod 外,无法在集群上创建任何 pod。对于现有集群,请确保在删除默认策略之前,创建涵盖所有正在运行的 pod 和命名空间的多个限制策略
现在,确认已创建策略:
$ kubectl get psp NAME PRIV CAPS SELINUX RUNASUSER FSGROUP SUPGROUP READONLYROOTFS VOLUMES eks.restrictive false RunAsAny RunAsAny RunAsAny RunAsAny false *
最后,作为非特权用户(模拟开发人员),尝试创建违反策略的 pod:
$ kubectl-dev apply -f- <<EOF apiVersion: v1 kind: Pod metadata: name: busybox spec: containers: - name: busybox image: busybox command: [ "sh", "-c", "sleep 1h" ] EOF
正如您所预期的那样,您会得到以下结果:
Error from server (Forbidden): error when creating "STDIN": pods "busybox" is forbidden: unable to validate against any pod security policy: []
上述操作失败,因为我们尚未授予开发人员适当的权限。换句话说,没有对开发者用户 eks-test-user
进行角色绑定。因此,让我们通过为 pod 安全策略 eks.restrictive
创建角色 psp:unprivileged
对其进行更改:
$ kubectl-admin create role psp:unprivileged \ --verb=use \ --resource=podsecuritypolicy \ --resource-name=eks.restrictive role.rbac.authorization.k8s.io/psp:unprivileged created
现在,创建 rolebinding
以授予 eks-test-user
有关 eks.restrictive
策略的 use
动词。
$ kubectl-admin create rolebinding eks-test-user:psp:unprivileged \ --role=psp:unprivileged \ --serviceaccount=psp-eks-restrictive:eks-test-user rolebinding.rbac.authorization.k8s.io/eks-test-user:psp:unprivileged created
验证 eks-test-user
是否可以使用 eks.restrictive
:
$ kubectl-user auth can-i use podsecuritypolicy/eks.restrictive yes
此时,开发人员 eks.restrictive
用户应该能够创建一个 pod:
$ kubectl-user apply -f- <<EOF apiVersion: v1 kind: Pod metadata: name: busybox spec: containers: - name: busybox image: busybox command: [ "sh", "-c", "sleep 1h" ] EOF pod/busybox created
好的,有效! 但是,由于我们在上述 eks.restrictive
中定义的内容,我们应拒绝基于主机联网的 pod 创建:
$ kubectl-user apply -f- <<EOF apiVersion: v1 kind: Pod metadata: name: privileged spec: hostNetwork: true containers: - name: busybox image: busybox command: [ "sh", "-c", "sleep 1h" ] EOF Error from server (Forbidden): error when creating "STDIN": pods "privileged" is forbidden: unable to validate against any pod security policy: [spec.securityContext.hostNetwork: Invalid value: true: Host network is not allowed to be used]
非常好! 这证实了PSP eks.restrictive
按预期工作,限制开发人员创建特权 pod。
新增功能
对于使用 Kubernetes 1.13 版的所有新 EKS 集群,PSP 现在可用。对于已从先前版本升级的集群,在升级过程中会自动创建完全允许的 PSP。您的主要任务是定义适合您的环境的合理 PSP,并按上述方法启用它们。从合理的角度看,我的意思是(例如)与生产环境相比,您可以选择在开发/测试环境中减少限制。或者,同样可能的是,不同的项目或团队需要保护级别不同可能,因此 PSP 也不同。
最后一点:作为集群管理员,请务必向开发人员介绍一般的安全上下文,特别是 PSP。将 CI/CD 管道测试 PSP 作为冒烟测试,以及其他与安全相关的主题的一部分,例如通过 RBAC 角色和绑定定义的测试权限。
您可以在 Amazon EKS 文档中了解有关 PSP 的更多信息。请在下面留下任何评论,或通过 Twitter 与我联系!
— Michael