关于云计算:Open-Policy-Agent-Top-5-Kubernetes-准入控制策略

27次阅读

共计 3938 个字符,预计需要花费 10 分钟才能阅读完成。

如何应用 Open Policy Agent 实现准入策略管制,能够参考这里

本文翻译自 Open Policy Agent: The Top 5 Kubernetes Admission Control Policies


Kubernetes 开发人员和平台工程师通常接受着十分大的压力,以放弃应用程序部署的疾速进行,并且总是为了速度和进度而做出斗争。平台团队越来越有责任确保这些斗争(例如治理 Ingress)不会导致客户数据裸露在整个互联网上等结果。

侥幸的是,Kubernetes 提供了设置策略的能力,通过查看并避免部署谬误将其投入生产,从而防止这些结果。为了确保团队的应用程序不会比信念更重要,以下是当初应该在集群中运行的前五个 Kubernetes 准入控制策略。

1. 可信镜像仓库

此策略很简略,但功能强大:仅容许从受信赖的镜像仓库中拉取的容器映像,并且能够抉择仅拉取与容许的仓库镜像地址列表匹配的那些镜像。

当然,从互联网(或可信镜像仓库库以外的任何中央)拉取未知镜像会带来危险——例如恶意软件。然而还有其余很好的理由来保护繁多的可信起源,例如在企业中实现可支持性。通过确保镜像仅来自受信赖的镜像仓库,能够亲密管制镜像库存,升高软件熵和蔓延的危险,并进步集群的整体安全性。

相干策略:

  • 禁止所有带有“latest”tag 的镜像
  • 仅容许签名镜像或匹配特定哈希 /SHA 的镜像

策略示例:

package kubernetes.validating.images
 
deny[msg] {
    some i
    input.request.kind.kind == "Pod"
    image := input.request.object.spec.containers[i].image
    not startswith(image, "hooli.com/")
    msg := sprintf("Image'%v'comes from untrusted registry", [image])
}

2. 标签平安

此策略要求所有 Kubernetes 资源都蕴含指定的标签并应用适当的格局。因为标签决定了 Kubernetes 对象和策略的分组,包含工作负载能够运行的地位——前端、后端、数据层——以及哪些资源能够发送流量,标签谬误会导致生产中无法解释的部署和可支持性问题。此外,如果没有对标签利用形式的访问控制,集群就不足根本的安全性。最初,手动输出标签的危险在于谬误会蔓延,特地是因为标签在 Kubernetes 中既灵便又弱小。利用此策略并确保标签配置正确且统一。

相干政策:

  • 确保每个工作负载都须要特定的注解(annotations)
  • 指定污点和容忍度以限度能够部署映像的地位

策略示例:

package kubernetes.validating.existence
 
deny[msg] {
    not input.request.object.metadata.labels.costcenter
    msg := "Every resource must have a costcenter label"
}
 
deny[msg] {
    value := input.request.object.metadata.labels.costcenter
    not startswith(value, "cccode-")
    msg := sprintf("Costcenter code must start with `cccode-`; found `%v`", [value])
}


## 3. 禁止(或指定)特权模式

此策略确保默认状况下容器不能在特权模式下运行 – 除非在容许的状况下排除特定状况(通常很少见)。

通常,心愿防止在特权模式下运行容器,因为它提供对主机资源和内核性能的拜访——包含禁用主机级爱护的能力。尽管容器在某种程度上是隔离的,但它们最终共享雷同的内核。这意味着如果特权容器受到入侵,它可能会成为入侵整个零碎的终点。尽管如此,在特权模式下运行还是有正当理由的——只有确保这些工夫是例外,而不是规定。

相干政策:

  • 禁止不平安的能力(capabilities)
  • 禁止容器以 root 身份运行(以非 root 身份运行)
  • 设置 userID

策略示例:

package kubernetes.validating.privileged
 
deny[msg] {
    some c
    input_container
    c.securityContext.privileged
    msg := sprintf("Container'%v'should not run in privileged mode.",)
}
 
input_container[container] {container := input.request.object.spec.containers[_]
}
 
input_container[container] {container := input.request.object.spec.initContainers[_]
}

定义和管制入口

Ingress 策略容许依据须要公开特定服务(容许 Ingress),或者依据须要不公开任何服务。在 Kubernetes 中,很容易意外启动与公共互联网通信的服务(Kubernetes 故障故事中有很多这样的例子)。同时,过于宽松的 Ingress 会导致启动不必要的内部 LoadBalancer,这也可能会变得十分低廉(如每月估算收入)十分快!此外,当两个服务尝试共享同一个 Ingress 时,它可能会毁坏应用程序。

上面的策略示例避免不同命名空间中的 Ingress 对象共享雷同的主机名。这个常见问题意味着新工作负载会从现有工作负载“窃取”互联网流量,这会产生一系列负面结果——从服务中断到数据裸露等等。

相干政策:

  • 须要 TLS
  • 禁止 / 容许特定端口

策略示例:

package kubernetes.validating.ingress
 
deny[msg] {
    is_ingress
    input_host := input.request.object.spec.rules[_].host
    some other_ns, other_name
    other_host :=
    data.kubernetes.ingresses[other_ns][other_name].spec.rules[_].host
    [input_ns, input_name] != [other_ns, other_name]
 
    input_host == other_host
 
    msg := sprintf("Ingress host conflicts with ingress %v/%v", [other_ns, other_name])
}
 
input_ns = input.request.object.metadata.namespace
 
input_name = input.request.object.metadata.name
 
is_ingress {
    input.request.kind.kind == "Ingress"
    input.request.kind.group == "extensions"
    input.request.kind.version == "v1beta1"
}

5. 定义和管制进口

每个应用程序都须要防护栏来管制进口流量的流动形式,此策略容许你指定集群内和集群外的通信。与 Ingress 一样,默认状况下很容易意外地“容许 Egress”到全世界的每个 IP。有时这甚至不是意外——齐全的放开通常是确保能够拜访新部署的应用程序的最初致力,即便它过于宽松或引入危险。在集群内级别,还有可能无心中将数据发送到不应该领有的服务。如果服务受到侵害,这两种状况都存在数据泄露和偷盗的危险。另一方面:过于严格,应用 Egress 有时会导致配置谬误,从而毁坏应用程序。实现两败俱伤意味着应用此策略抉择和指定容许 Egress 产生的工夫和服务。

相干政策。

  • 请参阅下面的入口策略

策略示例:

package kubernetes.validating.egress
 
allow_list := {
    "10.10.0.0/16",
    "192.168.100.1/32"
}
 
deny[reason] {
    network_policy_allows_all_egress
    reason := "Network policy allows access to any IP address."
}
 
deny[reason] {count(allow_list) > 0
    input.request.kind.kind == "NetworkPolicy"
    input.request.object.spec.policyTypes[_] == "Egress"
    ipBlock := input.request.object.spec.egress[_].to[_].ipBlock
    not any({t | t := net.cidr_contains(allow_list[_], ipBlock.cidr)})
    reason := "Network policy allows egress traffic outside of allowed IP ranges."
}
 
network_policy_allows_all_egress {
    input.request.kind.kind == "NetworkPolicy"
    input.request.object.spec.policyTypes[_] == "Egress"
    egress := input.request.object.spec.egress[_]
    not egress.to
}

有了这些政策,你就能够专一于构建一个世界级的平台。当然,如果你想为 Kubernetes 增加更多根本策略,请查看 openpolicyagent.org。

文章对立公布在公众号 云原生指北

正文完
 0