原理概述
动静准入控制器 Webhook 在拜访鉴权过程中能够更改申请对象或齐全回绝该申请,其调用 Webhook 服务的形式使其独立于集群组件,具备十分大的灵活性,能够不便的做很多自定义准入管制,下图为动静准入管制在 API 申请调用链的地位(来源于 Kubernetes 官网):
从上图能够看出,动静准入管制过程分为两个阶段:首先执行 Mutating 阶段,能够对达到申请进行批改,而后执行 Validating 阶段来验证达到的申请是否被容许,两个阶段能够独自应用也能够组合应用,本文将在 TKE 中实现一个简略的动静准入管制调用示例。
查看验证插件
在 TKE 现有集群版本中(1.10.5 及以上)曾经默认开启了 validating admission webhook 和 mutating admission webhook API,如果是更低版本的集群,能够在 Apiserver Pod 中执行 kube-apiserver -h | grep enable-admission-plugins
验证以后集群是否开启,输入插件列表中如果有 MutatingAdmissionWebhook
和 ValidatingAdmissionWebhook
就阐明以后集群开启了动静准入的控制器插件,如下图所示:
签发证书
为了确保动静准入控制器调用的是可信赖的 Webhook 服务端,必须通过 HTTPS 来调用 Webhook 服务(TLS 认证),所以须要为 Webhook 服务端颁发证书,并且在注册动静准入管制 Webhook 时为 caBundle
字段(ValidatingWebhookConfiguration
和 MutatingAdmissionWebhook
资源清单中的 caBundle
字段)绑定受信赖的颁发机构证书(CA)来核验 Webhook 服务端的证书是否可信赖,这里别离介绍两种举荐的颁发证书办法:
留神:当
ValidatingWebhookConfiguration
和MutatingAdmissionWebhook
应用clientConfig.service
配置时(Webhook 服务在集群内),为服务器端颁发的证书域名必须为<svc_name>.<svc_namespace>.svc
。
办法一:制作自签证书
制作自签证书的办法比拟独立,不依赖于 K8s 集群,相似于为一个网站做一个自签证书,有很多工具能够制作自签证书,本示例应用 Openssl 制作自签证书,操作步骤如下所示:
-
生成密钥位数为 2048 的 ca.key:
openssl genrsa -out ca.key 2048
-
根据 ca.key 生成 ca.crt,”webserver.default.svc” 为 Webhook 服务端在集群中的域名,应用
-days
参数来设置证书无效工夫:openssl req -x509 -new -nodes -key ca.key -subj "/CN=webserver.default.svc" -days 10000 -out ca.crt
-
生成密钥位数为 2048 的 server.key:
openssl genrsa -out server.key 2048
i. 创立用于生成证书签名申请(CSR)的配置文件 csr.conf 示例如下:
[req] default_bits = 2048 prompt = no default_md = sha256 distinguished_name = dn [dn] C = cn ST = shaanxi L = xi'an O = default OU = websever CN = webserver.default.svc [v3_ext] authorityKeyIdentifier=keyid,issuer:always basicConstraints=CA:FALSE keyUsage=keyEncipherment,dataEncipherment extendedKeyUsage=serverAuth,clientAuth
-
基于配置文件 csr.conf 生成证书签名申请:
openssl req -new -key server.key -out server.csr -config csr.conf
-
应用 ca.key、ca.crt 和 server.csr 颁发生成服务器证书(x509 签名):
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \ -CAcreateserial -out server.crt -days 10000 \ -extensions v3_ext -extfile csr.conf
-
查看 Webhook server 端证书:
openssl x509 -noout -text -in ./server.crt
其中,生成的证书、密钥文件阐明如下:
ca.crt 为颁发机构证书,ca.key 为颁发机构证书密钥,用于服务端证书颁发。
server.crt 为 颁发的服务端证书,server.key 为颁发的服务端证书密钥.
办法二:应用 K8S CSR API 签发
除了应用计划一加密工具制作自签证书,还能够应用 k8s 的证书颁发机构零碎来下发证书,执行上面脚本可应用 K8s 集群根证书和根密钥签发一个可信赖的证书用户,须要留神的是用户名应该为 Webhook 服务在集群中的域名:
USERNAME='webserver.default.svc' # 设置须要创立的用户名为 Webhook 服务在集群中的域名
# 应用 Openssl 生成自签证书 key
openssl genrsa -out ${USERNAME}.key 2048
# 应用 Openssl 生成自签证书 CSR 文件, CN 代表用户名,O 代表组名
openssl req -new -key ${USERNAME}.key -out ${USERNAME}.csr -subj "/CN=${USERNAME}/O=${USERNAME}"
# 创立 Kubernetes 证书签名申请(CSR)cat <<EOF | kubectl apply -f -
apiVersion: certificates.k8s.io/v1beta1
kind: CertificateSigningRequest
metadata:
name: ${USERNAME}
spec:
request: $(cat ${USERNAME}.csr | base64 | tr -d '\n')
usages:
- digital signature
- key encipherment
- server auth
EOF
# 证书审批容许信赖
kubectl certificate approve ${USERNAME}
# 获取自签证书 CRT
kubectl get csr ${USERNAME} -o jsonpath={.status.certificate} > ${USERNAME}.crt
其中,${USERNAME}
.crt 为服务端证书,${USERNAME}
.key 为 Webhook 服务端证书密钥。
操作示例
上面将应用 ValidatingWebhookConfiguration
资源在 TKE 中实现一个动静准入 Webhook 调用示例,本示例代码可在 示例代码 中获取(为了确保可拜访性,示例代码 Fork 自 原代码库,作者实现了一个简略的动静准入 Webhook 申请和响应的接口,具体接口格局请参考 Webhook 申请和响应。为了不便,我将应用它作为咱们的 Webhook 服务端代码。
-
筹备
caBundle
内容-
若颁发证书办法是计划一, 应用
base64
编码 ca.crt 生成caBundle
字段内容:cat ca.crt | base64 --wrap=0
- 若颁发证书办法是计划二,集群的根证书即为
caBundle
字段内容,能够通过 TKE 集群控制台【根本信息】->【集群 APIServer 信息】Kubeconfig 内容中的clusters.cluster[].certificate-authority-data
字段获取,该字段曾经base64
编码过了,无需再做解决。
-
- 复制生成的 ca.crt(颁发机构证书),server.crt(HTTPS 证书 )), server.key(HTTPS 密钥)到我的项目主目录:
-
批改我的项目中的 Dockerfile,增加三个证书文件到容器工作目录:
而后应用 docker 命令构建 Webhook 服务端镜像:
docker build -t webserver .
- 部署一个域名为 “weserver.default.svc” 的 Webhook 后端服务,批改适配后的 controller.yaml 如下:
- 注册创立类型为
ValidatingWebhookConfiguration
的资源,本示例配置的 Webhook 触发规定是当创立pods
类型,API 版本 “v1” 时触发调用,clientConfig
配置对应上述在集群中创立的的 Webhook 后端服务,caBundle
字段内容为证书颁发办法一获取的 ca.crt 内容,批改适配我的项目中的 admission.yaml 文件如下图: - 注册好后创立一个 Pod 类型,API 版本为 “v1” 的测试资源如下:
- 测试代码有打印申请日志,查看 Webhook 服务端日志能够看到动静准入控制器触发了 webhook 调用,如下图:
- 此时查看创立的测试 pod 是胜利创立的,是因为测试 Webhook 服务端代码写死的
allowed: true
,所以是能够创立胜利的,如下图: - 为了进一步验证,咱们把 “allowed” 改成 “false”,而后反复上述步骤从新打 Webserver 服务端镜像,并重新部署 controller.yaml 和 admission.yaml 资源,当再次尝试创立 “pods” 资源时申请被动静准入拦挡,阐明配置的动静准入策略是失效的,如下图所示:
总结
本文次要介绍了动静准入控制器 Webhook 的概念和作用、如何在 TKE 集群中签发动静准入控制器所需的证书,并应用简略示例演示如何配置和应用动静准入 Webhook 性能。
参考
Kubernetes Dynamic Admission Control by Example
Dynamic Admission Control(官网)
【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!