Guest post originally published on Armo’s blog by Bezalel Brandwinen, Team Lead at Armo Ltd Source CNCF
Kubernetes has taken center stage in how we now manage our containerized applications. As a result, many conventions to define our Kubernetes apps exist, including structures such as YAML, JSON, INI, and more. Kubernetes 在我们现在如何管理容器化应用程序方面占据了中心位置。因此,存在许多定义我们的 Kubernetes 应用程序的约定,包括 YAML、JSON、INI 等结构。
This leaves us to consider what is the best strategy to follow for our applications. Additionally, we must then also ask how we can validate our application configurations depending on the path we’ve chosen in terms of file structure and especially security. 这让我们考虑什么是我们的应用程序应遵循的最佳策略。此外,我们还必须询问如何根据我们在文件结构和特别是安全性方面选择的路径来验证我们的应用程序配置。
In this piece, we will explore defining Kubernetes applications using YAML configs and the various steps we can take to effectively validate these config definitions. 在本文中,我们将探索使用 YAML 配置定义 Kubernetes 应用程序,以及我们可以采取的各种步骤来有效验证这些配置定义。
YAML - Kubernetes中配置定义
YAML, compared to JSON and INI, is much more compact and readable. For example, if we were to define a pod that can be reached on port 80, then the configuration in YAML, JSON, and INI would be as shown in the table below. 与 JSON 和 INI 相比, YAML更加紧凑和可读。比如我们定义一个80端口可以访问的pod,那么YAML、JSON、INI中的配置如下表所示。
YAML | JSON | INI |
---|---|---|
apiVersion: v1kind: Podmetadata:name: spring-podspec:containers:– image:armo/springapp:examplename: spring-appports:– containerPort: 80协议:TCP | {“apiVersion”: “v1”,“kind”: “Pod”,“metadata”: {“name”: “spring-pod”},“spec”: {“containers”: [“image:armo/springapp: examplenname: spring-appnports:n- containerPort: 80nprotocol: TCP”] }} | apiVersion=v1kind=Pod[metadata] name=spring-pod[spec] containers[]=”image:armo/springapp:examplenname: spring-appnports:n- containerPort: 80nprotocol: TCP” |
It is clearly visible that YAML simplifies how we can define our Kubernetes applications, especially considering that a normal application can involve dozens of config files. Additionally, the compact nature of YAML allows you to group objects together, reducing the number of files required. 很明显,YAML 简化了我们定义 Kubernetes 应用程序的方式,特别是考虑到一个普通的应用程序可能涉及数十个配置文件。此外,YAML 的紧凑特性允许您将对象组合在一起,从而减少所需文件的数量。
However, there are major challenges with defining our Kubernetes config files, particularly when attempting to embed constraints and relationships between manifest files. For example, how can we ensure that the memory limits are configured to follow best practices? 但是,定义我们的 Kubernetes 配置文件存在重大挑战,尤其是在尝试在清单文件之间嵌入约束和关系时。例如,我们如何确保内存限制配置为遵循最佳实践?
Not only can the lack of validation result in unexpected behavior from our applications when edge cases are met, but it can also expose major security loopholes. Hence, it is necessary that we consider validation strategies for our YAML-based config files, and that’s what we will dive into in the following sections. 当遇到边缘情况时,缺乏验证不仅会导致我们的应用程序出现意外行为,而且还会暴露主要的安全漏洞。因此,我们有必要考虑基于 YAML 的配置文件的验证策略,这就是我们将在以下部分中深入探讨的内容。
验证的各个方面
There are three levels of validation that should be performed on our YAML files. These levels ensure that validation is performed in terms of the actual validity of the YAML file all the way to whether or not security practices have been met. 应该对我们的 YAML 文件执行三个级别的验证。这些级别确保根据 YAML 文件的实际有效性执行验证,一直到是否满足安全实践。 The first level is structural validation, which is the highest level of validation performed on Kubernetes configuration files. It involves simply validating the YAML file to ensure there are no syntax errors when writing it. This is something that can be validated by IDEs used when writing the config files. 第一级是 结构验证,这是对 Kubernetes 配置文件进行的最高级别的验证。它涉及简单地验证 YAML 文件以确保在编写它时没有语法错误。这是编写配置文件时使用的 IDE 可以验证的内容。
The second level is semantic validation. This ensures that the content of the YAML file translates to the Kubernetes resources desired, hence validating the Kubernetes application itself. 第二层是 语义验证。这确保 YAML 文件的内容转换为所需的 Kubernetes 资源,从而验证 Kubernetes 应用程序本身。 Finally, the third and deepest level of validation is security validation, to ensure that the Kubernetes application defined does not have any vulnerabilities. We may have been successful in writing our YAML config successfully to achieve the required Kubernetes resources and connections, but this does not ensure our Kubernetes application is well-secured and follows best practices. 最后,第三个也是最深层次的验证是 安全验证, 以确保定义的 Kubernetes 应用程序没有任何漏洞。我们可能已经成功地 编写了 YAML 配置 以成功实现所需的 Kubernetes 资源和连接,但这并不能确保我们的 Kubernetes 应用程序得到很好的保护并遵循最佳实践。
The last two validations above are both Kubernetes configuration validations, and not only in the aspect of YAML format validation. Since they are application-specific validations, a dedicated treatment is necessary. Deep and professional knowledge of the Kubernetes domain is required to perform such validations, and we will take a short look at how to handle them easily using tools developed by Kubernetes domain experts. 上面最后两个验证都是Kubernetes配置验证,并不仅仅在YAML格式验证方面。由于它们是特定于应用程序的验证,因此专门治疗是必要的。执行此类验证需要 Kubernetes 领域的深入专业知识,我们将简要介绍如何使用 Kubernetes 领域专家开发的工具轻松处理它们。
For example, locking down hostPath mount permissions makes sure a container in the cluster with a writable hostPath volume is not accessed by attackers, as they may then gain persistence on the underlying host. This does not follow security best practices, and to avoid the issue, we should always ensure that the readOnly section under the hostPath attribute is set to true. 例如,锁定 hostPath 挂载权限可确保集群中具有可写 hostPath 卷的容器不会被攻击者访问,因为他们可能会在底层主机上获得持久性。这不符合安全最佳实践,为避免此问题,我们应始终确保将 hostPath 属性下的 readOnly 部分设置为 true。
Another example is granting hostNetwork access to pods only when it is necessary. All pods that have access should also be whitelisted. Unnecessary access to hostNetwork increases the potential attack surface area. 另一个示例是仅在必要时授予 hostNetwork 对 pod 的访问权限。所有具有访问权限的 pod 也应列入白名单。对主机网络的不必要访问增加了潜在的攻击面。
So, it can be seen from the two examples above that even after our config files have passed the structural and semantic validations, leading to our Kubernetes resources successfully being orchestrated, security and functional vulnerabilities may still exist. Hence, we must consider how best to capture these vulnerabilities before being alerted to the consequences in production. Security validation is the method to do this. 所以,从上面两个例子可以看出,即使我们的配置文件通过了结构和语义验证,导致我们的 Kubernetes 资源被成功编排,安全和功能漏洞仍然可能存在。因此,我们必须考虑如何最好地捕获这些漏洞,然后再提醒生产中的后果。安全验证是执行此操作的方法。
验证和最佳实践
Considering that structural validation is fairly simple, it can be expected that the tooling available is now readily available in your IDEs. Kubernetes semantics and security validations require a bit more effort, especially in terms of strategy and tooling. 考虑到结构验证相当简单,可以预期可用的工具现在可以在您的 IDE 中轻松获得。Kubernetes 语义和安全验证需要更多的努力,尤其是在策略和工具方面。
Let’s consider some of the best practices and strategies these entail to achieve overall validation of our YAML files. 让我们考虑一些最佳实践和策略,这些实践和策略需要实现对我们的 YAML 文件的整体验证。
Always shift left 始终左移
We may always validate our K8s configurations, even though we already deployed them in the cluster, using tools like Kubescape, but it’s always better to “shift left”. Shift left is a term that has blown up in the past five or six years, and rightly so. You want to bring validation closer to the delivery and build stage of your applications. 我们可能总是验证我们的 K8s 配置,即使我们已经使用 Kubescape 等工具将它们部署在集群中,但“左移”总是更好。左移是一个在过去五六年里火了起来的词,这是理所当然的。您希望使验证更接近应用程序的交付和构建阶段。 For example, semantic validation is something that Kubernetes itself can handle. However, by the time you leave it to Kubernetes to handle, it’s too late. 例如,语义验证是 Kubernetes 本身可以处理的事情。但是,当您将其交给 Kubernetes 处理时,为时已晚。
You could perform a dry run (kubectl apply -f --dry-run='server’') to validate the semantic structure, but this still is an additional step that could slow down your overall velocity. However, a dry run requires you to have access to the Kubernetes cluster.
您可以执行dry run
( kubectl apply -f --dry-run='server’
) 来验证语义结构,但这仍然是一个额外的步骤,可能会降低您的整体速度。但是,dry run
需要您有权访问 Kubernetes 集群。
An alternative to this approach is Kubeval, which is an amazing tool that can be used to validate your config file semantics to ensure they meet Kubernetes’ object definition requirements. It can be part of your CI process and perform scanning locally, thereby ensuring that you semantically validate your config files before you go to production. 这种方法的替代方法是 Kubeval,这是一个了不起的工具,可用于验证您的配置文件语义以确保它们满足 Kubernetes 的对象定义要求。它可以成为您的 CI 过程的一部分并在本地执行扫描,从而确保您在投入生产之前从语义上验证您的配置文件。
Security validation can also be achieved in the CI using Kubescape. This is an open-source tool that ensures your Kubernetes application definitions follow multiple security frameworks such as NSA-CISA or MITRE ATT&CK®. By using the Kubescape CLI, you can scan all of your YAML files for security vulnerabilities and even get a risk score and risk trends. It acts as a YAML validator with its main value being security validation. 还可以使用 Kubescape在 CI 中实现安全验证。这是一个开源工具,可确保您的 Kubernetes 应用程序定义遵循多个安全框架,例如 NSA-CISA 或 MITRE ATT&CK®。通过使用 Kubescape CLI,您可以扫描所有 YAML 文件以查找安全漏洞,甚至可以获得风险评分和风险趋势。它充当 YAML 验证器 ,其主要价值是安全验证。
DevOps 到 DevSecOps
You can run a combination of tools already discussed in your CI pipeline to achieve structural, semantic, and security validation. However, just utilizing these tools and their predefined checks is not enough. 您可以运行 CI 管道中已经讨论过的工具组合,以实现结构、语义和安全验证。然而,仅使用这些工具及其预定义的检查是不够的。
One thing we’ve learned from DevOps is that there is always a cycle of improvement that can be adopted. That is why as your application evolves, and your security needs change, you should constantly review your security controls. 我们从 DevOps 中学到的一件事是,总有一个可以采用的改进周期。这就是为什么随着您的应用程序的发展和您的安全需求的变化,您应该不断检查您的安全控制。
New security controls are something you should incorporate into your security validation steps. Kubescape, an open-source platform by AMRO, allows you to define your own framework of controls. Even though the out-of-the-box framework is robust, you will see your policy controls take shape per the exact needs of your business and Kubernetes resources. 新的安全控制是您应该纳入安全验证步骤的东西。Kubescape 是 AMRO 的开源平台,允许您定义自己的控件框架。尽管开箱即用的框架非常强大,但您会看到您的策略控制是根据您的业务和 Kubernetes 资源的确切需求而形成的。
Such a practice can only be achieved if security concerns are embedded into the culture of how you’re building apps. Thanks to open-source tools such as Kubeval and Kubescape, the barriers to your development team continuously thinking about validation, and especially security validation, has been lowered. 只有将安全问题嵌入到您构建应用程序的文化中,才能实现这种做法。多亏了 Kubeval 和 Kubescape 等开源工具,您的开发团队不断思考验证,尤其是安全验证的障碍已经降低。
结论
YAML config files have made building Kubernetes applications quite simple. However, YAML does have its limitations in terms of validation. It is therefore necessary that we are aware of all validation strategies to ensure that we build our Kubernetes applications to be healthy and secure. YAML 配置文件使构建 Kubernetes 应用程序变得非常简单。然而,YAML 在验证方面确实有其局限性。因此,我们有必要了解所有验证策略,以确保我们构建的 Kubernetes 应用程序健康且安全。
Validating the structure of a YAML file is fairly simple with YAML tests in any IDE, but validating the correctness of Kubernetes resource object definitions and the security measures around them is difficult. Luckily, tools such as Kubescape close the gap, allowing you to shit left and constantly think about security across your entire application lifecycle. 在任何 IDE 中使用 YAML 测试验证 YAML 文件的结构都相当简单,但验证 Kubernetes 资源对象定义的正确性和围绕它们的安全措施却很困难。幸运的是,诸如 Kubescape 之类的工具弥补了这一差距,让您可以在整个应用程序生命周期中不断思考安全问题。
With security being one of the prime concerns of building containerized applications today, the validation strategies discussed here are one step in the right direction. 由于安全性是当今构建容器化应用程序的主要关注点之一,因此此处讨论的验证策略是朝着正确方向迈出的一步。
DevOps云学堂,一个盛满新技术实践的学习平台。技术开放交流,技术实践应用分享。目标前课程正正在一步步覆盖DevOps全面!