起因
在SASE项目开发过程中,大概率都存在私有化部署的场景,所以我所在的项目组也是不可避免的。项目架构说明:kubernetes + 微服务。私有化部署的难点在于客户的集群环境的适配,如:
-
客户提供的服务器linux发行版本; -
客户网络无法联网,需要纯离线安装等。
对于以上环境,服务的部署可采用以下方式:
-
对于服务改造,如果是测试用户,可执行通过docker compose部署all in one包的方式。 -
将所有依赖进行打包处理,并编写自动化部署脚本。
由于第一点,对于业务存在改造的成本,所以考虑的是第二种方式;在执行过程中,又经历了自开发以及开源项目二次开发,在此记录下心路历程。
自开发
涉及到分布式集群的搭建,所以使用的是ansible脚本来完成。一共可分为以下几种ansible的playbook role:
-
system init -
etcd -
kubernetes -
thirdpart(第三方组件安装) -
mongodb -
redis cluster -
rabbitmq -
微服务部署
主机离线包需要包括:
-
harbor – offlines.tar.gz -
安装所需的镜像,helm包(可以放到playbook中,安装时进行拷贝,解压,导入等操作) -
服务所需要的manifests文件或者helm包。
ansible经验项:
-
活用debug命令:在不清楚其内容的情况下,使用debug命令来进行打印数据; -
使用meta: end_play + –start-at-task:进行单个任务进行调试; -
使用pdb,说到底ansible还是python写的,那么也有pdb操作,实时看错误任务的堆栈信息。–>debugger 关键字。
缺点:
-
自开发,脚本都需要一步步验证,开发时间长。 -
离线包的抓取,rpm包依赖的下载,都是比较耗时费力的一件事,并且不同的linux的发行版都需要考虑。
kubekey二次开发方案
在搭建kubesphere作为k8s的管理平台时,偶然发现了kubekey这个部署工具,提供离线安装方式以及使用golang进行脚本的编写,可以说是相当nice。(这次发现golang非常的适合部署工具的开发)官方wiki
架构图
架构抽象出四个对象:
-
Action: 基础执行单元,表示在一台节点上执行一次具体任务(cmd、template、scp、fetch)。 -
Task:Action 管理单元,定义调度执行策略,例如:节点调度,重试次数,是否并行执行。 -
Module:Tasks 集合,是一个具有完整功能的模块。 -
Pipeline(相当于playbook):Modules 集合,顺序执行 Modules 流程。KubeKey 中每个功能均被定义为一个 Pipeline
可与ansible执行方式进行类比。
如何使用kk进行开发
下载kubekey源码后,需要关注的目录都在cmd目录下:
cmd
└── kk
├── apis -- 数据结构,如manifest结构体,cluster结构体等
├── cmd -- 命令定义
└── pkg -- 执行核心
需要改动的文件都在这几个目录下,在kubekey 目录下,执行make kk
即可生成命令行工具。
经验项
调试
在对开源项目进行二开时,首先需要考虑的是,如何调试代码?首先在cmd目录下直接执行go run . 进行调试,会包如下错误:
# pkg-config --cflags -- gpgme
Package gpgme was not found in the pkg-config search path.
Perhaps you should add the directory containing `gpgme.pc'
to the PKG_CONFIG_PATH environment variable
No package 'gpgme' found
pkg-config: exit status 1
# pkg-config --cflags -- devmapper
Package devmapper was not found in the pkg-config search path.
Perhaps you should add the directory containing `devmapper.pc'
to the PKG_CONFIG_PATH environment variable
No package 'devmapper' found
pkg-config: exit status 1
# github.com/containers/storage/drivers/btrfs
/root/go/pkg/mod/github.com/containers/storage@v1.43.0/drivers/btrfs/btrfs.go:9:10: fatal error: btrfs/ioctl.h: No such file or directory
9 | #include <btrfs/ioctl.h>
| ^~~~~~~~~~~~~~~
compilation terminated.
在直接编译的时候,我们可以看到存在多个第三方c库的依赖没有安装。但是我又不想安装依赖,所以我们需要去查看kk具体在makefile中如何编译出来的。
.PHONY: kk
kk:
CGO_ENABLED=0 go build -trimpath -tags "$(BUILDTAGS)" -ldflags "$(LDFLAGS)" -o ./kk github.com/kubesphere/kubekey/v3/cmd/kk;
这里存在两个变量不清楚如何赋值,所以可以直接执行make kk 来查看具体执行:
CGO_ENABLED=0 go build -trimpath -tags "exclude_graphdriver_devicemapper exclude_graphdriver_btrfs containers_image_openpgp" .
可以看出在编译时,kubekey将这些第三方库给排除掉了。相对应的,gorun如下:
CGO_ENABLED=0 go run -trimpath -tags "exclude_graphdriver_devicemapper exclude_graphdriver_btrfs containers_image_openpgp" .
开发
在开发时,kubekey使用的是cobra命令行框架,那就简单了,直接复制一个对应的命令出来,进行pipeline的改造,即可。编写路径为:
cobra-->pipeline-->module-->Task-->Action
最终执行的方法为action.Execute
。
一些源码的分析
源码分析,思维导图如下:借助思维导图,可以查看一个pipeline执行的主流程。其中localTask与RemoteTask的不同点在于,RemoteTask需要创建connection, 在Action中可以使用 host := runtime.RemoteHost()
获取远程Host, 通过执行runtime.GetRunner().SudoCmd()
来进行远程命令的执行。
优势
-
kubekey维护了现在流行的Linux发行版本,在离线时,可以直接使用。 -
kubekey提供了以下功能: -
集群部署 -
集群删除 -
添加节点 -
删除节点 -
集群升级 -
证书有效期检查 -
证书更新 -
etcd 备份 -
证书自动更新 -
支持自定义制作离线安装包 -
支持插件扩展 -
操作系统初始化 (安装依赖、配置时间同步、执行自定义脚本等)
并且提供高可用k8s集群搭建,可以说离线安装需要考虑的场景都已经考虑到了。
收获
在开发过程中,往往需要使用一些脚本自动化工具,在kubekey中有比较好的实践:
-
配置文件代码化,通过golang text/template 库进行维护,如system.serivce文件,etcd.env文件等等 -
通过golang ssh代码封装实现远程代码执行。 -
往往开发人员在shell脚本的使用上比较薄弱, 使用golang进行自动化工具的编写,可能达到意想不到的效果,并且编译出的二进制文件,跨平台依赖比较少。
原文始发于微信公众号(小唐云原生):一种云原生应用本地化方案-kubekey
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/247518.html