AWS Open Source Blog
Using Open Policy Agent on Amazon EKS
中文版 – Open Policy Agent (OPA) is a Cloud Native Computing Foundation (CNCF) sandbox project designed to help you implement automated policies around pretty much anything, similar to the way the AWS Identity and Access Management (IAM) works. With OPA, you can write a very slimmed-down policy using a language called rego
which is based on datalog
. You can then deploy these into rego
files to the Open Policy Agent Admission Controller and have them Validate or Mutate any request that is made to the Kubernetes API Server. This means that you could write a two-line policy and have it implementing validations on the attributes in the requests, for example checking imagePullPolicy
for Always
, or that a Deployment
always has at least 2 replicas
, or that the registry the image comes from is in a whitelisted repository. The rest of this post will walk you through deploying OPA into an Amazon Elastic Container Service for Kubernetes (EKS) cluster and implementing a check to only allow images from your own Amazon Elastic Container Registry (ECR) or the EKS ECR repository.
Getting Started
Before we can get started, we’re going to need to set up an Amazon EKS cluster. We’ll use eksctl
with the Cluster config file mechanism. Start by downloading these prerequisites:
-
eksctl
– http://eksctl.io -
kubectl
– https://kubernetes.io/docs/tasks/tools/install-kubectl/
With all the necessary tools installed, we can get started launching our EKS cluster. In this example, we’re deploying the cluster in us-east-2
, our Ohio region; you can replace the AWS_REGION
with any region that supports Amazon EKS.
Deploy Cluster
Once we’ve exported the region, we can create the ClusterConfig
as follows:
After the file has been created, we create the cluster using the eksctl create cluster
command:
This will take roughly 15 minutes to complete, then we’ll have an Amazon EKS cluster ready to go. In the meantime, we can start preparing the Open Policy Agent requirements. First, we’re going to generate a Self-Signed Certificate Authority for our Admission Controller so that all communication can be done via TLS
.
Create Resources
With our CA created, we need to create a TLS key and certificate for OPA:
With the server.conf
created, we can use openssl
again to generate the key and cert:
Next, we’ll create our Open Policy Agent Admission Controller Manifest:
We’ll then create a ValidatingWebhookConfiguration
which will tell Kubernetes to send CREATE
, UPDATE
pod events to allow our policy to validate them:
We’ll then create our first policy. The policy we’re going to create will validate that every Pod
‘s image comes from a registry in a whitelist. The first two entries in our policy will be our own account’s Amazon ECR and the Amazon EKS-specific ECR.
Lastly, we’ll create the nginx
test Pod
manifest which we’ll use to test our policy:
Once the cluster has been created, we can deploy all the resources and test it out.
Deploy Resources
First, we’ll create the opa
namespace and set that in our current context. This will make it easier to keep track of everything we’re doing:
Now, we’ll deploy all the manifests previously created, starting with the tls secret with our server key and cert:
Then we deploy the admission controller:
If you are running your cluster in a multi-tenant or untrusted environment, it’s recommended to read through the TLS and Authentication schemes here.
After we have the AdmissionController
deployed, we can deploy the ValidatingWebhookConfiguration
that we created. This tells the Kubernetes API Server to send all Pod
CREATE
and UPDATE
events to opa service for validation.
The final configuration needed is to deploy our custom policy that restricts Pod
from being deployed from an untrusted registry:
Note: This command, unlike the other kubectl
commands we are using, is an imperative configuration. This can sometimes make keeping your ConfigMap
in sync difficult, especially if you use a deployment strategy such as Gitops
. If you’d like to use apply
, you’ll need to create the ConfigMap
manifest and copy your policy into the data
attribute.
Once we have created the policy, we can test to see that it compiled properly and that the Open Policy Agent successfully initialized the rego
script. To do this, use kubectl get configmap image-source -o yaml
:
With that deployed and initialized in the Open Policy Agent, we can then run the nginx
pod test.
Test Policy
Now let’s tag the nginx
image with our own registry, push the image, and try deploying from our own registry. First, we need to create a repository:
We’ll then get the repository name from the API so we can tag our nginx
instance:
Now we’ll pull the Docker Hub public nginx
locally so that we can retag it:
Then we can retag latest
with our repository name and push the image to your own Amazon ECR. We start by logging into Amazon ECR:
Then, push the latest
tag to Amazon ECR:
Now we can recreate our nginx
manifest file and push it to our Amazon EKS cluster:
Finally, we deploy our nginx
Pod
to the cluster:
Clean Up
If you would like to tear down the cluster created, you can delete all the resources created in the cluster, then delete the Amazon EKS cluster again using eksctl
:
More Examples
Here are a bunch of great examples of how people are using Open Policy Agent today with their Kubernetes clusters to help manage their custom policies:
Who’s using @OpenPolicyAgent with @kubernetesio today? Any interesting policies?
I just wrote one for Amazon EKS to check if images come from the EKS registry or your own accounts ECR.
What else are you using it for?
— Chris Hein (@christopherhein) March 1, 2019
Video of gatekeeper in action – https://t.co/brjywlDmen
— Lachlan Evenson (@LachlanEvenson) March 1, 2019
I wrote a couple of interesting policies for federation where it would allow deployments only to EU or worldwide clusters based on tags, and another that checked a third party ‘jira’ (mocked) that would only allow access to the production namespace if a P1 ticket was open
— Andy Repton (@SethKarlo) March 2, 2019
We use it for a variety of things, but the main one is to ensure people don’t add ingresses to the wrong ingress class and expose things to the internet that they shouldn’t
— briggsl (@briggsl) March 2, 2019
@OpenPolicyAgent is a new core component in our @kubernetesio as a Sevice Stack.
My colleague @sbueringer wrote two blog posts about it:https://t.co/LFkfJ8ElEs and https://t.co/ZxsQtZ2Z1Y— Mario Constanti (@bavarian_bidi) March 2, 2019
Conclusion
With Open Policy Agent, you no longer need to write custom code to handle your organization or teams’ custom policies. You can now deploy custom ValidatingAdmissionControllers
as we did in this writeup, or even MutatingAdmissionControllers
(which give your Kubernetes resources sane defaults), or set up proper labels. The controls you have are nearly endless. To learn more about Open Policy Agent, check out the Open Policy Agent documentation, and get involved with the Open Policy Agent community.