配置命名空间和命名空间级对象

本主题说明了如何使用 Config Sync 来管理命名空间和命名空间级对象。

配置命名空间

对于非结构化代码库和分层代码库,配置命名空间的方式有所不同。以下示例重点介绍了这些差异。

非结构化代码库

命名空间和命名空间级对象的配置可以位于代码库的目录或子目录中的任何位置。

完成以下步骤,以在每个已注册的集群中配置名为 gamestore 的命名空间:

  1. 创建一个包含以下内容的 namespace-gamestore.yaml 文件。

    apiVersion: v1
    kind: Namespace
    metadata:
      name: gamestore
    

    您只需要创建一个包含命名空间配置的 YAML 文件。

  2. 创建包含 namespace-gamestore.yaml 配置的提交,并将该提交推送到远程存储库:

    git add multirepo/root/namespace-gamestore.yaml
    git commit -m "Created gamestore namespace config"
    git push REMOTE_NAME BRANCH_NAME
    

    替换以下内容:

    • REMOTE_NAME:远程代码库的名称。
    • BRANCH_NAME:您要提交到的分支。

    此示例将文件添加到根目录,但您可以将此文件移动到代码库的任何子目录。

分层代码库

命名空间和命名空间级对象的所有配置都位于分层代码库namespaces/ 目录及其后代目录中。

请按照以下步骤在每个已注册的集群中配置名为 gamestore 的命名空间:

  1. 在代码库的本地克隆中,创建一个命名空间目录。命名空间目录包含命名空间的配置。命名空间目录的名称必须与命名空间的名称一致。在此示例中,命名空间目录名为 namespaces/gamestore

    mkdir namespaces/gamestore
    
  2. 在命名空间目录中,创建一个包含以下内容的 gamestore.yaml 文件:

    apiVersion: v1
    kind: Namespace
    metadata:
      name: gamestore
    

    metadata.name 必须与命名空间目录的名称相匹配。

  3. 创建包含 gamestore.yaml 配置的提交,并将该提交推送到远程存储库:

    git add namespaces/gamestore/gamestore.yaml
    git commit -m "Created gamestore namespace config"
    git push REMOTE_NAME BRANCH_NAME
    

    替换以下内容:

    • REMOTE_NAME:远程代码库的名称。
    • BRANCH_NAME:您要提交到的分支。

稍等片刻之后,系统就会在每个已注册的集群中创建 gamestore 命名空间。如需进行验证,请描述该命名空间:

kubectl describe namespace gamestore

如需移除配置并从已注册的集群中删除 gamestore 命名空间,请创建一项新的提交以移除相应文件,然后将该提交推送到远程代码库。如果要为分层代码库配置抽象命名空间,请不要移除配置。

配置抽象命名空间

本部分仅适用于分层代码库非结构化代码库中不支持抽象命名空间。如果您使用的是非结构化代码库,并且需要类似功能,请使用分层命名空间

此示例在配置命名空间中的示例基础上进行了延伸,将 gamestore 命名空间目录移动到包含 gamestore 命名空间所继承的其他配置的抽象命名空间。

  1. 在存储库的本地克隆中,创建一个名为 eng 的抽象命名空间目录:

    mkdir namespaces/eng
    

    抽象命名空间目录不包含命名空间的配置,但其后代命名空间目录包含该配置。

  2. eng 抽象命名空间目录中,为名为 eng-viewer 的 Role 创建配置,以针对最终继承该 Role 的任何命名空间中的所有资源授予 getlist 权限:

    # namespaces/eng/eng-role.yaml
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: eng-viewer
    rules:
    - apiGroups: [""]
      resources: ["*"]
      verbs: ["get", "list"]
    
  3. 为名为 eng-admin 的 RoleBinding 创建配置,以将 eng-viewer 角色绑定到 eng@example.com 群组:

    # namespaces/eng/eng-rolebinding.yaml
    kind: RoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: eng-admin
    subjects:
    - kind: Group
      name: eng@example.com
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: Role
      name: eng-viewer
      apiGroup: rbac.authorization.k8s.io
    
  4. gamestore 命名空间目录从 namespaces/ 移动到 namespaces/eng/ 目录:

    mv namespaces/gamestore/namespaces/eng/
    
  5. 提交所有更改并将其推送到远程存储库。

Config Management Operator 会注意到这些更改,并将新的 Role 和 RoleBinding 应用于所有已注册集群上的 gamestore 命名空间。

如需移除这些配置并从已注册的集群中删除 gamestore 命名空间,您可以创建一个新提交实例来移除整个 eng 抽象命名空间,并将该实例推送到远程存储库。

限制受配置影响的集群

通常,Config Sync 会将配置应用到每个已注册的集群。如果配置位于分层代码库namespaces/ 子目录中,则 Config Sync 会先在每个集群中创建命名空间,然后再将所有继承的配置应用到该命名空间。如需根据每个集群的标签来限制特定配置影响的集群,请使用 ClusterSelector。如需了解详情,请参阅配置集群的子集

限制受配置影响的命名空间

如需限制配置影响的命名空间,请使用 NamespaceSelector。NamespaceSelector 是一种使用 Kubernetes labelSelector 的特殊类型配置。您可以将 NamespaceSelector 与非结构化代码库分层代码库中命名空间级对象的配置一起声明,以限制哪些命名空间可以继承该配置。注意:NamespaceSelector 与 ClusterSelector 相似,但不完全相同。NamespaceSelector 缩小配置所适用的命名空间池。

要声明 NamespaceSelector,请添加 metadata.namespaceNamespaceSelector 注释。如果同时声明这两个注释,则这样的声明是无效的。如果命名空间级资源未声明 metadata.namespaceNamespaceSelector 注释,则 Config Sync 使用集群的“默认”命名空间。

非结构化代码库中的 NamespaceSelector

非结构化代码库不必为代码库中的命名空间级对象声明所有命名空间。对象可以定义 metadata.namespace,但非结构化代码库中没有匹配的命名空间对象。如果集群上已存在命名空间,Config Sync 会在该命名空间内创建对象。如果集群上不存在该命名空间,Config Sync 会隐式地创建命名空间。

在非结构化代码库中,声明 NamespaceSelector 注解的对象会应用于满足 NamespaceSelector 条件的所有命名空间。在创建包含以前在分层代码库中使用的对象的非结构化代码库之前,请验证 NamespaceSelectors 是否不适用于其他资源。

当您从非结构化代码库中移除命名空间级对象时,Config Sync 会删除这些对象,但不会移除可能已为这些对象隐式创建的任何命名空间。之所以发生行为,是因为 Config Sync 无法推断出何时才能安全地删除隐式创建的命名空间,因此此命名空间会始终保留在集群上。

分层代码库中的 NamespaceSelector

在分层代码库中,无论 namespaces/ 目录的结构如何,声明 NamespaceSelector 注解的对象都会应用于从抽象命名空间继承指定配置的命名空间。无论一项配置是针对集群级对象还是命名空间级对象,ClusterSelector 都会将该配置所适用的集群池缩小到一定的范围。

NamespaceSelector 位置

在非结构化代码库中,您可以将 NamespaceSelector 置于任何目录或子目录中。

在分层代码库中,您可以将 NamespaceSelector 置于任何抽象命名空间目录中,但不能放置在命名空间目录中。

以下示例代码库架构显示了使用分层代码库时 NamespaceSelector 的有效位置和无效位置:

namespace-inheritance
...
├── namespaces
│   ├── eng
│   │   ├── gamestore
│   │   │   ├── namespace.yaml
│   │   │   └── ns_selector.yaml  # invalid
│   │   └── ns_selector.yaml  # valid
│   ├── ns_selector.yaml  # valid
│   ├── rnd
│   │   ├── incubator-1
│   │   │   ├── namespace.yaml
│   │   │   └── ns_selector.yaml  # invalid
│   │   └── ns_selector.yaml  # valid

由于 namespacesengrnd 目录表示抽象命名空间,因此您可以在这些目录中添加选择器。但是,由于 gamestoreincubator-1 目录表示实际命名空间,因此您无法在这些命名空间中放置 NamespaceSelector。

NamespaceSelector 示例

以下配置会创建一个名为 gamestore-selector 的 NamespaceSelector。如果您在另一项配置中引用了此 NamespaceSelector,那么该配置只能应用于具有 app: gamestore 标签的命名空间中的对象。

kind: NamespaceSelector
apiVersion: configmanagement.gke.io/v1
metadata:
  name: gamestore-selector
spec:
  selector:
    matchLabels:
      app: gamestore

如需在配置中引用 NamespaceSelector,请将 configmanagement.gke.io/namespace-selector 注释设置为 NamespaceSelector 的名称。

当您在另一个配置中引用 NamespaceSelector 之后,该 NamespaceSelector 才会生效。 如果 gamestore-selector NamespaceSelector 位于与以下 ResourceQuota quota 相同的层次结构中,那么系统将仅在具有 app: gamestore 标签的命名空间中创建 ResourceQuota:

kind: ResourceQuota
apiVersion: v1
metadata:
  name: quota
  annotations:
    configmanagement.gke.io/namespace-selector: gamestore-selector
spec:
  hard:
    pods: "1"
    cpu: "200m"
    memory: "200Mi"

总而言之,使用 NamespaceSelector 的过程分为三个步骤:

  1. 向命名空间添加标签。
  2. 创建 NamespaceSelector 配置。
  3. 在另一个配置中引用 NamespaceSelector 对象。

禁止继承某个对象类型

非结构化代码库不支持 HierarchyConfig Kubernetes 对象。 以下示例仅适用于分层代码库

您可以有选择地针对任何配置停用继承功能,只需将 hierarchyMode 字段设置为 none 即可。HierarchyConfig 存储在存储库的 system/ 目录中。以下示例会禁止继承 RoleBinding。

# system/hierarchy-config.yaml
kind: HierarchyConfig
apiVersion: configmanagement.gke.io/v1
metadata:
  name: rbac
spec:
  resources:
  # Configure Role to only be allowed in leaf namespaces.
  - group: rbac.authorization.k8s.io
    kinds: [ "RoleBinding" ]
    hierarchyMode: none

后续步骤