PSP examples

MKE admins or users with the appropriate permissions can create their own custom policies and attach them to MKE users or teams. This section highlights two use cases for custom PSPs. However, you can only apply one PSP to a Pod at a given time. Alternatively, you can combine the two use cases into one policy. Note that there are more PSP use cases than those covered in this topic.

Use a PSP to exclude root users

You can create a PSP to prevent a user from deploying containers that run with the root user.


To create a policy that excludes root users:

  1. Log in to MKE as cluster admin.

  2. Create a PSP using the parameter MustRunAsNonRoot:

    cat <<EOF | kubectl create -f -
    apiVersion: policy/v1beta1
    kind: PodSecurityPolicy
    metadata:
      name: norootcontainers
    spec:
      allowPrivilegeEscalation: false
      allowedHostPaths:
      - pathPrefix: /dev/null
        readOnly: true
      fsGroup:
        rule: RunAsAny
      hostPorts:
      - max: 65535
        min: 0
      runAsUser:
        rule: MustRunAsNonRoot
      seLinux:
        rule: RunAsAny
      supplementalGroups:
        rule: RunAsAny
      volumes:
      - '*'
    EOF
    
  3. If not done previously, remove the ClusterRoleBinding for the privileged policy:

    kubectl delete clusterrolebindings ucp:all:privileged-psp-role
    
  4. Create a ClusterRole that grants access to the new policy:

    cat <<EOF | kubectl create -f -
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: norootcontainers-psp-role
    rules:
    - apiGroups:
      - policy
      resourceNames:
      - norootcontainers
      resources:
      - podsecuritypolicies
      verbs:
      - use
    EOF
    
  5. Define a user to attach to the new policy:

    USER=<user-name>
    
  6. Create a RoleBinding that attaches the user to the ClusterRole:

    cat <<EOF | kubectl create -f -
    kind: RoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: norootcontainers-psp-role:$USER
      namespace: default
    roleRef:
      kind: ClusterRole
      name: norootcontainers-psp-role
      apiGroup: rbac.authorization.k8s.io
    subjects:
    - kind: User
      name: $USER
      namespace: default
    EOF
    

To verify the application of the new policy:

  1. Deploy a Pod that runs as a root user:

    cat <<EOF | kubectl create -f -
    apiVersion: v1
    kind: Pod
    metadata:
      name: demopod
    spec:
      containers:
        - name:  demopod
          image: nginx
    EOF
    
  2. Review the status of the Pod:

    kubectl get pods
    

    Example output:

    NAME      READY   STATUS                       RESTARTS   AGE
    demopod   0/1     CreateContainerConfigError   0          37s
    
  3. Describe the Pod:

    kubectl describe pods demopod
    

    Expected output:

    <..>
     Error: container has runAsNonRoot and image will run as root
    

Use a PSP to apply seccomp policies

You can create a PSP to prevent a user from deploying containers that do not have a seccomp policy.


To create a PSP that enforces the use of a seccomp policy:

  1. Log in to MKE as cluster admin.

  2. Create the new PSP:

    cat <<EOF | kubectl create -f -
    apiVersion: policy/v1beta1
    kind: PodSecurityPolicy
    metadata:
      name: seccomppolicy
      annotations:
        seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default'
        seccomp.security.alpha.kubernetes.io/defaultProfileName:  'docker/default'
    spec:
      allowPrivilegeEscalation: false
      allowedHostPaths:
      - pathPrefix: /dev/null
        readOnly: true
      fsGroup:
        rule: RunAsAny
      hostPorts:
      - max: 65535
        min: 0
      runAsUser:
        rule: RunAsAny
      seLinux:
        rule: RunAsAny
      supplementalGroups:
        rule: RunAsAny
      volumes:
      - '*'
    EOF
    
  3. If not done previously, remove the ClusterRoleBinding for the privileged policy:

    kubectl delete clusterrolebindings ucp:all:privileged-psp-role
    
  4. Create a ClusterRole that grants access to the new policy:

    cat <<EOF | kubectl create -f -
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: applyseccompprofile-psp-role
    rules:
    - apiGroups:
      - policy
      resourceNames:
      - seccomppolicy
      resources:
      - podsecuritypolicies
      verbs:
      - use
    EOF
    
  5. Define a user to attach to the new policy:

    USER=<user-name>
    
  6. Create a RoleBinding that attaches the user to the ClusterRole:

    cat <<EOF | kubectl create -f -
    kind: RoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: applyseccompprofile-psp-role:$USER
      namespace: default
    roleRef:
      kind: ClusterRole
      name: applyseccompprofile-psp-role
      apiGroup: rbac.authorization.k8s.io
    subjects:
    - kind: User
      name: $USER
      namespace: default
    EOF
    

To verify the application of the new policy:

If a user tries, for example, to deploy an nginx Pod without applying a seccomp policy as Pod metadata, Kubernetes automatically applies a policy for the user.

  1. Deploy a Pod without applying a seccomp policy in the Pod metadata:

    cat <<EOF | kubectl create -f -
    apiVersion: v1
    kind: Pod
    metadata:
      name: demopod
    spec:
      containers:
        - name:  demopod
          image: nginx
    EOF
    
  2. Review the status of the Pod:

    kubectl get pods
    

    Example output:

    NAME      READY   STATUS    RESTARTS   AGE
    demopod   1/1     Running   0          16s
    
  3. Verify that the seccomp policy is applied automatically:

    kubectl get pods demopod -o json | jq '.metadata.annotations."seccomp.security.alpha.kubernetes.io/pod"'
    

    Expected output:

    "docker/default"