手把手教你在容器服务 TKE 中使用动态准入控制器

在 TKE 中使用动态准入控制器 原理概述

动态准入控制器 Webhook 在访问鉴权过程中可以更改请求对象或完全拒绝该请求,其调用 Webhook 服务的方式使其独立于集群组件,具有非常大的灵活性,可以方便的做很多自定义准入控制,下图为动态准入控制在 API 请求调用链的位置(来源于 Kubernetes 官网):

img

从上图可以看出,动态准入控制过程分为两个阶段:首先执行 Mutating 阶段,可以对到达请求进行修改,然后执行 Validating 阶段来验证到达的请求是否被允许,两个阶段可以单独使用也可以组合使用,本文将在 TKE 中实现一个简单的动态准入控制调用示例。

查看验证插件

在 TKE 现有集群版本中(1.10.5 及以上)已经默认开启了 和 API,如果是更低版本的集群,可以在 Apiserver Pod 中执行 kube-apiserver -h | grep enable-admission-plugins 验证当前集群是否开启,输出插件列表中如果有 MutatingAdmissionWebhook 和 ValidatingAdmissionWebhook 就说明当前集群开启了动态准入的控制器插件,如下图所示:

img

签发证书

为了确保动态准入控制器调用的是可信任的 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 服务端证书密钥。

操作示例

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsffwx.html