作者:CODING - 王炜
1. 背景
如果对 Kubernetes 集群安全特别关注,那么我们可能想要实现这些需求:
- 如何实现 Kubernetes 集群的两步验证,除了集群凭据,还需要提供一次性的 Token 校验?
- 如何验证部署的镜像是否安全合规,使得仅允许部署公司内部镜像仓库的 Docker 镜像?
- 如何实现对每一个 Deployment 动态注入 sidecar ,满足特定安全或业务需求?
- 如何实现集群级的 imagePullSecrets ,当创建新的命名空间的时候,自动将 imagePullSecrets 注入到新的命名空间?
本文以实现 Kubernetes 两步验证为例,利用
Kubernetes Admission
动态准入控制,同时借助Serverless
实现一个两步验证
的 Demo,使读者对动态准入控制
和Serverless
有较深入的了解。
1.2 实现效果
Token 两步验证失败,不允许部署
Token 两步验证成功,允许部署
2. 什么是 Admission
Admission 是在用户执行 kubectl 通过认证之后,在将资源持久化到 ETCD 之前的步骤,Kubernetes 为了将这部分逻辑解耦,通过调用 Webhook 的方式来实现用户自定义业务逻辑的补充。而以上过程,都是在用户执行 kuberctl 并等待 API Server 同步返回结果的生命周期内。
上图标注的 ① 和 ② 是 Admission 介入的工作流程,我们会发现有这些特点:
- Admission 工作在集群认证通过之后
- Admission 一共有两种:
Mutating
和Validating
- 这两种具体的实现方式都是以
Webhook
实现的 - Admission 的操作对象可以是当前部署的用户、Yaml 内容等
2.2 Admission Mutating
Mutating
的字面理解是“变异”的意思,真正的含义是,在资源持久化到 ETCD 之前,Mutating
控制器可以修改所部署的资源文件,比如给特定的 POD 动态增加 Labels,动态注入 sidecar
等。 细心的读者会发现,Admission Mutating
在很多产品都被用到,比如 Istio
里面就是使用它来动态的给每一个容器注入 sidecar Envoy
容器来实现流量的劫持和管理。
2.3 Admission Validating
Validating
比较好理解,也就是“验证”,它在 Mutating
之后,我们可以将自定义的验证逻辑放在这个阶段实现。本文我们就是利用它来实现一个简单的两步验证机制。
3. 什么是 Admission Webhook
Admission Webhook
其实就是 Mutating Controllers
和 Validating Controllers
的具体实现方式,也就是说,我们需要给 Kubernetes 集群提供一个外部 Webhook Endpoint,API Server 执行到对应流程时,会调用我们预定义的 Webhook 来实现我们预定义的业务逻辑,通过返回规定的数据结构,来实现对 Yaml 文件的变更或者验证。
4. 动手实践
4.1 集群条件
根据官方文档,先决条件有以下几点:
- Kubernetes 集群版本至少为 v1.16
- 启用了 MutatingAdmissionWebhook 和 ValidatingAdmissionWebhook 控制器
如果不确定,可以通过以下命令查询:
kubectl get pods kube-apiserver -n kube-system -o yaml | grep MutatingAdmissionWebhook,ValidatingAdmissionWebhook
如果你使用的是托管集群,那么请使用以下命令查询:
kubectl api-versions | grep admission
如果出现 admissionregistration.k8s.io/v1beta1
说明集群支持,进行下一步。
4.2 其他条件
- 开通 CODING DevOps
- 克隆代码仓库 admission-webhook-example.git 并推送到自己的 CODING Git 仓库
- 准备一个 腾讯云账户
4.3 部署腾讯 Serverless 服务
登陆 CODING,并在配置 Serverless 身份授权,记录凭据 ID(类似:b68948cb-2ad9-4b67-8a49-ad7ba910ed92),稍后使用
克隆代码仓库
admission-webhook-example
git clone https://e.coding.net/wangweicoding/admission-webhook-example.git
修改根目录下的文件
- 根目录下的 Jenkinsfile,将上一步获取的凭据 ID 替换光标处的凭据 ID