Ubuntu 22.04 安装 Apache OpenWhisk 2.0.0 指南
在 Ubuntu 22.04 上从零安装 Apache OpenWhisk 2.0.0(无服务器函数平台),涵盖 OpenJDK 11 与 Gradle 6.9.1 前置、官方源码下载 sha512 校验、core:standalone 构建、openwhisk-standalone.jar 启动、wsk CLI 1.2.0 安装配置、创建并调用首个 nodejs:20 函数及常见失败排障,命令与回显均实测
Ubuntu 22.04 安装 Apache OpenWhisk 2.0.0 指南
目标:在真实 Ubuntu 22.04 服务器上从零安装 Apache OpenWhisk 2.0.0(无服务器函数平台),使用官方源码构建 standalone 单机模式并配合 wsk CLI 完成函数的创建、调用与监控。以下命令与回显均在 Ubuntu 22.04.5 真实环境逐步实测。
一、环境信息
- 操作系统:Ubuntu 22.04.5 LTS(x86_64)
- Java:OpenJDK 11.0.32.1(
openjdk-11-jdk) - 构建工具:Gradle 6.9.1
- Apache OpenWhisk 服务端:2.0.0(官方源码包构建的 standalone 单机模式)
- Apache OpenWhisk CLI(wsk):1.2.0
- 函数运行时:nodejs:20(平台内置默认运行时,映像
openwhisk/action-nodejs-v20:1.22.0) - 安装目录:
/opt/OpenWhisk-2.0.0(源码)、/opt/openwhisk-cli(CLI) - 默认端口:3233(API / Controller)、3232(Playground UI)
- 运行用户:root(示例账号:root,密码:q1w2e3r4)
💡 说明:Apache OpenWhisk 2024 年起进入 Apache Attic(退休)状态,官方不再发布可执行二进制包与公开运行时映像,但源码包仍可从 downloads.apache.org 获取,standalone 单机模式依然是官方 Quick Start 推荐路径,本指南即采用该路径。
二、版本选型说明
| 组件 | 版本 | 说明 |
|---|---|---|
| OpenWhisk 服务端 | 2.0.0 | 官方最后发布版;仅源码包 OpenWhisk-2.0.0-sources.tar.gz |
| OpenWhisk CLI | 1.2.0 | GitHub release 提供 OpenWhisk_CLI-1.2.0-linux-amd64.tgz 二进制 |
| OpenJDK | 11 | 官方 BUILDING_FROM_SOURCE 要求 Java 11 |
| Gradle | 6.9.1 | 2.0.0 源码构建要求;源码包不含 gradle-wrapper.jar |
| 默认运行时 | nodejs:20 | 内嵌 runtimes.json 声明的默认 kind,映像 tag 1.22.0 |
⚠️ 官方已进入 Apache Attic(退休)状态,此前发布的公开运行时映像仓库已一并下架(直接拉取返回 denied),不要再依赖映像方式安装服务端;运行时映像可通过源码自建(见 4.5 与第六章注意事项)。
三、前置条件
- 一台 Ubuntu 22.04 服务器,root 权限,内存建议 ≥ 4GB。
- 可访问 downloads.apache.org(下载源码)与 GitHub Releases(下载 CLI)。
- 具备函数运行时的执行环境(standalone 启动 preflight 会自动检查,不满足会给出明确错误)。
- 需安装
openjdk-11-jdk、wget、tar、unzip、net-tools(含netstat)、procps。
四、部署步骤
4.1 更新软件源并安装基础工具
apt-get update -qq
DEBIAN_FRONTEND=noninteractive apt-get install -y \
openjdk-11-jdk wget tar unzip net-tools procps
验证版本回显:
# java -version
openjdk version "11.0.32.1" 2026-08-18
OpenJDK Runtime Environment (build 11.0.32.1+1-post-1ubuntu1-22.04-Ubuntu)
OpenJDK 64-Bit Server VM (build 11.0.32.1+1-post-1ubuntu1-22.04-Ubuntu, mixed mode, sharing)
4.2 安装 Gradle 6.9.1
源码包未含 gradle-wrapper.jar,官方源 services.gradle.org 下载慢(易超时),改用腾讯镜像:
cd /opt
wget -q https://mirrors.cloud.tencent.com/gradle/gradle-6.9.1-bin.zip
unzip -q gradle-6.9.1-bin.zip
mv gradle-6.9.1 /opt/gradle
ln -sf /opt/gradle/bin/gradle /usr/local/bin/gradle
验证回显:
# gradle --version
Gradle 6.9.1
JVM: 11.0.32.1 (Ubuntu 11.0.32.1+1-post-1ubuntu1-22.04-Ubuntu)
4.3 下载并校验源码(2.0.0)
cd /opt
wget -q https://downloads.apache.org/openwhisk/OpenWhisk-2.0.0-sources.tar.gz
sha512sum OpenWhisk-2.0.0-sources.tar.gz
回显:
7841f303ed07d8d7ac503a79cd96a9402c4398d81f7c468c29a3f060e09cad417982c4b627ae3796095ea6e430273eff5bcbbf9e20721b47bfbcb04eaa27c5da OpenWhisk-2.0.0-sources.tar.gz
(与 https://downloads.apache.org/openwhisk/OpenWhisk-2.0.0-sources.tar.gz.sha512 一致)
解压并确认目录结构:
tar -xzf OpenWhisk-2.0.0-sources.tar.gz
ls OpenWhisk-2.0.0/core
回显:
controller cosmosdb invoker monitoring routemgmt scheduler standalone
4.4 构建 standalone 单机模式
官方 Quick Start 即 ./gradlew core:standalone:bootRun。构建前需对 2.0.0 源码做三处适配(2026 年环境实测必需,见「常见问题」Q1/Q2/Q3):
- 删除根
build.gradle中的classpath "cz.alenkacz:gradle-scalafmt:1.5.0"行与apply plugin: 'scalafmt'(jcenter 已关停,无法解析); - 删除
core/standalone/build.gradle中的com.gorylenko.gradle-git-properties插件行与gitProperties块(grgit 无法解析); - 设置
JAVA_TOOL_OPTIONS="-Djava.io.tmpdir=/opt/tmp"(避免 Scala 编译 JNA mmap 失败)。
执行构建:
mkdir -p /opt/tmp
cd /opt/OpenWhisk-2.0.0
JAVA_TOOL_OPTIONS="-Djava.io.tmpdir=/opt/tmp" gradle :core:standalone:build --no-daemon
构建日志(节选尾部):
> Task :core:standalone:compileScala UP-TO-DATE
> Task :core:standalone:copyGWActions
> Task :core:standalone:copyGrafanaConfig
> Task :core:standalone:copySwagger UP-TO-DATE
> Task :core:standalone:bootJar UP-TO-DATE
> Task :core:standalone:copyBootJarToBin UP-TO-DATE
> Task :core:standalone:test
> Task :core:standalone:build
BUILD SUCCESSFUL in 22s
32 actionable tasks: 6 executed, 26 up-to-date
产物:
ls -la /opt/OpenWhisk-2.0.0/bin/openwhisk-standalone.jar
回显:
-rw-r--r-- 1 root root 164875141 Oct 11 18:32 /opt/OpenWhisk-2.0.0/bin/openwhisk-standalone.jar
4.5 配置 standalone.conf(2.0.0 发布版两处修复)
2.0.0 发布版 core/standalone/src/main/resources/standalone.conf 存在两处实测问题,按下面修改后重新构建(增量构建约 22s):
- 未声明 InvokerProvider,默认实现需要额外的外部协调组件配置 → 在
whisk.spi段增加:
whisk.spi {
InvokerProvider = "org.apache.openwhisk.core.invoker.InvokerReactive"
InvokerServerProvider = "org.apache.openwhisk.core.invoker.DefaultInvokerServer"
}
pull-standard-images = true会导致函数冷启动时尝试从公网拉取标准运行时映像(网络受限时失败)→ 改为false:
# standalone 的运行时工厂配置段中
pull-standard-images = false
💡 修改后必须重新执行 4.4 的构建命令,jar 才会包含新配置。
4.6 安装 wsk CLI 1.2.0
mkdir -p /opt/openwhisk-cli && cd /opt/openwhisk-cli
wget -q https://github.com/apache/openwhisk-cli/releases/download/1.2.0/OpenWhisk_CLI-1.2.0-linux-amd64.tgz
tar -xzf OpenWhisk_CLI-1.2.0-linux-amd64.tgz
mv wsk /usr/local/bin/wsk
验证回显:
# wsk --version
Error: unknown flag: --version
(1.2.0 无 --version 参数,版本用如下命令查看)
# wsk property get --cliversion
whisk CLI version 2021-04-01T23:49:54.523+0000
4.7 启动 standalone 服务
cd /opt/OpenWhisk-2.0.0
JAVA_TOOL_OPTIONS="-Djava.io.tmpdir=/opt/tmp" nohup java -jar bin/openwhisk-standalone.jar \
> /tmp/openwhisk.log 2>&1 &
启动日志(节选,preflight 各检查项均 [ OK ]):
Running pre flight checks ...
Local Host Name: 172.18.0.1
Local Internal Name: 172.18.0.1
[ OK ] 'wsk' cli found. (2021-04-01T23:49:54.523+0000)
[ OK ] 'wsk' configured for namespace [guest].
[ OK ] 'wsk' configured to connect to http://172.18.0.1:3233.
[ OK ] Server port [3233] is free
[2026-10-11T18:39:12.257Z] [INFO] Starting OpenWhisk standalone on port 3233
[2026-10-11T18:39:13.827Z] [INFO] Using [/root/.openwhisk/standalone/server-3233] as data directory
[2026-10-11T18:39:16.019Z] [INFO] [StandaloneOpenWhisk] Created user [guest]
[2026-10-11T18:39:16.073Z] [INFO] [StandaloneOpenWhisk] Created user [whisk.system]
================================================================================
Launched service details
[ 3233 ] http://172.18.0.1:3233 (Controller)
[ 3232 ] http://172.18.0.1:3232/playground (Playground)
Local working directory - /root/.openwhisk/standalone/server-3233
================================================================================
[2026-10-11T18:39:16.759Z] [INFO] [Controller] starting controller instance standalone
验证监听端口:
netstat -tlnp | grep -E '3233|3232'
正常应看到 0.0.0.0:3233(API)与 0.0.0.0:3232(Playground)处于 LISTEN。
💡 日志中的
Local Host Name为本机实测地址(172.18.0.1),实际服务器请以本机网卡地址为准;wsk 连接的 apihost 与之一致即可。
4.8 配置 wsk 并创建首个函数
wsk property set --apihost http://172.18.0.1:3233
wsk property set --auth 23bc46b1-71f6-4ed5-8c54-816aa4f8c502:123zO3xZCLrMN6v2BKK1dXYFpXlPkccOFqm12CdAsMgRU4VrNZ9lyGVCGuMDGIwP
查看全部属性:
# wsk property get --all
whisk API host http://172.18.0.1:3233
whisk auth 23bc46b1-71f6-4ed5-8c54-816aa4f8c502:123zO3xZCLrMN6v2BKK1dXYFpXlPkccOFqm12CdAsMgRU4VrNZ9lyGVCGuMDGIwP
whisk namespace guest
client cert
Client key
whisk API version v1
whisk CLI version 2021-04-01T23:49:54.523+0000
whisk API build ???
whisk API build number standalone
编写函数并创建 action:
cat > /tmp/hello.js <<'EOF'
function main(params) {
const name = params.name || "stranger";
return { greeting: "Hello, " + name + "!" };
}
EOF
wsk action create hello /tmp/hello.js --kind nodejs:20
回显:
ok: created action hello
调用函数(阻塞模式,等待结果):
wsk action invoke hello --blocking -p name World
回显(节选):
ok: invoked /_/hello with id 77e664a9d0d7493da664a9d0d7393d7c
{
"activationId": "77e664a9d0d7493da664a9d0d7393d7c",
"duration": 455,
"name": "hello",
"namespace": "guest",
"response": {
"result": {
"greeting": "Hello, World!"
},
"size": 28,
"status": "success",
"success": true
},
"start": 1791744034865,
"subject": "guest",
"version": "0.0.1"
}
查看调用记录(activation):
# wsk activation list
Datetime Activation ID Kind Start Duration Status Entity
2026-10-11 18:40:35 961257515f2d4e9c9257515f2dde9c11 nodejs:20 warm 6ms success guest/hello:0.0.1
2026-10-11 18:40:35 0f1c7631433944b39c7631433954b3f7 nodejs:20 warm 5ms success guest/hello:0.0.1
2026-10-11 18:40:34 77e664a9d0d7493da664a9d0d7393d7c nodejs:20 cold 455ms success guest/hello:0.0.1
至此安装完成,平台可正常创建、调用、监控函数。
五、配置说明
5.1 JVM 堆内存(256-512MB)
standalone 为 Java 服务,建议限定堆内存防止吃满机器内存,在 4.7 启动命令中追加:
JAVA_TOOL_OPTIONS="-Djava.io.tmpdir=/opt/tmp -Xms256m -Xmx512m" \
java -jar /opt/OpenWhisk-2.0.0/bin/openwhisk-standalone.jar
验证生效值(ps -ef | grep java 输出中可见):
JAVA_TOOL_OPTIONS: -Djava.io.tmpdir=/opt/tmp -Xms256m -Xmx512m
5.2 默认端口
| 端口 | 用途 |
|---|---|
| 3233 | Controller / API 入口(wsk 连接端口) |
| 3232 | Playground 浏览器 UI(/playground) |
5.3 默认用户凭据
standalone 启动时自动引导两个用户(定义于 standalone.conf whisk.users 段):
| 用户 | 凭据 |
|---|---|
| guest | 23bc46b1-71f6-4ed5-8c54-816aa4f8c502:123zO3xZCLrMN6v2BKK1dXYFpXlPkccOFqm12CdAsMgRU4VrNZ9lyGVCGuMDGIwP |
| whisk.system | 789c46b1-71f6-4ed5-8c54-816aa4f8c502:abczO3xZCLrMN6v2BKK1dXYFpXlPkccOFqm12CdAsMgRU4VrNZ9lyGVCGuMDGIwP |
5.4 数据存储
standalone 使用内存存储(MemoryArtifactStore),数据目录为 ~/.openwhisk/standalone/server-3233;服务重启后已创建的 action / trigger / rule 等实体全部丢失,需重新创建(这是 standalone 单机模式的正常特性)。
六、注意事项
- 函数运行时映像需提前就绪:默认 kind 为 nodejs:20(映像
openwhisk/action-nodejs-v20:1.22.0)。网络受限时需在 4.4 构建前把pull-standard-images改为false并预先准备好运行时映像,否则冷启动首次调用会因拉取失败而报 HTTP 500 冷启动失败。 wsk api系列命令在 standalone 单机模式不可用(不含 API 网关组件),报错The requested resource does not exist. (code MFcH7wiX1KCmkNXkdaL0T3faY75CVX22)属预期现象。- 排查以日志
/tmp/openwhisk.log与端口为准;服务异常退出时该日志保留最后一次完整堆栈。 - 每个实例的命令逐个单独执行,避免循环批量操作。
七、常见问题
7.1 构建报 Could not find cz.alenkacz:gradle-scalafmt 或 Could not find org.ajoberstar.grgit:grgit-core
原因:jcenter 已关停、grgit 仓库不可达,2.0.0 源码声明的旧插件无法解析。
解决:删除根 build.gradle 的 scalafmt 插件行,删除 core/standalone/build.gradle 的 gradle-git-properties 插件及 gitProperties 块(见 4.4)。
7.2 编译报 /tmp/jna-...: failed to map segment from shared object
原因:Scala 编译期 JNA 加载 mmap 失败(/tmp 为 tmpfs 时常见)。
解决:设置 JAVA_TOOL_OPTIONS="-Djava.io.tmpdir=/opt/tmp" 并提前 mkdir -p /opt/tmp 后重跑构建。
7.3 启动报 Key not found: 'etcd'
原因:2.0.0 发布版 standalone.conf 未声明 InvokerProvider,默认实现需要 whisk.etcd 配置。
解决:按 4.5 在 whisk.spi 段增加 InvokerProvider 与 InvokerServerProvider,重新构建后重启。
7.4 首次调用函数报 HTTP 500 / 冷启动失败
原因:pull-standard-images = true 时冷启动尝试从公网拉取标准运行时映像,网络不可达即失败。
解决:改为 false 并预先准备运行时映像(见 4.5、六、注意事项)。
7.5 wsk 连接报 dial tcp [::1]:3233 ... refused
原因:standalone 监听的是本机 IPv4 地址,而 wsk 默认解析 localhost 为 ::1。
解决:用实际 IP 配置 apihost:wsk property set --apihost http://<实际IP>:3233。
7.6 重启服务后 action 全部丢失
原因:standalone 为内存存储,重启即清空实体。
解决:属正常特性;重启后重新执行 wsk action create 等命令即可。
八、卸载方式
pkill -f openwhisk-standalone.jar # 先停止服务
rm -rf /opt/OpenWhisk-2.0.0 /opt/gradle /opt/openwhisk-cli
rm -f /usr/local/bin/gradle /usr/local/bin/wsk
apt-get remove -y openjdk-11-jdk # 可选:卸载 JDK
九、参考链接
- Apache OpenWhisk 下载页:https://downloads.apache.org/openwhisk/
- OpenWhisk 源码与 BUILDING_FROM_SOURCE:https://github.com/apache/openwhisk
- OpenWhisk CLI 发布:https://github.com/apache/openwhisk-cli/releases
- OpenWhisk 官方 Quick Start:https://github.com/apache/openwhisk/blob/master/README.md