图片由 Trac Vu 在Unsplash 上提供
gVisor的架构
gVisor 主要包括两大组件:Sentry 和 Gofer。
Sentry
Sentry(不要与同名的 Sentry监控平台混淆)代表容器化应用程序负责拦截和服务系统调用。它充当类似内核的接口,但不会将调用直接转发到主机内核。
相反,Sentry 在其自己的隔离环境中为这些请求提供服务,可在正在运行的微服务和主机之间提供一层隔离。Sentry 会进行自己的有限系统调用,这些调用与安全执行的 seccomp规则密切相关。
Gofer
Gofer 是 gVisor 的组件,负责协调文件系统操作。当容器化应用程序需要访问主机文件系统时,Sentry 会将这些请求转发给 Gofer。
然后,Gofer 使用主机,代表应用程序执行必要的文件系统操作,通过防止从容器内直接访问主机文件系统,引入了额外的隔离层。
gVisor 使用名为 runsc(runsc 沙箱)的进程来代替 runc 作为底层容器运行时。runsc 专为 gVisor 设计,充当容器运行时和 gVisor 组件(Sentry 和 Gofer)之间的接口。
它处理容器生命周期管理、进程隔离和其他底层容器操作。 runsc 与 Sentry 和 Gofer 交互,为 gVisor 中的容器化应用程序提供安全的执行环境。
Kata Containers 的架构
Kata Containers 通过将每个容器或 Pod 封装在自己的专用 VM 中的方法提供了额外的保护层,因为每个 VM 都有自己的内核,该内核仅包含容器工作负载所需的服务,从而减少了潜在的攻击面。
除增强安全性之外,Kata Containers 还优先考虑性能和资源效率。Kata Containers提倡最小程度占用空间,这对于那些在安全需求与高效资源利用率之间寻求平衡的组织来说颇具吸引力。
Kata Containers旨在与现有的容器化应用程序和部署基础设施兼容,使组织能够采用安全的运行时功能,而无需进行重大修改。
用户通过将 Kata Containers 视为集群的安全运行时,可从其出色的隔离性、轻量资源占用和增强的安全性中受益,使其成为部署敏感或不可信工作负载的绝佳选择。
配置 gVisor 以实现容器安全
以下是用于创建 RuntimeClass对象和利用 gVisor 作为容器运行时的 pod 清单文件的代码示例。
在此示例中,创建了一个名为gvisor的RuntimeClass,指定容器运行时处理程序为“runsc”,该命令用于与 gVisor 交互。
在gvisor-pod.yaml文件中,定义了一个名为gvisor-pod的Pod。runtimeClassName字段指定该 Pod 使用“gvisor”RuntimeClass,对应于 gVisor 容器运行时。
容器部分可定义容器配置,包括要使用的容器名称和镜像(将“your-image”替换为实际镜像名称)。
准备好 gvisor.yaml 和gvisor-pod.yaml 文件后,可以使用以下命令创建 RuntimeClass 并部署 pod。
这些命令将为 gVisor 创建RuntimeClass 对象,并使用 gVisor 作为容器运行时来部署 pod。
请注意,务必确保在 Kubernetes 集群上正确安装和配置 gVisor,以使这些配置正常工作。
以下是用于创建RuntimeClass对象和利用 Kata Containers 作为容器运行时的 pod 清单文件的代码演示。
在上面的示例中,定义了一个名为kata的RuntimeClass,指定容器运行时处理程序为“kata-runtime”,对应于 Kata Containers 运行时。
kata-pod.yaml文件中定义了一个名为kata-pod的 Pod。runtimeClassName字段指定该 Pod 应使用kata RuntimeClass,对应于 Kata Containers 运行时。
容器部分可定义容器配置,包括容器名称和要使用的容器镜像(将“your-image”替换为实际镜像名称)。
准备好 kata.yaml 和kata-pod.yaml 文件后,可以使用以下命令创建 RuntimeClass 并部署 pod:
这些命令将为 Kata Containers 创建RuntimeClass 对象并部署 Pod,使用 Kata Containers 作为容器运行时。
请确保在 Kubernetes 集群上正确安装和配置 Kata Containers,以使这些配置按预期工作。
Kubernetes RuntimeClass 功能的优势
Kubernetes 中的 RuntimeClass 功能高度灵活,用户可根据特定需求和安全策略选择不同的容器运行时,为集群中的不同工作负载定义和选择合适的运行时。
以下是使用 RuntimeClass 的主要优势和用例:
工作负载隔离:不同的工作负载可能有不同的安全需求,通过RuntimeClass,您可选择最合适的运行时,为每个工作负载提供所需的隔离和安全级别。
例如,对于安全敏感型工作负载,可使用 gVisor 或 Kata Containers 等更轻量级、更高效的容器运行时;对于其他工作负载则使用标准运行时,如 Docker 或containerd。
自定义运行时:RuntimeClass能够在 Kubernetes 环境中集成和使用自定义容器运行时。如果您已经开发或采用定制的运行时来满足需求,可为其定义RuntimeClass 并用于特定工作负载。
性能优化:不同容器运行时的性能各有不同,通过使用RuntimeClass,您可为每个工作负载选择最合适的运行时以优化性能。例如,对于需要更高资源利用率和更快启动时间的工作负载,可选择 gVisor 或 Kata Containers 等轻量级运行时。
合规和安全策略:组织通常有特定的安全策略或合规性要求,规定用于某些工作负载的运行时。RuntimeClass让您可通过为需要遵守特定安全准则的工作负载配置适当的运行时来执行这些策略。
动态运行时切换:RuntimeClass还支持为正在运行的工作负载动态切换运行时。这种灵活性使您可按需切换运行时,从而适应不断变化的工作负载需求或高效应对安全事件。
部署安全运行时的最佳实践
了解何时以及如何使用安全容器运行时对于规划安全的 Kubernetes 环境至关重要。以下是根据特定需求部署安全运行时的一些选项和注意事项:
在集群中的每个 Pod 上使用安全运行时。一种方法是使用安全容器运行时(例如 gVisor 或 Kata Containers)作为集群中所有 Pod 的默认运行时,这可确保集群中运行的所有工作负载的一致且强大的隔离,无论其信任级别如何。
通过默认使用安全运行时,可为整个环境提供额外的保护层。
在安全容器中运行不受信任的或第三方应用程序。在运行不受信任的或第三方应用程序时,安全运行时尤为重要。通过使用 gVisor 或 Kata Containers 的运行时在安全容器中部署这些应用程序,可以降低潜在风险并将其与底层主机系统隔离。此方法有助于保护主机和其他工作负载免受来自不可信代码可的潜在漏洞或恶意活动的影响。
在默认的 runC 运行时中部署自研应用程序。如果企业或组织内部开发了值得信赖的应用程序并且经过了严格的安全审查,可以选择在默认的 runC 运行时中运行。这种方法承认可信应用程序可能不需要安全运行时提供的额外隔离。然而,为这些应用程序实施适当的安全实践(例如容器加固和漏洞扫描)至关重要。
考虑具体需求和环境。是否部署安全容器运行时应基于具体需求、安全要求和风险评估。评估数据敏感性、监管合规性、威胁形势和环境整体安全态势等因素。此外,还应考虑使用安全运行时产生的性能开销和对资源使用的影响,因为与标准运行时相比,它们可能会带来一些额外的开销。
本文翻译自英文文章,译文共包括(一)、(二)两篇:
https://thenewstack.io/container-security-and-the-importance-of-secure-runtimes/