A pod security policy (PSP) is a Kubernetes resource that is used to validate pod creation requests against a set of rules. This feature can limit the container runtime behavior to enhance security. This topic describes how to create, manage, and associate a PSP to service accounts.

Prerequisites

  • A managed or dedicated cluster is created. The cluster version is 1.14.8-aliyun.1 or later. For more information, see Create a managed ACK cluster.
  • An Alibaba Cloud account or a RAM user that has the administrator role is used to log on to the Container Service for Kubernetes (ACK) console. For more information, seeConfigure RBAC permissions for RAM users .

Background information

ACK allows you to create custom PSPs by specifying parameters in policy templates. This feature can limit the container runtime behavior to enhance security. To ensure security, you may consider using security engines such as AppArmor and SELinux to validate pod creation requests. To meet your security requirements, ACK enables the PSP feature. The following list describes this feature:
  • A PSP is a cluster-level Kubernetes resource that is used to validate pod creation requests against a set of rules. To use a policy, you must install and enable the PSP admission controller for kube-apiserver. If a pod fails to meet the conditions defined in a specified policy, kube-apiserver rejects the pod creation request.
  • To use a policy, enable the PSP admission controller. For more information, see Enable an admission controller. You must also use RBAC to create a role that has the permission to use the policy and then bind the role to target service accounts.
  • By default, ACK enables the PSP feature for new managed or dedicated clusters. In this case, you do not have to configure related parameters for kube-apiserver. This reduces the O&M workloads.
  • Assume that you have enabled the PSP feature for a cluster. To ensure the smooth running of the cluster, ACK creates a default policy named ack.privileged. This policy does not limit pod creation and is applied to all authenticated users of the cluster. However, we recommend that you create custom policies that grant users the minimum permissions. For example, you can create custom policies to prevent certain users from creating privileged pods. You can also set the root file system to read-only or specify a list of host paths that can store hostPath volumes.

Create a custom policy

  1. Log on to the ACK console.
  2. On the Clusters page, click the name of the target cluster or click Manage for the target cluster in the Actions column.
  3. On the page that appears, choose Security > PSPs.
  4. On the PSPs tab, click Create. In the dialog box that appears, select a policy template and click Use.
    The default policy ack.privileged does not limit pod creation and is applied to all authenticated users. You can use the following templates to create custom policies:
    • privileged-restricted: limits the creation of privileged pods. For example, you can specify whether to allow the creation of privileged pods that use the host network, host port, or host namespace.
    • privileged-root-volumes-restricted: limits the creation of privileged pods. For example, you can specify whether to allow the creation of privileged pods that use the host network, host port, or host namespace. You can also specify the supported volume types and limit the root privileges of pods.
  5. On the Create YAML page, create a custom policy by specifying parameter values in the YAML file based on your needs. For more information about the parameters, see Pod security policies.
    Parameter Description
    privileged Specifies whether a privileged pod can be created.
    hostPID and hostIPC Specify whether a pod can use the host namespace.
    hostNetwork and hostPorts Specify whether a pod can use the host network and host ports.
    volumes The supported volume types.
    allowedHostPaths A list of host paths that can store hostPath volumes. After you specify pathPrefix, hostPath volumes can be stored in all paths that use the specified prefix.
    allowedFlexVolumes The FlexVolume drivers supported by the pod.
    fsGroup The ID of the FSGroup that contains the volumes mounted to the pod.
    readOnlyRootFilesystem Specifies whether to set the root file system of the pod to read-only.
    runAsUser, runAsGroup, and supplementalGroups The IDs of the user, primary user group, and supplemental user group of the pod containers.
    allowPrivilegeEscalation and defaultAllowPrivilegeEscalation Specify whether to allow privilege escalation for containers. The two parameters determine whether setuid binaries can be used.
    defaultAddCapabilities, requiredDropCapabilities, and allowedCapabilities The Linux capabilities of pod containers.
    seLinux The SELinux context of pod containers.
    allowedProcMountTypes The ProcMountTypes of pod containers.
    annotations The AppArmor or seccomp profile of pod containers.
    forbiddenSysctls and allowedUnsafeSysctls The sysctl profile of pod containers.
  6. Click OK.
    On the PSPs tab, you can view the details of the policy that you create.
    Note
    • To modify a policy, click YAML for the target policy in the Actions column.
    • To delete a policy, click Delete for the target policy in the Actions column.

Associate a custom policy with service accounts

Assume that you have enabled the PSP feature for a cluster and disassociated the default policy. To use a custom policy, associate the policy with target service accounts. If no custom policy is associated, the following error occurs when you create a pod.
Error from server (Forbidden): error when creating xxx: pods "xxx" is forbidden: unable to validate against any pod security policy: []
You can associate a custom policy with specified or all service accounts in a specified namespace.
  1. Log on to the ACK console.
  2. On the Clusters page, click the name of the target cluster or click Manage for the target cluster in the Actions column.
  3. On the page that appears, choose Security > PSPs.
  4. Select the Association Rules tab and then click Add Association Rule. In the Add Association Rule dialog box, set Namespace, Account, and PSP.
  5. Click OK.

Disassociate the default policy from service accounts

To use a custom policy, disassociate the default policy from service accounts first.
  • When you disassociate the default policy, the system automatically grants the permission to use the default policy to all service accounts in the kube-system namespace and the system:nodes user group. This ensures that the system components and containers run smoothly.
  • If you do not associate a custom policy with service accounts in a specified namespace, the system automatically grants all service accounts in the namespace the permission to use the default policy. This ensures that the containers in the namespace run smoothly.
Notice
  • For a namespace in which service accounts are associated with a custom policy:

    To ensure that a custom policy takes effect, the system does not automatically associate the default policy with service accounts. Therefore, before you disassociate the default policy, make sure that service accounts in the namespace are associated with a target custom policy.

  • For a namespace that is newly created:

    The system does not automatically associate the default policy with service accounts in a new namespace. After you create a namespace, we recommend that you create a custom policy and associate it with service accounts in the namespace at the earliest opportunity.

  1. Log on to the ACK console.
  2. On the Clusters page, click the name of the target cluster or click Manage for the target cluster in the Actions column.
  3. On the page that appears, choose Security > PSPs.
  4. In the PSP Management Guide section, click Disassociate Default PSP.
  5. In the Disassociate dialog box, click OK.

Enable the PSP admission controller

By default, ACK enables the PSP admission controller for new clusters. To ensure that PSPs take effect in an existing cluster, enable the admission controller for kube-apiserver.

  1. Log on to the ACK console.
  2. On the Clusters page, click the name of the target cluster or click Manage for the target cluster in the Actions column.
  3. On the page that appears, choose Security > PSPs.
  4. Enable the admission controller.
    • In the upper-right corner of the PSPs page, Disabled indicates that the admission controller is disabled. You can click Change PSP State and then click OK to enable it.
    • In the upper-right corner of the PSPs page, Enabled indicates that the admission controller is enabled.
    Notice If you enable the admission controller, kube-apiserver is restarted. To minimize the impact on services, we recommend that you change the status of the admission controller during off-peak hours.

Examples

The following examples show how to create custom policies and associate them with service accounts.

  1. Connect to Kubernetes clusters through kubectl.
  2. Create custom policies based on the privileged-restricted and privileged-root-volumes-restricted templates. For more information, see Create a custom policy.
  3. Run the following commands to create two namespaces and service accounts in the namespaces, and use RBAC to bind required roles to service accounts.
    kubectl create ns ack-all-restrictive
    kubectl create ns ack-restrictive
    
    kubectl create sa ack-dev -n ack-restrictive
    kubectl create sa ack-tester -n ack-all-restrictive
    
    kubectl -n ack-restrictive create rolebinding ack-dev-editor \
               --clusterrole=edit \
               --serviceaccount=ack-restrictive:ack-dev
    kubectl -n ack-all-restrictive create rolebinding ack-tester-editor \
               --clusterrole=edit \
               --serviceaccount=ack-all-restrictive:ack-tester          
  4. On the Association Rules tab, associate custom policies with service account ack-dev.
    1. Click Add Association Rule. In the Add Association Rule dialog box, set Namespace to ack-restrictive, Account to ack-dev, and PSP to privileged-restricted. Click OK.
    2. Click Add Association Rule. In the Add Association Rule dialog box, set Namespace to ack-restrictive, Account to ack-dev, and PSP to privileged-root-volumes-restricted. Click OK.
  5. Run the following commands to generate aliases for service account ack-dev in namespace ack-restrictive and service account ack-tester in namespace ack-all-restrictive.
    alias kubectl-dev='kubectl --as=system:serviceaccount:ack-restrictive:ack-dev -n ack-restrictive'
    alias kubectl-tester='kubectl --as=system:serviceaccount:ack-all-restrictive:ack-tester -n ack-all-restrictive'
    
    kubectl-dev auth can-i use  podsecuritypolicy/privileged-restricted
    Warning: resource 'podsecuritypolicies' is not namespace scoped in group 'policy'
    yes
                            
  6. Run the following command to create a privileged pod that uses the host network.
    kubectl-dev 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 retrieving current configuration of:
    Resource: "/v1, Resource=pods", GroupVersionKind: "/v1, Kind=Pod"
    Name: "privileged", Namespace: "ack-restrictive"
    Object: &{map["apiVersion":"v1" "kind":"Pod" "metadata":map["annotations":map["kubectl.kubernetes.io/last-applied-configuration":""] "name":"privileged" "namespace":"ack-restrictive"] "spec":map["containers":[map["command":["sh" "-c" "sleep 1h"] "image":"busybox" "name":"busybox"]] "hostNetwork":%! q(bool=true)]]}
    from server for: "STDIN": pods "privileged" is forbidden: User "system:serviceaccount:ack-restrictive:ack-dev" cannot get resource "pods" in API group "" in the namespace "ack-restrictive"
    An error occurs when you create the privileged pod.
  7. Run the following command to create an unprivileged pod.
    kubectl-dev apply -f- <<EOF
    apiVersion: v1
    kind: Pod
    metadata:
      name: non-privileged
    spec:
      containers:
        - name: busybox
          image: busybox
          command: [ "sh", "-c", "sleep 1h" ]
    EOF
    pod/non-privileged created
    According to the command output, the unprivileged pod is created.
  8. Run the following commands to create a pod that has root privileges and a pod that does not have root privileges.
    kubectl-tester apply -f- <<EOF
    apiVersion: v1
    kind: Pod
    metadata:
      name: root-pod
    spec:
      containers:
        - name: busybox
          image: busybox
          command: [ "sh", "-c", "sleep 1h" ]
    EOF
    
    kubectl-tester apply -f- <<EOF
    apiVersion: v1
    kind: Pod
    metadata:
      name: non-root-pod
    spec:
      containers:
        - name: busybox
          image: busybox
          command: [ "sh", "-c", "sleep 1h" ]
          securityContext:
            runAsUser: 1000
            runAsGroup: 3000
    EOF
  9. Run the following command to query the statuses of pods.
    The pod that has root privileges cannot be created. The custom policy associated with service account ack-tester prevents the creation of pods that have root privileges.
    kubectl-tester get po
    NAME           READY   STATUS                       RESTARTS   AGE
    non-root-pod   1/1     Running                      0          115s
    root-pod       0/1     CreateContainerConfigError   0          24s
  10. Run the following command to query the error details.
    kubectl describe pod root-pod
    Warning  Failed     28s (x5 over 2m1s)   kubelet, cn-shenzhen.192.168.1.52  Error: container has runAsNonRoot and image will run as root