- 后端
- 云原生
【免费下载链接】openwhisk
Apache OpenWhisk is an open source serverless cloud platform
本文围绕 Apache OpenWhisk 仓库中的 Standalone Server 模块(core/standalone/README.md)展开,系统讲解如何用一条java -jar命令在本地启动一个无需 Kafka、CouchDB 等外部依赖的完整 OpenWhisk 平台,用于开发调试与功能验证。读完本文,你将掌握 Standalone 的全部启动选项、自定义配置(命名空间、运行时、CouchDB)、API Gateway / 嵌入式 Kafka / User Events 观测栈的开启方式,以及基于 KubernetesContainerFactory 和 Docker 的两种进阶运行方案。
Playground UI:Standalone Server 默认在 3232 端口提供的 Web 试玩界面,可快速创建并运行简单 Action。
一、设计定位:为什么需要 Standalone Server
OpenWhisk 的完整生产部署需要 Controller、Invoker、Kafka、CouchDB、Zookeeper、Etcd、Nginx 等多个组件协作(可参考 ansible 部署目录)。而 Standalone Server 的目标截然不同:在本地以单个 Java 进程模拟一个最小可用的 OpenWhisk 平台,专供本地开发与测试。
它可以直接以普通 Java 应用方式从命令行运行:
java -jar openwhisk-standalone.jar启动后默认在3233端口提供 OpenWhisk API(Controller),并在3232端口启动 Playground UI。整个平台只依赖Docker(用于运行 Action 容器)与Java,默认使用内存存储,不依赖任何外部中间件。
1.1 核心设计要点
原文档明确列出了如下关键特性:
- 内存存储:默认所有数据保存在进程内存中,服务停止后全部变更丢失;
- 默认用户引导:启动时会自动创建
guest与whisk.system两个内置命名空间及其默认鉴权密钥; - 跨平台:支持 macOS、Linux 与 Windows(实验性);
- 可插拔存储:可通过配置接入 CouchDB 等其他存储实现。
1.2 源码层面的"零依赖"实现
从 standalone.conf 可以看到,Standalone 通过 SPI 机制将各核心组件替换为轻量实现:
whisk { spi { ArtifactStoreProvider = "org.apache.openwhisk.core.database.memory.MemoryArtifactStoreProvider" MessagingProvider = "org.apache.openwhisk.connector.lean.LeanMessagingProvider" LoadBalancerProvider = "org.apache.openwhisk.core.loadBalancer.LeanBalancer" ContainerFactoryProvider = "org.apache.openwhisk.core.containerpool.docker.StandaloneDockerContainerFactoryProvider" ... } }即:存储使用内存版 ArtifactStore、消息传递使用 Lean 实现、负载均衡使用 LeanBalancer,Action 容器则由 Docker 容器工厂管理。此外该配置文件还默认将 Controller 只绑定到localhost(whisk.controller.interface = localhost),以提升本地安全性;内置的whisk-system与guest用户密钥也定义于此文件(standalone.conf)。
二、构建与三种启动方式
2.1 用 Gradle 构建可执行 Jar
./gradlew :core:standalone:build构建产物(可执行 Jar)位于bin/目录,之后即可通过java -jar bin/openwhisk-standalone.jar运行。
2.2 直接以 bootRun 方式运行
不想手动打包时,可直接运行:
./gradlew :core:standalone:bootRun如需向启动命令传递参数(例如指定运行时清单):
./gradlew :core:standalone:bootRun --args='-m runtimes.json'2.3 构建 Docker 镜像
./gradlew :core:standalone:distDocker此外,Standalone 模块自带 Dockerfile,镜像内会内置 Docker CLI 与 wsk CLI,容器入口脚本为init。
工作目录说明:默认数据目录为~/.openwhisk/standalone(源码中的defaultWorkDir,见 StandaloneOpenWhisk.scala)。可用-d/--data-dir指定其他位置,用--clean在启动前清空已有状态。
三、启动选项全解:-h帮助输出逐项解读
运行java -jar openwhisk-standalone.jar -h可看到完整帮助信息。以下将所有选项整理为表格(默认值结合帮助文本与源码 StandaloneOpenWhisk.scala 归纳):
| 选项 | 参数 | 默认值 | 说明 |
|---|---|---|---|
-m, --manifest | 文件路径 | classpath 中的/runtimes.json | 定义受支持运行时的 Manifest JSON |
-c, --config-file | 文件路径 | standalone.conf | 覆盖默认配置的application.conf |
--api-gw | - | 关闭 | 启用 API Gateway 支持 |
--couchdb | - | 关闭 | 启用 CouchDB 支持 |
--user-events | - | 关闭 | 启用 User Events,并附带 Prometheus 与 Grafana |
--kafka | - | 关闭 | 启用嵌入式 Kafka |
--kafka-ui | - | 关闭 | 启用 Kafka UI(基于 Kafdrop 3) |
--all | - | 关闭 | 一次性启用上述全部可选服务(CouchDB、Kafka、API GW、User Events、Kafka UI) |
--api-gw-port | 端口号 | 3234 | API Gateway 端口 |
--clean | - | 关闭 | 启动前清理已有状态(如数据库) |
-d, --data-dir | 目录 | ~/.openwhisk/standalone | 存储目录 |
--dev-kcf | - | 关闭 | 启用 KubernetesContainerFactory 供本地开发 |
--dev-mode | - | 关闭 | 开发者模式:跳过预检、避免显式拉取镜像,加速启动 |
--dev-user-events-port | 端口号 | 无 | 指定 user-event 服务端口,用于连接已有服务实例做本地开发 |
--disable-color-logging | - | 关闭 | 禁用彩色日志 |
--enable-bootstrap | - | 见下方说明 | 启用默认用户与 Action 的引导(API Gateway / Playground 所需) |
--kafka-docker-port | 端口号 | 9091(或随机空闲端口) | 供 Docker 服务使用的 Kafka 端口 |
--kafka-port | 端口号 | 9092(或随机空闲端口) | Kafka 端口 |
--no-ui | - | 关闭 | 禁用 Playground UI |
--ui-port | 端口号 | 3232(或随机空闲端口) | Playground UI 端口 |
-p, --port | 端口号 | 3233 | 服务器(Controller)端口 |
-v, --verbose | - | - | 冗余日志输出 |
--zk-port | 端口号 | 2181(或随机空闲端口) | Zookeeper 端口 |
-h, --help | - | - | 显示帮助信息 |
--version | - | - | 显示程序版本 |
3.1 端口占用策略
从源码看,除-p/--port外,各服务端口遵循"首选端口优先、被占用则随机分配"的策略:未指定端口时先尝试默认端口,若被占用则挑选随机空闲端口(参见StandaloneDockerSupport.checkOrAllocatePort与getPort,StandaloneOpenWhisk.scala)。例如 Kafka 首选端口定义在 KafkaLauncher.scala:
val preferredKafkaPort = 9092 val preferredKafkaDockerPort = preferredKafkaPort - 1 // 9091 val preferredZkPort = 2181若显式指定了端口且该端口已被占用,则对应服务不会启动——这主要用于测试场景(测试逻辑自行确定端口并确保服务只在该端口启动)。
3.2--all的展开逻辑
--all并非一个独立开关,而是在参数解析阶段被展开为--api-gw --couchdb --user-events --kafka --kafka-ui五个选项(见Conf.expandAllMode,StandaloneOpenWhisk.scala)。
四、自定义配置:application.conf 覆盖机制
4.1 基本覆盖方式
通过-c传入自定义application.conf,该文件必须include classpath("standalone.conf"),以继承默认配置:
include classpath("standalone.conf") whisk { //Custom config }然后启动:
java -jar openwhisk-standalone.jar -c custom.conf源码中initConfigLocation会校验配置文件存在性并设置config.file系统属性(StandaloneOpenWhisk.scala)。
4.2 添加自定义命名空间(用户)
在whisk.users下按用户名 = "uuid:密钥"的格式注册自定义用户:
include classpath("standalone.conf") whisk { users { whisk-test = "cafebabe-cafe-babe-cafe-babecafebabe:007zO3xZCLrMN6v2BKK1dXYFpXlPkccOFqm12CdAsMgRU4VrNZ9lyGVCGuMDGIwP" } }启动后日志中会打印创建成功的用户(#tid_userBootstrap事务 ID 标识引导流程):
[2019-06-21T19:52:02.923Z] [INFO] [#tid_userBootstrap] [StandaloneOpenWhisk] Created user [guest] [2019-06-21T19:52:03.008Z] [INFO] [#tid_userBootstrap] [StandaloneOpenWhisk] Created user [whisk.system] [2019-06-21T19:52:03.094Z] [INFO] [#tid_userBootstrap] [StandaloneOpenWhisk] Created user [whisk.test]实现上,bootstrapUsers会读取whisk.users配置,并为每个用户调用WhiskAdmin的user create --auth <key> <subject>命令完成写入(StandaloneOpenWhisk.scala)。
4.3 使用自定义运行时清单
通过-m传入定义运行时的 Manifest JSON,例如注册 Ruby 2.5 运行时:
{ "runtimes": { "ruby": [ { "kind": "ruby:2.5", "default": true, "deprecated": false, "attached": { "attachmentName": "codefile", "attachmentType": "text/plain" }, "image": { "prefix": "openwhisk", "name": "action-ruby-v2.5", "tag": "latest" } } ] } }启动时指定:
java -jar openwhisk-standalone.jar -m custom-runtime.json随后访问http://localhost:3233即可在响应中看到新的运行时配置。
默认运行时说明:未指定 manifest 时,Standalone 从 classpath 加载/runtimes.json;若该资源不存在(例如从 IDE 直接运行),则回退到内置的 Node.js 20 运行时定义(源码defaultRuntime,StandaloneOpenWhisk.scala)。
五、选择后端存储:内置 CouchDB 与外部 ArtifactStore
5.1 内置 CouchDB
使用--couchdb会在 Docker 中启动一个 CouchDB 容器(默认镜像apache/couchdb:2.3,端口 5984),数据保存在用户主目录下的.openwhisk/standalone目录中:
java -jar openwhisk-standalone.jar --couchdbCouchDB 相关的设计文档(views)在 standalone.conf 中配置,这些 JSON 设计文档文件位于 ansible/files 目录(如whisks_design_document_for_entities_db_v2.1.0.json)。
5.2 连接外部 CouchDB 或其他存储
如需连接已有的 CouchDB(或其他受支持的 ArtifactStore),通过-c传入存储配置:
include classpath("standalone.conf") whisk { couchdb { protocol = "http" host = "172.17.0.1" port = "5984" username = "whisk_admin" password = "some_passw0rd" provider = "CouchDB" databases { WhiskAuth = "whisk_local_subjects" WhiskEntity = "whisk_local_whisks" WhiskActivation = "whisk_local_activations" } } }然后:
java -jar openwhisk-standalone.jar -c external-couchdb.conf5.3 Bootstrap 规则:外部存储默认不写入默认用户
重要行为:使用外部 ArtifactStore 时,Standalone默认不会引导(bootstrap)默认用户与 Action(例如 API Gateway 与 Playground UI 所需的那些),以免污染你的外部存储。只有显式添加--enable-bootstrap才会执行引导。对应的判定逻辑在canInstallUserAndActions中(StandaloneOpenWhisk.scala):使用内存存储或内置 CouchDB 时总是引导;使用外部存储时仅当开启--enable-bootstrap才引导。
六、API Gateway 模式
通过--api-gw启用 API Gateway:启动时会在 Docker 中拉起一个独立的 OpenWhisk API Gateway 容器(默认镜像openwhisk/apigateway:0.11.0),对外端口为3234(可用--api-gw-port修改):
java -jar openwhisk-standalone.jar --api-gw启用后即可使用 OpenWhisk 的 API Gateway 能力(创建、管理 HTTP API 端点),详见仓库中的 API Gateway 文档。
内部细节:路由管理(route management)所需的 API 端口固定分配在 9000(apiGwApiPort = checkOrAllocatePort(9000)),引导阶段会通过InstallRouteMgmt安装路由管理包(StandaloneOpenWhisk.scala)。
七、嵌入式 Kafka 与 Kafka UI
7.1 启动嵌入式 Kafka
Standalone 支持直接启动一个嵌入式 Kafka,该模式主要面向 OpenWhisk 自身实现的开发调试:
java -jar openwhisk-standalone.jar --kafka7.2 附加 Kafka UI(Kafdrop 3)
同时使用--kafka-ui可拉起基于 Kafdrop 3 的 Web UI,用于查看创建的 Topic 及消息结构:
java -jar openwhisk-standalone.jar --kafka --kafka-uiUI 默认地址为http://localhost:9000;若 9000 被占用则自动选择随机端口,可从日志中查找whisk-kafka-drop-ui关键字确认实际端口:
[ 9092 ] localhost:9092 (kafka) [ 9092 ] 192.168.65.2:9091 (kafka-docker) [ 2181 ] Zookeeper (zookeeper) [ 9000 ] http://localhost:9000 (whisk-kafka-drop-ui)源码佐证:启用 Kafka 时,Standalone 会把消息提供方切换为KafkaMessagingProvider、负载均衡切换为KafkaAwareLeanBalancer(StandaloneOpenWhisk.scala),即从 Lean 单机模式切换到真实的 Kafka 消息通道。
八、User Events 观测栈:Kafka + Prometheus + Grafana
Standalone 支持发出 User Events 度量,并借助 Grafana Dashboard 可视化展示。度量由 User Event Service 消费并转换为 Prometheus 指标。一条命令即可拉起完整观测栈:
java -jar openwhisk-standalone.jar --user-events该模式会依次启动嵌入式 Kafka、User Event Service、Prometheus 与预配置好 Dashboard 的 Grafana:
Launched service details [ 9092 ] localhost:9092 (kafka) [ 9091 ] 192.168.65.2:9091 (kafka-docker) [ 2181 ] Zookeeper (zookeeper) [ 3235 ] http://localhost:3235 (whisk-user-events) [ 9090 ] http://localhost:9090 (whisk-prometheus) [ 3000 ] http://localhost:3000 (whisk-grafana)其中各组件镜像定义在 standalone.conf(openwhisk/user-events:nightly、prom/prometheus:v2.5.0、grafana/grafana:6.1.6),预置的 Grafana Dashboard 可在 core/monitoring/user-events/compose/grafana/dashboards 找到。关于 User 级指标的背景可参考 metrics 文档 与 user-events 模块说明。
九、KubernetesContainerFactory 本地开发(--dev-kcf)
Standalone 可通过--dev-kcf切换为 KubernetesContainerFactory(KCF),用于简化 KCF 本身的本地开发。以下步骤基于 Kind(用 Docker 容器作为节点的本地 Kubernetes 工具),不过只要正确设置KUBECONFIG,该模式对任意 Kubernetes 集群均适用。
9.1 安装并配置 Kind
kind create cluster --wait 5m # 导出 kind 配置供 kubectl 使用 export KUBECONFIG="$(kind get kubeconfig-path)" # 配置默认命名空间 kubectl config set-context --current --namespace=default # 查看配置路径 kind get kubeconfig-path /Users/example/.kube/kind-config-kind9.2 启动 Standalone(KCF 模式)
# 通过 kubeconfig 系统属性指向 kind 配置 java -Dkubeconfig="$(kind get kubeconfig-path)" -jar bin/openwhisk-standalone.jar --dev-kcfKCF 模式下使用的独立配置为 standalone-kcf.conf:它将ContainerFactoryProvider切换为KubernetesContainerFactoryProvider,启用端口转发(port-forwarding-enabled = true),并将本地开发场景下镜像可能未预拉取的情形考虑在内(run超时放宽到 10 分钟)。
9.3 验证一次 KCF 调用
启动成功后,将.wskprops配置指向 Standalone 服务器,创建hello.js:
function main(params) { greeting = 'hello, world' var hello = {payload: greeting} var result = {...hello, ...process.env} console.log(greeting); return result }wsk action create hello hello.js wsk action invoke hello -br输出类似如下,HOSTNAME为wsk0-2-prewarm-nodejs10,且包含KUBERNETES_*环境变量,说明 Action 已运行在 Kubernetes Pod 中,KCF 调用链路正常:
{ "HOME": "/root", "HOSTNAME": "wsk0-2-prewarm-nodejs10", "KUBERNETES_PORT": "tcp://10.96.0.1:443", "KUBERNETES_SERVICE_HOST": "10.96.0.1", "KUBERNETES_SERVICE_PORT": "443", "KUBERNETES_SERVICE_PORT_HTTPS": "443", "NODE_VERSION": "10.15.3", "PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "PWD": "/nodejsAction", "YARN_VERSION": "1.13.0", "__OW_ACTION_NAME": "/guest/hello", "__OW_ACTION_VERSION": "0.0.1", "__OW_ACTIVATION_ID": "71e48d2d62e142eca48d2d62e192ec2d", "__OW_API_HOST": "http://host.docker.internal:3233", "__OW_DEADLINE": "1570223213407", "__OW_NAMESPACE": "guest", "__OW_TRANSACTION_ID": "iSOoNklk6V7l7eh8KJnvugidKEmaNJmv", "payload": "hello, world" }十、用 Docker 启动 Standalone
10.1 一键脚本与本地方案
项目发布了一个便捷的一键启动脚本(bash <(curl -sL ...)形式,已测试 Linux、macOS 与 Windows Git Bash)。若你不想执行来自网络的任意代码,仓库中提供了等价的本地脚本 start.sh 与 stop.sh,其核心命令等价于:
docker run --rm -d \ -h openwhisk --name openwhisk \ -p 3233:3233 -p 3232:3232 \ -v /var/run/docker.sock:/var/run/docker.sock \ openwhisk/standalone:nightly默认发布的 Standalone 控制器镜像为openwhisk/standalone:nightly。脚本启动后会尝试自动打开 Playground;若浏览器未自动弹出,可访问http://localhost:3232。
10.2 配置 wsk CLI
如果 Playground 不够用,可安装 wsk CLI(参见 CLI 文档)并通过以下命令获取wsk的配置命令:
docker logs openwhisk | grep 'wsk property'配置好 CLI 后即可尝试仓库中的 示例 Action 与 samples 文档 中的各种用例。
10.3 关闭服务
要彻底关闭 OpenWhisk 及其创建的附加容器,可使用 stop.sh 或直接执行:
docker exec openwhisk stop10.4 向 Docker 镜像传递额外参数
启动脚本的完整格式为:
bash <(curl -sL <openwhisk.sh>) [<docker-parameters>...] [<image-name>] [<standalone-jar-options>...]例如:
bash <(curl -sL <openwhisk.sh>) -e SOME_DOCKER_ENV=a openwhisk/standalone:nightly --no-ui额外参数可用于配置运行 OpenWhisk 的 JVM,以及向 Action 容器传播环境变量(例如为 Action 开启调试):
JVM_EXTRA_ARGS:向运行 OpenWhisk 的 JVM 追加参数。例如-e JVM_EXTRA_ARGS=-Dconfig.loads可开启配置追踪,也可借此设置任意 OpenWhisk 参数;CONTAINER_EXTRA_ENV:为每个运行 Action 的容器追加环境变量。例如-e CONTAINER_EXTRA_ENV=__OW_DEBUG_PORT=8081可为支持调试器启动的镜像(如 TypeScript 运行时)开启调试端口。
后者在配置层面对应 standalone.conf 中的container-factory.container-args.extra-args.env += ${?CONTAINER_EXTRA_ENV}。
十一、常见注意事项
- 数据易失性:默认内存存储意味着服务重启即数据清空,适合测试;需要持久化时请改用
--couchdb或外部存储。 - 外部存储不自动引导:连接外部 CouchDB 等 ArtifactStore 时,默认不会创建
guest/whisk.system等用户与 Action,需显式加--enable-bootstrap。 - 端口自动规避:除显式指定外,Kafka(9092)、Kafka-docker(9091)、Zookeeper(2181)、Kafka UI(9000)等端口被占用时会自动选择随机空闲端口,请以启动日志中
Launched service details段落打印的端口为准(该日志由 ServiceInfoLogger.scala 输出)。 - 运行时最小依赖:仅需 Java 与 Docker(
--dev-kcf模式还需可用且已配置KUBECONFIG的 Kubernetes 集群)。
- 后端
- 云原生
【免费下载链接】openwhisk
Apache OpenWhisk is an open source serverless cloud platform
相关推荐
OpenCart 全新安装完整实战指南:Linux / Windows / 本地环境安装、CLI 自动化与上线安全配置
OpenCart 全新安装完整实战指南:Linux / Windows / 本地环境安装、CLI 自动化与上线安全配置 OpenCart 是一款基于 PHP 的
云原生后端微服务Apache OpenWhisk开发环境搭建:本地调试与测试的终极指南
Apache OpenWhisk开发环境搭建:本地调试与测试的终极指南 Apache OpenWhisk是一个开源的无服务器计算平台,它允许开发者构建、运行和管
云原生后端微服务虎符台:全面战争MOD管理终极解决方案,告别繁琐配置
虎符台:全面战争MOD管理终极解决方案,告别繁琐配置 还在为《全面战争》系列游戏的MOD管理而头疼吗?每次切换游戏存档都要重新配置几十个MOD,不同MOD之间的
桌面应用游戏开发
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考