在 TKE 中使用动态准入控制器

原理概述

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

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

查看验证插件

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

签发证书

为了确保动态准入控制器调用的是可信任的 Webhook 服务端,必须通过 HTTPS 来调用 Webhook 服务(TLS认证), 所以需要为 Webhook 服务端颁发证书,并且在注册动态准入控制 Webhook 时为 caBundle 字段( ValidatingWebhookConfigurationMutatingAdmissionWebhook 资源清单中的 caBundle 字段)绑定受信任的颁发机构证书(CA)来核验 Webhook 服务端的证书是否可信任, 这里分别介绍两种推荐的颁发证书方法:

注意:当ValidatingWebhookConfigurationMutatingAdmissionWebhook 使用 clientConfig.service 配置时(Webhook 服务在集群内),为服务器端颁发的证书域名必须为 <svc_name>.<svc_namespace>.svc

方法一: 制作自签证书

制作自签证书的方法比较独立,不依赖于 K8s 集群,类似于为一个网站做一个自签证书,有很多工具可以制作自签证书,本示例使用 Openssl 制作自签证书,操作步骤如下所示:

  1. 生成密钥位数为 2048 的 ca.key:

    openssl genrsa -out ca.key 2048
  2. 依据 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
  3. 生成密钥位数为 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
  4. 基于配置文件 csr.conf 生成证书签名请求:

    openssl req -new -key server.key -out server.csr -config csr.conf
  5. 使用 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
  6. 查看 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 服务端代码。

  1. 准备 caBundle 内容

    • 若颁发证书方法是方案一, 使用 base64 编码 ca.crt 生成 caBundle 字段内容:

       cat ca.crt | base64 --wrap=0
      
      
    • 若颁发证书方法是方案二,集群的根证书即为 caBundle 字段内容,可以通过 TKE 集群控制台【基本信息】-> 【集群APIServer信息】Kubeconfig 内容中的clusters.cluster[].certificate-authority-data 字段获取,该字段已经 base64 编码过了,无需再做处理。

  2. 复制生成的 ca.crt (颁发机构证书),server.crt(HTTPS 证书)), server.key(HTTPS 密钥) 到项目主目录:

  3. 修改项目中的 Dockerfile ,添加三个证书文件到容器工作目录:

    然后使用 docker 命令构建 Webhook 服务端镜像:

    docker build -t webserver .
    
    
  4. 部署一个域名为 "weserver.default.svc" 的 Webhook 后端服务,修改适配后的 controller.yaml 如下:

  5. 注册创建类型为 ValidatingWebhookConfiguration 的资源,本示例配置的 Webhook 触发规则是当创建 pods类型,API 版本 "v1" 时触发调用,clientConfig 配置对应上述在集群中创建的的 Webhook 后端服务, caBundle 字段内容为证书颁发方法一获取的ca.crt 内容,修改适配项目中的 admission.yaml 文件如下图:

  6. 注册好后创建一个 Pod 类型, API 版本为 "v1" 的测试资源如下:

  7. 测试代码有打印请求日志, 查看 Webhook 服务端日志可以看到动态准入控制器触发了 webhook 调用,如下图:

  8. 此时查看创建的测试pod 是成功创建的,是因为测试 Webhook 服务端代码写死的 allowed: true,所以是可以创建成功的,如下图:

  9. 为了进一步验证,我们把 "allowed" 改成 "false" ,然后重复上述步骤重新打 Webserver 服务端镜像,并重新部署 controller.yaml 和 admission.yaml 资源,当再次尝试创建 "pods" 资源时请求被动态准入拦截,说明配置的动态准入策略是生效的,如下图所示:

总结

本文主要介绍了动态准入控制器 Webhook 的概念和作用、如何在 TKE 集群中签发动态准入控制器所需的证书,并使用简单示例演示如何配置和使用动态准入 Webhook 功能。

参考

Kubernetes Dynamic Admission Control by Example

Dynamic Admission Control(官网)

【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!

手把手教你在容器服务 TKE 中使用动态准入控制器的更多相关文章

  1. 手把手教你在容器服务 TKE 上使用 LB 直通 Pod

    什么是 LB 直通 Pod ? Kubernetes 官方提供了 NodePort 类型的 Service,即给所有节点开一个相同端口用于暴露这个 Service,大多云上 LoadBalancer ...

  2. 手把手教你使用容器服务 TKE 集群审计排查问题

    概述 有时候,集群资源莫名被删除或修改,有可能是人为误操作,也有可能是某个应用的 bug 或恶意程序调用 apiserver 接口导致,需要找出 "真凶".这时候,我们需要为集群开 ...

  3. 在腾讯云容器服务 TKE 中利用 HPA 实现业务的弹性伸缩

    在 TKE 上利用 HPA 实现业务的弹性伸缩 概述 Kubernetes Pod 水平自动扩缩(Horizontal Pod Autoscaler,以下简称 HPA)可以基于 CPU 利用率.内存利 ...

  4. 腾讯云容器服务 TKE 推出新一代零损耗容器网络

    随着容器技术的发展成熟,越来越多的组件迁移到容器,在技术迁移过程中,数据库,游戏,AI 这些组件对容器网络性能(时延,吞吐,稳定性)提出了更高的要求.为了得到更优的时延和吞吐表现,各大云厂商都在致力于 ...

  5. 容器服务 TKE 存储插件与云硬盘 CBS 最佳实践应用

    引言 随着自研上云的深入,越来越多的有状态服务对于在 TKE 集群中使用云上存储能力的需求也越来越强烈. 目前腾讯云容器服务 TKE(Tencent Kubernetes Engine已支持在 TKE ...

  6. 腾讯云容器服务 TKE 拿下新加坡 MTCS 最高级别安全认证

    近日,腾讯云容器服务 TKE 荣获新加坡 MTCS 最高级安全认证,标志着腾讯云 TKE 在为用户提供可靠.易部署.灵活扩展等基础服务上,已经全面满足了新加坡监管机构以及多个行业客户对服务安全的要求. ...

  7. 容器服务 TKE 上服务暴露的几种方式

    预备知识 1. K8S 上 Service 类型 ClusterIP 通过集群的内部 IP 暴露服务,选择该值,服务只能够在集群内部可以访问,这也是默认的 ServiceType. NodePort ...

  8. 手把手教你如何在Ubuntu系统中安装Pycharm

    前几天带大家一起安装了Ubuntu14.04系统,没来得及上车的伙伴可以戳这篇文章:手把手教你在VMware虚拟机中安装Ubuntu14.04系统.今天小编带大家一起在Ubuntu14.04中安装Py ...

  9. Solr专题(一)手把手教你搭建Solr服务

    一.Solr是什么,能解决什么问题? Solr是一个高性能,采用Java开发,基于Lucene的全文搜索服务器.同时对其进行了扩展,提供了比Lucene更为丰富的查询语言,同时实现了可配置.可扩展并对 ...

随机推荐

  1. 解决github下载速度慢问题

    众所周知,GitHub是一个巨大的开源宝库,以及程序员和编程爱好者的聚集地,包括我之前推荐的诸多优秀的开源项目全部都是位于GitHub上.但是每当我们看到优秀的开源项目,准备去 下(bai)载(pia ...

  2. 实战Git命令(界面操作+命令行)

    先说明下公司的发版步骤,当需要开发一个新的功能,先从master分支中拉出一个自己的分支a(假设分支为a),在a分支开发功能完后,需要切换到dev分支,然后把自己的分支a合到dev分支,部署测试环境让 ...

  3. PostgreSQL WAL日志详解

    wal日志即write ahead log预写式日志,简称wal日志.wal日志可以说是PostgreSQL中十分重要的部分,相当于oracle中的redo日志. 当数据库中数据发生变更时:chang ...

  4. 常用 .gitignore 模板

    前言 每次建项目的时候可以直接复制了,也算是方便自己,以后发现少的会更新 正文 作用 git提交时忽略文件 文件名 .gitignore Python # Byte-compiled / optimi ...

  5. Go语言从入门到放弃(四)

    前言 有段时间没摸Go语言了,最近B站的Go语言泄露挺火的. 还差的很远呐 学无止境 本章主要介绍一些零碎的小知识点 变更记录 # 19.4.30  起笔 # 19.4.30  增加代码打包步骤 正文 ...

  6. 使用OpenCV进行简单的人像分割与合成

    图像合成 实现思路 通过背景建模的方法,对源图像中的动态人物前景进行分割,再将目标图像作为背景,进行合成操作,获得一个可用的合成影像. 实现步骤如下. 使用BackgroundSubtractorMO ...

  7. python模块详解 | filecmp

    简介: filecmp是python内置的一个模块,用于比较文件及文件夹的内容,它是一个轻量级的工具,使用非常简单 两个主要的方法: filecmp.cmp(f1, f2[, shallow]) 比较 ...

  8. 音视频入门-20-BMP、PNG、JPG、GIF静态图生成GIF动态图

    * 音视频入门文章目录 * 静态图 -> 动态图 前面 [18-手动生成一张GIF图片] 和 [19-使用giflib处理GIF图片] 生成的 GIF 每一帧都是一个颜色,平时用到的 GIF 每 ...

  9. 攻防世界 - Crypto(一)

    base64: 根据题目base64可知编码方式,下载附件发现是一个txt文件,把内容用工具解码就彳亍了,即可得到flag, flag: cyberpeace{Welcome_to_new_World ...

  10. ctfhub技能树—RCE—过滤cat

    打开靶机 查看页面信息 构造payload 127.0.0.1 || ls 题目提示过滤了cat,但我还是想试试 果然不行 网页访问没有结果,应该和上题一样被注释了,使用和同样的方法进行解题 利用命令 ...