如何应用 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。
文章对立公布在公众号
云原生指北