这篇文章已超过一年。较旧的文章可能包含过时内容。请检查页面中的信息自发布以来是否仍然准确。
Kubernetes 部署安全最佳实践
注意:本文中的一些建议可能不再适用。当前的集群加固选项请参阅此文档。
编者注:今天的文章由 Aqua Security 的 Amir Jerbi 和 Michael Cherny 撰写,他们根据从本地和云部署中收集的各种用例数据,描述了 Kubernetes 部署的安全最佳实践。
Kubernetes 提供了许多可以显著提升应用安全性的控制。配置这些控制需要对 Kubernetes 和部署的安全要求有深入的了解。本文重点介绍的最佳实践与容器生命周期(构建、发布和运行)相一致,并专门针对 Kubernetes 部署进行了调整。我们在我们自己的 SaaS 部署中采用了这些最佳实践,该部署在 Google Cloud Platform 上运行 Kubernetes。
以下是我们关于部署安全 Kubernetes 应用的建议
**确保镜像不含已知漏洞**
运行含有漏洞的容器会使你的环境面临容易受到攻击的风险。许多攻击可以通过简单地确保没有已知漏洞的软件组件来缓解。
实施持续安全漏洞扫描 -- 容器可能包含带有已知漏洞(CVE)的过期软件包。由于每天都有新的漏洞发布,这不能是一个“一次性”过程。对镜像进行持续评估的流程对于确保所需的安全态势至关重要。
定期对环境应用安全更新 -- 一旦在运行的容器中发现漏洞,应始终更新源镜像并重新部署容器。尽量避免直接更新(例如 ‘apt-update’)正在运行的容器,因为这可能会破坏镜像与容器之间的关系。使用 Kubernetes 的滚动更新特性可以非常轻松地升级容器 - 这允许通过将其镜像升级到最新版本来逐步更新正在运行的应用。
确保环境中只使用授权的镜像
如果没有一个确保只允许运行符合组织策略的镜像的流程,组织就面临着运行易受攻击甚至恶意容器的风险。从未知来源下载和运行镜像非常危险。这相当于在生产服务器上运行来自未知供应商的软件。切勿这样做。
使用私有镜像仓库存储你批准的镜像 - 确保只将批准的镜像推送到这些仓库。仅此一项就可以缩小范围,将进入你的流水线的潜在镜像数量减少到数十万个公开可用镜像的一小部分。构建一个集成安全评估(如漏洞扫描)的 CI 流水线,使其成为构建过程的一部分。
CI 流水线应确保仅使用经过审查的代码(已批准用于生产)来构建镜像。镜像构建完成后,应扫描其安全漏洞,只有在未发现问题的情况下,才将镜像推送到私有镜像仓库,然后从该仓库部署到生产环境。安全评估失败应导致流水线失败,防止具有不良安全质量的镜像被推送到镜像仓库。
Kubernetes 正在进行镜像授权插件的开发(预计在 Kubernetes 1.4 中推出),这将有助于阻止非授权镜像的发布。更多信息请参阅此pull request。
限制对 Kubernetes 节点的直接访问
应限制对 Kubernetes 节点的 SSH 访问,以减少未经授权访问主机资源的风险。相反,应要求用户使用“kubectl exec”,这将直接访问容器环境,而无法访问主机。
可以使用 Kubernetes 授权插件来进一步控制用户对资源的访问。这允许为特定的命名空间、容器和操作定义细粒度的访问控制规则。
创建资源间的管理边界
限制用户权限范围可以减少错误或恶意活动的影响。Kubernetes 命名空间允许你将创建的资源划分为逻辑上命名的组。在一个命名空间中创建的资源可以对其他命名空间隐藏。默认情况下,用户在 Kubernetes 集群中创建的每个资源都运行在名为 default 的默认命名空间中。你可以创建额外的命名空间并将资源和用户附加到其中。可以使用 Kubernetes 授权插件创建策略,隔离不同用户对命名空间资源的访问。
例如:以下策略将允许 'alice' 从命名空间 'fronto' 读取 Pod。
{
"apiVersion": "abac.authorization.kubernetes.io/v1beta1",
"kind": "Policy",
"spec": {
"user": "alice",
"namespace": "fronto",
"resource": "pods",
"readonly": true
}
}
定义资源配额
运行无资源限制的容器会使你的系统面临 DoS 或“嘈杂邻居”场景的风险。为了预防和最小化这些风险,应定义资源配额。默认情况下,Kubernetes 集群中的所有资源都以无限制的 CPU 和内存请求/限制创建。可以创建附加到 Kubernetes 命名空间的资源配额策略,以限制 Pod 允许消耗的 CPU 和内存。
以下是命名空间资源配额定义的示例,它将限制命名空间中的 Pod 数量为 4 个,CPU 请求限制在 1 到 2 之间,内存请求限制在 1GB 到 2GB 之间。
compute-resources.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-resources
spec:
hard:
pods: "4"
requests.cpu: "1"
requests.memory: 1Gi
limits.cpu: "2"
limits.memory: 2Gi
为命名空间分配资源配额
kubectl create -f ./compute-resources.yaml --namespace=myspace
实施网络分段
在同一 Kubernetes 集群上运行不同的应用会产生一个被入侵的应用攻击相邻应用的风险。网络分段对于确保容器只能与它们应该通信的对象进行通信非常重要。
Kubernetes 部署中的挑战之一是在 Pod、服务和容器之间创建网络分段。由于容器网络身份(IP)的“动态”特性,以及容器可以在同一节点内部或节点之间通信的事实,这是一项挑战。
Google Cloud Platform 用户可以从自动防火墙规则中获益,从而防止跨集群通信。类似的实现可以在本地使用网络防火墙或 SDN 解决方案进行部署。Kubernetes 网络 SIG 正在这方面进行工作,这将大大改善 Pod 之间的通信策略。新的网络策略 API 应该能满足围绕 Pod 创建防火墙规则的需求,限制容器化应用的网络访问权限。
以下是控制“backend” Pod 网络的一项网络策略示例,只允许来自“frontend” Pod 的入站网络访问
POST /apis/net.alpha.kubernetes.io/v1alpha1/namespaces/tenant-a/networkpolicys
{
"kind": "NetworkPolicy",
"metadata": {
"name": "pol1"
},
"spec": {
"allowIncoming": {
"from": [{
"pods": { "segment": "frontend" }
}],
"toPorts": [{
"port": 80,
"protocol": "TCP"
}]
},
"podSelector": {
"segment": "backend"
}
}
}
在此处阅读更多关于网络策略的信息:点击这里。
为 Pod 和容器应用安全上下文
设计容器和 Pod 时,确保配置 Pod、容器和卷的安全上下文。安全上下文是部署 YAML 文件中定义的一个属性。它控制将分配给 Pod/容器/卷的安全参数。一些重要的参数包括:
安全上下文设置 | 描述 |
---|---|
SecurityContext->runAsNonRoot | 指示容器应以非 root 用户身份运行 |
SecurityContext->Capabilities | 控制分配给容器的 Linux capability。 |
SecurityContext->readOnlyRootFilesystem | 控制容器是否能够写入 root 文件系统。 |
PodSecurityContext->runAsNonRoot | 防止容器在 Pod 中以 'root' 用户身份运行 |
以下是带有安全上下文参数的 Pod 定义示例
apiVersion: v1
kind: Pod
metadata:
name: hello-world
spec:
containers:
# specification of the pod’s containers
# ...
securityContext:
readOnlyRootFilesystem: true
runAsNonRoot: true
参考文档:点击这里。
如果你正在运行具有特权(--privileged)的容器,应考虑使用 “DenyEscalatingExec” Admission Control。此控制拒绝允许主机访问的、具有升级特权的 Pod 的 exec 和 attach 命令。这包括以特权模式运行、有权访问主机 IPC 命名空间和有权访问主机 PID 命名空间的 Pod。有关 Admission Control 的更多详细信息,请参阅 Kubernetes 文档。
记录一切
Kubernetes 提供基于集群的日志记录,允许将容器活动日志记录到中央日志中心。创建集群时,每个容器的标准输出和标准错误输出可以使用运行在每个节点上的 Fluentd 代理收集到 Google Stackdriver Logging 或 Elasticsearch 中,并使用 Kibana 查看。
总结
Kubernetes 提供了许多选项来创建安全的部署。没有放之四海而皆准的解决方案,因此需要对这些选项有一定的熟悉程度,并了解它们如何增强应用安全性。
我们建议实施本文中重点介绍的最佳实践,并利用 Kubernetes 灵活的配置能力将安全流程整合到持续集成流水线中,通过无缝“内置”安全性来自动化整个过程。
- 下载 Kubernetes
- 在 GitHub 上参与 Kubernetes 项目
- 在 Stack Overflow 上提问(或回答问题)
- 在 Slack 上与社区联系
- 在 Twitter @Kubernetesio 上关注我们获取最新动态