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 函数及常见失败排障,命令与回显均实测

Apache OpenWhiskApache OpenWhisk2026/10/12

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 CLI1.2.0GitHub release 提供 OpenWhisk_CLI-1.2.0-linux-amd64.tgz 二进制
OpenJDK11官方 BUILDING_FROM_SOURCE 要求 Java 11
Gradle6.9.12.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):

  1. 删除根 build.gradle 中的 classpath "cz.alenkacz:gradle-scalafmt:1.5.0" 行与 apply plugin: 'scalafmt'(jcenter 已关停,无法解析);
  2. 删除 core/standalone/build.gradle 中的 com.gorylenko.gradle-git-properties 插件行与 gitProperties 块(grgit 无法解析);
  3. 设置 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):

  1. 未声明 InvokerProvider,默认实现需要额外的外部协调组件配置 → 在 whisk.spi 段增加:
whisk.spi {
  InvokerProvider = "org.apache.openwhisk.core.invoker.InvokerReactive"
  InvokerServerProvider = "org.apache.openwhisk.core.invoker.DefaultInvokerServer"
}
  1. 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 默认端口

端口用途
3233Controller / API 入口(wsk 连接端口)
3232Playground 浏览器 UI(/playground)

5.3 默认用户凭据

standalone 启动时自动引导两个用户(定义于 standalone.conf whisk.users 段):

用户凭据
guest23bc46b1-71f6-4ed5-8c54-816aa4f8c502:123zO3xZCLrMN6v2BKK1dXYFpXlPkccOFqm12CdAsMgRU4VrNZ9lyGVCGuMDGIwP
whisk.system789c46b1-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

九、参考链接