×

集群管理员可以使用Operator组允许普通用户安装Operator。

其他资源

理解Operator安装策略

Operator可能需要广泛的权限才能运行,并且所需权限可能会在不同版本之间发生变化。Operator生命周期管理器(OLM)以cluster-admin权限运行。默认情况下,Operator作者可以在集群服务版本(CSV)中指定任何权限集,OLM随后将其授予Operator。

为了确保Operator无法获得集群范围的权限,并且用户无法使用OLM升级权限,集群管理员可以在将Operator添加到集群之前手动审核Operator。集群管理员还可以使用工具来确定和限制在Operator安装或升级期间允许的操作,方法是使用服务帐户。

集群管理员可以将Operator组与具有授予其一组权限的服务帐户关联。服务帐户设置Operator策略,以确保它们仅在使用基于角色的访问控制(RBAC)规则预先确定的范围内运行。因此,Operator无法执行未被这些规则明确允许的操作。

通过使用Operator组,具有足够权限的用户可以安装具有有限范围的Operator。因此,可以安全地向更多用户提供更多Operator框架工具,从而为使用Operator构建应用程序提供更丰富的体验。

Subscription对象的基于角色的访问控制(RBAC)自动授予在命名空间中具有editadmin角色的每个用户。但是,OperatorGroup对象上不存在RBAC;这种缺失阻止了普通用户安装Operator。预安装Operator组实际上就是赋予安装权限。

将Operator组与服务帐户关联时,请记住以下几点:

  • APIServiceCustomResourceDefinition资源始终由OLM使用cluster-admin角色创建。与Operator组关联的服务帐户不应被授予写入这些资源的权限。

  • 任何与该Operator组绑定的Operator现在都仅限于授予指定服务帐户的权限。如果Operator请求超出服务帐户范围的权限,则安装将失败并显示相应的错误,以便集群管理员可以排查并解决问题。

安装场景

在确定是否可以在集群上安装或升级Operator时,Operator生命周期管理器(OLM)会考虑以下场景:

  • 集群管理员创建一个新的Operator组并指定一个服务帐户。与该Operator组关联的所有Operator都将针对授予服务帐户的权限进行安装和运行。

  • 集群管理员创建一个新的Operator组,但未指定任何服务帐户。OpenShift Container Platform保持向后兼容性,因此默认行为保持不变,允许Operator安装和升级。

  • 对于未指定服务帐户的现有Operator组,默认行为保持不变,允许Operator安装和升级。

  • 集群管理员更新现有Operator组并指定一个服务帐户。OLM允许现有Operator继续使用其当前权限运行。当此类现有Operator进行升级时,它将被重新安装并针对授予服务帐户的权限运行,就像任何新的Operator一样。

  • 通过添加或删除权限来更改Operator组指定的服务器帐户,或将现有服务帐户与新服务帐户交换。当现有Operator进行升级时,它将被重新安装并针对授予更新的服务帐户的权限运行,就像任何新的Operator一样。

  • 集群管理员从Operator组中删除服务帐户。默认行为保持不变,允许Operator安装和升级。

安装流程

当Operator组与服务帐户绑定并且安装或升级Operator时,Operator生命周期管理器(OLM)使用以下流程:

  1. OLM获取给定的Subscription对象。

  2. OLM获取与该订阅绑定的Operator组。

  3. OLM确定Operator组已指定服务帐户。

  4. OLM创建一个作用域为服务帐户的客户端,并使用该作用域客户端来安装Operator。这确保Operator请求的任何权限始终限于Operator组中服务帐户的权限。

  5. OLM创建一个具有CSV中指定的权限集的新服务帐户,并将其分配给Operator。Operator作为分配的服务帐户运行。

Operator安装范围

要为Operator生命周期管理器(OLM)上的Operator安装和升级提供范围规则,请将服务帐户与Operator组关联。

使用此示例,集群管理员可以将一组Operator限制到指定的命名空间。

先决条件
  • 您可以作为具有cluster-admin角色的用户访问集群。

  • 您已安装OpenShift CLI (oc)。

步骤
  1. 创建一个新的命名空间

    创建Namespace对象的示例命令
    $ cat <<EOF | oc create -f -
    apiVersion: v1
    kind: Namespace
    metadata:
      name: scoped
    EOF
  2. 分配您希望Operator受限于的权限。这涉及在新创建的指定命名空间中创建新的服务帐户、相关角色和角色绑定。

    1. 运行以下命令创建服务帐户:

      创建ServiceAccount对象的示例命令
      $ cat <<EOF | oc create -f -
      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: scoped
        namespace: scoped
      EOF
    2. 运行以下命令创建一个密钥:

      创建长期有效的API令牌Secret对象的示例命令
      $ cat <<EOF | oc create -f -
      apiVersion: v1
      kind: Secret
      type: kubernetes.io/service-account-token (1)
      metadata:
        name: scoped
        namespace: scoped
        annotations:
          kubernetes.io/service-account.name: scoped
      EOF
      1 密钥必须是长期有效的API令牌,服务帐户将使用它。
    3. 运行以下命令创建一个角色。

      在此示例中,该角色仅出于演示目的授予服务帐户在指定命名空间中执行任何操作的权限。在生产环境中,您应该创建更细粒度的权限集。有关更多信息,请参阅“细粒度权限”。

      创建RoleRoleBinding对象的示例命令
      $ 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
  3. 运行以下命令在指定的命名空间中创建OperatorGroup对象。此Operator组针对指定的命名空间,以确保其租户限制在该命名空间内。此外,Operator组允许用户指定服务帐户。

    创建OperatorGroup对象的示例命令
    $ cat <<EOF | oc create -f -
    apiVersion: operators.coreos.com/v1
    kind: OperatorGroup
    metadata:
      name: scoped
      namespace: scoped
    spec:
      serviceAccountName: scoped (1)
      targetNamespaces:
      - scoped
    EOF
    1 指定上一步中创建的服务帐户。在指定命名空间中安装的任何 Operator 都与该 Operator 组绑定,因此也与指定的服务帐户绑定。
  4. 在指定的命名空间中创建一个Subscription对象以安装 Operator

    创建Subscription对象的示例命令
    $ cat <<EOF | oc create -f -
    apiVersion: operators.coreos.com/v1alpha1
    kind: Subscription
    metadata:
      name: openshift-cert-manager-operator
      namespace: scoped
    spec:
      channel: stable-v1
      name: openshift-cert-manager-operator
      source: <catalog_source_name> (1)
      sourceNamespace: <catalog_source_namespace> (2)
    EOF
    1 指定在指定命名空间中已存在的目录源,或在全局目录命名空间中存在的目录源,例如redhat-operators
    2 指定创建目录源的命名空间,例如redhat-operators目录的openshift-marketplace

    与该 Operator 组绑定的任何 Operator 都仅限于授予指定服务帐户的权限。如果 Operator 请求的权限超出了服务帐户的范围,则安装将失败并显示相关错误。

细粒度权限

Operator Lifecycle Manager (OLM) 使用 Operator 组中指定的服务帐户来创建或更新与正在安装的 Operator 相关的以下资源:

  • ClusterServiceVersion

  • Subscription

  • Secret

  • ServiceAccount

  • Service

  • ClusterRoleClusterRoleBinding

  • RoleRoleBinding

为了将 Operator 限制在指定的命名空间中,集群管理员可以首先向服务帐户授予以下权限:

以下角色是一个通用示例,根据具体的 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 添加创建其他资源的权限,例如此处显示的部署和 Pod。

此外,如果任何 Operator 指定了拉取密钥,则还必须添加以下权限:

kind: ClusterRole (1)
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get"]
---
kind: Role
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["create", "update", "patch"]
1 需要从 OLM 命名空间获取密钥。

Operator 目录访问控制

当在全局目录命名空间openshift-marketplace中创建 Operator 目录时,目录的 Operator 将在集群范围内对所有命名空间可用。在其他命名空间中创建的目录仅在其相同的命名空间中提供其 Operator。

在非集群管理员用户已被委派 Operator 安装权限的集群中,集群管理员可能希望进一步控制或限制允许这些用户安装的 Operator 集。这可以通过以下操作实现:

  1. 禁用所有默认全局目录。

  2. 在已预安装相关 Operator 组的相同命名空间中启用自定义的精选目录。

排查权限故障

如果 Operator 安装由于权限不足而失败,请使用以下步骤识别错误。

步骤
  1. 查看Subscription对象。其状态具有一个对象引用installPlanRef,该引用指向尝试为 Operator 创建必要的[Cluster]Role[Binding]对象的InstallPlan对象。

    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
  2. 检查InstallPlan对象的任何错误状态。

    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

    错误消息会告诉您:

    • 它未能创建的资源类型,包括资源的 API 组。在本例中,它是rbac.authorization.k8s.io组中的clusterroles

    • 资源的名称。

    • 错误类型:is forbidden表示用户没有足够的权限执行此操作。

    • 尝试创建或更新资源的用户的名称。在本例中,它指的是 Operator 组中指定的服务帐户。

    • 操作的范围:是集群范围还是不是。

      用户可以向服务帐户添加缺少的权限,然后迭代。

      Operator Lifecycle Manager (OLM) 目前不会在第一次尝试时提供完整的错误列表。