在 ARM64 架構的 Unbuntu 18.04 容器上安裝與測試 .NET Core 3

這是我在一個 ARM64 架構、執行於 docker 容器的 Ubuntu 18.04 環境上安裝和測試 .NET Core 3.0 的過程。

作業環境

  • Ubuntu 18.04 (ARM64)
  • NET Core 3.0 preview 4 (適用 .NET 5)
  • Visual Studio 2019 RC
2020-6-2 更新:我用這篇筆記裡面的相同步驟和指令,也順利安裝了 .NET 5.0.100-preview.6.20301.7。

註:.NET Core 2.2 Runtime 並不支援 Linux ARM64 平台
Initial support for ARM64 was added in the .NET Core 2.1 release. The team is not maintaining .NET Core 2.x branches with respect to ARM64. All ARM64 improvements will be made in the .NET Core 3.0 branch (currently master).

安裝過程

首先,用下列指令安裝 wget 和 curl:

apt-get update
apt-get install wget
apt-get install curl

簡單解釋一下,我的 Unbuntu 是從 Docker Hub 下載下來的容器,裡面沒有預先安裝太多常用工具(基本上啥都沒有),所以先執行 apt-get update 來更新現有裝好的所有套件,然後再去下載安裝 wget 和 curl —— 兩者功能類似,都可以透過 HTTP 協定下載檔案。有些安裝說明文件會用到 wget,有些則使用 curl,故方便起見,兩個工具都先裝好。

接著參考這份文件:Installing .NET Core 3.0 on Linux ARM64,執行下列指令:

curl -SL -o dotnet.tar.gz https://dotnetcli.blob.core.windows.net/dotnet/Sdk/master/dotnet-sdk-latest-linux-arm64.tar.gz mkdir -p /usr/share/dotnet tar -zxf dotnet.tar.gz -C /usr/share/dotnet ln -s /usr/share/dotnet/dotnet /usr/bin/dotnet

安裝完成後,我並未立刻建立一個範例專案來測試,而是先執行 dotnet --version 指令。結果出現錯誤:



這個 ICU 套件找不到的錯誤,可用以下命令解決:

apt-get install libicu-dev

安裝完成後,再執行一次 dotnet --version,先前的錯誤便不再出現。這次順利顯示 .NET 版本為「3.0.100-preview4-010675」。

接著執行以下命令來試試看能否建立並執行一個簡單的 console 應用程式:

dotnet new console -o app
cd app
dotnet run

順利成功:


相依套件

按官方文件的說明,.NET Core 需要下列套件:
  • libc6
  • libgcc1
  • libgssapi-krb5-2
  • libicu60
  • liblttng-ust0
  • libssl1.0.0
  • libstdc++6
  • zlib1g

如果在開發和執行 .NET 應用程式時還有其他錯誤訊息,可以找找看錯誤訊息裡面有沒有上述套件的名稱,若有的話,安裝那個套件應該就能解決。比如說,在我的環境上曾出現找不到 libssl 的錯誤,那麼只要執行 apt-get install libssl1.0.0 即可解決。

從 Windows 建置並且部署至 Linux-arm64

接著,我嘗試在 Windows 10 環境上面,以 Visual Studio 2019 RC 來建立一個簡單的 console 應用程式,並測試幾種不同的部署選項。

(1) 使用 Visual Studio 2019 RC 產生部署檔案

我在 Visual Studio 2019 RC 中開啟專案的部署設定視窗,將目標執行環境設定為 "linux-arm",如下圖:


執行 Publish 之後,把所有產生的檔案上傳至我那個 ARM64 架構的、以 Docker 容器執行的 Ubuntu 作業環境,結果無法執行。錯誤訊息是:

Unhandled Exception: System.BadImageFormatException: Could not load file or assembly......

試著把上圖中的 Target Runtime 選項改為 "Portable",再執行 Publish,產生出來的檔案便可順利執行於 ARM64 的 Ubuntu 作業環境。

喔對了,上圖有個 Deployment Mode 選項,我是選擇 "Framework Dependent"(框架相依部署;簡稱 FDD),這表示部署打包的時候,並不會附加一堆 .NET Core Framework 檔案,故需要部署的檔案數量會比較少。當然,以此模式來部署時,目標作業環境上面必須事先安裝好 .NET Core 執行環境。

Deployment Mode 的另一個選項是 "Self-contained"(自封式部署;簡稱 SCD)。以此模式來部署時,會在輸出路徑下產生應用程式執行時所需要的所有 .NET Core Framework 相關檔案(至少上百個檔案)。這種部署模式的缺點是安裝包的體積較大,而好處是我們的應用程式一定能順利運行於目標作業環境,而不會受到目標環境上面的 .NET Core 版本所影響(目標環境沒裝 .NET Core 也行)。

(2) 使用命令列產生部署檔案

使用命令列來產生部署檔案時,我試了兩種命令。首先是沒有加任何參數的 dotnet publish
命令,它會在專案目錄的 bin/Debug/netcoreapp3.0/publish 目錄下產生部署所需的應用程式檔案(沒有 .NET Framework 檔案,即剛才提過的 Frameowork Dependent 部署模式)。
註:若想使用「自封式部署模式」(SCD),那麼前面的 dotnet publish 命令可加上參數 --self-contained。

接著再測試有加上 Runtime Identifier 的命令:

dotnet publish -r ubuntu.18.04-arm64

執行結果如下圖:


產生的部署檔案是放在專案目錄的 bin/Debug/netcoreapp3.0/ubuntu.18.04-arm64/publish 路徑下,裡面有應用程式跟上百個 .NET Framework 相關的檔案。如下圖:


無論 dotnet publish 有沒有加上 RID 參數,產生出來的檔案都可以順利部署和執行於 Ubuntu ARM64 環境上。


結語

由於不熟悉 ARM64 架構和 Linux 作業系統,看似簡單的安裝程序,還是花了我一些時間來排除問題。事後回頭來看,在 Ubuntu 上面安裝 .NET Core 3.0 其實還蠻簡單的啦,只是得先弄清楚目標環境是 x64 還是 ARM64 架構,才不至於裝錯版本。底下整理幾個安裝文件的連結:
另外,我也測試了幾種部署方式,包括以 Visual Studio 2019 RC 來產生部署檔案,以及使用 dotnet publish 命令(使用參數 -r 來指定 RID)。這個部分的重點是了解 Framework Dependent 與 Self-contained 部署模式的區別。

延伸閱讀

技術提供:Blogger.
回頂端⬆️