无法覆盖GKE中的默认POD安全策略



我在我本地的Minikube中成功实现了PODSecurityPolicies(PSP),并且在将其移植到GKE中很难。我现在的目标很简单 -> 不允许使用UID 0或具有特权访问的吊舱。

我的PSP很简单:

apiVersion: extensions/v1beta1
kind: PodSecurityPolicy
metadata:
  name: default-psp
spec:
  privileged: false
  runAsUser:
    rule: MustRunAsNonRoot

和IVE设置RBAC ClusterRolebinding允许所有ServiceAccounts使用PSP。

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: restrict-root-clusterRole
rules:
- apiGroups: ['policy']
  resources: ['podsecuritypolicies']
  verbs:     ['use']
  resourceNames:
  - default-psp
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: restrict-root-clusterRoleBinding
roleRef:
  kind: ClusterRole
  name: restrict-root-clusterRole
  apiGroup: rbac.authorization.k8s.io
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: system:serviceaccounts

现在,我使用gcloud beta container clusters update psp-demo --enable-pod-security-policy

在GKE中启用PSP

,然后我注意到GKE创建以下PSP

$ k get psp
NAME                           PRIV    CAPS   SELINUX    RUNASUSER   FSGROUP    SUPGROUP   READONLYROOTFS   VOLUMES
gce.event-exporter             false          RunAsAny   RunAsAny    RunAsAny   RunAsAny   false            hostPath,secret
gce.fluentd-gcp                false          RunAsAny   RunAsAny    RunAsAny   RunAsAny   false            configMap,hostPath,secret
gce.persistent-volume-binder   false          RunAsAny   RunAsAny    RunAsAny   RunAsAny   false            nfs,secret
gce.privileged                 true    *      RunAsAny   RunAsAny    RunAsAny   RunAsAny   false            *
gce.unprivileged-addon         false          RunAsAny   RunAsAny    RunAsAny   RunAsAny   false            emptyDir,configMap,secret
然后,我创建我的PSP和RBAC规则。
k get psp
NAME                           PRIV    CAPS   SELINUX    RUNASUSER          FSGROUP     SUPGROUP    READONLYROOTFS   VOLUMES
default-psp                    false          RunAsAny   MustRunAsNonRoot   RunAsAny   RunAsAny   false            *
gce.event-exporter             false          RunAsAny   RunAsAny           RunAsAny    RunAsAny    false            hostPath,secret
gce.fluentd-gcp                false          RunAsAny   RunAsAny           RunAsAny    RunAsAny    false            configMap,hostPath,secret
gce.persistent-volume-binder   false          RunAsAny   RunAsAny           RunAsAny    RunAsAny    false            nfs,secret
gce.privileged                 true    *      RunAsAny   RunAsAny           RunAsAny    RunAsAny    false            *
gce.unprivileged-addon         false          RunAsAny   RunAsAny           RunAsAny    RunAsAny    false            emptyDir,configMap,secret

i然后旋转root用户pod

apiVersion: v1
kind: Pod
metadata:
  name: root-user-pod
spec:
  containers:
  - name: root-user-pod
    image: nginx
    ports:
    - containerPort: 80

它进入跑步状态并查看注释,我看到:

apiVersion: v1
kind: Pod
metadata:
  annotations:
    kubernetes.io/limit-ranger: 'LimitRanger plugin set: cpu request for container
      root-user-pod'
    kubernetes.io/psp: gce.privileged

很明显我的默认PSP没有使用。

我尝试编辑gce.privileged PSP,但GKE会自动将其还原回默认的privileged状态。

我所做的就是将特定名称空间中的吊舱作为特定的服务空间创建。我的新RBAC规则是:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: test-user
  namespace: test
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: test
  name: test-psp-role
rules:
- apiGroups: ['policy']
  resources: ['podsecuritypolicies']
  verbs:     ['use']
  resourceNames:
  - default-psp
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: test-psp-roleBinding
  namespace: test
subjects:
- kind: ServiceAccount
  name: test-user
  namespace: test
roleRef:
  kind: Role
  name: test-psp-role
  apiGroup: rbac.authorization.k8s.io

我在我的吊舱清单中添加了 serviceAccountName: test-user,然后在 test名称空间中部署吊舱,并且也进入运行状态。

k get po -n test
NAME            READY   STATUS    RESTARTS   AGE
root-user-pod   1/1     Running   0          7s

带注释:

apiVersion: v1
kind: Pod
metadata:
  annotations:
    kubernetes.io/psp: gce.privileged
  creationTimestamp: "2019-03-12T15:48:11Z"
  name: root-user-pod
  namespace: test

所以我不确定下一步该怎么做。我该如何骑行GKE创建的默认PSP?

tl; dr-运行提供关键群集功能的特权系统POD所必需的特权策略。您的用户帐户可以访问所有podsecuritypolicies。

使用特定的podsecuritypolicy可以通过两种不同的方式授权:

  1. POD的服务帐户在特定的PODSecurityPolicy上具有use的许可。
  2. 创建用户在特定的PODSecurityPolicy上具有use的许可。

您可以测试您的用户帐户是否可以使用以下方式使用策略。

kubectl auth can-i use podsecuritypolicy/${PSP_NAME}

您可以测试POD的服务帐户是否可以使用:

访问PSP
kubectl --as=system:serviceaccount:${NAMESPACE:-default}:${SERVICE_ACCOUNT:-default} auth can-i use podsecuritypolicy/${PSP_NAME}

如果您通过部署,replicaset或其他一些间接机制创建POD,则创建POD而不是用户的控制器。在这种情况下,控制器不应访问任何特权POD安全策略,您应该看到所需的行为。

另外,请确保创建非特权POD的用户无法访问群集 - Admin角色绑定。

这种方法存在已知问题,而Kubernetes社区正在努力解决这些方法,然后才能从beta提升到一般可用性。

最新更新