一 Admission Webhook概览
Kubernetes Admission Webhook机制作为API Server的扩展机制,可以用来灵活地在对API Server对象进行写操作时实现对象统一修改和检验等功能,详细的功能介绍可以参见官方文档。当客户端连接API Server更改对象时,会经过下图所示的过程。
总得来说,有两种Admission Webhook:
- Mutating Admission Webhook和
- Validating Admission Webhook。
在对象持久化进etcd之前,Mutating Admission Webhook被API Server首先调用用来对操作对象进行修改,然后再调用Validating Admission Webhook对对象进行合格性检查,如果检查通过则写入etcd,否则拒绝更新操作。具体来说就是返回HTTP 422 Unprocessable Entity
响应码。
1.1 使用的注意事项
- 实现Webhook的服务(就是个HTTP接口)必须提供HTTPS接口
- API Server必须信任HTTPS的证书,可以让自己的Webhook使用由Kubernetes签发的证书来保证API Server信任证书
- 配置Webhook Configuration时,可以指定拦截的API对象类型已经namespace等,如:
apiVersion: admissionregistration.k8s.io/v1beta1
kind: MutatingWebhookConfiguration
metadata:
name: prometheus-operator-rulesvalidation
webhooks:
- clientConfig:
service:
name: prometheus-operator
namespace: openshift-metrics
path: /admission-prometheusrules/mutate
port: 8081
failurePolicy: Fail
name: prometheusrulemutate.monitoring.coreos.com
namespaceSelector:
matchExpressions:
- key: prometheus
operator: In
values: ["infra", "business"] 命名空间
rules:
- apiGroups:
- monitoring.coreos.com
apiVersions:
- '*'
operations:
- CREATE
- UPDATE 拦截操作
resources:
- prometheusrules 对象类型
二 prometheus-operator简介
prometheus-operator支持用户通过以下Custom Resource方便快键地在K8S集群中快速创建监控和告警机制。
- 通过Custom Resource: Prometheus和AlertManager的实例用于监控和告警
- 通过PodMonitor,ServiceMonitor快速创建Prometheus采集数据的来源
- 通过PrometheusRule对象快速创建出Prometheus的Recording和Alerting规则
更多的介绍可以参见prometheus-operator.
Prometheus-operator使用了Kubernetes的三大设计模式
- Operator模式扩展了上面列出的多种自定义对象(Custom Resource Definition机制),并根据这些对象定义快速创建监控和告警体系
- Controller模式:Operator里的Controller通过Watch API Server中的对象变化做相应的配置更改
- Admission Webhook: 通过Webhook机制来对写入的PrometheusRule对象进行语法检验
prometheus-operator的工作机制如下:
Prometheus-operator生成的Prometheus实例的POD会挂载一个规则配置的ConfigMap,所有PrometheusRule对象会被operator转换成Prometheus规则后写进这个ConfigMap,然后operator会通知Prometheus动态去加载新的配置(其中的具体细节,比如通过rules-configmap-reloader container来完成加载等等不再展开)。(上图顶部的Prometheus Config其实是一个ConfigMap)
2.1 PrometheusRule
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
labels:
prometheus: app
role: alert-rules
name: admission-webhook-test
spec:
groups:
- name: admission-webhook-test
rules:
- alert: rule-id-1
annotations:
description: '{{ $value }}% of {{ $labels.job }} targets are down.'
summary: Targets are down
expr: up{test="nonexisting"} < 2
for: 24s
labels:
level: P3
2.2 Config Map
上面的规则被挂载为ConfigMap中一个key/value对。
2.3 Prometheus加载日志
如果在Prometheus中出现上面的日志,代表新的配置已经被加载成功。
三 Admission Webhook在prometheus-operator中的使用
编写PrometheusRule对象时,不可避免有时会有一些语法错误。如果编写的规则有错,kubectl create -f rules.yml
会报告成功,但实际上在Prometheus加载ConfigMap时会报错,但需要到后台日志或者Prometheus的rules菜单中查看才能发现新的错误规则迟迟未被加载。
比如下面这个规则,description的templating变量在.号前多了个空格,规则可以成功写入Kubernetes API Server,
但是Prometheus后台加载新规则时,会报以下错误
这种更新API Server Custom Resource对象成功但实际需要去关注后台日志才能知道是否最终成功的方式对管理人员非常不方便,所以这里prometheus-operator自版本0.31后引入了通过Validating AdmissionWebhook机制来在更新PrometheusRule对象时同步进行规则检验,从而保证写入API Server的对象肯定能被Prometheus正确加载。
可以通过创建以下对象启用Admission Webhook,
apiVersion: admissionregistration.k8s.io/v1beta1
kind: ValidatingWebhookConfiguration
metadata:
name: prometheus-operator-rulesvalidation
webhooks:
- clientConfig:
service:
name: prometheus-operator
namespace: metrics
path: /admission-prometheusrules/validate
failurePolicy: Fail
name: prometheusrulevalidate.monitoring.coreos.com
namespaceSelector:
matchExpressions:
- key: prometheus
operator: In
values: ["infra", "business"]
rules:
- apiGroups:
- monitoring.coreos.com
apiVersions:
- '*'
operations:
- CREATE
- UPDATE
resources:
- prometheusrules
apiVersion: admissionregistration.k8s.io/v1beta1
kind: MutatingWebhookConfiguration
metadata:
name: prometheus-operator-rulesvalidation
webhooks:
- clientConfig:
service:
name: prometheus-operator
namespace: metrics
path: /admission-prometheusrules/mutate
port: 8081
failurePolicy: Fail
name: prometheusrulemutate.monitoring.coreos.com
namespaceSelector:
matchExpressions:
- key: prometheus
operator: In
values: ["infra", "business"]
rules:
- apiGroups:
- monitoring.coreos.com
apiVersions:
- '*'
operations:
- CREATE
- UPDATE
resources:
- prometheusrules
其中Mutating WebHook是在验证通过的PrometheusRule对象上加入验证通过的annotation,
加入以上WebHook后,如果一旦插入的规则有误,则会收到API Server的以下422响应。
< HTTP/2 422
< cache-control: no-store
< content-type: application/json
< content-length: 490
< date: Sat, 21 Dec 2019 02:10:11 GMT
<
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {
},
"status": "Failure",
"message": "admission webhook \"prometheusrulemutate.monitoring.coreos.com\" denied the request: Rules are not valid",
"reason": "Invalid",
"details": {
"name": "prometheusrules",
"causes": [
{
"message": "group \"admission-webhook-test\", rule 0, \"rule-id-1\": msg=template: __alert_rule-id-1:1: unexpected \u003c.\u003e in operand"
}
]
},
"code": 422
}
而这些Webhook都是回调prometheus-operator的以下HTTP接口
/admission-prometheusrules/validate
/admission-prometheusrules/mutate
这些接口的实现都比较简单,见源码
以上即为Admission Webhook这种设计模式在prometheus-operator中的使用方式。