配置 Kubernetes 对象

本主题演示了如何创建配置,Anthos Config Management 从 Git 读取文件并自动应用到集群。

准备工作

  • 确保您了解代码库的结构。一项配置在代码库中的位置会影响该配置所适用的集群和命名空间。这对于 namespaces/ 目录尤其重要,因为 namespaces/ 目录的子目录可以从其抽象命名空间目录中继承配置。

  • 您需要对 YAML 或 JSON 语法有基本的了解,因为配置会采用这两种格式中的其中一种编写。本文档中的所有示例均使用 YAML,因为这种格式更便于用户阅读。

  • 不同类型的 Kubernetes 对象具有不同的可配置选项。 在为这些类型的对象编写配置之前,了解如何手动实现所需的配置会很有帮助。

  • 我们创建了一个规范的示例代码库来说明 Anthos Config Management 的工作原理。本主题中的示例取自该代码库,因此您可能会发现在浏览器中打开代码库或将其克隆到本地系统会很有帮助。

创建配置

创建配置时,您需要确定其在代码库中的最佳位置以及要包含的字段。

配置在代码库中的位置

配置在代码库中的位置是决定它将应用于哪些集群的一个因素。

  • 集群级对象(命名空间除外)的配置存储在代码库的 cluster/ 目录中。
  • 命名空间和命名空间级对象的配置存储在代码库的 namespaces/ 目录中。
  • Anthos Config Management 组件的配置存储在代码库的 system/ 目录中。
  • Config Management Operator 的配置不会直接存储在代码库中,也不会进行同步。

配置的内容

配置使用的是附加方式,这与 kubectl 类似。 如果创建新对象,您需要包含所有必填字段。但是,如果更新现有对象,您只需提供需要更新的字段。

配置在应用后必须生成有效的 Kubernetes 对象。

配置现有 Kubernetes 对象

在安装 Anthos Config Management 之前,您可以为现有 Kubernetes 对象(例如集群中已存在的命名空间)创建配置。但是,除非对象具有 configmanagement.gke.io/managed: enabled 注释,否则此配置将被忽略。对于现有对象,您需要手动应用该注释。

需要特别注意的是,对于命名空间对象,Anthos Config Management 应用可在未加注释的命名空间中创建新对象的配置,并将 configmanagement.gke.io/managed: enabled 注释应用于这些对象。但是,Anthos Config Management 会拒绝修改或移除集群中任何未加注释的集群级对象。这种情况在处理一段时间内的配置更改部分的图表中进行了说明。

配置 CustomResourceDefinition

Anthos Config Management 可让您以同步任何其他资源的相同方式同步 CustomResourceDefinition (CRD)。在同步 CRD 时,有一些注意事项。

  • 即使在声明命名空间的自定义资源时,CRD 也必须放置在 cluster/ 目录中。

  • CRD 及其相应 CustomResource 不会按任何可预测的顺序进行更新。如果您在同一次提交中修改了 CRD 和相应的 CustomResource,则 CRD 更新不会早于自定义资源更新。这可能导致 syncer 日志在短时间内报告暂时性错误,直到集群中同时存在 CustomResource 和 CRD。

  • 如果代码库中的任何 CustomResource 依赖于 CRD,则 Anthos Config Management 不允许移除该 CRD。如需移除 CRD,您还需要移除其 CustomResource。建议您在向代码库执行的同一次提交中同时移除这两项。

  • 您可以同步 CustomResource 而不同步其 CRD,只要您能保证 CRD 已存在于集群中。

示例配置

以下示例配置均取自示例代码库,您应该可以借助这些示例开始编写自己的配置。此列表并不详尽;您可以使用 Anthos Config Management 配置任何类型的 Kubernetes 对象。

命名空间配置

此配置会创建一个名为 audit 的命名空间。

apiVersion: v1
kind: Namespace
metadata:
  name: audit

创建命名空间配置时,您还可以向命名空间添加标签或注释。使用 NamespaceSelector 时,需要使用标签。

以下示例配置会创建一个名为 shipping-prod 的命名空间(如果该命名空间尚不存在或未受管理)。该命名空间的标签为 env: prod,注释为 audit: true。如果有人手动修改该对象的任何元数据,Anthos Config Management 会快速将其重置为配置中的值。

apiVersion: v1
kind: Namespace
metadata:
  name: shipping-prod
  labels:
    env: prod
  annotations:
    audit: "true"

如需详细了解如何使用命名空间,请参阅配置命名空间和命名空间级对象

ClusterRole 配置

此配置会创建一个名为 namespace-reader 的 ClusterRole,该对象可以读取(获取、监视和列出)集群中的所有 namespace 对象。ClusterRole 配置通常与 ClusterRoleBinding 配置一起使用。

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: namespace-reader
rules:
- apiGroups: [""]
  resources: ["namespaces"]
  verbs: ["get", "watch", "list"]

ClusterRoleBinding 配置

此配置会创建一个名为 namespace-readers 的 ClusterRoleBinding,该对象可将 namespace-reader ClusterRole 授予用户 cheryl@foo-corp.com

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: namespace-readers
subjects:
- kind: User
  name: cheryl@foo-corp.com
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: namespace-reader
  apiGroup: rbac.authorization.k8s.io

ClusterRoleBinding 是集群级对象,不能放置在命名空间目录或抽象名称空间中。

PodSecurityPolicy 配置

此示例会创建一个名为 psp 的 PodSecurityPolicy,该对象会禁止运行特权容器,但允许容器以节点上的任何有效用户身份运行。

apiVersion: extensions/v1beta1
kind: PodSecurityPolicy
metadata:
  name: psp
spec:
  privileged: false
  seLinux:
    rule: RunAsAny
  supplementalGroups:
    rule: RunAsAny
  runAsUser:
    rule: RunAsAny
  fsGroup:
    rule: RunAsAny
  volumes:
  - '*'

PodSecurityPolicy 是集群级对象,不能放置在命名空间目录或抽象名称空间中。

NetworkPolicy 配置

本示例会创建一个名为 default-deny-all-traffic 的 NetworkPolicy。

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: default-deny-all-traffic
spec:
  podSelector: {}

NetworkPolicy 是命名空间级对象,只能放置在命名空间目录或抽象命名空间中。

当您将上述 NetworkPolicy 应用于单个命名空间时,它会将该命名空间中的所有 Pod 与入站和出站流量隔离。

如果您将同一个 NetworkPolicy 放置在具有后代命名空间的抽象命名空间中,以将该 NetworkPolicy 应用于多个命名空间,其中的每个命名空间都会继承该 NetworkPolicy。在示例代码库中shipping-app-backend 是一个抽象命名空间,其中包含 shipping-devshipping-prodshipping-stage 的配置。如果您将上面的示例 NetworkPolicy 添加到这些 Namespace 中,其中的每个 Namespace 都会继承该 NetworkPolicy,因此它们的每个 Pod 都会受到保护,不受入站和出站流量的影响。

您可以使用命名空间继承来强制实施最小权限安全保障措施。例如,如果将上一个示例 NetworkPolicy 应用于 shipping-app-backend,并将以下 NetworkPolicy 添加到 shipping-dev 命名空间,则入站流量只能流向该命名空间中带有 app:nginx 标签的 Pod。shipping-prodshipping-staging 命名空间不受此 NetworkPolicy 的影响。

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: allow-nginx-ingress
spec:
  podSelector:
    matchLabels:
      app: nginx
  ingress:
  - {}

ResourceQuota 配置

此示例会创建一个名为 quotaResourceQuota,该对象设置了硬性限制,即 1 个 Pod、100 milli-CPU 和 100 兆比字节 (Mi) 内存。

kind: ResourceQuota
apiVersion: v1
metadata:
  name: quota
spec:
  hard:
    pods: "1"
    cpu: "100m"
    memory: 100Mi

如果创建指定类型的新对象会违反现有的 ResourceQuota,Kubernetes 将无法创建该对象,直到执行此操作不再违反 ResourceQuota 为止。

后续步骤