前情提要
工作经常使用到 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