Use Azure Policy to secure your Azure Kubernetes Service (AKS) clusters - Azure Kubernetes Service (original) (raw)

You can apply and enforce built-in security policies on your Azure Kubernetes Service (AKS) clusters using Azure Policy. Azure Policy helps enforce organizational standards and assess compliance at-scale. After you install the Azure Policy add-on for AKS, you can apply individual policy definitions or groups of policy definitions called initiatives (sometimes called policysets) to your cluster. See Azure Policy built-in definitions for AKS for a complete list of AKS policy and initiative definitions.

This article shows you how to apply policy definitions to your cluster and verify those assignments are being enforced.

Prerequisites

Assign a built-in policy definition or initiative

You can apply a policy definition or initiative in the Azure portal using the following steps:

  1. Navigate to the Azure Policy service in Azure portal called Policy.
  2. In the left pane of the Azure Policy page, select Definitions.
  3. Under Categories, select Kubernetes.
  4. Choose the policy definition or initiative you want to apply. For this example, select the Kubernetes cluster pod security baseline standards for Linux-based workloads initiative.
  5. Select Assign.
  6. Set the Scope to the resource group of the AKS cluster with the Azure Policy add-on enabled.
  7. Select the Parameters page and update the Effect from audit to deny to block new deployments violating the baseline initiative. You can also add extra namespaces to exclude from evaluation. For this example, keep the default values.
  8. Select Review + create > Create to submit the policy assignment.

Create and assign a custom policy definition

Custom policies allow you to define rules for using Azure. For example, you can enforce the following types of rules:

Before creating a custom policy, check the list of common patterns and samples to see if your case is already covered.

Custom policy definitions are written in JSON. To learn more about creating a custom policy, see Azure Policy definition structure and Create a custom policy definition.

Note

Azure Policy now utilizes a new property known as templateInfo that allows you to define the source type for the constraint template. When you define templateInfo in policy definitions, you don’t have to define constraintTemplate or constraint properties. You still need to define apiGroups and kinds. For more information on this, see Understanding Azure Policy effects.

Once you create your custom policy definition, see Assign a policy definition for a step-by-step walkthrough of assigning the policy to your Kubernetes cluster.

Validate an Azure Policy is running

kubectl get constrainttemplates  

Your output should be similar to the following example output:

NAME                                     AGE  
k8sazureallowedcapabilities              23m  
k8sazureallowedusersgroups               23m  
k8sazureblockhostnamespace               23m  
k8sazurecontainerallowedimages           23m  
k8sazurecontainerallowedports            23m  
k8sazurecontainerlimits                  23m  
k8sazurecontainernoprivilege             23m  
k8sazurecontainernoprivilegeescalation   23m  
k8sazureenforceapparmor                  23m  
k8sazurehostfilesystem                   23m  
k8sazurehostnetworkingports              23m  
k8sazurereadonlyrootfilesystem           23m  
k8sazureserviceallowedports              23m  

Validate rejection of a privileged pod

Let's first test what happens when you schedule a pod with the security context of privileged: true. This security context escalates the pod's privileges. The initiative disallows privileged pods, so the request is denied, which results in the deployment being rejected.

  1. Create a file named nginx-privileged.yaml and paste in the following YAML manifest.
apiVersion: v1  
kind: Pod  
metadata:  
  name: nginx-privileged  
spec:  
  containers:  
    - name: nginx-privileged  
      image: mcr.microsoft.com/oss/nginx/nginx:1.15.5-alpine  
      securityContext:  
        privileged: true  
  1. Create the pod using the kubectl apply command and specify the name of your YAML manifest.
kubectl apply -f nginx-privileged.yaml  

As expected, the pod fails to be scheduled, as shown in the following example output:

Error from server ([denied by azurepolicy-container-no-privilege-00edd87bf80f443fa51d10910255adbc4013d590bec3d290b4f48725d4dfbdf9] Privileged container is not allowed: nginx-privileged, securityContext: {"privileged": true}): error when creating "privileged.yaml": admission webhook "validation.gatekeeper.sh" denied the request: [denied by azurepolicy-container-no-privilege-00edd87bf80f443fa51d10910255adbc4013d590bec3d290b4f48725d4dfbdf9] Privileged container is not allowed: nginx-privileged, securityContext: {"privileged": true}  

The pod doesn't reach the scheduling stage, so there are no resources to delete before you move on.

Test creation of an unprivileged pod

In the previous example, the container image automatically tried to use root to bind NGINX to port 80. The policy initiative denies this request, so the pod fails to start. Now, let's try running that same NGINX pod without privileged access.

  1. Create a file named nginx-unprivileged.yaml and paste in the following YAML manifest.
apiVersion: v1  
kind: Pod  
metadata:  
  name: nginx-unprivileged  
spec:  
  containers:  
    - name: nginx-unprivileged  
      image: mcr.microsoft.com/oss/nginx/nginx:1.15.5-alpine  
  1. Create the pod using the kubectl apply command and specify the name of your YAML manifest.
kubectl apply -f nginx-unprivileged.yaml  
  1. Check the status of the pod using the kubectl get pods command.
kubectl get pods  

Your output should be similar to the following example output, which shows the pod is successfully scheduled and has a status of Running:

NAME                 READY   STATUS    RESTARTS   AGE  
nginx-unprivileged   1/1     Running   0          18s  

This example shows the baseline initiative affecting only the deployments that violate policies in the collection. Allowed deployments continue to function. 4. Delete the NGINX unprivileged pod using the kubectl delete command and specify the name of your YAML manifest.

kubectl delete -f nginx-unprivileged.yaml  

Disable a policy or initiative

You can remove the baseline initiative in the Azure portal using the following steps:

  1. Navigate to the Policy pane on the Azure portal.
  2. Select Assignments.
  3. Select the ... button next to the Kubernetes cluster pod security baseline standards for Linux-based workload initiative.
  4. Select Delete assignment.

Next steps

For more information about how Azure Policy works, see the following articles: