Kubernetes 部署的最佳安全实践

编者按:本文是由 Aqua Security 的Amir Jerbi 和Michael Cherny 所写,基于他们从本地和云端上收集到的实际数据,描述了Kubernetes 部署的最佳安全实践。

Kubernetes提供了许多可以极大地提高应用程序安全性的选项。配置它们要求你熟悉 Kubernetes 以及其部署的安全要求。

我们在这里强调的最佳实践与容器生命周期相匹配:构建、分发和运行,并专门为Kubernetes量身打造。我们在运行在Google云平台的kubernetes上使用了这些安全实践。

 以下是我们部署安全的Kubernetes应用的建议:

◆  确保镜像没有漏洞 

运行有漏洞的容器使你的环境会遭受损害的风险。许多攻击可以简单地通过将软件升级为没有漏洞的版本来避免。

实现Continuous Security Vulnerability Scanning (持续安全漏洞扫描)——容器可能包括含有已知漏洞(CVE)的过时包。新的漏洞每天都会发布,所以这不是一个“一次性”的工作,对镜像持续进行安全评估是至关重要的。

 定期对环境进行安全更新,一旦发现运行中容器的漏洞,你应该及时更新镜像并重新部署容器。尽量避免直接更新(例如, ‘apt-update’ )到正在运行的容器,因为这样打破了镜像与容器的对应关系。

使用Kubernetes滚动升级功能升级容器非常简单,该功能允许通过升级镜像到最新版本来逐步更新正在运行的容器。

◆  确保在你的环境中只使用授权镜像

如果无法保证只运行符合组织策略的镜像,那么组织会面临运行脆弱甚至恶意容器的危险。从未知的来源下载和运行镜像是危险的,它相当于在生产服务器上运行未知服务商的软件,所以千万别这样做!

使用私有镜像存储你的合法镜像,这样能大量减少可能进入到你的环境的镜像数量。将成安全评估(如漏洞扫描)加入持续集成(CI)中,使其成为构建流程的一部分。

持续集成应确保只使用审查通过的代码来构建镜像。当镜像构建成功后,要对它进行安全漏洞扫描,然后只有当没有发现问题时,镜像才能被推送私有镜像仓库。在安全评估中失败的镜像不应该被推送到镜像仓库中。

Kubernetes镜像授权插件的工作已经完成(预计随kubernetes 1.4发布)。该插件允许阻止未授权镜像的分发。具体请查看此PR (https://github.com/kubernetes/kubernetes/pull/27129)。

◆  限制对Kubernetes 节点的直接访问

应该限制SSH登陆Kubernetes节点,减少对主机资源未授权的访问。应该要求用户使用“ kubectl exec ”命令,此命令能够在不访问主机的情况下直接访问容器环境。

你可以使用kubernetes授权插件来进一步控制用户对资源的访问。它允许设置对指定命名空间、容器和操作的细粒度访问控制规则。

◆  创建资源间的管理界限

限制用户权限的范围可以减少错误或恶意活动的影响。Kubernetes 命名空间允许将资源划分为逻辑命名组。在一个命名空间中创建的资源对其他命名空间是隐藏的。

默认情况下,用户在Kubernetes 集群中创建的每个资源运行在名称为“default”的默认空间内。你也可以创建额外的命名空间并附加资源和用户给它们。你可以使用Kubernetes 授权插件来创建策略,以便将不同用户的访问请求隔离到不同的命名空间中。

例如:以下策略将允许 ‘alice’ 从命名空间 ‘fronto’ 读取pods。

%e5%ae%89%e5%85%a8%e5%ae%9e%e8%b7%b51

◆  定义资源配额

运行没有资源限制的容器会将你的系统置于DoS或被其他租户干扰的风险中。为了防止和最小化这些风险,你应该定义资源配额。

默认情况下,Kubernetes 集群中的所有资源没有对CPU 和内存的使用限制。你可以创建资源配额策略,并附加到Kubernetes命名空间中来限制Pod对CPU和内存的使用。

下面的例子将限制命名空间中Pod 的数量为4个,CPU使用在1和2之间,内存使用在1GB 和 2GB 之间。

compute-resources.yaml:%e5%ae%89%e5%85%a8%e5%ae%9e%e8%b7%b52

分配资源配额到命名空间:

%e5%ae%89%e5%85%a8%e5%ae%9e%e8%b7%b53

◆  实现网络分段

在相同的Kubernetes集群上运行不同的应用程序会导致恶意程序攻击其他应用程序的风险。所以网络分割对确保容器只与那些被允许的容器进行通信很重要。

Kubernetes 部署的挑战之一是创建Pod,服务和容器之间的网络分段。原因在于容器网络标识符(IP地址)动态的“天性”,以及容器可以在同一节点或节点间进行通信的事实。

谷歌云平台的用户受益于自动防火墙规则,能够防止跨集群通信。类似的实现可以使用网络防火墙或SDN解决方案部署。这方面的工作由Kubernetes 网络特别兴趣小组(Special Interest Group)完成,这将大大提高 pod到pod 的通信策略。

新的网络策略API应该解决 Pod之间创建防火墙规则的需求,限制容器化可以进行的网络访问。

下面展示了只允许前端(frontend)Pod访问后端(backend)Pod的网络策略:

%e5%ae%89%e5%85%a8%e5%ae%9e%e8%b7%b54

点击这里(http://blog.kubernetes.io/2016/04/Kubernetes-Network-Policy-APIs.html)阅读更多网络策略的内容。

◆  将安全环境应用到你的Pods和容器中

当设计你的容器和 pods时,确保为你的pods,容器和存储卷配置安全环境。安全环境是定义在yaml文件中的一项属性。它控制分配给 pod/容器/存储卷的安全参数。一些重要的参数是:

安全环境设置项 描述
SecurityContext->runAsNonRoot 容器应该以非root用户运行
SecurityContext->Capabilities 控制分配给容器的Linux能力
SecurityContext->readOnlyRootFilesystem 控制容器对root文件系统是否只读
PodSecurityContext->runAsNonRoot 防止root用户作为 pod 的一部分运行容器

下是一个具有安全环境参数的pod 定义示例:

%e5%ae%89%e5%85%a8%e5%ae%9e%e8%b7%b55

◆  记录所有的事情

Kubernetes提供基于集群的日志,允许将容器活动日志记录到一个日志中心。当集群被创建时,每个容器的标准输出和标准错误都可以通过运行在每个节点上的Fluentd 服务记录到Stackdriver或Elasticsearch中,然后使用Kibana进行查看。

◆  总结

Kubernetes 对创建安全部署提供多种选择,没有适合所有情况的万能解决方案,所以熟悉这些安全选项、了解它们如何提高应用程序安全性是很重要的。

我们推荐这篇文章中提到的安全实践,将Kubernetes的灵活配置能力加入到持续集成中,自动将安全性无缝融合到整个流程中。

本文由时速云翻译,如若转载,需注明转载自“时速云

原文链接:  http://blog.kubernetes.io/2016/08/security-best-practices-kubernetes-deployment.html

暂无评论

发表评论