$ cat <<EOF | oc create -f - apiVersion: v1 kind: Namespace metadata: name: scoped EOF
Operators can require wide privileges to run, and the required privileges can
change between versions. Operator Lifecycle Manager (OLM) runs with
cluster-admin
privileges. By default, Operator authors can specify any set of
permissions in the ClusterserviceVersion (CSV) and OLM will consequently grant
it to the Operator.
Cluster administrators should take measures to ensure that an Operator cannot achieve cluster-scoped privileges and that users cannot escalate privileges using OLM. One method for locking this down requires cluster administrators auditing Operators before they are added to the cluster. Cluster administrators are also provided tools for determining and constraining which actions are allowed during an Operator installation or upgrade using service accounts.
By associating an OperatorGroup with a service account that has a set of privileges granted to it, cluster administrators can set policy on Operators to ensure they operate only within predetermined boundaries using RBAC rules. The Operator is unable to do anything that is not explicitly permitted by those rules.
This self-sufficient, limited scope installation of Operators by non-cluster administrators means that more of the Operator Framework tools can safely be made available to more users, providing a richer experience for building applications with Operators.
Using OLM, cluster administrators can choose to specify a service account for an OperatorGroup so that all Operators associated with the OperatorGroup are deployed and run against the privileges granted to the service account.
APIservice
and CustomResourceDefinition
resources are always created by OLM
using the cluster-admin
role. A service account associated with an
OperatorGroup should never be granted privileges to write these resources.
If the specified service account does not have adequate permissions for an Operator that is being installed or upgraded, useful and contextual information is added to the status of the respective resource(s) so that it is easy for the cluster administrator to troubleshoot and resolve the issue.
Any Operator tied to this OperatorGroup is now confined to the permissions granted to the specified service account. If the Operator asks for permissions that are outside the scope of the service account, the install fails with appropriate errors.
When determining whether an Operator can be installed or upgraded on a cluster, OLM considers the following scenarios:
A cluster administrator creates a new OperatorGroup and specifies a service account. All Operator(s) associated with this OperatorGroup are installed and run against the privileges granted to the service account.
A cluster administrator creates a new OperatorGroup and does not specify any service account. OpenShift Container Platform maintains backward compatibility, so the default behavior remains and Operator installs and upgrades are permitted.
For existing OperatorGroups that do not specify a service account, the default behavior remains and Operator installs and upgrades are permitted.
A cluster administrator updates an existing OperatorGroup and specifies a service account. OLM allows the existing Operator to continue to run with their current privileges. When such an existing Operator is going through an upgrade, it is reinstalled and run against the privileges granted to the service account like any new Operator.
A service account specified by an OperatorGroup changes by adding or removing permissions, or the existing service account is swapped with a new one. When existing Operators go through an upgrade, it is reinstalled and run against the privileges granted to the updated service account like any new Operator.
A cluster administrator removes the service account from an OperatorGroup. The default behavior remains and Operator installs and upgrades are permitted.
When an OperatorGroup is tied to a service account and an Operator is installed or upgraded, OLM uses the following workflow:
The given Subscription object is picked up by OLM.
OLM fetches the OperatorGroup tied to this Subscription.
OLM determines that the OperatorGroup has a service account specified.
OLM creates a client scoped to the service account and uses the scoped client to install the Operator. This ensures that any permission requested by the Operator is always confined to that of the service account in the OperatorGroup.
OLM creates a new service account with the set of permissions specified in the CSV and assigns it to the Operator. The Operator runs as the assigned service account.
To provide scoping rules to Operator installations and upgrades on OLM, associate a service account with an OperatorGroup.
Using this example, a cluster administrator can confine a set of Operators to a designated namespace.
Create a new namespace:
$ cat <<EOF | oc create -f - apiVersion: v1 kind: Namespace metadata: name: scoped EOF
Allocate permissions that you want the Operator(s) to be confined to. This involves creating a new service account, relevant Role(s), and RoleBinding(s).
$ cat <<EOF | oc create -f - apiVersion: v1 kind: serviceAccount metadata: name: scoped namespace: scoped EOF
The following example grants the service account permissions to do anything in the designated namespace for simplicity. In a production environment, you should create a more fine-grained set of permissions:
$ cat <<EOF | oc create -f - apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: scoped namespace: scoped rules: - apiGroups: ["*"] resources: ["*"] verbs: ["*"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: scoped-bindings namespace: scoped roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: scoped subjects: - kind: serviceAccount name: scoped namespace: scoped EOF
Create an OperatorGroup in the designated namespace. This OperatorGroup targets the designated namespace to ensure that its tenancy is confined to it. In addition, OperatorGroups allow a user to specify a service account. Specify the serviceAccount created in the previous step:
$ cat <<EOF | oc create -f - apiVersion: operators.coreos.com/v1 kind: OperatorGroup metadata: name: scoped namespace: scoped spec: serviceAccountName: scoped targetNamespaces: - scoped EOF
Any Operator installed in the designated namespace is tied to this OperatorGroup and therefore to the service account specified.
Create a Subscription in the designated namespace to install an Operator:
$ cat <<EOF | oc create -f - apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: etcd namespace: scoped spec: channel: singlenamespace-alpha name: etcd source: <catalog_source_name> (1) sourceNamespace: <catalog_source_namespace> (2) EOF
1 | Specify a CatalogSource that already exists in the designated namespace or one that is in the global catalog namespace. |
2 | Specify a CatalogSourceNamespace where the CatalogSource was created. |
Any Operator tied to this OperatorGroup is confined to the permissions granted to the specified service account. If the Operator requests permissions that are outside the scope of the service account, the installation fails with appropriate errors.
OLM uses the service account specified in OperatorGroup to create or update the following resources related to the Operator being installed:
ClusterserviceVersion
Subscription
Secret
serviceAccount
service
ClusterRole and ClusterRoleBinding
Role and RoleBinding
In order to confine Operators to a designated namespace, cluster administrators can start by granting the following permissions to the service account:
The following role is a generic example and additional rules might be required based on the specific Operator. |
kind: Role
rules:
- apiGroups: ["operators.coreos.com"]
resources: ["subscriptions", "clusterserviceversions"]
verbs: ["get", "create", "update", "patch"]
- apiGroups: [""]
resources: ["services", "serviceaccounts"]
verbs: ["get", "create", "update", "patch"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["roles", "rolebindings"]
verbs: ["get", "create", "update", "patch"]
- apiGroups: ["apps"] (1)
resources: ["deployments"]
verbs: ["list", "watch", "get", "create", "update", "patch", "delete"]
- apiGroups: [""] (1)
resources: ["pods"]
verbs: ["list", "watch", "get", "create", "update", "patch", "delete"]
1 | Add permissions to create other resources, such as Deployments and Pods shown here. |
In addition, if any Operator specifies a pull secret, the following permissions must also be added:
kind: ClusterRole (1)
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get"]
---
kind: Role
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["create", "update", "patch"]
1 | Required to get the secret from the OLM namespace. |
If an Operator installation fails due to lack of permissions, identify the errors using the following procedure.
Review the Subscription object. Its status has an object reference
installPlanRef
that points to the InstallPlan object that attempted to create
the necessary [Cluster]Role[Binding](s) for the Operator:
apiVersion: operators.coreos.com/v1
kind: Subscription
metadata:
name: etcd
namespace: scoped
status:
installPlanRef:
apiVersion: operators.coreos.com/v1
kind: InstallPlan
name: install-4plp8
namespace: scoped
resourceVersion: "117359"
uid: 2c1df80e-afea-11e9-bce3-5254009c9c23
Check the status of the InstallPlan object for any errors:
apiVersion: operators.coreos.com/v1
kind: InstallPlan
status:
conditions:
- lastTransitionTime: "2019-07-26T21:13:10Z"
lastUpdateTime: "2019-07-26T21:13:10Z"
message: 'error creating clusterrole etcdoperator.v0.9.4-clusterwide-dsfx4: clusterroles.rbac.authorization.k8s.io
is forbidden: User "system:serviceaccount:scoped:scoped" cannot create resource
"clusterroles" in API group "rbac.authorization.k8s.io" at the cluster scope'
reason: InstallComponentFailed
status: "False"
type: Installed
phase: Failed
The error message tells you:
The type of resource it failed to create, including the API group of the
resource. In this case, it was clusterroles
in the rbac.authorization.k8s.io
group.
The name of the resource.
The type of error: is forbidden
tells you that the user does not have enough
permission to do the operation.
The name of the user who attempted to create or update the resource. In this case, it refers to the service account specified in the OperatorGroup.
The scope of the operation: cluster scope
or not.
The user can add the missing permission to the service account and then iterate.
OLM does not currently provide the complete list of errors on the first try, but may be added in a future release. |