作者:鲍盈海,专注于云原生、微服务、算力网络等
一、背景
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中文社区):集群网络连通性校验工具-NetDoctor
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论