|
| 1 | +--- |
| 2 | +title: Capsule on OpenShift |
| 3 | +weight: 30 |
| 4 | +description: > |
| 5 | + How to install Capsule and the Capsule Proxy on OpenShift |
| 6 | +--- |
| 7 | + |
| 8 | +## Introduction |
| 9 | + |
| 10 | +Capsule is a Kubernetes multi-tenancy operator that enables secure namespace-as-a-service in Kubernetes clusters. When combined with OpenShift's robust security model, it provides an excellent platform for multi-tenant environments. |
| 11 | + |
| 12 | +This guide demonstrates how to deploy Capsule and Capsule Proxy on OpenShift using the `nonroot-v2` and `restricted-v2` SecurityContextConstraint [SecurityContextConstraint (SCC)](https://docs.redhat.com/en/documentation/openshift_container_platform/4.18/html/authentication_and_authorization/managing-pod-security-policies), ensuring tenant owners operate within OpenShift's security boundaries. |
| 13 | + |
| 14 | +## Why Capsule on OpenShift |
| 15 | +While OpenShift can be already configured to be quite multi-tenant (together with for example Kyverno), Capsule takes it a step further and easier to manage. |
| 16 | + |
| 17 | +When people say a multitenant kubernetes cluster, they often think they will get one or two namespaces inside a cluster, with not that much privileges. But: Capsule is different. As a tenant owner, you can create as many namespaces as you want. RBAC is much easier, since Capsule is handling it, making it less error-prone. And resource quota is not set per namespace, but it's spread across a whole tenant, making management easy. Not to mention RBAC issues while listing clusterwide resources that are solved by the Capsule Proxy. Also, even some operators are able to be installed inside a tenant because of the [Capsule Proxy](./docs/proxy). Add the service account as a tenant owner, and set the env variable `KUBERNETES_SERVICE_HOST` of the operator deployment to the capsule proxy url. Now your operator thinks it is admin, but it lives completely inside the tenant. |
| 18 | + |
| 19 | +## Prerequisites |
| 20 | +Before starting, ensure you have: |
| 21 | +- OpenShift cluster with cluster-admin privileges |
| 22 | +- `kubectl` CLI configured |
| 23 | +- Helm 3.x installed |
| 24 | +- cert-manager installed |
| 25 | + |
| 26 | +## Limitations |
| 27 | +There are a few limitations that are currently known of using OpenShift with Capsule: |
| 28 | +- A tenant owner can not create a namespace/project in the OpenShift GUI. This must be done with `kubectl`. |
| 29 | +- When copying the `login token` from the OpenShift GUI, there will always be the server address of the kubernetes api instead of the Capsule Proxy. There is a RFE created at Red Hat to make this url configurable ([RFE-7592](https://issues.redhat.com/browse/RFE-7592)). If you have a support contract at Red Hat, it would be great to create a SR and ask that you would also like to have this feature to be implemented. The more requests there are, the more likely it will be implemented. |
| 30 | + |
| 31 | +## Capsule Installation |
| 32 | +### Remove selfprovisioners rolebinding |
| 33 | +By default, OpenShift comes with a selfprovisioner role and rolebinding. This role lets all users always create namespaces. For the use case of Capsule, this should be removed. The [Red Hat documentation](https://docs.redhat.com/en/documentation/openshift_container_platform/4.16/html/building_applications/projects#disabling-project-self-provisioning_configuring-project-creation) can be found here. |
| 34 | +Remove the subjects from the rolebinding: |
| 35 | +```shell |
| 36 | +kubectl patch clusterrolebinding.rbac self-provisioners -p '{"subjects": null}' |
| 37 | +``` |
| 38 | +Also set the `autoupdate` to false, so the rolebinding doesn't get reverted by Openshift. |
| 39 | +```shell |
| 40 | +kubectl patch clusterrolebinding.rbac self-provisioners -p '{ "metadata": { "annotations": { "rbac.authorization.kubernetes.io/autoupdate": "false" } } }' |
| 41 | +``` |
| 42 | + |
| 43 | +### Extend the admin role |
| 44 | +In this example, we will add the default kubernetes `admin` role to the tenant owner, so it gets admin privileges on the namespaces that are in their tenant. This role should be extended. |
| 45 | +- Add the finalizers so users can create/edit resources that are managed by capsule |
| 46 | +- Add the SCC's that tenant owners can use. In this example, it is will be `restricted-v2` and `nonroot-v2`. |
| 47 | + |
| 48 | +```yaml |
| 49 | +kind: ClusterRole |
| 50 | +apiVersion: rbac.authorization.k8s.io/v1 |
| 51 | +metadata: |
| 52 | + name: extend-admin-role |
| 53 | + labels: |
| 54 | + rbac.authorization.k8s.io/aggregate-to-admin: 'true' |
| 55 | +rules: |
| 56 | + - verbs: |
| 57 | + - update |
| 58 | + apiGroups: |
| 59 | + - capsule.clastix.io |
| 60 | + resources: |
| 61 | + - '*/finalizers' |
| 62 | + - apiGroups: |
| 63 | + - security.openshift.io |
| 64 | + resources: |
| 65 | + - securitycontextconstraints |
| 66 | + resourceNames: |
| 67 | + - restricted-v2 |
| 68 | + - nonroot-v2 |
| 69 | + verbs: |
| 70 | + - 'use' |
| 71 | +``` |
| 72 | +
|
| 73 | +### Helm Chart values |
| 74 | +The jobs that Capsule uses can be runned with the `restricted-v2` SCC. For this, the securityContext and podSecurityContexts of the job must be disabled. For Capsule it self, we leave it to enabled. This is because capsule runs as `nonroot-v2`, which is still a very secure SCC. Also, always add the `pullPolicy: Always` on a multitenant cluster, to make sure you are working with the correct images you intended to. |
| 75 | +The following chart values can be used: |
| 76 | +```yaml |
| 77 | + podSecurityContext: |
| 78 | + enabled: true |
| 79 | + securityContext: |
| 80 | + enabled: true |
| 81 | + jobs: |
| 82 | + podSecurityContext: |
| 83 | + enabled: false |
| 84 | + securityContext: |
| 85 | + enabled: false |
| 86 | + image: |
| 87 | + pullPolicy: Always |
| 88 | + manager: |
| 89 | + image: |
| 90 | + pullPolicy: Always |
| 91 | +``` |
| 92 | +Deploy the Capsule Helm chart with (at least) these values. |
| 93 | + |
| 94 | +### Example tenant |
| 95 | +A minimal example tenant can look as the following: |
| 96 | +```yaml |
| 97 | +apiVersion: capsule.clastix.io/v1beta2 |
| 98 | +kind: Tenant |
| 99 | +metadata: |
| 100 | + name: sun |
| 101 | +spec: |
| 102 | + imagePullPolicies: |
| 103 | + - Always |
| 104 | + owners: |
| 105 | + - clusterRoles: |
| 106 | + - admin |
| 107 | + - capsule-namespace-deleter |
| 108 | + kind: Group |
| 109 | + name: sun-admin-group |
| 110 | + priorityClasses: |
| 111 | + allowed: |
| 112 | + - openshift-user-critical |
| 113 | +``` |
| 114 | + |
| 115 | +## Capsule Proxy |
| 116 | +The same principles for Capsule are also for Capsule Proxy. That means, that all (pod)SecurityContexts should be disabled for the job. |
| 117 | +In this example we enable the `ProxyAllNamespaced` feature, because that is one of the things where the Proxy really shines in its power. |
| 118 | +The following helm values can be used as a template: |
| 119 | +```yaml |
| 120 | + securityContext: |
| 121 | + enabled: true |
| 122 | + podSecurityContext: |
| 123 | + enabled: true |
| 124 | + options: |
| 125 | + generateCertificates: false #set to false, since we are using cert-manager in .Values.certManager.generateCertificates |
| 126 | + enableSSL: true |
| 127 | + extraArgs: |
| 128 | + - '--feature-gates=ProxyAllNamespaced=true' |
| 129 | + - '--feature-gates=ProxyClusterScoped=false' |
| 130 | + image: |
| 131 | + pullPolicy: Always |
| 132 | + global: |
| 133 | + jobs: |
| 134 | + kubectl: |
| 135 | + securityContext: |
| 136 | + enabled: true |
| 137 | + webhooks: |
| 138 | + enabled: true |
| 139 | + certManager: |
| 140 | + generateCertificates: true |
| 141 | + ingress: |
| 142 | + enabled: true |
| 143 | + annotations: |
| 144 | + route.openshift.io/termination: "reencrypt" |
| 145 | + route.openshift.io/destination-ca-certificate-secret: capsule-proxy-root-secret |
| 146 | + hosts: |
| 147 | + - host: "capsule-proxy.example.com" |
| 148 | + paths: ["/"] |
| 149 | +``` |
| 150 | +That is basically all the configuration needed for the Capsule Proxy. |
| 151 | + |
| 152 | +## Console Customization |
| 153 | +The OpenShift console can be customized. For example, the capsule-proxy can be added as a shortcut on the top right application menu with the `ConsoleLink` CR: |
| 154 | +```yaml |
| 155 | +apiVersion: console.openshift.io/v1 |
| 156 | +kind: ConsoleLink |
| 157 | +metadata: |
| 158 | + name: capsule-proxy-consolelink |
| 159 | +spec: |
| 160 | + applicationMenu: |
| 161 | + imageURL: 'https://github.com/projectcapsule/capsule/raw/main/assets/logo/capsule.svg' |
| 162 | + section: 'Capsule' |
| 163 | + href: 'capsule-proxy.example.com' |
| 164 | + location: ApplicationMenu |
| 165 | + text: 'Capsule Proxy Kubernetes API' |
| 166 | +``` |
| 167 | +It's also possible to add links specific for certain namespaces, which are shown on the Namespace/Project overview. These can also be tenant specific by adding a NamespaceSelector: |
| 168 | +```yaml |
| 169 | +apiVersion: console.openshift.io/v1 |
| 170 | +kind: ConsoleLink |
| 171 | +metadata: |
| 172 | + name: namespaced-consolelink-sun |
| 173 | +spec: |
| 174 | + text: "Sun Docs" |
| 175 | + href: "https://linktothesundocs.com" |
| 176 | + location: "NamespaceDashboard" |
| 177 | + namespaceDashboard: |
| 178 | + namespaceSelector: |
| 179 | + matchExpressions: |
| 180 | + - key: capsule.clastix.io/tenant |
| 181 | + operator: In |
| 182 | + values: |
| 183 | + - sun |
| 184 | +``` |
| 185 | +Also a custom logo can be provided, for example by adding the Capsule logo. |
| 186 | + |
| 187 | +**Add** these config lines to the existing `cluster` CR `Console`. |
| 188 | +```shell |
| 189 | +kubectl create configmap console-capsule-logo --from-file capsule-logo.png -n openshift-config |
| 190 | +``` |
| 191 | +```yaml |
| 192 | +apiVersion: operator.openshift.io/v1 |
| 193 | +kind: Console |
| 194 | +metadata: |
| 195 | + name: cluster |
| 196 | +spec: |
| 197 | + customization: |
| 198 | + customLogoFile: |
| 199 | + key: capsule-logo.png |
| 200 | + name: console-capsule-logo |
| 201 | + customProductName: Capsule OpenShift Cluster |
| 202 | +``` |
| 203 | + |
| 204 | +# Conclusion |
| 205 | +After this section, you have a ready to go Capsule and Capsule-Proxy setup configured on OpenShift with some nice customizations in the OpenShift console. All ready to go and to ship to the development teams! |
0 commit comments