1.知识准备

1.Webhook 是一种用于接收准入请求并对其进行处理的 HTTP 回调机制

2.Webhook 接收来自apiserver的回调,对回调资源做一些校验、注入、修改元数据等工作

3.来一张图片

2.环境准备

组件 版本
OS CentOS Linux release 7.6.1810 (Core)
docker 18.09.7
k8s v1.15.2
golang go1.16.9 darwin/amd64
ip hostname
10.248.33.220 k8s-master

3.部署

下载代码

3.1 创建相关证书

|># sh webhook-create-signed-cert.sh
creating certs in tmpdir ./webhook-certs
Generating RSA private key, 2048 bit long modulus
..................................................+++
.................+++
e is 65537 (0x10001)
certificatesigningrequest.certificates.k8s.io/wilsonchai-webhook-svc.default created
NAME AGE REQUESTOR CONDITION
wilsonchai-webhook-svc.default 0s kubernetes-admin Pending
certificatesigningrequest.certificates.k8s.io/wilsonchai-webhook-svc.default approved
secret/wilsonchai-webhook-certs created

3.2 创建权限

|># kubectl apply -f yaml/rbac.yaml
serviceaccount/wilsonchai-webhook-sa changed
clusterrole.rbac.authorization.k8s.io/wilsonchai-webhook-cr changed
clusterrolebinding.rbac.authorization.k8s.io/wilsonchai-webhook-crb changed

3.3 创建 mutetingwebhookconfiguration

|># cat yaml/mutatingwebhookconfiguration.yaml | sh webhook-patch-ca-bundle.sh | kubectl apply -f -
mutatingwebhookconfiguration.admissionregistration.k8s.io/wilsonchai-webhook-example-cfg created
|># kubectl get mutatingwebhookconfiguration
NAME CREATED AT
wilsonchai-webhook-example-cfg 2021-11-08T03:34:39Z

3.4 namespace 打 label

kubectl label namespace default wilsonchai-webhook=enabled

3.5编译代码并且上传镜像

|># sh build.sh 0.0.1
go: downloading github.com/golang/glog v1.0.0
go: downloading k8s.io/apimachinery v0.22.3
go: downloading github.com/unrolled/secure v1.0.9
go: downloading k8s.io/api v0.22.3
go: downloading github.com/gin-gonic/gin v1.7.4
go: downloading golang.org/x/sys v0.0.0-20210616094352-59db8d763f22
go: downloading github.com/golang/protobuf v1.5.2
go: downloading github.com/go-playground/validator/v10 v10.4.1
go: downloading google.golang.org/protobuf v1.26.0
go: downloading github.com/gogo/protobuf v1.3.2
go: downloading k8s.io/klog/v2 v2.9.0
go: downloading github.com/google/gofuzz v1.1.0
go: downloading github.com/go-logr/logr v0.4.0
go: downloading sigs.k8s.io/structured-merge-diff/v4 v4.1.2
go: downloading github.com/json-iterator/go v1.1.11
go: downloading golang.org/x/net v0.0.0-20210520170846-37e1c6afe023
go: downloading github.com/google/go-cmp v0.5.5
Sending build context to Docker daemon 22.04MB
Step 1/3 : FROM alpine:latest
---> 389fef711851
Step 2/3 : Add wilsonchai-webhook /wilsonchai-webhook
---> 05381b24d25c
Step 3/3 : ENTRYPOINT ["./wilsonchai-webhook"]
---> Running in c36e1e7a0bfb
Removing intermediate container c36e1e7a0bfb
---> c4a4c7042625
Successfully built c4a4c7042625
Successfully tagged registry.cn-beijing.aliyuncs.com/wilsonchai/mutating-webhook:0.0.1
The push refers to repository [registry.cn-beijing.aliyuncs.com/wilsonchai/mutating-webhook]
85e0257311fe: Pushed
777b2c648970: Pushed
0.0.1: digest: sha256:6750fe64823810caa0ad7551a61ba4b4e6ee0ccd40ab93a76b6a1fb8bcdc5bee size: 740

3.6部署镜像

|># kubectl apply -f yaml/deploy.yaml
deployment.apps/wilsonchai-webhook-deployment created
service/wilsonchai-webhook-svc created
|># kubectl get pod | grep wilsonchai-webhook
wilsonchai-webhook-deployment-8444c7d8dd-89qwp 1/1 Running 0 19s

至此,整个部署完成,是不是非常简单,现在我们来测试一下是否能够正常工作

4.测试

4.1 先打开一个shell 1,监控wilsonchai-webhook的日志输出

|># kubectl logs -f wilsonchai-webhook-deployment-8444c7d8dd-89qwp
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached. [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode) [GIN-debug] POST /mutate --> main.WebhookCallback (4 handlers)
[GIN-debug] Listening and serving HTTPS on :443

4.2 打开另一个shell 2,部署一个测试的deployment,busybox-test

|># kubectl apply -f yaml/busybox.yaml
deployment.apps/busybox-test created

4.3 回到shell 1,wilsonchai-webhook成功接收到来自api的回调

[GIN] 2021/11/08 - 03:53:59 | 200 |     176.172µs |      10.244.0.0 | POST     "/mutate?timeout=30s"

4.4 回到shell 2,查看busybox-test是否部署成功

|># kubectl get pod | grep busybox
busybox-test-59c6487468-h4zx9 1/1 Running 0 110s

至此,部署成功

5.调试模式

由于我们的开发环境在远端(相对于k8s集群),我们想要配置可以直接回调到远端的开发环境,方便我们调试代码,here we go!!

5.1 k8s master上操作

5.1.1 删除 k8s 集群中的 wilsonchai-webhook

|># kubectl delete -f yaml/deploy.yaml
deployment.apps "wilsonchai-webhook-deployment" deleted
service "wilsonchai-webhook-svc" deleted

5.1.2 部署调试模式

|># kubectl apply -f yaml/debug.yaml
service/wilsonchai-webhook-svc created
endpoints/wilsonchai-webhook-svc created

注意: 这里的10.248.33.220,是我的k8s master ip,请大家自行替换成k8s master ip

...
apiVersion: v1
kind: Endpoints
metadata:
name: wilsonchai-webhook-svc
subsets:
- addresses:
- ip: 10.248.33.220
ports:
- port: 443

5.1.3 修改k8s master 的ssh配置(如果没有,请添加),然后重启

|># grep GatewayPorts /etc/ssh/sshd_config
GatewayPorts yes
|># systemctl restart sshd

5.2 回到开发机器操作

5.2.1 打开一条ssh隧道

 ssh -N -R 10.248.33.220:443:127.0.0.1:443 root@10.248.33.220
root@10.248.33.220's password:

5.2.2 运行wilsonchai-webhook,这里需要手工指向证书位置(证书就在“创建相关证书”小节中创建出来的webhook-certs中)

 go run main.go webhook.go -tlsCertFile webhook-certs/server-cert.pem -tlsKeyFile webhook-certs/server-key.pem
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached. [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode) [GIN-debug] POST /mutate --> main.WebhookCallback (4 handlers)
[GIN-debug] Listening and serving HTTPS on :443

至此,开发环境搭建完成,我们来测试一下

5.3 重建busybox-test

|># kubectl delete -f yaml/busybox.yaml
deployment.apps "busybox-test" deleted
|># kubectl apply -f yaml/busybox.yaml
deployment.apps/busybox-test created

5.4 查看开发环境

[GIN] 2021/11/08 - 12:08:59 | 200 |    3.812455ms |       127.0.0.1 | POST     "/mutate?timeout=30s"

没错,apiserver已经回调到我们的开发环境了

6.原理浅析

6.1 mutate webhook

● 通过mutatingwebhookconfiguration,告诉apiserver哪一种资源需要回调

● 用一个wilsonchai-webhook来接收回调,并且进行适当的处理(本文只是打通流程,并没有处理回调内容)

● wilsonchai-webhook最后将回调内容经过处理之后,回写到apiserver去

● mutate webhook有30s的超时时间,超时之后apiserver将进入自己的流程,并在日志打印一行错误

6.2 调试

● 第一步,修改service 的endpoint,把请求流出k8s集群

● 第二步,修改k8s master 的sshd_config,这样做的目的是让隧道监听0.0.0.0,否则只能监听127.0.0.1

● 第三步,建立一条ssh隧道,将访问到k8s master的请求导入到开发环境来

● 总的来说:apiserver --> wilsonchai-webhook-svc --> k8s master ip --> 开发环境

注意:如果你的k8s集群能够直接访问开发环境,那就更加简单,只需要把endpoint的address指向你的开发环境ip即可

7.小结

● 需要注意的是,本文的k8s是1.15.2版本的,如果是高于 v1.16,mutatingwebhookconfiguration的apiversion有变化,具体请参考官网

● 本文只是打通了流程,并没有演示webhook的具体作用

● 本文中的代码:代码

8.参考

https://kubernetes.io/zh/docs/reference/access-authn-authz/extensible-admission-controllers/

https://www.qikqiak.com/post/k8s-admission-webhook/


至此,本文结束

在下才疏学浅,有撒汤漏水的,请各位不吝赐教...

k8s之mutating webhook + gin的更多相关文章

  1. istio sidecar自动注入过程分析

    目录 istio sidecar自动注入过程分析 sidecar自动注入检查 检查kube-apiserver 检查sidecar-injector的configmap 检查namespace标签 s ...

  2. 部署Bookinfo示例程序详细过程和步骤(基于Kubernetes集群+Istio v1.0)

    部署Bookinfo示例程序详细过程和步骤(基于Kubernetes集群+Istio v1.0) 部署Bookinfo示例程序   在下载的Istio安装包的samples目录中包含了示例应用程序. ...

  3. istio1.0.2配置

    项目的组件相对比较复杂,原有的一些选项是靠 ConfigMap 以及 istioctl 分别调整的,现在通过重新设计的Helm Chart,安装选项用values.yml或者 helm 命令行的方式来 ...

  4. 注入 Istio sidecar

    注入 Istio sidecar 网格中的每个 Pod 都必须伴随一个 Istio 兼容的 Sidecar 一同运行. 下文中将会介绍两种把 Sidecar 注入到 Pod 中的方法:使用 istio ...

  5. openshift 4.3 Istio的搭建(istio 系列一)

    openshift 4.3 Istio的搭建 本文档覆盖了官方文档的Setup的所有章节 目录 openshift 4.3 Istio的搭建 安装Istio openshift安装Istio 更新is ...

  6. Kubernetes 两步验证 - 使用 Serverless 实现动态准入控制

    作者:CODING - 王炜 1. 背景 如果对 Kubernetes 集群安全特别关注,那么我们可能想要实现这些需求: 如何实现 Kubernetes 集群的两步验证,除了集群凭据,还需要提供一次性 ...

  7. 第24 章 : Kubernetes API 编程利器:Operator 和 Operator Framework

    Kubernetes API 编程利器:Operator 和 Operator Framework 本节课程主要分享以下三方面的内容: operator 概述 operator framework 实 ...

  8. 乘风破浪,.Net Core遇见Dapr,为云原生而生的分布式应用运行时

    Dapr是一个由微软主导的云原生开源项目,国内云计算巨头阿里云也积极参与其中,2019年10月首次发布,到今年2月正式发布V1.0版本.在不到一年半的时间内,github star数达到了1.2万,超 ...

  9. 深入解析Kubernetes admission webhooks

    BACKGROUND admission controllers的特点: 可定制性:准入功能可针对不同的场景进行调整. 可预防性:审计则是为了检测问题,而准入控制器可以预防问题发生 可扩展性:在kub ...

随机推荐

  1. web自动化:IE11运行Python+selenium程序

    from selenium import webdriver # 运行此脚本前必须按要求修改注册表'''[HKEY_CURRENT_USER\Software\Microsoft\Internet E ...

  2. join方法个人理解

    首先抛出对join的疑问 如果我有一个a线程,一个b线程 那此时 a.start(); b.start(); a.join(); b.join(); 是否意思是a线程先执行完,然后再执行b线程; 如果 ...

  3. Gaussion

    # Kernel density estimation import numpy as np import matplotlib.pyplot as plt from scipy.stats impo ...

  4. Java并发编程实战——读后感

    未完待续. 阅读帮助 本文运用<如何阅读一本书>的学习方法进行学习. P15 表示对于书的第15页. Java并发编程实战简称为并发书或者该书之类的. 熟能生巧,不断地去理解,就像欣赏一部 ...

  5. 在Vue中使用JSX,很easy的

    摘要:JSX 是一种 Javascript 的语法扩展,JSX = Javascript + XML,即在 Javascript 里面写 XML,因为 JSX 的这个特性,所以他即具备了 Javasc ...

  6. Idea进行java应用的远程调试Remote debugging

    本文可以解决如下两个问题: 1.如何处理和调试那些只发生在生产环境(或其他远程环境)而本地开发环境可能没办法重现的"问题". 2.只有一个可以部署的war/jar包,只有class ...

  7. 洛谷4630APIO2018铁人两项(圆方树+dp)

    QWQ神仙题啊(据说是今年第一次出现圆方树的地方) 首先根据题目,我们就是求对于每一个路径\((s,t)\)他的贡献就是两个点之间的点数,但是图上问题我并没有办法很好的解决... 这时候考虑圆方树,我 ...

  8. 洛谷2387 NOI2014魔法森林(LCT维护最小生成树)

    本题是运用LCT来维护一个最小生成树. 是一个经典的套路 题目中求的是一个\(max(a_i)+max(b_i)\)尽可能小的路径. 那么这种的一个套路就是,先按照一维来排序,然后用LCT维护另一维 ...

  9. 复杂对象List集合的排序

    对于集合的排序,直接的有sort().间接的有借用compareTo.Comparable等,但是对于相对复杂的对象集合,还得自己实现方法来处理. 现在有这样一个思路: 第一步:从需要排序的对象集合中 ...

  10. spark性能优化(一)

    本文内容说明 初始化配置给rdd和dataframe带来的影响 repartition的相关说明 cache&persist的相关说明 性能优化的说明建议以及实例 配置说明 spark:2.4 ...