diff --git a/docs/deploy/deploy_on_k8s/index.md b/docs/deploy/deploy_on_k8s/index.md new file mode 100644 index 0000000000000000000000000000000000000000..7097bc8fa65baf32638b38733dd29aa938bb9c20 --- /dev/null +++ b/docs/deploy/deploy_on_k8s/index.md @@ -0,0 +1,83 @@ + # 在 Kubernetes 上部署 + +```{eval-rst} +.. toctree:: + :glob: + :maxdepth: 1 + :hidden: + + single-node-deployment + production/index.md +``` + +本节将介绍如何在 Kubernetes 上部署openYuanrong集群。 + +## 概述 + +openYuanrong集群由主节点 pod 和从节点 pod 组成。 + +![](../../images/4bf29e7902e9a206c4a8af1bb48e4ec8_564x427.png) + +- 学习和开发可参考[快速部署](./single-node-deployment.md),使用默认配置在单节点或多节点 Kubernetes 集群上部署openYuanrong。 + +- 生产环境部署可参考[生产部署](./production/index.md),包含配置项介绍、安全、集群运维等更多内容。 + +### 主节点 pod + +主节点 pod 用于管理集群,负责全局函数调度、请求转发等工作。包含的组件有 function master、FaaS manager、FaaS scheduler、FaaS controller、fronted、meta service、admin service、function repository、IAM server 及开源 MinIO、etcd。 + +### 从节点 pod + +从节点 pod 用于运行分布式任务,部署的openYuanrong组件有 function agent、function proxy、data worker 及 runtime manager。 + +### 组件介绍 + +- **function master** + + 负责拓扑管理、全局函数调度、函数实例生命周期管理及 function agent 组件的扩缩容。部署形式为 [Deployment](https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/deployment/){target="_blank"},一主多备。 +- **FaaS controller** + + 负责管理 FaaS manager、FaaS scheduler 及 frontend 组件。它是由 function master 创建的openYuanrong系统函数。 +- **FaaS manager** + + 负责租约申请与回收,清理过期连接信息。它是由 FaaS controller 创建的openYuanrong系统函数。 +- **FaaS scheduler** + + 负责 FaaS 函数的调度。它是由 FaaS controller 创建的openYuanrong系统函数。 +- **frontend** + + 提供 REST API 用于函数调用、流订阅等数据处理。它是由 FaaS controller 创建的openYuanrong系统函数。 +- **meta service** + + 提供 REST API 用于函数创建、资源池创建等管理操作。部署形式为 [Deployment](https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/deployment/){target="_blank"}。 +- **admin service** + + 提供部署函数接口,当前仅在用命令工具 yr 部署函数时使用。可以不部署,使用 meta service 组件提供的函数管理 API 替代,该组件即将废弃。 +- **function repository** + + 提供函数代码包上传 MinIO 接口,当前仅在用命令工具 yr 部署函数时使用。可以不部署,使用 MinIO 客户端工具或者前端页面上传函数代码包替代,该组件即将废弃。 +- **IAM server** + + 负责多租鉴权与认证。部署形式为 [Deployment](https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/deployment/){target="_blank"},一主多备。如果无相关需求或已有认证鉴权平台,可以不部署。 +- **MinIO** + + 第三方开源组件,用于存储用户上传的函数代码包。可以不部署,使用 OBS 服务替代或把函数代码包存放在 k8s 的所有节点相同路径下,并配置函数为本地代码方式。 +- **etcd** + + 第三方开源组件,用于存储集群组件注册信息、函数元数据以及实例状态等信息。 +- **function proxy** + + 负责消息转发、本地函数调度及实例生命周期管理。部署形式为 [DaemonSet](https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/daemonset/){target="_blank"}。 +- **function agent** + + 最小资源单元,负责函数代码包下载和解压、网络安全隔离配置等。部署形式为 [Deployment](https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/deployment/){target="_blank"},它与 runtime manager 在一个 pod 内。 +- **runtime manager** + + 负责 cpu、memory 等资源采集和上报、函数进程生命周期管理等。部署形式为 [Deployment](https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/deployment/){target="_blank"},它与 function agent 在一个 pod 内。 +- **data worker** + + 提供数据对象的存取等能力。部署形式为 [DaemonSet](https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/daemonset/){target="_blank"}。 + +### Pod 资源池 + +Pod 资源池用于运行函数实例,原理上基于 K8s Deployment 工作负载实现,包括 function agent 和 function manager 两个容器镜像。根据您实际业务函数需要,可以在部署时配置 Pod 资源池的 CPU、内存、副本数量等信息,也可以通过[资源池管理 API](../../multi_language_function_programming_interface/api/meta_service/pod_pool_management/index.md) 在部署后动态创建。 diff --git a/docs/deploy/deploy_on_k8s/production/config-parameters.md b/docs/deploy/deploy_on_k8s/production/config-parameters.md new file mode 100644 index 0000000000000000000000000000000000000000..2d67648ba9e36e815a25de51673eda74d9044f5f --- /dev/null +++ b/docs/deploy/deploy_on_k8s/production/config-parameters.md @@ -0,0 +1,490 @@ +# 部署参数表 + +## 通用配置 + +表 1 + +| 配置项 | 默认值 | 说明 | +|---------------------------------------------------------------|-----------------|----------------------------------------------------------------------------------------------------------------------------------------| +| .Values.global.timeout | 900 | 开发面组件内部访问超时,单位: s, 可保持默认配置 | +| .Values.global.version | version | openYuanrong版本号,可保持默认配置 | +| .Values.global.namespace | default | k8s 命名空间,可保持默认配置 | +| .Values.global.enableNonPreemptive | false | daemonSet 组件是否开启自定义 PriorityClassName, 开启后设置为 proxy-custom-priority,且 pod 为非抢占式 | +| .Values.global.clusterId | | 集群 ID,可保持默认配置 | +| .Values.global.imagePullSecrets | default-secret | 函数系统组件镜像拉取 secret, 保持默认配置 | +| .Values.global.imageRegistry | cd-docker-hub.szxy5.artifactory.cd-cloud-artifact.tools.xxx.com/yuanrong_euleros_x86 | 组件镜像仓配置,建议修改 | +| .Values.global.images | | 组件镜像版本配置,建议修改 | +| .Values.global.resources | | 组件资源配置,可根据集群实际可用资源进行修改 | +| .Values.global.port | | 组件端口配置,保持默认配置 | +| .Values.global.replicas | | 组件副本数,可保持默认配置 | +| .Values.global.hpa | | 组件 HPA 配置,可保持默认配置 | +| .Values.global.network.elbId | | elb 配置,CCE 环境可配置 | + +表 2 + +| 配置项 | 默认值 | 说明 | +|---------------------------------------------------------------|------------|-----------------------------------------------------------------------------------------------------------------------------| +| .Values.global.common.decryptAlgorithm | GCM | 加密算法,取值 GCM、CBC、STS、NO_CROPTO | +| .Values.global.common.electionMode | k8s | 选主模式,取值 k8s,etcd | +| .Values.global.common.stateStorageType | datasystem | 状态存储类型 | +| .Values.global.common.secretKeyEnable | false | 开启后,部署前需要提前创建 local-auth | +| .Values.global.common.maxGrpcSize | 4 | grpc 请求消息限制,单位:MB,范围 4-10240 | +| .Values.global.common.driverEnable | true | 是否开启 driver 模式 | +| .Values.global.common.maxStorageOperateRetryTimes | 5 | etcd 最大重试次数,范围 1-1000 | +| .Values.global.common.systemTimeout | 60000 | 组件超时时间,单位:ms, 范围 3000-3600000 | +| .Values.global.common.busproxyServiceTTL | 60000 | Busproxy 服务 TTL 时间,单位:ms | +| .Values.global.common.enablePrintResourceView | false | 调度时是否打印资源视图,用于调试 | +| .Values.global.common.functionAgentMgrRetryTimes | 9 | local-scheduler 请求 function-agent 重试次数,配置范围 0-100 | +| .Values.global.common.functionAgentMgrRetryInterval | 20000 | local-scheduler 请求 function-agent 重试间隔,单位:ms, 配置范围 5000-600000 | +| .Values.global.common.workerTaintExcludes | | 对于某些节点存在特定 labels,不部署 worker 时,不打污点 | +| .Values.global.common.deletePodGracePeriodSeconds | 5 | scalar 删除 pod 优雅退出时间,单位:s | +| .Values.global.common.masterHostNetworkEnable | false | function-master 是否开启主机网络(如果黄区环境组件通信存在问题,可以修改为 true) | +| .Values.global.common.concurrentNumUpperLimit | 1000 | faas 函数允许配置的最大并发度 | +| .Values.global.common.schedulePlugins | | 调度插件配置,建议保持默认配置 | +| .Values.global.common.scheduleRelaxed | -1 | 大于 0 启用宽松调度策略。当调度选中 scheduleRelaxed 个节点或者 pod 后即退出流程,不遍历所有节点或者 pod . 默认为 -1 (或 0 ) 表示需要遍历所有节点或 pod 。 warn :当 > 0 时会降低调度的准确性 | +| .Values.global.common.prioritySchedule.maxPriority | 0 | 为 0 时关闭实例优先级调度。 当 > 0 时使能实例优先级调度,maxPriority 表示集群支持的实例最大优先级 | +| .Values.global.common.prioritySchedule.enablePreemption | false | 使能调度抢占功能(高优先级实例可以抢占低优先级被配置为可抢占的实例),仅 maxPriority > 0 生效 | +| .Values.global.common.instanceClusterList | | 预留实例集群名称列表,多个使用,分隔,固定包含 cluster001 | +| .Values.global.common.maxFunctionVersion | 8 | 对于一个函数,允许最多发布的版本数量 | +| .Values.global.common.maxInstanceLabel | 100 | 对于同一个函数版本,一个集群内允许最多创建的标签数量 | + +## IAM 与租户隔离配置 + +| 配置项 | 默认值 | 说明 | +|---------------------------------------------------------------|-------|----------------------------------------------------------------------------------------------------------------------------------------| +| .Values.global.iam.enable | false | 是否开启 iam 鉴权,可关闭 | +| .Values.global.iam.tokenExpiredTimeSpan | 86400 | iam token 过期时间,单位:s, 范围 720-604800 | +| .Values.global.iam.credentialType | token | iam 鉴权凭据类型, 可选值: token, AK/SK | +| .Values.global.tenantIsolation.affinity.enable | true | openYuanrong集群模式容器部署,是否支持租户强亲和的调度,是多租户隔离的基础。 | +| .Values.global.tenantIsolation.affinity.tenantPodReuseTimeWindow | 10 | openYuanrong集群模式容器部署, function_agent POD 上的租户实例都被删除或 Fatal 状态,会删除 function_agent POD, 删除前为同一个租户预留的 POD 复用的时间窗口,单位 s。 | +| .Values.global.tenantIsolation.ipv4.enable | false | openYuanrong集群模式容器部署,承载租户函数的 function_agent POD 是否开启多租户间的网络隔离。 | +| .Values.global.tenantIsolation.ipv4.tcpPortWhitelist | | function-agent POD 网络隔离开启下 tcp 端口白名单,多个端口使用 ',' 间隔 | +| .Values.global.tenantIsolation.ipv4.udpPortWhitelist | | function-agent POD 网络隔离开启下 udp 端口白名单,多个端口使用 ',' 间隔 | +| .Values.global.tenantIsolation.thirdPartyWhitelist | | 租户网络隔离,第三方服务配置白名单。 规则:"完整服务域名,IP,端口 1/协议,端口 2/协议;" 用;分隔多条记录,注意:IP 可能为 None,如未指定 IP,填写"None",根据服务域名,在集群内解析。 | + +thirdPartyWhitelist 默认配置 "kubernetes.default.svc.cluster.local,None,443/TCP;minio.default.svc.cluster.local,None,9000/TCP;ds-core-etcd.default.svc.cluster.local,None,2379/TCP,2380/TCP;ds-core-etcd-headless.default.svc.cluster.local,None,2379/TCP,2380/TCP;", 按照实际网络环境调整 + +## 代码包配置 + +| 配置项 | 默认值 | 说明 | +|---------------------------------------------------------------|-----------------|----------------------------------------------------------------------------------------------------------------------------------------| +| .Values.global.common.deployDir | /dcache | 代码包部署目录 | +| .Values.global.common.storageType | s3 | 代码包存储类型,取值 s3,local | +| .Values.global.common.zipFile.unzipFileSizeMax | 600 | 用户代码包解压后允许最大值,单位:MB, 范围 10-10485760 | +| .Values.global.common.zipFile.zipFileSizeMax | 300 | 用户代码压缩包允许最大值,单位:MB, 范围 10-10485760 | +| .Values.global.common.zipFile.fileCountsMax | 30000 | 用户代码包允许最大文件个数,范围 10-30000 | +| .Values.global.common.zipFile.dirDepthMax | 20 | 用户代码包允许最大深度,范围 1-50 | +| .Values.global.common.zipFile.signatureValidationEnable | false | 用户代码包是否开启一致性校验,下载代码检查 sha512 值 | +| .Values.global.common.layer.layerMaxNumber | 5 | 允许最大层数量 | +| .Values.global.common.codeAgingTime | 0 | 代码包老化时间,配置整数,单位:s, 范围 0-3600, 当开启多租隔离时,建议该值小于 tenantPodReuseTimeWindow 配置值 | + +## 系统函数配置 + +| 配置项 | 默认值 | 说明 | +|---------------------------------------------------------------|-----------------|---------------------------------------------------| +| .Values.global.common.functionBootstrapEnable | true | 是否拉起系统函数 | +| .Values.global.common.functionBootstrapRetryPeriod | 5000 | 系统函数监控间隔,单位:ms | +| .Values.global.systemFunc.faasController | | faas-controller 函数 cpu、mem、实例数配置 | +| .Values.global.systemFunc.faasFrontend | | faas-frontend 函数 cpu、mem、实例数配置 | +| .Values.global.systemFunc.faasFrontend.invokeMaxRetryTimes | 5 | faas-frontend 与其他系统函数最大重试次数 | +| .Values.global.systemFunc.faasFrontend.retry.instanceExceptionRetry | true | 是否开启 faas-frontend 与其他系统函数调用重试 | +| .Values.global.systemFunc.faasFrontend.serverReadTimeout | 0 | frontend 从客户端读取请求超时时间,超时后关闭连接,默认不超时,单位:s | +| .Values.global.systemFunc.faasFrontend.serverWriteTimeout | 0 | frontend 向客户端写入响应超时时间,超时后关闭连接,默认不超时,单位:s | +| .Values.global.systemFunc.faasFrontend.clientIdleTimeout | 130 | frontend 优雅退出时,等待客户端连接最大空闲时间,单位:s | +| .Values.global.systemFunc.faasScheduler | | faas-scheduler 函数 cpu、mem、实例数配置 | +| .Values.global.systemFunc.faasManager | | faasManager 函数 cpu、mem、实例数配置(暂不支持) | +| .Values.global.systemFunc.faasManager | | faasManager 函数 cpu、mem、实例数配置(暂不支持) | +| .Values.global.systemFunc.tlsConfig | | 系统函数安全证书配置 | +| .Values.global.systemFunc.urpcEnabled | false | 是否开启 urpc, 安全环境可开启 | +| .Values.global.systemFunc.httpsEnabled | false | frontend 开启 https,安全环境可开启 | +| .Values.global.systemFunc.actorLeaseRenewMinute| 5 | remote client lease 超时销毁时间,只能为整数,必须大于等于 2 ,单位:min | +| .Values.global.systemUpgradeConfig.enable | false | 是否开启系统升级监听开关 | +| .Values.global.systemUpgradeConfig.azID | 0 | 集群 AZ ID | +| .Values.global.systemUpgradeConfig.systemUpgradeKey | /hms-caas/edgems/upgrade-zones | 系统升级监听 key | +| .Values.global.systemUpgradeConfig.systemUpgradeWatchAddress | | 系统升级监听地址 | + +## 资源池配置 + +| 配置项 | 默认值 | 说明 | +|---------------------------------------------------------------|-----------------|----------------------------------------------------------------------------------------------------------------------------------------| +| .Values.global.pool.gracePeriodSeconds | 1 | 默认资源池 pod 优雅退出时间配置,单位:s | +| .Values.global.pool.accelerator | 1 | 异构资源名称,支持 xxx-Ascend310、xxx-Ascend310P、xxx-Ascend910、xxx-Ascend910B、nvidia-gpu、amd-gpu | +| .Values.global.pool.readinessProbeFailureThreshold | 3 | agent 就绪探针失败阈值 | +| .Values.global.pool.livenessProbeFailureThreshold | 3 | agent 存活探针失败阈值 | + +默认资源池配置参考 + +```yaml +global: + pools: + - id: default + size: 1 + resources: + requests: + cpu: "3000m" + memory: "6144Mi" + limits: + cpu: "3000m" + memory: "6144Mi" +``` + +NPU 资源池配置参考 + +```yaml +global: + pools: + - id: npu-pool1 + size: 1 + resources: + requests: + cpu: "125m" + memory: "256Mi" + xxx.com/Ascend910: "1" + limits: + cpu: "400m" + memory: "256Mi" + xxx.com/Ascend910: "1" + environment: + NPU_COLLECTION_MODE: "all" +``` + +## 限流配置 + +| 配置项 | 默认值 | 说明 | +|---------------------------------------------------------------|-----------------|----------------------------------------------------------------------------------------------------------------------------------------| +| .Values.global.rateLimit.admin.enable | false | 是否开启 admin 限流 | +| .Values.global.rateLimit.admin.totalConcurrent | 1 | 总并发量限流配置 | +| .Values.global.rateLimit.admin.tenantConcurrent | 1 | 单租户并发量限流配置 | +| .Values.global.rateLimit.admin.tenantDaily | 1 | 单租户日调用量限流配置 | +| .Values.global.rateLimit.invokeRateLimit.enable | false | 是否开启 function-proxy invoke 请求限流 | +| .Values.global.rateLimit.invokeRateLimit.lowThreshold | 0.6 | 开启限流内存低水位 | +| .Values.global.rateLimit.invokeRateLimit.highThreshold | 0.8 | 开启限流内存高水位 | +| .Values.global.rateLimit.invokeRateLimit.msgSize | 20480 | 消息限制 | +| .Values.global.rateLimit.createRateLimit.enable | false | function-proxy 节点范围 POSIX Create 请求接口租户粒度限流开关 | +| .Values.global.rateLimit.createRateLimit.tokenBucketCapacity | 1000 | function-proxy 节点范围 POSIX Create 请求接口租户粒度限流,令牌桶容量,也是限制 create 的最大速率 | + +## runtime 配置 + +| 配置项 | 默认值 | 说明 | +|---------------------------------------------------------------|-----------------|----------------------------------------------------------------------------------------------------------------------------------------| +| .Values.global.runtime.serverModeEnable | true | 是否开启 Server 反转 | +| .Values.global.runtime.killProcessTimeoutSeconds | 0 | 支持用户配置优雅退出(SIGINT->SIGKILL)的超时时间(单位:s),默认立即删除,资源回收 | +| .Values.global.runtime.metricsCollectorType | proc | runtime 指标采集类型 | +| .Values.global.runtime.runtimeShutdownTimeoutSeconds | 600 | runtime 默认优雅退出时间,单位:s | +| .Values.global.runtime.runtimeHeartbeatTimeoutMS | 5000 | runtime 心跳超时时间,单位:ms | +| .Values.global.runtime.runtimeMaxHeartbeatTimeoutTimes | 5 | runtime 最大心跳超时次数 | +| .Values.global.runtime.minInstanceCpuSize | 300 | 允许实例最小 cpu | +| .Values.global.runtime.maxInstanceCpuSize | 16000 | 允许实例最大 cpu | +| .Values.global.runtime.minInstanceMemorySize | 128 | 允许实例最小 mem | +| .Values.global.runtime.maxInstanceMemorySize | 1073741824 | 允许实例最大 mem | +| .Values.global.runtime.migratePrefix | | 用于区分 NPU 实例 | +| .Values.global.runtime.taintToleranceList | | NPU 实例迁移时,可容忍的污点列表 | +| .Values.global.runtime.migrateEnable | false | 是否开启节点打上污点,NPU 实例迁移 | +| .Values.global.runtime.npuCollectionMode | all |npu 信息采集模式,取值:all, count, hbm, sfmd, topo, off | +| .Values.global.runtime.gpuCollectionEnable | false | 是否开启 gpu 采集 | +| .Values.global.runtime.useAscendCustomConfig | false | 是否开启 ascend 定制配置 | +| .Values.global.runtime.massifEnable | false | 是否开启 massif,用于调试 | +| .Values.global.runtime.runtimeDsConnectTimeout | 60 | 连接数据系统超时时间 | +| .Values.global.runtime.fsGroup | 1002 | runtime-manager sn 用户 ID | +| .Values.global.runtime.diskUsageMonitor.path | /dcache | 自定义磁盘监控目录,可配置多个目录,采用 `;` 分隔,不建议配置根目录 | +| .Values.global.runtime.diskUsageMonitor.limit | -1 | 磁盘限额,单位:MB, -1 代表不限制 | +| .Values.global.runtime.diskUsageMonitor.snuserDirSizeLimit | -1 | /home/snuser 目录磁盘限额,单位:MB, -1 代表不限制 | +| .Values.global.runtime.diskUsageMonitor.tmpDirSizeLimit | -1 | tmp 目录磁盘限额(包含 /tmp,/var/tmp 目录,单位:MB, -1 代表不限制 | +| .Values.global.runtime.diskUsageMonitor.duration | 1000 | 磁盘监控间隔时间,单位:ms | +| .Values.global.runtime.diskUsageMonitor.notifyFailureEnable | false | 磁盘超限,是否显式通知 POD 内所有实例失败;若不通知,将等待实例断连超时后变更状态 | +| .Values.global.runtime.diskUsageMonitor.forceDeletePODEnable | true | 磁盘超限,是否强制删除 POD | +| .Values.global.runtime.prestartCount | | runtime 预启动配置 | +| .Values.global.runtime.jvmCustomArgs | | java runtime prestart 自定义 JVM 配置 | +| .Values.global.runtime.defaultArgs | | runtime 支持用户自定义启动参数 | +| .Values.global.runtime.dataSystem.authEnable | false | 是否开启 runtime 与数据系统鉴权配置 | +| .Values.global.runtime.isProtoMsgToRuntime | true | 传输到 runtime 数据格式是否 proto, LibRuntime 版本需要开启 | +| .Values.global.runtime.oomKill.memoryDetectionInterval | 1000 | runtime 内存检测时间间隔,单位:毫秒。最小值 100 ms。用户须知容器部署,该特性 10ms 间隔的检测频率约引入 60~100m CPU 的底噪,100ms 间隔的检测频率约引入 30m CPU 的底噪,runtime-manager 和 runtime 共容器部署,将会挤占函数能使用的 CPU 资源,在高并发高内存底噪占用的情况下,会有明显影响 | +| .Values.global.runtime.oomKill.enable | false | 是否开启基于 runtime 进程内存使用情况检测超过配置内存大小并 kill | +| .Values.global.runtime.oomKill.controlLimit | 0 | 基于进程内存使用配置运行时 OOM kill 的控制限,单位为 MB 。如 limit=-5,设置的内存大小 -5 MB(例如 300m-128Mi 的函数,内存上限为 123MB),主动预防 OOM。对于 K8S 容器部署,特别是 FaaS 场景单 POD 单函数部署形态,① 强烈不建议设置控制限为正数!因为容器内使用的内存受 cgroup 限制,例如 FaaS 单 POD 单函数 300m-128Mi,若控制限设置为 limit=10,设置的内存大小 +10 MB,单个函数内存上限为 138MB,此水线根本达不到,cgroup 限制内存 <128MB;特性无效,反而会因为频繁的 runtime 内存检测而引入 CPU 底噪,挤占函数能使用的 CPU 资源,造成函数执行变慢。 ② 建议至少扣减掉同容器中 runtime-manager 占用的内存底噪,如 20MB,设置 limit=-20。 openYuanrong runtime-manager 资源占用情况,请参考[《规格与限制》章节](./restrictions.md#runtime-runtime-manager)。 ③ 若用户的需求是提前防御函数 OOM,请在扣减掉 runtime-manager 占用的内存底噪基础上,进一步设置防御预留量,并考虑容器的内存资源总量避免资源闲置,如设置 limit=-30 | +| .Values.global.runtime.oomKill.consecutiveDetectionCount | 3 | 内存连续检测异常点的次数。参考控制图中的 3σ 原则 | + +用户自定义启动参数配置: + +| 配置项 | 默认值 | 说明 | +|---------------------------------------------------------------|-----------------|----------------------------------------------------------------------------------------------------------------------------------------| +| .Values.global.runtime.defaultArgs.java8 | `'["-XX:InitialRAMPercentage=35.0", "-XX:+UseConcMarkSweepGC", "-XX:+CMSClassUnloadingEnabled", "-XX:+CMSIncrementalMode", "-XX:+CMSScavengeBeforeRemark", "-XX:+UseCMSInitiatingOccupancyOnly", "-XX:CMSInitiatingOccupancyFraction=70", "-XX:CMSFullGCsBeforeCompaction=5", "-XX:MaxGCPauseMillis=200", "-XX:+ExplicitGCInvokesConcurrent", "-XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses"]'` | java8 runtime 支持自定义 JVM 默认启动参数 | +| .Values.global.runtime.defaultArgs.java11 | `'["-XX:+UseG1GC", "-XX:MaxRAMPercentage=80.0", "-XX:+TieredCompilation"]'` | java11 runtime 支持自定义 JVM 默认启动参数 | +| .Values.global.runtime.defaultArgs.java17 | `'["-XX:+UseZGC", "-XX:+AlwaysPreTouch", "-XX:+UseCountedLoopSafepoints", "-XX:+TieredCompilation", "--add-opens=java.base/java.util=ALL-UNNAMED", "--add-opens=java.base/java.lang=ALL-UNNAMED", "--add-opens=java.base/java.net=ALL-UNNAMED", "--add-opens=java.base/java.io=ALL-UNNAMED", "--add-opens=java.base/java.math=ALL-UNNAMED", "--add-opens=java.base/java.time=ALL-UNNAMED", "--add-opens=java.base/java.text=ALL-UNNAMED", "--enable-preview"]'` | java17 runtime 支持自定义 JVM 默认启动参数 | +| .Values.global.runtime.defaultArgs.java21 | `'["-XX:+UseZGC", "-XX:+ZGenerational", "-XX:+AlwaysPreTouch", "-XX:+UseCountedLoopSafepoints", "-XX:+TieredCompilation", "--add-opens=java.base/java.util=ALL-UNNAMED", "--add-opens=java.base/java.lang=ALL-UNNAMED", "--add-opens=java.base/java.net=ALL-UNNAMED", "--add-opens=java.base/java.io=ALL-UNNAMED", "--add-opens=java.base/java.math=ALL-UNNAMED", "--add-opens=java.base/java.time=ALL-UNNAMED", "--add-opens=java.base/java.text=ALL-UNNAMED", "--enable-preview"]'` | java21 runtime 支持自定义 JVM 默认启动参数 | + +配置示例:如果需要在 java21 JVM 启动参数中,传入从环境变量(如 `$JAVA_OPTS` )动态读取的值 + +- 配置 .Values.global.runtime.defaultArgs.java21 值为: + +`'["-XX:+UseZGC", "-XX:+ZGenerational", "-XX:+AlwaysPreTouch", "-XX:+UseCountedLoopSafepoints", "-XX:+TieredCompilation", "--add-opens=java.base/java.util=ALL-UNNAMED", "--add-opens=java.base/java.lang=ALL-UNNAMED", "--add-opens=java.base/java.net=ALL-UNNAMED", "--add-opens=java.base/java.io=ALL-UNNAMED", "--add-opens=java.base/java.math=ALL-UNNAMED", "--add-opens=java.base/java.time=ALL-UNNAMED", "--add-opens=java.base/java.text=ALL-UNNAMED", "--enable-preview", {{javaOpts}}]'` + +- 在 entrypoint-runtime-manager 或拉起 runtime-manager/function-agent 组件脚本中,替换启动参数的配置,如下: + +```bash +RUNTIME_DEFAULT_CONFIG=$(echo ${RUNTIME_DEFAULT_CONFIG} | sed "s|{{javaOpts}}|$JAVA_OPTS|g") +``` + +确保传递给组件的启动参数 `--runtime_default_config` 值 `RUNTIME_DEFAULT_CONFIG` 含有从环境变量( `$JAVA_OPTS` )动态读取的值 + +(k8s-deploy-params-log)= + +## 日志配置 + +| 配置项 | 默认值 | 说明 | +|---------------------------------------------------------------|-----------------|--------------------------------------| +| .Values.global.log.hostPath.enable | true | 是否将组件日志挂载到宿主机 | +| .Values.global.log.hostPath.componentLog | /var/paas/sys/log/cff/default/componentlogs | openYuanrong组件日志挂载主机目录 | +| .Values.global.log.hostPath.componentLog | /var/paas/sys/log/cff/default/servicelogs | runtime 日志挂载主机目录 | +| .Values.global.log.hostPath.userLog | /var/paas/sys/log/cff/default/servicelogs | runtime 标准输出日志挂载主机目录 | +| .Values.global.log.functionSystem.path | /home/sn/log | 函数系统组件日志容器目录,不建议修改 | +| .Values.global.log.functionSystem.level | /home/sn/log | 函数系统组件日志级别,取值:DEBUG、INFO、WARN、ERROR | +| .Values.global.log.functionSystem.pattern | | 函数系统组件日志格式 | +| .Values.global.log.functionSystem.compress | true | 函数系统组件是否开启压缩 | +| .Values.global.log.functionSystem.rolling.maxSize | 1000 | 函数系统组件滚动日志配置,单个日志文件大小(单位:MB) | +| .Values.global.log.functionSystem.rolling.maxfiles | 3 | 函数系统组件滚动日志配置,保留最大文件数 | +| .Values.global.log.functionSystem.async.logBufSecs | 30 | 函数系统组件日志缓存时间(单位:s) | +| .Values.global.log.runtime.path | /home/snuser/log | runtime 日志容器目录,不建议修改 | +| .Values.global.log.runtime.level | INFO | runtime 日志级别,取值:DEBUG、INFO、WARN、ERROR | +| .Values.global.log.runtime.expiration.enable | true | 是否启用 runtime 日志老化删除 | +| .Values.global.log.runtime.expiration.cleanupInterval | 600 | 检查过期日志的时间间隔,单位 s,默认 10 min: 60 * 10,需要明确小于 timeThreshold,否则非法 | +| .Values.global.log.runtime.expiration.timeThreshold | 432000 | 过期日志文件保留的最长时间,单位 s,默认 5 天:60 * 60 * 24 * 5 | +| .Values.global.log.runtime.expiration.maxFileCount | 512 | 最大保留的过期日志文件数,单位个数,默认 512 | +| .Values.global.log.runtime.expiration.logReuseEnable | false | 是否开启日志前缀功能,开启时需要启用日志老化删除功能,默认 false | +| .Values.global.log.runtime.userLogExportMode | file | 用户日志导出方式,取值:file(导出至文件)、std(导出至标准输出流),默认导出至文件 | +| .Values.global.log.userOutput.level | INFO | 用户函数输出 日志级别,取值:DEBUG、INFO、WARN、ERROR | +| .Values.global.log.userOutput.path | /home/snuser/log/instances | runtime 标准输出日志容器目录,不建议修改 | + +## 部署亲和配置 + +| 配置项 | 默认值 | 说明 | +|-----------------------------------------------------|-----------------|--------------------------------------| +| .Values.global.controlPlane.nodeSelector | | 控制面组件部署标签选择 | +| .Values.global.controlPlane.tolerations | | 控制面组件部署允许容忍污点 | +| .Values.global.controlPlane.nodeAffinity | | 控制面组件部署节点亲和配置 | +| .Values.global.functionProxy.nodeSelector | | function-proxy 部署标签选择 | +| .Values.global.functionProxy.tolerations | | function-proxy 部署允许污点 | +| .Values.global.functionProxy.nodeAffinity | | function-proxy 部署节点亲和配置 | +| .Values.global.pool.nodeSelector | | 默认 function-agent 池部署标签选择 | +| .Values.global.pool.tolerations | | 默认 function-agent 池部署允许容忍污点 | +| .Values.global.pool.nodeAffinity | | 默认 function-agent 池部署节点亲和配置 | +| .Values.global.systemFunc.faasController.affinity | | faasController 部署亲和配置,配置字符串 | +| .Values.global.systemFunc.faasFrontend.affinity | | faasFrontend 部署亲和配置,配置字符串 | +| .Values.global.systemFunc.faasScheduler.affinity | | faasScheduler 部署亲和配置,配置字符串 | +| .Values.global.systemFunc.faasManager.affinity | | faasManager 部署亲和配置,配置字符串 | +| .Values.global.systemFunc.faasFrontend.pool.enabled | false | frontend 与 agent 资源池(配置了 reuse=true)共节点部署,支持一个节点部署一个 frontend,frontend 数量跟随 agent 资源池动态调整, 开启后,instanceNum 配置将忽略 | + +配置参考如下 + +```yaml +global: + # control-plane 配置示例,functionProxy、pool 配置类似 + controlPlane: + nodeSelector: + node-role.kubernetes.io/controlplane: true + tolerations: + - key: "node.kubernetes.io/disk-pressure" + operator: "Equal" + value: "true" + effect: "NoSchedule" + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: node-role.kubernetes.io/controlplane + operator: In + values: + - "true" + # 系统函数配置参考 + systemFunc: + faasController: + affinity: "{\"nodeAffinity\": {\"requiredDuringSchedulingIgnoredDuringExecution\":{\"nodeSelectorTerms\":[{\"matchExpressions\":[{\"key\":\"node-type\",\"operator\":\"In\",\"values\":[\"system\"]}]}]}}}" + faasFrontend: + affinity: "{\"nodeAffinity\": {\"requiredDuringSchedulingIgnoredDuringExecution\":{\"nodeSelectorTerms\":[{\"matchExpressions\":[{\"key\":\"node-type\",\"operator\":\"In\",\"values\":[\"system\"]}]}]}}}" + faasScheduler: + affinity: "{\"nodeAffinity\": {\"requiredDuringSchedulingIgnoredDuringExecution\":{\"nodeSelectorTerms\":[{\"matchExpressions\":[{\"key\":\"node-type\",\"operator\":\"In\",\"values\":[\"system\"]}]}]}}}" + faasManager: + affinity: "{\"nodeAffinity\": {\"requiredDuringSchedulingIgnoredDuringExecution\":{\"nodeSelectorTerms\":[{\"matchExpressions\":[{\"key\":\"node-type\",\"operator\":\"In\",\"values\":[\"system\"]}]}]}}}" +``` + +frontend 数量如果需要动态调整,可参考如下配置: + +```yaml +global: + systemFunc: + faasFrontend: + # frontend 需要配置 pod 节点反亲和,并且亲和 yr-reuse=true 的 pod + affinity: "{\"nodeAffinity\":{\"requiredDuringSchedulingIgnoredDuringExecution\":{\"nodeSelectorTerms\":[{\"matchExpressions\":[{\"key\":\"lhs.application.label\",\"operator\":\"In\",\"values\":[\"service-x86\"]}]}]}},\"podAntiAffinity\":{\"requiredDuringSchedulingIgnoredDuringExecution\":[{\"topologyKey\":\"kubernetes.io/hostname\",\"labelSelector\":{\"matchExpressions\":[{\"key\":\"faasfrontend\",\"operator\":\"Exists\",\"values\":[]}]}}]},\"podAffinity\":{\"requiredDuringSchedulingIgnoredDuringExecution\":[{\"topologyKey\":\"kubernetes.io/hostname\",\"labelSelector\":{\"matchExpressions\":[{\"key\":\"yr-reuse\",\"operator\":\"In\",\"values\":[\"true\"]}]}}]}}" + instanceNum: 0 + # if a node deploys a function-agent pool, the frontend will also be deployed on the node. + pool: + # if it is true, "instanceNum" does not take effect + enabled: false +``` + +**特别说明:** + +配置亲和属性时,nodeSelector 与 nodeAffinity 会同时生效,当二者配置冲突时,可能导致组件 pending 无法拉起,建议配置一项即可。 + +## meta-store 配置 + +| 配置项 | 默认值 | 说明 | +|---------------------------------------------------------------|--------------------------------------------|---------------------------------------------| +| .Values.global.metaStore.enable | false | 是否启用 meta-store | +| .Values.global.metaStore.address | meta-store.default.svc.cluster.local:22770 | meta-store 对外暴露地址 | +| .Values.global.metaStore.mode | local | meta-store 模式,local:本地缓存模式,passthrough:透传模式 | +| .Values.global.metaStore.enablePersistence | false | 是否开启持久化(仅本地模式有效) | +| .Values.global.metaStore.enableSyncSysFunc | false | 是否开启系统函数实例信息,双写 metaStore 和 etcd | +| .Values.global.metaStore.maxFlushConcurrency | 100 | metaStore 持久化到 etcd 允许最大请求并发数,当需要持久化的请求数超过该值后,会进行限流,延迟持久化 | +| .Values.global.metaStore.maxFlushBatchSize | 50 | metaStore 持久化到 etcd 一次性最多允许的条数,采用分批次持久化 | + +## 函数系统对接数据系统配置 + +| 配置项 | 默认值 | 说明 | +|---------------------------------------------------------------|-----------------|--------------------------------------| +| .Values.global.curve.workerPublicKey | | runtime 访问数据系统, worker 公钥,开启鉴权时需要配置, SCC 加密后的 base64 编码 | +| .Values.global.curve.clientPrivateKey | | runtime 访问数据系统, client 私钥,开启鉴权时需要配置, SCC 加密后的 base64 编码 | +| .Values.global.curve.clientPublicKey | | runtime 访问数据系统, client 公钥,开启鉴权时需要配置, SCC 加密后的 base64 编码 | +| .Values.global.dataSystem.authEnabled | false | 是否开启数据系统鉴权 | +| .Values.global.dataSystem.ak | | proxy 访问数据系统 ak | +| .Values.global.dataSystem.sk | | proxy 访问数据系统 sk | +| .Values.global.dataSystem.authType | | proxy 访问数据系统鉴权类型,取值 ZMQ、AK/SK | + +## 对接 K8s 配置 + +| 配置项 | 默认值 | 说明 | +|---------------------------------------------------------------|-----------------|--------------------------------------| +| .Values.global.kubernetes.kubeApiBaseUrl | true | k8s api-server 地址,建议修改 | +| .Values.global.kubernetes.svcCIDR | 10.43.0.0/16 | SVC CIDR 配置;当开启租户网络隔离时,屏蔽该配置网段的通信;按最小权限原则,默认屏蔽用户函数对集群内部服务的访问,按白名单放通 | +| .Values.global.kubernetes.podCIDR | 10.42.0.0/16 | Pod CIDR 配置,多个 POD CIDR 使用 ',' 间隔;当开启租户网络隔离时,屏蔽该配置网段的通信;按最小权限原则,默认屏蔽用户函数对集群内部其他 POD 的访问,仅同一租户的 POD 间网络互通 | +| .Values.global.kubernetes.hostCIDR | | Host CIDR 配置,多个 Host CIDR 使用 ',' 间隔;当开启租户网络隔离时,屏蔽该配置网段的通信;默认为空,不屏蔽用户函数对外部主机的访问 | +| .Values.global.kubernetes.kubeSystemDNSSuffix | kube-system.svc.cluster.local | k8s 集群 DNS 后缀 | +| .Values.global.kubernetes.kubeClientRetryTime | 5 | kubeclient 访问 k8sApi 请求重试次数,配置范围 0 - uint32_max | +| .Values.global.kubernetes.kubeClientRetryCycMs | 3000 | kubeclient 访问 k8sApi 请求初始重试间隔,单位 ms,配置范围 0 - uint32_max。 注:间隔时间使用指数退避,公式为 T=t\*pow(2, r-1) + rand(0, 1000)(r 为重试次数,t 为初始间隔时间) | +| .Values.global.kubernetes.healthMonitorMaxFailure | 5 | k8s 健康监测请求失败容忍次数,配置范围 0 - uint32_max | +| .Values.global.kubernetes.healthMonitorRetryInterval | 3000 | k8s 健康监测间隔时间,单位 ms,配置范围 0 - uint32_max | +| .Values.global.common.selfTaintPrefix | | 污点名称前缀, ds-worker 或者 function-proxy 故障时会对节点添加污点,默认为 is-function-proxy-unready=true:PreferNoSchedule,is-ds-worker-unready=true:PreferNoSchedule | + +## 对接 etcd 配置 + +| 配置项 | 默认值 | 说明 | +|---------------------------------------------------------------|-----------------|--------------------------------------| +| .Values.global.etcdManagement.detcd | ds-core-etcd.default.svc.cluster.local:2379 | 路由 etcd 地址 | +| .Values.global.etcdManagement.authType | Noauth | etcd 鉴权配置,取值 Noauth、PWD、TLS、STS | +| .Values.global.etcdManagement.etcdUser | root | 路由 etcd 用户名 | +| .Values.global.etcdManagement.etcdPassword | | 路由 etcd 密码 | +| .Values.global.etcdManagement.metaEtcdEnable | true | 是否开启元数据 etcd | +| .Values.global.etcdManagement.metcd | ds-core-etcd.default.svc.cluster.local:2379 | 元数据 etcd 地址 | +| .Values.global.etcdManagement.metaEtcdUser | root | 元数据 etcd 用户名 | +| .Values.global.etcdManagement.metaEtcdPassword | true | 元数据 etcd 密码 | +| .Values.global.etcdManagement.maxTolerateMetaStoreFailedTimes | 12 | 允许 etcd 健康检查失败的最大次数, 配置范围 0 - uint32_max | +| .Values.global.etcdManagement.metaStoreCheckHealthIntervalMs | 5000 | etcd 元存储健康状况检查间隔,单位:ms, 配置需要大于 0 - uint32_max | +| .Values.global.etcdManagement.metaStoreTimeoutMs | 10000 | etcd 元存储健康状况检查超时时间,单位:ms, 配置需要大于 0 - uint32_max
注:按照如上配置,当 etcd 发生故障时,openYuanrong内核将在[12 x 5000, 12 x (5000 + 10000)], 即 1 分钟到 3 分钟之内触发熔断 | +| .Values.global.etcdManagement.useSecret | true | 是否使用 secret, 安全配置 | +| .Values.global.etcdManagement.secretName | true | secret 名称,用于 etcd TLS 连接 | +| .Values.global.etcdManagement.etcdDecryptTool | SCC | etcd 证书加解密工具,取值 SCC | +| .Values.global.etcdManagement.rootCA | | CA 证书内容 base64 值 | +| .Values.global.etcdManagement.clientCert | | 客户端公钥证书内容 base64 值 | +| .Values.global.etcdManagement.clientKey | | 客户端私钥证书内容 base64 值 | +| .Values.global.etcdManagement.certPwd | | 证书密码配置,需使用 SCC 加密后的 base64 值 | +| .Values.global.etcdManagement.targetNameOverride | | etcd TLS 证书域名 | + +## 对接 OBS 配置 + +| 配置项 | 默认值 | 说明 | +|---------------------------------------------------------------|-----------------|--------------------------------------| +| .Values.global.obsManagement.obsBucketName | SN_IP:32379 | OBS 或者 Minio 桶名 | +| .Values.global.obsManagement.s3Endpoint | minio.default.svc.cluster.local:9000 | OBS 或者 Minio 地址 | +| .Values.global.obsManagement.s3AccessKey | root | OBS 或者 Minio 用户名,默认使用 GCM 加密,开启 SCC 后,需使用 SCC 加密 | +| .Values.global.obsManagement.s3SecretKey | | OBS 或者 Minio 密码,默认使用 GCM 加密,开启 SCC 后,需使用 SCC 加密 | +| .Values.global.obsManagement.protocol | https | 从 OBS 下载代码包的协议,http 或 https | +| .Values.global.obsManagement.credentialType | credential_type_rotating_credentials | OBS 凭据类型,值为空""则兼容之前的固定凭据;值为 credential_type_rotating_credentials 或 credential_type_permanent_credentials. 凭据轮转由 function_proxy 获取和透传给 function_agent | +| .Values.global.oidc.enable | false | 是否挂载 oidc-token,当 obsManagement.credentialType 设置为 credential_type_rotating_credentials 且在 云厂商集群环境下,如 CCE,可开启该选项进行凭据轮转 | +| .Values.global.oidc.mountPath | | oidc-token 在 function_proxy 容器中的挂载路径,如 /var/run/secrets/tokens, 默认挂载文件名为 oidc-token, /var/run/secrets/tokens/oidc-token 文件内容就是 Kubernetes 生成的 serviceAccountToken, 调用获取联邦认证 token (OpenID Connect ID token 方式) 接口即可获取 IAM Token | +| .Values.global.oidc.workloadIdentity | | OBS 身份提供商名称, 由云厂商提供,可参考 | +| .Values.global.oidc.clientId | | 身份提供商的客户端 ID , 如 a572 | +| .Values.global.oidc.projectId | | scope 项目 ID , 云厂商项目控制台获取 | +| .Values.global.oidc.projectName | | scope 项目名, 如 cn-north-7 | +| .Values.global.oidc.iamEndpoint | | 外部云厂商 IAM 的 endpoint,如 , 有时 endpoint 需要带 region ID。通过 IAM Token 从 iamEndpoint 可获取临时 AK/SK 和 securitytoken, 临时 AK/SK 和 securitytoken 是系统颁发给 IAM 用户的临时访问令牌。临时 AK/SK 和 securitytoken 遵循权限最小化原则。 | +| .Values.global.oidc.serviceAccountTokenExpirationSeconds | 7200 | 指定 oidc-token 的过期时间,单位 s, 当超过 24 小时或超过 80% 的过期时间时,kubelet 会主动轮转 serviceAccountToken | +| .Values.global.oidc.temporaryAccessKeyExpirationSeconds | 86400 | 临时 AK/SK 和 securitytoken 的过期时间, 单位 s。有效期可在 15 分钟至 24 小时范围内设置,过期后需要重新获取,所以设置范围是 [900, 86400]。参考 | + +## 对接 STS 配置 + +| 配置项 | 默认值 | 说明 | +|---------------------------------------------------------------|-----------------|--------------------------------------| +| .Values.global.sts.enable | false | 是否开启 sts | +| .Values.global.sts.serverDomain | | sts 服务地址 | + +## 加密算法配置(安全配置) + +| 配置项 | 默认值 | 说明 | +|---------------------------------------------------------------|-----------------|--------------------------------------| +| .Values.global.secret.apple | | 默认 GCM 加密算法密钥材料 | +| .Values.global.secret.boy | | 默认 GCM 加密算法密钥材料 | +| .Values.global.secret.cat | | 默认 GCM 加密算法密钥材料 | +| .Values.global.secret.dog | | 默认 GCM 加密算法密钥材料 | +| .Values.global.secret.egg | | 默认 GCM 加密算法密钥材料 | +| .Values.global.scc.enable | false | 是否开启 SCC,安全环境需要开启 | +| .Values.global.scc.secretName | scc-ks-secret | secret 名称 | +| .Values.global.scc.primaryContent | | SCC 密钥材料 primary.ks 内容 base64 值 | +| .Values.global.scc.standbyContext | | SCC 密钥材料 standby.ks 内容 base64 值 | +| .Values.global.scc.algorithm | AES256_GCM | SCC 加密算法 | + +## 函数系统组件双向认证配置(安全配置) + +| 配置项 | 默认值 | 说明 | +|---------------------------------------------------------------|-----------------|--------------------------------------| +| .Values.global.mutualSSLConfig.sslEnable | false | 是否开启双向认证 | +| .Values.global.mutualSSLConfig.sslBasePath | /home/sn/resource/https | 证书挂载路径,不建议修改 | +| .Values.global.mutualSSLConfig.rootCA | | CA 证书 base64 值 | +| .Values.global.mutualSSLConfig.moduleCert | | 客户端证书 base64 值 | +| .Values.global.mutualSSLConfig.moduleKey | | 客户端私钥 base64 值 | +| .Values.global.mutualSSLConfig.certPwd | | 证书密码 SCC 加密后 base64 值 | +| .Values.global.mutualSSLConfig.serverName | test | 证书 server name | +| .Values.global.mutualSSLConfig.secretName | https-secret | secret 名称 | +| .Values.global.mutualSSLConfig.sslDecryptTool | SCC | 加密工具 | +| .Values.global.enableComponentAuth | false | 是否开启组件(master, worker)间的鉴权 | + +## 可观测性配置 + +| 配置项 | 默认值 | 说明 | +|----------------------------------------------------------|--------------------------------------------------|------------------------------------------------------------------------------------| +| .Values.global.observer.trace.enable | false | trace 开关 | +| .Values.global.observer.trace.runtimeTraceConfig | | runtime 的 trace 配置项,trace.enable 为 true 时生效 | +| .Values.global.observer.metrics.enable | false | metrics 开关 | +| .Values.global.observer.metrics.sslEnable | true | metrics 对接后端是否开启双向认证 证书同组件间双向认证 | +| .Values.global.observer.metrics.metricsConfig | | metrics 配置项,metrics.enable 为 true 时生效 | +| .Values.global.observer.metrics.metricsConfigFile | | metrics 配置项文件路径,metrics.enable 为 true 且 metrics.metricsConfig 为空时生效 | +| .Values.global.observer.metrics.runtimeMetricsConfig | | runtime metrics 配置项,metrics.enable 为 true 时生效 | +| .Values.global.observer.metrics.runtimeMetricsConfigFile | | runtime metrics 配置项文件路径,metrics.enable 为 true 且 metrics.runtimeMetricsConfig 为空时生效 | +| .Values.global.observer.proGatewayIP | prometheus-pushgateway.default.svc.cluster.local | push gateway ip | +| .Values.global.observer.gatewayPort | 9091 | push gateway 端口 | +| .Values.global.observer.proServerIP | SN_IP | 普罗 server IP | +| .Values.global.observer.proServerPort | 30901 | 普罗 server 端口 | + +## 多openYuanrong集群共用 K8s 集群部署配置说明 + +如果需要在同一个 K8s 集群部署多套openYuanrong集群,需要创建多个命名空间,不同openYuanrong集群通过命名空间隔离,如下配置需要更改(其余配置可根据实际需要进行修改)。 + +| 配置项 | 配置说明 | 集群 1 配置示例 | 集群 2 配置示例 | +|---------------------------------------------------------------|-----------------|--------------------------------------|--------------------------------------| +| .Values.global.namespace | 命名空间配置 | yr1 | yr2 | +| .Values.global.port.admin | admin 端口配置 | 31172 | 31173 | +| .Values.global.port.metaService | meta-service 端口配置 | 31182 | 31183 | +| .Values.global.port.functionProxyPort | function-proxy 监听端口 | 22772 | 23772 | +| .Values.global.port.functionProxyGrpcPort | runtime 与 proxy 通信端口 | 22771 | 23771 | +| .Values.global.port.functionProxyPrometheusPort | function-proxy prometheus 监控端口 | 9392 | 9492 | +| .Values.global.port.functionMasterPort | function-master 监听端口(当使用主机网络时)|22770| 23770| +| .Values.global.port.worker | 数据系统 ds-worker 监听端口 | 31501 | 32501 | +| .Values.global.port.frontend | frontend 对外访问端口 | 31222 | 31223 | +| .Values.global.enableNonPreemptive | daemonSet 组件是否开启自定义 priorityClass, 如果不希望部署新集群抢占老集群 agent pod,建议设置为 true | true | true | +| .Values.global.common.selfTaintPrefix | 建议配置不同污点前缀,否则集群内 ds-worker 或者 proxy 故障, 可能影响其他集群实例运行 | yr1- | yr2- | +| .Values.global.tenantIsolation.ipv4.tcpPortWhitelist | agent pod 端口访问白名单(放开 ds-worker 端口) | 31501 | 32501 | +| .Values.global.tenantIsolation.thirdPartyWhitelist | agent pod 端口访问第三方白名单 | 按实际配置 | 按实际配置 | +| .Values.global.etcdManagement.detcd | 路由 etcd 地址,建议配置不同的 etcd | X.X.X.X:32379 | X.X.X.X:32380 | +| .Values.global.etcdManagement.metcd | 元数据 etcd 地址,建议配置不同的 etcd | X.X.X.X:32379 | X.X.X.X:32380 | +| .Values.global.logDir | 数据系统日志挂载目录 | 建议配置不同路径 | 建议配置不同路径 | +| .Values.global.workerResources.backendStoreDir | 数据系统持久化数据挂载目录,建议配置不同路径 | 建议配置不同路径 | 建议配置不同路径 | +| .Values.global.workerResources.spillDirectory|数据系统开启 spill 时需要配置 | 建议配置不同路径 | 建议配置不同路径 | +| .Values.global.etcdAddress | 数据系统 etcd 地址 | X.X.X.X:32379 | X.X.X.X:32380 | +| .Values.global.tenantAuth.yuanrong.yuanrongIamUrl | 数据系统访问函数系统 IAM 组件地址(开启 IAM 后需要配置) | http://iam-server.yr1.svc.cluster.local:31218 | http://iam-server.yr2.svc.cluster.local:31218 | diff --git a/docs/deploy/deploy_on_k8s/production/index.md b/docs/deploy/deploy_on_k8s/production/index.md new file mode 100644 index 0000000000000000000000000000000000000000..0027f29197434e7b27b0bc0aa71c45bc971cea32 --- /dev/null +++ b/docs/deploy/deploy_on_k8s/production/index.md @@ -0,0 +1,20 @@ +# 生产部署 + +```{eval-rst} +.. toctree:: + :glob: + :maxdepth: 1 + :hidden: + + prepare + production-deployment + config-parameters + restrictions +``` + +本章节将展开介绍如何在 K8s 上部署openYuanrong生产环境。 + +- [环境准备](./prepare.md) +- [部署openYuanrong](./production-deployment.md) +- [部署参数表](./config-parameters.md) +- [规格与限制](./restrictions.md) \ No newline at end of file diff --git a/docs/deploy/deploy_on_k8s/production/prepare.md b/docs/deploy/deploy_on_k8s/production/prepare.md new file mode 100644 index 0000000000000000000000000000000000000000..ddfd696af3674f5e4c3863f3ff28a2fef52efbf1 --- /dev/null +++ b/docs/deploy/deploy_on_k8s/production/prepare.md @@ -0,0 +1,161 @@ +# 环境准备 + +本节介绍openYuanrong对部署环境的要求 + +## 操作系统及硬件 + +- 主机操作系统平台为 Linux X86_64 或 ARM_64 +- 单台主机至少有 16 个 CPU,32G 以上内存,总集群至少有 32 个 CPU,64G 以上内存。 +- 主机磁盘可用空间大于 40G,用于下载openYuanrong组件镜像 +- 主机之间通信正常,开发测试环境可以关闭防火墙规避 + + ```bash + systemctl stop firewalld + systemctl disable firewalld + ``` + +## 依赖服务 + +部署openYuanrong依赖以下服务,我们提供了**黄区环境**一键部署工具,方便您快速完成环境准备。如果您已安装相关依赖,可直接进入[部署openYuanrong](./production-deployment.md)章节。 + +- k8s 集群 及 kubectl 工具 1.19.4 及以上版本 +- MinIO 不限制版本 +- ETCD v3 版本 +- helm 工具 3.2 及以上版本,用于部署openYuanrong。安装参考:[黄区环境安装](developer-install-and-configure-helm),[公网环境安装](https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/){target="_blank"} + +### 准备一键部署工具的环境 + +工具运行依赖以下软件 + +- 所有主机安装 docker 19.03 及以上版本并配置openYuanrong镜像仓,[安装及配置参考](developer-install-and-configure-docker) +- k8s master 节点主机安装 kubectl,[安装参考](developer-install-and-configure-kubectl) +- k8s master 节点主机安装 python 3.8 及以上版本,[安装参考](developer-install-and-configure-python-libffi-devel-and-cmake) +- k8s master 节点主机安装 xmllint,安装命令 `yum install libxml2` +- k8s master 节点主机安装 etcdctl,需匹配 ETCD 版本,[官网下载地址](https://github.com/etcd-io/etcd/releases){target="_blank"},参考以下命令安装 + + ```bash + tar -zxf etcd-v3.4.14-linux-amd64.tar.gz + mv etcd-v3.4.14-linux-amd64/etcdctl /usr/local/bin + chmod +x /usr/local/bin/ + # 验证安装:etcdctl version + ``` + +### 按需部署 k8s、MinIO 及 ETCD + +下载工具包 `base.tar.gz` 到您部署 k8s master 节点的主机上:[X86_64 平台下载](http://10.244.152.5/release/ServerlessNative/depend/develop/EulerOS_x86_64_v2r11/base.tar.gz) + +1. 下载依赖组件镜像 + + ```bash + # 解压压缩包 + tar -zxf base.tar.gz -C . + cd basic + + 下载依赖组件的镜像 + bash sources/pull_basic_images.sh + ``` + +2. 安装 ntp 服务(可选),同步时钟 + + 拷贝 `basic/sources/ntp.sh` 文件到所有主机并安装 + + ```bash + bash ntp.sh + ``` + +3. 按需部署依赖服务 + + 参考下表,根据实际情况选择安装的组件并修改对应配置 `basic/config.xml`,其中 rancher 用于安装 k8s,S3 对应 MinIO 的配置。 + + | **参数** | **描述** | **默认值** | **备注** | + | ------------------ | ----------------------------------------------------------------------------- | ---------- | --------------------------------------------------------------------------------------- | + | local_ip | 配置为运行环境的本机 IP 地址 | 无 | 必填,eth0 网口绑定的 IP | + | nic_name | 配置为运行环境的本机 IP 的网卡名 | eth0 | 选填 | + | rancher_http | 配置部署的 rancher 的 http 访问端口 | 8082 | 选填 | + | rancher_https | 配置部署的 rancher 的 https 访问端口 | 8146 | 选填 | + | rancher_password | 配置部署的 rancher 的访问密码 | xxx | 选填,建议自行修改。 | + | nfs_serverip | 配置部署的 nfs 的 server 的 IP 地址,选择快速部署时也是运行环境的本机 IP 地址 | 无 | 必填,eth0 网口绑定的 IP | | + | S3_AK | 配置部署的 S3 的 accessKey | root | 必填。 | + | S3_SK | 配置部署的 S3 的 secretKey | password | 必填。 | + | minio_tls_enable | 访问 minio 是否开启 tls | false | 选填 | + | minio_secret_name | 鉴权的证书和密钥 | 无 | 选填。Minio_tls_enable 为 false 可以不填 | + | etcd_auth_type | Etch 鉴权类型 | Noauth | 选填,默认不开启鉴权。 | + | core_etcd_password | 配置部署的 ds_core_etcd 的密码 | password | 选填,建议自行修改。 | + | etcd_cert_file | 经过 ca 签名的证书位置 | 无 | 选填。etcd_auth_type 为 false 可以不填。 | + | etcd_key_file | CA 机构私钥位置 | 无 | etcd_auth_type 为 false 可以不填。 | + | etcd_ca_file | 鉴权根证书位置 | 无 | etcd_auth_type 为 false 可以不填。 | + | etcd_no_fsync | 关闭 etcd 同步机制 | false | 选填。【警告】设置 etcd_no_fsync true 将提高 I/O 性能,但可能会在节点崩溃时导致数据丢失 | + | etcd_proxy_enable | 是否开启 etcd proxy | False | 选填。 | + | client_cert_file | Etcd 客户端的签名证书位置 | 无 | 选填。etcd_auth_type 为 false 可以不填。 | + | client_key_file | Etcd 客户端的密钥位置 | 无 | 选填。etcd_auth_type 为 false 可以不填。 | + | etcd_proxy_nums | Etcd proxy 的数量 | 0 | 选填。etcd_proxy_enable 为 false 可以不填。 | + | etcd_proxy_ports | Etcd proxy 监听的端口 | 23790 | 选填。etcd_proxy_enable 为 false 可以不填。 | + + ```bash + # 安装 k8s, etcd, minio + bash process.sh -o install -m quick + + # 仅安装 etcd + bash process.sh -o install -m ds-core-etcd + + # 仅安装 minio + bash process.sh -o install -m minio + ``` + + 验证安装结果:以下命令成功执行且所有 POD 状态为 `Running` 即为部署成功。 + + ```shell + kubectl get pods -w + + NAME READY STATUS RESTARTS AGE + ds-core-etcd-0 1/1 Running 0 2m56s + minio-75978b9b47-547vb 1/1 Running 0 2m56s + ``` + + :::{note} + + - 安装过程中,可能遇到超时错误,例如 `error: timed out waiting for the condition xxx`,此类错误可忽略。 + + - 安装正常耗时 10 分钟以内,如长时间卡住或者脚本执行完毕,组件 POD 状态异常,可参考章节[常见问题](prepare-faq-install-rancher)。 + + ::: + +4. 使用 Rancher 纳管节点,组建 k8s 集群 + + 登录 Rancher 管理前台(网址为 ,`local_ip` 是安装 Rancher 后台的主机的 IP 地址)。 + + 使用浏览器进入 Rancher 管理前台的编辑集群页面,复制安装命令,如下图所示 + + ![进入 Rancher 管理前台复制添加节点的命令](../../../images/d44dab10a376edb601d6c65fa3ea0e00_865x181.png@900-0-90-f.png) + + ![进入 Rancher 管理前台复制添加节点的命令](../../../images/34c27e269e0dccea983b985fa6f6f5e8_865x333.png@900-0-90-f.png) + + 将命令复制到待添加的节点主机的命令行终端中执行(执行前请确保当前节点已经执行过 `bash sources/pull_basic_images.sh`,完成镜像的拉取)。 + + 返回 Rancher 管理前台等待节点纳管,节点对应的状态标签(State)变为“**Active**”即为纳管成功,效果如下图所示 + + ![在 Rancher 管理前台查看节点纳管状态](../../../images/1ddcfb3bccf6ef7b305899439dc6d4f8_865x248.png@900-0-90-f.png) + +## 常见问题 + +(prepare-faq-install-rancher)= + +### 如何查看 rancher 部署进度 + +在主机终端执行命令 `docker logs xxx 2>&1 |grep provisioning`,替换 xxx 为 rancher 容器 ID。 + +### process.sh 脚本日志中出现 Waiting is_rancher_ready time out 错误 + +检查主机环境中代理设置是否屏蔽本机地址。 + +### rancher 容器日志中出现 permission denied 或 operation not supported 错误 + +在主机终端执行命令 `echo 1048576 > /proc/sys/net/netfilter/nf_conntrack_max` 修改内核网络参数后重启 rancher 容器。 + +### rancher 容器日志中出现 Ubable to find suitable network address,error='ubable to select an IP from default routes.' 错误 + +在主机终端执行命令 `ifconfig docker0` 查看 docker0 配置 ip 是否为 169.254.255.255/16,如果是,修改 为 172.17.255.255/16。详细解释参考[Issue #14840 · rancher/rancher](https://github.com/rancher/rancher/issues/14840) + +### rancher 容器日志中出现 Failed to retrieve node info: nodes "local-node" not found 错误 + +在主机 `/etc/hosts` 文件中添加 hostip 和 hostname diff --git a/docs/deploy/deploy_on_k8s/production/production-deployment.md b/docs/deploy/deploy_on_k8s/production/production-deployment.md new file mode 100644 index 0000000000000000000000000000000000000000..158ffd1760c3973b937e4e0f8f1d7f3af2d2dbbc --- /dev/null +++ b/docs/deploy/deploy_on_k8s/production/production-deployment.md @@ -0,0 +1,315 @@ +# 部署openYuanrong + +本节介绍部署openYuanrong的流程。 + +(k8s-deploy-download-release-package)= + +## 获取发布包 + +openYuanrong发布包在 [CMC 上获取](https://cmc-szv.clouddragon.xxx.com/cmcversion/index/search){target="_blank"},CMC 上版本搜索 `yuanrong`,在高级筛选中版本状态选 `released`。根据不同的使用平台选择软件包并下载其中的 `yuanrong.tar.gz` 文件即可。 + +:::{Note} + +同时检查版本详情页 `Inner` 标签下您要下载的软件包内是否包含 `imageTag` 文件。如不包含,您可参考[常见问题](k8s-deploy-build-component-image)手动构建组件镜像。 + +::: + +您也可以下载每日构建版本,但要注意的是,该版本有可能会被清理而无法溯源。 + +- [X86 平台下载](http://10.244.181.91:8080/job/YuanRong_kernel_ImageBuild_EulerOSX86V2R9/lastSuccessfulBuild/artifact/output/){target="_blank"} +- [ARM 平台下载](http://10.244.181.91:8080/job/YuanRong_Kernel_ImageBuild_EulerOSARMV2R8/lastSuccessfulBuild/artifact/output/){target="_blank"} + +## 配置镜像仓 + +在终端执行 `vim /etc/docker/daemon.json` 命令,增加如下文件内容,为 docker 添加openYuanrong黄区环境白名单镜像仓库地址,openYuanrong组件及基础镜像存放在这里。 + +```json +{ + "insecure-registries": [ + "cd-docker-hub.szxy5.artifactory.cd-cloud-artifact.tools.xxx.com", + "yuanrong.docker.tool.xxx.com" + ] +} +``` + +执行如下命令使配置生效: + +```shell +systemctl daemon-reload +systemctl restart docker +``` + +## 部署 + +openYuanrong部署基于 helm 工具,按需设置好配置文件即可一键安装。 + +:::{caution} + +如果 ETCD 非全新安装,请先清理残留数据。 + +::: + +执行如下命令解压发布包: + +```bash +tar -zxf yuanrong.tar.gz -C . +cd yuanrong/deploy/k8s/charts/ +``` + +在 `yuanrong/deploy/k8s/charts/` 目录下参考以下命令全新部署openYuanrong,更多配置参数设置参考[部署参数表](./config-parameters.md)。如果您你已有openYuanrong集群,可直接执行 `helm upgrade yr .` 升级。 + +- 只部署openYuanrong,不创建 Pod 资源池,需要配置 MinIO 的密码,适合自行通过[资源池管理 API](../../../multi_language_function_programming_interface/api/meta_service/pod_pool_management/index.md) 创建资源池的场景。 + + ```shell + helm install yr --set global.obsManagement.s3SecretKey=${Your Minio Password} . + ``` + +- 部署openYuanrong并创建默认规格为(3 核 cpu,6GB 内存)的 Pod 资源池,建议用于开发有状态函数。 + + ```shell + helm install yr --set global.obsManagement.s3SecretKey=${Your Minio Password},global.pools[0].id=default,global.pools[0].size=1,\ + global.pools[0].resources.requests.cpu=3000m,global.pools[0].resources.requests.memory=6144Mi,\ + global.pools[0].resources.limits.cpu=3000m,global.pools[0].resources.limits.memory=6144Mi, . + ``` + + 您也可以在部署完成后按需拉起该默认 Pod 资源池。 + + ```shell + kubectl scale deployment/function-agent-default --replicas=1 + ``` + +- 部署openYuanrong并创建默认规格为 600 毫核 cpu,512MB 内存的 Pod 资源池,建议用于开发 FaaS 函数。 + + ```shell + helm install yr --set global.obsManagement.s3SecretKey=${Your Minio Password},global.pools[0].id=pool-600-512-fusion,global.pools[0].size=1,\ + global.pools[0].resources.requests.cpu=600m,global.pools[0].resources.requests.memory=512Mi,\ + global.pools[0].resources.limits.cpu=600m,global.pools[0].resources.limits.memory=512Mi, . + ``` + + 您也可以在部署完成后按需拉起该默认 Pod 资源池。 + + ```shell + kubectl scale deployment/function-agent-pool-600-512-fusion --replicas=1 + ``` + +- 其他:修改单个组件的镜像版本示例。 + + ```shell + helm install yr --set global.images.functionProxy=function-proxy:${version} . + ``` + +检查部署结果:以下所有 Pod 全部为 Running 状态即部署成功。 + +```shell +kubectl get pods -owide -w + +NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATE +docker-registry-7cf47bf9c-vkq5k 1/1 Running 0 50d 10.42.0.81 dggphis18024 +ds-core-etcd-0 1/1 Running 0 19d 10.42.0.122 dggphis18024 +ds-worker-llcq8 1/1 Running 0 2m56s 10.244.177.56 dggphis18023 +ds-worker-wrmtn 1/1 Running 0 2m56s 10.247.23.146 dggphis18024 +function-agent-0-500m-500mi-faascontroller-27ac26400000000000b8 2/2 Running 0 104s 10.42.1.217 dggphis18023 +function-agent-1f51e49f873f-500m-500mi-faasscheduler-20000000fb 2/2 Running 0 91s 10.42.1.218 dggphis18023 +function-agent-b862b1c6d8eb-500m-500mi-faasfrontend-c6f13fa2000 2/2 Running 0 81s 10.42.1.219 dggphis18023 +function-agent-e19efb73cb3c-500m-500mi-faasmanager-08ca786e0000 2/2 Running 0 81s 10.42.1.220 dggphis18023 +function-master-777f6bb8c5-csn5m 1/1 Running 0 2m56s 10.42.1.215 dggphis18023 +function-proxy-5z27x 1/1 Running 0 2m56s 10.247.23.146 dggphis18024 +function-proxy-l7d59 1/1 Running 0 2m56s 10.244.177.56 dggphis18023 +iam-server-bb5cf566-dhsvm 1/1 Running 0 2m56s 10.42.1.214 dggphis18023 +meta-service-587d5fc6db-p5wh7 1/1 Running 0 2m56s 10.42.1.216 dggphis18023 +minio-75978b9b47-547vb 1/1 Running 0 50d 10.42.0.84 dggphis18024 +nfs-client-provisioner-96fdb99fc-257g6 1/1 Running 0 50d 10.42.0.80 dggphis18024 +``` + +openYuanrong日志默认开启并挂载到 K8s 节点上。其中 data worker 组件日志路径为 `/home/sn/datasystem/logs/`,其他组件日志路径为 `/var/paas/sys/log/cff/default/componentlogs`,函数实例 runtime 日志路径为 `/var/paas/sys/log/cff/default/servicelogs`,函数实例用户日志路径为 `/var/paas/sys/log/cff/default/processrouters/stdlogs`。如果部署失败,可通过日志分析原因。 + +:::{Note} + +对于 Rancher K8s 环境,如果日志挂载未生效,可参考[常见问题](k8s-deploy-config-mount-logs)解决。 + +::: + +## 自定义 Pod 资源池 + +部署时创建的默认 Pod 资源池通常用于开发或者测试。实际生产场景中,为了更好的匹配业务工作负载,openYuanrong支持自定义 Pod 资源池。您可以通过修改 values.yaml 文件在部署时自定义 Pod 资源池,也可以通过[资源池管理 API](../../../multi_language_function_programming_interface/api/meta_service/pod_pool_management/index.md) 动态创建,两种方式效果一致。 + +多个业务或者开发、测试等多个环境共用一套 K8s 时,您可以创建多个自定义 Pod 资源池并按业务或者环境类型打上标签,使用openYuanrong的[亲和调度策略](../../../multi_language_function_programming_interface/development_guide/scheduling/affinity.md)将函数实例指派到特定的 Pod 上,实现隔离。另外,[创建 pod 资源池 API](../../../multi_language_function_programming_interface/api/meta_service/pod_pool_management/create_pod_pool.md) 提供了 node_selector 和 affinities 字段,原生支持 [k8s pod 亲和调度](https://kubernetes.io/zh-cn/docs/concepts/scheduling-eviction/assign-pod-node/){target="_blank"},将创建的 Pod 指派给特定的节点。两者结合可实现更灵活的资源匹配。 + +## 卸载 + +执行如下命令卸载: + +```shell +helm uninstall yr +``` + +## 常见问题 + +(k8s-deploy-build-component-image)= + +### 发布包中无组件镜像 Tag + +从 CMC 获取到的openYuanrong发布包,镜像 TAG 可在如下目录找到 + +![imageTag](../../../images/5a0783ff6bc4bb98e52d0ec005c1339b_1910x874.png@900-0-90-f.png) + +如果部署镜像找不到,可参考以下步骤手动构建。 + +#### 构建全量组件镜像 + +提前准备您的镜像仓库地址,并创建脚本文件 `build_image.sh`,内容如下: + +```shell +#!/bin/bash + +set -e + +IMAGES_LIST=( + "admin" + "function-repository" + "function-master" + "function-proxy" + "meta-service" + "function-agent" + "runtime-manager" + "datasystem" + "function-agent-init" + "iam-server" +) + +WORKSPACE=$(dirname $(readlink -f "$0")) + +LOCAL_OS=$(cat /etc/os-release | grep -w NAME | awk -F "\"" '{print $2}')_$(uname -m) +case "${LOCAL_OS}" in +Ubuntu_x86_64) + DS_OPT="ubuntu" + DS_IMAGE="ubuntu:18.04" + ;; +EulerOS_x86_64) + DS_OPT="euler" + DS_IMAGE="euleros:v2r9" + ;; +EulerOS_aarch64) + DS_OPT="euler" + DS_IMAGE="euleros:v2r8" + ;; +"CentOS Linux_x86_64") + DS_OPT="centos" + DS_IMAGE="centos:7.9" + ;; +esac + +while getopts 'v:w:r:' opt +do + case "$opt" in + v) + VERSION_TAG="$OPTARG" + ;; + w) + WORKSPACE="$OPTARG" + ;; + r) + REGISTRY_SERVER="$OPTARG" + ;; + *) + log_info "Invalid command" + usage + exit 1 + ;; + esac +done + +if [ ! -d $WORKSPACE/yuanrong/deploy/k8s/build ]; then + echo "cannot find package in $WORKSPACE" + exit 1 +fi + +# check registry server +if [ "X${REGISTRY_SERVER}" = "X" ]; then + echo "use '-r' to specify a registry server" + exit 1 +fi + +# generate version +if [ "X${VERSION_TAG}" = "X" ]; then + cd $WORKSPACE/yuanrong + VERSION=$(cat VERSION | awk -F "\"" '{print$2}') + VERSION_TAG="${VERSION}.$(date +%Y%m%d%H%M)$(printf "%04d" $((RANDOM % 10000)))" +fi + +# build function system +cd $WORKSPACE/yuanrong/deploy/k8s/build/function_system/ +bash docker_build.sh -s 1002 -m all -v "${VERSION_TAG}" + +# build data system image +cd $WORKSPACE/yuanrong/deploy/k8s/build/data_system/ +bash docker_build.sh -n datasystem -t "${VERSION_TAG}" -b "${DS_IMAGE}" -s "${DS_OPT}" -i $WORKSPACE/yuanrong/data_system + +# upload images +docker images|grep -v REPOSITORY|grep -F "${VERSION_TAG}"|awk '{print "docker tag " $3 " " "'${REGISTRY_SERVER}'/"$1":'${VERSION_TAG}'"}'|sh +# push image to REGISTRY_SERVER +for image in "${IMAGES_LIST[@]}" +do +{ + echo "push ${image} now" + docker push "${REGISTRY_SERVER}"/"${image}":"${VERSION_TAG}" > "${image}"_1.log 2>&1 +}& +done + +wait +cat *.log +rm -rf *.log +``` + +将发布包与脚本放到同一目录,执行如下命令,完成镜像构建与上传,预计耗时 10 分钟左右。 + +```shell +# 解压发布包 +tar -xzf yuanrong.tar.gz + +# 执行脚本 (包含构建镜像,以及 push 镜像到镜像仓), 如果不指定版本,将随机生成时间戳作为版本 +bash build_image.sh -v "${YOUR_VERSION_TAG}" -r "${YOUR_IMAGE_REGISTRY}" +``` + +#### 构建单个组件镜像 + +如果您只需要构建单独组件镜像,可按照如下操作 + +```shell +# 解压发布包 +tar -xzf yuanrong.tar.gz +cd yuanrong/deploy/k8s/build/function_system/ + +# 构建 function-master 镜像 +bash docker_build.sh -m function-master -v ${YOUR_VERSION_TAG} +docker tag function-master:${YOUR_VERSION_TAG} ${YOUR_IMAGE_REGISTRY}/function-master:${YOUR_VERSION_TAG} +docker push ${YOUR_IMAGE_REGISTRY}/function-master:${YOUR_VERSION_TAG} + +# 构建 runtime-manager 镜像, -s 指定 sn 用户 ID +bash docker_build.sh -m runtime-manager -v ${YOUR_VERSION_TAG} -s 1002 +docker tag runtime-manager:${YOUR_VERSION_TAG} ${YOUR_IMAGE_REGISTRY}/runtime-manager:${YOUR_VERSION_TAG} +docker push ${YOUR_IMAGE_REGISTRY}/runtime-manager:${YOUR_VERSION_TAG} +``` + +(k8s-deploy-config-mount-logs)= + +### 日志挂载未生效 + +对于 Rancher K8s 环境,参考以下步骤修改配置并重新部署openYuanrong集群。 + +**在 rancher 前端 Dashboard 页面点击“Edit”。** + +![](../../../images/3ab3a41ff19c9bc997534eeb022af4d9_1410x643.png) + +**点击“Edit as a Form”展开集群配置。** + +![](../../../images/07e48d4a44ee49c02101b22a1cce05d9_1423x609.png) + +**新增红框内的配置内容。** + +```yaml + extra_binds: + - '/var/paas/sys/log/cff:/var/paas/sys/log/cff:rshared' +``` + +![](../../../images/375b00d3b4b87266ce93ebe88d6cf541_1415x784.png) diff --git a/docs/deploy/deploy_on_k8s/production/restrictions.md b/docs/deploy/deploy_on_k8s/production/restrictions.md new file mode 100644 index 0000000000000000000000000000000000000000..264ece2b34cfb442c9d25aea6d1c3538101298e6 --- /dev/null +++ b/docs/deploy/deploy_on_k8s/production/restrictions.md @@ -0,0 +1,95 @@ +# 规格与限制 + +包含对软件、网络、硬件环境的要求及限制, 例如不支持在 windows 环境上的部署。 + +## 1. ds-worker 启动参数规格限制 + +| 名称 | 含义 | 默认值 | 约束 | +|--|--|--|--| +| unix_domain_socket_dir | 指定 unix domain socket 文件创建的路径 | ~/.datasystem/unix_domain_socket_dir/ | 有效的路径格式&长度不超过 80 个字符 | + +## 2. function-agent K8S POD pids 资源规格限制 + +| 名称 | 含义 | 默认值 | 约束 | +|--|--|--|--| +| 平均每个 CppRuntime 所需 pids 资源 | 基于 function-agent K8S POD pids 资源规格限制 (`/sys/fs/cgroup/pids/kubepods/{burstable,besteffort,}/pod${uuid}/pids.max`) 可计算单个 POD 所能 拉起的最大 CppRuntime 实例个数 | 51 | function-agent K8S POD 内函数系统组件占用 60 pids 的资源,此外对 CppRuntime (不带数据系统) 每个 runtime 需要预留 27 个以上 pids 的资源,(带数据系统) 每个 runtime 需要预留 51 个以上 pids 的资源。修改 K8S POD pids 资源规格,需修改 kubelet 的 `--pod-max-pids` 启动参数;临时修改已有 POD pids cgroups 资源规格可修改`/sys/fs/cgroup/pids/kubepods/{burstable,besteffort,}/pod${uuid}/pids.max` | + +## 3. function-master K8S POD 资源规格限制 + +| 名称 | 含义 | 默认值 | 约束 | +|--|--|--|--| +| .Values.global.resources.functionMaster.limits.memory | 3 Gi | 当集群实例规模大于 10000 , 建议该参数设置大于 5 Gi ,否则可能出现 function-master 内存不足 oom 。( k8s 部署当前支持的最大规格不超过 20000 实例) | + +## 4. openYuanrong runtime 及 runtime-manager 资源占用情况说明 + +openYuanrong资源池 pool pod 内,会运行 runtime 及 runtime-manager 。当 runtime 实例被拉起时,这两个组件本身也会占用内存。因此,能提供给用户代码的内存资源,小于 pool 本身的资源配额。具体来说,不同语言 runtime 进程占用 RSS 的情况如下。数据随实际场景和软件版本更迭存在波动,供参考(单位 MB )。 + +| 测试内容 | Java | Python | Cpp | +| --- | -----------------| --- | --- | +| Sleep 60s | 175 | 107 | 95 | +| 100 次 invoke | 176 –> 181 | 107 | 95 | + +注:以上数据来自 MultiLanguageRuntime 版的 runtime 。 + +runtime-manager 占用的内存为 25 MB - 27 MB. + +以一个正在运行的空载 cpp runtime 实例为例, runtime 和 runtime-mananger 占用的内存 RSS 之和约为 110 MB. 对于一个配额为 128 MB 的资源池 pod ,可供用户使用的内存不超过 18 MB 。容易导致 runtime 和 runtime-manager 因为 OOM 被杀。 + +用户需根据其代码运行占用的内存,和其代码的动态链接库 .so 文件加载占用的内存,自行评估合理的资源池内存大小配置。 + +## 5. etcd 部署规格说明 + +### etcd 配置说明 + +| 参数名称 | 含义 | 默认值 | 参数影响 | +|------|----------------------------------------------------------------|------------|--------------------------------------------------------| +| `--snapshot-count` | 指收到多少个写请求后就触发生成一次快照,并对 Raft 日志条目进行压缩。 | 100000 | 执行快照前,数据需要保存在内存中,如果值过大,会消耗较多的内存,如果值过小,可能频繁触发快照,影响写入性能。 | +| `--quota-backend-bytes` | 后端存储的最大存储字节限制,单位 B | 8589934592 | 当写入数据超过这个限制时,etcd 将停止接受新的写入操作 | +| `--auto-compaction-mode` | 自动压缩策略, 配置 periodic 表示定期压缩,配置 revision 表示按照修订版本数量压缩 | revision | 如果 etcd 非定时写入数据,建议配置 revision 策略 | +| `--auto-compaction-retention` | 指定自动压缩的保留值,对于 periodic 策略,表示保留的时间窗口,对于 revision 策略,表示保留的修订版本数量 | 1000 | 自动压缩会清理旧的修订版本,减少 etcd 的存储空间占用,但可能会对性能产生一定影响 | + +### 性能基线配置 + +| Cpu | Memory | quota-backend-bytes | snapshot-count | auto-compaction-mode | auto-compaction-retention | 集群节点数 | 最大并发实例创建数 | 注册函数数量 | 最大运行中实例数 | +|-----|--------|----------------|----------------|---------------|---------------------------|-------|-----------|--------|----------| +| 4C | 8G | 8589934592 (8G) | 20000 | revision | 5000 | <100 | <1000 | <1000 | <2000 | +| 8C | 16G | 8589934592 (8G) | 50000 | revision | 10000 | <500 | <2000 | <5000 | <5000 | +| 16C | 32G | 8589934592 (8G) | 100000 | revision | 25000 | <1000 | <5000 | <10000 | <10000 | + +Cpu 和 Memory 参考配置(修改 etcd 部署 StatefulSet): + +```yaml +resources: + limits: + cpu: "4" + memory: 8Gi + requests: + cpu: "4" + memory: 8Gi +``` + +压缩参数和 DB Size 参考配置(修改 etcd 部署 StatefulSet): + +```yaml +# 新增如下环境变量 +# 配置 auto-compaction-mode 压缩模式 +- name: ETCD_AUTO_COMPACTION_MODE + value: "revision" +# 配置 auto-compaction-retention 配置压缩参数 +- name: ETCD_AUTO_COMPACTION_RETENTION + value: "10000" +# 配置 quota-backend-bytes DB Size(配置单位为 bytes) +- name: ETCD_QUOTA_BACKEND_BYTES + value: "8589934592" +# 配置 snapshot-count +- name: ETCD_SNAPSHOT_COUNT + value: "20000" +``` + +### 特别说明 + +1. 最大并发实例创建数增大,请增大 Cpu,Memory, 自动压缩参数。 +2. 注册函数数量/最大运行中实例数增大,请增大 Memory,DB Size。 +3. 集群节点数增大,请增大 Cpu,Memory。 +4. 当内存不足时,请减少保存快照数量,防止 etcd 发生 OOM。 +5. etcd 性能依赖磁盘,请尽量使用高性能磁盘,参照官网 [etcd](https://etcd.io/docs/v3.5/op-guide/hardware/)。 \ No newline at end of file diff --git a/docs/deploy/deploy_on_k8s/single-node-deployment.md b/docs/deploy/deploy_on_k8s/single-node-deployment.md new file mode 100644 index 0000000000000000000000000000000000000000..57d4d7f293b44bd2418dfc985bac9e4ea2cd0187 --- /dev/null +++ b/docs/deploy/deploy_on_k8s/single-node-deployment.md @@ -0,0 +1,105 @@ +# 快速部署 + +快速部署使用默认配置参数在单节点或多节点 Kubernetes 集群上部署openYuanrong,建议用于学习和开发。 + +:::{admonition} 部署环境要求 +:class: note + +- 已部署好 k8s 集群(1.19.4 及以上版本),集群中每个节点(主机)至少有 16 个 CPU,32G 以上内存,总集群至少有 32 个 CPU,64G 以上内存。部署参考:[黄区部署单机 k8s 集群](deploy-single-node-k8s),[公网环境部署 k8s 集群](https://kubernetes.io/docs/reference/setup-tools/kubeadm/){target="_blank"} + +- 配套 k8s 版本的 kubectl 工具。安装参考:[黄区环境安装](developer-install-and-configure-kubectl),[公网环境安装](https://helm.sh/zh/docs/intro/install/){target="_blank"} + +- helm 工具(3.2 及以上版本)用于部署openYuanrong。安装参考:[黄区环境安装](developer-install-and-configure-helm),[公网环境安装](https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/){target="_blank"} + +::: + +## 添加openYuanrong的 helm 仓库 + +openYuanrong k8s 安装包依赖于 helm,需要添加openYuanrong提供的 helm 仓库地址。 + +```bash +helm repo add yuanrong http://10.244.163.66:35000 +helm repo update +``` + +## 配置openYuanrong的版本镜像仓库 + +openYuanrong版本镜像存放在私有镜像仓库上,在终端执行 `vim /etc/docker/daemon.json` 命令,补充如下文件内容,为 docker 添加openYuanrong黄区环境白名单镜像仓库地址。 + +```json +{ + "insecure-registries": [ + "cd-docker-hub.szxy5.artifactory.cd-cloud-artifact.tools.xxx.com", + "yuanrong.docker.tool.xxx.com" + ] +} +``` + +执行如下命令使配置生效: + +```shell +systemctl daemon-reload +systemctl restart docker +``` + +## 部署openYuanrong + +:::{caution} + +openYuanrong依赖三方组件 etcd 和 minio 提供完整服务,以下部署流程会自动为用户安装,如果您 k8s 环境中存在已安装的 minio 及 etcd,需先手动删除。 + +- etcd: 用于在openYuanrong组件之间共享和交换元信息 +- minio: 用于存储用户发布的函数代码包 + +::: + +根据 k8s 硬件平台架构(X86/ARM)不同选择安装包,在任意 k8s 节点上使用 helm 命令部署openYuanrong。 + +::::{tab-set} +:::{tab-item} X86_64 平台 + +```bash +helm install yuanrong yuanrong/YuanRong --version=202.2.0 +``` + +::: + +:::{tab-item} ARM_64 平台 + +```bash +helm install yuanrong yuanrong/YuanRong --version=202.2.0 +``` + +::: +:::: + +使用 `kubectl get pods` 命令检查openYuanrong组件运行状态:以下 pod 个数正确且运行状态全部为 Running 才表示openYuanrong成功拉起。 + +```bash +kubectl get pods +# NAME READY STATUS RESTARTS AGE +# admin-bcff89bdc-fcq85 1/1 Running 0 2m15s +# ds-core-etcd-0 1/1 Running 0 2m15s +# ds-worker-7zv94 1/1 Running 2 2m15s +# ds-worker-rd2qv 1/1 Running 2 2m15s +# function-agent-0-666m-666mi-faascontroller-ff2e2dbd000000000070 2/2 Running 0 52s +# function-agent-7cb89f9887-2p7j9 2/2 Running 0 2m15s +# function-agent-8798923c9d0c-5000m-10240mi-faasfrontend-b51d6066 2/2 Running 0 49s +# function-agent-a06d7afc49db-999m-4096mi-faasscheduler-164893650 2/2 Running 0 49s +# function-agent-e9dcb279bac1-1000m-1024mi-faasmanager-8000800b00 2/2 Running 0 49s +# function-master-6f9b957f9d-b4lzw 1/1 Running 1 2m15s +# function-proxy-62npv 1/1 Running 1 2m15s +# function-proxy-nh4xp 1/1 Running 1 2m15s +# function-repository-74b7bd96cc-lxlbr 1/1 Running 0 2m15s +# iam-server-78ff4cbf69-mlwxf 1/1 Running 1 2m15s +# meta-service-754df6c44f-mlv6n 1/1 Running 0 2m15s +# minio-69d7bd5786-fl9kr 1/1 Running 0 2m15s +``` + +可运行[简单示例](../../multi_language_function_programming_interface/examples/simple-function-template.md)进一步验证部署结果。 + +## 卸载openYuanrong + +```bash +helm uninstall yuanrong +``` diff --git a/docs/multi_language_function_programming_interface/FaaS/function_call/asynchronized_invoke.md b/docs/multi_language_function_programming_interface/FaaS/function_call/asynchronized_invoke.md new file mode 100644 index 0000000000000000000000000000000000000000..ce65e387b39c7e89ef7b3124bf6de0c3fe66bb8e --- /dev/null +++ b/docs/multi_language_function_programming_interface/FaaS/function_call/asynchronized_invoke.md @@ -0,0 +1,3 @@ +# 异步调用 + +TODO diff --git a/docs/multi_language_function_programming_interface/FaaS/function_call/index.md b/docs/multi_language_function_programming_interface/FaaS/function_call/index.md new file mode 100644 index 0000000000000000000000000000000000000000..4130b4a0922506f52f1f7b2242bfb2cf074e731c --- /dev/null +++ b/docs/multi_language_function_programming_interface/FaaS/function_call/index.md @@ -0,0 +1,11 @@ +# 调用 FaaS 函数 + +```{eval-rst} +.. toctree:: + :glob: + :maxdepth: 1 + :hidden: + + synchronized_invoke + asynchronized_invoke +``` diff --git a/docs/multi_language_function_programming_interface/FaaS/function_call/invoked_by_yr_cli.md b/docs/multi_language_function_programming_interface/FaaS/function_call/invoked_by_yr_cli.md new file mode 100644 index 0000000000000000000000000000000000000000..95a8861b8fa4646bd4bfc8b0e07cd3cab8488705 --- /dev/null +++ b/docs/multi_language_function_programming_interface/FaaS/function_call/invoked_by_yr_cli.md @@ -0,0 +1,13 @@ +# 使用命令行调用函数 + +指定函数名字(test),调用函数(不带参数),执行命令如下: + +```shell +yrctl invoke test +``` + +指定函数名字(test),调用函数(带参数: 参数限制为 json 格式),执行命令如下: + +```shell +yrctl invoke test -e '{"key": "value"}' +``` diff --git a/docs/multi_language_function_programming_interface/FaaS/function_call/synchronized_invoke.md b/docs/multi_language_function_programming_interface/FaaS/function_call/synchronized_invoke.md new file mode 100644 index 0000000000000000000000000000000000000000..aed4751318d17cffe39d5c4c0557ab38b9c3be2a --- /dev/null +++ b/docs/multi_language_function_programming_interface/FaaS/function_call/synchronized_invoke.md @@ -0,0 +1,49 @@ +# 同步调用 + +## 功能介绍 + +同步调用指的是客户端请求需要明确等到响应结果,也就是说这样的请求必须得调用到用户的函数,并且等到调用完成才返回。 + +## API 示例 + +```{eval-rst} +.. openapi:: ./swagger.yaml +``` + +## 请求示例 + +```shell +POST HTTP:///serverless/v1/functions/<函数URN>/invocations +Content-Type: application/json +{ + "key" : "value" +} +``` + +## 响应示例 + +- 成功示例 + +```shell +HTTP/1.1 200 OK +Content-Type: application/json +X-Billing-Duration: <计费信息> +X-Inner-Code: 0 +X-Invoke-Summary: <执行摘要> +X-Log-Result: <执行日志> +{ + "key" : "value" +} +``` + +- 失败示例 + +```shell +HTTP/1.1 500 Internal Server Error +Content-Type: application/json +X-Inner-Code: <错误码> +{ + "code" : <错误码>, + "message" : <错误信息> +} +``` \ No newline at end of file diff --git a/docs/multi_language_function_programming_interface/FaaS/function_configuration/config_env.md b/docs/multi_language_function_programming_interface/FaaS/function_configuration/config_env.md new file mode 100644 index 0000000000000000000000000000000000000000..815cf609461d732c8dc012e5f2bddf5a96967f46 --- /dev/null +++ b/docs/multi_language_function_programming_interface/FaaS/function_configuration/config_env.md @@ -0,0 +1,93 @@ +# 环境变量 + +可以使用环境变量,在不修改代码的前提下执行不同的代码片段。环境变量作为函数配置的一部分,以字符串键值对的方式存储,不同函数拥有独立的环境变量。本文介绍环境变量的基本信息、配置方式。 + +> 环境变量在openYuanrong系统中使用 AES256 ( Advanced Encryption Standard 256 )标准加密存储,在初始化函数实例时,会将环境变量解密后注入到函数实例上下文中。 + +## 使用限制 + +1. 字符集规则 + - Key 的字符集:必须以大小写字母开头,只能包含大小写字母、数字。 + +## 配置环境变量 + +参考[创建事件函数](../function_management/create_faasFunc.md) 创建openYuanrong函数时,请求参数中新增 environment 即可给函数实例设置环境变量 + +### URI + +```text +POST /serverless/v1/functions +``` + +### 请求参数 + + + + + + + + + + + + + + + + + + + + +
参数类型是否必填约束描述
environmentmap + key-value 格式,key 和 value 均为 string。 + + 需要使用JSON格式。 +
+ +### 举例 + +

+{
+  "name": "0@faaspy@example1",
+  "runtime": "python3.9",
+  "description": "this is a FaaS function",
+  "handler": "handler.my_handler",
+  "kind": "faas",
+  "cpu": 600,
+  "memory": 512,
+  "timeout": 600,
+  "customResources": {},
+  "environment": {
+    "env1": "value"
+  },
+  "extendedHandler": {
+    "initializer": "handler.init",
+    "pre_stop": "handler.prestop"
+  },
+  "extendedTimeout": {
+    "initializer": 600,
+    "pre_stop": 10
+  },
+  "minInstance": "0",
+  "maxInstance": "10",
+  "concurrentNum": "2",
+  "storageType": "local",
+  "codePath": "/home/example/create_faasFunc/"
+}
+
+ +## 使用环境变量 + +在 FaaS 函数中调用获取环境变量,以 python 为例(获取环境变量名为 env1 的环境变量): + +```python +context.getUserData(env1) +``` + +以 java 为例(获取环境变量名为 env1 的环境变量): + +```java +context.getUserData(env1); +``` \ No newline at end of file diff --git a/docs/multi_language_function_programming_interface/FaaS/function_configuration/config_layer.md b/docs/multi_language_function_programming_interface/FaaS/function_configuration/config_layer.md new file mode 100644 index 0000000000000000000000000000000000000000..6471de971e16e65f2ff34b8196f4a188ff3497cf --- /dev/null +++ b/docs/multi_language_function_programming_interface/FaaS/function_configuration/config_layer.md @@ -0,0 +1,12 @@ +# 函数层 + +## 概念介绍 + +与函数包不同,层中通常用来存储不经常变更的静态文件或三方依赖库。比如 node_modules 、 python 依赖包等。 +使用层管理,您可以将依赖放在层中而不是部署包中,可确保部署包保持较小的体积。 + +## 配置函数层 + +当前版本暂不支持 + +参考 [发布层](http://7.227.34.194:8888/development/source_zh_ch/7_command_line_tool/clilist/layermanagement/%E5%8F%91%E5%B8%83%E5%B1%82.html) diff --git a/docs/multi_language_function_programming_interface/FaaS/function_configuration/config_max_instance.md b/docs/multi_language_function_programming_interface/FaaS/function_configuration/config_max_instance.md new file mode 100644 index 0000000000000000000000000000000000000000..aa8cf25353cf263d66d5b0df5afc1ab400ee7a92 --- /dev/null +++ b/docs/multi_language_function_programming_interface/FaaS/function_configuration/config_max_instance.md @@ -0,0 +1,67 @@ +# 最大实例数 + +最大实例指openYuanrong分配给用户 FaaS 函数的实例个数(计算资源数量)上限,在请求量增多时,openYuanrong会根据实例负载情况进行扩容,上限的实例个数为最大实例个数。 + +## 配置最大实例数 + +参考[创建事件函数](../function_management/create_faasFunc.md) 创建openYuanrong函数时,请求参数中新增 maxInstance 即可给函数设置最大实例数。 + +### URI + +```text +POST /serverless/v1/functions +``` + +### 请求参数 + + + + + + + + + + + + + + + + + +
参数类型是否必填约束
maxInstancestring + 字符串形式的数字 +
+ +### 举例 + +

+{
+  "name": "0@faaspy@example1",
+  "runtime": "python3.9",
+  "description": "this is a FaaS function",
+  "handler": "handler.my_handler",
+  "kind": "faas",
+  "cpu": 600,
+  "memory": 512,
+  "timeout": 600,
+  "customResources": {},
+  "environment": {
+    "env1": "value"
+  },
+  "extendedHandler": {
+    "initializer": "handler.init",
+    "pre_stop": "handler.prestop"
+  },
+  "extendedTimeout": {
+    "initializer": 600,
+    "pre_stop": 10
+  },
+  "minInstance": "0",
+  "maxInstance": "10",
+  "concurrentNum": "2",
+  "storageType": "local",
+  "codePath": "/home/example/create_faasFunc/"
+}
+
\ No newline at end of file diff --git a/docs/multi_language_function_programming_interface/FaaS/function_configuration/config_reserve_instance.md b/docs/multi_language_function_programming_interface/FaaS/function_configuration/config_reserve_instance.md new file mode 100644 index 0000000000000000000000000000000000000000..df765b9240ccd81b1879b1b065c91f0e1fb9230b --- /dev/null +++ b/docs/multi_language_function_programming_interface/FaaS/function_configuration/config_reserve_instance.md @@ -0,0 +1,69 @@ +# 预留实例 + +预留实例指openYuanrong分配给用户 FaaS 函数的最小实例个数(计算资源数量),函数实例最少运行的数量。 + +函数创建完成后,就会预先拉起对应数量的函数实例。openYuanrong会在请求规模降低时对函数实例进行缩容,但是至少保持最小实例个数的实例处理用户请求。 + +## 配置预留实例 + +参考[创建事件函数](../function_management/create_faasFunc.md) 创建openYuanrong函数时,请求参数中新增 minInstance 即可给函数设置预留实例。 + +### URI + +```text +POST /serverless/v1/functions +``` + +### 请求参数 + + + + + + + + + + + + + + + + + +
参数类型是否必填约束
minInstancestring + 字符串形式的数字 +
+ +### 举例 + +

+{
+  "name": "0@faaspy@example1",
+  "runtime": "python3.9",
+  "description": "this is a FaaS function",
+  "handler": "handler.my_handler",
+  "kind": "faas",
+  "cpu": 600,
+  "memory": 512,
+  "timeout": 600,
+  "customResources": {},
+  "environment": {
+    "env1": "value"
+  },
+  "extendedHandler": {
+    "initializer": "handler.init",
+    "pre_stop": "handler.prestop"
+  },
+  "extendedTimeout": {
+    "initializer": 600,
+    "pre_stop": 10
+  },
+  "minInstance": "0",
+  "maxInstance": "10",
+  "concurrentNum": "2",
+  "storageType": "local",
+  "codePath": "/home/example/create_faasFunc/"
+}
+
diff --git a/docs/multi_language_function_programming_interface/FaaS/function_configuration/config_scale_policy.md b/docs/multi_language_function_programming_interface/FaaS/function_configuration/config_scale_policy.md new file mode 100644 index 0000000000000000000000000000000000000000..3d0d7451bb1f38ace07d178b678897a85d2c7a08 --- /dev/null +++ b/docs/multi_language_function_programming_interface/FaaS/function_configuration/config_scale_policy.md @@ -0,0 +1,11 @@ +# 弹性策略 + +openYuanrong支持基于并发度的弹性策略,当并发度达到配置的单实例并发度时,触发实例扩容。 + +当前函数并发与实例数的关系如图: + +![](../../../../images/4d792ba0dea7ac4f501e3470b49421cb_474x285.png) + +## 配置弹性策略 + +当前openYuanrong不支持其他弹性策略,默认使用基于并发度的弹性。 diff --git a/docs/multi_language_function_programming_interface/FaaS/function_configuration/config_scheduling_policy.md b/docs/multi_language_function_programming_interface/FaaS/function_configuration/config_scheduling_policy.md new file mode 100644 index 0000000000000000000000000000000000000000..9d4a4a70a9965b82f8330e1873e4a2d99feb427b --- /dev/null +++ b/docs/multi_language_function_programming_interface/FaaS/function_configuration/config_scheduling_policy.md @@ -0,0 +1,29 @@ +# 请求调度策略 + +## 概念介绍 + +openYuanrong支持为函数配置不同的调度策略当前支持 concurrency 、 round-robin 和 microservice 。 + +### concurrency + +concurrency 调度策略即为根据当前实例的并发度情况完成调度,请求会被优先调度到并发度较低的实例上。 + +### round-robin + +round-robin 调度策略即轮询调度,请求会被轮流分配给不同的实例。 + +### microservice + +microservice 调度策略代表您没有为单个函数指定调度策略,具体使用什么调度策略将在openYuanrong集群部署时指定。 + +### 最小连接数 + +TODO + +### 随机调度 + +TODO + +## 配置调度策略 + +TODO diff --git a/docs/multi_language_function_programming_interface/FaaS/function_configuration/config_single_concurrency.md b/docs/multi_language_function_programming_interface/FaaS/function_configuration/config_single_concurrency.md new file mode 100644 index 0000000000000000000000000000000000000000..9100beae57eb1d0f4362b09b125b16aba99f5fad --- /dev/null +++ b/docs/multi_language_function_programming_interface/FaaS/function_configuration/config_single_concurrency.md @@ -0,0 +1,75 @@ +# 单实例并发度 + +## 概念介绍 + +并发度指openYuanrong分配给用户 FaaS 函数的单个实例的最大线程数,即每个实例同时处理的请求个数。 + +单实例单并发:函数实例在同一时间只能处理 1 个请求, 1 个请求处理完了再处理下一个请求。计费时长从处理第一个请求开始,到最后一个请求结束为止。 + +单实例多并发:多个请求在一个实例并发处理时,以实例的实际占用时间作为计费的执行时长,即从第一个请求开始,到最后一个请求结束期间的时长。 + +应用场景:单实例多并发功能使用与函数中有较多时间在等待下游服务响应的场景,等待响应一般不消耗资源,在一个实例内并发处理可以节省费用。 + +## 配置并发度 + +参考[创建事件函数](../function_management/create_faasFunc.md)创建openYuanrong函数时,请求参数中新增 concurrentNum 即可给函数实例设置单实例并发度。 + +### URI + +```text +POST /serverless/v1/functions +``` + +### 请求参数 + + + + + + + + + + + + + + + + + +
参数类型是否必填约束
concurrentNumstring + 字符串形式的数字 +
+ +### 举例 + +

+{
+  "name": "0@faaspy@example1",
+  "runtime": "python3.9",
+  "description": "this is a FaaS function",
+  "handler": "handler.my_handler",
+  "kind": "faas",
+  "cpu": 600,
+  "memory": 512,
+  "timeout": 600,
+  "customResources": {},
+  "environment": {
+    "env1": "value"
+  },
+  "extendedHandler": {
+    "initializer": "handler.init",
+    "pre_stop": "handler.prestop"
+  },
+  "extendedTimeout": {
+    "initializer": 600,
+    "pre_stop": 10
+  },
+  "minInstance": "0",
+  "maxInstance": "10",
+  "concurrentNum": "2",
+  "storageType": "local",
+  "codePath": "/home/example/create_faasFunc/"
+}
+
diff --git a/docs/multi_language_function_programming_interface/FaaS/function_configuration/index.md b/docs/multi_language_function_programming_interface/FaaS/function_configuration/index.md new file mode 100644 index 0000000000000000000000000000000000000000..4cafda36e9c362b04a357ad8f2f89046aa693b71 --- /dev/null +++ b/docs/multi_language_function_programming_interface/FaaS/function_configuration/index.md @@ -0,0 +1,16 @@ +# 配置 FaaS 函数 + +```{eval-rst} +.. toctree:: + :glob: + :maxdepth: 1 + :hidden: + + config_scale_policy + config_single_concurrency + config_max_instance + config_reserve_instance + config_env + config_scheduling_policy + config_layer +``` diff --git a/docs/multi_language_function_programming_interface/FaaS/function_development/build_layer/index.md b/docs/multi_language_function_programming_interface/FaaS/function_development/build_layer/index.md new file mode 100644 index 0000000000000000000000000000000000000000..26f9ff0c714e37fe13ba55ec752d2daee5a1b5dc --- /dev/null +++ b/docs/multi_language_function_programming_interface/FaaS/function_development/build_layer/index.md @@ -0,0 +1,3 @@ +# 制作函数层 + +TODO diff --git a/docs/multi_language_function_programming_interface/FaaS/function_development/build_package/build_package.md b/docs/multi_language_function_programming_interface/FaaS/function_development/build_package/build_package.md new file mode 100644 index 0000000000000000000000000000000000000000..c34cae9b0c71c3871bf9d673441f3c70006f159c --- /dev/null +++ b/docs/multi_language_function_programming_interface/FaaS/function_development/build_package/build_package.md @@ -0,0 +1,36 @@ +# 打包 + +代码开发完成后,需要压缩成 zip 格式包后上传。 + +## 解释型语言打包 + +例如 python 、 nodejs 等解释型语言,不需要对工程编译,只需要将源码进行打包即可。如果函数类型是 http 函数,则还需要将 bootstrap 文件也打包进行 zip 包中。 + +函数入口文件,建议放在根目录下,例如 Nodejs 的入口函数文件是 index.js ,则其打包的目录结构如: + +```text +|yrnodejsfunc + index.js + xxx... +``` + +则我们仅需要将 index.js 以及同目录下的其他代码文件也压缩即可 +*注*:需要在 yrnodejsfunc 目录下进行压缩,不要把 yrnodejsfunc 文件夹名也打包进去。 + +event 类型的 Node.js 函数的打包可以参考[event Node.js 部署](../event_function/Node.js/部署.md) +event 类型的 python 语言的打包可以参考[event Python 部署](../event_function/Python/部署.md)。 + +http 类型 Node.js 函数的打包可以参考[http Node.js 部署](../http_function/Node.js.md) +http 类型的 python 语言的打包可以参考 todo 。 + +## 编译型语言打包 + +例如 Java 等编译型语言,需要对工程编译后,将二进制文件打包上传即可。如果函数类型是 http 函数,则还需要将 bootstrap 文件也打包进行 zip 包中。 +与解释型语言不同的是,函数入口文件不需要放在根目录下。 + +event 类型的 Java 函数打包可以参考[event Java 部署](../event_function/Java/编译部署.md) +http 类型的 Java 函数打包可以参考[http Java 部署](../http_function/Java.md) + +## 自定义镜像语言打包 + +自定义镜像函数其实没有打包概念,其需要先将镜像推送到镜像仓后,获取对应镜像名即可。镜像名填入对应的函数部署的对应字段。openYuanrong在该函数实例启动时会自动去镜像仓库拉取镜像。 \ No newline at end of file diff --git a/docs/multi_language_function_programming_interface/FaaS/function_development/build_package/index.md b/docs/multi_language_function_programming_interface/FaaS/function_development/build_package/index.md new file mode 100644 index 0000000000000000000000000000000000000000..fbabbc0f924fe017a547d5c7dfb038e261882a07 --- /dev/null +++ b/docs/multi_language_function_programming_interface/FaaS/function_development/build_package/index.md @@ -0,0 +1,9 @@ +# 制作函数代码包 + +```{eval-rst} +.. toctree:: + :glob: + :hidden: + + build_package +``` diff --git a/docs/multi_language_function_programming_interface/FaaS/function_development/customimage_function/index.md b/docs/multi_language_function_programming_interface/FaaS/function_development/customimage_function/index.md new file mode 100644 index 0000000000000000000000000000000000000000..545dc4a87c3aee13acde6761af9936ffec84b1f8 --- /dev/null +++ b/docs/multi_language_function_programming_interface/FaaS/function_development/customimage_function/index.md @@ -0,0 +1,43 @@ +# 开发自定义镜像函数 + +openYuanrong支持用户自定义容器镜像来提供函数的代码包及运行时环境,相比代码包形式发布的函数,自定义镜像拥有更大的用户自定义空间。 + +## 函数入口 + +自定义镜像函数需要在镜像拉起后启动一个 HTTP 服务端进程,作为用户的函数入口,从openYuanrong函数系统接收函数调用请求并传递返回值。 + +### 函数入口的约束 + +- HTTP 服务端进程监听的端口必须是 8000 +- 作为调用入口的 Path 必须是 /invoke , Method 必须是 POST +- 作为调用事件的 HTTP 请求 Body 体必须使用 APIGTriggerEvent 格式 +- 作为调用结果的 HTTP 返回 Body 体会被封装 APIGTriggerResponse 格式 + +### 格式参考 + +APIGTriggerEvent + +```json +{ + "isBase64Encoded": "<是否使用 Base64 编码>", + "httpMethod": "", + "path": "", + "pathParameters": "", + "queryStringParameters": "", + "headers": "", + "body": "", + "requestContext": "<请求上下文>", + "user_data": "<用户数据>" +} +``` + +APIGTriggerResponse + +```json +{ + "isBase64Encoded": "<是否使用 Base64 编码>", + "headers": "", + "body": "", + "statusCode": "<请求返回码>" +} +``` \ No newline at end of file diff --git "a/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/C++/C++\350\277\220\350\241\214\346\227\266\344\273\213\347\273\215.md" "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/C++/C++\350\277\220\350\241\214\346\227\266\344\273\213\347\273\215.md" new file mode 100644 index 0000000000000000000000000000000000000000..1e369588df8b7791b4928bbb8bba18a6c31165c7 --- /dev/null +++ "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/C++/C++\350\277\220\350\241\214\346\227\266\344\273\213\347\273\215.md" @@ -0,0 +1,29 @@ +# C++ 运行时介绍 + +本文介绍 FaaS 场景下编写 C++ 运行时函数。 + +## 背景信息 + +C++ 需要编译后打包上传至云平台运行。 + +## Cpp 运行时 + +FaaS 目前支持的 C++ 运行环境如下: + +| 版本 | 操作系统系统 | 架构 | +|---------------|--------------------------|-----------------------| +| C++17 gcc 10.3.1 | Linux | x86_64、arm | + +需要提前安装好 gcc 环境。 + +```bash +$ gcc -v +Using built-in specs. +COLLECT_GCC=gcc +COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-linux-gnu/10.3.1/lto-wrapper +Target: x86_64-linux-gnu +Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,fortran,lto --enable-plugin --enable-initfini-array --disable-libgcj --without-isl --without-cloog --enable-gnu-indirect-function --build=x86_64-linux-gnu --with-stage1-ldflags=' -Wl,-z,relro,-z,now' --with-boot-ldflags=' -Wl,-z,relro,-z,now' --disable-bootstrap --with-tune=generic --with-arch_32=x86-64 --enable-multilib +Thread model: posix +Supported LTO compression algorithms: zlib +gcc version 10.3.1 (GCC) +``` \ No newline at end of file diff --git a/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/C++/index.rst b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/C++/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..7cff038ad64788c6e7d22e83a484850183ef570b --- /dev/null +++ b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/C++/index.rst @@ -0,0 +1,24 @@ +:orphan: + +.. Copyright (c) 2022 Huawei Technologies Co., Ltd + This software is licensed under Mulan PSL v2. + You can use this software according to the terms and conditions of the Mulan PSL v2. + You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 + THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + See the Mulan PSL v2 for more details. + +Cpp +============================== + +.. toctree:: + :glob: + :hidden: + + C++运行时介绍 + 函数入口 + 上下文 + 日志 + 编译部署 \ No newline at end of file diff --git "a/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/C++/\344\270\212\344\270\213\346\226\207.md" "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/C++/\344\270\212\344\270\213\346\226\207.md" new file mode 100644 index 0000000000000000000000000000000000000000..eaab73121b57f2c8f5e654edacf7f8d957c19c81 --- /dev/null +++ "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/C++/\344\270\212\344\270\213\346\226\207.md" @@ -0,0 +1,31 @@ +# 上下文 + +Context 类中提供了许多上下文方法供用户使用,包含一些函数的运行时信息,例如:request id、临时 access key 等。其声明和功能如表 1 所示。 + +表 1 Context 类上下文方法说明 + +| 方法名 | 方法说明 | +|-----------------------------------|------------------------------------------------------------------------| +| GetAccessKey() | 获取用户委托的 AccessKey(有效期 24 小时),使用该方法需要给函数配置委托。 | +| GetSecretKey() | 获取用户委托的 SecretKey(有效期 24 小时),使用该方法需要给函数配置委托。 | +| GetSecurityAccessKey() | 获取用户委托的 SecurityAccessKey(有效期 24 小时),使用该方法需要给函数配置委托。 | +| GetSecuritySecretKey() | 获取用户委托的 SecuritySecretKey(有效期 24 小时),使用该方法需要给函数配置委托。 | +| GetToken() | 获取函数 token 。 | +| GetAlias() | 获取函数的别名。 | +| GetTraceId() | 获取用户 Trace ID 。 | +| GetInvokeId() | 获取用户 Invoke ID 。 | +| GetLogger() | 获取 context 提供的 logger 方法,返回一个日志输出类,通过使用其 info 方法按“时间-请求 ID-输出内容”的格式输出日志。 | +| GetState() | 获取函数状态 。 | +| GetInstanceId() | 获取实例 ID 。 | +| GetInstanceLabel() | 获取示例标签。 | +| SetState(const std::string &state) | 设置函数状态。 | +| GetRequestID() | 获取当前函数的请求 ID 。 | +| GetUserData(string key) | 获取用户数据? | +| GetFunctionName() | 获取函数名称。 | +| GetRemainingTimeInMilliSeconds() | 获取函数超时时间(毫秒)。 | +| GetRunningTimeInSeconds() | 获取函数超时时间(秒)。 | +| GetVersion() | 获取函数的版本。 | +| GetMemorySize() | 获取函数占用的内存。 | +| GetCPUNumber() | 获取函数占用的 CPU 资源。 | +| GetProjectID() | 获取函数的 Project ID。 | +| GetPackage() | 获取函数包的名称的。 | diff --git "a/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/C++/\345\207\275\346\225\260\345\205\245\345\217\243.md" "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/C++/\345\207\275\346\225\260\345\205\245\345\217\243.md" new file mode 100644 index 0000000000000000000000000000000000000000..4053d61652807f3a42911b8ccc74bdf9cbf5731e --- /dev/null +++ "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/C++/\345\207\275\346\225\260\345\205\245\345\217\243.md" @@ -0,0 +1,74 @@ +# 函数入口 + +对于 C++ ,openYuanrong运行时支持 C++17 (gcc 10.3.1) 版本。 + +## 执行方法 + +函数有明确的接口定义,如下所示。 + +```cpp +std::string HandleRequest(const std::string &request, Function::Context &context); +``` + +入口函数名(HandleRequest):入口函数名称,需和函数执行入口处用户自定义的入口函数名称一致。 + +执行事件(request):函数执行界面由用户输入的执行事件参数, 格式为 JSON 对象。 + +上下文环境(context):Runtime 提供的函数执行上下文,其接口定义在上下文章节说明。 + +## initializer 入口介绍 + +### 功能说明 + +当函数实例被拉起时,函数初始化入口方法会首先被执行(函数实例生命周期中只会执行一次)当初始化入口执行完成,才会执行函数调用的方法。注意 Initializer 不是必须的 + +### 函数原型 + +```cpp +void Initializer(Function::Context &context); +``` + +用户实现 Initializer 方法后,通过`RegisterInitializerFunction`方法注册 + +```cpp +void Initializer(Function::Context &context) { + // 初始化的逻辑 +} + +Function::Runtime rt; +rt.RegisterInitializerFunction(Initializer); +``` + +### initializer 接口的优点 + +- 分离初始化逻辑和请求处理逻辑 +- 用户函数代码更新时,系统能够保证用户函数的平滑升级,减少应用层初始化冷启动带来的性能损耗。新的函数实例启动后能够自动执行用户的初始化逻辑,在初始化完成后再处理请求 +- 在应用负载上升、需要增加更多函数实例时,系统能够识别函数应用层初始化的开销,由此更准确的计算资源伸缩的时机和所需的资源量、让请求延时更加平稳 + +## InitState 介绍 + +### 功能说明 + +当调用函数时,如果该函数是一个有状态函数,会触发状态初始化方法的调用,然后才会执行函数调用请求。 + +### 函数原型 + +```cpp +void InitState(const std::string& state, Function::Context& context); +``` + +状态数据 state: 当进行有状态函数互调时,可以将 state 信息放入 request 里。该参数可忽略,业务自己在该方法中实现状态相关逻辑。 + +上下文环境 context : runtime 构造的变量,用户可以通过 context 进行日志打印、获取环境变量等,具体可以参考上下文章节的说明 + +对于有状态函数,用户需要自行实现 InitState 方法,并通过 InitState 方法注册 + +```cpp +void InitState(const std::string& request, Function::Context& context) { + // 业务逻辑 + context.SetState(stateString); // 必须 +} + +Function::Runtime rt; +rt.InitState(InitState); +``` \ No newline at end of file diff --git "a/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/C++/\346\227\245\345\277\227.md" "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/C++/\346\227\245\345\277\227.md" new file mode 100644 index 0000000000000000000000000000000000000000..04b85a2212a81b5b90ca84074acff6412e77965b --- /dev/null +++ "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/C++/\346\227\245\345\277\227.md" @@ -0,0 +1,45 @@ +# 日志 + +## 使用 stdout 打印日志 + +使用该方法打印日志会将内容原样输出到日志中。代码示例如下所示。 + +```cpp +std::string HandleRequest(const std::string &request, Function::Context &context) +{ + std::cout << "hello world" << std::endl; + return "done"; +} +``` + +执行以上代码,输出的日志内容如下所示。 + +```bash +hello world +``` + +## 使用 context().GetLogger 打印日志 + +使用 context.getLogger 打印日志,以通过 request id 区分各并发请求的日志。代码示例如下所示。 + +```cpp +std::string HandleRequest(const std::string &request, Function::Context &context) +{ + Function::FunctionLogger logger = context.GetLogger(); + logger.setLevel("INFO"); + logger.Debug("hello cpp %s ", "user debug log"); + logger.Info("hello cpp %s ", "user info log"); + logger.Warn("hello cpp %s ", "user warn log"); + logger.Error("hello cpp %s ", "user error log"); + return "done"; +} +``` + +执行以上代码,输出的日志内容如下所示。 + +```bash +2025-xx-xx xx:xx:xx xxxxxxxx-xxxx-xxxx-xxxx-xxxxx****xx [DEBUG] hello cpp user debug log +2025-xx-xx xx:xx:xx xxxxxxxx-xxxx-xxxx-xxxx-xxxxx****xx [INFO] hello cpp user info log +2025-xx-xx xx:xx:xx xxxxxxxx-xxxx-xxxx-xxxx-xxxxx****xx [WARNING] hello cpp user warn log +2025-xx-xx xx:xx:xx xxxxxxxx-xxxx-xxxx-xxxx-xxxxx****xx [ERROR] hello cpp user error log +``` \ No newline at end of file diff --git "a/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/C++/\347\274\226\350\257\221\351\203\250\347\275\262.md" "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/C++/\347\274\226\350\257\221\351\203\250\347\275\262.md" new file mode 100644 index 0000000000000000000000000000000000000000..3cf1b580a3c9321527fc17c4e6baf44d4f21d726 --- /dev/null +++ "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/C++/\347\274\226\350\257\221\351\203\250\347\275\262.md" @@ -0,0 +1,151 @@ +# 部署 + +## Step 1. 部署基于 k8s 的openYuanrong集群 + +部署使用openYuanrong的 FaaS 能力,当前需要基于 k8s 的部署方式,请参考 [k8s 部署快速起步](../../../../../../deploy/deploy_on_k8s/single-node-deployment.md) 章节。 + +## Step 2. 创建一个 Cpp 的 faas 工程 + +在自己的工作目录 (例如 `/home/user/faas`)下创建一个 cpp 工程。目录如下 + +```bash +$ tree +faascpp +├── CMakeLists.txt +└── main.cpp + +0 directories, 2 files +``` + +`main.cpp`内容如下 + +```cpp +#include +#include +#include "Function.h" +#include "Runtime.h" + +std::string HandleRequest(const std::string &request, Function::Context &context) +{ + std::string traceID = context.GetTraceId(); + std::string RequestID = context.GetRequestID(); + std::string FunctionName = context.GetFunctionName(); + std::cout << "hello faas!" << std::endl; + + nlohmann::json j = { + {"traceID", traceID}, + {"RequestID", RequestID}, + {"FunctionName", FunctionName} + }; + return j.dump(); +} + +void Initializer(Function::Context &context) { + return; +} + +int main(int argc, char *argv[]) +{ + Function::Runtime rt; + rt.RegisterHandler(HandleRequest); + rt.RegisterInitializerFunction(Initializer); + rt.Start(argc, argv); + return 0; +} +``` + +`CMakeLists.txt` 内容如下。注意替换 `YUANRONG_DIR` 为自己本地 yuanrong 目录 + +```cmake +cmake_minimum_required(VERSION 3.16.1) +project("faas-cpp" LANGUAGES C CXX) +set(CMAKE_CXX_STANDARD 17) + +include_directories( + ${YUANRONG_DIR}/runtime/sdk/cpp/include +) + +link_directories( + ${YUANRONG_DIR}/runtime/sdk/cpp/lib +) + +add_executable(handler main.cpp) +target_link_libraries(handler functionsdk) +``` + +然后编译 + +```bash +mkdir build +cd build +cmake .. +make -j8 +``` + +## Step 3. 打包可执行文件并通过 Meta-Service 创建函数 + +```bash +cd /home/user/faas/faascpp/build +ldd ./handler | awk '/=>/ {print $3}' | grep -v '^$' | tr '\n' '\0' | xargs zip -j faascpp.zip ./handler +``` + +把这个 zip 文件上传到自定义的 s3 路径,例如`https://x.x.x.x:xxx` 的 bucket `my-bucket-id` 下。然后编写下方 json 连接 Meta-Service。 + +```json +{ + "name": "0@faascpp@hello", + "runtime": "posix-custom-runtime", + "handler": "handler", + "kind": "faas", + "cpu": 600, + "memory": 512, + "timeout": 600, + "storageType": "s3", + "s3CodePath": { + "bucketId": "my-bucket-id", + "objectId": "faascpp.zip", + "bucketUrl": "https://x.x.x.x:xxx" + } +} +``` + +### 请求示例 + +```bash +META_SERVICE_ADDR="http://$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type=="InternalIP")].address}'):$(kubectl get svc meta-service -o jsonpath='{.spec.ports[0].nodePort}')" + +curl -X POST -H "Content-Type: application/json" -d \ +'{ + "name": "0@faascpp@hello", + "runtime": "posix-custom-runtime", + "handler": "handler", + "kind": "faas", + "cpu": 600, + "memory": 512, + "timeout": 600, + "storageType": "s3", + "s3CodePath": { + "bucketId": "my-bucket-id", + "objectId": "faascpp.zip", + "bucketUrl": "https://x.x.x.x:xxx" + } +}' \ +http://${META_SERVICE_ADDR}/serverless/v1/functions +``` + +## Step 4. 访问函数 + +在 FaaS 函数发布后,openYuanrong会生成一个访问链接,可以通过这个链接触发 FaaS 函数的访问。这里用`json`格式传入 event 的 name 字段。这个参数将从响应中体现。 + +### 请求示例 + +```bash +curl -X POST -H "Content-Type: application/json" -d '{"name": "faas"}' \ + -i ${META_SERVICE_ADDR}/serverless/v1/functions/sn:cn:yrk:12345678901234561234567890123456:function:0@faascpp@hello:latest/invocations +``` + +### 响应示例 + +```bash +hello faas! +``` diff --git "a/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Java/Java\350\277\220\350\241\214\346\227\266\344\273\213\347\273\215.md" "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Java/Java\350\277\220\350\241\214\346\227\266\344\273\213\347\273\215.md" new file mode 100644 index 0000000000000000000000000000000000000000..5a3481d9988e6a55311357eaa778c7aca0727c27 --- /dev/null +++ "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Java/Java\350\277\220\350\241\214\346\227\266\344\273\213\347\273\215.md" @@ -0,0 +1,24 @@ +# Java 运行时介绍 + +本文介绍 FaaS 场景下编写 Java 运行时函数。 + +## 背景信息 + +Java 语言是编译型语言,需要编译后在 JVM 虚拟机中运行,有如下限制: 【 todo -改完编译后上传】 + +- 不支持代码在线编译,使用 Java 语言仅支持上传已经开发完成编译打包后的 zip 包【 todo -待确定是否两种方式都支持】。 +- 不支持代码在线编辑,由于不支持上传代码,所以不支持在线编辑代码。 + +## Java 运行时 + +FaaS 目前支持的 Java 运行环境如下: + +| 版本 | 操作系统系统 | 架构 | +|---------|--------------------------|-----------------------| +| Java 8 | Linux | x86_64、arm | +| Java 11 | Linux | x86_64、arm | +| Java 17 | Linux | x86_64、arm | +| Java 21 | Linux | x86_64、arm | + +FaaS 提供 Java SDK,提供函数互调【 todo java sdk 的功能还需要补充】等功能。 +【todo】如何部署时候指定 Java 版本 diff --git a/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Java/index.rst b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Java/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..3c29fad9a4db660f2b27dbfc3799df181e521cfe --- /dev/null +++ b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Java/index.rst @@ -0,0 +1,24 @@ +:orphan: + +.. Copyright (c) 2022 Huawei Technologies Co., Ltd + This software is licensed under Mulan PSL v2. + You can use this software according to the terms and conditions of the Mulan PSL v2. + You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 + THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + See the Mulan PSL v2 for more details. + +Java +============================== + +.. toctree:: + :glob: + :hidden: + + Java运行时介绍 + 函数入口 + 上下文 + 日志 + 编译部署 \ No newline at end of file diff --git "a/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Java/\344\270\212\344\270\213\346\226\207.md" "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Java/\344\270\212\344\270\213\346\226\207.md" new file mode 100644 index 0000000000000000000000000000000000000000..053154745fd22519d741b58fdc32af69c03cfa3a --- /dev/null +++ "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Java/\344\270\212\344\270\213\346\226\207.md" @@ -0,0 +1,122 @@ +# 上下文 + +在执行函数初始化方法或者执行方法时,Java 运行时会传递 context 参数, context 中包含函数和请求的信息以及 Java Runtime 提供给函数的功能。 +context 的引入方式为:*import com.xxx.services.runtime.Context;* + +## 上下文介绍 + +context 以方法形式提供信息和功能。 + +``` java + + // 获取本次请求的requestId + public String getRequestID() + + // 获取本次请求剩余执行时间,单位毫秒 + public int getRemainingTimeInMilliSeconds() + + // 获取ak + public String getAccessKey() + + // 获取sk + public String getSecretKey() + + // 根据key查询环境变量 + public String getUserData(String key) + + // 获取函数名 + public String getFunctionName() + + // 获取请求超时时间,单位秒 + public int getRunningTimeInSeconds() + + // 获取函数版本 + public String getVersion() + + // 获取函数的内存大小 + public int getMemorySize() + + // 获取函数的cpu大小 + public int getCPUNumber() + + // 获取函数的projectId + public String getProjectID() + + // 获取token // todo 不确定 + public String getToken() + + // 获取安全token // todo 不确定 + public String getSecurityToken() + + // 获取本租户所有的别名 // todo 不确定 + public String getAlias() + + // 获取日志方法,用于日志打印 + public RuntimeLogger getLogger() + + // 获取Java运行时的实例名 + public String getInstanceID() + + // 获取请求的traceId + public String getTraceID() + + // 获取当前实例的InstanceLabel + public String getInstanceLabel() {} +``` + +## 通过 context 获取请求上下文示例 + +```java +package programmingmodel; + +import java.io.UnsupportedEncodingException; +import java.util.HashMap; +import java.util.Map; +import java.io.*; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import java.util.Date; +import java.text.SimpleDateFormat; + +import com.xxx.services.runtime.Context; + +public class Testyrjavacontext001 { + public String myHandler(String name, Context context) throws Exception { + + Map headers = new HashMap(); + headers.put("Content-Type", "application/json"); + + Map bodyDict = new HashMap(); + + bodyDict.put("getRequestID",context.getRequestID()); + bodyDict.put("getRemainingTimeInMilliSeconds",String.valueOf(context.getRemainingTimeInMilliSeconds())); + bodyDict.put("getAccessKey",context.getAccessKey()); + bodyDict.put("getSecretKey",context.getSecretKey()); + bodyDict.put("getUserData",context.getUserData("key")); + bodyDict.put("getFunctionName",context.getFunctionName()); + bodyDict.put("getRunningTimeInSeconds",String.valueOf(context.getRunningTimeInSeconds())); + bodyDict.put("getVersion",context.getVersion()); + bodyDict.put("getMemorySize",String.valueOf(context.getMemorySize())); + bodyDict.put("getCPUNumber",String.valueOf(context.getCPUNumber())); + bodyDict.put("getProjectID",context.getProjectID()); + bodyDict.put("getPackage",context.getPackage()); + bodyDict.put("instanceLabel",context.getInstanceLabel()); + + try { + BufferedReader reader=new BufferedReader(new FileReader("/tmp/initializer.log")); + String initializer_file_data = reader.readLine(); + bodyDict.put("initializer_file_data",initializer_file_data); + reader.close(); + } + catch (IOException e){ + System.out.print("==========================================!!!!!!!!!!!!!!!! error read /tmp/initializer.log error "); + throw new Exception("=====!!!!!!!!!!!!!!!! error read /tmp/initializer.log error"); + } + + Gson gson = new Gson(); + String res = gson.toJson(bodyDict); + return res; + } +} + +``` \ No newline at end of file diff --git "a/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Java/\345\207\275\346\225\260\345\205\245\345\217\243.md" "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Java/\345\207\275\346\225\260\345\205\245\345\217\243.md" new file mode 100644 index 0000000000000000000000000000000000000000..29f7d432bf4011d01a977c4fd60fe0babad4e8bc --- /dev/null +++ "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Java/\345\207\275\346\225\260\345\205\245\345\217\243.md" @@ -0,0 +1,89 @@ +# 函数入口 + +函数入口包含两种方法:执行方法和初始化方法。定义 Java 函数入口,格式为: *[包名].[类名].[方法名]* 或者 *[包名].[类名]::[方法名]* + +例如,包名是 com.example , 类名是 FaaSHandler ,函数名是 handler ,则方法为*com.example.FaaSHandler.handler*或者是*com.example.FaaSHandler::handler*。 + +如下,functions.yrjavafunc.handler 定义了执行方法,functions.yrjavafunc.initializer 定义了初始化方法。**注:yrjavafunc 为自定义的函数名** + +```text +service: yrjavatest +kind: faas +description: Java Faas示例 +functions: + yrjavafunc: + handler: com.example.FaaSHandler::handler + initializer: com.example.FaaSHandler.initializer + description: java function example + runtime: java1.8 + memory: 256 + timeout: 900 + cpu: 400 +``` + +## 执行方法 + +执行方法是 Java 运行时处理函数请求时调用的方法,即函数请求执行入口。在函数部署时**必须**指定执行方法。 +执行方法的示例: + +```java +package com.example; + +import com.xxx.services.runtime.Context; +import com.xxx.services.runtime.RuntimeLogger; +import com.google.gson.JsonObject; + +public class FaaSHandler{ + public JsonObject handler(JsonObject args, Context context) { + JsonObject res = new JsonObject(); + + res.add("body",new JsonObject()); + res.addProperty("contentType", "application/json"); + res.addProperty("statusCode", "200"); + return res; + } + + public void initializer(Context context) { + + } +} +``` + +Java 执行方法不必要实现某个接口。其入参有 args,context 。 + +- args 是用调用函数的事件数据,其类型可以根据您需要自定义,不必指定为 JsonObject。 +- context 是此次请求执行的上下文信息,其类型*必须*为*com.xxx.services.runtime.Context*,其具体内容可以参考下一节:上下文。 + +Java 执行方法的出参有一个 + +- 出参的类型可以根据您的需要自定义。 + +## 初始化方法 + +初始化方法是 Java 运行时启动后调用该方法,完成函数必要的准备工作,即函数初始化入口,该方法仅会调用一次。在函数部署时**按需**指定初始化方法。 +初始化方法的示例: + +```java +package com.example; + +import com.xxx.services.runtime.Context; +import com.xxx.services.runtime.RuntimeLogger; +import com.google.gson.JsonObject; + +public class FaaSHandler{ + public JsonObject handler(JsonObject args, Context context) { + return new JsonObject(); + } + + public void initializer(Context context) { + + } +} +``` + +Java 初始化方法不必要实现某个接口。其入参有 context。 + +- context 是此次调用的上下文信息,其类型*必须*为*com.xxx.services.runtime.Context*,其具体内容可以参考下一节:上下文。 + Java 初始化方法的出参有一个 +- 出参的类型为 void。 + diff --git "a/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Java/\346\227\245\345\277\227.md" "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Java/\346\227\245\345\277\227.md" new file mode 100644 index 0000000000000000000000000000000000000000..adf56c13327a624aed4e1019022e9ca4fa7e8152 --- /dev/null +++ "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Java/\346\227\245\345\277\227.md" @@ -0,0 +1,58 @@ +# 日志 + +context 中也提供了日志功能,日志对运维和问题定位有重要作用。 + +## 日志使用 + +示例: + +```java +package programmingmodel; + +import com.google.gson.JsonObject; +import com.xxx.services.runtime.Context; +import com.xxx.services.runtime.RuntimeLogger; + +public class YRLog +{ + public String myHandler(String name, Context context) + { + + RuntimeLogger runtimeLog = context.getLogger(); + runtimeLog.log(name); + runtimeLog.log(System.getenv().toString()); + runtimeLog.log(context.getRequestID()); + String rep = "a"; + rep = rep.repeat(6291456); + return rep; + } +} + +``` + +日志需要引入*import com.xxx.services.runtime.RuntimeLogger;*,类型为 RuntimeLogger 。其接口如下: + +```java + // 设置日志显示的级别,默认是INFO,level可以设置为DEBUG、INFO、WARN、ERROR + public void setLevel(String level) + + // 打印日志,级别为info,功能同info()函数 + public void log(String message) + + // 打印info级别的日志 + public void info(String message) + + // 打印debug级别的日志 + public void debug(String message) + + // 打印warn级别的日志 + public void warn(String message) + + // 打印error级别的日志 + public void error(String message) + +``` + +## 日志显示 + +该功能暂未实现 \ No newline at end of file diff --git "a/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Java/\347\274\226\350\257\221\351\203\250\347\275\262.md" "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Java/\347\274\226\350\257\221\351\203\250\347\275\262.md" new file mode 100644 index 0000000000000000000000000000000000000000..04644377beb8b4c5c73ed494bd83f850a0a2403a --- /dev/null +++ "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Java/\347\274\226\350\257\221\351\203\250\347\275\262.md" @@ -0,0 +1,194 @@ +# 编译部署 + +## Java 工程准备 + +```text +|yrjavatest + |service.yaml + |yrjavafunc + |pom.xml + |src + |main + |assembly + |zip_file.xml + |java + |com + |example + |FaaSHandler.java +``` + +## service.yaml 示例 + +```text +service: yrjavatest +kind: faas +description: Java Faas示例 +functions: + yrjavafunc: + handler: com.example.FaaSHandler::handler + initializer: com.example.FaaSHandler.initializer + description: java function example + runtime: java1.8 + memory: 256 + timeout: 900 + cpu: 400 +``` + +## 入口函数 + +```java +package com.example; + +import com.xxx.services.runtime.Context; +import com.xxx.services.runtime.RuntimeLogger; +import com.google.gson.Gson; +import com.google.gson.JsonObject; + +public class FaaSHandler{ + public JsonObject handler(JsonObject args, Context context) { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("func","hello"); + + JsonObject res = new JsonObject(); + + JsonObject p1 = new JsonObject(); + p1.addProperty("faas-content-type", "json"); + p1.addProperty("res-type", "context.env"); + JsonObject p2 = new JsonObject(); + p2.add("result",jsonObject); + + res.add("headers",p1); + res.addProperty("isBase64Encoded",false); + res.add("body",p2); + res.addProperty("contentType", "application/json"); + res.addProperty("statusCode", "200"); + return res; + } + + public void initializer(Context context) { + + } +} +``` + +```xml + + + + 4.0.0 + + com.example + faas-example + 1.0.0 + fass-udf-example + + + UTF-8 + 1.8 + 1.8 + yyyyMMddHHmmss + example + target + + + + + com.xxx.yuanrong + faas-function-sdk + 1.0.0 + + + com.google.code.gson + gson + 2.9.0 + + + org.json + json + 20190722 + + + junit + junit + 4.11 + test + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + 2.2 + + + + true + + + false + + + + auto-deploy + package + + single + + + + src/main/assembly/zip_file.xml + + ${package.finalName} + ${package.outputDirectory} + + 0700 + 0600 + 0700 + + + + + + + + +``` + +zipfile + +```xml + + + + + auto-deploy + + + zip + + + + + src/main/resources/ + config + + ** + + 0600 + 0700 + + + + + + + lib + runtime + + + +``` \ No newline at end of file diff --git "a/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Node.js/Node.js\350\277\220\350\241\214\346\227\266\344\273\213\347\273\215.md" "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Node.js/Node.js\350\277\220\350\241\214\346\227\266\344\273\213\347\273\215.md" new file mode 100644 index 0000000000000000000000000000000000000000..2925edc0130c20e0feee5b94de5e8088dc811e8c --- /dev/null +++ "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Node.js/Node.js\350\277\220\350\241\214\346\227\266\344\273\213\347\273\215.md" @@ -0,0 +1,22 @@ +# Node.js 运行时介绍 + +本文介绍 FaaS 场景下编写 Node.js 运行时函数。 + +## 背景信息 + +Node.js 语言是解释型语言,可以直接打包上传至云平台运行。 + +## Node.js 运行时 + +FaaS 目前支持的 Node.js 运行环境如下: + +| 版本 | 操作系统系统 | 架构 | +|---------------|--------------------------|-----------------------| +| Node.js 6.10 | Linux | x86_64、arm | +| Node.js 8.10 | Linux | x86_64、arm | +| Node.js 10.16 | Linux | x86_64、arm | +| Node.js 12.13 | Linux | x86_64、arm | +| Node.js 14.18 | Linux | x86_64、arm | +| Node.js 16.17 | Linux | x86_64、arm | +| Node.js 18.15 | Linux | x86_64、arm | + diff --git a/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Node.js/index.rst b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Node.js/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..5fa02776f5a587f19c5ce11f55cc74d99212fdc3 --- /dev/null +++ b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Node.js/index.rst @@ -0,0 +1,22 @@ +.. Copyright (c) 2022 Huawei Technologies Co., Ltd + This software is licensed under Mulan PSL v2. + You can use this software according to the terms and conditions of the Mulan PSL v2. + You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 + THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + See the Mulan PSL v2 for more details. + +Node.js +============================== + +.. toctree:: + :glob: + :hidden: + + Node.js运行时介绍 + 函数入口 + 上下文 + 日志 + 部署 \ No newline at end of file diff --git "a/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Node.js/\344\270\212\344\270\213\346\226\207.md" "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Node.js/\344\270\212\344\270\213\346\226\207.md" new file mode 100644 index 0000000000000000000000000000000000000000..3ba9e8567ac252293759aba082e6f46c384ea824 --- /dev/null +++ "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Node.js/\344\270\212\344\270\213\346\226\207.md" @@ -0,0 +1,80 @@ +# 上下文 + +在执行函数初始化方法或者执行方法时, Node.js 运行时会传递 context 参数, context 中包含函数和请求的信息以及 Node.js Runtime 提供给函数的功能。 + +## 上下文介绍 + +context 以方法形式提供信息和功能。 + +```javascript + + // 获取本次请求的requestId + getRequestID() + + // 获取本次请求剩余执行时间,单位毫秒 + getRemainingTimeInMilliSeconds() + + // 获取ak + getAccessKey() + + // 获取sk + getSecretKey() + + // 根据key查询环境变量 + getUserData(key) + + // 获取函数名 + getFunctionName() + + // 获取请求超时时间,单位秒 + getRunningTimeInSeconds() + + // 获取函数版本 + getVersion() + + // 获取函数的内存大小 + getMemorySize() + + // 获取函数的cpu大小 + getCPUNumber() + + // 获取函数的projectId + getProjectID() + + // 获取函数的别名 + getAlias() + + // 获取日志方法,用于日志打印 + getLogger() + +``` + +## 通过 context 获取请求上下文示例 + +通过 context 获取函数名示例 + +```javascript +var isInitializer = false; + +exports.init = function (context, callback) { + isInitializer = true; + let data = isInitializer; + callback(null, data); +}; + +exports.my_handler = (event, context, callback) => { + const output = + { + 'statusCode': 200, + 'headers': + { + 'Content-Type': 'application/json' + 'functinName': context.getFunctionName() + }, + 'isBase64Encoded': false, + 'body': JSON.stringify(event), + } + let err = null; + callback(err, output); + +``` \ No newline at end of file diff --git "a/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Node.js/\345\207\275\346\225\260\345\205\245\345\217\243.md" "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Node.js/\345\207\275\346\225\260\345\205\245\345\217\243.md" new file mode 100644 index 0000000000000000000000000000000000000000..47b1d60eb518752da3add0555f23047b9de8e169 --- /dev/null +++ "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Node.js/\345\207\275\346\225\260\345\205\245\345\217\243.md" @@ -0,0 +1,104 @@ +# 函数入口 + +函数入口包含两种方法:执行方法和初始化方法。定义 Node.js 函数入口,格式为: *[文件名].[函数名]* +例如,文件名是*handler.js*, 函数名是*my_handler*,,则方法为*handler.my_handler*。 +如下,`functions.yrnodejsfunc.handler`定义了执行方法,`functions.yrnodejsfunc.init`定义了初始化方法。 +**注:`yrjavafunc`为自定义的函数名** + +```text +service: yrnodejstest +kind: faas +description: this is a empty service +functions: + yrnodejsfunc: + handler: handler.my_handler + initializer: handler.init + description: empty function + runtime: nodejs10.15.2 + concurrentNum: 1 + maxInstance: 30 + memory: 512 + timeout: 900 + cpu: 600 +``` + +## 执行方法 + +执行方法是 Nodejs 运行时处理函数请求时调用的方法,即函数请求执行入口。在函数部署时**必须**指定执行方法。 +执行方法的示例: + +```javascript +var isInitializer = false; + +exports.init = function (context, callback) { + isInitializer = true; + let data = isInitializer; + callback(null, data); +}; + +exports.my_handler = (event, context, callback) => { + // log.info("isInitializer %s", isInitializer) + const output = + { + 'statusCode': 200, + 'headers': + { + 'Content-Type': 'application/json' + }, + 'isBase64Encoded': false, + 'body': JSON.stringify(event), + } + let err = null; + callback(err, output); +} +``` + +Nodejs 的执行方法入参有 event ,context ,callback。 + +- event 是用调用函数的事件数据,格式为 JSON 对象。 +- context 是此次请求执行的上下文信息,其具体内容可以参考下一节:上下文。 +- callback 是回调函数,其完整声明是 callback(err, message)。通过此方法可以将执行的结果返回,message 表示执行的结果,err 不为空,表示此次结果失败,err 为空,表示此次结果成功。 + +## 初始化方法 + +初始化方法是 Node.js 运行时启动后调用该方法,完成函数必要的准备工作,即函数初始化入口,该方法仅会调用一次。在函数部署时**按需**指定初始化方法。 +初始化方法的示例: + +```javascript +var isInitializer = false; + +exports.init = function (context, callback) { + isInitializer = true; + let data = isInitializer; + callback(null, data); +}; + +exports.my_handler = (event, context, callback) => { + console.log("isInitializer %s", isInitializer) + const output = + { + 'statusCode': 200, + 'headers': + { + 'Content-Type': 'application/json' + }, + 'isBase64Encoded': false, + 'body': JSON.stringify(event), + } + let err = null; + callback(err, output); +} +``` + +Node.js 的初始化方法入参有 context,callback 。 + +- context 是函数执行的的上下文信息,其具体内容可以参考下一节:上下文。 +- callback 为回调函数,其完整声明是 callback(err, message) 。通过此方法可以将执行的结果返回,message 表示执行的结果,err 不为空,表示此次结果失败,err 为空,表示此次结果成功。 + +## async 函数 + +除了 Node.js 6.10 外,其余 Node.js 版本支持以 async 的异步形式作为函数入口。 +例如: +`export.my_handler = async (event, context, callback) => {return data;}` + +此时 callback 为可选参数 \ No newline at end of file diff --git "a/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Node.js/\346\227\245\345\277\227.md" "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Node.js/\346\227\245\345\277\227.md" new file mode 100644 index 0000000000000000000000000000000000000000..1799a339ff6d8b354fef4a69fafbf0db9b753e96 --- /dev/null +++ "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Node.js/\346\227\245\345\277\227.md" @@ -0,0 +1,46 @@ +# 日志 + +context 中也提供了日志功能,日志对运维和问题定位有重要作用。 + +## 日志使用 + +示例: + +```javascript +exports.my_handler = (event, context, callback) => { + let logger = context.getLogger() + logger.debug("debug level message") + logger.info("info level message") + logger.warn("warn level message") + logger.error("error level message") + const output = + { + 'statusCode': 200, + 'headers': + { + 'Content-Type': 'application/json' + 'functinName': context.getFunctionName() + }, + 'isBase64Encoded': false, + 'body': JSON.stringify(event), + } + let err = null; + callback(err, output); + +``` + +日志可以通过 context.getLogger() 获得,其提供如下方法: + +```js + debug(msg) + + info(msg) + + warn(msg) + + error(msg) +``` + +## 日志显示 + +该功能暂未实现 \ No newline at end of file diff --git "a/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Node.js/\351\203\250\347\275\262.md" "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Node.js/\351\203\250\347\275\262.md" new file mode 100644 index 0000000000000000000000000000000000000000..02927bbf85ccf85c1561214debb0aaba9d374c11 --- /dev/null +++ "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Node.js/\351\203\250\347\275\262.md" @@ -0,0 +1,57 @@ +# 编译部署 + +## Node.js 工程准备 + +```text +|yrnodejstest + |service.yaml + |yrnodejsfunc + handler.js +``` + +## service.yaml 示例 + +```yaml +service: yrnodejstest +kind: faas +description: this is a empty service +functions: + yrnodejsfunc: + handler: handler.my_handler + initializer: handler.init + description: empty function + runtime: nodejs10.15.2 + concurrentNum: 1 + maxInstance: 30 + memory: 512 + timeout: 900 + cpu: 600 +``` + +## 入口函数 + +```javascript +var isInitializer = false; + +exports.init = function (context, callback) { + isInitializer = true; + let data = isInitializer; + callback(null, data); +}; + +exports.my_handler = (event, context, callback) => { + // log.info("isInitializer %s", isInitializer) + const output = + { + 'statusCode': 200, + 'headers': + { + 'Content-Type': 'application/json' + }, + 'isBase64Encoded': false, + 'body': JSON.stringify(event), + } + let err = null; + callback(err, output); +} +``` \ No newline at end of file diff --git "a/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Python/Python\350\277\220\350\241\214\346\227\266\344\273\213\347\273\215.md" "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Python/Python\350\277\220\350\241\214\346\227\266\344\273\213\347\273\215.md" new file mode 100644 index 0000000000000000000000000000000000000000..3f2f9d028ebdaee0c531686d6cb91f97e8034754 --- /dev/null +++ "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Python/Python\350\277\220\350\241\214\346\227\266\344\273\213\347\273\215.md" @@ -0,0 +1,26 @@ +# Python 运行时介绍 + +本文介绍 FaaS 场景下编写 Python 运行时函数。 + +## 背景信息 + +Python 语言是解释型语言,可以直接打包上传至云平台运行。 + +## Python 运行时 + +FaaS 目前支持的 Python 运行环境如下: + +| 版本 | 操作系统系统 | 架构 | +|-------------|--------------------------|-----------------------| +| Python 3.9 | Linux | x86_64、arm | +| Python 3.10 | Linux | x86_64、arm | +| Python 3.11 | Linux | x86_64、arm | + +需要提前安装好 python3.9 等软件环境。 + +```bash +Python 3.9.0 (default, Xxx x xxxx, 12:00:00) +[GCC 9.3.0] on linux +Type "help", "copyright", "credits" or "license" for more information. +>>> +``` \ No newline at end of file diff --git a/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Python/index.rst b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Python/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..96275cccfbd76c958c2add981e91c4aa2db4c260 --- /dev/null +++ b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Python/index.rst @@ -0,0 +1,24 @@ +:orphan: + +.. Copyright (c) 2022 Huawei Technologies Co., Ltd + This software is licensed under Mulan PSL v2. + You can use this software according to the terms and conditions of the Mulan PSL v2. + You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 + THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + See the Mulan PSL v2 for more details. + +Python +============================== + +.. toctree:: + :glob: + :hidden: + + Python运行时介绍 + 函数入口 + 上下文 + 日志 + 部署 \ No newline at end of file diff --git "a/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Python/\344\270\212\344\270\213\346\226\207.md" "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Python/\344\270\212\344\270\213\346\226\207.md" new file mode 100644 index 0000000000000000000000000000000000000000..5bf4a2e6abbd0269895906768decbf45da315a86 --- /dev/null +++ "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Python/\344\270\212\344\270\213\346\226\207.md" @@ -0,0 +1,27 @@ +# 上下文 {#faaspythoncontextanchor} + +Context 类中提供了许多上下文方法供用户使用,包含一些函数的运行时信息,例如:request id、临时 access key、function meta 等。其声明和功能如表 1 所示。 + +`getToken()`、`getAccessKey()`和`getSecretKey()`方法返回的内容包含敏感信息,请谨慎使用,避免造成用户敏感信息的泄露。 + +表 1 Context 类上下文方法说明 + +| 方法名 | 方法说明 | +|-----------------------------------|------------------------------------------------------------------------| +| getRequestID() | 获取请求 ID。 | +| getRemainingTimeInMilliSeconds() | 获取函数剩余运行时间。 | +| getAccessKey() | 获取用户委托的 AccessKey(有效期 24 小时),使用该方法需要给函数配置委托。**当前已停止维护 Runtime SDK 中 getAccessKey 接口,您将无法使用 getAccessKey 获取临时 AK。** | +| getSecretKey() | 获取用户委托的 SecretKey(有效期 24 小时),使用该方法需要给函数配置委托。**当前已停止维护 Runtime SDK 中 getSecretKey 接口,您将无法使用 getSecretKey 获取临时 SK。** | +| getSecurityAccessKey() | 获取用户委托的 SecurityAccessKey(有效期 24 小时),使用该方法需要给函数配置委托。 | +| getSecuritySecretKey() | 获取用户委托的 SecuritySecretKey(有效期 24 小时),使用该方法需要给函数配置委托。 | +| getSecurityToken() | 获取用户委托的 SecurityToken(有效期 24 小时),使用该方法需要给函数配置委托。 | +| getUserData(string key) | 通过 key 获取用户通过环境变量传入的值。 | +| getFunctionName() | 获取函数名称。 | +| getRunningTimeInSeconds() | 获取函数超时时间。 | +| getVersion() | 获取函数的版本。 | +| getMemorySize() | 分配的内存。 | +| getCPUNumber() | 获取函数占用的 CPU 资源。 | +| getPackage() | 获取函数组。 | +| getAuthToken() | 获取用户委托的 token(有效期 24 小时),使用该方法需要给函数配置委托。 | +| getLogger() | 获取 context 提供的 logger 方法,返回一个日志输出类,通过使用其 info 方法按“时间-请求 ID-输出内容”的格式输出日志。如调用 info 方法输出日志:`log = context.getLogger(); log.info("test")` | +| getAlias() | 获取函数的别名。 | diff --git "a/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Python/\345\207\275\346\225\260\345\205\245\345\217\243.md" "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Python/\345\207\275\346\225\260\345\205\245\345\217\243.md" new file mode 100644 index 0000000000000000000000000000000000000000..a65ecb27fba0efa53022901f7b53dd2c11763d38 --- /dev/null +++ "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Python/\345\207\275\346\225\260\345\205\245\345\217\243.md" @@ -0,0 +1,32 @@ +# 函数入口 + +对于 Python ,openYuanrong运行时支持 Python3.9 版本。 + +## 执行方法 + +函数有明确的接口定义,如下所示。 + +```python +def handler(event, context) +``` + +入口函数名(handler):入口函数名称,需和函数执行入口处用户自定义的入口函数名称一致。 + +执行事件(event): 函数执行界面由用户输入的执行事件参数, 格式为 JSON 对象。 + +上下文环境(context):Runtime 提供的函数执行上下文,其接口定义在上下文章节中说明。 + +## initializer 入口介绍 + +initializer 接口的优点: + +- 分离初始化逻辑和请求处理逻辑 +- 用户函数代码更新时,系统能够保证用户函数的平滑升级,减少应用层初始化冷启动带来的性能损耗。新的函数实例启动后能够自动执行用户的初始化逻辑,在初始化完成后再处理请求 +- 在应用负载上升、需要增加更多函数实例时,系统能够识别函数应用层初始化的开销,由此更准确的计算资源伸缩的时机和所需的资源量、让请求延时更加平稳 + +使用openYuanrong编写 Python initializer,需要定义一个 Python 函数作为 initializer 入口,一个最简单的 initializer(以 Python 3.9 版本为例)示例如下。 + +```python +def initializer(context): + print('hello world!') +``` diff --git "a/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Python/\346\227\245\345\277\227.md" "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Python/\346\227\245\345\277\227.md" new file mode 100644 index 0000000000000000000000000000000000000000..ac2d8444189de81b4b81f18c3ba554d81e99551b --- /dev/null +++ "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Python/\346\227\245\345\277\227.md" @@ -0,0 +1,52 @@ +# 日志 + +## 使用 logging 模块打印日志 + +使用此方法打印的每条日志中都包含时间、request id 和日志级别等信息,request id 可用于出错时定位问题日志。代码示例如下所示。 + +```python +import logging + +def handler(event, context): + logger = logging.getLogger() + logger.info('hello world') + return 'done' +``` + +执行以上代码,输出的日志内容如下所示。 + +```bash +2025-xx-xxTxx:xx:xx.xxxZ xxxxxxxx-xxxx-xxxx-xxxx-xxxxx****xx [INFO] hello world +``` + +## 使用 print 打印日志 + +使用该方法打印日志会将内容原样输出到日志中。代码示例如下所示。 + +```python +def handler(event, context): + print('hello world') + return 'done' +``` + +执行以上代码,输出的日志内容如下所示。 + +```bash +hello world +``` + +## 使用 context.getLogger 打印日志 + +使用 context.getLogger 打印日志,以通过 request id 区分各并发请求的日志。代码示例如下所示。 + +```python +def handler(event, context): + context.getLogger().info("hello world") + return 'done' +``` + +执行以上代码,输出的日志内容如下所示。 + +```bash +2025-xx-xx xx:xx:xx xxxxxxxx-xxxx-xxxx-xxxx-xxxxx****xx [INFO] hello world +``` \ No newline at end of file diff --git "a/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Python/\351\203\250\347\275\262.md" "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Python/\351\203\250\347\275\262.md" new file mode 100644 index 0000000000000000000000000000000000000000..8a66eb31ca8da2d05fdb0ea96265a1037f8e68a8 --- /dev/null +++ "b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/Python/\351\203\250\347\275\262.md" @@ -0,0 +1,204 @@ +# 部署 + +## Step 1. 部署基于 k8s 的openYuanrong集群 + +部署使用openYuanrong的 FaaS 能力,当前需要基于 k8s 的部署方式,请参考 [k8s 部署快速起步](../../../../../../deploy/deploy_on_k8s/single-node-deployment.md) 章节。 + +## Step 2. 创建一个 Python 的 faas 工程 + +在自己的工作目录 (例如 `/home/user/faas`)下创建一个`main.py`,内容如下 + +```python +def handler(event, context): + context.getLogger().info("this is handler") + return f'hello {event.get("name", "world")}!' + +def init(context): + context.getLogger().info("this is initializer") +``` + +Initializer 入口格式为 **[文件名].[initializer 名]**。extendedHandler.initializer 需要与实现 initializer 的接口相对应。如果实现 initializer 接口时指定的 Initializer 入口为 main.initializer,那么函数服务会去加载 main.py 中定义的 initializer 函数。例如,在请求体重实现 initializer 接口时指定的 Initializer 入口为 main.initializer,那么openYuanrong会去加载 main.py 中定义的 initializer 函数。 + +## Step 3. 打包代码文件并通过 Meta-Service 创建函数 + +```bash +cd /home/user/faas +zip -j faascpp.zip main.py +``` + +把这个 zip 文件上传到自定义的 s3 路径,例如`https://x.x.x.x:xxx` 的 bucket `my-bucket-id` 下。然后编写下方 json 连接 Meta-Service。 + +```json +{ + "name": "0@faaspy@hello", + "runtime": "python3.9", + "handler": "main.handler", + "kind": "faas", + "cpu": 600, + "memory": 512, + "timeout": 600, + "extendedHandler": { + "initializer": "main.init" + }, + "storageType": "s3", + "s3CodePath": { + "bucketId": "my-bucket-id", + "objectId": "faascpp.zip", + "bucketUrl": "https://x.x.x.x:xxx" + } +} +``` + +openYuanrong使用 NodePort 的方式暴露了一个 k8s service (meta-service) 提供集群外的访问,你可以通过这个 service 提交任务到集群中。可以通过 kubectl 命令来获取openYuanrong在 k8s 上提供的 service 的地址并通过这些地址连接到openYuanrong。 + +### 请求示例 + +```bash +META_SERVICE_ADDR="http://$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type=="InternalIP")].address}'):$(kubectl get svc meta-service -o jsonpath='{.spec.ports[0].nodePort}')" + +curl -X POST -H "Content-Type: application/json" -d \ +'{ + "name": "0@faaspy@hello", + "runtime": "python3.9", + "handler": "main.handler", + "kind": "faas", + "cpu": 600, + "memory": 512, + "timeout": 600, + "extendedHandler": { + "initializer": "main.init" + }, + "storageType": "s3", + "s3CodePath": { + "bucketId": "my-bucket-id", + "objectId": "faascpp.zip", + "bucketUrl": "https://x.x.x.x:xxx" + } +}' \ +http://${META_SERVICE_ADDR}/serverless/v1/functions +``` + +### 响应示例 + +```json +{ + "code": 0, + "message": "SUCCESS", + "function": { + "id": "sn:cn:yrk:12345678901234561234567890123456:function:0@faaspy@hello:latest", + "createTime": "2025-xx-xx xx:xx:xx.xxx UTC", + "updateTime": "", + "functionUrn": "sn:cn:yrk:12345678901234561234567890123456:function:0@faaspy@hello", + "name": "0@faaspy@hello", + "tenantId": "12345678901234561234567890123456", + "businessId": "yrk", + "productId": "", + "reversedConcurrency": 0, + "description": "", + "tag": null, + "functionVersionUrn": "sn:cn:yrk:12345678901234561234567890123456:function:0@faaspy@hello:latest", + "revisionId": "2025xxxxxxxxxxxxx", + "codeSize": 0, + "codeSha256": "", + "bucketId": "", + "objectId": "", + "handler": "main.handler", + "layers": null, + "cpu": 600, + "memory": 512, + "runtime": "python3.9", + "timeout": 600, + "versionNumber": "latest", + "versionDesc": "latest", + "environment": {}, + "customResources": null, + "statefulFlag": 0, + "lastModified": "", + "Published": "2025-xx-xx xx:xx:xx.xxx UTC", + "minInstance": 0, + "maxInstance": 100, + "concurrentNum": 100, + "funcLayer": [], + "status": "", + "instanceNum": 0, + "device": {}, + "created": "" + } +} +``` + +## Step 4. 查询函数 + +使用 Meta-Service API 查询函数 + +### 请求示例 + +```bash +curl -X GET http://${META_SERVICE_ADDR}/serverless/v1/functions/0@faaspy@hello?versionNumber=latest +``` + +### 响应示例 + +```json +{ + "code": 0, + "message": "SUCCESS", + "function": { + "id": "sn:cn:yrk:12345678901234561234567890123456:function:0@faaspy@hello:latest", + "createTime": "2025-xx-xx xx:xx:xx.xxx UTC", + "updateTime": "", + "functionUrn": "sn:cn:yrk:12345678901234561234567890123456:function:0@faaspy@hello", + "name": "0@faaspy@hello", + "tenantId": "12345678901234561234567890123456", + "businessId": "yrk", + "productId": "", + "reversedConcurrency": 0, + "description": "", + "tag": null, + "functionVersionUrn": "sn:cn:yrk:12345678901234561234567890123456:function:0@faaspy@hello:latest", + "revisionId": "2025xxxxxxxxxxxxx", + "codeSize": 0, + "codeSha256": "", + "bucketId": "", + "objectId": "", + "handler": "main.handler", + "layers": null, + "cpu": 600, + "memory": 512, + "runtime": "python3.9", + "timeout": 600, + "versionNumber": "latest", + "versionDesc": "latest", + "environment": {}, + "customResources": null, + "statefulFlag": 0, + "lastModified": "2025-xx-xx xx:xx:xx.xxx UTC", + "Published": "2025-xx-xx xx:xx:xx.xxx UTC", + "minInstance": 0, + "maxInstance": 100, + "concurrentNum": 100, + "funcLayer": null, + "status": "unavailable", + "instanceNum": 0, + "device": {}, + "created": "2025-02-06 09:12:07.086 UTC" + } +} +``` + +## Step 5. 访问函数 + +在 FaaS 函数发布后,openYuanrong会生成一个访问链接,可以通过这个链接触发 FaaS 函数的访问。这里用`json`格式传入 event 的 name 字段。这个参数将从响应中体现。 + +### 请求示例 + +```bash +curl -X POST -H "Content-Type: application/json" -d '{"name": "faas"}' \ + -i ${META_SERVICE_ADDR}/serverless/v1/functions/sn:cn:yrk:12345678901234561234567890123456:function:0@faaspy@hello:latest/invocations +``` + +### 响应示例 + +```bash +hello faas! +``` diff --git a/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/index.md b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/index.md new file mode 100644 index 0000000000000000000000000000000000000000..3a639af5c5c3849a8eef4a02e46485b9712ba214 --- /dev/null +++ b/docs/multi_language_function_programming_interface/FaaS/function_development/event_function/index.md @@ -0,0 +1,13 @@ +# 开发事件函数 + +```{eval-rst} +.. toctree:: + :glob: + :maxdepth: 1 + :hidden: + + Python/index.rst + Java/index.rst + Node.js/index.rst + C++/index.rst +``` diff --git a/docs/multi_language_function_programming_interface/FaaS/function_development/http_function/Java.md b/docs/multi_language_function_programming_interface/FaaS/function_development/http_function/Java.md new file mode 100644 index 0000000000000000000000000000000000000000..58726371ec23288726ed06b1e6e9a205dcbcd1b1 --- /dev/null +++ b/docs/multi_language_function_programming_interface/FaaS/function_development/http_function/Java.md @@ -0,0 +1,157 @@ +# Java 示例 + +## 简介 + +以 Java 语言为例,创建 http 函数。http 函数实质是要求用户开启一个 http server 进程。 + +## 约束 + +要求监听地址为 127.0.0.1,开放端口 8000。 +要求提供 bootstrap 文件,作为 http 函数的启动文件。 + +## 前提条件 + +准备一个 bootstrap 启动文件,举例如下: + +``` shell +/opt/function/runtime/java1.8/rtsp/java/bin/java $RUNTIME_CODE_ROOT/my-http-server.jar +``` + +- `/opt/function/runtime/java1.8/rtsp/java/bin/java`:表示 Java 编译环境所在路径。 +- `$RUNTIME_CODE_ROOT`:系统变量,表示容器中项目代码存放路径`/opt/function/code`。 +- `my-http-server.jar`:项目入口文件,可自定义名称。 + +目前支持的 Java 语言和对应的路径请参见下表: + +| 版本 | 路径 | +|---------|---------------------------------------------------| +| Java 8 | /opt/function/runtime/java1.8/rtsp/java/bin/java | +| Java 11 | /opt/function/runtime/java1.11/rtsp/java/bin/java | +| Java 17 | /opt/function/runtime/java1.17/rtsp/java/bin/java | +| Java 21 | /opt/function/runtime/java1.21/rtsp/java/bin/java | + +## 项目准备 + +以 spring boot web 应用为例 + +- 创建项目文件夹 + +``` text +http-server-example +``` + +- 项目结构。 + +``` text +my-http-server/ +├── src/ +│ └── main/ +│ ├── java/ +│ │ └── com/ +│ │ └── example/ +│ │ └── MyHttpServerApplication.java +│ └── resources/ +│ └── application.properties +├── pom.xml +└── README.md +``` + +- 添加依赖( Maven ) + 在*pom.xml*文件中,添加 Spring Boot 的依赖。以下是基本的*pom.xml*配置: + +```xml + + + 4.0.0 + + com.example + my-http-server + 1.0-SNAPSHOT + + + org.springframework.boot + spring-boot-starter-parent + 2.7.1 + + + + + + org.springframework.boot + spring-boot-starter-web + + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + +``` + +- 创建主应用程序类。 + +在*src/main/java/com/example/MyHttpServerApplication.java*中,创建主应用程序类: + +```java +package com.example; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@SpringBootApplication +public class MyHttpServerApplication { + + public static void main(String[] args) { + SpringApplication.run(MyHttpServerApplication.class, args); + } + + @RestController + public static class HelloWorldController { + + @GetMapping("/hello") + public String hello() { + return "Hello, World!"; + } + } +} +``` + +- 配置属性 + 在 src/main/resources/application.properties 中,可以配置一些基本的服务器属性,例如端口号: + +```text +server.port=8080 +``` + +- 打包 + +使用 maven 命令进行打包,如果没有安装请从[maven 官网](https://maven.apache.org/download.cgi)下载并安装。 +在项目根目录下,执行 + +```shell +mvn clean package +``` + +并在生成的 jar 包的 target 目录下,创建 bootstrap 文件, + +```shell +/opt/function/runtime/java1.8/rtsp/java/bin/java $RUNTIME_CODE_ROOT/my-http-server.jar +``` + +将 jar 包和 bootstrap 文件打包成 zip 包。 \ No newline at end of file diff --git a/docs/multi_language_function_programming_interface/FaaS/function_development/http_function/Node.js.md b/docs/multi_language_function_programming_interface/FaaS/function_development/http_function/Node.js.md new file mode 100644 index 0000000000000000000000000000000000000000..e663530dd23303e3d94fe93d3c76af5937b2787d --- /dev/null +++ b/docs/multi_language_function_programming_interface/FaaS/function_development/http_function/Node.js.md @@ -0,0 +1,84 @@ +# Node.js 示例 + +## 简介 + +以 Node.js 语言为例,创建 http 函数。http 函数实质是要求用户开启一个 http server 进程。 + +## 约束 + +要求监听地址为 127.0.0.1,开放端口 8000。 +要求提供 bootstrap 文件,作为 http 函数的启动文件。 + +## 前提条件 + +准备一个 bootstrap 启动文件,举例如下: + +```shell +/opt/function/runtime/nodejs6.10/rtsp/nodejs/bin/node $RUNTIME_CODE_ROOT/example.js +``` + +- `/opt/function/runtime/nodejs6.10/rtsp/nodejs/bin/node`:表示 Node.js 编译环境所在路径。 +- `$RUNTIME_CODE_ROOT`:系统变量,表示容器中项目代码存放路径`/opt/function/code`。 +- `example.js`:项目入口文件,可自定义名称。 + +目前支持的 Node.js 语言和对应的路径请参见下表: + +| 版本 | 路径 | +|---------------|--------------------------------------------------------| +| Node.js 6.10 | /opt/function/runtime/nodejs6.10/rtsp/nodejs/bin/node | +| Node.js 8.10 | /opt/function/runtime/nodejs8.10/rtsp/nodejs/bin/node | +| Node.js 10.16 | /opt/function/runtime/nodejs10.16/rtsp/nodejs/bin/node | +| Node.js 12.13 | /opt/function/runtime/nodejs12.13/rtsp/nodejs/bin/node | +| Node.js 14.18 | /opt/function/runtime/nodejs14.18/rtsp/nodejs/bin/node | +| Node.js 16.17 | /opt/function/runtime/nodejs16.17/rtsp/nodejs/bin/node | +| Node.js 18.15 | /opt/function/runtime/nodejs18.15/rtsp/nodejs/bin/node | + +## 项目准备 + +以 koa web 应用为例 + +- 创建项目文件夹 + +```text +koa-example +``` + +- 初始化 Node.js 项目,下载 koa 框架,文件夹中会新增 node_modules 文件夹和 package.json 、 package-lock.json 文件。 + +``` shell +npm init -y +npm i koa +``` + +- 创建 index.js 文件,在 index.js 文件中引入 koa 框架,koa 框架[使用参考](https://koajs.github.net.cn/) + +代码示例: + +```js +const Koa = require("koa"); +const app = new Koa(); +const main = (ctx) =>{ + if (ctx.request.path == ("/koa")) { + ctx.response.type = " application/json"; + ctx.response.body = "Hello World, user!"; + ctx.response.status = 200; + } else { + ctx.response.type = " application/json"; + ctx.response.body = 'Hello World!'; + ctx.response.status = 200; + } +}; +app.use(main); +app.listen(8000, '127.0.0.1'); +console.log('Node.js web server at port 8000 is running..') +``` + +- 创建 bootstrap 文件。 + +```shell +/opt/function/runtime/nodejs14.18/rtsp/nodejs/bin/node $RUNTIME_CODE_ROOT/index.js +``` + +- 打包 + +将项目下所有文件打包,形成 zip 包。 \ No newline at end of file diff --git a/docs/multi_language_function_programming_interface/FaaS/function_development/http_function/index.md b/docs/multi_language_function_programming_interface/FaaS/function_development/http_function/index.md new file mode 100644 index 0000000000000000000000000000000000000000..ccf0b7ba19adb553255eeb313701936378af925e --- /dev/null +++ b/docs/multi_language_function_programming_interface/FaaS/function_development/http_function/index.md @@ -0,0 +1,10 @@ +# 开发 HTTP 函数 + +```{eval-rst} +.. toctree:: + :glob: + :hidden: + + Java + Node.js +``` diff --git a/docs/multi_language_function_programming_interface/FaaS/function_development/index.md b/docs/multi_language_function_programming_interface/FaaS/function_development/index.md new file mode 100644 index 0000000000000000000000000000000000000000..b732290c79b37b2f45b0c09a64065cd1542cfb5c --- /dev/null +++ b/docs/multi_language_function_programming_interface/FaaS/function_development/index.md @@ -0,0 +1,14 @@ +# 开发 FaaS 函数 + +```{eval-rst} +.. toctree:: + :glob: + :maxdepth: 1 + :hidden: + + event_function/index + http_function/index + customimage_function/index + build_package/index + build_layer/index +``` diff --git a/docs/multi_language_function_programming_interface/FaaS/function_management/create_faasFunc.md b/docs/multi_language_function_programming_interface/FaaS/function_management/create_faasFunc.md new file mode 100644 index 0000000000000000000000000000000000000000..0fdad4dd2af933b21cb29f53a28c228c367d2cc1 --- /dev/null +++ b/docs/multi_language_function_programming_interface/FaaS/function_management/create_faasFunc.md @@ -0,0 +1,170 @@ +# 创建函数 + +当前 FaaS 服务支持创建事件、 HTTP、 自定义镜像三种函数类型,本节介绍如何通过 HTTP 接口创建 FaaS 函数。 + +| 类型 | 定义 | 约束 | +|---------|--------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| 事件函数 | 事件是指用于触发函数,通常为 JSON 格式的请求。 | 仅支持部分语言 | +| HTTP 函数 | HTTP 函数专注于优化 Web 服务场景,用户可以直接发送 HTTP 请求到 URL 触发函数执行,从而使用自己的 Web 服务。 | 1. HTTP 函数当前不区分编程语言,函数执行入口必须在 bootstrap 文件中设置,用户直接写启动命令,端口统一开放成 8000 ,绑定 IP 为 127.0.0.1。2. bootstrap 文件是 HTTP 函数的启动文件, HTTP 函数仅支持读取 bootstrap 作为启动文件名称,其它名称将无法正常启动服务, bootstrap 启动文件请参见 [http Node.js 部署](../http_function/Node.js.md) 里的 bootstrap 文件示例。3. HTTP 函数支持多种开发语言。4. 用户函数需要返回一个合法的 http 响应报文。 | +| 自定义镜像函数 | 用户在本地环境打包容器镜像,将包含 HTTP Server 的容器镜像作为函数的交付物。 | 内部不限制语言 | + +## 编写函数 + +【TODO】跳转至如何写代码的章节 + +## 上传代码包 + +【TODO】如何上传代码包 + +## 创建事件函数 + +此处我们调用 meta_service 的接口创建 FaaS 函数 + +【TODO】如何调用 meta_service API + +### 功能介绍 + +该 API 用于在openYuanrong集群创建函数。 + +### URI + +```text +POST /serverless/v1/functions +``` + +### Table.1 请求参数 + +| 参数 | 类型 | 是否必填 | 约束 | 描述 | +|-----------------|------------------|----------|----------------------------------------------------------------------|----------------------------------------------------------------------| +| name | string | 是 | 其中 ServiceName 为 1 - 16 位字母、数字组合;funcName 为小写字母开头,可使用小写字母、数字、中划线组合,长度不超过 127 位。 | 函数名称,FaaS 函数格式按照 @{serviceName}@{funcName} 格式填写,需要唯一。 | +| runtime | string | 是 | 当前支持版本见 Table.3 | 函数 runtime 类型 | +| description | string | 否 | | 函数描述 | +| handler | string | 是 | | call handler | +| kind | string | 是 | | 函数类型,取值 faas | +| cpu | int | 是 | | 函数 CPU 大小,单位:m(毫核) | +| memory | int | 是 | | 函数 MEM 大小,单位:MB | +| timeout | int | 是 | 最大值 8640000 s,参数超过最大值时,自动设置为最大值,不填默认 900 s | 函数调用超时时间 | +| extendedHandler | ExtendedHandler | 否 | | 配置 init handler 信息 | +| storageType | string | 是 | 取值 local, s3, copy | 代码包存储类型 | +| codePath | string | 否 | 代码包本地路径,storageType 配置为 local, copy 时生效 | | + +__特别说明:__
+当 storageType 配置为 copy 时,openYuanrong会将 codePath 里的代码包拷贝到容器其他目录,请确保目录有权限被容器内 sn 用户拷贝,建议设置权限为 755; + +### Table.2 ExtendedHandler + +| 参数 | 类型 | 是否必填 | 约束 | 描述| +|-------------| -------- | -------- | ---- | -----------------------------------| +| initializer | string | 否 | | 初始化接口,FaaS 函数按需配置| +| pre_stop | string | 否 | | 停止接口,函数停止之前执行的退出逻辑,FaaS 函数按需配置| + +### Table.3 runtime 支持的编程语言说明 + +| 运行时语言 | 支持版本| +|---------|----------------| +| Node.js | 6.10(6.10.1)、8.10(8.10.0)、10.16(10.16.1)、12.13(12.13.1)、14.18(14.18.1)、16.17(16.17.1)、18.15(18.15.0) | +| Python | 3.9(3.9.2)| +| Java | 8、11、17、21| +| Go | 1.x| +| C# | .NET Core 2.1、.NET Core 3.1| +| PHP | 7.3| +| Cangjie | 1.0| + +### 其它参数可见 + + API 参考:注册函数 + +### 请求示例 + +```json +{ + "name": "0@faaspy@example1", + "runtime": "python3.9", + "description": "this is a FaaS function", + "handler": "handler.my_handler", + "kind": "faas", + "cpu": 600, + "memory": 512, + "timeout": 600, + "customResources": {}, + "environment": {}, + "extendedHandler": { + "initializer": "handler.init", + "pre_stop": "handler.prestop" + }, + "extendedTimeout": { + "initializer": 600, + "pre_stop": 10 + }, + "minInstance": "0", + "maxInstance": "10", + "concurrentNum": "2", + "storageType": "local", + "codePath": "/home/example/create_faasFunc/" +} +``` + +### 响应示例 + +正常响应 + +```json +{ + "code": 0, + "message": "SUCCESS", + "function": { + "id": "sn:cn:yrk:12345678901234561234567890123456:function:0@faaspy@example1:latest", + "createTime": "2025-01-23 02:38:53.364 UTC", + "updateTime": "", + "functionUrn": "sn:cn:yrk:12345678901234561234567890123456:function:0@faaspy@example1", + "name": "0@faaspy@example1", + "tenantId": "12345678901234561234567890123456", + "businessId": "yrk", + "productId": "", + "reversedConcurrency": 0, + "description": "this is a FaaS function", + "tag": null, + "functionVersionUrn": "sn:cn:yrk:12345678901234561234567890123456:function:0@faaspy@example1:latest", + "revisionId": "20250123023853364", + "codeSize": 0, + "codeSha256": "", + "bucketId": "", + "objectId": "", + "handler": "handler.my_handler", + "layers": null, + "cpu": 600, + "memory": 512, + "runtime": "python3.9", + "timeout": 600, + "versionNumber": "latest", + "versionDesc": "latest", + "environment": {}, + "customResources": null, + "statefulFlag": 0, + "lastModified": "", + "Published": "2025-01-23 02:38:53.364 UTC", + "minInstance": 0, + "maxInstance": 10, + "concurrentNum": 2, + "funcLayer": [], + "status": "", + "instanceNum": 0, + "device": {}, + "created": "" + } +} +``` + +错误响应 + +```json +{ + "code": 4101, + "message": "the function name already exists. rename your function" +} +``` + +## 创建 HTTP 函数 + +## 创建自定义镜像函数 + diff --git a/docs/multi_language_function_programming_interface/FaaS/function_management/delete_faasFunc.md b/docs/multi_language_function_programming_interface/FaaS/function_management/delete_faasFunc.md new file mode 100644 index 0000000000000000000000000000000000000000..13235abfa0f08cbb4ed60c18e7774349ecc7cd17 --- /dev/null +++ b/docs/multi_language_function_programming_interface/FaaS/function_management/delete_faasFunc.md @@ -0,0 +1,48 @@ +# 删除函数 + +本节介绍如何通过 HTTP 接口删除指定的 FaaS 函数。 + +1、此处我们调用 meta_service 的接口创建 FaaS 函数 + +【TODO】如何调用 meta_service API + +## 功能介绍 + +该 API 用于在openYuanrong集群删除函数,如果函数存在多个版本,均会删除。 + +## URI + +```text +DELETE /serverless/v1/functions/{name}?versionNumber={version} +``` + +## 路径参数 + +| 参数 | 类型 | 是否必填 | 约束 | 描述 | +|------------|--------|----------|------|------------| +| name | string | 是 | | 函数名称 | +| version | string | 否 | | 函数版本 | + +## 请求示例 + +```text +curl -X DELETE http://X.X.X.X:X/serverless/v1/functions/0@faaspy@example1 +``` + +## 响应示例 + +正常响应 + +```json +{} +``` + +错误响应 + +```json +{ + "code": 4115, + "message": "function [0@faaspy@example1] is not found. check input parameters" +} +``` + diff --git a/docs/multi_language_function_programming_interface/FaaS/function_management/index.md b/docs/multi_language_function_programming_interface/FaaS/function_management/index.md new file mode 100644 index 0000000000000000000000000000000000000000..30bdce5916b5fe463074c056a800a9fd4a1ef1a6 --- /dev/null +++ b/docs/multi_language_function_programming_interface/FaaS/function_management/index.md @@ -0,0 +1,13 @@ +# 管理 FaaS 函数 + +```{eval-rst} +.. toctree:: + :glob: + :hidden: + + create_faasFunc + update_faasFunc + publish/index + delete_faasFunc + search_faasFunc +``` diff --git a/docs/multi_language_function_programming_interface/FaaS/function_management/publish/index.rst b/docs/multi_language_function_programming_interface/FaaS/function_management/publish/index.rst new file mode 100644 index 0000000000000000000000000000000000000000..fe4fd4c43d18ccbda867ce927dc3d4ff77cc616f --- /dev/null +++ b/docs/multi_language_function_programming_interface/FaaS/function_management/publish/index.rst @@ -0,0 +1,20 @@ +.. Copyright (c) 2022 Huawei Technologies Co., Ltd + This software is licensed under Mulan PSL v2. + You can use this software according to the terms and conditions of the Mulan PSL v2. + You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 + THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + See the Mulan PSL v2 for more details. + +发布函数 +============================== +.. toctree:: + :glob: + :maxdepth: 1 + :hidden: + + 版本管理.md + 别名管理.md + 灰度发布.md \ No newline at end of file diff --git "a/docs/multi_language_function_programming_interface/FaaS/function_management/publish/\345\210\253\345\220\215\347\256\241\347\220\206.md" "b/docs/multi_language_function_programming_interface/FaaS/function_management/publish/\345\210\253\345\220\215\347\256\241\347\220\206.md" new file mode 100644 index 0000000000000000000000000000000000000000..e54ce5e9dc153593f5168adbf6c078310f496d80 --- /dev/null +++ "b/docs/multi_language_function_programming_interface/FaaS/function_management/publish/\345\210\253\345\220\215\347\256\241\347\220\206.md" @@ -0,0 +1,36 @@ +# 别名管理 + +FaaS 支持为函数版本创建别名。结合别名和版本功能,实现软件开发生命周期中的持续集成和发布。本节介绍别名的含义以及如何通 FaaS 控制台管理别名。 + +## 什么是别名 + +FaaS 支持为函数的版本创建别名。别名可以理解为指向特定版本的指针。您可以利用别名来轻松实现发布、回滚以及灰度发布等功能。别名无法脱离函数或版本单独存在。使用别名访问函数时,函数计算会将别名解析为其指向的版本,调用方无需了解别名指向的具体版本。 + +以 HTTP 触发器为例,如果没有别名,每次新版本上线,您需要手动修改 HTTP 触发器关联的版本号,在修改的过程中会影响客户端的使用。如果使用别名进行版本管理,您可以实现版本的平滑升级。如下图所示,将别名 PROD 指向稳定的版本 1 。客户端可以直接通过别名 PROD 调用版本 1 下的函数。 + +### 图 1. 发布版本 1 + +![](../../../../../images/ad21bdea8424fdab0b7322046b5d4154_449x205.png) + +版本 1 发布后,您可以继续在 lastest 版本上开发新功能。由于客户端是通过别名调用对应版本下的函数,当需要发布新版本 2 时,只需要将别名 PROD 更新为指向版本 2 ,此时,客户端通过别名 PROD 调用函数时解析出的版本即为版本 2 ,这样就可以完成版本的更新迭代。 + +您也可以将别名 PROD 重新指向版本 1 ,回滚到之前的版本,此操作不会影响客户端的使用。 + +### 图 2. 发布版本 2 + +![](../../../../../images/dc4833d5b3c3fbadcaaf909bb50164eb_512x202.png) + +您还可以通过别名来控制流量灰度,将 5 %的线上流量通过别名发送到新版本 2 进行灰度验证,然后逐步切换流量到版本 2 ,从而降低部署新版本的风险。 + +### 图 3 . 灰度发布 + +![](../../../../../images/c274990d1068948fa6b5fca91932c8bb_526x194.png) + +## 前提条件 + +创建函数
+发布版本 + +## 创建别名 + +【todo】如何创建别名 \ No newline at end of file diff --git "a/docs/multi_language_function_programming_interface/FaaS/function_management/publish/\347\201\260\345\272\246\345\217\221\345\270\203.md" "b/docs/multi_language_function_programming_interface/FaaS/function_management/publish/\347\201\260\345\272\246\345\217\221\345\270\203.md" new file mode 100644 index 0000000000000000000000000000000000000000..58d0bb4e66189c971424ecc7d82ca339a8504d4b --- /dev/null +++ "b/docs/multi_language_function_programming_interface/FaaS/function_management/publish/\347\201\260\345\272\246\345\217\221\345\270\203.md" @@ -0,0 +1,15 @@ +# 灰度发布 + +您可以为函数发布一个或多个版本,版本就相当于函数的快照,当您发布版本时,函数计算会为您的函数生成快照,并自动分配一个版本号与其关联。您还可以为函数的版本创建别名,指向该版本。结合函数的版本和别名,您可以轻松实现发布、回滚以及灰度发布等功能。 + +## 灰度发布流程 + +![](../../../../../images/55f8b786c4ed20370cb68e2087e765f8_783x523.png) + +## 前提条件 + +创建函数 + +## 灰度发布 + +【todo】如何灰度发布 \ No newline at end of file diff --git "a/docs/multi_language_function_programming_interface/FaaS/function_management/publish/\347\211\210\346\234\254\347\256\241\347\220\206.md" "b/docs/multi_language_function_programming_interface/FaaS/function_management/publish/\347\211\210\346\234\254\347\256\241\347\220\206.md" new file mode 100644 index 0000000000000000000000000000000000000000..676e883ba1bcd137d7203f845cfac1f867d877ed --- /dev/null +++ "b/docs/multi_language_function_programming_interface/FaaS/function_management/publish/\347\211\210\346\234\254\347\256\241\347\220\206.md" @@ -0,0 +1,156 @@ +# 版本管理 + +FaaS 函数持版本管理功能,帮助您更高效地管理函数以及触发器。您可以通过版本管理功能发布多个版本的函数,实现软件开发生命周期中的持续集成和发布,确保函数的稳定性和可靠性。 + +## 什么是版本 + +我们提供函数级别的版本控制功能,支持您为自己的函数发布一个或多个版本。版本相当于函数的快照,包括函数代码及函数配置,不包括触发器。当您发布版本时,函数计算会为函数生成快照,并自动分配一个版本号与其关联,以供后续使用。 + +如果没有版本功能,您在函数上的每次改动都会影响到生产环境,无法控制发布的时机。有了版本功能,您可以在测试稳定后发布函数版本,用稳定的版本来服务线上请求,并且可以继续在 LATEST 版本上开发测试。实现原理,如下图所示。 + +![](../../../../../images/74ae3096ac37ec20b704843aee77ca3f_663x448.png) + +## 注意事项 + +新创建的函数,默认只有一个 latest 版本,在未发布任何版本前, latest 版本是您拥有的唯一函数版本, latest 版本不能被删除。 + +版本发布后,已发布的版本不可更改。且版本号单调递增,不会被重复使用。 + +## 前提条件 + +创建函数 + +## 发布版本 + +本节介绍如何通过 HTTP 接口发布函数版本。 + +1、此处我们调用 meta_service 的接口更新 FaaS 函数 + +【todo】如何调用 meta_service API + +## 功能介绍 + +该 API 用于在openYuanrong集群发布函数。 + +## 接口约束 + +使用默认生成版本号发布时,多次发布间隔须大于 1 s。当前默认版本号生成依据为当前时间,短时间多次发布会生成重复版本号,会返回重复版本号错误。 + +## URI + +```text +POST /serverless/v1/functions/{name}/versions +``` + +### 路径参数 + +| 参数 | 类型 | 是否必填 | 约束 | 描述 | +|------|--------|----------|------|------------| +| name | string | 是 | - | 函数名称 | + +## 请求参数 + +### 请求 Header 参数 + +| 参数 | 类型 | 是否必填 | 约束 | 描述 | +|----------------|-----------|----------|------|--------------------------------------------| +| Content-Type | string | 是 | - | 消息体类型;建议填写 `application/json` | + +### 请求 Body 参数 + +| 参数 | 类型 | 是否必填 | 约束 | 描述 | +|------------------|-----------|----------|----------------------------------------------------------------------|----------------------------------------------------------------------| +| revisionId | string | 是 | - | 函数 revisionId,需要为 latest 版本的 | +| versionNumber | string | 否 | 字母数字开头结尾,可包含字母数字,中划线 (-),下划线 (_) 及点 (.) ,长度不超过 42;为空时默认生成格式形如 “v20060102-150405” | 版本号 | +| versionDesc | string | 否 | - | 版本描述 | +| kind | string | 是 | - | 函数类型,取值 faas | + +## 响应参数 + +| 参数 | 类型 | 是否必填 | 约束 | 描述 | +|---------------|--------------------------|----------|------|--------------------------------| +| code | int | 是 | - | 返回码,0 表示更新成功,非 0 则更新失败 | +| message | string | 是 | - | 返回错误信息 | +| function | PublishFunctionResult | 是 | - | 更新结果 | + +### PublishFunctionResult + +| 参数 | 类型 | 是否必填 | 约束 | 描述 | +|--------------------------|--------------------------|----------|------|------------------------------------| +| id | int | 是 | - | 函数 ID | +| functionVersionUrn | string | 是 | - | 函数版本 URN,用于调用函数 | +| revisionId | PublishFunctionResult | 是 | - | 函数 revisionId,用于发布函数 | + +## 请求示例 + +__提示:__
+revisionId 可以从查询函数接口中获取 + +```json +{ + "revisionId": "2025012312054261", + "versionDesc": "try-mod-version2", + "versionNumber": "B.2233", + "kind": "faas" +} +``` + +## 请求响应 + +正常响应 + +```json +{ + "code": 0, + "message": "SUCCESS", + "function": { + "id": "sn:cn:yrk:12345678901234561234567890123456:function:0@faaspy@example1:B.2233", + "createTime": "2025-01-23 02:38:53.364 UTC", + "updateTime": "2025-01-23 12:05:42.610 UTC", + "functionUrn": "sn:cn:yrk:12345678901234561234567890123456:function:0@faaspy@example1", + "name": "0@faaspy@example1", + "tenantId": "12345678901234561234567890123456", + "businessId": "yrk", + "productId": "", + "reversedConcurrency": 0, + "description": "this is a function", + "tag": null, + "functionVersionUrn": "sn:cn:yrk:12345678901234561234567890123456:function:0@faaspy@example1:B.2233", + "revisionId": "2025012312054261", + "codeSize": 0, + "codeSha256": "", + "bucketId": "", + "objectId": "", + "handler": "handler.my_handler", + "layers": null, + "cpu": 600, + "memory": 512, + "runtime": "python3.9", + "timeout": 600, + "versionNumber": "B.2233", + "versionDesc": "try-mod-version2", + "environment": {}, + "customResources": {}, + "statefulFlag": 0, + "lastModified": "2025-01-23 12:05:42.610 UTC", + "Published": "2025-01-23 12:11:31.134 UTC", + "minInstance": 0, + "maxInstance": 10, + "concurrentNum": 2, + "funcLayer": null, + "status": "unavailable", + "instanceNum": 0, + "device": {}, + "created": "2025-01-23 02:38:53.364 UTC" + } +} +``` + +错误响应 + +```json +{ + "code": 4134, + "message": "revisionId is non latest version" +} +``` \ No newline at end of file diff --git a/docs/multi_language_function_programming_interface/FaaS/function_management/search_faasFunc.md b/docs/multi_language_function_programming_interface/FaaS/function_management/search_faasFunc.md new file mode 100644 index 0000000000000000000000000000000000000000..cbcf679166f497549ff733bd4280d4de0c640366 --- /dev/null +++ b/docs/multi_language_function_programming_interface/FaaS/function_management/search_faasFunc.md @@ -0,0 +1,95 @@ +# 查找函数 + +本节介绍如何通过 HTTP 接口查找 FaaS 函数。 + +1、此处我们调用 meta_service 的接口创建 FaaS 函数 + +【todo】如何调用 meta_service API + +## 功能介绍 + +该 API 用于在openYuanrong集群删除函数,如果函数存在多个版本,均会删除。 + +## URI + +```text +GET /serverless/v1/functions/{name}?versionNumber={version} +``` + +## 路径参数 + +|参数 | 类型 | 是否必填 | 约束 | 描述| +|---- | ------ | -------- | ---- | ----| +|name | string | 是 | | 函数名称| + +## 查询参数 + +| 参数 | 类型 | 是否必填 | 约束 | 描述| +|----------| ------ | -------- | ---- | ----| +| version | string | 是 | | 函数版本| + +## 请求示例 + +```text +curl -X GET http://X.X.X.X:X/serverless/v1/functions/0@faaspy@example1?versionNumber=latest +``` + +## 响应示例 + +正常响应 + +```json +{ + "code": 0, + "message": "SUCCESS", + "function": { + "id": "sn:cn:yrk:12345678901234561234567890123456:function:0@faaspy@example1:latest", + "createTime": "2025-01-23 02:38:53.364 UTC", + "updateTime": "", + "functionUrn": "sn:cn:yrk:12345678901234561234567890123456:function:0@faaspy@example1", + "name": "0@faaspy@example1", + "tenantId": "12345678901234561234567890123456", + "businessId": "yrk", + "productId": "", + "reversedConcurrency": 0, + "description": "this is a faas function", + "tag": null, + "functionVersionUrn": "sn:cn:yrk:12345678901234561234567890123456:function:0@faaspy@example1:latest", + "revisionId": "20250123023853364", + "codeSize": 0, + "codeSha256": "", + "bucketId": "", + "objectId": "", + "handler": "handler.my_handler", + "layers": null, + "cpu": 600, + "memory": 512, + "runtime": "python3.9", + "timeout": 600, + "versionNumber": "latest", + "versionDesc": "latest", + "environment": {}, + "customResources": {}, + "statefulFlag": 0, + "lastModified": "2025-01-23 02:38:53.364 UTC", + "Published": "2025-01-23 02:38:53.364 UTC", + "minInstance": 0, + "maxInstance": 10, + "concurrentNum": 2, + "funcLayer": null, + "status": "unavailable", + "instanceNum": 0, + "device": {}, + "created": "2025-01-23 02:38:53.364 UTC" + } +} +``` + +错误响应 + +```json +{ + "code":4115, + "message":"function [X] is not found. check input parameters" +} +``` diff --git a/docs/multi_language_function_programming_interface/FaaS/function_management/update_faasFunc.md b/docs/multi_language_function_programming_interface/FaaS/function_management/update_faasFunc.md new file mode 100644 index 0000000000000000000000000000000000000000..ef524adafb4492c84472303a017566715a4b75d8 --- /dev/null +++ b/docs/multi_language_function_programming_interface/FaaS/function_management/update_faasFunc.md @@ -0,0 +1,158 @@ +# 更新函数 + +本文介绍如何通过 HTTP 接口更新 FaaS 函数。 + +1、此处我们调用 meta_service 的接口更新 FaaS 函数 + +【todo】如何调用 meta_service API + +## 功能介绍 + +该 API 用于在openYuanrong集群更新函数。 + +## URI + +```text +PUT /serverless/v1/functions/{name} +``` + +## 路径参数 + +| 参数 | 类型 | 是否必填 | 约束 | 描述| +|-------| ------ | -------- | ---- | ----| +| name | string | 是 | | 函数名称| + +## Table.1 请求参数 + +| 参数 | 类型 | 是否必填 | 约束 | 描述 | +|---------------|-----------|----------|----------------------------------------------------------------------|----------------------------------------------------------------------| +| name | string | 是 | 其中 `ServiceName` 为 1 - 16 位字母、数字组合;`funcName` 为小写字母开头,可使用小写字母、数字、中划线组合,长度不超过 127 位。 | 函数名称,faas 函数格式按照 `@{serviceName}@{funcName}` 格式填写,需要唯一。 | +| runtime | string | 是 | 当前支持版本见 Table.3 | 函数 runtime 类型 | +| description | string | 否 | - | 函数描述 | +| handler | string | 是 | - | call handler | +| kind | string | 是 | - | 函数类型,取值 faas | +| cpu | int | 是 | - | 函数 CPU 大小,单位:m(毫核) | +| memory | int | 是 | - | 函数 MEM 大小,单位:MB | +| timeout | int | 是 | 最大值 8640000 s,参数超过最大值时,自动设置为最大值,不填默认 900 s | 函数调用超时时间 | +| extendedHandler | ExtendedHandler | 否 | - | 配置 init handler 信息 | +| storageType | string | 是 | 取值 local, s3, copy | 代码包存储类型 | +| codePath | string | 否 | 代码包本地路径,`storageType` 配置为 local, copy 时生效 | - | + +__特别说明:__
+当 storageType 配置为 copy 时,openYuanrong会将 codePath 里的代码包拷贝到容器其他目录,请确保目录有权限被容器内 sn 用户拷贝,建议设置权限为 755; + +## Table.2 ExtendedHandler + +| 参数 | 类型 | 是否必填 | 约束 | 描述 | +|------------|-----------|----------|------|----------------------------------------------------------------------| +| initializer | string | 否 | - | 初始化接口,faas 函数按需配置 | +| pre_stop | string | 否 | - | 停止接口,函数停止之前执行的退出逻辑,faas 函数按需配置 | + +## Table.3 runtime 支持的编程语言说明 + +| 运行时语言 | 支持版本 | +|------------|--------------------------------------------------------------------------| +| Node.js | 6.10(6.10.1)、8.10(8.10.0)、10.16(10.16.1)、12.13(12.13.1)、14.18(14.18.1)、16.17(16.17.1)、18.15(18.15.0) | +| Python | 2.7(2.7.15)、3.6(3.6.8)、3.9(3.9.2)、3.11(3.11.4) | +| Java | 8、11、17、21 | +| Go | 1.x | +| C# | .NET Core 2.1、.NET Core 3.1 | +| PHP | 7.3 | +| 定制运行时 | - | +| Cangjie | 1.0 | + +## 其它参数可见 + + API 参考:注册函数 + +## 请求示例 + +__提示:__
+revisionId 可以从查询函数接口中获取 + +```json +{ + "revisionId": "20250123120507733", + "name": "0@faaspy@example1", + "runtime": "python3.9", + "description": "this is a function", + "handler": "handler.my_handler", + "kind": "faas", + "cpu": 600, + "memory": 512, + "timeout": 600, + "customResources": {}, + "environment": {}, + "extendedHandler": { + "initializer": "handler.init", + "pre_stop": "test.prestop" + }, + "extendedTimeout": { + "initializer": 600, + "pre_stop": 10 + }, + "minInstance": "0", + "maxInstance": "10", + "concurrentNum": "2", + "storageType": "local", + "codePath": "/home/example/create_faasFunc/" +} +``` + +## 请求示例 + +正常响应 + +```json +{ + "code": 0, + "message": "", + "result": { + "createTime": "2025-01-23 02:38:53.364 UTC", + "updateTime": "2025-01-23 12:05:42.610 UTC", + "functionUrn": "sn:cn:yrk:12345678901234561234567890123456:function:0@faaspy@example1", + "name": "0@faaspy@example1", + "tenantId": "12345678901234561234567890123456", + "businessId": "yrk", + "productId": "", + "reversedConcurrency": 0, + "description": "this is a function", + "tag": null, + "functionVersionUrn": "sn:cn:yrk:12345678901234561234567890123456:function:0@faaspy@example1:latest", + "revisionId": "2025012312054261", + "codeSize": 0, + "codeSha256": "", + "bucketId": "", + "objectId": "", + "handler": "handler.my_handler", + "layers": null, + "cpu": 600, + "memory": 512, + "runtime": "python3.9", + "timeout": 600, + "versionNumber": "latest", + "versionDesc": "latest", + "environment": {}, + "customResources": null, + "statefulFlag": 0, + "lastModified": "", + "Published": "2025-01-23 02:38:53.364 UTC", + "minInstance": 0, + "maxInstance": 10, + "concurrentNum": 2, + "funcLayer": [], + "status": "", + "instanceNum": 0, + "device": {} + } +} +``` + +错误响应 + +```json + { + "code": 4134, + "message": "revisionID is not the same" + } +``` diff --git a/docs/multi_language_function_programming_interface/FaaS/index.md b/docs/multi_language_function_programming_interface/FaaS/index.md new file mode 100644 index 0000000000000000000000000000000000000000..1ff644b5896ed2c0d07467cc3bbdc222edad56ab --- /dev/null +++ b/docs/multi_language_function_programming_interface/FaaS/index.md @@ -0,0 +1,12 @@ +# FaaS 函数 + +```{eval-rst} +.. toctree:: + :glob: + :hidden: + + function_management/index.md + function_development/index.md + function_configuration/index.md + function_call/index.md +```