Docker(官網)這種比虛擬機器更輕量化的「容器」虛擬化技術,基本上算是這幾年來一個滿重要的技術。透過 Docker,他可以將需要的環境打包、建構出類似虛擬機器,但是更小、更彈性的可移植環境,在需要自動佈署的環境上,應該算是很實用的一種技術。(參考介紹、參考介紹)
不過由於工作的領域不同,所以 Heresy 其實之前都沒有去碰這一個技術;真的開始接觸到,是之前試著使用 Docker 來架設 GitLab Server 的時候開始的。
後來,Heresy 也很認真地開始搞整個 GitLab CI/CD 的架構,試著透過 GitLab 的系統來做一些程式開發的自動化建置、測試。最初,考慮到環境的熟系程度,Heresy 都是直接使用作業系統的 shell 來作為 gitlab-runner 的 executor。
而在整個弄到一定程度後,也發現如果能把 runner 的 executor 改成 Docker 的話,的確是有一定程度的幫助的!
怎麼說呢?如果 Runner 是用 shell 在跑的話,基本上就要先幫 runner 的系統安裝好必要的工具、函式庫等等東西。如果有好幾台 runner、就需要每一台都各自安裝成一樣的環境;而日後如果有要更新版本、或是新增套件的話,就需要每一台各自去做調整。
假設又碰到多個專案要共用同一組 runner,但是需要的套件卻有衝突的話,那就會非常麻煩了…
雖然透過虛擬機器的確可以解決這個問題,但是虛擬機器的映像檔其實也不小,要更新時也較為麻煩,所以管理上還是沒這麼方便。
這時候,Docker 就可以解決這個問題了!
透過 Docker,可以針對不同的專案建立需要的環境、而不會影響到系統、也不容易碰到版本衝突的問題;同時,Docker 的映像檔可以直接透過 Dockerfile 來產生,相對好控制、也可以進行版本控管。而透過 Docker registry 的機制,也可以讓 gitlab-runner 自己把需要的 docker image 下載下來、建立出需要的容器,更解決了更新和佈署的問題。
研究了一下、有了一點概念之後,Heresy 就投下去玩了。針對 Linux 的 Docker 環境的部分,基本上都還算玩得很順利,目前也已經把這邊的主要專案改成用 Docker 來建置了。
但是到了 Windows 環境的時候…恩,開始碰到一堆問題了。而最後,到了寫這篇文章的時候,這些問題也沒辦法完全解決,變成只能暫時放棄的狀態了。這篇文章,基本上就是一個簡單的問題紀錄了。
Windows Docker 映像檔的肥大
剛開始玩 Linux Docker 的時候,所使用的 base-image 是 ubuntu,檔案大小不到 70MB,安裝完必要的開發環境、函式庫後,容量到達了 3.8GB 左右、Heresy 就覺得已經大的有點誇張了。
而 Windows 呢?Windows 最單純的 base-image 基本上就已經是 5GB+ 的大小(官網、例如 servercore:1903 的大小就要 12.9GB…),感覺根本是把整個基礎 OS 都包起來了?而且在這肥大的映像檔的狀況下,Windows 容器還是有版本相容性的問題(參考),真的讓 Heresy 懷疑他包這麼多檔案的目的到底是什麼? = =
(這可能是因為 Windows 有使用所謂的「Hyper-V 容器」這樣的執行模式階段的關係)
這還是沒有安裝開發環境的狀況。如果要安裝 Build Tools for Visual Studio 來建置 Visual C++ 的專案的話,還需要使用包含 .Net Framework SDK 的基底影像,其容量更是往上跳了不少。
對於比較複雜、需要工具比較多的專案,整個映像檔要弄到能用,感覺可能接近 20GB 是跑不掉的了…(到時候還得改設定才行)
某方面來說,感覺也已經快要可以和 VM 的虛擬硬碟相比了。
難以處理的程式安裝
Windows 雖然有提供 batch(cmd)和 PowerShell 等 CLI(Command-Line Interface)環境,但是基本上還是一套以圖形介面為基礎的作業系統。
但是 Docker 本身並沒有辦法支援圖形介面,所有的操作都需要以 command line 的形式來進行。
這也導致了本來在 Windows 環境下、很方便就可以完成的安裝流程,在要安裝在 Docker 上的時候,有可能會碰到各式各樣的詭異狀況。
先不說別的,光是要能成功地建立出一個包含 Build Tools for Visual Studio 的 docker image 出來,就花了 Heresy 快要一個禮拜的時間…
雖然微軟官方有提供對應的 Dockerfile 的範例(參考、參考),但是在 Heresy 這邊卻是怎樣都沒辦法建置出一個可以用的 Docker image。
直接使用官方 vs-2017 的 Dockerfile 來建置的話,不管怎麼測試,Docker 內就是看不到 C:\BuildTools 這個應該要有開發工具的資料夾…更慘的是,這邊的安裝錯誤,連個錯誤訊息都不給…
後來是找到另一個範例(連結),才終於建置出一個可以用的版本(17.8GB)。
而這時,也才大概確定,Build Tools for Visual Studio 2017 大概只能搭配 mcr.microsoft.com/dotnet/framework/sdk:3.5-windowsservercore-1709 這個 base image 使用、而不能用更新版的 base-image。
雖然官方有說 Visual Studio 2017 version 15.8 以前的版本無法安裝於 1809 以後的版本,但是…現在 Visual Stduio 2017 不是已經更新到 15.9 了嗎?而且 Heresy 有試過用 1803 一樣不行啊…
老實說,這部分其實應該不能算是 Windows Docker 的問題,而是很多 Windows 程式的 installer 針對 CLI-only 的環境其實設計得並不好了…
至於其他程式(Qt、CUDA)的安裝?Heresy 還沒測試就先放棄了。
Windows Docker 的隔離模式
Windows Docker 有兩種隔離模式/運作模式(官網),一種是早期的 Hyper-V 模式,實際上就是透過小型的 Hyper-V 虛擬機器來跑。透過這樣的方式,Windows Docker 也可以在一定的程度上支援 Linux 容器,但是相對地會有一些效能、使用資源上的限制。
而從 Windows 1809 後,Windows Docker 就有支援和 Linux 一樣的 process 隔離了;在個人來看,這種模式應該才算是 Docker 最初設計的目的。
但是如果使用這種模式的話…舊版的 Windows base-image(像是現在被 VS2017 綁死的 1709…)基本上不能用,而同時也不能用 Linux 容器了。
GtLab Runner 支援度不佳
其實前面的問題大多都有解,或是可能有辦法解。但是最後讓 Heresy 放棄繼續研究下去的,是 Gitlab-Runner 本身的問題了…
當 Heresy 成功弄出第一個映像檔後,真的要掛到 GitLab-Runner 上跑的時候,就馬上碰到
ERROR: Preparation failed: could not determine windows version
的錯誤。
而查了一下,這個問題是因為 GitLab Runner 在使用 Docker 來執行的時候,針對 Windows 的支援,是針對不同版本寫死的(參考);而目前又只支援 1803 和 1809 兩個版本,所以在 Heresy 這邊主要的機器都已經升級到 1903 的情況下,就變得完全不能用了…
雖然官方看來是已經知道有這個問題了,不過看來要支援似乎還沒那麼快。而如果官方沒有想要設計一個可以跨版本的方法,那之後應該每次微軟推出大升級,都繪出一次問題了…
檔案存取的問題?
另外,之前在使用建置出來的容器想要用 bind mount(官方文件)的形式把專案拿到容器裡面建置,結果看起來似乎是以 symbolic link(SYMLINKD)的形式存在的,而在平行編譯的時候,會出現檔案存取的錯誤:
fatal error C1041: cannot open program database 'xxx.pdb'; if multiple CL.EXE write to the same .PDB file, please use /FS
這個問題除了去改專案設定還有沒有其他解法呢?恩,還不知道。
上面就是目前碰到的問題了。
而目前想到可能還可以玩的方法:
-
不要使用 Build Tools for Visual Studio 2017、而改用 2019 版,然後安裝 2017 的 toolset,看看能不能用新版的 base-image。
-
GitLab 的部分,繼續使用 shell 當作 executor、手動去執行 docker 的指令。
(元件參考)
之後…總之就再看看吧。
[…] 想不到有什麼簡短的標題,姑且就順著上次的《GitLab CI + Windows Docker 的一些紀錄》,把這篇當成 part 2 吧。 […]
讚讚
[…] Heresy 從去年年初開始玩 Gitlab CI/CD 一段時間後,就開始試著把建置環境移動到 Docker(官網)上。在 Linux 上的問題不算大,但是在 Windows 上卻常常碰到一些問題(參考一、參考二);前一陣子,甚至因為微軟自己的安全性更新,搞到整個不能用(參考)… […]
讚讚
Hi Heresy:
我用 windows:1809 + vs_buildtools: vs2015/vs2017 + gitlab-runner-helper 是可以跑起來的 給你參考
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Dockerfile.vs2017
hosted with ❤ by GitHub
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
install-gitlab-ci-runner.ps1
hosted with ❤ by GitHub
讚讚
感謝。不過目前應該還是不能在 1903 的系統跑,所以已經放棄了。
(更何況系統都更新到 1909 了)
讚讚
[…] 這篇算是《GitLab CI + Windows Docker 的一些紀錄》的延伸。由於 Heresy 這邊的開發專案有用到 Qt SDK(官網),所以在建置用的 Docker 容器裡面,也需要安裝 Qt 的 SDK。 […]
讚讚
[…] 前一篇《GitLab CI + Windows Docker 的一些紀錄》的時候,Heresy 已經大概有說明最近在玩 GitLab CI/CD,並試著拿 Docker 來做 Runner 時、在 Windows 平台上碰到的一些狀況了。 […]
讚讚