With the widespread adoption of containers among organizations, Kubernetes has become the de facto standard to deploy and operate containerized applications. As you expand your Kubernetes footprint, creating and enforcing consistent configurations and security policies across your growing fleet can create friction. Anthos Config Management (ACM) tackles this by enabling you to set and enforce consistent configurations and policies for your Kubernetes resources — wherever you build and run them — and manage Google Cloud services the same way. Anthos Config Management makes it even easier to declaratively specify resources with YAML or JSON by adding pre-built, opinionated config and policy automations, such as creating a secure landing zone and provisioning a GKE cluster from a blueprint

As the famous adage goes “show, don’t tell.” In this post, We’ll show an example of how you can leverage a GitOps methodology using Config Sync to apply configuration consistently across clusters and environments with an auditable, transactional, and version-controlled deployment process. And we’ll use Policy Controller for the enforcement of programmable policies that represent constraints on the desired state. 

First, follow the setup process in the Git Repo to build out the infrastructure and then deploy the services as per the directions.

1 Anthos Config Management.jpg

Now imagine that you’re a platform administrator, responsible for not just one of the services inside your organization, but for the entire Kubernetes environment, including the development, staging, and production clusters. An app developer may care most about testing their code and getting features into production with minimal friction, but your concerns are probably different. You care about consistency across the whole platform — that certain baseline configuration and policy are always deployed and in sync across all the clusters. (You do not want a developer to kubectl apply -f one of those resources by mistake, and you especially don’t want that to happen without knowing about it) You also care about compliance with your industry regulations, and you might work directly with your security team to make sure the necessary policies are in place.

In other words, as a platform admin, you really care about two things with the Kubernetes Resource Model (KRM) : 1) Consistency, and 2) Protecting the clusters from unsafe configuration. Let’s take a look at how using Anthos Config Management can help you achieve those two goals. 

​​In this example, we will deploy a mock banking application called Cymbal-Bank.

2 Anthos Config Management.jpg

For the purpose of this exercise, let’s assume that you have already installed Config Sync and Policy Controller in your clusters.

  (foo) arunkasi$ gcloud beta container hub config-management status \
>--project=arun-krm
Name            Status          Last_Synced_Token  Sync_Branch  Last_Synced_Time      Policy_Controller                          
cymbal-dev      SYNCED          720476f            main         2021-12-02T12:31:37Z  INSTALLED                                  
cymbal-prod     SYNCED          720476f            main         2021-12-02T12:32:34Z  INSTALLED                                  
cymbal-staging  SYNCED          720476f            main         2021-12-02T12:33:11Z  INSTALLED
  (foo) arunkasi$ kubectl get pods -n config-management-system
NAME                                          READY   STATUS    RESTARTS   AGE
admission-webhook-64948475d7-74j29            1/1     Running   3          32m
admission-webhook-64948475d7-ggwt2            1/1     Running   2          32m
config-management-operator-7d5f54c74c-pbxbs   1/1     Running   0          32m
reconciler-manager-7c6dccbb5f-6phml           2/2     Running   0          32m
root-reconciler-66c788cc97-cfl4s              4/4     Running   0          2m15s

(foo) arunkasi$ kubectl get pods -n gatekeeper-system
NAME                                             READY   STATUS    RESTARTS   AGE
gatekeeper-audit-8479c4fd8f-jmvcv                1/1     Running   0          2m48s
gatekeeper-controller-manager-7f778d8b94-vxsq9   1/1     Running   0          33m

The first set of pods, in the config-management-system namespace, run Config Sync. These workloads periodically check your GitHub policy repo for any updates to the KRM source of truth stored there, and deploy those updated resources to the cluster. These workloads help ensure that any resources entering the cluster — both through CI/CD or through Config Sync — adheres with any policies we set.

The second set of workloads, in the gatekeeper-system namespace, run Policy Controller,  which is based on the open-source Gatekeeper project, which in turn grew out of the OpenPolicyAgent project, part of the Cloud-Native Computing Foundation (the same foundation that hosts Kubernetes). 

Policy Controller is a Kubernetes dynamic admission controller that checks, audits, and enforces your clusters’ compliance with policies related to security, regulations, or arbitrary business rules. Policy Controller policies are broken up into two separate objects: Constraints and ConstraintTemplates. Having two distinct objects allows for separation of the policy definition (ConstraintTemplate) and policy enforcement (Constraint). 

Let’s unpack that. An admission controller is a pod that sits at the “gate” of a Kubernetes cluster, watching what’s coming into the API server and doing some type of operation on that resource, before it’s “allowed inside” the cluster and persisted in etcd. That “operation on the resource” could include modifying the resource in-flight (MutatingAdmissionWebhook) or rejecting the resource entirely (ValidatingAdmissionWebhook). Policy Controller uses the second kind of webhook to validate incoming config against the policies it knows about, allowing policies in, or rejecting them. 

Policy Controller enforces constraints, but what do those constraints actually look like? What kinds of Kubernetes resources can we use PolicyController to accept or reject?

Here’s an example constraint:

  (foo) arunkasi$ cat constraint-ext-services/constraint.yaml
# Blocks the creation of Ingress and Service type=LoadBalancer resources 
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sNoExternalServices
metadata:
  name: dev-no-ext-services
  annotations:
    configsync.gke.io/cluster-name-selector: cymbal-dev
spec:
  parameters:
    internalCIDRs: [ ]

Here, “kind: K8sNoExternalServices” refers to the k8snoexternalservices constraint template already installed on the cluster. And notice how we’re using Config Sync’s cluster-name-selector annotation to scope this resource to the cymbal-dev cluster only.

This Constraint implements the K8sNoExternalServices Constraint Template with concrete information about our environment.

Expected output:

  (foo) arunkasi$ kubectl get constraint 
NAME                                                                  AGE
k8snoexternalservices.constraints.gatekeeper.sh/dev-no-ext-services   2m15s

(foo) arunkasi$ kubectl apply -f constraint-ext-services/contacts-svc-lb.yaml
Error from server ([dev-no-ext-services] Creating services of type `LoadBalancer` without Internal annotation is not allowed)Resource: "/v1, Resource=services", GroupVersionKind: "/v1, Kind=Service" Name: "contacts", Namespace: "contacts"for: "constraint-ext-services/contacts-svc-lb.yaml": admission webhook "validation.gatekeeper.sh" denied the request: [dev-no-ext-services] Creating services of type `LoadBalancer` without Internal annotation is not allowed

With the above command, you just deployed a Policy Controller policy via Config Sync! When we went to deploy an application that violated the policy constraint, ACM correctly denied the request. If you would like to test drive this lab please follow the setup on this Git Repo developed by our Staff Developer Relations Engineer, Megan O’Keefe. If you’re a GKE customer, you can now use Anthos Config Management at a low incremental per-cluster cost. To learn more about Anthos Config Management and explore best practices, quickstarts, and tutorials, visit Google Cloud documentation page.

Take the next step

Start building on Google Cloud with $500 in free credits and 20+ always free products.