RHACM and Policies – More Details

October 11, 2021

As Kubernetes gets more and more adopted, the need for tools to manage diverse and widespread installations grows. Red Hat’s answer to that challenge is Red Hat Advanced Cluster Management for Kubernetes (RHACM).

This article is the continuation of my first article on policies in RHACM, which can be found here: 

https://open011prod.wpengine.com/2021/08/23/rhacm-and-policies-an-introduction/

Now I want to explain a bit more about the framework itself and its applicability.

Quick Recap

As mentioned in my first article on RHACM and Policies, a Policy is a CRD, and therefore can be represented in a YAML file. For the policy to be effective, it needs to consist of three parts: The Policy, the PlacementBinding and the PlacementRule:

apiVersion: policy.open-cluster-management.io/v1
kind: Policy
.
apiVersion: policy.open-cluster-management.io/v1
kind: PlacementBinding
.
apiVersion: apps.open-cluster-management.io/v1
kind: PlacementRule

Here we simply see the top line definitions of the three parts.

Note here, that the Kubernetes kind: Policy will define which (policy) controller to use in its policy-templates element via the below mentioned three types, namely:

  • The Configuration policy is of kind: ConfigurationPolicy
  • The Certificate policy is of kind: CertificatePolicy
  • The IAM policy is of kind: IamPolicy

According to the documentation, these are currently the three “Out-of-box Policy Controllers” supported by RHACM:

More information on the specifics and the allowed parameters of these controllers can be found in the GitHub sections of the controllers:

What they can contain, and how they interact will be explained in this blog entry.

Definitions

In order to have a policy framework, some definitions for the objects are needed. In the case of RHACM they are listed under:

https://github.com/open-cluster-management/governance-policy-framework/tree/main/deploy/crds

In the case of this article, we want to initially look at three of them, namely:

  • PlacementBinding
  • PlacementRule
  • Policy

As the Policy is the most powerful, we keep it until the end of these first three, and start with the most simple one.

Also, many of these things can be accessed via the RHACM API, documented here:

https://access.redhat.com/documentation/en-us/red_hat_advanced_cluster_management_for_kubernetes/2.3/html/apis/index

PlacementBinding

The current definition can be found here:

https://github.com/open-cluster-management/governance-policy-propagator/blob/main/deploy/crds/policy.open-cluster-management.io_placementbindings.yaml

What we see in there is that this connects a Policy referred to in the subjects part with a PlacementRule referred to in the PlacementRef part. As this is as simple as that, we can leave our explanations with that.

PlacementRule

The current definition can be found here:

https://github.com/open-cluster-management/multicloud-operators-placementrule/blob/main/deploy/crds/apps.open-cluster-management.io_placementrules_crd.yaml

What this allows us to do, is to define, where the Policies shall be applied to.

In the definition we see, that spec is a required element for the definition, and under spec we find the following 7 elements:

  • clusterConditions
  • clusterReplicas
  • clusterSelector
  • clusters
  • policies
  • resourceHint
  • schedulerName

Note: This PlacementRule definition is also used for the application deployment part of RHACM, therefore some aspects might not make much sense in the context of policies.

An example for this is the clusterReplicas element, which allows to define on how many clusters an application shall run concurrently, if the matching of the clusters leads to more than one cluster. In the case of a policy, we always want these policies to be available on all matched clusters, therefore we will ignore this element here.

The schedulerName so far does not contain any specification via some sort or properties, therefore we can currently ignore that field as a selector for objects to apply policies to.

The policies element is also more important in the case of application deployment, as it allows defining filters to apply to the Policy, therefore we can and will also ignore that here.

An important part is the clusterConditions section. This is typically always set to status: “True” for the kind: ManagedClusterConditionAvailable. This way we ensure that a policy is only applied to a cluster that is really managed by RHACM.

This leaves us with three elements to look at.

clusters allows us to define an array of clusters by just using their names.

clusterSelector allows us to define rules for selecting clusters to which policies shall be applied either via matchExpressions or matchLabels. The matchLabels option is the same as a matchExpressions definition with some predefined elements for quicker typing for the lazy developers. Details can be found in the definition file linked above.

resourceHint I have not yet seen in practice with policies, so I leave the exploration of its applicability to the reader.

Policy

This is the third and most important part of the policy framework in RHACM.

The current definition can be found here:

https://github.com/open-cluster-management/governance-policy-propagator/blob/main/deploy/crds/policy.open-cluster-management.io_policies.yaml

The policy definition itself is more simple than the one for the placementRule, but the fun starts with its elements.

There are practically just two, spec and status.

As status is the return value, we will only look at spec here.

The properties element of the spec contains three elements:

  • remediationAction (can be inform or enforce)
  • disable (true or false)
  • policy-templates

This so far explains the YAML structure that RHACM uses in its Policy or GRC section.

Policy Templates

The following sections now look at the three officially included and supported policy templates, as mentioned above:

  • ConfigurationPolicy
  • CertificatePolicy
  • IamPolicy

As we can see further down in the screenshot of the specification selection box, there are a couple more options here, but let’s now look at the three officially supported policy-templates in a bit more detail:

ConfigurationPolicy

The current definition can be found here:

https://github.com/open-cluster-management/config-policy-controller/blob/main/deploy/crds/policy.open-cluster-management.io_configurationpolicies_crd.yaml

Again like in the Policy definition above, in the ConfigurationPolicy we have the following elements of the spec:

  • labelSelector
  • namespaceSelector
  • object-templates
  • remediationAction (enforce or inform)
  • severity (low, medium or high)

With the namespaceSelector and/or the labelSelector it’s possible to include or exclude namespaces or clusters. The real work is in defining the object-templates, which can be a list/an array of objectDefinition which has a complianceType of musthave, mustnothave or mustonlyhave.

This allows to describe in different ConfigurationPolicy elements, how the Kubernetes clusters shall be configured. With the enforce remediationAction switch it is even possible to control applications, routes, etc. in Kubernetes clusters.

CertificatePolicy

The current definition can be found here:

https://github.com/open-cluster-management/cert-policy-controller/blob/main/deploy/crds/policy.open-cluster-management.io_certificatepolicies_crd.yaml

Again like in the Policy definition above, in the CertificatePolicy we have the following elements of the spec:

  • labelSelector
  • allowedSANPattern
  • disallowedSANPattern
  • maximumCADuration
  • maximumDuration
  • minimumCADuration
  • minimumDuration
  • namespaceSelector
  • remediationAction (enforce or inform)
  • severity (low, medium or high)

As most of the elements have been already mentioned in some of the other policy descriptions above, I’ll leave the unexplained options here to the interested reader.

IamPolicy

The current definition can be found here:

https://github.com/open-cluster-management/iam-policy-controller/blob/main/deploy/crds/policy.open-cluster-management.io_iampolicies_crd.yaml

Again like in the Policy definition above, in the IamPolicy we have the following elements of the spec:

  • ignoreClusterRoleBinding
  • labelSelector
  • maxClusterRoleBindingUsers
  • clusterRole
  • namespaceSelector
  • remediationAction (enforce or inform)
  • severity (low, medium or high)

As we already had been talking about some of these values, I will not go into more detail with all values, as they can be also seen in the definition file linked above. As an example I’ll just mention the ignoreClusterRoleBindings which is a list of regex values signifying which cluster role binding names to ignore. 

And more…

There are additional approaches, like the Gatekeeper controller which I used as an example in the first post.

If we look at the GUI, we see, that there are more policy approaches available from the specification section in the GUI, which I will leave open to the interested reader:

Summary

Policies allow to describe how Kubernetes configurations shall look like. Just like for example with the Red Hat Ansible Automation Platform and its playbooks, which describe the desired endstate of a configuration and leave the execution of the changes to the modules in Ansible, policies in RHACM allow to describe the desired state of Kubernetes clusters and leave the work to reach these desired configuration states to the policy controllers in RHACM.

Therefore this can even be used to deploy applications onto Kubernetes clusters, because everything in Kubernetes is an object, and the policies can describe, which objects shall be available, so making sure that for example an imagesource is there, and specific containers are started in the Kubernetes cluster.

With policies the control can be moved from a less workflow based to a more desired state config description approach. This is a very powerful toolset and there are many examples to draw from directly in RHACM as well as in the upstream communities GitHub repository at: https://github.com/open-cluster-management/policy-collection.