这是本节的多页打印视图。 点击此处打印.

返回本页常规视图.

5. Module Controller V2 模块运维

Koupleless Module Controller V2架构下的模块运维

1 - 5.1 模块发布

Koupleless 模块上线与下线

注意:当前 ModuleController v2 仅在 K8S 1.24 版本测试过,没有在其它版本测试,ModuleController V2依赖了部分K8S特性,K8S的版本不能低于V1.10。

模块上线

ModuleController V2支持以任意Pod的发布方式进行模块发布上线,包含但不仅限于裸pod发布、Deployment、DaemonSet、StatefulSet。下面以Deployment为例演示模块的发布流程,其他方式可以参考Deployment中template的配置:

kubectl apply -f samples/module-deployment.yaml --namespace yournamespace

完整内容如下:

apiVersion: apps/v1  # 指定api版本,此值必须在kubectl api-versions中
kind: Deployment  # 指定创建资源的角色/类型
metadata:  # 资源的元数据/属性
  name: test-module-deployment  # 资源的名字,在同一个namespace中必须唯一
  namespace: default # 部署在哪个namespace中
spec: # 资源规范字段
  replicas: 1
  revisionHistoryLimit: 3 # 保留历史版本
  selector: # 选择器
    matchLabels: # 匹配标签
      app: test-module-deployment
  strategy: # 策略
    rollingUpdate: # 滚动更新
      maxSurge: 30% # 最大额外可以存在的副本数,可以为百分比,也可以为整数
      maxUnavailable: 30% # 示在更新过程中能够进入不可用状态的 Pod 的最大值,可以为百分比,也可以为整数
    type: RollingUpdate # 滚动更新策略
  template: # 模版
    metadata: # 资源的元数据/属性
      labels: # 设定资源的标签
        module-controller.koupleless.io/component: module # 必要,声明pod的类型,用于module controller管理
        # deployment unique id
        app: test-module-deployment-non-peer
    spec: # 资源规范字段
      containers:
        - name: biz1 # 必要,声明module的bizName,需与pom中声明的artifactId保持一致
          image: https://serverless-opensource.oss-cn-shanghai.aliyuncs.com/module-packages/stable/biz1-web-single-host-0.0.1-SNAPSHOT-ark-biz.jar
          env:
            - name: BIZ_VERSION # 必要,声明module的biz_version,value需与pom中声明的version保持一致
              value: 0.0.1-SNAPSHOT
      affinity:
        nodeAffinity: # 必要,声明基座选择器,保证模块被调度到指定的基座上
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: base.koupleless.io/stack
                    operator: In
                    values:
                      - java # 多语言环境下可能有其他技术栈,必填
                  - key: base.koupleless.io/version
                    operator: In
                    values:
                      - 1.1.1 # 指定的基座版本,必填,至少需要一个
                  - key: base.koupleless.io/name
                    operator: In
                    values:
                      - base  # 指定的基座bizName,必填,至少需要一个
      tolerations: # 必要,允许pod被调度到基座node上
        - key: "schedule.koupleless.io/virtual-node"
          operator: "Equal"
          value: "True"
          effect: "NoExecute"

其中所有的配置与普通Deployment一致,除必填项外,可添加其他Deployment的配置实现自定义能力。

后续模块的更新也可以直接通过更新模块 Deployment 的 Container Image 和 BIZ_VERSION 来实现,复用 Deployment 的 RollingUpdate 来实现分批更新。

Module Controller 通过控制同一个基座上的 Pod 状态更新顺序实现了滚动更新过程中的模块流量无损,具体过程为:

  1. Deployment 更新后会根据更新策略配置先创建出新版本模块的 Pod
  2. K8S Scheduler 将这些 Pod 调度到 VNode 上,此时这些 VNode 上安装了老版本的模块
  3. Module Controller 监听到 Pod 成功调度,发起新版本模块的安装
  4. 安装完成之后,Module Controller 会检查当前基座上所有模块的状态,然后对所关联的 Pod 根据创建时间进行排序,按序更新状态,从而使得旧版本模块对应的 Pod 会先变成 Not Ready 状态,其后新版本模块对应的 Pod 才会变成 Ready
  5. Deployment 控制器在监听到新创建出来的 Pod Ready 之后会开始清理旧版本 Pod,在这一过程中 Deployment 会优先选择当前状态为 Not Ready 的 Pod 进行删除,而此时同一个基座上的老版本 Pod 已经 Not Ready,会被删除,从而避免其他基座上的 Ready 状态的旧版本模块 Pod 先被删除

在上述过程中,不会出现某一个基座上无模块的情况,从而保证了模块更新过程中的流量无损。

查看模块状态

这一需求可以通过查看nodeName为基座对应node的Pod来实现。首先需要了解基座服务与node的对应关系。

在Module Controller V2的设计中,每一个基座会在启动时随机生成一个全局唯一的UUID作为基座服务的标识,对应的node的Name则将包含这一ID。

除此之外,基座服务的IP与node的IP是一一对应的,也可以通过IP来筛选对应的基座Node。

因此,可以通过以下命令查看某个基座上安装的所有Pod(模块),和对应的状态。

kubectl get pod -n <namespace> --field-selector status.podIP=<baseIP>

kubectl get pod -n <namespace> --field-selector spec.nodeName=virtual-node-<baseUUID>

模块下线

在 K8S 集群中删除模块的Pod或其他控制资源即可完成模块下线,例如,在Deployment部署的场景下,可以直接删除对应的Deployment实现模块的下线:

kubectl delete yourmoduledeployment --namespace yournamespace

其中 yourmoduledeployment 替换成您的 ModuleDeployment 名字,yournamespace 替换成您的 namespace。

如果要自定义模块发布运维策略(比如分组、Beta、暂停等),可参考模块发布运维策略

样例演示的是使用 kubectl 方式,直接调用 K8S APIServer 删除Deployment一样能实现模块分组下线。

模块扩缩容

由于ModuleController V2完全复用了K8S的Pod编排方案,扩缩容只发生在ReplicaSet、Deployment、StatefulSet等部署方式上,扩缩容可以按照各自对应的扩缩容方式实现,下面以Deployment为例:

kubectl scale deployments/yourdeploymentname --namespace=yournamespace --replicas=3

其中 yourdeploymentname 替换成您的 Deployment name,yournamespace 替换成您的 namespace,replicas参数设置为希望扩/缩容到的数量。

也可以通过API调用实现扩缩容策略。

模块替换

在ModuleController v2中,模块与Container是强绑定的关系,如果想实现模块的替换,需要执行更新逻辑,更新模块所在Pod上的模块对应Image地址。

具体的替换方式随模块部署的方式不同而略有区别,例如,直接更新Pod信息会在原地进行模块的替换,Deployment会执行配置的更新策略(例如滚动更新,先创建新版本的Pod,再删除旧版本的Pod),DaemonSet也会执行配置的更新策略,与Deployment不同,DaemonSet是先删除后创建的逻辑,可能会造成流量损失。

模块回滚

由于与原生的Deployment兼容,因此可以采用Deployment的回滚方式实现模块回滚。

查看deployment历史。

kubectl rollout history deployment yourdeploymentname

回滚到指定版本

kubectl rollout undo deployment yourdeploymentname --to-revision=<TARGET_REVISION>

其他运维问题

模块流量 Service 实现方案

可以通过创建原生Service的方式创建模块的Service,仅当基座与ModuleController部署在同一VPC中时才能够正常提供服务。

由于目前基座与ModuleController并不一定部署在同一个VPC下,两者之间通过MQTT消息队列实现交互。基座node会集成基座所在Pod的IP,模块所在Pod会集成基座node的IP,因此,当基座本身与ModuleController不属于同一个VPC的时候,这里模块的IP实际上是无效的,因此无法对外提供服务。

可能的解决方案是在Service上的LB层做转发,将对应Service的流量转发到基座所在K8S的对应IP的基座服务上。后续将根据实际使用情况对这一问题进行评估与优化。

基座和模块不兼容发布

  1. 首先部署一个module的Deployment,其中Container指定为最新版本的模块代码包地址,nodeAffinity指定新版本基座的名称和版本信息。 此时,这一Deployment会创建出对应的Pod,但是由于还没有新版本的基座创建,因此不会被调度。

  2. 更新基座Deployment,发布新版本镜像,此时会触发基座的替换和重启,基座启动时会告知ModuleController V2控制器,会创建对应版本的node。

  3. 对应版本的基座node创建之后,K8S调度器会自动触发调度,将步骤1中创建的模块Pod调度到基座node上,进行新版本的模块安装,从而实现同时发布。



2 - 5.2 模块发布运维策略

Koupleless 模块发布运维策略

运维策略

为了实现生产环境的无损变更,模块发布运维基于K8S的原生调度能力提供了安全可靠的变更能力。用户可以通过业务需要使用合适的模块Pod部署方式。

调度策略

打散调度:通过Deployment的原生控制方式实现,可以通过PodAffinity配置实现打散调度。

对等和非对等

可以通过选择不同的部署方式实现对等和非对等部署策略。

对等部署

下面提供两种实现方式:

  1. 可以通过将模块部署成为DaemonSet实现,这样每当一个基座node上线时,DaemonSet控制器就会自动为其创建模块Pod,实现对等部署。

    这里需要注意,DaemonSet的滚动更新是先卸后装,请结合业务实际需求进行选择。

  2. 通过Deployment实现,相比DaemonSet,需要额外增加一个组件用于控制模块副本数与基座数量一致(正在建设中,预计下一个版本发布)。支持先装后卸,不会造成中台模式下基座流量损失。

    注意,Deployment虽然会尽量选择打散部署,但是并不能完全保证打散调度,可能会出现统一模块多次部署到同一个基座上,如果要实现强打散调度,需要在部署模块Deployment中添加Pod反亲和配置,示例如下:

apiVersion: apps/v1  # 指定api版本,此值必须在kubectl api-versions中
kind: Deployment  # 指定创建资源的角色/类型
metadata:  # 资源的元数据/属性
    name: test-module-deployment  # 资源的名字,在同一个namespace中必须唯一
    namespace: default # 部署在哪个namespace中
    labels:  # 设定资源的标签
        module-controller.koupleless.io/component: module-deployment # 资源类型标记, 用于module controller管理
spec: # 资源规范字段
    replicas: 1
    revisionHistoryLimit: 3 # 保留历史版本
    selector: # 选择器
        matchLabels: # 匹配标签
            module.koupleless.io/name: biz1
            module.koupleless.io/version: 0.0.1
    strategy: # 策略
        rollingUpdate: # 滚动更新
            maxSurge: 30% # 最大额外可以存在的副本数,可以为百分比,也可以为整数
            maxUnavailable: 30% # 示在更新过程中能够进入不可用状态的 Pod 的最大值,可以为百分比,也可以为整数
        type: RollingUpdate # 滚动更新策略
    template: # 模版
        metadata: # 资源的元数据/属性
            labels: # 设定资源的标签
                module-controller.koupleless.io/component: module # 必要,声明pod的类型,用于module controller管理
                module.koupleless.io/name: biz1
                module.koupleless.io/version: 0.0.1
        spec: # 资源规范字段
            containers:
            - name: biz1
              image: https://serverless-opensource.oss-cn-shanghai.aliyuncs.com/module-packages/test_modules/biz1-0.0.1-ark-biz.jar
              env:
              - name: BIZ_VERSION
                value: 0.0.1
            affinity:
              nodeAffinity:
                requiredDuringSchedulingIgnoredDuringExecution:
                  nodeSelectorTerms: # 基座node选择
                      - matchExpressions:
                        - key: base.koupleless.io/stack
                          operator: In
                          values:
                              - java
                        - key: base.koupleless.io/version
                          operator: In
                          values:
                              - 1.0.0 # 模块可能只能被调度到一些特殊版本的 node 上,如有这种限制,则必须有这个字段。
                        - key: base.koupleless.io/name
                          operator: In
                          values:
                          - base  # 模块可能只能被调度到一些特殊版本的 node 上,如有这种限制,则必须有这个字段。
              podAntiAffinity: # 打散调度核心配置
                  requiredDuringSchedulingIgnoredDuringExecution:
                  - labelSelector:
                      matchLabels:
                          module.koupleless.io/name: biz1 # 与template中的label配置保持一致
                          module.koupleless.io/version: 0.0.1 # 与template中的label配置保持一致
                    topologyKey: topology.kubernetes.io/zone
            tolerations:
              - key: "schedule.koupleless.io/virtual-node" # 确保模块能够调度到基座node上
                operator: "Equal"
                value: "True"
                effect: "NoExecute"

非对等部署:可以通过将模块部署成为Deployment/ReplicaSet实现,此时将根据replica设置进行模块的部署。

分批更新

分批更新策略需要自行实现相关控制逻辑,ModuleController V2能够提供的能力是,当某个基座上先后安装同名不同版本的模块之后,安装时间较早的模块对应Pod会进入BizDeactivate状态,并进入Failed Phase。可结合这一逻辑实现分批更新逻辑。



3 - 5.3 健康检查

背景

健康检查的目的是获取应用在生命周期中的状态,包括:运维阶段和运行阶段的状态,以便用户根据该状态做决策。例如:如果发现应用状态为 DOWN,则表示应用存在故障,用户可以重启或替换机器。

在单应用情况下,健康检查比较简单:

  • 运维阶段状态:
    • 如果正在启动,则为 UNKNOWN;
    • 如果启动失败,则为 DOWN;
    • 如果启动成功,则为 UP。
  • 运行阶段状态:
    • 如果应用各健康检查点健康,则为 UP;
    • 如果应用各健康检查点不健康,则为 DOWN。

在多应用场景下,情况会复杂得多。 我们需要考虑多应用在运维阶段运行阶段的状态对整体应用健康状态的影响。在设计健康检查时,我们需要考虑以下2个问题:

  • 模块运维阶段,模块启动状态是否应该影响整体应用健康状态?

    在不同运维场景下,用户的期望是不同的。 koupleless 中模块运维有三种场景:

场景模块对整体应用健康状态的影响
模块热部署提供配置,让用户自行决定模块热部署结果是否影响应用整体健康状态(默认配置为:不影响整体应用原本的健康状态)
静态合并部署模块部署发生在基座启动时,模块启动状态应该直接影响整体应用的健康状态
模块回放模块回放发生在基座启动时,模块启动状态应该直接影响整体应用的健康状态
  • 模块运行阶段,模块运行状态是否应该影响整体应用健康状态?

    模块运行阶段的状态应该直接影响应用整体健康状态。

在此背景下,我们设计了多应用下的健康检查方案。

使用

前置条件

  • koupleless 版本 >= 1.2.1
  • sofa-ark 版本 >= 2.2.9

获取应用整体健康状态

基座的健康状态有 3 类:

状态含义
UP健康,表示已就绪(readiness)
UNKNOWN正在启动中
DOWN不健康(可能是启动失败,也可能是运行状态不健康)

由于 Koupleless 支持热部署模块,因此用户在获取应用整体健康状态时,可能希望模块部署是否成功影响整体应用健康状态,或不影响。

模块启动是否成功不影响整体应用健康状态(默认)

  • 特点:对于健康的基座,如果模块安装失败,不会影响整体应用健康状态。
  • 使用:和普通 Spring Boot 应用的配置一致,在基座的 application.properties 中配置:
# 或者不配置 management.endpoints.web.exposure.include
management.endpoints.web.exposure.include=health
# 如果需要展示所有信息,则配置以下内容
management.endpoint.health.show-components=always
management.endpoint.health.show-details=always
  • 访问:{baseIp:port}/actuator/health
  • 结果:
{
    // 应用整体健康状态
    "status": "UP",
    "components": {
        // 模块聚合健康状态
        "arkBizAggregate": {
            "status": "UP",
            "details": {
                "biz1:0.0.1-SNAPSHOT": {
                    "status": "UP",
                    // 可以看到模块中所有生效的 HealthIndicator 的健康状态
                    "details": {
                        "diskSpace": {
                          "status": "UP",
                          "details": {
                            "total": 494384795648,
                            "free": 272435396608,
                            "threshold": 10485760,
                            "exists": true
                            }
                        },
                        "pingHe": {
                          "status": "UP",
                          "details": {}
                        }
                    }
                }
            }
        },
        // 启动健康状态
        "masterBizStartUp": {
            "status": "UP",
            // 包括每一个模块的启动状态
            "details": {
                "base:1.0.0": {
                    "status": "UP"
                },
                "biz1:0.0.1-SNAPSHOT": {
                    "status": "UP"
                },
                "biz2:0.0.1-SNAPSHOT": {
                    "status": "DOWN"
                }
            }
        }
    }
}

不同场景下的整体健康状态

场景1:无模块基座启动

状态含义
UP基座健康
UNKNOWN基座正在启动中
DOWN基座不健康

场景2:基座启动时,静态合并部署

状态含义
UP基座和模块都健康
UNKNOWN基座正在启动中/模块正在启动中
DOWN基座启动失败/基座不健康/模块启动失败/模块不健康

场景3:基座启动后,热部署

提供配置,让用户自行决定模块热部署结果是否影响应用整体健康状态(默认配置为:不影响整体应用原本的健康状态)

默认配置:热部署场景下,模块是否安装成功不影响应用整体健康状态,如下:

状态含义
UP基座和模块都健康
UNKNOWN基座正在启动中
DOWN基座启动失败/基座不健康/模块不健康

场景4:基座运行中

状态含义
UP基座和模块都健康
UNKNOWN-
DOWN基座不健康或模块不健康

场景5:基座启动后,模块回放

模块回放是指在基座启动后,自动拉取模块基线,并安装模块。

目前未支持模块回放。

模块启动是否成功影响整体应用健康状态

  • 特点:对于健康的基座,如果模块安装失败,整体应用健康状态也会为失败。
  • 使用:在上述配置之外,需要配置 koupleless.healthcheck.base.readiness.withAllBizReadiness=true,即在基座的 application.properties 中配置:
# 或者不配置 management.endpoints.web.exposure.include
management.endpoints.web.exposure.include=health
# 如果需要展示所有信息,则配置以下内容
management.endpoint.health.show-components=always
management.endpoint.health.show-details=always
# 不忽略模块启动状态
koupleless.healthcheck.base.readiness.withAllBizReadiness=true
  • 访问:{baseIp:port}/actuator/health
  • 结果:
{
    // 应用整体健康状态
    "status": "UP",
    "components": {
        // 模块聚合健康状态
        "arkBizAggregate": {
            "status": "UP",
            "details": {
                "biz1:0.0.1-SNAPSHOT": {
                    "status": "UP",
                    // 可以看到模块中所有生效的 HealthIndicator 的健康状态
                    "details": {
                        "diskSpace": {
                          "status": "UP",
                          "details": {
                            "total": 494384795648,
                            "free": 272435396608,
                            "threshold": 10485760,
                            "exists": true
                            }
                        },
                        "pingHe": {
                          "status": "UP",
                          "details": {}
                        }
                    }
                }
            }
        },
        // 启动健康状态
        "masterBizStartUp": {
            "status": "UP",
            // 包括每一个模块的启动状态
            "details": {
                "base:1.0.0": {
                    "status": "UP"
                },
                "biz1:0.0.1-SNAPSHOT": {
                    "status": "UP"
                }
            }
        }
    }
}

不同场景下的整体健康状态

场景1:无模块基座启动

状态含义
UP基座健康
UNKNOWN基座正在启动中
DOWN基座不健康

场景2:基座启动时,静态合并部署

状态含义
UP基座和模块都健康
UNKNOWN基座正在启动中/模块正在启动中
DOWN基座启动失败/基座不健康/模块启动失败/模块不健康

场景3:基座启动后,热部署

提供配置,让用户自行决定模块热部署结果是否影响应用整体健康状态(默认配置为:不影响整体应用原本的健康状态)

当设置为 koupleless.healthcheck.base.readiness.withAllBizReadiness=true

状态含义
UP基座和模块都健康
UNKNOWN基座正在启动中/模块正在启动中
DOWN基座启动失败/模块启动失败/基座不健康/模块不健康

场景4:基座运行中

状态含义
UP基座和模块都健康
UNKNOWN-
DOWN基座不健康或模块不健康

场景5:基座启动后,模块回放

模块回放是指在基座启动后,自动拉取模块基线,并安装模块。

目前未支持模块回放。

获取单个模块的健康状态

  • 使用:和普通 springboot 的健康检查配置一致,开启 health 节点,即:在模块的 application.properties 中配置:
# 或者不配置 management.endpoints.web.exposure.include
management.endpoints.web.exposure.include=health
  • 访问:{baseIp:port}/{bizWebContextPath}/actuator/info
  • 结果:
{
    "status": "UP",
    "components": {
        "diskSpace": {
            "status": "UP",
            "details": {
                "total": 494384795648,
                "free": 270828220416,
                "threshold": 10485760,
                "exists": true
            }
        },
        "ping": {
            "status": "UP"
        }
    }
}

获取基座、模块和插件信息

  • 使用:和普通 springboot 的健康检查配置一致,开启 info 节点,即:在基座的 application.properties 中配置:
# 注意:如果用户自行配置了 management.endpoints.web.exposure.include,则需要将 health 节点配置上,否则无法访问 health 节点
management.endpoints.web.exposure.include=health,info
  • 访问:{baseIp:port}/actuator/info
  • 结果:
{
    "arkBizInfo": [
      {
        "bizName": "biz1",
        "bizVersion": "0.0.1-SNAPSHOT",
        "bizState": "ACTIVATED",
        "webContextPath": "biz1"
      },
      {
        "bizName": "base",
        "bizVersion": "1.0.0",
        "bizState": "ACTIVATED",
        "webContextPath": "/"
      }
    ],
    "arkPluginInfo": [
        {
            "pluginName": "koupleless-adapter-log4j2",
            "groupId": "com.alipay.sofa.koupleless",
            "artifactId": "koupleless-adapter-log4j2",
            "pluginVersion": "1.0.1-SNAPSHOT",
            "pluginUrl": "file:/Users/lipeng/.m2/repository/com/alipay/sofa/koupleless/koupleless-adapter-log4j2/1.0.1-SNAPSHOT/koupleless-adapter-log4j2-1.0.1-SNAPSHOT.jar!/",
            "pluginActivator": "com.alipay.sofa.koupleless.adapter.Log4j2AdapterActivator"
        },
        {
            "pluginName": "web-ark-plugin",
            "groupId": "com.alipay.sofa",
            "artifactId": "web-ark-plugin",
            "pluginVersion": "2.2.9-SNAPSHOT",
            "pluginUrl": "file:/Users/lipeng/.m2/repository/com/alipay/sofa/web-ark-plugin/2.2.9-SNAPSHOT/web-ark-plugin-2.2.9-SNAPSHOT.jar!/",
            "pluginActivator": "com.alipay.sofa.ark.web.embed.WebPluginActivator"
        },
        {
            "pluginName": "koupleless-base-plugin",
            "groupId": "com.alipay.sofa.koupleless",
            "artifactId": "koupleless-base-plugin",
            "pluginVersion": "1.0.1-SNAPSHOT",
            "pluginUrl": "file:/Users/lipeng/.m2/repository/com/alipay/sofa/koupleless/koupleless-base-plugin/1.0.1-SNAPSHOT/koupleless-base-plugin-1.0.1-SNAPSHOT.jar!/",
            "pluginActivator": "com.alipay.sofa.koupleless.plugin.ServerlessRuntimeActivator"
        }
    ]
}

4 - 5.4 Module Controller 部署

Koupleless Module Controller V2的部署方式

注意:当前 ModuleController v2 仅在 K8S 1.24 版本测试过,没有在其它版本测试,ModuleController V2依赖了部分K8S特性,K8S的版本不能低于V1.10。

资源文件位置

  1. Role 定义
  2. RBAC 定义
  3. ServiceAccount 定义
  4. ModuleControllerV2 部署定义

部署方式

使用 kubectl apply 命令,依次 apply 上述 4 个资源文件,即可完成单实例 ModuleController 部署。

如使用 Module Controller 分片集群能力,指需要将上述部署定义修改为 Deployment 版本,将 Pod Spec 中内容放到 Deployment template 中。

如需在分片集群中使用负载均衡能力,需要在 Module Controller ENV 配置中将 IS_CLUSTER 参数置为 true。

可配置参数解析

环境变量配置

以下是一些可配置的环境变量及其解释:

  • ENABLE_MQTT_TUNNEL

  • 含义: MQTT 运维管道启用标志。设置为 true 表示启用 MQTT 运维管道,如启用,请配置以下相关环境变量。

  • MQTT_BROKER

  • 含义: MQTT 代理的 URL。

  • MQTT_PORT

  • 含义: MQTT 端口号。

  • MQTT_USERNAME

  • 含义: MQTT 用户名。

  • MQTT_PASSWORD

  • 含义: MQTT 密码。

  • MQTT_CLIENT_PREFIX

  • 含义: MQTT 客户端前缀。

  • ENABLE_HTTP_TUNNEL

  • 含义: HTTP 运维管道启用标志。设置为 true 表示启用 HTTP 运维管道,可选择配置以下环境变量。

  • HTTP_TUNNEL_LISTEN_PORT

  • 含义: 模块控制器 HTTP 运维管道监听端口,默认使用 7777。

  • REPORT_HOOKS

  • 含义: 错误上报链接,支持多个链接,用;进行分割,目前仅支持钉钉机器人 webhook。

  • ENV

  • 含义: Module Controller环境,将设置为VNode标签,用于运维环境隔离。

  • IS_CLUSTER

  • 含义: 集群标志,若为 true,将使用集群配置启动 Virtual kubelet。

  • WORKLOAD_MAX_LEVEL

  • 含义: 集群配置,表示 Virtual kubelet 中工作负载计算的最大工作负载级别,默认值为 3,详细计算规则请参考 Module Controller 架构设计。

  • ENABLE_MODULE_DEPLOYMENT_CONTROLLER

  • 含义: Module Deployment Controller 启用标志,若为 true,将启动部署控制器以修改模块部署的副本和基线。

  • VNODE_WORKER_NUM

  • 含义: VNode 并发模块处理线程数,设为 1 表示单线程。

  • CLIENT_ID

  • 含义: 可选配置,Module Controller 实例ID,需保证同环境中全局唯一,默认情况下会生成随机UUID

文档参考

具体的结构和实现介绍请参考文档



5 - 5.5 模块信息查看

Koupleless 模块信息查看

查看某个基座上所有安装的模块名称和状态

kubectl get module -n <namespace> -l koupleless.alipay.com/base-instance-ip=<pod-ip> -o custom-columns=NAME:.metadata.name,STATUS:.status.status

kubectl get module -n <namespace> -l koupleless.alipay.com/base-instance-name=<pod-name> -o custom-columns=NAME:.metadata.name,STATUS:.status.status

查看某个基座上所有安装的模块详细信息

kubectl describe module -n <namespace> -l koupleless.alipay.com/base-instance-ip=<pod-ip>

kubectl describe module -n <namespace> -l koupleless.alipay.com/base-instance-name=<pod-name>

替换<pod-ip>为需要查看的基座ip,<pod-name>为需要查看的基座名称,<namespace>为需要查看资源的namespace

6 - 5.6 错误码

本文主要介绍 Arklet, ModuleController, KouplelessBoard 的错误码。

ErrorCode 规则

两级错误码,支持动态组合,采用大驼峰方式,不同级别错误码之间只能用 “.” 分隔。
如 Arklet.InstallModuleFailed
一级:错误来源
二级:错误类型

Suggestion

简要说明解决方案,供上游操作参考。

Arklet 错误码

一级 错误来源

编码含义
User客户导致的错误
ArkletArklet 自身异常
ModuleController具体上游组件导致的异常
OtherUpstream未知上游导致的异常

二级 错误类型

业务类型错误来源错误类型含义解决方案
通用ArkletUnknownError未知错误(默认)请排查

ModuleControllerInvalidParameter参数校验失败请检查参数
ModuleControllerInvalidRequest操作类型非法请检查请求
OtherUpstreamDecodeURLFailedurl 解析失败请检查 url 是否合法
查询相关ArkletNoMatchedBiz模块查询失败,没有目标 biz 存在-
ArkletInvalidBizName模块查询失败,查询参数 bizName 不能为空请添加查询参数 bizName
安装相关ArkletInstallationRequirementNotMet模块安装条件不满足请检查模块安装的必要参数
ArkletPullBizError拉包失败请重试
ArkletPullBizTimeOut拉包超时请重试
UserDiskFull拉包时,磁盘已满请替换基座
UserMachineMalfunction机器故障请重启基座
UserMetaspaceFullMetaspace超过阈值请重启基座
ArkletInstallBizExecuting模块安装时,当前模块正在安装请重试

ArkletInstallBizTimedOut模块安装时,卸载老模块失败请排查
ArkletInstallBizFailed模块安装时,新模块安装失败请排查
UserInstallBizUserError模块安装失败,业务异常请检查业务代码
卸载相关ArkletUninstallBizFailed卸载失败,当前 biz 还存在在 容器中请排查
ArkletUnInstallationRequirementNotMet模块卸载条件不满足当前模块存在多版本,且卸载的版本是激活状态的,不允许卸载

ModuleController 错误码

一级 错误来源

编码含义
User客户导致的错误
ModuleControllerModuleController 自身异常
KouplelessBoard具体上游组件导致的异常
Arklet具体下游组件导致的异常
OtherUpstream未知上游导致的异常
OtherDownstream未知下游导致的异常

二级 错误类型

业务类型错误来源错误类型含义解决方案
通用ModuleControllerUnknownError未知错误(默认)请排查

OtherUpstreamInvalidParameter参数校验失败请检查参数
ArkletArkletServiceNotFound找不到基座服务请确保基座有Koupleless依赖
ArkletNetworkError网络调用异常请重试
OtherUpstreamSecretAKError签名异常请确认有操作权限
ModuleControllerDBAccessError读写数据库失败请重试
OtherUpstreamDecodeURLFailedurl 解析失败请检查 url 是否合法
ModuleControllerRetryTimesExceeded重试多次失败请排查
ModuleControllerProcessNodeMissed缺少可用的工作节点请稍后重试
ModuleControllerServiceMissed服务缺失请检查ModuleController版本是否含有该模版类型
ModuleControllerResourceConstraned资源受限(线程池、队列等满)请稍后重试
安装相关ArkletInstallModuleTimedOut模块安装超时请重试
Arklet / UserInstallModuleFailed模块安装失败请检查失败原因
ArkletInstallModuleExecuting模块安装中相同模块在安装,请稍后重试
UserDiskFull磁盘已满请替换
卸载相关OtherUpstreamEmptyIPListip 列表为空请输入要卸载的ip

ArkletUninstallBizTimedOut模块卸载超时请重试

ArkletUninstallBizFailed模块卸载失败请排查
基座相关ModuleControllerBaseInstanceNotFound基座实例不存在请确保基座实例存在

KubeAPIServerGetBaseInstanceFailed查询不到基座信息请确保基座实例存在
ModuleControllerBaseInstanceInOperation基座正在运维中请稍后重试
ModuleControllerBaseInstanceNotReady暂未读到基座数据或基座不可用请确保基座可用
ModuleControllerBaseInstanceHasBeenReplaced基座已被替换后续会新增基座实例,请等候
ModuleControllerInsufficientHealthyBaseInstance健康基座不足请扩容
扩缩容ModuleControllerRescaleRequirementNotMet扩缩容条件不满足请检查扩容机器是否足够/请检查缩容比例

⚠️注意:基座运行在不同基座实例上,如:pod。因此 BaseInstanceInOperation, BaseInstanceNotReady, BaseInstanceHasBeenReplaced, InsufficientHealthyBaseInstance 错误码可能指包括基座应用状态或基座实例的状态。

DashBoard 错误码

一级 错误来源

编码含义
KouplelessBoardKouplelessBoard 自身异常
ModuleController具体下游组件导致的异常
OtherUpstream未知上游导致的异常
OtherDownstream未知下游导致的异常

二级 错误类型

业务类型错误来源错误类型含义解决方案
通用KouplelessBoardUnknownError未知错误(默认)

OtherUpstreamInvalidParameter参数校验失败请检查参数
工单KouplelessBoardOperationPlanNotFound工单不存在请排查
KouplelessBoardOperationPlanMutualExclusion工单互斥请重试
内部错误KouplelessBoardInternalError系统内部错误请排查
KouplelessBoardThreadPoolError线程池调用异常请排查
运维ModuleControllerBaseInstanceOperationFailed运维失败请排查
ModuleControllerBaseInstanceUnderOperation运维中请重试
ModuleControllerBaseInstanceOperationTimeOut运维超时请重试
ModuleControllerOverFiftyPercentBaseInstancesUnavaliable超过50% 机器流量不可达请检查基座实例
KouplelessBoardBaselineInconsistency一致性校验失败(基线不一致)请排查
外部服务调用错误OtherDownstreamExternalError外部服务调用错误请排查
KouplelessBoardNetworkError外部服务调用超时请重试