Nocalhost 是一款开源的基于 IDE 的云原生应用开发工具:
- 直接在 Kubernetes 集群中构建、测试和调试应用程序
- 提供易于使用的 IDE 插件(支持 VS Code 和 JetBrains),即使在 Kubernetes 集群中进行开发和调试,Nocalhost 也能保持和本地开发一样的开发体验
- 使用即时文件同步进行开发: 即时将您的代码更改同步到远端容器,而无需重建镜像或重新启动容器。
- 安装
打开goland,进Settings - Plugins,在Marketplace处搜索nocalhost并安装:
最新版本的goland在插件仓库搜索不到,目前只支持到231.*****版本。 2023.1可以搜索下载使用
重启goland后,主界面右边栏应该多出一个tab,点击它,再点➕
然后选中kubeconfig文件,再选具体的conte
结束后在右侧菜单里会出现集群菜单,里面罗列了集群里的几乎所有资源:
我们选中deployment,找到要开发的服务,然后右键选择开发模式:
源代码远端编译模式:
菜单中的DevMode、DevMode(Duplicate)、Mesh(Duplicate)都是属于在远端镜像内直接编译源代码的模式。
因为该模式会同步本地源代码到集群内容器,所以可能会有潜在的安全问题(oncall中)
上述三种模式的配置基本相同,先选择Dev Config:
这时nocalhost会为你初始化一份config文件,并询问你是否要在网页端进行可视化配置:
2.配置
点击Yes跳转到浏览器,开始编辑config:
左侧填写的内容会直接反映到右侧的yaml文件中。现在逐项解释各项配置的含义:
输入完成后点击上面蓝色Apply按钮,成功后如图所示:
3.开发模式
1.在goland中 找到要开发的服务,右键,选择Start DevMode
2.点击后选择使用指定源代码本地目录,或者可以从现有的 Git 仓库克隆源码,如图(此处选择了一个之前测试的服务,打开的本地源代码)
注:当此时选择本地的源代码时候,实际就是把选择的目录中的内容同步到容器中,即选择的文件夹中有什么文件,就把那些文件放到工作负载的容器中去,而把之前容器中的文件覆盖,下方是官方解释
进入 DevMode 后,用户需要选择一个本地目录。或右键单击目标工作量并选择 Associate Local DIR 来主动关联一个本地目录。 本地选中的目录将与 DevMode 中容器的 workDir 同步。
WORKDIR 注意事项
workDir 使用 emptyDir 在 容器中共享 ,所以 这个目录在开始时是空的
3.点击Open后Nocalhost 会自动在新窗口中启动开发模式
4.进入开发模式之后,出现一个新的Terminal,如下:
本地ide展示:
![在这里插入图片描述](https://img-blog.csdnimg.cn/a0824d0f678745fa91bb4c827f4f22fb.png
容器内部展示:
5.测试
此时,本地环境已经和线上同步,做几个小测试
1:文件同步
创建一个文件,观察是否同步
本地:
线上:
2:代码同步
修改代码看是否能同步生效
步骤:
1.将服务器上代码编译成可执行文件运行,执行 localhost:8888/ping方法,返回 {“message”:“pong123”}
2.修改代码,修改返回值
3.线上重新编译,执行执行 localhost:8888/ping方法,返回 {“message”:“pong pong pong”}
4.调试模式
1.编写配置文件
右键想要debug的服务,点击Dev Config
打开后如图所示:
参照nocalhost官网编写配置,点击左下角Run And Debug,填写配置:
注:左侧填写配置后,会自动同步到右边的yaml文件,此处我们是按照官网去填写的
官网示例:https://nocalhost.dev/zh-CN/docs/guides/debug/jetbrains-debug
2.编写脚本
上面我们在debug启动时执行了一个debug.sh的脚本。下面就是脚本内容,内容详情请自行百度
#! /bin/sh
export GOPROXY=https://goproxy.cn
dlv --headless --log --listen :9009 --api-version=2 --accept-multiclient debug .
注:1.脚本放置位置应该位于工作空间目录下,并具有可执行权限,如图
注:2.容器内必须安装 dlv(go语言调试依赖dlv),否则无法以debug启动,安装dlv命令整理如下:
git clone https://github.com/go-delve/delve.git $GOPATH/src/github.com/go-delve/delve
cd $GOPATH/src/github.com/go-delve/delve
make install
3.启动调试
启动调试前,我们在容器内执行curl命令,看是否启动,如图:
此处未启动,完全符合预期
启动调试
调试时,工作负载应处于开发模式下(goland中服务前面有个锤子的图标),右键服务,点击Remote Debug
等待启动程序,当goland的console出现启动成功的日志,启动成功.如图
注:该日志为我测试程序成功启动的日志,不同程序日志也不同,关注点应在于是否启动成功
这时候,工作负载中的容器代码应该成功启动了,进行测试:
(1)当我们在容器内部输入"curl localhost:8888/ping"的时候,没有立马返回结果,而是卡在了原地
(2)此处我们看我们的Goland,发现成功进入了我们事先打好的断点
(3)在编辑器中放行代码,容器中成功打印结果,证明可以在本地调试容器的代码
5:端口转发
nacalhost提供端口转发的能力,可以将k8s集群的工作负载的端口转发到本地。
1.在goland右侧的nocalhost中点击Port Forward
2.设置本地端口与服务器端口映射,此处选择8090端口,监听远端的工作负载上的8888端口
3.在本地测试 localhost:8090/ping方法,返回 {“message”:“pong pong pong”}
6.三种开发模式
1.DevMode(Replace)
上面所介绍的开发模式就是DevMode(Replace),做个简单介绍。
- 将副本数缩减为 1。 开发应用程序时,只需要在一个容器里运行正在开发的应用程序, 如果存在多个副本,我们通过 Service 访问该工作负载时,就无法控制流量只访问到我们正在开发的应用程序所运行的那个副本。 所以 Nocalhost 需要先将工作负载的副本数缩减为 1。
- 替换容器的镜像为开发镜像。 生产环境运行的容器往往会使用很轻量级的镜像,镜像里仅包含运行业务程序所必须的组件,而缺少编译构建业务程序的相关工具(如 JDK)。 所以在对某个工作负载进行开发的时候,Nocalhost 会将容器镜像替换成包含完整开发工具的开发镜像。
- 增加一个 sidecar 容器。 为了将本地的源代码改动同步到容器中,需要在容器里运行一个文件同步服务器。 为了使文件同步服务器进程和业务进程解耦,Nocalhost 将文件同步服务器运行在一个独立的 sidecar 容器中。 该容器与业务容器挂载相同的同步目录, 因此,同步到 sidecar 容器中的源代码在业务容器中也可以访问。
- 转发一个本地端口到文件同步服务器。 文件同步服务器监听在容器里的某个端口,我们在本地无法直接访问, 所以 Nocalhost 会把一个本地随机端口转发到容器里文件同步服务器监听的端口。
- 启动本地文件同步客户端。 文件同步客户端启动后会通过上一步转发的本地随机端口和文件同步服务器建立通信, 之后便会开始进行文件的同步。
- 打开远程终端。 在容器替换成功之后,Nocalhost 会自动打开一个进入到远程容器的终端。 通过该终端,我们可以把同步到容器里到源代码直接运行起来。
大致的意思总结就是容器内部的镜像会完全替换成本地正在开发的镜像,容器内部环境和本地环境一样,流量全部打在正在开发的镜像上。
弊端: - 容易破坏原有的环境. 可能会因为开发中的服务出现问题而导致整个环境出问题.
- 容易影响其它团队成员对环境的正常使用. 其它团队成员可能只想访问正常的的环境,而不是处于开发中的环境
- 多个团队成员无法对同一套环境的同一个服务同时进行开发
2.DevMode(Duplicate)
因为上方的弊端,所以有第二种开发模式 DevMode(Duplicate)。官方介绍如下:
在 Duplicate DevMode 中,Nocalhost 不会对原有工作负载进行任何修改,而是创建一个原有工作负载的副本,在该副本上进行开发. 副本及其管理的 Pod 会使用和原有工作负载不一样的 labels,所以它不会接收任何访问原有工作负载的流量. 这么做的原因是,和 Replace DevMode 不同,Duplicate DevMode 是允许在多台设备上同时进入开发模式的,如果副本和原有工作负载一样都接收来自线上流量的话,我们无法知道当前访问的环境使用的哪个设备上正在开发的服务,从而会导致访问环境的结果变得不可预期.
在不同设备上可以同时使用 Duplicate DevMode 创建工作负载的副本进行开发. 副本上会被 Nocalhost 打上设备的 ID 以标识该副本是哪个设备在进行开发 (设备 ID 由 Nocalhost 自动生成,对用户透明. 并保证不同设备上的设备 ID 不会重复). 各个副本之间互不影响.
意思就是在你使用这种开发模式的时候,当你进入开发模式的时候,集群中容器的环境并不会改变,nacalhost会在你的本地环境生成一个副本,你所修改的东西都在此本地上,不会影响集群中正在运行的负载。并且副本不会接受到任何的流量,因为接受流量可能导致不可预期的结果。
通过官方的方式进行该开发模式的启动
成功启动之后,发现我们的Terminal环境和容器内部的不太一样了,因为是容器内部没有同步我们本地的环境,而是创建了一个副本(对用户隐藏)。如图:
容器内部
Terminal
此时我们分别在容器内部和本地环境启动我们的程序,调用localhost:8888/ping
容器内部
Terminal
注意: 此刻的Terminal所访问的localhost并不是我自己电脑,而是容器的localhost,因为采用的是Duplicate的模式,所以运行时产生不同的结果,这就是上述提到的副本的含义。
该图为我自己电脑的终端,可以证明我自己电脑是没有启动服务的。
我们同样可以通过端口转发方式访问,转发到本地访问
测试
弊端:
不会接受流量
3.DevMode Mesh
由于DevMode(Replace)和DevMode(Duplicate)各自的弊端,提供了第三种开发模式。
它采用一个请求头的方式,只有匹配到正确的请求头,流量才能转发过来。