容器化开发调试

本文介绍如何使用 Kubernetes 技术来简化 Linkis 项目的开发调试工作。在没有引入 Kubernetes 工具前,调试 Linkis 是一个非常繁琐和复杂的工作,有时候可能需要搭建 Linkis 依赖的 Hadoop 环境。为了改善这个问题,本文使用了另一种方法,利用 Kubernetes 技术在开发机上创建一个 Hadoop 集群并拉起所有 Linkis 服务,这是个分布式的环境,并且可以随时拉起和销毁,开发者通过 JVM 远程调试功能连接这些服务并进行单步调试. 这里我们用到了如下几个技术:

  • Docker: 一种容器化技术,用于支创建和使用 Linux 容器;
  • Kubernetes: 一种可自动部署和管理 Linux 容器的开源平台,Kubernetes 还整合了网络、存储、安全性、遥测和其他服务,提供了全面的基于容器的基础设施;
  • KinD: 一个使用Docker容器作为 “Kubernetes节点” 来运行本地 Kubernetes 集群的工具;
  • Helm: Kubernetes 上一个开源的包管理工具, 通过 Helm 命令行工具和安装包(Chart)来管理 Kubernetes 上的用户资源;

  • Docker, 最低版本 v20.10.8+

  • Kubernetes, 最低版本 v1.21.0+
  • Helm, 最低版本 v3.0.0+.
  • KinD, 最低版本 v0.11.0+.

Helm 是 Kubernetes 上一个开源的包管理工具,Helm 最初的目标是为用户提供一种更好的方式来管理在 Kubernetes 上创建的所有 Kubernetes YAML 文件。Helm 使用 Charts 这个方式来解决上述问题,Chart 是一组文本文件,使用 Helm 模版语言编写,用来描述一个或者多个 Kubernetes 资源文件,Chart 直接依赖或者引用其他 Chart. 在使用 Charts 时,用户需要提供一个 变量文件,Helm 使用这个变量文件中定义的变量来渲染相应的 Chart, 生产 Kubernetes YAML 文件, 然后调用 Kubernetes api 提交到 Kubernetes 上。每一个发布到 Kubernetes 的 Charts 被称为 Release,一个 Chart 通常可以被多次安装到同一个集群中,而每次安装时,都会创建一个新的 Release。

Helm 的安装方式比较简单,请参考官方文档进行安装: Installing Helm

在本地创建一个 Kubernetes 测试环境是一个非常普遍的需求,Kubernetes 社区提供了多种解决方案,如 MiniKube 或 MicroK8s 等,KinD 是一个相对较新的工具,KinD 是 Kubernetes IN Docker 的缩写,顾名思义,它使用 Docker 托管节点来创建一个面向测试的 Kubernetes 集群。

KinD 系统架构

容器化开发调试 - 图1

部署 KinD 也非常简单,请参考官方部署文档: KinD Installation, 部署 KinD 前请先安装 Docker .

⚠️注意: KinD 是面向测试的用途的工具,不能用于生产部署。同时,KinD 利用 Docker 带来的便利的同时,也引入了一些限制, 比如,开发机重启后,KinD 集群无法继续使用,需要重新创建(因为 KinD 在创建 Node 容器后会进行一系列的初始化工作,这些工作在机器重启后无法自动回复)。

Linkis 提供了多个镜像,所有镜像的 Dockerfile 和相关脚本都在 linkis-dist/docker 目录下。 可以通过 Maven 命令和 docker build 命令来制作相应的镜像。Linkis 镜像主要包括如下几个:

  • linkis: Linkis 服务镜像,镜像中包含了 Apache Linkis 的所有组件的二进制包和各类脚本。
  • linkis-web: Linkis Web 控制台镜像,镜像中包含了 Apache Linkis Web 控制台的的二进制包和各类脚本,本镜像使用 nginx 作为 Web 服务器。
  • linkis-ldh: LDH 是一个面向测试用途的镜像,LDH 镜像提供了一套完整的、伪分布式模式的 Apache Hadoop 运行环境,包含了 HDFS, YARN, HIVE, Spark, Flink 和 Zookeeper, 可以很方便的在开发环境中拉起一个全真的 Hadoop 环境用来测试 Linkis 的功能。

具体请参考: Linkis Docker 镜像打包.

Linkis Helm Chart 是遵循 Helm Chart 规范开发的 Helm 安装包,在 linkis-dist/helm 目录下. 模块目录结构如下:

  1. linkis-dist/helm
  2. ├── charts # Charts 目录, 目前仅包含 Linkis Helm Chart
  3. └── linkis # Linkis Helm Chart 目录
  4. ├── Chart.yaml # - Chart 元数据
  5. ├── templates # - Chart 模版文件,包含了所有 linkis 组件的 Kubernetes YAML 模版
  6. ├── NOTES.txt # - Chart 提示信息
  7. ├── _helpers.tpl # - Chart 变量辅助模版
  8. ├── configmap-init-sql.yaml # - 数据库初始化 SQL 脚本模版
  9. ├── configmap-linkis-config.yaml # - Linkis 服务配置文件模版
  10. ├── configmap-linkis-web-config.yaml # - Linkis Web 控制台配置文件模版
  11. ├── jobs.yaml # - Kubernetes Job 模版,目前仅包括一个数据库初始化作业, 数据库初始化 SQL 脚本会在这个
  12. | | | # 作业中被执行
  13. ├── linkis-cg-engineconnmanager.yaml # - Linkis EngineConnManager 部署模版,是一个 Kubernetes Deployment 类型的工作负载
  14. ├── linkis-cg-engineplugin.yaml # - Linkis EngineConn 部署模版,是一个 Kubernetes Deployment 类型的工作负载
  15. ├── linkis-cg-entrance.yaml # - Linkis Entrance 部署模版,是一个 Kubernetes Deployment 类型的工作负载
  16. ├── linkis-cg-linkismanager.yaml # - Linkis Manager 部署模版,是一个 Kubernetes Deployment 类型的工作负载
  17. ├── linkis-mg-eureka.yaml # - Linkis Eureka 部署模版,是一个 Kubernetes Statefulset 类型的工作负载
  18. ├── linkis-mg-gateway.yaml # - Linkis Gateway 部署模版,是一个 Kubernetes Deployment 类型的工作负载
  19. ├── linkis-ps-publicservice.yaml # - Linkis PublicService 部署模版,是一个 Kubernetes Deployment 类型的工作负载
  20. ├── linkis-web.yaml # - Linkis Web Console 部署模版,是一个 Kubernetes Deployment 类型的工作负载
  21. └── serviceaccount.yaml # - Linkis 相关的 Kubernetes Service Account 模版
  22. └── values.yaml # - Linkis Helm Chart 变量文件,默认提供了 Linkis Local 模式相关的变量
  23. ├── scripts # 一些用于简化开发调试的工具脚本
  24. ├── common.sh # - 公共脚本,定义了一些公共方法和变量
  25. ├── create-kind-cluster.sh # - 创建 KinD 集群
  26. ├── install-charts-with-ldh.sh # - 在 KinD 集群上部署 Linkis 服务,使用 On-LDH 的部署方式, 调用 install-linkis.sh 实现
  27. ├── install-charts.sh # - 在 KinD 集群上部署 Linkis 服务,使用 Local 的部署方式, 调用 install-linkis.sh 实现
  28. ├── install-ldh.sh # - 在 KinD 集群上部署 LDH 部署
  29. ├── install-linkis.sh # - 在 KinD 集群上部署 Linkis 服务,可以为 Local 或者 On-LDH 的模式
  30. ├── install-mysql.sh # - 在 KinD 集群上部署一个 MySQL 实例
  31. ├── login-pod.sh # - 登入一个 Pod,打开 Bash 进行交互
  32. ├── remote-debug-proxy.sh # - 开启 JVM 远程调试代理,开启后,可以在 IDE 上连接相应的端口进行调试
  33. └── resources # - 一些资源文件
  34. ├── kind-cluster.yaml # - KinD 集群配置,默认为单个 Node
  35. ├── ldh # - LDH 相关资源文件
  36. ├── configmaps # - LDH 各个组件的配置文件
  37. ├── configmap-flink.yaml # - Flink 配置文件
  38. ├── configmap-hadoop.yaml # - Hdfs & Yarn 配置文件
  39. ├── configmap-hive.yaml # - Hive 配置文件
  40. ├── configmap-spark.yaml # - Spark 配置文件
  41. └── configmap-zookeeper.yaml # - Zookeeper 配置文件
  42. └── ldh.yaml # - LDH Kubernetes YAML, 用于在 KinD 上部署 LDH 实例
  43. └── mysql.yaml # - MySQL Kubernetes YAML, 用于在 KinD 上部署 MySQL 实例

本项目提供了一组工具脚本,用于快速创建一个用于开发测试的 Linkis 环境。在生产部署中,需要根据集群的实际情况,修改 values.yaml 文件,再使用 Helm CLI 进行部署。使用 Helm CLI 进行部署时,通常有如下两种比较常见的做法:

  1. 使用 helm install 命令直接部署。适用于非定制化的部署方式;
  2. 使用 helm template 命令选生成 Kubernetes YAML 文件,然后手动修改这些文件,添加自定义配置,然后使用kubectl apply命令进行部署。适用于需要定制 Linkis Helm Charts 不支持的 Kubernetes 特性的高阶用户, 如需要使用特定的 StorageClass 或者 PV 等;

LDH 是一个面向测试用途的 Hadoop 集群镜像,它提供了一个伪分布式的 hadoop 集群,方便快速测试 On Hadoop 的部署模式。 这个镜像包含以下多个 hadoop 组件,LDH 中引擎的默认模式是 on-yarn 的。

  • Hadoop 2.7.2 , 包括 HDFS 和 YARN
  • Hive 2.3.3
  • Spark 2.4.3
  • Flink 1.12.2
  • ZooKeeper 3.5.9

LDH 启动时会进行一些初始化操作,比如 format hdfs, 在 HDFS 上创建初始化目录等,这些操作定义在linkis-dist/docker/scripts/entry-point-ldh.sh这个文件中,添加、修改、删除一些初始化操作需要重新制作 LDH 镜像才能生效。

另外,LDH 中的 Hive 组件依赖外部的 MySQL 实例,需要先部署 MySQL 实例才能使用 LDH 中的 Hive 组件。

  1. # 创建 KinD 集群,并部署 Linkis 和 LDH 实例
  2. $> sh ./scripts/create-kind-cluster.sh \
  3. && sh ./scripts/install-mysql.sh \
  4. && sh ./scripts/install-ldh.sh
  5. # 快速体验 LDH
  6. $> kubectl exec -it -n ldh $(kubectl get pod -n ldh -o jsonpath='{.items[0].metadata.name}') -- bash
  7. [root@ldh-96bdc757c-dnkbs /]# hdfs dfs -ls /
  8. Found 4 items
  9. drwxrwxrwx - root supergroup 0 2022-07-31 02:48 /completed-jobs
  10. drwxrwxrwx - root supergroup 0 2022-07-31 02:48 /spark2-history
  11. drwxrwxrwx - root supergroup 0 2022-07-31 02:49 /tmp
  12. drwxrwxrwx - root supergroup 0 2022-07-31 02:48 /user
  13. [root@ldh-96bdc757c-dnkbs /]# beeline -u jdbc:hive2://ldh.ldh.svc.cluster.local:10000/ -n hadoop
  14. Connecting to jdbc:hive2://ldh.ldh.svc.cluster.local:10000/
  15. Connected to: Apache Hive (version 2.3.3)
  16. Driver: Hive JDBC (version 2.3.3)
  17. Transaction isolation: TRANSACTION_REPEATABLE_READ
  18. Beeline version 2.3.3 by Apache Hive
  19. 0: jdbc:hive2://ldh.ldh.svc.cluster.local:100> create database demo;
  20. No rows affected (1.306 seconds)
  21. 0: jdbc:hive2://ldh.ldh.svc.cluster.local:100> use demo;
  22. No rows affected (0.046 seconds)
  23. 0: jdbc:hive2://ldh.ldh.svc.cluster.local:100> create table t1 (id int, data string);
  24. No rows affected (0.709 seconds)
  25. 0: jdbc:hive2://ldh.ldh.svc.cluster.local:100> insert into t1 values(1, 'linikis demo');
  26. WARNING: Hive-on-MR is deprecated in Hive 2 and may not be available in the future versions. Consider using a different execution engine (i.e. spark, tez) or using Hive 1.X releases.
  27. No rows affected (5.491 seconds)
  28. 0: jdbc:hive2://ldh.ldh.svc.cluster.local:100> select * from t1;
  29. +--------+---------------+
  30. | t1.id | t1.data |
  31. +--------+---------------+
  32. | 1 | linikis demo |
  33. +--------+---------------+
  34. 1 row selected (0.39 seconds)
  35. 0: jdbc:hive2://ldh.ldh.svc.cluster.local:100> !q
  36. [root@ldh-96bdc757c-dnkbs /]# spark-sql
  37. 22/07/31 02:53:18 INFO hive.metastore: Trying to connect to metastore with URI thrift://ldh.ldh.svc.cluster.local:9083
  38. 22/07/31 02:53:18 INFO hive.metastore: Connected to metastore.
  39. ...
  40. 22/07/31 02:53:19 INFO spark.SparkContext: Running Spark version 2.4.3
  41. 22/07/31 02:53:19 INFO spark.SparkContext: Submitted application: SparkSQL::10.244.0.6
  42. ...
  43. 22/07/31 02:53:27 INFO yarn.Client: Submitting application application_1659235712576_0001 to ResourceManager
  44. 22/07/31 02:53:27 INFO impl.YarnClientImpl: Submitted application application_1659235712576_0001
  45. 22/07/31 02:53:27 INFO cluster.SchedulerExtensionServices: Starting Yarn extension services with app application_1659235712576_0001 and attemptId None
  46. 22/07/31 02:53:28 INFO yarn.Client: Application report for application_1659235712576_0001 (state: ACCEPTED)
  47. ...
  48. 22/07/31 02:53:36 INFO yarn.Client: Application report for application_1659235712576_0001 (state: RUNNING)
  49. ...
  50. Spark master: yarn, Application Id: application_1659235712576_0001
  51. 22/07/31 02:53:46 INFO thriftserver.SparkSQLCLIDriver: Spark master: yarn, Application Id: application_1659235712576_0001
  52. spark-sql> use demo;
  53. Time taken: 0.074 seconds
  54. 22/07/31 02:58:02 INFO thriftserver.SparkSQLCLIDriver: Time taken: 0.074 seconds
  55. spark-sql> select * from t1;
  56. ...
  57. 1 linikis demo
  58. 2 linkis demo spark sql
  59. Time taken: 3.352 seconds, Fetched 2 row(s)
  60. spark-sql> quit;
  61. [root@ldh-96bdc757c-dnkbs /]# zkCli.sh
  62. Connecting to localhost:2181
  63. Welcome to ZooKeeper!
  64. JLine support is enabled
  65. WATCHER::
  66. WatchedEvent state:SyncConnected type:None path:null
  67. [zk: localhost:2181(CONNECTED) 0] get -s /zookeeper/quota
  68. cZxid = 0x0
  69. ctime = Thu Jan 01 00:00:00 UTC 1970
  70. mZxid = 0x0
  71. mtime = Thu Jan 01 00:00:00 UTC 1970
  72. pZxid = 0x0
  73. cversion = 0
  74. dataVersion = 0
  75. aclVersion = 0
  76. ephemeralOwner = 0x0
  77. dataLength = 0
  78. numChildren = 0
  79. [zk: localhost:2181(CONNECTED) 1] quit
  80. # 以 per-job cluster 模式启动 Flink 作业
  81. [root@ldh-96bdc757c-dnkbs /]# HADOOP_CLASSPATH=`hadoop classpath` flink run -t yarn-per-job /opt/ldh/current/flink/examples/streaming/TopSpeedWindowing.jar
  82. # 以 session 模式启动 Flink 作业,
  83. # Flink session 在 LDH Pod 启动时会被启动了一个.
  84. [root@ldh-96bdc757c-dnkbs /]# flink run /opt/ldh/current/flink/examples/streaming/TopSpeedWindowing.jar
  85. Executing TopSpeedWindowing example with default input data set.
  86. Use --input to specify file input.
  87. Printing result to stdout. Use --output to specify output path.
  88. ...

Linkis 项目默认使用的 KinD 集群描述文件是linkis-dist/helm/scripts/resources/kind-cluster.yaml, 默认会创建一个包含一个节点的 KinD 集群。打开文件中注释的内容可以添加多个节点。

⚠️注意,KinD 集群仅用于测试用途。

  1. # linkis-dist/helm/scripts/resources/kind-cluster.yaml
  2. kind: Cluster
  3. apiVersion: kind.x-k8s.io/v1alpha4
  4. nodes:
  5. - role: control-plane
  6. extraMounts:
  7. - hostPath: ${KIND_CLUSTER_HOST_PATH} # 指向开发机上的一个目录。这个目录会被映射到 Kind Node 容器中的 `/data` 目录,
  8. # Linkis Helm Charts 默认会使用这个目录作为数据目录挂载到各个 Linkis 组件的
  9. # Pod 中。当 Linkis 使用 Local 模式进行部署时,所有组件实际上使用了开发机上的
  10. # 同一个目录,就和在同一台机器上一样,从而模拟了 Local 模式的行为。当使用
  11. # On-Hadoop 模式进行部署时,这个目录不会被使用。
  12. containerPath: /data
  13. # - role: worker # 打开注释可以添加2个 KinD 节点。添加 KinD 节点会增加加载 Docker 镜像到 KinD
  14. # # 集群的时间,所以默认不打开。
  15. # extraMounts:
  16. # - hostPath: ${KIND_CLUSTER_HOST_PATH}
  17. # containerPath: /data
  18. # - role: worker
  19. # extraMounts:
  20. # - hostPath: ${KIND_CLUSTER_HOST_PATH}
  21. # containerPath: /data

下面介绍使用 Linkis 容器化组件开发调试的步骤(目前仅支持 Linux 和 MacOS)。在进行本步骤前请确认如下事项:

  1. 开发机上是否已经安装了 Docker 引擎
  2. 开发机上是否已经安装了 Helm
  3. 开发机上是否已经安装了 KinD
  4. 是否已经按照 Linkis Docker 镜像打包 所述的方式制作了 Linkis 镜像

本步骤会创建一个 KinD 集群,并在其上部署 MySQL、 Linkis 和 LDH 实例。

  1. $> cd linkis-dist/helm
  2. $> sh ./scripts/create-kind-cluster.sh \
  3. > && sh ./scripts/install-mysql.sh \
  4. > && sh ./scripts/install-ldh.sh \
  5. > && sh ./scripts/install-charts-with-ldh.sh
  6. # Creating KinD cluster ...
  7. - kind cluster config: /var/folders/9d/bb6ggdm177j25q40yf5d50dm0000gn/T/kind-XXXXX.Fc2dFJbG/kind-cluster.yaml
  8. ...
  9. kind: Cluster
  10. apiVersion: kind.x-k8s.io/v1alpha4
  11. nodes:
  12. - role: control-plane
  13. extraMounts:
  14. - hostPath: /var/folders/9d/bb6ggdm177j25q40yf5d50dm0000gn/T/kind-XXXXX.Fc2dFJbG/data
  15. containerPath: /data
  16. ...
  17. Creating cluster "test-helm" ...
  18. Ensuring node image (kindest/node:v1.21.1) 🖼
  19. Preparing nodes 📦
  20. Writing configuration 📜
  21. Starting control-plane 🕹️
  22. Installing CNI 🔌
  23. Installing StorageClass 💾
  24. Set kubectl context to "kind-test-helm"
  25. You can now use your cluster with:
  26. kubectl cluster-info --context kind-test-helm
  27. Have a nice day! 👋
  28. # Loading MySQL image ...
  29. Image: "mysql:5.7" with ID "sha256:3147495b3a5ce957dee2319099a8808c1418e0b0a2c82c9b2396c5fb4b688509" not yet present on node "test-helm-control-plane", loading...
  30. # Deploying MySQL ...
  31. namespace/mysql created
  32. service/mysql created
  33. deployment.apps/mysql created
  34. # LDH version: dev
  35. # Loading LDH image ...
  36. Image: "linkis-ldh:dev" with ID "sha256:aa3bde0a31bf704413fb75673fc2894b03a0840473d8fe15e2d7f7dd22f1f854" not yet present on node "test-helm-control-plane", loading...
  37. # Deploying LDH ...
  38. namespace/ldh created
  39. configmap/flink-conf created
  40. configmap/hadoop-conf created
  41. configmap/hive-conf created
  42. configmap/spark-conf created
  43. configmap/zookeeper-conf created
  44. service/ldh created
  45. deployment.apps/ldh created
  46. # Loading Linkis image ...
  47. Image: "linkis:dev" with ID "sha256:0dfa7882c4216305a80cf57efa8cfb483d006bae5ba931288ffb8025e1db4e58" not yet present on node "test-helm-control-plane", loading...
  48. Image: "linkis-web:dev" with ID "sha256:1dbe0e9319761dbe0e93197665d38077cb2432b8b755dee834928694875c8a22" not yet present on node "test-helm-control-plane", loading...
  49. # Installing linkis, image tag=dev,local mode=false ...
  50. NAME: linkis-demo
  51. NAMESPACE: linkis
  52. STATUS: deployed
  53. REVISION: 1
  54. TEST SUITE: None
  55. NOTES:
  56. ...
  57. ---
  58. Welcome to Apache Linkis (v1.3.0)!
  59. .___ .___ .______ .____/\ .___ .________
  60. | | : __|: \ : / \: __|| ___/
  61. | | | : || ||. ___/| : ||___ \
  62. | |/\ | || | || \ | || /
  63. | / \| ||___| || \| ||__:___/
  64. |______/|___| |___||___\ /|___| : v1.3.0
  65. \/
  66. Linkis builds a layer of computation middleware between upper applications and underlying engines.
  67. Please visit https://linkis.apache.org/ for details.
  68. Enjoy!
  69. configmap/flink-conf created
  70. configmap/hadoop-conf created
  71. configmap/hive-conf created
  72. configmap/spark-conf created
  73. configmap/zookeeper-conf created
  74. $> kubectl get pods -n ldh -o wide
  75. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  76. ldh-6648554447-ml2bn 1/1 Running 0 6m25s 10.244.0.6 test-helm-control-plane <none> <none>
  77. $> kubectl get pods -n linkis -o wide
  78. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  79. init-db-bcp85 0/1 Completed 0 4m52s 10.244.0.14 test-helm-control-plane <none> <none>
  80. linkis-demo-cg-engineconnmanager-659bf85689-ddvhw 1/1 Running 1 4m52s 10.244.0.7 test-helm-control-plane <none> <none>
  81. linkis-demo-cg-engineplugin-98bd6945-tsgjl 1/1 Running 1 4m52s 10.244.0.10 test-helm-control-plane <none> <none>
  82. linkis-demo-cg-entrance-858f74c868-xrd82 1/1 Running 0 4m52s 10.244.0.12 test-helm-control-plane <none> <none>
  83. linkis-demo-cg-linkismanager-6f96f69b8b-ns6st 1/1 Running 0 4m52s 10.244.0.11 test-helm-control-plane <none> <none>
  84. linkis-demo-mg-eureka-0 1/1 Running 0 4m52s 10.244.0.13 test-helm-control-plane <none> <none>
  85. linkis-demo-mg-gateway-68ddb8c547-xgvhn 1/1 Running 0 4m52s 10.244.0.15 test-helm-control-plane <none> <none>
  86. linkis-demo-ps-publicservice-6bbf99fcd7-sc922 1/1 Running 0 4m52s 10.244.0.8 test-helm-control-plane <none> <none>
  87. linkis-demo-web-554bd7659f-nmdjl 1/1 Running 0 4m52s 10.244.0.9 test-helm-control-plane <none> <none>

每个组件在容器内的 JVM 远程调试端口均为 5005, 这些端口会被映射到宿主机上的不同端口,具体如下:

  • mg-eureka: 5001
  • mg-gateway: 5002
  • ps-publicservice: 5004
  • cg-linkismanager: 5007
  • cg-entrance: 5008
  • cg-engineconnmanager: 5009
  • cg-engineplugin: 5010

另外,Web Console 会被映射到宿主机上的 8087 端口,可以在浏览器上输入http://localhost:8087进行访问.

  1. $> ./scripts/remote-debug-proxy.sh start
  2. - starting port-forwad for [web] with mapping [local->8087:8087->pod] ...
  3. - starting port-forwad for [mg-eureka] with mapping [local->5001:5005->pod] ...
  4. - starting port-forwad for [mg-gateway] with mapping [local->5002:5005->pod] ...
  5. - starting port-forwad for [ps-publicservice] with mapping [local->5004:5005->pod] ...
  6. - starting port-forwad for [cg-linkismanager] with mapping [local->5007:5005->pod] ...
  7. - starting port-forwad for [cg-entrance] with mapping [local->5008:5005->pod] ...
  8. - starting port-forwad for [cg-engineconnmanager] with mapping [local->5009:5005->pod] ...
  9. - starting port-forwad for [cg-engineplugin] with mapping [local->5010:5005->pod] ..
  10. $> ./scripts/remote-debug-proxy.sh list
  11. user 10972 0.0 0.1 5052548 31244 s001 S 12:57AM 0:00.10 kubectl port-forward -n linkis pod/linkis-demo-cg-engineplugin-98bd6945-tsgjl 5010:5005 --address=0.0.0.0
  12. user 10970 0.0 0.1 5053060 30988 s001 S 12:57AM 0:00.12 kubectl port-forward -n linkis pod/linkis-demo-cg-engineconnmanager-659bf85689-ddvhw 5009:5005 --address=0.0.0.0
  13. user 10968 0.0 0.1 5054084 30428 s001 S 12:57AM 0:00.10 kubectl port-forward -n linkis pod/linkis-demo-cg-entrance-858f74c868-xrd82 5008:5005 --address=0.0.0.0
  14. user 10966 0.0 0.1 5053316 30620 s001 S 12:57AM 0:00.11 kubectl port-forward -n linkis pod/linkis-demo-cg-linkismanager-6f96f69b8b-ns6st 5007:5005 --address=0.0.0.0
  15. user 10964 0.0 0.1 5064092 31152 s001 S 12:57AM 0:00.10 kubectl port-forward -n linkis pod/linkis-demo-ps-publicservice-6bbf99fcd7-sc922 5004:5005 --address=0.0.0.0
  16. user 10962 0.0 0.1 5051012 31244 s001 S 12:57AM 0:00.12 kubectl port-forward -n linkis pod/linkis-demo-mg-gateway-68ddb8c547-xgvhn 5002:5005 --address=0.0.0.0
  17. user 10960 0.0 0.1 5053060 31312 s001 S 12:57AM 0:00.13 kubectl port-forward -n linkis pod/linkis-demo-mg-eureka-0 5001:5005 --address=0.0.0.0
  18. ...
  19. # 在调试完成后,可以使用如下命令停止端口转发
  20. $> ./scripts/remote-debug-proxy.sh stop
  21. - stopping port-forward for [web] with mapping [local->8087:8087->pod] ...
  22. - stopping port-forward for [mg-eureka] with mapping [local->5001:5005->pod] ...
  23. - stopping port-forward for [mg-gateway] with mapping [local->5002:5005->pod] ...
  24. - stopping port-forward for [ps-publicservice] with mapping [local->5004:5005->pod] ...
  25. - stopping port-forward for [cg-linkismanager] with mapping [local->5007:5005->pod] ...
  26. - stopping port-forward for [cg-entrance] with mapping [local->5008:5005->pod] ...
  27. - stopping port-forward for [cg-engineconnmanager] with mapping [local->5009:5005->pod] ...
  28. - stopping port-forward for [cg-engineplugin] with mapping [local->5010:5005->pod] ...

在 IDE 上进行如下配置,开启远程调试:

容器化开发调试 - 图2

开启远程调试 容器化开发调试 - 图3

设置断点,提交一个作业,进行调试

  1. $> ./scripts/login-pod.sh mg-gateway
  2. - login [mg-gateway]'s bash ...
  3. bash-4.2$ ./bin/./linkis-cli -engineType shell-1 -codeType shell -code "echo \"hello\" " -submitUser hadoop -proxyUser hadoop
  4. =====Java Start Command=====
  5. exec /etc/alternatives/jre/bin/java -server -Xms32m -Xmx2048m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/linkis/logs/linkis-cli -XX:ErrorFile=/opt/linkis/logs/linkis-cli/ps_err_pid%p.log -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=80 -XX:+DisableExplicitGC -classpath /opt/linkis/conf/linkis-cli:/opt/linkis/lib/linkis-computation-governance/linkis-client/linkis-cli/*:/opt/linkis/lib/linkis-commons/public-module/*: -Dconf.root=/etc/linkis-conf -Dconf.file=linkis-cli.properties -Dlog.path=/opt/linkis/logs/linkis-cli -Dlog.file=linkis-client..log.20220925171540947077800 org.apache.linkis.cli.application.LinkisClientApplication '-engineType shell-1 -codeType shell -code echo "hello" -submitUser hadoop -proxyUser hadoop'
  6. ...

容器化开发调试 - 图4

调试完成后,可以使用如下命令清理整个环境:

  1. $> kind delete clusters test-helm
  2. Deleted clusters: ["test-helm"]
  1. $> kubectl logs -n linkis linkis-demo-cg-engineconnmanager-659bf85689-ddvhw -f
  2. + RUN_IN_FOREGROUND=true
  3. + /opt/linkis/sbin/linkis-daemon.sh start cg-engineconnmanager
  4. Start to check whether the cg-engineconnmanager is running
  5. Start server, startup script: /opt/linkis/sbin/ext/linkis-cg-engineconnmanager
  6. =====Java Start Command=====
  7. java -DserviceName=linkis-cg-engineconnmanager -Xmx512M -XX:+UseG1GC -Xloggc:/var/logs/linkis/linkis-cg-engineconnmanager-gc.log -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -cp /etc/linkis-conf:/opt/linkis/lib/linkis-commons/public-module/*:/opt/linkis/lib/linkis-computation-governance/linkis-cg-engineconnmanager/* org.apache.linkis.ecm.server.LinkisECMApplication --eureka.instance.prefer-ip-address=true --eureka.instance.instance-id=${spring.cloud.client.ip-address}:${spring.application.name}:${server.port} 2>&1
  8. OpenJDK 64-Bit Server VM warning: If the number of processors is expected to increase from one, then you should configure the number of parallel GC threads appropriately using -XX:ParallelGCThreads=N
  9. Listening for transport dt_socket at address: 5005
  10. 16:32:41.101 [main] INFO org.apache.linkis.common.conf.BDPConfiguration$ - ******************* Notice: The Linkis configuration file is linkis.properties ! *******************
  11. 16:32:41.130 [main] INFO org.apache.linkis.common.conf.BDPConfiguration$ - *********************** Notice: The Linkis serverConf file is linkis-cg-engineconnmanager.properties ! ******************
  12. 16:32:41.222 [main] INFO org.apache.linkis.LinkisBaseServerApp - Ready to start linkis-cg-engineconnmanager with args: --eureka.instance.prefer-ip-address=true
  13. --eureka.instance.instance-id=${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
  14. ...

使用./scripts/login-pod.sh <组件名>可以进入组件的 Pod 打开一个 Bash 实例进行交互式操作,其中组件名可以为:

  • cg-engineconnmanager
  • cg-engineplugin
  • cg-entrance
  • cg-linkismanager
  • mg-eureka
  • mg-gateway
  • ps-publicservice
  • web
  1. $> ./scripts/login-pod.sh cg-engineconnmanager
  2. - login [cg-engineconnmanager]'s bash ...
  3. bash-4.2$ pwd
  4. /opt/linkis
  5. bash-4.2$ env |grep LINKIS
  6. LINKIS_DEMO_PS_PUBLICSERVICE_SERVICE_HOST=127.0.0.1
  7. LINKIS_DEMO_CG_LINKISMANAGER_PORT_9101_TCP_PROTO=tcp
  8. LINKIS_DEMO_WEB_PORT_8087_TCP_PORT=8087
  9. ...
  10. LINKIS_CLIENT_CONF_DIR=/etc/linkis-conf
  11. bash-4.2$ ps aux |grep linkis
  12. hadoop 1 0.0 0.0 11708 2664 ? Ss 16:32 0:00 /bin/bash /opt/linkis/sbin/linkis-daemon.sh start cg-engineconnmanager
  13. hadoop 10 0.0 0.0 11708 2624 ? S 16:32 0:00 sh /opt/linkis/sbin/ext/linkis-cg-engineconnmanager
  14. hadoop 11 0.0 0.0 11712 2536 ? S 16:32 0:00 sh /opt/linkis/sbin/ext/linkis-common-start
  15. hadoop 12 4.0 3.2 4146404 400084 ? Sl 16:32 0:35 java -DserviceName=linkis-cg-engineconnmanager -Xmx512M -XX:+UseG1GC -Xloggc:/var/logs/linkis/linkis-cg-engineconnmanager-gc.log -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -cp /etc/linkis-conf:/opt/linkis/lib/linkis-commons/public-module/*:/opt/linkis/lib/linkis-computation-governance/linkis-cg-engineconnmanager/* org.apache.linkis.ecm.server.LinkisECMApplication --eureka.instance.prefer-ip-address=true --eureka.instance.instance-id=${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
  16. bash-4.2$ exit
  17. exit