As an Amazon Associate I earn from qualifying purchases from amazon.com

Coverage as Code and the Open Coverage Agent


Coverage as code is the pure evolution of infrastructure as code. When you begin to handle your infrastructure as code, you quickly understand that the method wants stable governance and enforcement of insurance policies at scale. The standard method of defining and implementing insurance policies with guide processes or cumbersome GUIs received’t minimize it.

Coverage as code signifies that you outline insurance policies declaratively utilizing textual content recordsdata which can be checked into supply management and could be reviewed and audited. Then, a coverage engine is accountable for implementing the insurance policies.

On this article, we’ll give attention to how coverage as code performs out in Kubernetes. We’ll take a look at what comes built-in with Kubernetes and the way the Open Coverage Agent—with Gatekeeper—helps Kubernetes operators take coverage enforcement additional.

The coverage as code mannequin matches Kubernetes like a glove, since Kubernetes is about declarative definitions at each degree. An administrator or developer defines sources, sometimes as YAML recordsdata, and Kubernetes shops them in its state retailer, etcd. Then, the Kubernetes controllers watch these sources and reconcile the state of the world with these sources.

For instance, if you happen to create a Deployment useful resource with a picture and a sure variety of replicas, then Kubernetes will create pods that run the picture and make sure the right variety of replicas is working.

Insurance policies are simply one other sort of useful resource

Kubernetes itself defines some insurance policies corresponding to pod safety insurance policies and community insurance policies. Nevertheless, the extensible nature of Kubernetes permits using third-party insurance policies and coverage engines.

Admission controllers as coverage enforcers

In Kubernetes, the lifecycle of a request goes by way of authentication, authorization, and admission. When a request comes  in, Kubernetes first authenticates it to see who’s making the request. Then, the request goes by way of authorization to see if the requesting entity is allowed to make this request. The request could be rejected at this level. If the request is allowed, then it goes by way of admission, which checks extra dynamic situations. A certified request might also be rejected at this stage.

Admission is the stage the place coverage enforcement is available in. Coverage engines could be applied as admission controllers that can flag, alert, and/or reject requests that violate insurance policies.

Pod safety insurance policies

Kubernetes had pod safety insurance policies, however they have been deprecated in Kubernetes 1.21 and will likely be changed by a more moderen design. Imposing safety settings on a pod is a vital concern that may’t be carried out utilizing present mechanisms like authentication, authorization, or pod safety context. A great instance of such a coverage is forbidding pods in a sure namespace to run with root privileges.

Community insurance policies

Controlling community ingress and egress is one other essential functionality. Kubernetes supplies built-in community insurance policies. The community coverage operates on the pod degree (utilizing label selectors) and may management entry (ingress and egress) on the namespace, pod, or IP block degree. Notice that Kubernetes doesn’t present a controller to implement the coverage. To make use of community insurance policies, the cluster will need to have a community plugin that helps community insurance policies.

Whereas Kubernetes’ built-in insurance policies are a very good begin, they’re inadequate for a lot of organizations with superior governance necessities. That is the place third-party coverage engines are available in. The Open Coverage Agent, which is a CNCF venture, is a cloud-native coverage engine that may implement insurance policies for a lot of completely different targets, together with Kubernetes, Envoy, Terraform, HTTP APIs, SQL databases, Plain purposes, Kafka, and extra.

On this article, we focus on Gatekeeper,  a Kubernetes admission controller that evaluates OPA insurance policies based mostly on Kubernetes customized useful resource definitions (CRD).

Gatekeeper parts

Gatekeeper consists of three major parts:

  1. The controller, accountable for creating Constraint customized sources.
  2. The auditor, which scans the cluster and detects coverage violations.
  3. The validating webhook, which is accountable for denying requests that violate insurance policies.

Gatekeeper additionally has a CLI known as Gator that may assist with testing constraints and constraint templates regionally. 

The coverage library

You’ll be able to outline your individual insurance policies, however Gatekeeper already comes with a considerable library of insurance policies. The library has a big part of basic insurance policies that cowl many subjects. Some examples embrace:

One of many causes Kubernetes deprecated its authentic PodSecurityPolicy is that the identical impact could be achieved by way of Gatekeeper constraints from the coverage library.

Gatekeeper constraint templates

A constraint template is a CRD that defines the schema and the definition of the constraint within the Rego language. The template could be personalized by an administrator to create concrete constraints to be enforced later.

Here’s a snippet from the requiredprobes constraint template:

apiVersion: templates.gatekeeper.sh/v1beta1
variety: ConstraintTemplate
metadata:
  identify: k8srequiredprobes
  annotations:
    description: Requires Pods to have readiness and/or liveness probes.
spec:
  crd:
    spec:
      names:
        variety: K8sRequiredProbes
      validation:
        openAPIV3Schema:
          sort: object
          properties:
            probes:
              description: "A listing of probes which can be required (ex: `readinessProbe`)"
              sort: array
              objects:
                sort: string
            probeTypes:
              description: "The probe should outline a discipline listed in `probeType` to be able to fulfill the constraint (ex. `tcpSocket` satisfies `['tcpSocket', 'exec']`)"
              sort: array
              objects:
                sort: string

Gatekeeper constraints

As soon as a constraint template is put in on the cluster, you possibly can outline constraints that use the templates. Gatekeeper enforces insurance policies specified by constraints.

That is an instance of a constraint based mostly on the requiredprobes template:

apiVersion: constraints.gatekeeper.sh/v1beta1
variety: K8sRequiredProbes
metadata:
  identify: must-have-probes
spec:
  match:
    varieties:
      - apiGroups: [""]
        varieties: ["Pod"]
  parameters:
    probes: ["readinessProbe", "livenessProbe"]
    probeTypes: ["tcpSocket", "httpGet", "exec"]

This constraint requires each pod to have readiness and liveness probes of the required probe sorts.

Rego: the declarative coverage language

The Rego language used to outline the coverage builds on high of a question language known as Datalog, extending Datalog to help structured paperwork. Rego could be very highly effective, and its declarative nature makes it an ideal match for coverage administration. Right here is an instance from the requiredprobes constraint template:

targets:
    - goal: admission.k8s.gatekeeper.sh
      rego: |
        bundle k8srequiredprobes
        probe_type_set = probe_types {
          probe_types :=  sort := enter.parameters.probeTypes[_]
        }
        violation[{"msg": msg}] {
          container := enter.evaluate.object.spec.containers[_]
          probe := enter.parameters.probes[_]
          probe_is_missing(container, probe)
          msg := get_violation_message(container, enter.evaluate, probe)
        }
        probe_is_missing(ctr, probe) = true {
          not ctr[probe]
        }
        probe_is_missing(ctr, probe) = true {
          probe_field_empty(ctr, probe)
        }
        probe_field_empty(ctr, probe) = true {
          probe_fields :=  ctr[probe][field]
          diff_fields := probe_type_set - probe_fields
          rely(diff_fields) == rely(probe_type_set)
        }
        get_violation_message(container, evaluate, probe) = msg {
          msg := sprintf("Container <%v> in your <%v> <%v> has no <%v>", [container.name, review.kind.kind, review.object.metadata.name, probe])
        }

OPA/Gatekeeper shouldn’t be the one recreation on the town. There are different Kubernetes-specific coverage engines with shallower studying curves: 

Kyverno is a Kubernetes-native coverage engine. Insurance policies are outlined as YAML utilizing Kubernetes CRDs. There isn’t any particular language like Rego. Kyverno has insurance policies to generate configuration, mutate present sources, and validate sources.

Okay-Rail is one other open-source coverage engine. Additionally it is Kubernetes-specific and comes with many built-in insurance policies. New insurance policies are outlined in Go and have to be added to the engine.

Coverage as code is a vital greatest observe for giant techniques. Kubernetes is the go-to platform for giant distributed techniques. There are a number of stable options for coverage as code on Kubernetes. OPA/Gatekeeper has a strong coverage definition language. Kyverno and Okay-Rail are Kubernetes-specific and could also be easier to make use of. Consider your wants and select the precise answer in your use case.


We’d love to listen to what you assume. Ask a query or go away a remark beneath.
And keep linked with Cisco DevNet on social!

LinkedIn | Twitter @CiscoDevNet | Fb Developer Video Channel

Share:



We will be happy to hear your thoughts

Leave a reply

Dealssoreal
Logo
Enable registration in settings - general
Compare items
  • Total (0)
Compare
0
Shopping cart