[TOC]
### **背景简介**
前面我们学习了K8S的认证与授权机制,当客户端向APIserver发起API请示的时候,需要被认证与授权,这两个步骤通过,该请示才能正常返回。那为什么还要准入控制机制呢?
使用过服务网格Istio的同学都知道,当我们创建一个Pod时,K8S最终会往这个Pod中注入一个SideCar容器(也就是说,这个Pod的yaml文件被修改了,增加了一个Container)。那么问题来了,这个SideCar容器是如何被注入的呢(或者说,这个Pod的yaml文件是如何被修改的呢)?
### **什么是准入控制器**
首先,我们先看看 Kubernetes 官方文档中关于`准入控制器`的定义
> An admission controller is a piece of code that intercepts requests to the Kubernetes API server prior to persistence of the object, but after the request is authenticated and authorized. \[…\] Admission controllers may be “validating”, “mutating”, or both. Mutating controllers may modify the objects they admit; validating controllers may not. \[…\] If any of the controllers in either phase reject the request, the entire request is rejected immediately and an error is returned to the end-user.
大概意思就是说`准入控制器`是在对象持久化之前用于对 Kubernetes API Server 的请求进行拦截的代码段,在请求经过身份验证和授权之后放行通过。准入控制器可能正在`validating`、`mutating`或者都在执行,Mutating 控制器可以修改他们的处理的资源对象,Validating 控制器不会,如果任何一个阶段中的任何控制器拒绝了请求,则会立即拒绝整个请求,并将错误返回给最终的用户。
流程如下:
![](https://img.kancloud.cn/2f/c1/2fc108d002c6d68dca927500198a0d0c_1492x655.png)
当client发送一个创建Pod的请求给Apiserver,Apiserver检查自己的web-hook链是否有注册admission-controller,如果有则把这个请求转发给它。然后admission-controller会对Pod的Yaml进行处理(验证或修改),然后返回结果给Apiserver,Apiserver根据返回结果,判断是否需要将这个Pod对象持久化,最后Apiserver再返回结果给client。
### **如何开启准入控制器**
kube-apiserver提供了两个启动参数:
```
--enable-admission-plugins NamespaceLifecycle,LimitRanger,...
--disable-admission-plugins xxx,xxx,...
```
第一参数用来指定开启哪些控制器,第二个参数用来指定关闭哪些控制器。这个链接[https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#what-does-each-admission-controller-do](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#what-does-each-admission-controller-do)可以看到有哪些准入控制器。
### **静态控制器与动态控制器**
静态控制器的代码内置在K8S当中的,比如ServiceAccount、LimitRanger等,它们的行为是定义好的。所以如果我们要定义自己的控制器行为,就得用到动态控制器。
在 Kubernetes apiserver 中包含两个特殊的准入控制器:`MutatingAdmissionWebhook`和`ValidatingAdmissionWebhook`。这两个控制器将发送准入请求到外部的 HTTP(HTTPS) 回调服务并接收一个准入响应。
总的来说,步骤如下:
* 检查集群中是否启用了 admission webhook 控制器,并根据需要进行配置。
* 编写处理准入请求的 HTTP 回调,回调可以是一个部署在集群中的简单 HTTP 服务
* 通过`MutatingWebhookConfiguration`和`ValidatingWebhookConfiguration`资源配置 admission webhook
这两种类型的 admission webhook 之间的区别是非常明显的:validating webhooks 可以拒绝请求,但是它们却不能修改在准入请求中获取的对象,而 mutating webhooks 可以在返回准入响应之前通过创建补丁来修改对象,如果 webhook 拒绝了一个请求,则会向最终用户返回错误。
现在非常火热的的[Service Mesh](https://www.qikqiak.com/post/what-is-service-mesh/)应用`istio`就是通过 mutating webhooks 来自动将`Envoy`这个 sidecar 容器注入到 Pod 中去的:[https://istio.io/docs/setup/kubernetes/sidecar-injection/](https://istio.io/docs/setup/kubernetes/sidecar-injection/)
### **FAQ**
### **参考**
* https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/
* https://kubernetes.io/blog/2019/03/21/a-guide-to-kubernetes-admission-controllers/
* https://www.qikqiak.com/post/k8s-admission-webhook/
- 常用命令
- 安装
- 安装Kubeadm
- 安装单Master集群
- 安装高可用集群(手动分发证书)
- 安装高可用集群(自动分发证书)
- 启动参数解析
- certificate-key
- ETCD相关参数
- Kubernetes端口汇总
- 安装IPv4-IPv6双栈集群
- 下载二进制文件
- 使用Kata容器
- 快速安装shell脚本
- 存储
- 实践
- Ceph-RBD实践
- CephFS实践
- 对象存储
- 阿里云CSI
- CSI
- 安全
- 认证与授权
- 认证
- 认证-实践
- 授权
- ServiceAccount
- NodeAuthorizor
- TLS bootstrapping
- Kubelet的认证
- 准入控制
- 准入控制示例
- Pod安全上下文
- Selinux-Seccomp-Capabilities
- 给容器配置安全上下文
- PodSecurityPolicy
- K8S-1.8手动开启认证与授权
- Helm
- Helm命令
- Chart
- 快速入门
- 内置对象
- 模板函数与管道
- 模板函数列表
- 流程控制
- Chart依赖
- Repository
- 开源的Chart包
- CRD
- CRD入门
- 工作负载
- Pod
- Pod的重启策略
- Container
- 探针
- 工作负载的状态
- 有状态服务
- 网络插件
- Multus
- Calico+Flannel
- 容器网络限速
- 自研网络插件
- 设计文档
- Cilium
- 安装Cilium
- Calico
- Calico-FAQ
- IPAM
- Whereabouts
- 控制平面与Pod网络分开
- 重新编译
- 编译kubeadm
- 编译kubeadm-1.23
- 资源预留
- 资源预留简介
- imagefs与nodefs
- 资源预留 vs 驱逐 vs OOM
- 负载均衡
- 灰度与蓝绿
- Ingress的TLS
- 多个NginxIngressController实例
- Service的会话亲和
- CNI实践
- CNI规范
- 使用cnitool模拟调用
- CNI快速入门
- 性能测试
- 性能测试简介
- 制作kubemark镜像
- 使用clusterloader2进行性能测试
- 编译clusterloader2二进制文件
- 搭建性能测试环境
- 运行density测试
- 运行load测试
- 参数调优
- Measurement
- TestMetrics
- EtcdMetrics
- SLOMeasurement
- PrometheusMeasurement
- APIResponsivenessPrometheus
- PodStartupLatency
- FAQ
- 调度
- 亲和性与反亲和性
- GPU
- HPA
- 命名规范
- 可信云认证
- 磁盘限速
- Virtual-kubelet
- VK思路整理
- Kubebuilder
- FAQ
- 阿里云日志服务SLS