跳转至

开启准入控制

K8s 的准入控制(Admission Control)是一种安全机制,并在运行时作为 Webhook 运行。通过准入 Webhook 对请求进行拦截和修改,从而保证集群的安全性。准入 Webhook 操作包括验证(Validating)和变更(Mutating)两类。NebulaGraph Operator 仅支持验证操作,并提供一些默认的准入控制规则。本文介绍 NebulaGraph Operator 的默认准入控制规则及如何开启准入控制。

前提条件

已使用 K8s 创建一个集群。具体步骤,参见使用 Kubectl 创建NebulaGraph集群

准入控制规则

K8s 的准入控制允许用户在 Kubernetes API Server 处理请求之前,插入自定义的逻辑或策略。这种机制可以用于实现一些安全策略,比如限制 Pod 的资源使用量,或者限制 Pod 的访问权限等。NebulaGraph Operator 仅支持验证操作,即对请求进行验证和拦截,不支持对请求进行变更操作。NebulaGraph Operator 默认的准入验证控制规则包括:

  • 满足高可用模式下的最小副本数:

    • Graph 服务:至少需要 2 个副本。
    • Meta 服务:至少需要 3 个副本。
    • Storage 服务:至少需要 3 个副本。

    Note

    高可用模式是指NebulaGraph集群服务的高可用。Storage 服务和 Meta 服务是有状态的服务,其副本数据通过 Raft 协议保持一致性且副本数量不能为偶数。因此,高可用模式下,至少需要 3 个 Storage 服务和 3 个 Meta 服务。Graph 服务为无状态的服务,因此其副本数量可以为偶数,但至少需要 2 个副本。

  • 禁止通过dataVolumeClaims为 Storage 服务追加额外的 PV。
  • 禁止缩小所有服务的 PVC 的容量,但是可以扩容。
  • 禁止在 Storage 服务扩缩容期间,进行任何二次操作。

为准入 Webhook 创建证书

为了确保通信的安全性和数据的完整性,K8s 的 API server 和准入 Webhook 之间的通信默认通过 HTTPS 协议进行,因此使用准入控制还需要为准入 Webhook 提供 TLS 证书。cert-manager 是一个 K8s 的证书管理控制器,可以自动化证书的签发和更新。NebulaGraph Operator 使用 cert-manager 来管理证书。

当 cert-manager 安装完成并且开启准入控制时,NebulaGraph Operator 会自动创建一个 Issuer,用于签发准入 Webhook 所需的证书,同时会创建一个 Certificate,用于存储签发的证书。签发的证书被存储在 nebula-operator-webhook-secret的 Secret 中。

开启准入控制

  1. 安装部署 cert-manager。

    kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.1/cert-manager.yaml
    

    建议部署最新版本 cert-manager。详情参见 cert-manager 官方文档

  2. 修改 NebulaGraph Operator 的配置文件,开启准入控制。默认准入控制是关闭的,需要手动开启。

    # 查看当前的配置
    helm show values nebula-operator/nebula-operator 
    
    # 修改配置,将`enableAdmissionWebhook`设置为`true`。
    helm upgrade nebula-operator nebula-operator/nebula-operator --set enableAdmissionWebhook=true 
    

    Note

    nebula-operator为 chart 所在仓库的名称,nebula-operator/nebula-operator为 chart 的名称。如果没有指定 chart 的命名空间,默认为default

  3. 查看准入 Webhook 的证书 Secret。

    kubectl get secret nebula-operator-webhook-secret -o yaml
    

    如果输出的结果中包含证书内容,则表示准入 Webhook 的证书已经创建成功。

  4. 验证控制规则。

    • 验证高可用模式下的最小副本数。

      # 标注集群为高可用模式
      $ kubectl annotate nc nebula nebula-graph.io/ha-mode=true
      # 验证 Graph 服务的最小副本数
      $ kubectl patch nc nebula  --type='merge' --patch '{"spec": {"graphd": {"replicas":1}}}'
      Error from server: admission webhook "nebulaclustervalidating.nebula-graph.io" denied the request: spec.graphd.replicas: Invalid value: 1: should be at least 2 in HA mode
      
    • 验证禁止通过dataVolumeClaims为 Storage 服务追加额外的 PV。

      $ kubectl patch nc nebula  --type='merge' --patch '{"spec": {"storaged": {"dataVolumeClaims":[{"resources": {"requests": {"storage": "2Gi"}}, "storageClassName": "local-path"},{"resources": {"requests": {"storage": "3Gi"}}, "storageClassName": "fask-disks"}]}}}'
      Error from server: admission webhook "nebulaclustervalidating.nebula-graph.io" denied the request: spec.storaged.dataVolumeClaims: Forbidden: storaged dataVolumeClaims is immutable
      
    • 验证禁止缩小 Storage 服务的 PVC 的容量。

      $ kubectl patch nc nebula  --type='merge' --patch '{"spec": {"storaged": {"dataVolumeClaims":[{"resources": {"requests": {"storage": "1Gi"}}, "storageClassName": "fast-disks"}]}}}'
      Error from server: admission webhook "nebulaclustervalidating.nebula-graph.io" denied the request: spec.storaged.dataVolumeClaims: Invalid value: resource.Quantity{i:resource.int64Amount{value:1073741824, scale:0}, d:resource.infDecAmount{Dec:(*inf.Dec)(nil)}, s:"1Gi", Format:"BinarySI"}: data volume size can only be increased
      
    • 验证禁止在 Storage 服务缩容期间,进行任何二次操作。

      $ kubectl patch nc nebula  --type='merge' --patch '{"spec": {"storaged": {"replicas": 5}}}'
      nebulacluster.apps.nebula-graph.io/nebula patched
      $ kubectl patch nc nebula  --type='merge' --patch '{"spec": {"storaged": {"replicas": 3}}}'
      Error from server: admission webhook "nebulaclustervalidating.nebula-graph.io" denied the request: [spec.storaged: Forbidden: field is immutable while in ScaleOut phase, spec.storaged.replicas: Invalid value: 3: field is immutable while not in Running phase]
      

最后更新: November 15, 2023