命名空间继承和抽象命名空间
本页面介绍如何在 Config Sync 分层代码库中利用命名空间继承的概念。
根据代码库的结构,Config Sync 会自动将配置应用于所有存在(或应该存在)命名空间的集群中的命名空间组。这些命名空间称为抽象命名空间。
非结构化代码库不支持命名空间继承和抽象命名空间。如果您使用的是非结构化代码库并希望实现类似功能,请使用层次结构控制器。
命名空间继承功能的工作原理
命名空间继承适用于分层代码库及其所有子目录的 namespaces/
目录。代码库中其他目录(例如 cluster/
)下的配置不受继承功能的约束。
在分层代码库中,namespaces/
目录可以包含两种不同类型的子目录:
命名空间目录包含命名空间的配置。包含该配置的文件名称并不重要,但是这项配置必须具有
kind: Namespace
。命名空间目录还可以包含其他类型的 Kubernetes 对象的配置。命名空间目录不能包含子目录。命名空间配置表示集群中的实际命名空间。抽象命名空间目录包含命名空间目录,还可以包含其他 Kubernetes 对象的配置,但不能直接包含命名空间的配置。抽象命名空间目录不代表 Kubernetes 集群中的对象,但其后代命名空间目录可以。
为了帮助确保您的命名空间和抽象命名空间代码库具有正确的配置和结构类型,请在出现问题时报告错误 KNV1003: IllegalNamespaceSubdirectoryError。
命名空间目录中的配置仅应用于该命名空间。但是,抽象命名空间目录中的配置将应用于该抽象命名空间的所有后代命名空间目录(或者与配置的 NamespaceSelector(如果存在)匹配的后代命名空间)。
命名空间继承示例
配置中 namespaces/
的继承在很大程度上取决于该配置在代码库中的目录树中的位置。如需了解哪些配置应用于给定集群中的给定命名空间,您可以浏览命名空间继承示例代码库。
命名空间继承示例代码库中的 namespaces/
目录具有以下架构:
├── namespaces # Abstract namespace directory
│ ├── eng # Abstract namespace directory
│ │ ├── analytics # Namespace directory
│ │ └── gamestore # Namespace directory
│ ├── rnd # Abstract namespace directory
│ │ ├── incubator-1 # Namespace directory
│ │ └── incubator-2 # Namespace directory
| |── network-policy-default-deny-all.yaml
| |── viewers-rolebinding.yaml
如需详细了解此示例代码库的工作原理,请先探索 viewers-rolebinding.yaml
:
由于此 RoleBinding 位于 namespaces/
目录的根目录中,因此它会向 system:serviceaccounts:foo
群组中的所有人授予 Config Sync 管理的每个命名空间中的 view
ClusterRole。
接下来,通过浏览器中打开 namespaces/eng/
目录。eng
目录是一个抽象命名空间目录,因为其中不包含命名空间的配置。eng
目录包含以下配置:
eng-role.yaml
eng-rolebinding.yaml
network-policy-allow-gamestore-ingress.yaml
quota.yaml
selectors.yaml
eng
目录也有两个子目录:analytics
和 gamestore
。这些子目录是命名空间目录,因为它们分别包含命名空间的配置。在此示例中,命名空间配置称为 namespace.yaml
,但您可以随意调用它们。analytics
和 gamestore
中的每个命名空间都会继承 eng
抽象命名空间目录中的 eng-role.yaml
、eng-rolebinding.yaml
和 network-policy-allow-gamestore-ingress.yaml
配置。
在 quota.yaml
中定义的 ResourceQuota 对象使用 NamespaceSelector,因此此 ResourceQuota 对象仅在 analytics
和 gamestore
命名空间中创建。
gamestore
命名空间目录包含适用于 bob-rolebinding
RoleBinding 的其他配置,但 analytics
命名空间目录不含此配置,因此 analytics
命名空间不包含该 RoleBinding(除非有人手动创建此绑定)。
命名空间继承代码库还具有 README.md
文件,其中进一步提供了命名空间继承的工作原理示例。
受限命名空间
config-management-system
是受限命名空间。您不能将其用作抽象命名空间目录。从 1.11.0 版及更高版本开始,您可以定义 config-management-system
命名空间。但是,config-management-system
命名空间唯一允许的资源类型是 RootSync
。
从继承中排除命名空间
您可以使用命名空间选择器豁免特定命名空间从树中继承资源。
以下示例允许根 /namespaces
目录中正确注释的 ResourceQuota
对象可被每个命名空间继承,标记为 quota-exempt: exempt
的除外:
kind: NamespaceSelector
apiVersion: configmanagement.gke.io/v1
metadata:
name: excludes-exempt-namespaces
spec:
selector:
matchExpressions:
- key: quota-exempt
operator: NotIn
values:
- exempt
如需详细了解 Config Sync 中的 NamespaceSelectors
,请参阅限制配置影响的命名空间。
Git 操作对命名空间的影响
在 namespaces/
目录中创建或删除命名空间目录的 Git 操作可能会产生与您最初的预期不同的效果。以下几个部分介绍了这些互动情况。
在 namespaces/
中创建目录
当您将有效的 namespaces/
层次结构提交到存储库时,Config Sync 会创建命名空间,然后在这些命名空间中为命名空间目录包含或继承的每项配置创建 Kubernetes 对象。
从 namespaces/
中删除目录
删除命名空间目录是一种破坏性操作。此操作将从由 Config Sync 管理并包含相关命名空间的所有集群中删除该命名空间及其全部内容。
如果您删除包含后代命名空间目录的抽象命名空间目录,则所有这些命名空间及其内容都将从 Config Sync 管理的所有集群中删除。
重命名 namespaces/
中的目录
重命名命名空间目录是在创建操作之后执行的删除操作,因此也是一种破坏性操作。
重命名抽象命名空间目录不会产生任何外部可见的影响。
移动 namespaces/
中的目录
在 namespaces/
中移动命名空间或抽象命名空间目录不会删除命名空间或其中的对象,除非命名空间由于其层次结构发生更改而开始或停止从抽象命名空间目录继承配置。
与层次结构控制器集成
层次结构控制器使您可以使用分层命名空间,这与抽象命名空间类似。层次结构控制器还支持额外的功能,例如分层资源配额和自助命名空间。
选择相关命名空间
有时,您可能希望将政策应用于通过共同祖先实体关联的命名空间集。层次结构控制器通过使用树标签的概念来支持此功能。即使未启用层次结构控制器,抽象命名空间也支持树标签。
树标签是具有以下格式的 Kubernetes 标签:
NAMESPACE_NAME.tree.hnc.x-k8s.io/depth: DEPTH
这些标签允许您编写命名空间选择器(例如,可以用作网络政策的一部分),以允许相关命名空间的子树内的流量,但禁止该子树外部的流量。
我们可通过返回示例代码库来说明此概念。
├── namespaces # Abstract namespace directory
│ ├── eng # Abstract namespace directory
│ │ ├── analytics # Namespace directory
│ │ └── gamestore # Namespace directory
│ ├── rnd # Abstract namespace directory
│ │ ├── incubator-1 # Namespace directory
│ │ └── incubator-2 # Namespace directory
| |── network-policy-default-deny-all.yaml
| |── viewers-rolebinding.yaml
假设在本例中,gamestore
抽象命名空间目录中的 namespace.yaml
具有以下树标签:
eng.tree.hnc.x-k8s.io/depth: "1"
gamestore.tree.hnc.x-k8s.io/depth: "0"
您可以使用 kubectl
命令直接在集群上检查这些关系,而无需访问 Git 代码库:
# View all descendants of 'eng'
kubectl get namespaces -l 'eng.tree.hnc.x-k8s.io/depth'
# View any immediate children of 'eng'
kubectl get namespaces -l 'eng.tree.hnc.x-k8s.io/depth=1'
层次结构控制器还会将任何树标签从抽象命名空间传播到任何后代命名空间。例如,如果您按如下方式创建 gamestore
的子命名空间:
kubectl hns create gamestore-v1 -n gamestore
在这种情况下,gamestore-v1
命名空间将包含其父级的所有标签以及其自身的标签,并适当调整深度:
eng.tree.hnc.x-k8s.io/depth: 2
gamestore-v1.tree.hnc.x-k8s.io/depth: 0
gamestore.tree.hnc.x-k8s.io/depth: 1