kubernetes-Pod安全策略psp实践-LMLPHP

  • Pod Securities Policy

    Pod Security Policies(Adminssion Controller)授予users和service accounts创建或更新pods使用资源的权限。这是一种集群级别的资源类型,用来限制pod对敏感资源的使用。

    Adminssion Controller

    Addmission controller会拦截发往Kubernetes API Server调用资源的请求,验证请求调用的users和service accout是否已经授权和认证使用被调用的资源对象。例如:Admission controller会验证请求者是否拥有使用hostNetwork等kubernetes资源的权限。

    Policy

    对授权资源使用权限的规则定义在YAML文件中。

    Policy Definition Guidelines

    规则有两种:一种是限制(restrictive)使用资源的规则,另一种是允许(permission)使用资源的规则。

    Pod Security Policy应该遵循以下的规范:

    例子

    在这部分中我们将开始在集群中实践pod security policy

    Enabling Pod Security Policy

    PSP(Pod Security Policy) 在默认情况下并不会开启。通过将PodSecurityPolicy关键词添加到 --enbale-admission-plugins 配置数组后,可以开启PSP权限认证功能。

    # Example
    --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,ResourceQuota,PodSecurityPolicy

    注意:开启PodSecurityPolicy功能后,即使没有使用任何安全策略,都会使得创建pods(包括调度任务重新创建pods)失败

    Testing

    通过下面的deployment yaml文件测试在没有PSP策略的情况下是否可以创建pod:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
      namespace: default
      labels:
        app: nginx
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:1.15.4

    使用下面的命令创建deployment资源:

    sudo kubectl apply -f nginx-deployment.yaml

    使用下面的命令检查pod是否创建:

    kubectl get pods,replicasets,deployments

    通过上图可见deployments和relicaset正在运行,由于缺少PSP policy,集群并没有创建相应的pods。

    Defining Policies

    下面将创建两个policies,

    下面是典型的限制资源使用的restrictive policy:

    apiVersion: policy/v1beta1
    kind: PodSecurityPolicy
    metadata:
      name: restrictive
    spec:
      privileged: false
      hostNetwork: false
      allowPrivilegeEscalation: false
      defaultAllowPrivilegeEscalation: false
      hostPID: false
      hostIPC: false
      runAsUser:
        rule: RunAsAny
      fsGroup:
        rule: RunAsAny
      seLinux:
        rule: RunAsAny
      supplementalGroups:
        rule: RunAsAny
      volumes:
      - 'configMap'
      - 'downwardAPI'
      - 'emptyDir'
      - 'persistentVolumeClaim'
      - 'secret'
      - 'projected'
      allowedCapabilities:
      - '*'

    下面是允许使用资源的permissive policy,多条permissive policy规则被用来设置相应user或者sevice account使用相关类型的资源。

    apiVersion: policy/v1beta1
    kind: PodSecurityPolicy
    metadata:
      name: permissive
    spec:
      privileged: true
      hostNetwork: true
      hostIPC: true
      hostPID: true
      seLinux:
        rule: RunAsAny
      supplementalGroups:
        rule: RunAsAny
      runAsUser:
        rule: RunAsAny
      fsGroup:
        rule: RunAsAny
      hostPorts:
      - min: 0
        max: 65535
      volumes:
      - '*'

    上面两种poicies可以使用下面的命令创建对应的PSP资源:

    kubectl apply -f default-restrict-psp.yaml

    kubectl apply -f permissive-psp.yaml

    核对psp是否创建成功与否:

    sudo kubectl get psp

    下面将通过cluster role和cluster role binding在集群中使用刚才定义的安全策略(Pod Security Policy)。

    Cluster Role

    kind: ClusterRole
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: psp-restrictive
    rules:
    - apiGroups:
      - extensions
      resources:
      - podsecuritypolicies
      resourceNames:
      - restrictive
      verbs:
      - use
    kind: ClusterRole
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: psp-permissive
    rules:
    - apiGroups:
      - extensions
      resources:
      - podsecuritypolicies
      resourceNames:
      - permissive
      verbs:
      - use

    通过下面命令创建相应的cluster role资源:

    kubectl apply -f psp-restrictive-cluster-roleyaml

    kubectl apply -f psp-permissive-cluster-roleyaml

    Cluster Role Bindings

    kind: ClusterRoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: psp-default
    subjects:
    - kind: Group
      name: system:serviceaccounts
      namespace: kube-system
    roleRef:
      kind: ClusterRole
      name: psp-restrictive
      apiGroup: rbac.authorization.k8s.io

    上面的role binding会将restrictive cluster role绑定到所有的system service account。

    使用下面的命令生成role binding资源:

    kubectl apply -f psp-restrictive-cluster-role-binding.yaml

    Testing

    已经定义了restrictive policy并且将对应的psp绑定到对应的service account,我将通过重新生成开篇的deployment资源来验证pods是否可以创建。

    首先,删除已经存在的deployment资源。

    kubectl delete deploy nginx-deployment

    kubectl get po,rs,deploy

    重新创建deployment:

    kubectl apply -f nginx-deployment.yaml

    kubectl get po,rs,deploy

    注意:通过图可见在policies创建后,可以创建pod资源。

    在这部分,我将在deployment中使用已经在restrictive policy中禁止的“hostNetwork”。

    首先,清楚前面创建的deployment资源。

    kubectl delete deploy ninx-deployment

    kubectl get po.rs,deploy

    使用下面的命令和yaml文件重新创建相应资源:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-hostnetwork-deployment
      namespace: kube-system
      labels:
        app: nginx
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:1.15.4
          hostNetwork: true
    kubectl apply -f   nginx-host-network-deployment.yaml

    kubectl get po,rs,deploy

    可见replica set controller并没有创建相对应的pod,原因如下:

    Warning FailedCreate 2m38s (x17 over 8m5s) replicaset-controller Error creating: pods "nginx-hostnetwork-deployment-fd75d78b-" is forbidden: unable to validate against any pod security policy: [spec.securityContext.hostNetwork: Invalid value: true: Host network is not allowed to be used]

    注意:

    上面的错误显示在创建deployment时试图获取已经被限制的资源,k8s集群不允许这样的行为。

    在这部分,我将通过对一些controllers(deamon-set-controller,replicaset-controller,job-controller)的调用user和service account授予一些特殊权限。

    首先,我先创建role binding。

    apiVersion: rbac.authorization.k8s.io/v1beta1
    kind: RoleBinding
    metadata:
      name: psp-permissive
      namespace: kube-system
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: psp-permissive
    subjects:
    - kind: ServiceAccount
      name: daemon-set-controller
      namespace: kube-system
    - kind: ServiceAccount
      name: replicaset-controller
      namespace: kube-system
    - kind: ServiceAccount
      name: job-controller
      namespace: kube-system

    使用以下命令创建role binding:

    kubectl apply -f psp-permissive-cluster-role-binding.yaml

    接下来我将重新创建deployment并在pod中使用被restrictive policy限制使用的资源。当前deployment与前面deployment的区别在于现在在kube-system命名空间中创建deployment,以前则是在default命名空间中,这主要是由于刚刚对kube-system授予permissive policy权限。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-hostnetwork-deployment
      namespace: kube-system
      labels:
        app: nginx
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:1.15.4
          hostNetwork: true

    使用下面命令,重新创建deployment资源:

    kubectl apply -f nginx-host-network-deployment-kube-system.yaml

    使用下面命令,验证pod是否正常运行:

    kubectl get po,rs,deploy -n kube-system | grep hostnetwork

    注意:由于已经对kube-system命名空间的user和service account授权使用hostNetwork,可见nginx-hostnetwork-deployment pod已经部署在kube-system命名空间。

    总结

    上面的内容演示了如何通过使用PSP授权使用特殊资源,在k8s集群中实现Pod Security Policy安全策略。

    参考资料

    本文分享自微信公众号 - 云原生生态圈(CloudNativeEcoSystem)。
    如有侵权,请联系 [email protected] 删除。
    本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

    03-10 02:46