各位 Kubernetes 探险家们,早上好!☕
今天我们要聊的是 Kubernetes 王国的安全命脉——API Server 审计与 Admission Controller。这两位可是 Kubernetes 安全界的“双子星”,一个负责事后追查,一个负责事前把关,珠联璧合,守护着我们的集群安全。
别害怕,这听起来好像很厉害的样子,其实就像给你的城堡🏰设置了双重保险,确保任何试图进入的家伙都得经过严格的审查,任何可疑的行为都会被记录在案。
准备好了吗?让我们一起踏上这段安全之旅,揭开这两位“安全卫士”的神秘面纱!
第一站:API Server 审计,Kubernetes 的“黑匣子” 🕵️♂️
想象一下,你的 Kubernetes 集群就像一个繁忙的都市,每天发生着各种各样的事件:Pod 被创建、Deployment 被更新、Service 被暴露…… 如果没有一个靠谱的“监控摄像头”,我们怎么知道谁做了什么,何时做的?
这就是 API Server 审计的作用!它就像一个“黑匣子”,记录着所有对 Kubernetes API Server 的请求,包括谁发起的请求、请求的内容、以及请求的结果。有了这些信息,我们就可以:
- 事后追责: 发生了安全事件?不用慌!翻看审计日志,找到肇事者,让他“吃不了兜着走”。
- 安全分析: 通过分析审计日志,我们可以发现潜在的安全风险,比如异常的用户行为、未授权的访问等等。
- 合规性审计: 满足各种合规性要求,证明你的 Kubernetes 集群是安全可靠的。
那么,如何开启这个“黑匣子”呢?
其实很简单,只需要配置 API Server 的审计策略即可。审计策略定义了哪些事件需要被记录,以及如何记录。
我们可以通过一个 YAML 文件来配置审计策略,就像这样:
apiVersion: audit.k8s.io/v1
kind: Policy
metadata:
name: default
rules:
- level: Metadata
users: ["system:serviceaccount:kube-system:default"]
verbs: ["get", "watch", "list"]
resources:
- groups: [""]
resources: ["pods"]
- level: RequestResponse
verbs: ["create", "update", "patch", "delete"]
resources:
- groups: [""]
resources: ["pods", "services", "deployments"]
- level: RequestResponse
verbs: ["*"]
resources:
- groups: [""]
resources: ["secrets", "configmaps"]
这个策略定义了三个规则:
- 对于
kube-system
命名空间下的default
ServiceAccount,只记录对 Pod 的get
、watch
、list
请求的元数据。 - 对于 Pod、Service、Deployment 的
create
、update
、patch
、delete
请求,记录完整的请求和响应。 - 对于 Secret、ConfigMap 的所有请求,记录完整的请求和响应。
审计级别 (Audit Level):
审计级别决定了记录事件的详细程度。常用的审计级别有:
- None: 不记录任何事件。
- Metadata: 只记录事件的元数据,比如请求者、请求时间、资源类型等等。
- Request: 记录事件的元数据和请求内容。
- RequestResponse: 记录事件的元数据、请求内容和响应内容。
- RequestResponseBody: 记录事件的元数据、请求内容,响应内容,以及请求和响应的内容体。
📝小贴士:
- 审计策略越详细,记录的信息就越多,但也意味着更高的性能开销。所以要根据实际需求选择合适的审计级别。
- 审计日志可以输出到文件、syslog、webhook 等多种目标。选择合适的输出目标,方便后续的分析和处理。
审计日志长什么样?
审计日志通常是 JSON 格式的,包含了事件的各种信息,比如:
{
"kind": "Event",
"apiVersion": "audit.k8s.io/v1",
"metadata": {
"creationTimestamp": "2023-10-27T08:00:00Z"
},
"stage": "ResponseComplete",
"requestReceivedTimestamp": "2023-10-27T07:59:59Z",
"stageTimestamp": "2023-10-27T08:00:00Z",
"verb": "create",
"user": {
"username": "kube-admin",
"groups": [
"system:masters",
"system:authenticated"
]
},
"sourceIPs": [
"10.0.0.1"
],
"objectRef": {
"resource": "pods",
"namespace": "default",
"name": "my-pod"
},
"requestURI": "/api/v1/namespaces/default/pods",
"responseStatus": {
"code": 201,
"status": "Created"
}
}
通过分析这些日志,我们可以了解集群中发生的各种事件,并及时发现潜在的安全风险。
第二站:Admission Controller,Kubernetes 的“安全门卫” 👮♀️
API Server 审计是事后追查,那有没有什么办法可以在事前阻止恶意请求呢?
答案就是:Admission Controller!
Admission Controller 就像 Kubernetes 的“安全门卫”,它会在请求到达 API Server 之前进行拦截,根据预定义的规则对请求进行验证和修改。只有通过了 Admission Controller 的检查,请求才能被 API Server 接受。
Admission Controller 的工作流程:
- 用户发起一个请求,比如创建一个 Pod。
- 请求首先到达 API Server。
- API Server 将请求发送给 Admission Controller。
- Admission Controller 根据预定义的规则对请求进行验证和修改。
- 如果请求通过了检查,Admission Controller 将修改后的请求返回给 API Server。
- API Server 将请求持久化到 etcd 中。
- API Server 将响应返回给用户。
Admission Controller 的类型:
Admission Controller 可以分为两种类型:
- Mutating Admission Controller: 可以修改请求。
- Validating Admission Controller: 只能验证请求,不能修改请求。
Kubernetes 内置了一些 Admission Controller,比如:
- NamespaceLifecycle: 防止删除活跃的命名空间。
- PodSecurityPolicy: 限制 Pod 的安全配置。
- ResourceQuota: 限制命名空间的资源使用。
自定义 Admission Controller:
除了使用 Kubernetes 内置的 Admission Controller,我们还可以自定义 Admission Controller,以满足特定的安全需求。
自定义 Admission Controller 通常使用 Webhook 的方式实现。Webhook Admission Controller 实际上是一个 HTTP 服务,它接收 API Server 发送的 AdmissionReview 请求,并根据自定义的逻辑进行验证和修改,然后将结果返回给 API Server。
举个栗子:限制 Pod 的镜像来源
假设我们只想允许 Pod 使用来自 my-registry.com
的镜像。我们可以创建一个 Validating Admission Webhook 来实现这个功能。
首先,我们需要创建一个 Webhook 服务:
apiVersion: apps/v1
kind: Deployment
metadata:
name: image-validator
spec:
selector:
matchLabels:
app: image-validator
template:
metadata:
labels:
app: image-validator
spec:
containers:
- name: image-validator
image: your-image-validator-image
ports:
- containerPort: 8080
这个 Deployment 创建了一个 Pod,Pod 中运行着我们的 Webhook 服务。
然后,我们需要创建一个 Service 来暴露这个 Webhook 服务:
apiVersion: v1
kind: Service
metadata:
name: image-validator
spec:
selector:
app: image-validator
ports:
- port: 443
targetPort: 8080
这个 Service 将 Pod 的 8080 端口映射到 Service 的 443 端口。注意,这里使用了 443 端口,因为 Admission Webhook 必须使用 HTTPS。
接下来,我们需要创建一个 ValidatingWebhookConfiguration 来告诉 API Server 如何调用我们的 Webhook 服务:
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: image-validator
webhooks:
- name: image-validator.example.com
clientConfig:
service:
name: image-validator
namespace: default
path: "/validate"
caBundle: your-ca-bundle
rules:
- apiGroups: [""]
apiVersions: ["v1"]
operations: ["CREATE", "UPDATE"]
resources: ["pods"]
admissionReviewVersions: ["v1", "v1beta1"]
sideEffects: None
这个 ValidatingWebhookConfiguration 定义了一个 Webhook,它会拦截对 Pod 的 CREATE
和 UPDATE
请求,并将请求发送到 image-validator
Service 的 /validate
路径。
⚠️ 注意:
caBundle
是用于验证 Webhook 服务证书的 CA 证书。你需要将 Webhook 服务的 CA 证书编码成 Base64 字符串,并替换your-ca-bundle
。sideEffects: None
表示 Webhook 服务没有副作用,也就是说,它不会修改任何资源的状态。
最后,我们需要编写 Webhook 服务的代码,来验证 Pod 的镜像来源:
from flask import Flask, request, jsonify
import json
app = Flask(__name__)
@app.route('/validate', methods=['POST'])
def validate():
request_info = request.get_json()
pod = request_info['request']['object']
for container in pod['spec']['containers']:
image = container['image']
if not image.startswith('my-registry.com'):
return jsonify({
'apiVersion': 'admission.k8s.io/v1',
'kind': 'AdmissionReview',
'response': {
'uid': request_info['request']['uid'],
'allowed': False,
'status': {
'reason': f'Image {image} is not from my-registry.com'
}
}
})
return jsonify({
'apiVersion': 'admission.k8s.io/v1',
'kind': 'AdmissionReview',
'response': {
'uid': request_info['request']['uid'],
'allowed': True
}
})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080, debug=True)
这个 Python 代码定义了一个 Flask 应用,它监听 /validate
路径,并接收 AdmissionReview 请求。它会检查 Pod 的所有容器的镜像是否来自 my-registry.com
,如果不是,则返回一个错误,阻止 Pod 的创建或更新。
🎉 大功告成!
现在,任何试图创建或更新使用非 my-registry.com
镜像的 Pod 的请求都会被 Admission Controller 拦截,从而保证了集群的安全。
总结:
API Server 审计和 Admission Controller 是 Kubernetes 安全的两大支柱。API Server 审计负责事后追查,Admission Controller 负责事前把关。通过合理配置和使用它们,我们可以构建一个安全可靠的 Kubernetes 集群。
特性 | API Server 审计 | Admission Controller |
---|---|---|
作用 | 事后追查,记录所有 API 请求 | 事前把关,验证和修改 API 请求 |
工作方式 | 被动记录 | 主动拦截 |
类型 | 无 | Mutating (修改请求), Validating (验证请求) |
使用场景 | 安全事件调查、安全分析、合规性审计 | 权限控制、资源限制、安全策略强制执行 |
优缺点 | 记录详细,但性能开销大;无法阻止恶意请求 | 可以阻止恶意请求,但配置复杂;可能影响集群性能 |
最后的温馨提示:
安全是一个持续的过程,而不是一蹴而就的事情。我们需要不断学习和实践,才能构建一个真正安全的 Kubernetes 集群。
希望今天的分享对你有所帮助!下次再见!👋