基于 kubebuilder 的 webhook 踩坑史

前情提要

工作经常使用到 webhook 进行开发和设计工作,遇到的问题也是多种多样,针对 webhook 的开发调试将通过如下几个方面展开论述开发和实践过程,新项目建立之初,需要统一代码提交的规范和使用范围,go 项目的管理如何更加方便的管理 go 的包依赖等问题,再有就是如果验证过程中出现的针对资源无法清理问题的解决方案,如何分解发布流程和使用过程进行项目的同步和使用。

问题梳理

1 git 管理
# git 免密设置
[场景1]:永久记住密码
git config --global credential.helper store
[场景2]:记住密码(默认15分钟)
git config --global credential.helper cache
[场景3]:自己定义时间(一小时后失效):
git config credential.helper 'cache --timeout=3600'

# git 账号/密码设置
git config --global user.email "lys-15102xxxx@qq.com"
git config --global user.name vpc123

# 建立全新 go 项目,为项目打 tag 进行区分
git clone https://gitee.com/vpc123/k8swebhook.git

# 创建新分支并切换到新分支
git checkout -b  feature-base
git brnach

# 提交分支代码到仓库
git add .
git commit -m "feat: add new test info."
git push origin feature-base

# 创建新 tag 并切换到新 tag
git add .
git commit -m "fixed some bugs"
git tag -a 0.1.3 -m "Release version 0.1.3"

# 提交 新tag 代码到仓库
git checkout origin feature-base
git push origin feature-base
git push origin --tags 0.1.3

# 切换到已有的 tag
git tag --list  // 查看已有tag列表
git checkout [tag/branch/commit]  // 切换到指定tag/branch/commit都是此命令

# 删除标签
[场景1]:删除本地 tag
git tag -d 0.1.3
[场景2]:删除远程 tag
git push origin :refs/tags/0.1.3
2 go 私有/公有/本地依赖管理
# 获取全新的 go 项目
git clone https://gitvpc123.com/vpc123/test.git
# go mod 初始化
git mod init 
git mod tidy
git mod download

# 具体命令参考
download                //下载模块到本地缓存,具体可以通过命令go env查看,其中环境变量GOCACHE就是缓存的地址,如果该文件夹的内容太大,可以通过命令go clean -cache
edit                    //从工具或脚本中编辑go.mod文件
graph                   //打印模块需求图
init                    //在当前目录下初始化新的模块
tidy                    //添加缺失的模块以及移除无用的模块
verify                  //验证依赖项是否达到预期的目的
why                     //解释为什么需要包或模块

a 公有库模块

# 设置公有库代理
go env -w GOPROXY=https://goproxy.cn,direct
# 设置跳过私有库,私有库不用代理
go env -w GOPRIVATE=*.gitlab.com,*.gitee.com
# GO111MODULE解释, 当为on时则使用Go Modules,go 会忽略 $GOPATH和 vendor文件夹,只根据go.mod下载依赖
go env -w GO111MODULE=on

go.mod 引用解读:

module elasticweb

go 1.13
require (
	github.com/go-logr/logr v0.1.0
	github.com/onsi/ginkgo v1.11.0
	github.com/onsi/gomega v1.8.1
	k8s.io/api v0.17.2
	k8s.io/apimachinery v0.17.2
	k8s.io/client-go v0.17.2
	k8s.io/utils v0.0.0-20191114184206-e782cd3c129f
	sigs.k8s.io/controller-runtime v0.5.0
)

b 私有库模块

# 设置跳过私有库,私有库不用代理
go env -w GOPRIVATE=*.gitlab.com,*.gitee.com
# GO111MODULE解释, 当为on时则使用Go Modules,go 会忽略 $GOPATH和 vendor文件夹,只根据go.mod下载依赖
go env -w GO111MODULE=on

go.mod 引用解读:

module elasticweb

go 1.13
require (
	github.com/go-logr/logr v0.1.0
	vpcdemo v0.0.1
)

replace vpcdemo v0.0.1 =>  gitee.com/vpc123/vpcdemo v0.0.1

c 本地库模块
go.mod 引用解读:

module elasticweb

go 1.13
require (
	github.com/go-logr/logr v0.1.0
	vpcdemo v0.0.1
)

replace vpcdemo v0.0.1 =>  ../vpcdemo

备注说明: 其实整体来说 go 项目存在多种方式的版本依赖关系,可以通过 1 GOPATH;2 govendor;3 gomod,通用性来看的话,gomod更加灵活和通用,所以墙裂安利大家在 go 语言项目使用中通过 go mod 进行项目的管理和发布。

3 kubebuilder 资源调试发布

a 远程调试 & make run

# 此场景,需要开发机器通过 config 进行远程集群的资源监控
[第一步]:有一个 K8s 集群用于访问测试
略
[第二步]:部署相关 crd 资源
cd $GOPATH/src/vpc123_demo
make install
[第三步]:清理相关 crd 资源
cd $GOPATH/src/vpc123_demo
make uninstall

备注: 此种调试方式对于 api & controller 的调试支持度比较友好也很方便。

b 集群调试 & make deploy

[安装部署]:
# 安装 crd,并生成二进制
cd $GOPATH/src/vpc123_demo
make install & make manager
# 资源设置
ImageName="elasticweb:001"
make docker-build docker-push IMG=$ImageName
# 部署集成了webhook功能的controller
make deploy IMG=$ImageName
# 查看 pod 资源
kubectl get pods --all-namespaces
 
[删除清理]:
# 删除 cr 资源对象
kubectl delete -f config/samples/
# 删除controller
kustomize build config/default | kubectl delete -f -
# 删除CRD
make uninstall

备注: 本地make run测试,且使用make deploy 测试,会需要不同的webhookconfiguration,两种测试方式建议只选择一种,不要来回切换,否则要确保webhookconfiguration的配置,比较费时。

4 资源强删技巧

1 命名空间 Terminating 强制删除也无法删除

# 一般删除
kubectl delete namespace test
# 一般删除不生效时,强制删除
kubectl delete namespace test --force --grace-period=0
# 接口调度删除(最后的稻草):打开2个控制台分别执行如下命令
[窗口1]:开启 proxy 代理转发
kubectl proxy --address='0.0.0.0'  --accept-hosts='^*$'

[窗口2]:其中 test 命名空间需要对应
kubectl get namespace test -o json > tmp.json
curl -k -H "Content-Type: application/json" -X PUT --data-binary @tmp.json http://127.0.0.1:8001/api/v1/namespaces/test/finalize

2 强删其它资源

# 一般删除
kubectl delete pod [pod name] -n [namespace] --force --grace-period=0 
# 强制删除
kubectl delete pod [pod name] --force --grace-period=0 -n [namespace]

###4 webhook 资源概述
什么是AdmissionWebhook,就要先了解K8S中的admission controller, 按照官方的解释是: admission controller是拦截(经过身份验证)API Server请求的网关,并且可以修改请求对象或拒绝请求。

简而言之,它可以认为是拦截器,类似web框架中的middleware。

K8S默认提供很多内置的admission controller,通过kube-apiserver启动命令参数可以 查看到支持的admission controller plugin有哪些。

# 查看 kube-apiserver 的帮助
kube-apiserver --help |grep enable-admission-plugins
# 查看 webhook 版本
kubectl  api-versions
# 查看 webhook 系统资源
kubectl  api-resources

这里不对每个plugin详细说明,网上都可以搜到相关资料。 总体来说,admission-plugins分为三大类:

1.修改类型(mutating)

2.验证类型(validating)

3.既是修改又是验证类型(mutating&validating)

这些admission plugin构成一个顺序链,先后顺序决定谁先调用,但不会影响使用。

这里关心的plugin有两个:

一、MutatingAdmissionWebhook, ValidatingAdmissionWebhook

MutatingAdmissionWebhook: 做修改操作的AdmissionWebhook
ValidatingAdmissionWebhook: 做验证操作的AdmissionWebhook

引用kubernetes官方博客的一张图来说明MutatingAdmissionWebhook和ValidatingAdmissionWebhook所处的位置:

解释下这个过程:

1.api请求到达K8S API Server

2.请求要先经过认证
a.kubectl调用需要kubeconfig
b.直接调用K8S api需要证书+bearToken
c.client-go调用也需要kubeconfig

3.执行一连串的admission controller,包括MutatingAdmissionWebhook和ValidatingAdmissionWebhook, 先串行执行MutatingAdmission的Webhook list

4.对请求对象的schema进行校验

5.并行执行ValidatingAdmission的Webhook list

6.最后写入etcd

拓展阅读

说明: 演练环境需要把时区完成统一,不然会出现校验失败的问题等现象。

参考:
goland 配置远程开发调试:
https://zhuanlan.zhihu.com/p/55296765

k8s 的 webhook 概述:
https://cloud.tencent.com/developer/article/1445760

演练环境时区统一:
https://blog.csdn.net/xgysimida/article/details/111073919

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流雨声

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值