Bookmark this page

Guided Exercise: The Project Template and the Self-Provisioner Role

Restrict the ability to self-provision projects to a group of users, and ensure that all users from that group have write privileges on all projects that any of them creates. Also, ensure that their new projects are constrained by a limit range that restricts memory usage.

Outcomes

  • Limit project creation to a group of users.

  • Customize project creation.

As the student user on the workstation machine, use the lab command to prepare your system for this exercise.

This command performs the following actions:

  • Ensure that the cluster API is reachable.

  • Create the provisioner1 and provisioner2 users with the redhat password.

[student@workstation ~]$ lab start selfservice-projtemplate

Instructions

In this exercise, you configure the cluster so that only members of the provisioners group can create projects. Members of the provisioners group have full permissions on new projects. Users cannot create workloads that request more than 1 GiB of RAM in new projects.

  1. Log in to your OpenShift cluster as the admin user with the redhatocp password.

    1. Log in to the cluster as the admin user.

      [student@workstation ~]$ oc login -u admin -p redhatocp \
        https://api.ocp4.example.com:6443
      Login successful.
      ...output omitted...
  2. Allow only members of the provisioners group to create projects.

    1. Examine the provisioners group.

      [student@workstation ~]$ oc describe group provisioners
      Name:           provisioners
      Created:        12 seconds ago
      Labels:         <none>
      Annotations:    <none>
      Users:          provisioner1
                      provisioner2

      The provisioners group contains the provisioner1 and provisioner2 users.

    2. Use the oc edit command to edit the self-provisioners cluster role binding.

      [student@workstation ~]$ oc edit clusterrolebinding self-provisioners

      The oc edit command launches the vi editor to apply your modifications. Change the subject of the role binding from the system:authenticated:oauth group to the provisioners group.

      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRoleBinding
      metadata:
      ...output omitted...
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: self-provisioner
      subjects:
      - apiGroup: rbac.authorization.k8s.io
        kind: Group
        name: provisioners

      Note

      The rbac.authorization.kubernetes.io/autoupdate annotation protects this cluster role binding. If the API server restarts, then Kubernetes restores this cluster role binding.

      In this exercise context, you are not required to make the change permanent.

      Not in this exercise, but in a real-world context, you would make the change permanent by using the following command:

      [user@host ~]$ oc annotate clusterrolebinding/self-provisioners \
        --overwrite rbac.authorization.kubernetes.io/autoupdate=false
  3. Verify that users outside the provisioners group cannot create projects.

    1. Log in to the cluster as the developer user with the developer password.

      [student@workstation ~]$ oc login -u developer -p developer
      Login successful.
      
      You don't have any projects. Contact your system administrator to request a project.

      After the role binding is changed, the oc login command reports that you must contact your system administrator to request a project, because the developer user cannot create projects.

    2. Verify that the developer user cannot create projects.

      [student@workstation ~]$ oc new-project test
      Error from server (Forbidden): You may not request a new project via this API.
  4. Verify that members of the provisioners group can create projects.

    1. Log in to the cluster as the provisioner1 user with the redhat password.

      [student@workstation ~]$ oc login -u provisioner1 -p redhat
      Login successful.
      
      You don't have any projects. You can try to create a new project, by running
      ...output omitted...
    2. Create a project by using the oc new-project command.

      [student@workstation ~]$ oc new-project test
      Now using project "test" on server "https://api.ocp4.example.com:6443".
      ...output omitted...
    3. Verify that you can create resources in the test project.

      [student@workstation ~]$ oc create configmap test
      configmap/test created
  5. Verify that another member of the provisioners group cannot access the test project.

    1. Log in to the cluster as the provisioner2 user with the redhat password.

      [student@workstation ~]$ oc login -u provisioner2 -p redhat
      Login successful.
      
      You don't have any projects. You can try to create a new project, by running
      
          oc new-project <projectname>

      The oc login command reports that the provisioner2 user does not have any projects.

    2. Try to change to the test project with the oc project command.

      [student@workstation ~]$ oc project test
      error: You are not a member of project "test".
      You are not a member of any projects. You can request a project to be created with the 'new-project' command.
  6. Log in to the cluster as the admin user with the redhatocp password, to clean up.

    1. Log in as the admin user.

      [student@workstation ~]$ oc login -u admin -p redhatocp
      ...output omitted...
    2. Delete the test project.

      [student@workstation ~]$ oc delete project test
      project.project.openshift.io "test" deleted
  7. Create a namespace to design a project template. Add a limit range that prevents users from creating workloads that request more than 1 GiB of RAM.

    1. Use the oc create namespace command to create the template-test namespace.

      [student@workstation ~]$ oc create namespace template-test
      namespace/template-test created
    2. Edit the ~/DO280/labs/selfservice-projtemplate/limitrange.yaml file to add the limit. The file must match the following content:

      apiVersion: v1
      kind: LimitRange
      metadata:
        name: max-memory
        namespace: template-test
      spec:
        limits:
        - max:
            memory: 1Gi
          type: Container
    3. Use the oc create command to create the limit range that the ~/DO280/labs/selfservice-projtemplate/limitrange.yaml file defines.

      [student@workstation ~]$ oc create \
        -f ~/DO280/labs/selfservice-projtemplate/limitrange.yaml
      limitrange/max-memory created
    4. Examine the ~/DO280/labs/selfservice-projtemplate/deployment.yaml file. This file defines a deployment that requests 2 GiB of RAM.

      apiVersion: apps/v1
      kind: Deployment
      metadata:
      ...output omitted...
        name: test
      spec:
      ...output omitted...
        template:
      ...output omitted...
          spec:
            containers:
            - image: registry.ocp4.example.com:8443/redhattraining/hello-world-nginx:v1.0
              name: hello-world-nginx
              resources:
                limits:
                  memory: 2Gi
    5. Create the deployment by using the ~/DO280/labs/selfservice-projtemplate/deployment.yaml file.

      [student@workstation ~]$ oc create \
        -f ~/DO280/labs/selfservice-projtemplate/deployment.yaml \
        -n template-test
      deployment.apps/test created
    6. Examine the pods and events in the template-test namespace.

      [student@workstation ~]$ oc get pod -n template-test
      No resources found in template-test namespace.
      [student@workstation ~]$ oc get event -n template-test \
        --sort-by=metadata.creationTimestamp
      LAST SEEN   TYPE      REASON              OBJECT                       MESSAGE
      ...output omitted...
      39s         Warning   FailedCreate        replicaset/test-846769884c   Error creating: pods "test-846769884c-5zjhw" is forbidden: maximum memory usage per Container is 1Gi, but limit is 2Gi

      The limit range maximum prevents the deployment from creating pods.

  8. Define the project template.

    The ~/DO280/solutions/selfservice-projtemplate/template.yaml file contains a solution.

    1. Use the oc adm create-bootstrap-project-template command to print an initial project template. Redirect the output to the template.yaml file.

      [student@workstation ~]$ oc adm create-bootstrap-project-template \
        -o yaml >template.yaml
    2. Use the oc command to list the limit range in YAML format. Redirect the output to append to the template.yaml file.

      [student@workstation ~]$ oc get limitrange -n template-test \
        -o yaml >>template.yaml
    3. Edit the template.yaml file to perform the following operations:

      • Apply the following changes to the subjects key in the admin role binding:

        • Change the kind key to Group.

        • Change the name key to provisioners.

      • Move the limit range to immediately after the role binding definition.

      • Replace the namespace: template-test text with the namespace: ${PROJECT_NAME} text.

      • Remove any left-over content after the parameters block.

      • Remove the following keys from the limit range and quota definitions:

        • creationTimestamp

        • resourceVersion

        • uid

      If you use the vi editor, then you can use the following procedure to move a block of text:

      • Move to the beginning of the block.

      • Press V to enter visual line mode. This mode selects entire lines for manipulation.

      • Move to the end of the block. The editor highlights the selected lines.

      • Press d to delete the lines and to store them in a register for later use.

      • Move to the destination.

      • Press P to insert the lines that are stored in the register.

      You can also press dd to delete entire lines, and press . to repeat the operation.

      The resulting file should match the following content:

      apiVersion: template.openshift.io/v1
      kind: Template
      metadata:
        creationTimestamp: null
        name: project-request
      objects:
      - apiVersion: project.openshift.io/v1
        kind: Project
        metadata:
          annotations:
            openshift.io/description: ${PROJECT_DESCRIPTION}
            openshift.io/display-name: ${PROJECT_DISPLAYNAME}
            openshift.io/requester: ${PROJECT_REQUESTING_USER}
          creationTimestamp: null
          name: ${PROJECT_NAME}
        spec: {}
        status: {}
      - apiVersion: rbac.authorization.k8s.io/v1
        kind: RoleBinding
        metadata:
          creationTimestamp: null
          name: admin
          namespace: ${PROJECT_NAME}
        roleRef:
          apiGroup: rbac.authorization.k8s.io
          kind: ClusterRole
          name: admin
        subjects:
        - apiGroup: rbac.authorization.k8s.io
          kind: Group
          name: provisioners
      - apiVersion: v1
        kind: LimitRange
        metadata:
          name: max-memory
          namespace: ${PROJECT_NAME}
        spec:
          limits:
          - default:
              memory: 1Gi
            defaultRequest:
              memory: 1Gi
            max:
              memory: 1Gi
            type: Container
      parameters:
      - name: PROJECT_NAME
      - name: PROJECT_DISPLAYNAME
      - name: PROJECT_DESCRIPTION
      - name: PROJECT_ADMIN_USER
      - name: PROJECT_REQUESTING_USER

      Note

      The limit range has default and defaultRequest limits, although the definition does not contain these keys. When creating a limit range, always set the default and defaultRequest limits for more predictable behavior.

  9. Create and configure the project template.

    1. Use the oc command to create the project template.

      [student@workstation ~]$ oc create -f template.yaml -n openshift-config
      template.template.openshift.io/project-request created
    2. Use the oc edit command to change the global cluster project configuration.

      [student@workstation ~]$ oc edit projects.config.openshift.io cluster

      Edit the resource to match the following content:

      apiVersion: config.openshift.io/v1
      kind: Project
      metadata:
      ...output omitted...
        name: cluster
      ...output omitted...
      spec:
        projectRequestTemplate:
          name: project-request
    3. Use the watch command to view the API server pods.

      [student@workstation ~]$ watch oc get pod -n openshift-apiserver
      NAME		    READY   STATUS    RESTARTS	  AGE
      apiserver-6b7b...   2/2	    Running   0           2m30s

      Wait until new pods are rolled out. The rollout can take a few minutes to start. Press Ctrl+C to exit the watch command.

  10. Create a project as the provisioner1 user.

    1. Log in to the cluster as the provisioner1 user with the redhat password.

      [student@workstation ~]$ oc login -u provisioner1 -p redhat
      Login successful.
      ...output omitted...
    2. Create a project by using the oc new-project command.

      [student@workstation ~]$ oc new-project test
      Now using project "test" on server "https://api.ocp4.example.com:6443".
      ...output omitted...
  11. Verify that the provisioner2 user can access the test project and create resources. Verify that the limit range has the intended effect.

    1. Log in to the cluster as the provisioner2 user with the redhat password.

      [student@workstation ~]$ oc login -u provisioner2 -p redhat
      Login successful.
      
      You have one project on this server: "test"
      
      Using project "test".

      The oc login command reports that the provisioner2 user has the test project. The command selects the project.

    2. Create a resource on the test project.

      [student@workstation ~]$ oc create configmap test
      configmap/test created

      The provisioner2 user can create resources in a project that the provisioner1 user created.

    3. Create a deployment that exceeds the limit range by using the ~/DO280/labs/selfservice-projtemplate/deployment.yaml file.

      [student@workstation ~]$ oc create \
        -f ~/DO280/labs/selfservice-projtemplate/deployment.yaml
      deployment.apps/test created
    4. Examine the pods and events in the template-test namespace.

      [student@workstation ~]$ oc get pod
      No resources found in test namespace.
      [student@workstation ~]$ oc get event --sort-by=metadata.creationTimestamp
      LAST SEEN   TYPE      REASON              OBJECT                       MESSAGE
      ...output omitted...
      39s         Warning   FailedCreate        replicaset/test-846769884c   Error creating: pods "test-846769884c-5zjhw" is forbidden: maximum memory usage per Container is 1Gi, but limit is 2Gi

      The limit range works as expected.

Finish

On the workstation machine, use the lab command to complete this exercise. This step is important to ensure that resources from previous exercises do not impact upcoming exercises.

[student@workstation ~]$ lab finish selfservice-projtemplate

Revision: do280-4.14-08d11e1