1

前言

在很早以前发表了一篇文章springcloud本地开发的微服务如何调用远程k8s的微服务。着重介绍的如何利用kt-connect来打通开发环境与K8S环境的调试。今天介绍的Nocalhost,不仅仅能达到上述的效果,而且功能更加强大。下面我们就进入正题

什么是Nocalhost

Nocalhost 是一款开源的基于 IDE 的云原生应用开发工具,它具有如下功能:

  • 直接在 Kubernetes 集群中构建、测试和调试应用程序
  • 提供易于使用的 IDE 插件(支持 VS Code 和
    JetBrains),即使在 Kubernetes 集群中进行开发和调试,Nocalhost 也能保持和本地开发一样的开发体验
  • 使用即时文件同步进行开发: 即时将您的代码更改同步到远端容器,而无需重建镜像或重新启动容器。

Nocalhost是如何工作

Nocalhost 由单个二进制 CLI 和 IDE 插件组成。 理想情况下,您可以直接将它与您熟悉的 IDE 一起使用。 Nocalhost 不需要服务器端组件,因为它通过 KubeConfig 直接与您的 Kubernetes 集群通信,就像 kubectl 一样。

实操

注: 本文以java语言为例子,window环境通过idea来演示

1、在idea中安装Nocalhost插件

通过文件 > 设置 > 插件 > 浏览插件仓库... > 搜索 "Nocalhost" > 安装插件"

注: Nocalhost对idea版本有要求,他idea的最低要求版本为2020.3

其他方式的插件安装,查看Nocalhost官网
https://nocalhost.dev/zh-CN/docs/installation

2、配置K8S集群

点击idea右侧菜单栏,选中nocalhost tab

点开,看到如下界面

点击connect to cluster按钮,进入如下界面

可以通过下载 kubeconfig 文件到本地,然后Load KubeConfig选择kubeconfig 保存的文件路径。或者可以直接复制
kubeconfig 内容到文本区

如果连接成功,就会看下形如下内容


更多集群配置可以查看官网,https://nocalhost.dev/zh-CN/docs/guides/manage-cluster/

3、创建实例应用

以一个java项目为例,本示例以mvc来演示,编写一个controller

@RestController
@RequestMapping(value = "develop")
@Api(tags = "开发专用")
@Slf4j
public class DevelopController {

    @GetMapping("local")
    @ApiOperation(value = "本地调试")
    public String testLocalDev(){
        return "localDev";
    }
}
4、将创建的java项目打成jar(可选)

通过执行

mvn clean package -DskipTests

打包后,会在target目录下,产生相应的jar,形如下

注: 是否需要打包,根据config.yaml的配置的command参数而定,如果配置如下示例,其实可以不用打成jar

# Deployment Name
name: pig-auth
serviceType: deployment
containers:
    # Deployment 主容器名称
  - name: auth
    dev:
        # 开发镜像,该镜像包含了 Java Maven 环境
      image: registry.cn-hangzhou.aliyuncs.com/zqqq/maven:3.8.6-openjdk-8
      # 默认终端为 bash
      shell: bash
      # Rainbond 提供的 StorageClass Name
      storageClass: rainbondvolumerwx
      # 配置开发容器资源
      resources:
        limits:
          memory: 4096Mi
          cpu: "2"
        requests:
          memory: 2048Mi
          cpu: "1"
      persistentVolumeDirs:
          # Maven 依赖包缓存路径,配合 storageClass 一起食用
        - path: /root/.m2/repository
          capacity: 10Gi
      command:
        # 一键启动命令,安装依赖包和启动 pig-auth 子模块
        run:
          - mvn
          - install
          - '&&'
          - mvn
          - spring-boot:run
          - -pl
          # 指定子模块启动
          - pig-auth
        # 一键 Debug 命令,安装依赖包和 Debug pig-auth 子模块
        debug:
          - mvn
          - install
          - '&&'
          - mvn
          - spring-boot:run
          - -pl
          # 指定子模块启动
          - pig-auth
          # Java Debug 命令
          - -Dspring-boot.run.jvmArguments=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005
      debug:
        # 远程端口,对应Debug命令中的 address=5005
        remoteDebugPort: 5005
        # 选择 Java 语言
        language: java
      # 热加载
      hotReload: true
      # 文件同步
      sync:
        type: send
        mode: gitIgnore
        deleteProtection: true
      # 端口转发,转发容器内的3000端口到本地3999
      portForward:
        - 3999:3000

该配置来源博客https://cloud.tencent.com/developer/article/2043129的配置示例

5、将应用发布到k8s

可以通过界面操作,也可以通过kubectl apply -f 或者helm进行操作

附: 示例的deployment.yml文件

ApiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    workload.user.cattle.io/workloadselector: nocalhost-demo
  name: nocalhost-demo
  namespace: test
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      workload.user.cattle.io/workloadselector: nocalhost-demo
  template:
      labels:
       workload.user.cattle.io/workloadselector: nocalhost-demo
    spec:
      affinity: {}
      containers:
      - env:
        - name: SERVER_PORT
          value: "80"
        image: harbor.images.cn/devops/adoptopenjdk/openjdk8
        imagePullPolicy: IfNotPresent
        name: nocalhost-demo
        ports:
        - containerPort: 80
          name: 80tcp
          protocol: TCP
        readinessProbe:
          failureThreshold: 5
          httpGet:
            path: /actuator/health/ping
            port: 80
            scheme: HTTP
          initialDelaySeconds: 10
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30

发布上去后,可以通过nocalhost面板查看

6、使用nocalhost进行服务调试

a、 选择想要调试的工作负载


b、 右键点击工作负载并选择 Dev Config,编辑您的调试配置


选中后会提示


选择yes,跳转到如下页面


其实就跳转到这个链接https://nocalhost.dev/zh-CN/tools,填好相关信息,选择应用即可

注: 不过我们更经常使用如下方式

在项目根目录创建个 .nocalhost 文件夹,然后拷贝形如下内容到config.yaml文件


示例

name: "nocalhost-demo"
serviceType: "deployment"
containers:
  -
    name: "nocalhost-demo"
    dev:
      gitUrl: ""
      image: "nocalhost-docker.pkg.coding.net/nocalhost/dev-images/java:11"
      shell: "bash"
      workDir: ""
      storageClass: ""
      resources:
        limits:
          memory: "2048Mi"
          cpu: "2"
        requests:
          memory: "512Mi"
          cpu: "0.5"
      persistentVolumeDirs: []
      command:
        run:
          - "exec"
          - "java"
          - "-Dlog4j2.formatMsgNoLookups=true"
          - "-Djava.security.egd=file:/dev/./urandom"
          - "-jar"
          - "/home/nocalhost-dev/target/nocalhost-demo.jar"
        debug:
          - "java"
          - "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005"
          - "-jar"
          - "/home/nocalhost-dev/target/nocalhost-demo.jar"
      debug:
        language: "java"
        remoteDebugPort: 5005
      hotReload: true
      sync:
        type: "send"
        mode: "pattern"
        filePattern:
          - "."
        ignoreFilePattern:
          - ".git"
        deleteProtection: true
      env:
        - name: JAVA_TOOL_OPTIONS
          value: -Xms1024M -Xmx1024M
      portForward:
        # 8082本地端口,80为容器端口
        - "8082:80"
      sidecarImage: ""

注: 这些内容可以直接通过nocalhost提供的可视化界面https://nocalhost.dev/zh-CN/tools进行操作配置,再拷贝即可

c、 右键再次点击此工作负载并选择Start DevMode 或者Start DevMode(Duplicate )

Nocalhost 目前支持两种开发模式, Repliace DevMode 和 Duplicate DevMode。其中Repliace 是默认模式
这两者的区别在于

Repliace DevMode使用直接替换镜像的方式可以很好地保持原有的服务间调用关系,让集群中其它服务的流量打到正在开发的服务上。即开发的镜像会直接替换原有的镜像。该模式可能会出现以下问题

  1. 容易破坏原有的环境. 可能会因为开发中的服务出现问题而导致整个环境出问题.
  2. 容易影响其它团队成员对环境的正常使用. 其它团队成员可能只想访问正常的的环境,而不是处于开发中的环境
  3. 多个团队成员无法对同一套环境的同一个服务同时进行开发

Duplicate DevMode不会对原有工作负载进行任何修改,而是创建一个原有工作负载的副本,在该副本上进行开发. 在不同设备上可以同时使用 Duplicate DevMode 创建工作负载的副本进行开发. 副本上会被 Nocalhost 打上设备的 ID 以标识该副本是哪个设备在进行开发 (设备 ID 由 Nocalhost 自动生成,对用户透明. 并保证不同设备上的设备 ID 不会重复). 各个副本之间互不影响。该模式可能会出现如下问题

Duplicate DevMode 是允许在多台设备上同时进入开发模式的,如果副本和原有工作负载一样都接收来自线上流量的话,我们无法知道当前访问的环境使用的哪个设备上正在开发的服务,从而会导致访问环境的结果变得不可预期.

这两种模式的更多信息可以查看如下链接https://nocalhost.dev/zh-CN/docs/guides/develop-service-dup-en

我们通过Duplicate DevMode启动,观察控制台

通过控制台,可以看出来,已经启动成功了

e、 配置端口转发(可选)

可以通过config.yaml配置形如下内容(如果是已经在配置文件中,已经配置转发端口,则该步骤可以跳过)

   portForward:
        # 8082本地端口,80为容器端口
        - "8082:80"

也可以右键点击此工作负载,选中Port Forward

8082为本地端口,80为代理端口

f: 右键点击工作负载,选中Remote run或者Remote debug

正常情况下,idea的控制台会打印相关项目日志信息,形如下

在这里插入图片描述

该日志是容器里面的日志,我们可以先在项目中打个断点,然后通过浏览器访问localhost:8082/develop/local

跳过断点,浏览器跳转到如下页面


说明已经成功进行调试。

更多关于调试相关内容可以查看如下链接https://nocalhost.dev/zh-CN/docs/guides/debug/jetbrains-debug/

总结

其实本文的内核都来自官网,对Nocalhost感兴趣的朋友,可以看下官网,实操一下。官网的资料还是很齐全。


linyb极客之路
330 声望191 粉丝