1 - 模块上线与下线

模块上线

在 K8S 集群中创建一个 ModuleDeployment CR 资源即可完成模块上线,例如:

kubectl apply -f sofa-serverless/module-controller/config/samples/module-deployment_v1alpha1_moduledeployment.yaml --namespace yournamespace

其中 deployment_v1alpha1_moduledeployment.yaml 替换成您的 ModuleDeployment 定义 yaml 文件,yournamespace 替换成您的 namespace。module-deployment_v1alpha1_moduledeployment.yaml 完整内容如下:

apiVersion: serverless.alipay.com/v1alpha1
kind: ModuleDeployment
metadata:
  labels:
    app.kubernetes.io/name: moduledeployment
    app.kubernetes.io/instance: moduledeployment-sample
    app.kubernetes.io/part-of: module-controller
    app.kubernetes.io/managed-by: kustomize
    app.kubernetes.io/created-by: module-controller
  name: moduledeployment-sample
spec:
  baseDeploymentName: dynamic-stock-deployment
  template:
    spec:
      module:
        name: provider
        version: '1.0.2'
        url: http://serverless-opensource.oss-cn-shanghai.aliyuncs.com/module-packages/stable/dynamic-provider-1.0.2-ark-biz.jar
  replicas: 2
  operationStrategy:  # 此处可自定义发布运维策略
    upgradePolicy: installThenUninstall
    needConfirm: true
    useBeta: false
    batchCount: 2
  schedulingStrategy: # 此处可自定义调度策略
    schedulingPolicy: Scatter

ModuleDeployment 所有字段可参考 ModuleDeployment CRD 字段解释
如果要自定义模块发布运维策略(比如分组、Beta、暂停等)可配置 operationStrategy 和 schedulingStrategy,具体可参考模块发布运维策略
样例演示的是使用 kubectl 方式,直接调用 K8S APIServer 创建 ModuleDeployment CR 一样能实现模块分组上线。

模块下线

在 K8S 集群中删除一个 ModuleDeployment CR 资源即可完成模块下线,例如:

kubectl delete yourmoduledeployment --namespace yournamespace

其中 yourmoduledeployment 替换成您的 ModuleDeployment 名字(ModuleDeployment 的 metadata name),yournamespace 替换成您的 namespace。
如果要自定义模块发布运维策略(比如分组、Beta、暂停等)可配置 operationStrategy 和 schedulingStrategy,具体可参考模块发布运维策略
样例演示的是使用 kubectl 方式,直接调用 K8S APIServer 删除 ModuleDeployment CR 一样能实现模块分组下线。



2 - 模块发布

模块发布

修改 ModuleDeployment.spec.template.spec.module.version 字段和 ModuleDeployment.spec.template.spec.module.url(可选)字段并重新 apply,即可实现新版本模块的分组发布,例如:

kubectl apply -f sofa-serverless/module-controller/config/samples/module-deployment_v1alpha1_moduledeployment.yaml --namespace yournamespace

其中 deployment_v1alpha1_moduledeployment.yaml 替换成您的 ModuleDeployment 定义 yaml 文件,yournamespace 替换成您的 namespace。module-deployment_v1alpha1_moduledeployment.yaml 完整内容如下:

apiVersion: serverless.alipay.com/v1alpha1
kind: ModuleDeployment
metadata:
  labels:
    app.kubernetes.io/name: moduledeployment
    app.kubernetes.io/instance: moduledeployment-sample
    app.kubernetes.io/part-of: module-controller
    app.kubernetes.io/managed-by: kustomize
    app.kubernetes.io/created-by: module-controller
  name: moduledeployment-sample
spec:
  baseDeploymentName: dynamic-stock-deployment
  template:
    spec:
      module:
        name: provider
        version: '2.0.0'  # 注意:这里将 version 字段从 1.0.2 修改为了 2.0.0 即可实现模块新版本分组发布
        # 注意:url 字段可以修改为新的 jar 包地址,也可以不用修改
        url: http://serverless-opensource.oss-cn-shanghai.aliyuncs.com/module-packages/stable/dynamic-provider-1.0.2-ark-biz.jar
  replicas: 2
  operationStrategy:
    upgradePolicy: install_then_uninstall
    needConfirm: true
    grayTimeBetweenBatchSeconds: 0
    useBeta: false
    batchCount: 2
  schedulingStrategy:
    schedulingPolicy: scatter

如果要自定义模块发布运维策略可配置 operationStrategy,具体可参考模块发布运维策略
样例演示的是使用 kubectl 方式,直接调用 K8S APIServer 修改 ModuleDeployment CR 一样能实现分组发布。

模块回滚

重新修改 ModuleDeployment.spec.template.spec.module.version 字段和 ModuleDeployment.spec.template.spec.module.url(可选)字段并重新 apply,即可实现模块的分组回滚发布。



3 - 基座和模块不兼容发布

步骤 1

修改基座代码和模块代码,然后将基座构建为新版本的镜像,将模块构建为新版本的代码包(Java 就是 Jar 包)。

步骤 2

修改模块对应的 ModuleDeployment.spec.template.spec.module.url 为新的模块代码包地址。

步骤 3

使用 K8S Deployment 发布基座到新版本镜像(会触发基座容器的替换或重启),基座容器启动时会拉取 ModuleDeployment 上最新的模块代码包地址,从而实现了基座与模块的不兼容变更(即同时发布)。



4 - 模块扩缩容与替换

模块扩缩容

修改 ModuleDeployment CR 的 replicas 字段并重新 apply,即可实现模块扩缩容,例如:

kubectl apply -f sofa-serverless/module-controller/config/samples/module-deployment_v1alpha1_moduledeployment.yaml --namespace yournamespace

其中 deployment_v1alpha1_moduledeployment.yaml 替换成您的 ModuleDeployment 定义 yaml 文件,yournamespace 替换成您的 namespace。module-deployment_v1alpha1_moduledeployment.yaml 完整内容如下:

apiVersion: serverless.alipay.com/v1alpha1
kind: ModuleDeployment
metadata:
  labels:
    app.kubernetes.io/name: moduledeployment
    app.kubernetes.io/instance: moduledeployment-sample
    app.kubernetes.io/part-of: module-controller
    app.kubernetes.io/managed-by: kustomize
    app.kubernetes.io/created-by: module-controller
  name: moduledeployment-sample
spec:
  baseDeploymentName: dynamic-stock-deployment
  template:
    spec:
      module:
        name: provider
        version: '1.0.2'
        url: http://serverless-opensource.oss-cn-shanghai.aliyuncs.com/module-packages/stable/dynamic-provider-1.0.2-ark-biz.jar
  replicas: 2  # 注意:在此处修改模块实例 Module 副本数,实现扩缩容
  operationStrategy:
    upgradePolicy: installThenUninstall
    needConfirm: true
    useBeta: false
    batchCount: 2
  schedulingStrategy: # 此处可自定义调度策略
    schedulingPolicy: Scatter  

如果要自定义模块发布运维策略可配置 operationStrategy 和 schedulingStrategy,具体可参考模块发布运维策略
样例演示的是使用 kubectl 方式,直接调用 K8S APIServer 修改 ModuleDeployment CR 一样能实现扩缩容。

模块替换

在 K8S 集群中删除一个 Module CR 资源即可完成模块替换,例如:

kubectl delete yourmodule --namespace yournamespace

其中 yourmodule 替换成您的 Module CR 实体名字(Module 的 metadata name),yournamespace 替换成您的 namespace。
样例演示的是使用 kubectl 方式,直接调用 K8S APIServer 删除 Module CR 一样能实现模块替换。



5 - 模块发布运维策略

运维策略

为了实现生产环境的无损变更,模块发布运维提供了安全可靠的变更能力,用户可以在 ModuleDeployment CR spec 的 operationStrategy 中,配置发布运维的变更策略。operationStrategy 内具体字段解释如下:

字段名字段解释取值范围取值解释
batchCount分批发布运维批次数1 - N分 1 - N 批次发布运维模块
useBeta是否启用 beta 分组发布。启用 beta 分组发布会让第一批次只有一个 IP 做灰度,剩下的 IP 再划分成 (batchCount - 1) 批true 或 falsetrue 表示启用 beta 分组
false 表示不启用 beta 分组
needConfirm是否启用分组确认。启用后每一批次模块发布运维后,都会暂停,修改 ModuleDeployment.spec.pause 字段为 false 后,则运维继续true 或 falsetrue 表示启用分组确认
false 表示不启用分组确认
grayTime每一个发布运维批次完成后,sleep 多少时间才能继续执行下一个批次0 - N批次间的灰度时长,单位秒,0 表示批次完成后立即执行下一批次,N 表示批次完成后 sleep N 秒再执行下一批次

调度策略

可以为基座 K8S Pod Deployment 配置 Label “serverless.alipay.com/max-module-count”,指定每个 Pod 最多可以安装多少个模块。支持配置为 0 - N 的整数。模块支持打散调度和堆叠调度。
打散调度:设置 ModuleDeployment.spec.schedulingStrategy.schedulingPolicy 为 scatter。打散调度表示在模块上线、扩容、替换时,优先把模块调度到模块数最少的机器上去安装。
堆叠调度:设置 ModuleDeployment.spec.schedulingStrategy.schedulingPolicy 为 stacking。堆叠调度表示在模块上线、扩容、替换时,优先把模块调度到模块数最多且没达到基座 max-module-count 上限的机器上去安装。

保护机制

(正在开发中,10.15 上线) 您可以配置 ModuleDeployment.spec.maxUnavailable 指定模块在发布运维过程中,最多有几个模块副本可以同时处在不可用状态。模块发布运维需要更新 K8S Service 并卸载模块,会导致该模块副本不可用。配置为 50% 表示模块发布运维的一个批次,必须保证至少 50% 的模块副本可用,否则 ModuleDeployment.status 会展示报错信息。

对等和非对等

您可以配置 ModuleDeployment.spec.replicas 指定模块采用对等还是非对等部署架构。
非对等架构:设置 ModuleDeployment.spec.replicas 为 **0 - N **表示非对等架构。非对等架构下必须要为 ModuleDeployment、ModueRepicaSet 设置副本数,因此非对等架构下支持模块的扩容和缩容操作。
对等架构:设置 ModuleDeployment.spec.replicas 为 **-1 表示对等架构。**对等架构下,K8S Pod Deployment 有多少副本数模块就自动安装到多少个 Pod,模块的副本数始终与 K8S Pod Deployment 副本数一致。因此对等架构下不支持模块的扩缩容操作。对等架构正在建设中,预计 10.30 发布。



6 - 独立使用 Arklet

Arklet 作为 SOFAServerless 模块发布运维的 Agent(定位类似 K8S 的 Kubelet),可以完全脱离 ModuleController 独立使用。它暴露了一组安装卸载模块的 HTTP 接口,从而可以让 SOFAServerless 对接到您自己的发布运维平台,接口文档详见此处



7 - 模块信息查看

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

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

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

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

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

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

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

8 - 模块Service

ModuleService 简介

K8S 通过 Service ,将运行在一个或一组 Pod 上的网络应用程序公开为网络服务。 模块也支持 Module 相关的 Service ,在模块发布时自动创建一个 service 来服务模块,将安装在一个或一组 Pod 的模块公开为网络服务。 具体见:OperationStrategy.ServiceStrategy

apiVersion: serverless.alipay.com/v1alpha1
kind: ModuleDeployment
metadata:
  labels:
    app.kubernetes.io/name: moduledeployment
    app.kubernetes.io/instance: moduledeployment-sample
    app.kubernetes.io/part-of: module-controller
    app.kubernetes.io/managed-by: kustomize
    app.kubernetes.io/created-by: module-controller
  name: moduledeployment-sample-provider
spec:
  baseDeploymentName: dynamic-stock-deployment
  template:
    spec:
      module:
        name: provider
        version: '1.0.2'
        url: http://serverless-opensource.oss-cn-shanghai.aliyuncs.com/module-packages/stable/dynamic-provider-1.0.2-ark-biz.jar
  replicas: 1
  operationStrategy:
    needConfirm: false
    grayTimeBetweenBatchSeconds: 120
    useBeta: false
    batchCount: 1
    upgradePolicy: install_then_uninstall
    serviceStrategy:
      enableModuleService: true
      port: 8080
      targetPort: 8080
  schedulingStrategy:
    schedulingPolicy: scatter

字段解释

OperationStrategy.ServiceStrategy 字段解释如下:

字段解释取值范围
EnableModuleService开启模块servicetrue or false
Port公开的端口1 到 65535
TargetPortpod上要访问的端口1 到 65535

示例

kubectl apply -f sofa-serverless/module-controller/config/samples/module-deployment_v1alpha1_moduledeployment_provider.yaml --namespace yournamespace

自动创建的模块的 service

apiVersion: v1
kind: Service
metadata:
  creationTimestamp: "2023-11-03T09:52:22Z"
  name: dynamic-provider-service
  namespace: default
  resourceVersion: "28170024"
  uid: 1f85e468-65e3-4181-b40e-48959a069df5
spec:
  clusterIP: 10.0.147.22
  clusterIPs:
  - 10.0.147.22
  externalTrafficPolicy: Cluster
  internalTrafficPolicy: Cluster
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - name: http
    nodePort: 32232
    port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    module.serverless.alipay.com/dynamic-provider: "true"
  sessionAffinity: None
  type: NodePort
status:
  loadBalancer: {}

9 - 所有 K8S 资源定义及部署方式

资源文件位置

  1. ModuleDeployment CRD 定义
  2. ModuleReplicaset CRD 定义
  3. ModuleTemplate CRD 定义
  4. Module CRD 定义
  5. Role 定义
  6. RBAC 定义
  7. ServiceAccount 定义
  8. ModuleController 部署定义

部署方式

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