美文网首页Kyverno
Kyverno生成资源

Kyverno生成资源

作者: 王勇1024 | 来源:发表于2022-09-27 11:11 被阅读0次

    生成资源

    根据资源创建或更新创建其他资源。

    generate 规则可用于在创建新资源或更新源时创建其他资源。这对于创建支持资源很有用,例如命名空间的新 RoleBindings 或 NetworkPolicies。

    generate 规则像其它规则一样,支持 matchexclude 块。因此,可以在创建任何资源时触发该规则。还可以根据subjects、roles等匹配或排除 API 请求。

    在执行 API CREATE 操作时触发 generate 规则。您可以使用 synchronize 属性,在更改时保持资源同步。当 synchronize 被设为 true 时,衍生资源会和源资源(可以定义为策略的一部分,也可以是现有资源)保持同步,并且衍生资源不能被用户修改。如果 synchronize 被设为 false,用户可以直接修改或删除衍生资源。

    注意:在 Kyverno 1.3.0 中,synchronize=true 的衍生资源可能会被其它 Kubernetes 控制器及有相应访问权限的用户修改或删除,Kyverno 将重新创建或更新资源以符合配置的策略。

    当使用 generate 规则时,源资源既可以是由 Kubernetes 定义的、已存在的资源,也可以是由规则定义的新资源。如果源资源是已存在的资源,如 ConfigMap 或 Secret,将使用 clone 对象。如果源资源是规则中定义的新资源,将使用 data 对象。这些是相互排斥的,并且只能在规则中指定一个。

    警告:删除包含有使用 data 对象的 generate 规则,且 synchronize=true 的策略时,将导致立即删除下游的衍生资源。包含 clone 对象的策略不受此行为的影响。

    在 CustomResourceDefinitions (CRD) 中定义的 CustomResources 之前,Kubernetes 就有许多默认资源类型。Kyverno 也可以像生成 Kubernetes 默认资源一样,生成 CustomResources,但都需要给 generate 行为所依赖的 ClusterRole 授予额外的权限。要想允许 Kyverno 生成这些类型,需要修改名为 kyverno:generate 的 ClusterRole,并为其添加或更新规则以涵盖所需的资源和动词。

    注意:生成自定义资源时,需要设置 apiVersion(例如 spec.generate.apiVersion 和 kind(例如 spec.generate.kind)。

    Kyverno 将创建一个名为 UpdateRequest 的中间对象,用于将工作项排队以生成最终资源。要获取生成资源的详细信息和状态,请检查 UpdateRequest 的详细信息。下面将给出 UpdateRequest 的列表。

    kubectl get updaterequests -A
    

    UpdateRequest 状态可以具有以下四个值之一:

    • Completed:UpdateRequest 控制器完成策略中定义的资源的创建。
    • Failed:UpdateRequest 控制器处理规则失败。
    • Pending:请求尚未处理或资源尚未创建。
    • Skip:通过向现有资源添加标签/注释来触发 generate 策略,而策略中未定义选择器。

    使用内联数据生成 ConfigMap

    此策略基于在规则中定义的 ConfigMap 为所有命名空间设置 Zookeeper 和 Kafka 连接字符串。请注意,此规则定义了 generate.data 对象,在这种情况下,该规则将使用规则清单中指定的数据创建一个名为 zk-kafka-address 的新 ConfigMap。

    apiVersion: kyverno.io/v1
    kind: ClusterPolicy
    metadata:
      name: zk-kafka-address
    spec:
      rules:
      - name: k-kafka-address
        match:
          any:
          - resources:
              kinds:
              - Namespace
        exclude:
          any:
          - resources:
              namespaces:
              - kube-system
              - default
              - kube-public
              - kyverno
        generate:
          synchronize: true
          apiVersion: v1
          kind: ConfigMap
          name: zk-kafka-address
          # 创建 namespace 时生成如下资源
          namespace: "{{request.object.metadata.name}}"
          data:
            kind: ConfigMap
            metadata:
              labels:
                somekey: somevalue
            data:
              ZK_ADDRESS: "192.168.10.10:2181,192.168.10.11:2181,192.168.10.12:2181"
              KAFKA_ADDRESS: "192.168.10.13:9092,192.168.10.14:9092,192.168.10.15:9092"
    

    克隆 ConfigMap 并传播更改

    此策略中,源数据是一个已存在于 default 命名空间中名为 config-template 的 ConfigMap。请注意,当原始数据存在于 Kubernetes 中时,此处的 generate 规则将使用 generate.clone 对象。

    apiVersion: kyverno.io/v1
    kind: ClusterPolicy
    metadata:
      name: basic-policy
    spec:
      rules:
      - name: Clone ConfigMap
        match:
          any:
          - resources:
              kinds:
              - Namespace
        exclude:
          any:
          - resources:
              namespaces:
              - kube-system
              - default
              - kube-public
              - kyverno
        generate:
          # Kind of generated resource
          kind: ConfigMap
          # apiVersion of the generated resource
          apiVersion: v1
          # Name of the generated resource
          name: default-config
          # namespace for the generated resource
          namespace: "{{request.object.metadata.name}}"
          # propagate changes from the upstream resource
          synchronize : true
          clone:
            namespace: default
            name: config-template
    

    生成 Bindings

    为了让 Kyverno 生成新的 RoleBinding 或 ClusterRoleBinding 资源,它的 ServiceAccount 必须首先绑定到您尝试生成的、相同 Role 或 ClusterRole。如果不这样做,Kubernetes 会阻止请求,因为它看到来自 Kyverno ServiceAccount 可能在尝试提升权限。这不是 Kyverno 的功能,而是 Kubernetes RBAC 的工作方式。

    例如,如果你想要编写一个 generate 规则,该规则会创建一个新的 RoleBinding 资源,并授予某些用户在新命名空间上的 admin 角色,Kyverno ServiceAccount 必须通过 ClusterRoleBinding 与同样的 admin 角色绑定。

    为 Kyverno 的 ServiceAccount(默认名为 kyverno )创建一个新的 ClusterRoleBinding。

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: kyverno:generate-admin
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: admin
    subjects:
    - kind: ServiceAccount
      name: kyverno
      namespace: kyverno
    

    现在,像往常一样,创建一个 generate 规则,将名为 steven 的测试用户与新命名空间的 admin ClusterRole 相绑定。此规则中名为 admin 的内置 ClusterRole 必须与之前 ClusterRoleBinding 中授予 Kyverno ServiceAccount 的 ClusterRole 匹配。

    apiVersion: kyverno.io/v1
    kind: ClusterPolicy
    metadata:
      name: steven-rolebinding
    spec:
      rules:
      - name: steven-rolebinding
        match:
          any:
          - resources:
              kinds:
              - Namespace
        generate:
          kind: RoleBinding
          apiVersion: rbac.authorization.k8s.io/v1
          name: steven-rolebinding
          namespace: "{{request.object.metadata.name}}"
          data:  
            subjects:
            - kind: User
              name: steven
              apiGroup: rbac.authorization.k8s.io
            roleRef:
              kind: ClusterRole
              name: admin
              apiGroup: rbac.authorization.k8s.io
    

    新创建命名空间时,Kyverno 会生成一个名为 steven-rolebinding 的 RoleBinding,并授予用户 steven 上述新命名空间的 admin ClusterRole。

    生成 NetworkPolicy

    在此示例中,新命名空间将接收到一个拒绝所有入站和出站流量的 NetworkPolicy。与第一个示例类似,generate.data 对象用于将 NetworkPolicy 资源的规范定义为覆盖模式。

    apiVersion: kyverno.io/v1
    kind: ClusterPolicy
    metadata:
      name: default
    spec:
      rules:
      - name: deny-all-traffic
        match:
          any:
          - resources:
              kinds:
              - Namespace
        exclude:
          any:
          - resources:
              namespaces:
              - kube-system
              - default
              - kube-public
              - kyverno
        generate:
          kind: NetworkPolicy
          apiVersion: networking.k8s.io/v1
          name: deny-all-traffic
          namespace: "{{request.object.metadata.name}}"
          data:  
            spec:
              # select all pods in the namespace
              podSelector: {}
              policyTypes:
              - Ingress
              - Egress
    

    将资源与 ownerReferences 连接

    在某些情况下,触发(源)资源和衍生(下游)资源需要共享相同的生命周期。也就是说,当触发资源被删除时,衍生资源也应该被删除。这样做是有价值的,因为某些资源只有在另一个资源存在时才需要,例如 LoadBalancer 类型的服务需要在某些 CNI 插件中使用特定的网络策略。虽然 Kyverno 不会在内部处理此任务,但 Kubernetes 可以通过在衍生资源中设置 ownerReferences 字段。对于下面的示例,当衍生的 ConfigMap 指定了 metadata.ownerReferences[] 对象,并定义了如下字段,包括引用触发的 Service 资源的 uid 时,就形成了所有者依赖关系。稍后,如果 Service 被删除,ConfigMap 也会被删除。有关更多详细信息,请参阅 Kubernetes 文档,包括有关这些参考范围的重要警告。命名空间级别资源不能是集群级别资源的所有者,也不允许跨命名空间引用。

    apiVersion: kyverno.io/v1
    kind: ClusterPolicy
    metadata:
      name: demo-ownerref
    spec:
      background: false
      rules:
      - name: demo-ownerref-svc-cm
        match:
          any:
          - resources:
              kinds:
              - Service
        generate:
          kind: ConfigMap
          apiVersion: v1
          name: "{{request.object.metadata.name}}-gen-cm"
          namespace: "{{request.namespace}}"
          synchronize: false
          data:
            metadata:
              ownerReferences:
              - apiVersion: v1
                kind: Service
                name: "{{request.object.metadata.name}}"
                uid: "{{request.object.metadata.uid}}"
            data:
              foo: bar
    

    为现有资源生成衍生资源

    在 Kyverno 1.7.0+ 中,Kyverno 支持为现有资源生成衍生资源。为现有资源生成衍生资源的策略在后台应用,根据策略中的匹配语句创建目标资源。它们也可以选择配置为在更新策略本身时应用。

    在现有命名空间中生成 NetworkPolicy

    默认情况下,安装时不会将策略应用于现有触发器资源。可以通过 generateExistingOnPolicyUpdate 属性配置该行为。只有 generateExistingOnPolicyUpdate 设置为 true 时,Kyverno 会在收到策略的 CREATEUPDATE 事件时,为现有的触发器生成目标衍生资源。

    在这个示例中,触发器资源是 Namespace 类型,将会为所有新建或已存在的 Namespace 生成一个新的 NetworkPolicy。

    apiVersion: kyverno.io/v1
    kind: ClusterPolicy
    metadata:
      name: generate-resources
    spec:
      generateExistingOnPolicyUpdate: true
      rules:
      - name: generate-existing-networkpolicy
        match:
          any:
          - resources:
              kinds:
              - Namespace
        generate:
          kind: NetworkPolicy
          apiVersion: networking.k8s.io/v1
          name: default-deny
          namespace: "{{request.object.metadata.name}}"
          synchronize: true
          data:
            metadata:
              labels:
                created-by: kyverno
            spec:
              podSelector: {}
              policyTypes:
              - Ingress
              - Egress
    

    为现有的 Deployment 生成 PodDisruptionBudget

    下面这个策略会给已存在的或新建的 deployment 创建一个 PodDisruptionBudget 资源。

    apiVersion: kyverno.io/v1
    kind: ClusterPolicy
    metadata:
      name: create-default-pdb
    spec:
      generateExistingOnPolicyUpdate: true
      rules:
      - name: create-default-pdb
        match:
          any:
          - resources:
              kinds:
              - Deployment
        exclude:
          resources:
            namespaces:
            - local-path-storage
        generate:
          apiVersion: policy/v1
          kind: PodDisruptionBudget
          name: "{{request.object.metadata.name}}-default-pdb"
          namespace: "{{request.object.metadata.namespace}}"
          synchronize: true
          data:
            spec:
              minAvailable: 1
              selector:
                matchLabels:
                  "{{request.object.metadata.labels}}"
    

    故障排查

    要对策略应用程序故障进行故障排查,请检查 UpdateRequest 自定义资源以获取详细信息。

    例如,如果未授予 Kyverno 相应的权限,您应该在 updaterequest.status 中看到此错误:

    $ kubectl get ur -n kyverno
    NAME       POLICY               RULETYPE   RESOURCEKIND   RESOURCENAME           RESOURCENAMESPACE   STATUS   AGE
    ur-7gtbx   create-default-pdb   generate   Deployment     nginx-deployment       test                Failed   2s
    
    $ kubectl describe ur ur-7gtbx -n kyverno
    Name:         ur-7gtbx
    Namespace:    kyverno
    ...
    
    status:
      message: 'poddisruptionbudgets.policy is forbidden: User "system:serviceaccount:kyverno:kyverno-service-account"
                cannot create resource "poddisruptionbudgets" in API group "policy" in the namespace "test"'
     state: Failed
    

    相关文章

      网友评论

        本文标题:Kyverno生成资源

        本文链接:https://www.haomeiwen.com/subject/lpyfartx.html