如何在Kubernetes中强制执行清单的策略

69次阅读
没有评论

问题描述

在基于Kubernetes构建了一个自助平台,为每个团队创建了命名空间,并允许他们“在命名空间内做任何他们想做的事情”(我们设置了资源限制,以防止任何人破坏整个集群)。
然而,现在我想在整个组织中实施一些标准。例如,我希望每个PodSpec都定义自己的资源限制,并且我希望每个资源都有一个标签,指定它属于哪个应用程序。
是否有一种机制可以让API服务器检查正在应用的清单是否符合一组规则,如果检查失败,则拒绝该清单。
例如,以下清单将被拒绝,因为它既没有标签,也没有设置资源限制:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

但是以下清单将成功,因为它满足所有规则:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: foobar
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80
        resources:
          limits:
            cpu: "1"
          requests:
            cpu: "0.5"

解决方案

请注意以下操作注意版本差异及修改前做好备份。

方案1

我建议您使用Open Policy Agent(OPA),它可以让您定义类似以下策略:

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sContainerLimits
metadata:
  name: container-must-have-limits
spec:
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Pod"]
  parameters:
    cpu: "200m"
    memory: "1Gi"

OPA将通过一个Admission Controller来强制执行您定义的任何策略。但请注意,OPA非常强大,如果不仔细考虑选项,可能会导致集群崩溃。

方案2

另一种方法是使用自定义资源(Custom Resource)来实现此目的。您可以创建一个自定义资源定义(Custom Resource Definition,CRD),并编写一个控制器来验证清单是否符合您的规则。这种方法需要编写一些自定义代码,并且可能需要更多的工作量。

方案3

您还可以考虑为每个命名空间创建资源配额(Resource Quota)。资源配额可以限制命名空间中的资源使用量,并且可以强制执行一些规则。您可以为每个命名空间设置资源配额,以确保每个清单都符合您的要求。有关如何启用资源配额的更多信息,请参阅Kubernetes文档
请根据您的需求选择适合您的解决方案。

正文完