本文我們將探討如何使用預(yù)裝程序創(chuàng)建并分發(fā) AArch64 容器。
創(chuàng)建容器
首先需要建立一個(gè) Dockerfile。由于創(chuàng)建容器的目的是為小程序提供一個(gè)快速且占用資源最小的環(huán)境,因此選擇 Alpine Linux 作為容器運(yùn)行時(shí)。Alpine Linux 是一個(gè)小型的容器基礎(chǔ)鏡像(8MB),在容器開發(fā)中很受歡迎。初始的 Dockerfile 非常小,在獲取容器鏡像后,將“fizzbuzz”可執(zhí)行文件從預(yù)存的構(gòu)建環(huán)境第一部分復(fù)制到容器中,并將可執(zhí)行文件設(shè)置為容器的入口點(diǎn)(當(dāng)容器運(yùn)行時(shí)將自動(dòng)運(yùn)行可執(zhí)行文件):
FROM alpine:latest
WORKDIR /root/
COPY ./fizzbuzz ./
ENTRYPOINT [“./fizzbuzz”]
本次演示以 Podman 為例,其命令行與 Docker 的原理類似:
[dneary@fedora fizzbuzz-c]$ podman build -f ./Dockerfile -t fizzbuzz:1
STEP 1/4: FROM alpine:latest
STEP 2/4: WORKDIR /root/
--> Using cache
a6bfe2eb0767b7966a2e25e3f1fdd638b5a74aaf8abf2abd12f54a8f20fdf9be
--> a6bfe2eb076
STEP 3/4: COPY ./fizzbuzz ./
--> 772088bc011
STEP 4/4: ENTRYPOINT ["./fizzbuzz"]
COMMIT fizzbuzz:1
--> 4afe789ccb9
Successfully tagged localhost/fizzbuzz:1
4afe789ccb91e3ce11907a81f0b0ebbe559b65b10d9e50ff86da8a610670434d
以上步驟看似可成功運(yùn)行,但當(dāng)運(yùn)行容器時(shí):
[dneary@fedora fizzbuzz-c]$ podman run fizzbuzz:1
{"msg":"exec container process (missing dynamic library?) `/root//./fizzbuzz`:
No such file or directory","level":"error","time":"2022-07-11T2334.000019606Z"}
顯然,運(yùn)行失敗了,但失敗是容器開發(fā)的必經(jīng)之路。
問題在于:構(gòu)建在 Fedora 主機(jī)上的二進(jìn)制文件被編譯后要?jiǎng)討B(tài)鏈接到 glibc,而 Alpine Linux 基于 Busybox 并采用 musl 的小型 libc,旨在用于桌面和服務(wù)器之外的嵌入式環(huán)境。當(dāng)我們?cè)?Alpine 中運(yùn)行二進(jìn)制文件時(shí),無(wú)法找到其所需的庫(kù),于是便出現(xiàn)以上錯(cuò)誤。
對(duì)于以上問題,有幾個(gè)選項(xiàng)可以進(jìn)行修正:
1. 在主機(jī)上靜態(tài)鏈接二進(jìn)制文件并復(fù)制一個(gè)嵌入了靜態(tài)版本 glibc 的全包二進(jìn)制文件;
2. 給 Alpine 添加一個(gè)兼容層,讓它運(yùn)行時(shí)動(dòng)態(tài)鏈接到 glibc 的二進(jìn)制文件;
3. 最后一項(xiàng)則為最優(yōu)選:在 Alpine Linux 容器中構(gòu)建應(yīng)用程序。新 Docker 文件在 Alpine 上安裝“build-base”,并復(fù)制 C 文件和 Makefile,在容器內(nèi)編譯 fizzbuzz。
FROM alpine:latest
WORKDIR /build/
# Install C compiler and Make
RUN apk --no-cache add build-base
COPY fizzbuzz.c Makefile ./
RUN make clean && make all
ENTRYPOINT ["./fizzbuzz"]
該方法相當(dāng)簡(jiǎn)單且有效。當(dāng)我們建立一個(gè)新的容器并使用 Podman 運(yùn)行它時(shí),熟悉的 FizzBuzz 輸出便呈現(xiàn)出來(lái)。然而,當(dāng)運(yùn)行“podman images fizzbuzz”時(shí),出現(xiàn)了以下問題:
內(nèi)存優(yōu)化
由于我們安裝了 GNUMake 以及整個(gè) C 和 C++ 開發(fā)堆棧,輕量型小容器從不到 6MB 急劇擴(kuò)大到了 192MB。那么是否存在一種方法將新構(gòu)建的可執(zhí)行文件復(fù)制回較小的鏡像?
答案是肯定的:使用“多階段構(gòu)建”容器來(lái)返回到容器的上一層,并從構(gòu)建環(huán)境中復(fù)制文件。使用“builder”標(biāo)記構(gòu)建的環(huán)境,然后將可執(zhí)行文件復(fù)制到原始容器。這也使得 Dockerfile 的復(fù)雜性略有增加。
FROM alpine:latest AS builder
WORKDIR /build/
# Install C compiler and Make
RUN apk --no-cache add build-base
COPY fizzbuzz.c Makefile ./
RUN make clean && make all
FROM alpine:latest AS app
WORKDIR /root/
# Add our executable from the builder container
COPY --from=builder /build/fizzbuzz ./
ENTRYPOINT ["./fizzbuzz"]
不過鏡像大小問題可以很好地得到解決:遷移到多階段構(gòu)建后,容器鏡像恢復(fù)到可管理的 5.84MB:
接下來(lái)準(zhǔn)備在 GitHub 中構(gòu)建自定義運(yùn)行程序。我們將使用預(yù)安裝在 GitHub “ubuntu-latest” 虛擬環(huán)境上的 Docker 堆棧,并在 OCI 上的自托管 AlmaLinux 實(shí)例上使用 Podman。
將 Dockerfile 添加到存儲(chǔ)庫(kù)后,選擇“添加新工作流”,GitHub Actions 將推薦“構(gòu)建 Docker 容器”操作:
我們自己的 Docker 鏡像工作流程如下所示。因?yàn)樵诿總€(gè)運(yùn)行器上使用的工具鏈不同,所以新的工作流程文件中存在較多重復(fù)。遺憾的是,沒有一種簡(jiǎn)單的方法來(lái)創(chuàng)建一個(gè) build matrix,從而實(shí)現(xiàn)在共享其余操作的同時(shí),還能指示不同主機(jī)使用哪個(gè)容器運(yùn)行時(shí)和 Builder。
name: Docker Image CI
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
jobs:
x86-fizzbuzz-container:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build the Docker image
run: docker build . --file Dockerfile --tag fizzbuzz:latest –-tag fizzbuzz:${{ github.sha }}
- name: Run the Docker image
run: docker run fizzbuzz
aarch64-fizzbuzz-container:
runs-on: [self-hosted, linux, ARM64]
steps:
- uses: actions/checkout@v3
- name: Build the Docker image with Buildah
uses: redhat-actions/buildah-build@v2
with:
image: fizzbuzz
tags: latest ${{ github.sha }}
containerfiles: |
./Dockerfile
- name: Run the Docker image
run: podman run fizzbuzz
在運(yùn)行器上安裝 Podman 和 Buildah 工具后,每一次推送項(xiàng)目到 GitHub 后,我們終于可以在本地構(gòu)建容器并在兩個(gè)不同的操作系統(tǒng)上運(yùn)行。隨后還可以采取一些后續(xù)措施來(lái)進(jìn)行完善,比如:
在構(gòu)建前將項(xiàng)目源目錄安裝到容器中;
運(yùn)行一組“冒煙測(cè)試”驗(yàn)證最后一次提交未產(chǎn)生任何破壞;
構(gòu)建容器后自動(dòng)上傳到容器注冊(cè)表;
潛在地構(gòu)建一個(gè)跨硬件架構(gòu)容器。
不過,本文不會(huì)就構(gòu)建 CI pipeline 進(jìn)行介紹,我們將在今后的文章中針對(duì)基于 Ampere 處理器構(gòu)建持續(xù)集成和持續(xù)交付(CI/CD)系統(tǒng)進(jìn)行介紹。
非常感謝 Podman 社區(qū),GitHub 貢獻(xiàn)的大量操作文檔,以及來(lái)自 Twitter 的優(yōu)秀容器開發(fā)者對(duì)初學(xué)者問題的解答幫助。Ampere 持續(xù)挖掘開發(fā)社區(qū)的創(chuàng)造力,并將其與我們世界一流的處理器相結(jié)合。
審核編輯:湯梓紅
-
Linux
+關(guān)注
關(guān)注
87文章
11399瀏覽量
212034 -
容器
+關(guān)注
關(guān)注
0文章
503瀏覽量
22297 -
aarch64
+關(guān)注
關(guān)注
0文章
7瀏覽量
5175
原文標(biāo)題:創(chuàng)芯課堂 | 通過 Ampere? Altra? 和 GitHub Actions 構(gòu)建并測(cè)試 AArch64 容器
文章出處:【微信號(hào):AmpereComputing,微信公眾號(hào):安晟培半導(dǎo)體】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
誰(shuí)能提供下aarch64的工具呢
在ARMv8中aarch64與aarch32是怎樣進(jìn)行切換的
一文讀懂ARM AArch64 state的寄存器
如何在x86環(huán)境下基于Qemu和Docker快速搭建AARCH64開發(fā)環(huán)境
為什么aarch64和x86不像以前那樣支持條件執(zhí)行了呢
AArch64異常模型指南
AArch64自托管調(diào)試指南
AArch64外部調(diào)試詳解
Arm AArch64體系結(jié)構(gòu)的可擴(kuò)展矢量擴(kuò)展指南
在AArch64平臺(tái)上性能下降的例子
kvm_arm64資料下載
AArch64寄存器介紹
最新的Linux aarch64 LSA驅(qū)動(dòng)程序

探索aarch64架構(gòu)上使用ftrace的BPF LSM
第四章:在 PC 交叉編譯 aarch64 的 tensorflow 開發(fā)環(huán)境并測(cè)試

評(píng)論