客座文章作者:Robert Brennan,Fairwinds 开源软件总监。文章最初在 Fairwinds 的博客上发表。
Kubernetes 是一个非常强大的软件部署平台。它提供的灵活性级别可以容纳几乎任何用例,不管它有多独特。这就是 Kubernetes 被一半以上的财富 500 强公司采用的原因。根据 Dimensional Research 和 VMware 的一项研究,“State of Kubernetes 2020 Report[1]”,K8s 的使用率从 2018 年的 27%大幅飙升至 2020 年的 48%。
但与所有工具一样,在力量和安全之间有一个自然的权衡。有数百万种方法可以配置 Kubernetes 及其运行的工作负载,但其中 99%都是危险的。很容易出现安全性、效率或可靠性方面的问题——通常只是因为忘记在 YAML 配置中指定特定的字段。
为了解决这个问题,社区提出了一组配置 Kubernetes 工作负载的 Kubernetes 最佳实践。这些都是你应该一直遵循的指导方针,除非你有很好的理由不去遵循。Fairwinds 的 Polaris 项目[2]就是为了帮助定义和实施这些最佳实践而诞生的。
下面是一个 Kubernetes Deployment 的例子,直接摘自 Polaris 文档:
YAML
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
你能看出哪里出了问题吗?可能不会,除非你非常熟悉 Kubernetes 的配置。但仍有几个未指明的字段可能导致严重的问题。
首先,一定要告诉 Kubernetes 你的应用程序预期将使用多少内存和 CPU。这允许 Kubernetes 有效地将你的工作负载打包到将运行它们的底层节点上,并为它提供指导,以确定应用程序何时行为不正常(例如,由于内存泄漏)。
一个更好的容器规范应该是这样的:
YAML
containers:
- name: nginx
image: nginx:1.14.2
resources:
requests:
memory: 512MB
cpu: 500m
limits:
memory: 1GB
cpu: 1000m
上面的例子也缺少 Liveness 和 Readiness 探针。这些设置告诉 Kubernetes 如何检查你的应用程序是否健康,是否可以提供流量。如果没有 Liveness Probe,Kubernetes 将无法在你的应用程序冻结时自愈;如果没有 Readiness Probe,它可能会把流量导向还没有完全就绪的 pod。
Liveness 和 Readiness 探针需要一些特定于应用程序的知识,但通常轮询特定的 HTTP 端点或运行 Unix 命令来测试应用程序是否正确响应。例如:
YAML
containers:
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
readinessProbe:
httpGet:
path: /healthz
port: 8080
许多 Kubernetes 的工作负载设置“默认情况下是不安全的”——它们错误的做法是授予你的应用程序权限去做它可能需要或不需要的事情。例如,默认情况下,每个容器都将安装一个可写的根文件系统,这可以使攻击者能够替换系统二进制文件或修改配置。
更安全的容器配置应该是这样的:
YAML
containers:
- name: nginx
image: nginx:1.14.2
securityContext:
allowPrivilegeEscalation: false
privileged: false
readOnlyRootFilesystem: true
runAsNonRoot: true
capabilities:
drop:
- ALL
Polaris 会检查上面所有的问题和更多的问题。它有 24 个内置检查(截至 2021 年 5 月)。随着用户提交反馈和社区学习新的更好的配置工作负载的方法,检查不断被添加到我们的库中。
我们的每个检查都在 JSON Schema 中定义——每次运行 kubectl 来验证添加到集群中的资源时,Kubernetes 本身都使用相同的模式语言。
最简单的检查只需要几行配置:
YAML
successMessage: Host network is not configured
failureMessage: Host network should not be configured
category: Security
target: Pod
schema:
'$schema': http://json-schema.org/draft-07/schema
type: object
properties:
hostNetwork:
not:
const: true
但我们也可以利用 JSON 模式和 Go 模板的全部功能来创建一些相当复杂的检查。你可以查看Polaris 文档[3],了解更多关于如何编写自己的自定义 Polaris 检查的信息,如果你的组织有自己的内部策略和想要实施的最佳实践,这将非常有用。
一旦你设置好你的 Polaris 配置(或者你对我们提供的默认配置很满意),Polaris 可以在三种不同的模式下运行:作为一个仪表盘,显示你的集群中哪些资源需要关注;作为一个准入控制器,阻止有问题的资源进入集群;或者在 CI/CD 中,在基础结构作为代码检入之前检查。
Kubernetes 是一个非常强大的平台,但是强大的力量带来了巨大的责任。在部署到 Kubernetes 时,确保遵循最佳实践是很重要的。如果你忽略了验证你的配置,可能会导致安全漏洞、生产中断或云成本超支。
将 Polaris 添加到你的工作流程中——无论是在 CI/CD、准入控制,或只是一个被动的仪表板——可以帮助你充满信心地在这些危险的水域导航。如果你想利用 Polaris 在集群的舰队,或把它和其他一些伟大的 Kubernetes 审计工具——如Trivy[4]扫描容器, Goldilocks[5]精简内存和 CPU 设置——来看看Fairwinds Insights[6],一个在 Kubernetes 环境审核和执行政策的平台。
因此,无论你是经验丰富的 Kubernetes 专家,还是你只是在构建你的第一个集群,都要确保有一些防护措施!Fairwinds 的 Polaris 和 Insights 便是一个很好的起点。
[1]
State of Kubernetes 2020 Report: https://k8s.vmware.com/state-of-kubernetes-2020/
[2]
Fairwinds 的 Polaris 项目: https://github.com/FairwindsOps/polaris
[3]
Polaris 文档: https://polaris.docs.fairwinds.com/customization/custom-checks/
[4]
Trivy: https://github.com/aquasecurity/trivy
[5]
Goldilocks: https://github.com/FairwindsOps/goldilocks/
[6]
Fairwinds Insights: https://www.fairwinds.com/insights