Automating the Template for New OpenShift Projects

Posted: January 22nd, 2018 | Author: | Filed under: Technology | Tags: , , | No Comments »

Project templateSeparation of concerns is one of the fundamental principles in a multitenant environment. It ensures that multiple users can coexist without knowledge or access to each others resources. While OpenShift supports multitenancy through a number of different mechanisms, the use of projects provide users with their own separate workspace with the cluster. Built on top of Kubernetes namespaces, projects in OpenShift not only allows for a single user, but an entire community of users the ability to effectively collaborate within the cloud. One of the unique features of projects is that when they are initially created, they are preconfigured with a set of service accounts and permissions (roles/role bindings) that allow for users to be immediately productive. While the initial set of customized resources within a project provides a suitable baseline for end users, cluster administrators may want to enforce additional policies and configurations whenever a new project is created. Fortunately, OpenShift provides the capability of defining a default project template that will be instantiated whenever a new project is created. The following steps describe how to create a new default project template:

  1. Export the default project template to a file
  2. Make the appropriate modifications
  3. Add the template to the cluster
  4. Edit the master-config.yaml configuration on each master to designate the template that should be used as the default project template

In most of the clusters that I regularly deploy, I have automated these actions as a post installation step (obviously driven through Ansible). Even with the additional automation, it still presents another dependency that must be maintained when installing a new OpenShift environment. Fortunately starting with OpenShift 3.7.14, native support for configuring the default project template is available within the installation. Similar to the other options that are available during an installation of OpenShift, all that is required is defining a few Ansible variables. The rest of this post describes how to automate the configuration of a default project template through the OpenShift installer.

Before specifying the mechanisms necessary to configure the installer, let’s define a common use case of how the default project template could be modified. To protect the stability of the cluster, ResourceQuotas and LimitRanges can be applied to any new project to define the and restrict the amount of resources that can be consumed by running applications. While these metrics can vary from cluster to cluster, a middle of the road set of resources can be defined as follows:

ResourceQuotas

Name CPU Memory Scope
quota 2 12Gi NonTerminating
burst-quota 4 16

LimitRanges

Name Pod Max Pod Min Container Max Container Min Container Default
limits CPU: 200m Memory: 2Gi CPU: 10m Memory: 128Mi CPU: 200m Memory: 2Gi CPU: 20m Memory: 256Mi CPU: 50 Memory: 256Mi

The openshift_project_request_template Ansible role is ultimately responsible for implementing many of the steps that would normally need to be manually configured. This role makes use of an Ansible library called yedit that allows for the modification of YAML files. As the role executes, it exports the default project template and modifies the file with customized values. Any modification to the default project template must be defined by the variable openshift_project_request_template_edits which takes in an array of modifications that should be executed by yedit. This variable, similar to other variables that allow for the customization of the OpenShift installation are defined within the [OSEv3:vars] section of the Ansible inventory. Formatting the variable in a manner in which the module can properly process the changes is the most complex aspect of the customization process.

Each array value must define a set of values to perform the desired results of customizing the default project template. First is a key within the yaml file that should be modified. For those familiar with OpenShift templates, there are two primary key properties: objects which define the resources that are applied to OpenShift and parameters which allow for values to be dynamically injected at runtime. Since default project templates do not support additional parameter values, the only the object key can be modified. Since the desired outcome of the execution process is to append the existing list of objects, yedit has a module option called `append` that when set to True, will append the newly defined values with the existing values. Finally, the newly created object itself must be defined. Each additional resource to be added to the default project template must be separated into its own array object. In our use case, three objects will be created as shown below:

 

openshift_project_request_template_edits:
  - key: objects
    action: append
    value:
      apiVersion: v1
      kind: ResourceQuota
      metadata:
        annotations:
          openshift.io/quota-tier: Medium
        labels:
          quota-tier: Medium
        name: quota
      spec:
        hard:
          cpu: "2"
          memory: 12Gi
        scopes:
        - NotTerminating
  - key: objects
    action: append
    value:
      apiVersion: v1
      kind: ResourceQuota
      metadata:
        annotations:
          openshift.io/quota-tier: Medium
        labels:
          quota-tier: Medium
        name: burst-quota
      spec:
        hard:
          cpu: "4"
          memory: 16Gi
  - key: objects
    action: append
    value:
      apiVersion: v1
      kind: LimitRange
      metadata:
        annotations:
          openshift.io/quota-tier: Medium
        labels:
          quota-tier: Medium
        name: limits
      spec:
        limits:
        - max:
            cpu: 200m
            memory: 2Gi
          min:
            cpu: 10m
            memory: 128Mi
          type: Pod
        - default:
            cpu: 50m
            memory: 256Mi
          max:
            cpu: 200m
            memory: 2Gi
          min:
            cpu: 20m
            memory: 256Mi
          type: Container

 

Once the openshift_project_request_template_edits variable has been defined, a few more variables must also be defined. First, openshift_project_request_template_name should be defined in order to specify the name of the template that should be created and then openshift_project_request_template_namespace specifies the namespace (or project) in which the template will be created. To create a template called project-request in the default namespace, the following variables can be specified:

 

openshift_project_request_template_namespace: default
openshift_project_request_template_name: project-request

 

Next, the OpenShift installation must be instructed to execute the logic in the openshift_project_request_template through the use of the openshift_project_request_template_manage boolean variable which should be set to True as shown below:

 

openshift_project_request_template_manage: True

 

The final step is to define the name along with the namespace in the format namespace/name that will be added to the projectRequestTemplate field of the master-config.yaml file. This is defined by the osm_project_request_template as shown below:

 

osm_project_request_template: default/project-request

 

After the four (4) variables have been added, execute the installer against a new or existing OpenShift cluster.

Once the installer has completed, verify the expected results by logging in to the OpenShift environment and creating a new project. Create a new project called test-project-template.

 

oc new-project test-project-template

 

Verify the ResourceQuotas are present:

 

$ oc get resourcequotas

NAME          AGE
burst-quota   1m
quota         1m

 

Now verify the LimitRange was created:

 

$ oc get limitrange

NAME      AGE
limits    1m

 

With just a few Ansible variables, the OpenShift installer streamlined the steps necessary to configure the default project template for an OpenShift cluster.