将 Pod 安全策略与 Amazon EKS 集群结合使用

阅读数:44 2019 年 9 月 27 日 14:38

将 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 角色和绑定定义的测试权限。

本文转载自 AWS 技术博客。

原文链接:
https://amazonaws-china.com/cn/blogs/china/using-pod-security-policies-amazon-eks-clusters/

欲了解 AWS 的更多信息,请访问【AWS 技术专区】

评论

发布