一、背景
Komsos能够快速部署多集群网络,多集群网络最基础的一个考量指标就是节点之间是否联通。为了高效的完成多集群网络连通性的检查,NetDoctor作为Kosmos的网络连通性校验工具应运而生。
二、功能介绍
NetDoctor能够一次检测集群中的所有节点之间容器网络的连通性,在单集群网络场景下,集群中所有节点之间都会做一次连通性校验;在跨集群场景下,集群中所有节点都会跟另一集群中的所有节点做一次连通性校验;
支持多种协议:目前支持ICMP和TCP两种协议,UDP协议正在适配中。 支持多线程并发检测:默认3个协程同时进行,能够大大提高检测效率,缩短检测时间。 可视化界面:进度条,详细的检测报告,包含成功的和异常的节点。
异常节点重测:支持单独测试异常节点,只做关键任务,大大缩短检测时间。
三、快速开始
前置条件
需要镜像仓库,将floater镜像上传至仓库中,NetDoctor会创建Daemonset类型的资源,会在每个节点上运行一个floater服务,所以需要每个节点能够拉取到floater镜像。 需要提供集群的kubeconfig文件,netDoctor会使用此文件来连接集群 以上提到的文件可以从这里获取:https://github.com/kosmos-io/netdoctor。
当完成以上前置条件后,就可以开始下面的步骤了。
步骤一
首先,挑选一个可以访问集群的节点作为我们运行netdoctor的节点,进一步讲,就是可以在这个节点上使用kubectl --kubeconfig=xxxx这个命令来访问集群资源,然后将netdoctor的可执行文件netctl上传至节点上。
步骤二
在节点上运行netctl init命令,会在当前目录下生成一个config.json文件。文件内容如下:
{
"namespace": "kosmos-system",
"version": "0.2.1",
"protocol": "tcp",
"podWaitTime": 30,
"port": "8889",
"maxNum": 3,
"cmdTimeout": 10,
"srcKubeConfig": "~/.kube/config",
"srcImageRepository": "ghcr.io/kosmos-io"
}
其中,只需要将srcKubeConfig修改成你的集群的kubeconfig文件路径,将srcImageRepository修改成你的镜像仓库即可。
步骤三
执行netctl check命令,就会开始连通性检查,日志如下:
主要包含三部分,第一部分进度条,表示检测的的进度,方便使用者评估任务执行时间。第二部分是成功的表格,展示了连通的节点信息。第三部分是异常的表格,展示了存在问题的节点信息,包含异常日志。
假如有异常的节点,可以在问题排查后再单独做一次检测,此时的检测命令是netctl resume
如图所示,netDoctor只检测了异常的节点,大大提高了检测效率。
四、实现原理
相信接触过k8s的小伙伴都用过kubectl exec这个命令吧,我们可以使用它来在容器里执行一个命令,一般我们使用-it参数来进入容器。
这个命令的原理也是向apiserver发送请求,可以用代码实现发送一个exec请求,代码片段如下:
func (i *Floater) CommandExec(podInfo *PodInfo, cmd command.Command) *command.Result {
req := i.KubeClientSet.CoreV1().RESTClient().Post().Resource("pods").Namespace(i.Namespace).Name(podInfo.PodName).
SubResource("exec").
Param("container", "floater").
Param("command", "/bin/sh").
Param("stdin", "true").
Param("stdout", "true").
Param("stderr", "true").
Param("tty", "false")
outBuffer := &bytes.Buffer{}
errBuffer := &bytes.Buffer{}
exec, err := remotecommand.NewSPDYExecutor(i.KueResetConfig, "POST", req.URL())
if err != nil {
return command.ParseError(err)
}
// timeout 5s
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
cmdStr := cmd.GetCommandStr()
klog.Infof("cmdStr: %s", cmdStr)
err = exec.StreamWithContext(ctx, remotecommand.StreamOptions{
Stdin: strings.NewReader(cmdStr),
Stdout: outBuffer,
Stderr: errBuffer,
Tty: false,
})
if err != nil {
klog.Infof("error: %s", err)
return command.ParseError(fmt.Errorf("%s, stderr: %s", err, errBuffer.String()))
}
return cmd.ParseResult(outBuffer.String())
}
NetDoctor最早期的核心代码就是上面这段。后来加上性能,安全,可用性,可扩展性等方面的设计后,就有了下面这张架构图:
netDoctor包含两个模块:netctl和floater
netctl是一个可执行文件,它主要包含三个命令。
Init:创建默认的配置文件,用户根据自己需求修改配置文件,来修改netdoctor的一些行为。
Check:是检验连通性的命令,这个命令会根据配置文件的内容,向floater发起exec请求。
Resume:这是命令是我们实施运维的小伙伴提的,当上一次检查出现有异常的节点后,希望可以单独测试一下有异常的节点,所以resume应运而生。
Floater是一个客户端服务,它运行在每个节点上,一般是以镜像的形式发布,用户需要将这个镜像推送到自己的镜像仓库中,netctl在执行check命令时,会创建一个dameset,最终效果是在每个节点上启动一个floater服务。Floater服务的职责有:接收netctl发来的exec请求、收集节点信息、作为连通性校验请求的发起端和接收端。
下图简单展示了netctl和floater各自的工作内容:
五、总结
Netdoctor总的来讲是一款比较轻量级的工具,他使用起来比较方便,配置和命令都比较简单。希望有同样需求的小伙伴可以尝试用一用这款工具,同时也欢迎大家使用Kosmos,如果使用中有任何问题,可以通过下方的微信群联系我们。
Komsmos:https://github.com/kosmos-io/kosmos
NetDoctor:https://github.com/kosmos-io/netdoctor
温馨提示:文章内容系作者个人观点,不代表Docker中文社区对观点赞同或支持。
版权声明:本文为转载文章,来源于 鲍盈海 ,版权归原作者所有,欢迎分享本文,转载请保留出处!
发表评论