Nova Kwok's Awesome Blog

入门 Rust——为 Rust 程序构建 MultiArch Docker 镜像的一点踩坑记录

事情是这样的,前段时间我和在 BennyThink 讨论要不要亲自下场做一个开源,好用,尊重用户隐私的评论系统来替换掉会随意在也面上插广告的 Disqus,BennyThink 表示想用点新的技术栈(根据上下文,这里的”旧技术栈“ 应该是是指 Python/Node + MySQL/MongoDB 等)。

于是我第一反应就想到了一个 Event sourcing 的设计,一个定序器 + 在 S3 上的可随意平行扩展的方案,而且可以借这个机会熟悉一下 Rust。

虽然后面讨论了一下对于评论系统而言的多维度查询在上面那个方案上几乎等于烂透了。

Anyway,既然牛都吹出去了,那感觉可以从一些小的项目来试试看这个被许多人吹捧的 Rust 用起来到底怎么样了。

由于我不太会写代码,我熟悉任何一个程序开发语言的过程都是面向实现一个小玩具开始(而非阅读「xx 语言设计」等教程),就像:

所以为了熟悉 Rust,我挑了一个之前一直想解决的痛点开始—— https://github.com/knatnetwork/github-runner-kms,这个过于简单的程序镜像居然有 100+ MB,而且启动和停止速度很慢,属实不应该。

KMS 是个什么?在之前的博文:

中我们可以知道,如果你想运行一个 Self-hosted GitHub Runner,那么你需要有个地方传入你的 GitHub PAT 来获得 Runner 的 Registration Token,然后在 Runner 上通过那个 Token 来注册,这里的风险就是如果你把 PAT 想办法放到了 Runner 里面,那这里 PAT 被盗用之后产生的风险就会非常大,所以 KMS 服务就是将你的 PAT 放到一个额外的服务中,Runner 在启动和停止的时候和 KMS 交互来动态获得 Runner 专属的 Registration Token 和 Remove Token,减少安全隐患。

如果你想了解更加详细的内容,请参考上面的两篇文章。

所以 https://github.com/knatnetwork/github-runner-kms 的工作很简单,只要接受来自 Runner 的请求,给 GitHub 发一个请求,拿到 Token 并返回就可以了,为了让大家更直观的了解工作流程,一个例子如下:

app.get('/:github_org_name/registration-token', (req, res) => {
  const registration_token_url = `https://api.github.com/orgs/${req.params.github_org_name}/actions/runners/registration-token`
  const github_pat = org_pat_map[`${req.params.github_org_name}`]
  const headers = {
    Authorization: `token ${github_pat}`,
  }
  axios
    .post(registration_token_url, {}, { headers: headers })
    .then((github_res) => {
      res.send(github_res['data']['token'])
    })
})

既然是个简单的 Web Application,那用 Rust 改写一下应该没啥难度吧,而且还有 ChatGPT 和 GitHub Copilot 加持,What could possibly go wrong?

很快我便找到了一个看上去用的人很多的 Web 框架——Rocket,然后在和 ChatGPT 大量对话,在 VSCode 中大量 Quick Fix 解决了各种奇妙的借用和引用的问题,学会了奇怪的 match, Ok 等语法之后,我终于有一个能用的 https://github.com/knatnetwork/github-runner-kms-rs Rust 版本的 KMS 了!

在和 BennyThink 炫耀了一翻(我的 ChatGPT 使用技巧)之后我便开始准备起了我的老本行工作——CI/CD 和 MultiArch 镜像打包(不然 ARM64 用户怎么用),然后噩梦就开始了。

最开始我的 Dockerfile 是这样的:

# docker build . -t knatnetwork/github-runner-kms-rs
FROM rust:1.72 as builder

WORKDIR /app

COPY Cargo.toml Cargo.lock rust-toolchain.toml ./

RUN mkdir src

COPY src ./src

RUN cargo build --release

FROM debian:bookworm-slim

RUN apt update && apt install -y libssl-dev && rm -rf /var/lib/apt/lists/*

WORKDIR /

COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /app/target/release/github-runner-kms-rs /github-runner-kms-rs

ENV ROCKET_ADDRESS=0.0.0.0
ENV ROCKET_PORT=3000

CMD ["/github-runner-kms-rs"]

这样虽然可以直接用 Buildx 构建多架构镜像,但是这样构建出出来的镜像比较大,和我之前用 Node 写的版本体积差异不大(那这 Rust 重写的优势似乎就一点都没了):

knatnetwork/github-runner-kms-rs latest 99a06a8d8f58 About a minute ago 111MB
knatnetwork/github-runner-kms    latest f7f01af885d1 16 months ago      116MB

于是我想了一下,应该把运行时环境改为 scratch 之类的,这样可以减少运行时的负担。

然后 Dockerfile 就成了这个样子:

# docker build . -t knatnetwork/github-runner-kms-rs
FROM rust:1.72 as builder

WORKDIR /app

COPY Cargo.toml Cargo.lock rust-toolchain.toml ./

RUN mkdir src

COPY src ./src

RUN cargo build --release

FROM scratch

WORKDIR /

COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /app/target/release/github-runner-kms-rs /github-runner-kms-rs

ENV ROCKET_ADDRESS=0.0.0.0
ENV ROCKET_PORT=3000

CMD ["/github-runner-kms-rs"]

很快啊,就构建好了,镜像体积也很小:

REPOSITORY                                  TAG                  IMAGE ID       CREATED          SIZE
knatnetwork/github-runner-kms-rs            latest               bb498b0571f6   4 seconds ago    17MB

完美啊,这不得吹爆,我们来运行一下:

exec /github-runner-kms-rs: no such file or directory

我知道了,肯定是 scratch 有什么问题,我换成 alpine 试试,由于 Rust 的镜像默认是 debian 的,所以也需要一并修改一下:

# docker build . -t knatnetwork/github-runner-kms-rs
FROM rust:1.72-alpine as builder

WORKDIR /app

COPY Cargo.toml Cargo.lock rust-toolchain.toml ./

RUN mkdir src

COPY src ./src

RUN cargo build --release

FROM alpine

WORKDIR /

COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /app/target/release/github-runner-kms-rs /github-runner-kms-rs

ENV ROCKET_ADDRESS=0.0.0.0
ENV ROCKET_PORT=3000

CMD ["/github-runner-kms-rs"]

然后构建的时候就看到报错了:

#0 42.91   cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR
#0 42.91   run pkg_config fail: Could not run `PKG_CONFIG_ALLOW_SYSTEM_CFLAGS="1" "pkg-config" "--libs" "--cflags" "openssl"`
#0 42.91   The pkg-config command could not be found.
#0 42.91
#0 42.91   Most likely, you need to install a pkg-config package for your OS.
#0 42.91   Try `apt install pkg-config`, or `yum install pkg-config`,
#0 42.91   or `pkg install pkg-config`, or `apk add pkgconfig` depending on your distribution.
#0 42.91
#0 42.91   If you've already installed it, ensure the pkg-config command is one of the
#0 42.91   directories in the PATH environment variable.
#0 42.91
#0 42.91   If you did not expect this build to link to a pre-installed system library,
#0 42.91   then check documentation of the openssl-sys crate for an option to
#0 42.91   build the library from source, or disable features or dependencies
#0 42.91   that require pkg-config.
#0 42.91
#0 42.91   --- stderr
#0 42.91   thread 'main' panicked at /usr/local/cargo/registry/src/index.crates.io-6f17d22bba15001f/openssl-sys-0.9.92/build/find_normal.rs:190:5:

行,那我加上 pkg-config 啥的再构建一次,这个时候我的 Dockerfile 长这个样子:

# docker build . -t knatnetwork/github-runner-kms-rs
FROM rust:1.72-alpine as builder

WORKDIR /app

RUN apk add --no-cache musl-dev pkgconfig openssl-dev perl make

COPY Cargo.toml Cargo.lock rust-toolchain.toml ./

RUN mkdir src

COPY src ./src

RUN cargo build --release

FROM alpine

WORKDIR /

COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /app/target/release/github-runner-kms-rs /github-runner-kms-rs

ENV ROCKET_ADDRESS=0.0.0.0
ENV ROCKET_PORT=3000

CMD ["/github-runner-kms-rs"]

我们再构建一次!果不其然,又报错了:

#0 241.7 error: linking with `cc` failed: exit status: 1
#0 241.7   |
#0 241.7   = note: LC_ALL="C" PATH="/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/bin:/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/bin/self-contained:/usr/local/cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" VSLANG="1033" "cc" "-m64" "/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/self-contained/rcrt1.o" "/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/self-contained/crti.o" "/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/self-contained/crtbeginS.o" "/tmp/rustcDeOMKK/symbols.o" "/app/target/release/deps/github_runner_kms_rs-17a998135e03eec4.github_runner_kms_rs.a68f20bb02f7f6b1-cgu.00.rcgu.o" "/app/target/release/deps/github_runner_kms_rs-17a998135e03eec4.github_runner_kms_rs.a68f20bb02f7f6b1-cgu.01.rcgu.o" "/app/target/release/deps/github_runner_kms_rs-17a998135e03eec4.github_runner_kms_rs.a68f20bb02f7f6b1-cgu.02.rcgu.o" "/app/target/release/deps/github_runner_kms_rs-17a998135e03eec4.github_runner_kms_rs.a68f20bb02f7f6b1-cgu.03.rcgu.o" "/app/target/release/deps/github_runner_kms_rs-17a998135e03eec4.github_runner_kms_rs.a68f20bb02f7f6b1-cgu.04.rcgu.o" "/app/target/release/deps/github_runner_kms_rs-17a998135e03eec4.github_runner_kms_rs.a68f20bb02f7f6b1-cgu.05.rcgu.o" "/app/target/release/deps/github_runner_kms_rs-17a998135e03eec4.github_runner_kms_rs.a68f20bb02f7f6b1-cgu.06.rcgu.o" "/app/target/release/deps/github_runner_kms_rs-17a998135e03eec4.github_runner_kms_rs.a68f20bb02f7f6b1-cgu.07.rcgu.o" "/app/target/release/deps/github_runner_kms_rs-17a998135e03eec4.github_runner_kms_rs.a68f20bb02f7f6b1-cgu.08.rcgu.o" "/app/target/release/deps/github_runner_kms_rs-17a998135e03eec4.github_runner_kms_rs.a68f20bb02f7f6b1-cgu.09.rcgu.o" "/app/target/release/deps/github_runner_kms_rs-17a998135e03eec4.github_runner_kms_rs.a68f20bb02f7f6b1-cgu.10.rcgu.o" "/app/target/release/deps/github_runner_kms_rs-17a998135e03eec4.github_runner_kms_rs.a68f20bb02f7f6b1-cgu.11.rcgu.o" "/app/target/release/deps/github_runner_kms_rs-17a998135e03eec4.github_runner_kms_rs.a68f20bb02f7f6b1-cgu.12.rcgu.o" "/app/target/release/deps/github_runner_kms_rs-17a998135e03eec4.github_runner_kms_rs.a68f20bb02f7f6b1-cgu.13.rcgu.o" "/app/target/release/deps/github_runner_kms_rs-17a998135e03eec4.github_runner_kms_rs.a68f20bb02f7f6b1-cgu.14.rcgu.o" "/app/target/release/deps/github_runner_kms_rs-17a998135e03eec4.github_runner_kms_rs.a68f20bb02f7f6b1-cgu.15.rcgu.o" "/app/target/release/deps/github_runner_kms_rs-17a998135e03eec4.29evm7mljwxoiapo.rcgu.o" "-Wl,--as-needed" "-L" "/app/target/release/deps" "-L" "/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib" "-Wl,-Bstatic" "/app/target/release/deps/libreqwest-413f19fd305705be.rlib" "/app/target/release/deps/libhyper_tls-de7cff274ebc6082.rlib" "/app/target/release/deps/libipnet-0c1b57a669a9cbd8.rlib" "/app/target/release/deps/libtokio_tls-466d4c7c8ccde9e9.rlib" "/app/target/release/deps/libserde_urlencoded-564227aa75c6cf61.rlib" "/app/target/release/deps/libserde_json-315a6db3313efd74.rlib" "/app/target/release/deps/libryu-90b15a42c578bb1b.rlib" "/app/target/release/deps/libbase64-8443b2b8d5247f8c.rlib" "/app/target/release/deps/libmime_guess-70f88a763e586f7b.rlib" "/app/target/release/deps/libunicase-97b33380ac397ca5.rlib" "/app/target/release/deps/libnative_tls-f133c0df3c5c9fd7.rlib" "/app/target/release/deps/libopenssl_probe-4ee893680cc72bb7.rlib" "/app/target/release/deps/libopenssl-7f4f468be3a29e7b.rlib" "/app/target/release/deps/libforeign_types-c9b9e12302cd9400.rlib" "/app/target/release/deps/libforeign_types_shared-bb46efa448555615.rlib" "/app/target/release/deps/libopenssl_sys-84601691acc36521.rlib" "-lssl" "-lcrypto" "/app/target/release/deps/libhyper-ff2045cb6eee285f.rlib" "/app/target/release/deps/libitoa-9c4aa3027875d0a4.rlib" "/app/target/release/deps/libwant-5bbf44ef9f4a7fa8.rlib" "/app/target/release/deps/libtry_lock-6191f2e97230b624.rlib" "/app/target/release/deps/libh2-82e3ed415fa5aea0.rlib" "/app/target/release/deps/libtracing_futures-efb4777831323b90.rlib" "/app/target/release/deps/libtokio_util-73b052921eb07c94.rlib" "/app/target/release/deps/libhttpdate-4c5189ab64dae771.rlib" "/app/target/release/deps/libsocket2-1130a50fedd9c30b.rlib" "/app/target/release/deps/libpin_project-b61326a08f60c63f.rlib" "/app/target/release/deps/libtokio-70f5a8f7f958d3c5.rlib" "/app/target/release/deps/libmio-9d4964e6513a1ad4.rlib" "/app/target/release/deps/libiovec-5eb94694c4d55713.rlib" "/app/target/release/deps/libnet2-385966268f23ec9a.rlib" "/app/target/release/deps/libcfg_if-527be9ad7a3eeeb2.rlib" "/app/target/release/deps/libpin_project_lite-026a5c0a6346e10b.rlib" "/app/target/release/deps/libhttp_body-b029c1e1a93a3fdf.rlib" "/app/target/release/deps/libbytes-fef57e8100be4cf1.rlib" "/app/target/release/deps/liblazy_static-87ea8e6cd0d19ffd.rlib" "/app/target/release/deps/liburl-e81b6a63132098ee.rlib" "/app/target/release/deps/libidna-5684e22ece388933.rlib" "/app/target/release/deps/libunicode_normalization-92c59e55724ea807.rlib" "/app/target/release/deps/libtinyvec-4891f23dc055ae76.rlib" "/app/target/release/deps/libtinyvec_macros-ae46f58adef890f1.rlib" "/app/target/release/deps/libunicode_bidi-67cd6e4bd49a819a.rlib" "/app/target/release/deps/libform_urlencoded-4e21afe0dbb58abf.rlib" "/app/target/release/deps/librocket-832be8dcd38752d6.rlib" "/app/target/release/deps/libtempfile-8989b89b2acedd7d.rlib" "/app/target/release/deps/libfastrand-17898f5e8f1a75d7.rlib" "/app/target/release/deps/librocket_http-f225536aa9ad7cf2.rlib" "/app/target/release/deps/libcookie-ce99a55cf79ae699.rlib" "/app/target/release/deps/libstable_pattern-da7d537afad82119.rlib" "/app/target/release/deps/libref_cast-a3c03861c7b11191.rlib" "/app/target/release/deps/libpercent_encoding-fe9f461b263a8555.rlib" "/app/target/release/deps/libhyper-7fc355661d3af9a4.rlib" "/app/target/release/deps/libsocket2-7287e7ae2a015f6e.rlib" "/app/target/release/deps/libh2-a5c9f91aa852b87a.rlib" "/app/target/release/deps/libtower_service-d7d1e275b15ecdd2.rlib" "/app/target/release/deps/libhttp_body-917efee2cb9ae3e1.rlib" "/app/target/release/deps/libhttpdate-193fb5bb3fc8a1ae.rlib" "/app/target/release/deps/libmulter-548b013c594046c9.rlib" "/app/target/release/deps/libmime-1cad6985ad94cd3b.rlib" "/app/target/release/deps/libtokio_util-881f259bd1a88175.rlib" "/app/target/release/deps/libtracing-673c78ac2e8759c9.rlib" "/app/target/release/deps/libtracing_core-de020e7a190e075f.rlib" "/app/target/release/deps/libonce_cell-80e3a82336bdedeb.rlib" "/app/target/release/deps/libhttparse-915a8f2da663425b.rlib" "/app/target/release/deps/libspin-90368875e9195bbf.rlib" "/app/target/release/deps/libencoding_rs-a267f372c3465d02.rlib" "/app/target/release/deps/libhttp-2aa08726f20a7e51.rlib" "/app/target/release/deps/libfnv-ccadf0ca239599af.rlib" "/app/target/release/deps/libindexmap-b2631349373b4eda.rlib" "/app/target/release/deps/libhashbrown-646e7ed123d930ac.rlib" "/app/target/release/deps/libeither-6a752b59d57df59f.rlib" "/app/target/release/deps/libtokio_stream-936dd6e7aa37fe15.rlib" "/app/target/release/deps/libatomic-63dfc73318740fca.rlib" "/app/target/release/deps/libstate-f900f6803deccbbb.rlib" "/app/target/release/deps/libparking_lot-b00169d41edd8ef0.rlib" "/app/target/release/deps/libparking_lot_core-4300f975357633e6.rlib" "/app/target/release/deps/libcfg_if-bdedb1558d5a790e.rlib" "/app/target/release/deps/libsmallvec-b7eac3fc16cf2b93.rlib" "/app/target/release/deps/liblock_api-8154e6a7bb534615.rlib" "/app/target/release/deps/libscopeguard-ddf34753bef86582.rlib" "/app/target/release/deps/libubyte-d7872ed76fc901cf.rlib" "/app/target/release/deps/liblog-9d9910a5d9babcfc.rlib" "/app/target/release/deps/libis_terminal-f80d54d2371bb2f4.rlib" "/app/target/release/deps/librustix-56fc3b73c0650f3b.rlib" "/app/target/release/deps/libbitflags-6f97b00d5a87d32c.rlib" "/app/target/release/deps/liblinux_raw_sys-ae38d2f22413e0d9.rlib" "/app/target/release/deps/libtime-be7976a42ebcbd3a.rlib" "/app/target/release/deps/libitoa-8df96135456c1a40.rlib" "/app/target/release/deps/libtime_core-5ca9150016beb056.rlib" "/app/target/release/deps/libderanged-9d02b676a9edd287.rlib" "/app/target/release/deps/libfigment-1aed0533fdd61cdb.rlib" "/app/target/release/deps/libtoml-4a1822de166a3a68.rlib" "/app/target/release/deps/libtoml_edit-0314208a88a6ab31.rlib" "/app/target/release/deps/libserde_spanned-9c866aa0a4b5efb3.rlib" "/app/target/release/deps/libindexmap-9b4c1e51b49f3cb4.rlib" "/app/target/release/deps/libequivalent-0346c4465917450c.rlib" "/app/target/release/deps/libhashbrown-4b13bd6e646304c9.rlib" "/app/target/release/deps/libwinnow-00608ede3019061f.rlib" "/app/target/release/deps/libtoml_datetime-c86f900ee8b12fe5.rlib" "/app/target/release/deps/libuncased-919310f4f59c9874.rlib" "/app/target/release/deps/libpear-c5fa3a40c5c3f0af.rlib" "/app/target/release/deps/libyansi-df176c4301432cd3.rlib" "/app/target/release/deps/libinlinable_string-a22ad308dd1b07a2.rlib" "/app/target/release/deps/libserde-59ec3dd8b1be388a.rlib" "/app/target/release/deps/libtokio-95992c2592bb0c1f.rlib" "/app/target/release/deps/libsignal_hook_registry-4379b6cf82a47e5f.rlib" "/app/target/release/deps/libnum_cpus-22db30514c6fb165.rlib" "/app/target/release/deps/libsocket2-dd7ce22dc0bab972.rlib" "/app/target/release/deps/libbytes-cddfab68b70b4adf.rlib" "/app/target/release/deps/libmio-d42badb48e0ac464.rlib" "/app/target/release/deps/liblibc-2ca4858ecc804368.rlib" "/app/target/release/deps/libfutures-ea9b2c8ab782fbcb.rlib" "/app/target/release/deps/libfutures_util-9fb679167ede9916.rlib" "/app/target/release/deps/libmemchr-ff5c1472ed3ed161.rlib" "/app/target/release/deps/libfutures_io-01dc2cf3aa4236c2.rlib" "/app/target/release/deps/libslab-177f4a968e2a0d65.rlib" "/app/target/release/deps/libfutures_channel-5981b2be6878f268.rlib" "/app/target/release/deps/libfutures_sink-513fa35af3ccc1e4.rlib" "/app/target/release/deps/libfutures_task-e1c37fe63f09b725.rlib" "/app/target/release/deps/libpin_utils-935e967700f223b2.rlib" "/app/target/release/deps/libasync_stream-a5738128891a22b0.rlib" "/app/target/release/deps/libpin_project_lite-e1c5bd7fc51504b1.rlib" "/app/target/release/deps/libfutures_core-75ef89d194605f16.rlib" "/app/target/release/deps/libyansi-3091a0348e2a99aa.rlib" "/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/libstd-392158b4be25c1ca.rlib" "/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/libpanic_unwind-2f4593a24c3685f6.rlib" "/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/libobject-3d441ba40b9044b1.rlib" "/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/libmemchr-a1fdc3e91cd7a940.rlib" "/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/libaddr2line-b27007973df10889.rlib" "/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/libgimli-018fc651c64b4919.rlib" "/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/librustc_demangle-74ef6c2730cac143.rlib" "/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/libstd_detect-b5bb5c679f5e4950.rlib" "/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/libhashbrown-5d0fff17d48f6fa3.rlib" "/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/librustc_std_workspace_alloc-60e165cf1cd7e3ba.rlib" "/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/libminiz_oxide-d0b56a52ada963bf.rlib" "/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/libadler-ebe9143ffa577f3e.rlib" "/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/libunwind-734e914bc1b79a35.rlib" "-lunwind" "/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/libcfg_if-718dc81eeaa0f994.rlib" "/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/liblibc-22394e7a0b2ed9e6.rlib" "-lc" "/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/liballoc-9535089e3d7da7cd.rlib" "/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/librustc_std_workspace_core-e251179636a4eb0c.rlib" "/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/libcore-d01acce508fabf16.rlib" "/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/libcompiler_builtins-7ab2269e6a08c0c8.rlib" "-Wl,-Bdynamic" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-nostartfiles" "-L" "/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib" "-L" "/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/self-contained" "-o" "/app/target/release/deps/github_runner_kms_rs-17a998135e03eec4" "-Wl,--gc-sections" "-static-pie" "-Wl,-z,relro,-z,now" "-Wl,-O1" "-nodefaultlibs" "/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/self-contained/crtendS.o" "/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/self-contained/crtn.o"
#0 241.7   = note: /usr/lib/gcc/x86_64-alpine-linux-musl/12.2.1/../../../../x86_64-alpine-linux-musl/bin/ld: cannot find -lssl: No such file or directory
#0 241.7           /usr/lib/gcc/x86_64-alpine-linux-musl/12.2.1/../../../../x86_64-alpine-linux-musl/bin/ld: cannot find -lcrypto: No such file or directory
#0 241.7           collect2: error: ld returned 1 exit status
#0 241.7
#0 241.7
#0 241.8 error: could not compile `github-runner-kms-rs` (bin "github-runner-kms-rs") due to previous error
------

各种网上搜索发现好像和 ssl 库相关,参考网上搜到的做法在 Cargo.toml 中加入:

openssl = { version = "0.10", features = ["vendored"] }

If the vendored Cargo feature is enabled, the openssl-src crate will be used to compile and statically link to a copy of OpenSSL. The build process requires a C compiler, perl (and perl-core), and make. The OpenSSL version will generally track the newest OpenSSL release, and changes to the version are not considered breaking changes.

The vendored copy will not be configured to automatically find the system’s root certificates, but the openssl-probe crate can be used to do that instead.

features = ["vendored"]:这是一个特性(feature)列表,你启用了名为 “vendored” 的特性。这个特性通常用于启用 OpenSSL crate 内部包含的 OpenSSL 库代码,而不是依赖系统上已安装的 OpenSSL 库。这对于确保项目的可移植性和不受外部系统库影响很有用。

并重新构建,构建成功,体积不大,且可用:

REPOSITORY                                  TAG                  IMAGE ID       CREATED          SIZE
knatnetwork/github-runner-kms-rs            latest               89d3f57c74e8   13 seconds ago   24.7MB

为了确认这个 Dockerfile 在 ARM64 上是可用的,我去 Hetzner ARM64 的机器上又构建了一下,然后又报错了:

Compiling github-runner-kms-rs v0.0.1 (/app)
error: linking with `cc` failed: exit status: 1
  |
  = note: LC_ALL="C" PATH="/usr/local/rustup/toolchains/nightly-aarch64-unknown-linux-musl/lib/rustlib/aarch64-unknown-linux-musl/bin:/usr/local/rustup/toolchains/nightly-aarch64-unknown-linux-musl/lib/rustlib/aarch64-unknown-linux-musl/bin/self-contained:/usr/local/cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" VSLANG="1033" "cc" "/usr/local/rustup/toolchains/nightly-aarch64-unknown-linux-musl/lib/rustlib/aarch64-unknown-linux-musl/lib/self-contained/crt1.o" "/usr/local/rustup/toolchains/nightly-aarch64-unknown-linux-musl/lib/rustlib/aarch64-unknown-linux-musl/lib/self-contained/crti.o" "/usr/local/rustup/toolchains/nightly-aarch64-unknown-linux-musl/lib/rustlib/aarch64-unknown-linux-musl/lib/self-contained/crtbegin.o" "/tmp/rustc471pKi/symbols.o" "/app/target/release/deps/github_runner_kms_rs-bffd4dfb21b941cb.github_runner_kms_rs.3726c178f93421ac-cgu.00.rcgu.o" "/app/target/release/deps/github_runner_kms_rs-bffd4dfb21b941cb.github_runner_kms_rs.3726c178f93421ac-cgu.01.rcgu.o" "/app/target/release/deps/github_runner_kms_rs-bffd4dfb21b941cb.github_runner_kms_rs.3726c178f93421ac-cgu.02.rcgu.o" "/app/target/release/deps/github_runner_kms_rs-bffd4dfb21b941cb.github_runner_kms_rs.3726c178f93421ac-cgu.03.rcgu.o" "/app/target/release/deps/github_runner_kms_rs-bffd4dfb21b941cb.github_runner_kms_rs.3726c178f93421ac-cgu.04.rcgu.o" "/app/target/release/deps/github_runner_kms_rs-bffd4dfb21b941cb.github_runner_kms_rs.3726c178f93421ac-cgu.05.rcgu.o" "/app/target/release/deps/github_runner_kms_rs-bffd4dfb21b941cb.github_runner_kms_rs.3726c178f93421ac-cgu.06.rcgu.o" "/app/target/release/deps/github_runner_kms_rs-bffd4dfb21b941cb.github_runner_kms_rs.3726c178f93421ac-cgu.07.rcgu.o" "/app/target/release/deps/github_runner_kms_rs-bffd4dfb21b941cb.github_runner_kms_rs.3726c178f93421ac-cgu.08.rcgu.o" "/app/target/release/deps/github_runner_kms_rs-bffd4dfb21b941cb.github_runner_kms_rs.3726c178f93421ac-cgu.09.rcgu.o" "/app/target/release/deps/github_runner_kms_rs-bffd4dfb21b941cb.github_runner_kms_rs.3726c178f93421ac-cgu.10.rcgu.o" "/app/target/release/deps/github_runner_kms_rs-bffd4dfb21b941cb.github_runner_kms_rs.3726c178f93421ac-cgu.11.rcgu.o" "/app/target/release/deps/github_runner_kms_rs-bffd4dfb21b941cb.github_runner_kms_rs.3726c178f93421ac-cgu.12.rcgu.o" "/app/target/release/deps/github_runner_kms_rs-bffd4dfb21b941cb.github_runner_kms_rs.3726c178f93421ac-cgu.13.rcgu.o" "/app/target/release/deps/github_runner_kms_rs-bffd4dfb21b941cb.github_runner_kms_rs.3726c178f93421ac-cgu.14.rcgu.o" "/app/target/release/deps/github_runner_kms_rs-bffd4dfb21b941cb.github_runner_kms_rs.3726c178f93421ac-cgu.15.rcgu.o" "/app/target/release/deps/github_runner_kms_rs-bffd4dfb21b941cb.386c0okcsj1kdyxq.rcgu.o" "-Wl,--as-needed" "-L" "/app/target/release/deps" "-L" "/app/target/release/build/openssl-sys-4b52ea22bc2c9689/out/openssl-build/install/lib" "-L" "/usr/local/rustup/toolchains/nightly-aarch64-unknown-linux-musl/lib/rustlib/aarch64-unknown-linux-musl/lib" "-Wl,-Bstatic" "/app/target/release/deps/libreqwest-54f0eecd9a64461b.rlib" "/app/target/release/deps/libhyper_tls-5ca5c68388624029.rlib" "/app/target/release/deps/libipnet-08585b1977ca241e.rlib" "/app/target/release/deps/libtokio_tls-47f0cf803f182381.rlib" "/app/target/release/deps/libserde_urlencoded-0289e236f6d19683.rlib" "/app/target/release/deps/libserde_json-d3559a6d9b9bafad.rlib" "/app/target/release/deps/libryu-d11638cc977e3ce1.rlib" "/app/target/release/deps/libbase64-59c1b043c4836ced.rlib" "/app/target/release/deps/libmime_guess-69823f6aefb6b725.rlib" "/app/target/release/deps/libunicase-a40432df8a9a314e.rlib" "/app/target/release/deps/libnative_tls-04640cf8429bb72d.rlib" "/app/target/release/deps/libopenssl_probe-9623f95c78a89b7b.rlib" "/app/target/release/deps/libopenssl-1cda5fdcb61189f2.rlib" "/app/target/release/deps/libforeign_types-1b720a3fcda466c3.rlib" "/app/target/release/deps/libforeign_types_shared-b7ca5d81cc6277ea.rlib" "/app/target/release/deps/libopenssl_sys-a1fc529eecb6f62a.rlib" "/app/target/release/deps/libhyper-759486257b4ee38e.rlib" "/app/target/release/deps/libitoa-30035605c6471794.rlib" "/app/target/release/deps/libwant-890dfc4530313552.rlib" "/app/target/release/deps/libtry_lock-f77b14c662e56223.rlib" "/app/target/release/deps/libh2-3c32179e7d40dc2c.rlib" "/app/target/release/deps/libtracing_futures-17d9f4809bc33a4e.rlib" "/app/target/release/deps/libtokio_util-3b78186931dd6398.rlib" "/app/target/release/deps/libhttpdate-ff82d3c9a161b281.rlib" "/app/target/release/deps/libsocket2-3a41184621f5382b.rlib" "/app/target/release/deps/libpin_project-ccc7c81d8c5b7805.rlib" "/app/target/release/deps/libtokio-f37464c26f941839.rlib" "/app/target/release/deps/libmio-e71907e4eff0fc5b.rlib" "/app/target/release/deps/libiovec-f51c232606345975.rlib" "/app/target/release/deps/libnet2-3fca814dd8e633ad.rlib" "/app/target/release/deps/libcfg_if-168a945f68d1bbcd.rlib" "/app/target/release/deps/libpin_project_lite-1bf4ebfeba6a22ff.rlib" "/app/target/release/deps/libhttp_body-8b198314e43c14c3.rlib" "/app/target/release/deps/libbytes-68abd7f3517436fa.rlib" "/app/target/release/deps/liblazy_static-3eab779d0755d944.rlib" "/app/target/release/deps/liburl-2ce936308decc46b.rlib" "/app/target/release/deps/libidna-cd14ab0da5fb1a63.rlib" "/app/target/release/deps/libunicode_normalization-6c57abfbf329ee87.rlib" "/app/target/release/deps/libtinyvec-ef48a9b182dd1dde.rlib" "/app/target/release/deps/libtinyvec_macros-5fd9bbd566d8bb0f.rlib" "/app/target/release/deps/libunicode_bidi-4858cefce3fa42ab.rlib" "/app/target/release/deps/libform_urlencoded-3a4a484c740e305e.rlib" "/app/target/release/deps/librocket-fe764f64c47f18d0.rlib" "/app/target/release/deps/libtempfile-2da99e2fd34c9ea0.rlib" "/app/target/release/deps/libfastrand-5e43380f5d309843.rlib" "/app/target/release/deps/librocket_http-10249d804070975f.rlib" "/app/target/release/deps/libcookie-d052d9163ba02221.rlib" "/app/target/release/deps/libstable_pattern-8f4888ae4649d360.rlib" "/app/target/release/deps/libref_cast-be488d9518312b95.rlib" "/app/target/release/deps/libpercent_encoding-359ca849981e7017.rlib" "/app/target/release/deps/libhyper-fbeb526f03e319c6.rlib" "/app/target/release/deps/libsocket2-da6932068eedebf0.rlib" "/app/target/release/deps/libh2-fc18c83bb913466d.rlib" "/app/target/release/deps/libtower_service-bb0e22f36f510baa.rlib" "/app/target/release/deps/libhttp_body-d96258acc03c9153.rlib" "/app/target/release/deps/libhttpdate-8d23528641b845b0.rlib" "/app/target/release/deps/libmulter-a3bb3415bbe509b1.rlib" "/app/target/release/deps/libmime-521d44d88d9ca9b8.rlib" "/app/target/release/deps/libtokio_util-90ef3865aaa61e5e.rlib" "/app/target/release/deps/libtracing-1da3a3ff67f4bec1.rlib" "/app/target/release/deps/libtracing_core-b63b26b64e7a8105.rlib" "/app/target/release/deps/libonce_cell-8069f17fd4df89e6.rlib" "/app/target/release/deps/libhttparse-57449685ff4705cf.rlib" "/app/target/release/deps/libspin-73dbf16dd571446e.rlib" "/app/target/release/deps/libencoding_rs-7683a3afbd2abe9a.rlib" "/app/target/release/deps/libhttp-35200d3ad46ec0f9.rlib" "/app/target/release/deps/libfnv-82c7e996987a6199.rlib" "/app/target/release/deps/libindexmap-02aebc2b2c11958e.rlib" "/app/target/release/deps/libhashbrown-a5ea1c03e41647ca.rlib" "/app/target/release/deps/libeither-7a72415ff30e3108.rlib" "/app/target/release/deps/libtokio_stream-22af83096a1cd410.rlib" "/app/target/release/deps/libatomic-c03615d17583da5e.rlib" "/app/target/release/deps/libstate-d79b0fb801f7b15b.rlib" "/app/target/release/deps/libparking_lot-56f62f958a9794d9.rlib" "/app/target/release/deps/libparking_lot_core-24ca98da7d7f2b19.rlib" "/app/target/release/deps/libcfg_if-85c334935ca1cf3d.rlib" "/app/target/release/deps/libsmallvec-b80672ee63140a1f.rlib" "/app/target/release/deps/liblock_api-aa9a3618939327ad.rlib" "/app/target/release/deps/libscopeguard-17c02f89e1495a6b.rlib" "/app/target/release/deps/libubyte-53a35973dcef3b92.rlib" "/app/target/release/deps/liblog-40d6ddc909b0c838.rlib" "/app/target/release/deps/libis_terminal-b2dec1edfa9020e0.rlib" "/app/target/release/deps/librustix-b79c7cdf68554bb1.rlib" "/app/target/release/deps/libbitflags-33a64692a7b926e9.rlib" "/app/target/release/deps/liblinux_raw_sys-3c0ed39bce490458.rlib" "/app/target/release/deps/libtime-c9efb7347e1d4147.rlib" "/app/target/release/deps/libitoa-4e3c2272091e09ac.rlib" "/app/target/release/deps/libtime_core-6e76d0b901dc6f13.rlib" "/app/target/release/deps/libderanged-f37da7152db973f2.rlib" "/app/target/release/deps/libfigment-d56bce3860016ab3.rlib" "/app/target/release/deps/libtoml-b489a43dc0f6eb1c.rlib" "/app/target/release/deps/libtoml_edit-9281968d258c7d78.rlib" "/app/target/release/deps/libserde_spanned-b158dd6ea3b96735.rlib" "/app/target/release/deps/libindexmap-ba48b6652434a2a8.rlib" "/app/target/release/deps/libequivalent-632a5c005316850d.rlib" "/app/target/release/deps/libhashbrown-3983d74463a82636.rlib" "/app/target/release/deps/libwinnow-6899879cdd6c2091.rlib" "/app/target/release/deps/libtoml_datetime-0897972d9afde5d0.rlib" "/app/target/release/deps/libuncased-e60bc90193c31787.rlib" "/app/target/release/deps/libpear-daf347955190abd8.rlib" "/app/target/release/deps/libyansi-8f33bca686eb0e72.rlib" "/app/target/release/deps/libinlinable_string-edce6a169e8d4fb3.rlib" "/app/target/release/deps/libserde-b9f17f14c671d860.rlib" "/app/target/release/deps/libtokio-f5a651b5671ad6ce.rlib" "/app/target/release/deps/libsignal_hook_registry-43f091791edab8d3.rlib" "/app/target/release/deps/libnum_cpus-645e52fa82c5038d.rlib" "/app/target/release/deps/libsocket2-5f5a714d64fd802d.rlib" "/app/target/release/deps/libbytes-62c9407790d48b4a.rlib" "/app/target/release/deps/libmio-31b9694540026601.rlib" "/app/target/release/deps/liblibc-995eeee032a5f5f9.rlib" "/app/target/release/deps/libfutures-cba62e5842e36664.rlib" "/app/target/release/deps/libfutures_util-36aed2c0518ed210.rlib" "/app/target/release/deps/libmemchr-3a7c2b395cb2f36e.rlib" "/app/target/release/deps/libfutures_io-eb63744d4682e029.rlib" "/app/target/release/deps/libslab-7b5bd29f7639d510.rlib" "/app/target/release/deps/libfutures_channel-955aedcfa158ff5e.rlib" "/app/target/release/deps/libfutures_sink-6b1883f3a3d27161.rlib" "/app/target/release/deps/libfutures_task-231e41c20a6bfd7e.rlib" "/app/target/release/deps/libpin_utils-5a2c59a680150faa.rlib" "/app/target/release/deps/libasync_stream-ba095822278f5551.rlib" "/app/target/release/deps/libpin_project_lite-7d06350189cc1d02.rlib" "/app/target/release/deps/libfutures_core-3bef00756fc0a4ca.rlib" "/app/target/release/deps/libyansi-a9a29b8f1212c3c5.rlib" "/usr/local/rustup/toolchains/nightly-aarch64-unknown-linux-musl/lib/rustlib/aarch64-unknown-linux-musl/lib/libstd-a55c99d9aac7c6c8.rlib" "/usr/local/rustup/toolchains/nightly-aarch64-unknown-linux-musl/lib/rustlib/aarch64-unknown-linux-musl/lib/libpanic_unwind-46b2ae4ce5f4ac3c.rlib" "/usr/local/rustup/toolchains/nightly-aarch64-unknown-linux-musl/lib/rustlib/aarch64-unknown-linux-musl/lib/libobject-bc100d33f847f53c.rlib" "/usr/local/rustup/toolchains/nightly-aarch64-unknown-linux-musl/lib/rustlib/aarch64-unknown-linux-musl/lib/libmemchr-6fed8b06d1b8dd31.rlib" "/usr/local/rustup/toolchains/nightly-aarch64-unknown-linux-musl/lib/rustlib/aarch64-unknown-linux-musl/lib/libaddr2line-ef156e55b8a0b661.rlib" "/usr/local/rustup/toolchains/nightly-aarch64-unknown-linux-musl/lib/rustlib/aarch64-unknown-linux-musl/lib/libgimli-5dd0cc5240ff597d.rlib" "/usr/local/rustup/toolchains/nightly-aarch64-unknown-linux-musl/lib/rustlib/aarch64-unknown-linux-musl/lib/librustc_demangle-b6251d721ee20ba8.rlib" "/usr/local/rustup/toolchains/nightly-aarch64-unknown-linux-musl/lib/rustlib/aarch64-unknown-linux-musl/lib/libstd_detect-2abef0e4453983bd.rlib" "/usr/local/rustup/toolchains/nightly-aarch64-unknown-linux-musl/lib/rustlib/aarch64-unknown-linux-musl/lib/libhashbrown-7ba331d2a4169fa6.rlib" "/usr/local/rustup/toolchains/nightly-aarch64-unknown-linux-musl/lib/rustlib/aarch64-unknown-linux-musl/lib/librustc_std_workspace_alloc-94dcb2b51eeefe61.rlib" "/usr/local/rustup/toolchains/nightly-aarch64-unknown-linux-musl/lib/rustlib/aarch64-unknown-linux-musl/lib/libminiz_oxide-b86470996bafb930.rlib" "/usr/local/rustup/toolchains/nightly-aarch64-unknown-linux-musl/lib/rustlib/aarch64-unknown-linux-musl/lib/libadler-500cadb64a5228ac.rlib" "/usr/local/rustup/toolchains/nightly-aarch64-unknown-linux-musl/lib/rustlib/aarch64-unknown-linux-musl/lib/libunwind-53353d61a88a3a7a.rlib" "-lunwind" "/usr/local/rustup/toolchains/nightly-aarch64-unknown-linux-musl/lib/rustlib/aarch64-unknown-linux-musl/lib/libcfg_if-fe0ba221a42ab3ba.rlib" "/usr/local/rustup/toolchains/nightly-aarch64-unknown-linux-musl/lib/rustlib/aarch64-unknown-linux-musl/lib/liblibc-a76e01b4e68d0f0e.rlib" "-lc" "/usr/local/rustup/toolchains/nightly-aarch64-unknown-linux-musl/lib/rustlib/aarch64-unknown-linux-musl/lib/liballoc-74327c4df0bf25aa.rlib" "/usr/local/rustup/toolchains/nightly-aarch64-unknown-linux-musl/lib/rustlib/aarch64-unknown-linux-musl/lib/librustc_std_workspace_core-e7cc358bf4ebd76f.rlib" "/usr/local/rustup/toolchains/nightly-aarch64-unknown-linux-musl/lib/rustlib/aarch64-unknown-linux-musl/lib/libcore-632ed3ff9dfe5d9b.rlib" "/usr/local/rustup/toolchains/nightly-aarch64-unknown-linux-musl/lib/rustlib/aarch64-unknown-linux-musl/lib/libcompiler_builtins-6865cdea8e17976b.rlib" "-Wl,-Bdynamic" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-nostartfiles" "-L" "/usr/local/rustup/toolchains/nightly-aarch64-unknown-linux-musl/lib/rustlib/aarch64-unknown-linux-musl/lib" "-L" "/usr/local/rustup/toolchains/nightly-aarch64-unknown-linux-musl/lib/rustlib/aarch64-unknown-linux-musl/lib/self-contained" "-o" "/app/target/release/deps/github_runner_kms_rs-bffd4dfb21b941cb" "-Wl,--gc-sections" "-static" "-no-pie" "-Wl,-z,relro,-z,now" "-Wl,-O1" "-nodefaultlibs" "/usr/local/rustup/toolchains/nightly-aarch64-unknown-linux-musl/lib/rustlib/aarch64-unknown-linux-musl/lib/self-contained/crtend.o" "/usr/local/rustup/toolchains/nightly-aarch64-unknown-linux-musl/lib/rustlib/aarch64-unknown-linux-musl/lib/self-contained/crtn.o"
  = note: /usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: /usr/local/rustup/toolchains/nightly-aarch64-unknown-linux-musl/lib/rustlib/aarch64-unknown-linux-musl/lib/libcompiler_builtins-6865cdea8e17976b.rlib(45c91108d938afe8-cpu_model.o): in function `init_have_lse_atomics':
          /cargo/registry/src/index.crates.io-6f17d22bba15001f/compiler_builtins-0.1.98/./lib/builtins/cpu_model.c:1075: undefined reference to `getauxval'
          /usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: /usr/local/rustup/toolchains/nightly-aarch64-unknown-linux-musl/lib/rustlib/aarch64-unknown-linux-musl/lib/libcompiler_builtins-6865cdea8e17976b.rlib(45c91108d938afe8-cpu_model.o): in function `init_cpu_features':
          /cargo/registry/src/index.crates.io-6f17d22bba15001f/compiler_builtins-0.1.98/./lib/builtins/cpu_model.c:1373: undefined reference to `getauxval'
          /usr/lib/gcc/aarch64-alpine-linux-musl/12.2.1/../../../../aarch64-alpine-linux-musl/bin/ld: /cargo/registry/src/index.crates.io-6f17d22bba15001f/compiler_builtins-0.1.98/./lib/builtins/cpu_model.c:1374: undefined reference to `getauxval'
          collect2: error: ld returned 1 exit status

  = note: some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified
  = note: use the `-l` flag to specify native libraries to link
  = note: use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargorustc-link-libkindname)

error: could not compile `github-runner-kms-rs` (bin "github-runner-kms-rs") due to previous error

经过了各种搜索,发现可能是一个 Bug,最后在 https://github.com/rust-lang/git2-rs/issues/706 中发现有人加入了 CFLAGS=-mno-outline-atomics 环境变量,于是我也试试:

# docker build . -t knatnetwork/github-runner-kms-rs
FROM rust:1.72-alpine as builder

WORKDIR /app

RUN apk add --no-cache musl-dev pkgconfig openssl-dev perl make

COPY Cargo.toml Cargo.lock rust-toolchain.toml ./

RUN mkdir src

COPY src ./src

ENV CFLAGS=-mno-outline-atomics
RUN cargo build --release

FROM alpine

WORKDIR /

COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /app/target/release/github-runner-kms-rs /github-runner-kms-rs

ENV ROCKET_ADDRESS=0.0.0.0
ENV ROCKET_PORT=3000

CMD ["/github-runner-kms-rs"]

再来构建,这次在 ARM64 上构建成功了,但是回过来在 AMD64 上构建又失败了:

#0 51.10
#0 51.10   **********************************************************************
#0 51.10   ***                                                                ***
#0 51.10   ***   OpenSSL has been successfully configured                     ***
#0 51.10   ***                                                                ***
#0 51.10   ***   If you encounter a problem while building, please open an    ***
#0 51.10   ***   issue on GitHub <https://github.com/openssl/openssl/issues>  ***
#0 51.10   ***   and include the output from the following command:           ***
#0 51.10   ***                                                                ***
#0 51.10   ***       perl configdata.pm --dump                                ***
#0 51.10   ***                                                                ***
#0 51.10   ***   (If you are new to OpenSSL, you might want to consult the    ***
#0 51.10   ***   'Troubleshooting' section in the INSTALL file first)         ***
#0 51.10   ***                                                                ***
#0 51.10   **********************************************************************
#0 51.10   running cd "/app/target/release/build/openssl-sys-efe4f068ed311573/out/openssl-build/build/src" && "make" "depend"
#0 51.10   running cd "/app/target/release/build/openssl-sys-efe4f068ed311573/out/openssl-build/build/src" && MAKEFLAGS="-j --jobserver-fds=8,13 --jobserver-auth=8,13" "make" "build_libs"
#0 51.10   perl "-I." -Mconfigdata "util/dofile.pl" \
#0 51.10       "-oMakefile" include/crypto/bn_conf.h.in > include/crypto/bn_conf.h
#0 51.10   perl "-I." -Mconfigdata "util/dofile.pl" \
#0 51.10       "-oMakefile" include/crypto/dso_conf.h.in > include/crypto/dso_conf.h
#0 51.10   perl "-I." -Mconfigdata "util/dofile.pl" \
#0 51.10       "-oMakefile" include/openssl/opensslconf.h.in > include/openssl/opensslconf.h
#0 51.10   make depend && make _build_libs
#0 51.10   make[1]: Entering directory '/app/target/release/build/openssl-sys-efe4f068ed311573/out/openssl-build/build/src'
#0 51.10   make[1]: Leaving directory '/app/target/release/build/openssl-sys-efe4f068ed311573/out/openssl-build/build/src'
#0 51.10   make[1]: Entering directory '/app/target/release/build/openssl-sys-efe4f068ed311573/out/openssl-build/build/src'
#0 51.10   cc  -I. -Iinclude -fPIC -pthread -m64 -Wa,--noexecstack -mno-outline-atomics -O2 -ffunction-sections -fdata-sections -fPIC -m64 -mno-outline-atomics -DOPENSSL_USE_NODELETE -DL_ENDIAN -DOPENSSL_PIC -DOPENSSL_CPUID_OBJ -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DKECCAK1600_ASM -DRC4_ASM -DMD5_ASM -DAESNI_ASM -DVPAES_ASM -DGHASH_ASM -DECP_NISTZ256_ASM -DX25519_ASM -DPOLY1305_ASM -DOPENSSLDIR="\"/usr/local/ssl\"" -DENGINESDIR="\"/app/target/release/build/openssl-sys-efe4f068ed311573/out/openssl-build/install/lib/engines-1.1\"" -DNDEBUG -DOPENSSL_NO_SECURE_MEMORY -MMD -MF apps/app_rand.d.tmp -MT apps/app_rand.o -c -o apps/app_rand.o apps/app_rand.c
#0 51.10   make[1]: Leaving directory '/app/target/release/build/openssl-sys-efe4f068ed311573/out/openssl-build/build/src'
#0 51.10
#0 51.10   --- stderr
#0 51.10   cc: error: unrecognized command-line option '-mno-outline-atomics'; did you mean '-fno-inline-atomics'?
#0 51.10   cc: error: unrecognized command-line option '-mno-outline-atomics'; did you mean '-fno-inline-atomics'?
#0 51.10   make[1]: *** [Makefile:679: apps/app_rand.o] Error 1
#0 51.10   make: *** [Makefile:177: build_libs] Error 2
#0 51.10   thread 'main' panicked at /usr/local/cargo/registry/src/index.crates.io-6f17d22bba15001f/openssl-src-111.27.0+1.1.1v/src/lib.rs:506:13:
#0 51.10
#0 51.10
#0 51.10
#0 51.10   Error building OpenSSL:
#0 51.10       Command: cd "/app/target/release/build/openssl-sys-efe4f068ed311573/out/openssl-build/build/src" && MAKEFLAGS="-j --jobserver-fds=8,13 --jobserver-auth=8,13" "make" "build_libs"
#0 51.10       Exit status: exit status: 2
#0 51.10
#0 51.10
#0 51.10
#0 51.10   note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
#0 51.11 warning: build failed, waiting for other jobs to finish...
------
Dockerfile:15
--------------------
  13 |
  14 |     ENV CFLAGS=-mno-outline-atomics
  15 | >>> RUN cargo build --release

无奈,最终只能暂时接受 ARM64 和 AMD64 用两个独立的 Dockerfile 来构建的模式了(AMD64 的 Dockerfile 中不加入 ENV CFLAGS=-mno-outline-atomics 环境变量),最后参考了一下自己早期文章 在 GitHub Actions 上使用多 Job 并行构建,提升 Multi-Arch 镜像制作速度 分两个 Job 分开构建镜像并缝合的方式,终于可以在一个看上去还算合理的时间内构建这个新程序的 MultiArch 镜像了。

当然,这里「还算合理的时间」其实也没那么合理就是了,下一步的研究方向可能是做一个可以按需启动 Hetzner 机器并自动注册 ARM64 Self-hosted Runner 的方式

总结一下,在这次的构建过程中遇到了如下的问题:

感觉好像我一上手 Rust 就踩了个大坑,也许不该上来就搞 HTTP 相关的东西的

对比一下如果用 Go 要解决上面静态链接 SSL 相关库的问题似乎只要:

CGO_ENABLED=0 go build .

就可以了,但是在 Rust 这里,就得各种找人打架,安装依赖,尝试看各种看不懂的报错。(当然也有可能是我太菜了导致)。

在学习期间还偶然发现一个神奇的玩法,即使用:

rustup target add x86_64-unknown-linux-musl
cargo build --release --target=x86_64-unknown-linux-musl

使用这种方式构建出来的 Binary 不会有任何依赖(静态链接):

ldd target/x86_64-unknown-linux-musl/release/github-runner-kms-rs
        statically linked

du -ch target/x86_64-unknown-linux-musl/release/github-runner-kms-rs
17M     target/x86_64-unknown-linux-musl/release/github-runner-kms-rs
17M     total

而且最有趣的是,这里虽然名字叫 musl ,但是并不会像我们传统的在 Alpine 上构建出来的文件依赖 musl 库没法在 glibc 运行时环境的机器上运行,这个 binary 似乎可以在任何 AMD64 架构的平台上运行。

对比之下,传统方式用 cargo build --release 构建的话会有许多的依赖(但是构建出来文件体积和静态链接的是一样的):

ldd target/release/github-runner-kms-rs
        linux-vdso.so.1 (0x00007fffba6fd000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f276cebc000)
        libm.so.6 => /lib64/libm.so.6 (0x00007f276cdde000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f276c000000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f276cefa000)

du -ch target/release/github-runner-kms-rs
17M     target/release/github-runner-kms-rs
17M     total

References

  1. https://www.mail-archive.com/[email protected]/msg1802783.html
  2. https://github.com/rust-lang/git2-rs/issues/706
  3. https://github.com/rust-lang/rust/issues/89626
  4. https://news.ycombinator.com/item?id=24443835
  5. https://gitlab.alpinelinux.org/alpine/aports/-/issues/13690
  6. https://gitlab.alpinelinux.org/alpine/aports/-/issues/11377
  7. https://docs.rs/openssl/latest/openssl/

#Chinese