最近我發(fā)現(xiàn)有個趨勢哈,就是ARM server越來越多,但是ARM好像不像x64平臺那么好識別,總是有各種各樣的arm識別不了。如果SRS能出ARM的docker鏡像,那會比較容易跑起來。
SRS已經支持了多CPU架構的docker鏡像,如下圖所示:
下面是用法和技術背景。
Usage
現(xiàn)在SRS支持了多個CPU架構,參考ossrs/srs:
-
linux/amd64
這就是x86_64架構,Intel的64位服務器,目前主要的Linux服務器都是這種類型,無論任何操作系統(tǒng)只要是這個芯片都可以用這個鏡像。蘋果Mac Intel芯片也是可以用這個鏡像。 -
linux/arm/v7
這是armv7也就是32位架構,比如RaspberryPI就是這種服務器,如果你要在PI上使用SRS,可以用這個鏡像。我沒有硬件驗證,所以歡迎大家測試反饋。 -
linux/arm64/v8
這就是armv8也就是64位架構,目前一般的ARM云服務器都是這種架構,無論任何操作系統(tǒng)都可以用這個鏡像。蘋果Mac M1芯片,應該是可以用這個鏡像的,我沒有硬件所以歡迎大家測試反饋。
Note: 國內可以用阿里云鏡像registry.cn-hangzhou.aliyuncs.com/ossrs/srs,注意沒有顯示多CPU架構,但也是支持的。
具體用法和之前是一樣的,docker會根據機器的CPU架構,選擇合適的鏡像執(zhí)行。所以用法沒有變更,舉一個簡單例子:
docker run --rm -it -p 1935:1935 -p 1985:1985 -p 8080:8080 \
ossrs/srs:4 ./objs/srs -c conf/docker.conf
國內可以用阿里云鏡像,比如:
docker run --rm -it -p 1935:1935 -p 1985:1985 -p 8080:8080 \
registry.cn-hangzhou.aliyuncs.com/ossrs/srs:4 ./objs/srs -c conf/docker.conf
更多的例子可以參考Wiki:
下面是支持多CPU架構的鏡像的其他背景,若你需要修改代碼了自己打鏡像,或者需要支持其他CPU架構,可以參考下面的資料支持。
Note: 除了SRS鏡像,SRS的開發(fā)鏡像中,CentOS 7和Ubuntu 20支持了多CPU架構,注意CentOS不支持
linux/arm/v7
詳細請參考本文后面的詳細描述。
Verify
如果需要驗證arm/v7架構,可以選擇RaspberryPI。目前云主機都是arm64/v8的架構。
實際上SRS可以支持多種CPU,比如x86_64、arm、aarch64、mips、loongarch等,具體請參考ST:適配,但是要支持這些CPU的docker鏡像需要再單獨適配。
可以選擇云主機驗證ARM的docker,騰訊云ARM,阿里云ARM,華為云鯤鵬,AWS ARM。
執(zhí)行命令,查看機器的CPU架構:
# uname -p
aarch64
啟動docker,查看容器中的CPU架構:
docker run -it --rm ossrs/srs:ubuntu20 uname -p
aarch64
docker run -it --rm registry.cn-hangzhou.aliyuncs.com/ossrs/srs:ubuntu20 uname -p
aarch64
開發(fā)鏡像驗證完成。我們驗證下SRS的鏡像,在一臺ARM云主機上,CPU架構是aarch64
也就是linux/arm64/v8
,執(zhí)行命令:
docker run --rm -it registry.cn-hangzhou.aliyuncs.com/ossrs/srs:v4 ldd objs/srs
libdl.so.2 => /lib/aarch64-linux-gnu/libdl.so.2 (0x0000ffff97240000)
libpthread.so.0 => /lib/aarch64-linux-gnu/libpthread.so.0 (0x0000ffff97200000)
libstdc++.so.6 => /lib/aarch64-linux-gnu/libstdc++.so.6 (0x0000ffff97010000)
libm.so.6 => /lib/aarch64-linux-gnu/libm.so.6 (0x0000ffff96f60000)
libgcc_s.so.1 => /lib/aarch64-linux-gnu/libgcc_s.so.1 (0x0000ffff96f30000)
libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000ffff96db0000)
/lib/ld-linux-aarch64.so.1 (0x0000ffff97c10000)
可以看到docker正確下載了aarch64
架構的鏡像,驗證完成。
SRS Image
若你需要自己打SRS的多CPU架構鏡像,可以詳細看這一節(jié)的內容。
Note: 由于基礎開發(fā)鏡像ossrs/srs:ubuntu20支持多CPU架構后,SRS鏡像的編譯就比較簡單,只需要從
ossrs/srs:dev
修改成ossrs/srs:ubuntu20
,同時從CentOS切換到Ubuntu安裝命令要修改;發(fā)布的鏡像,從CentOS改成Ubuntu,詳細修改請參考Commit:xxxx
操作起來很簡單,可以調用命令打包就行:
docker buildx create --name mybuilder --driver docker-container
docker buildx use mybuilder
cd ~/git/srs
docker buildx build --platform linux/arm/v7,linux/arm64/v8,linux/amd64 \
--output "type=image,push=true" --progress plain --build-arg JOBS=10 \
--tag your-repository/ossrs/srs:4 -f trunk/Dockerfile .
Note: 記得修改
--tag
為你的倉庫的鏡像就可以。
Multiple CPU Image
之前SRS的docker實際上只支持了x86_64架構,所以在ARM和其他CPU上是沒法跑的,參考SRS。其實鏡像是可以支持多個架構的,參考手動打多CPU架構鏡像。
為了了解docker的多CPU架構鏡像,我們先嘗試一個簡單的鏡像,沒有任何依賴。
首先,新建一個Dockerfile,它的FROM是帶ARCH前綴:
ARG ARCH
FROM ${ARCH}debian:buster-slim
RUN apt-get update \
&& apt-get install -y curl \
&& rm -rf /var/lib/apt/lists/*
ENTRYPOINT [ "curl" ]
若在Mac下,需要創(chuàng)建一個builder,例如:
docker buildx create --name mybuilder --driver docker-container
docker buildx use mybuilder
然后,使用docker buildx編譯鏡像:
docker buildx build --push --platform linux/arm/v7,linux/arm64/v8,linux/amd64 \
-t ossrs/srs:multiarch-example .
若需要上傳到其他registry比如阿里云,可以再運行一次,docker有緩存:
docker buildx build --push --platform linux/arm/v7,linux/arm64/v8,linux/amd64 \
-t registry.cn-hangzhou.aliyuncs.com/ossrs/srs:multiarch-example .
這樣就打包并上傳了一個多CPU架構的鏡像:
# docker manifest inspect ossrs/srs:multiarch-example
{
"manifests": [
{ "platform": { "architecture": "arm", "variant": "v7" } },
{ "platform": { "architecture": "arm64", } },
{ "platform": { "architecture": "amd64", } }
]
}
可以在docker hub上看到這個鏡像,包含多個CPU架構。
GitHub Actions
SRS是使用GitHub Actions自動打鏡像,并上傳到Docker和Aliyun的鏡像倉庫。
在.github/workflows/release.yml
中,需要加一個步驟,安裝buildx:
# See https://github.com/crazy-max/ghaction-docker-buildx#moved-to-docker-organization
# https://github.com/docker/setup-qemu-action
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
# https://github.com/docker/setup-buildx-action
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
Note: 注意最新的是用的qemu和官方docker的actions,很多文檔還是老的。
Multiple Repositories
多CPU架構的鏡像,不能使用一般的方式直接推送多倉庫,需要使用一個獨立的action。
在.github/workflows/release.yml
中,需要加一個步驟,推送多個倉庫:
- name: Login aliyun hub
uses: docker/login-action@v1
with:
registry: registry.cn-hangzhou.aliyuncs.com
username: "${{ secrets.ACR_USERNAME }}"
password: "${{ secrets.ACR_PASSWORD }}"
- name: Push to Aliyun registry
uses: akhilerm/tag-push-action@v2.0.0
with:
src: ossrs/srs:${{ env.SRS_TAG }}
dst: |
registry.cn-hangzhou.aliyuncs.com/ossrs/srs:${{ env.SRS_TAG }}
Note: 由于buildx涉及到了manifest,所以不能直接用docker tag和docker push。
ARG
參數ARCH只能在FROM中用,還可以根據目標平臺在FROM之后做判斷:
ARG ARCH
FROM ${ARCH}centos:7 as build
ARG BUILDPLATFORM
ARG TARGETPLATFORM
RUN echo "BUILDPLATFORM: $BUILDPLATFORM, TARGETPLATFORM: $TARGETPLATFORM"
Note: 注意ARCH在FROM之前申明,只能在FROM中使用。
Issues
CentOS7的鏡像,無法支持linux/arm/v7
,會出現(xiàn)錯誤:
ARG ARCH
FROM ${ARCH}centos:7
RUN yum install -y curl
ENTRYPOINT [ "curl" ]
執(zhí)行命令:
docker buildx build --platform linux/arm/v7 .
出現(xiàn)錯誤,并一直卡死:
[+] Building 29.0s (5/6)
=> [2/2] RUN yum install -y curl 25.7s
=> => # qemu: uncaught target signal 11 (Segmentation fault) - core dumped
Note: 換成CentOS8也不支持armv7。
換成Ubuntu20就沒有問題:
ARG ARCH
# http://releases.ubuntu.com/focal/
FROM ${ARCH}ubuntu:focal
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update && apt-get install -y curl
ENTRYPOINT [ "curl" ]
三個平臺都能編譯:
docker buildx build --platform linux/arm/v7,linux/arm64/v8,linux/amd64 .
所以SRS準備切換成Ubuntu20的基礎開發(fā)鏡像。
Debug Building SRT
編譯某個平臺比如linux/arm/v7
的SRT,先對代碼打包:
cd ~/git/srs
tar cf srs.tar trunk
然后修改trunk/Dockerfile
,直接編譯SRT:
ARG ARCH
FROM ${ARCH}ossrs/srs:ubuntu20 AS build
ARG BUILDPLATFORM
ARG TARGETPLATFORM
RUN echo "BUILDPLATFORM: $BUILDPLATFORM, TARGETPLATFORM: $TARGETPLATFORM"
# https://serverfault.com/questions/949991/how-to-install-tzdata-on-a-ubuntu-docker-image
ENV DEBIAN_FRONTEND noninteractive
# Install depends tools.
RUN apt-get update && apt-get install -y gcc make g++ patch unzip perl git
ARG SRS_AUTO_PACKAGER
############ TEST
ADD srs.tar /srs
WORKDIR /srs/trunk/3rdparty/srt-1-fit
RUN apt-get install -y libssl-dev
RUN ./configure --disable-app --enable-static --enable-c++11=0 --enable-shared=0
RUN echo "CMakeOutput.log" && cat /srs/trunk/3rdparty/srt-1-fit/CMakeFiles/CMakeOutput.log
RUN echo "CMakeError.log" && cat /srs/trunk/3rdparty/srt-1-fit/CMakeFiles/CMakeError.log
RUN exit 1
執(zhí)行命令:
docker buildx create --name mybuilder --driver docker-container
docker buildx use mybuilder
cd ~/git/srs && docker buildx build --platform linux/arm/v7 -f trunk/Dockerfile --progress=plain .
這樣相當于直接編譯SRT,調試周期很短。