官网:
https://www.notion.so/etaon/ImagePolicyWebhook-6b7d52ff6b474d168688698cea046905#991170999fd84532aa6354ade5ccb0dd
准入控制器是一段代码,它会在请求通过认证和授权之后、对象被持久化之前拦截到达 API 服务器的请求。控制器由下面的列表组成, 并编译进 kube-apiserver 二进制文件,并且只能由集群管理员配置。 在该列表中,有两个特殊的控制器:MutatingAdmissionWebhook 和 ValidatingAdmissionWebhook。 它们根据 API 中的配置,分别执行变更和验证 准入控制 webhook。
准入控制器可以执行 “验证(Validating)” 和/或 “变更(Mutating)” 操作。 变更(mutating)控制器可以修改被其接受的对象;验证(validating)控制器则不行。
准入控制过程分为两个阶段。第一阶段,运行变更准入控制器。第二阶段,运行验证准入控制器。 再次提醒,某些控制器既是变更准入控制器又是验证准入控制器。
如果任何一个阶段的任何控制器拒绝了该请求,则整个请求将立即被拒绝,并向终端用户返回一个错误。
如何启用一个准入控制器?Kubernetes API 服务器的 enable-admission-plugins 标志接受一个用于在集群修改对象之前 调用的(以逗号分隔的)准入控制插件顺序列表。
例如,下面的命令就启用了 NamespaceLifecycle 和 LimitRanger 准入控制插件:
kube-apiserver --enable-admission-plugins=NamespaceLifecycle,LimitRanger ...
说明:
根据你 Kubernetes 集群的部署方式以及 API 服务器的启动方式的不同,你可能需要以不同的方式应用设置。 例如,如果将 API 服务器部署为 systemd 服务,你可能需要修改 systemd 单元文件; 如果以自托管方式部署 Kubernetes,你可能需要修改 API 服务器的清单文件。
Kubernetes API 服务器的 disable-admission-plugins 标志,会将传入的(以逗号分隔的) 准入控制插件列表禁用,即使是默认启用的插件也会被禁用。
kube-apiserver --disable-admission-plugins=PodNodeSelector,AlwaysDeny ...
ImagePolicyWebhookImagePolicyWebhook 准入控制器允许使用一个后端的 webhook 做出准入决策。
配置文件格式ImagePolicyWebhook 使用配置文件来为后端行为设置配置选项。该文件可以是 JSON 或 YAML, 并具有以下格式:
**imagePolicy**: **kubeConfigFile**: /path/to/kubeconfig/for/backend *# 以秒计的时长,控制批准请求的缓存时间* **allowTTL**: 50 *# 以秒计的时长,控制批准请求的缓存时间* **denyTTL**: 50 *# 以毫秒计的时长,控制重试间隔* **retryBackoff**: 500 *# 确定 Webhook 后端失效时的行为* **defaultAllow**: **true**
从文件中引用 ImagePolicyWebhook 的配置文件,并将其提供给 API 服务器命令标志 --admission-control-config-file:
- apiserver.config.k8s.io/v1
**apiVersion**: apiserver.config.k8s.io/v1 **kind**: AdmissionConfiguration **plugins**: - **name**: ImagePolicyWebhook **path**: imagepolicyconfig.yaml **...**
或者,你也可以直接将配置嵌入到文件中:
- apiserver.config.k8s.io/v1
**apiVersion**: apiserver.config.k8s.io/v1
**kind**: AdmissionConfiguration
**plugins**:
- **name**: ImagePolicyWebhook
**configuration**:
**imagePolicy**:
**kubeConfigFile**:
**allowTTL**: 50
**denyTTL**: 50
**retryBackoff**: 500
**defaultAllow**: **true**
ImagePolicyWebhook 的配置文件必须引用 kubeconfig 格式的文件;该文件设置了到后端的连接参数。 要求后端使用 TLS 进行通信。
kubeconfig 文件的 cluster 字段需要指向远端服务,user 字段需要包含已返回的授权者。
*# clusters 指的是远程服务。***clusters**:
- **name**: name-of-remote-imagepolicy-service
**cluster**:
**certificate-authority**: /path/to/ca.pem *# CA 用于验证远程服务***server**: https://images.example.com/policy *# 要查询的远程服务的 URL。必须是 'https' 。# users 指的是 API 服务器的 Webhook 配置。***users**:
- **name**: name-of-api-server
**user**:
**client-certificate**: /path/to/cert.pem *# webhook 准入控制器使用的证书***client-key**: /path/to/key.pem *# 证书匹配的密钥*
案例:
Context
A container image scanner is set up on the cluster, but it’s not yet fully integrated into the cluster’s configuration. When complete, the container image scanner shall scan for and reject the use of vulnerable images.
Task
You have to complete the entire task on the cluster’s master node, where all services and files have been prepared and placed.
Given an incomplete configuration in directory /etc/kubernetes/aa and a functional container
image scanner with HTTPS endpoint http://192.168.26.60:1323/image_policy:
- Enable the necessary plugins to create an image policy
- validate the control configuration and change it to an implicit deny
- Edit the configuration to point t the provided HTTPS endpoint correctly.
Finally , test if the configuration is working by trying to deploy the vulnerable resource
/cks/1/web1.yaml
You can find the container image scanner’s log file at /var/loglimagepolicyiacme.log
分析:
-
需要集群启动 ImagePolicyWebhook来container image scanner shall scan和reject the use of vulnerable images即必须指定image版本,不允许latest
-
config file题目已给(/etc/kubernetes/aa 里),填写Kube-apiserver参数记录,config file的文件夹是否已经mount到Pod了,需要检查)
-
修改ImagePolicyWebhook默认策略为默认拒绝, 再Kubeconfig中配置给定的Https Server的地址
-
答案
- 启动ImagePolicyWebhook准入控制器
#root@master01:~# vim /etc/kubernetes/manifests/kube-apiserver.yaml --admission-control-config-file=/etc/kubernetes/aa/admission_configuration.json #具体是json还是yaml文件看文件夹 --enable-admission-plugins=ImagePolicyWebhook
- 检查/etc/kubernetes/manifests/kube-apiserver.yaml,是否mount了config file的文件夹
... volumeMounts: - mountPath: /etc/kubernetes/aa name: aa volumes: - hostPath: path: /etc/kubernetes/aa name: aa
- 编辑/etc/kubernetes/aa/admission_configuration.json或yaml
{ "imagePolicy": { **"kubeConfigFile": "/etc/kubernetes/aa/kubeconfig.yaml", # 文件夹里的kubeconfig.yaml** "allowTTL": 50, "denyTTL": 50, "retryBackoff": 500, **"defaultAllow": false #改为false** } }**plugins**: - **name**: ImagePolicyWebhook **configuration**: **imagePolicy**: **kubeConfigFile: /etc/kubernetes/aa/kubeconfig.yaml** **allowTTL**: 50 **denyTTL**: 50 **retryBackoff**: 500 **defaultAllow: false #改为false**- 编辑/etc/kubernetes/aa/kubeconfig.yaml,添加 webhook server 地址:
apiVersion: v1 kind: Config clusters: - cluster: certificate-authority: /etc/kubernetes/aa/webhook.pem **server: https://192.168.26.60:1323/image_policy #添加webhook server地址** name: bouncer_webhook contexts: - context: cluster: bouncer_webhook user: api-server name: bouncer_validator current-context: bouncer_validator preferences: {} users: - name: api-server user: client-certificate: /etc/kubernetes/aa/apiserver-client.pem client-key: /etc/kubernetes/aa/apiserver-clientkey.pem- 重启kubelet并应用web1.yaml
systemctl restart kubelet kubectl apply -f /cks/1/web1.yaml
测试效果:
kubectl run pod1 --image=nginx Error from server (Forbidden): pods "pod1" is forbidden: image policy webhook backend denied one or more images: Images using latest tag are not allowed



