作者 | Tomas Tomecek
譯者 | qhwdw
Ansible Container 解決了 Dockerfile 的不足,並對容器化專案提供了完整的管理。
Image by : opensource.com
我喜歡容器,並且每天都使用這個技術。即便如此,容器並不完美。不過,在過去幾個月裡,一系列專案已經解決了我遇到的一些問題。
我剛開始時,用 Docker[1] 使用容器,這個專案使得這種技術非常流行。除了使用這個容器引擎之外,我學到了怎麼去使用 docker-compose[2] 以及怎麼去用它管理我的專案。使用它使得我的生產力猛增!一個命令就可以執行我的專案,而不管它有多複雜。因此,我太高興了。
使用一段時間之後,我發現了一些問題。最明顯的問題是建立容器映象的過程。Docker 工具使用一個定製的檔案格式作為生成容器映象的依據:Dockerfile。這個格式易於學習,並且很短的一段時間之後,你就可以自己製作容器映象了。但是,一旦你希望進一步掌握它或者考慮到複雜場景,問題就會出現。
讓我們打斷一下,先去瞭解一個不同的東西:Ansible[3] 的世界。你知道它嗎?它棒極了,是嗎?你不這麼認為?好吧,是時候去學習一些新事物了。Ansible 是一個允許你透過寫一些任務去管理你的基礎設施,併在你選擇的環境中執行它們的專案。不需要去安裝和設定任何的服務;你可以從你的膝上型電腦中很容易地做任何事情。許多人已經接受 Ansible 了。
想像一下這樣的場景:你在 Ansible 中,你寫了很多的 Ansible 角色和劇本,你可以用它們去管理你的基礎設施,並且你想把它們運用到容器中。你應該怎麼做?透過 shell 指令碼和 Dockerfile 去寫容器映象定義?聽起來好像不對。
來自 Ansible 開發團隊的一些人問到這個問題,並且他們意識到,人們每天編寫和使用的那些同樣的 Ansible 角色和劇本也可以用來製作容器映象。但是 Ansible 能做到的不止這些 —— 它可以被用於去管理容器化專案的完整生命週期。從這些想法中,Ansible Container[4] 專案誕生了。它利用已有的 Ansible 角色轉變成容器映象,甚至還可以被用於生產環境中從構建到部署的完整生命週期。
現在讓我們討論一下,我之前提到過的在 Dockerfile 環境中的最佳實踐問題。這裡有一個警告:這將是非常具體且技術性的。出現最多的三個問題有:
1、 在 Dockerfile 中內嵌的 Shell 指令碼
當寫 Dockerfile 時,你可以指定會由 /bin/sh -c
解釋執行的指令碼。它類似如下:
RUN dnf install -y nginx
這裡 RUN
是一個 Dockerfile 指令,其它的都是引數(它們傳遞給 shell)。但是,想像一個更複雜的場景:
RUN set -eux; \
\
# this "case" statement is generated via "update.sh"
%%ARCH-CASE%%; \
\
url="https://golang.org/dl/go${GOLANG_VERSION}.${goRelArch}.tar.gz"; \
wget -O go.tgz "$url"; \
echo "${goRelSha256} *go.tgz" | sha256sum -c -; \
這僅是從 golang 官方映象[5] 中拿來的一段。它看起來並不好看,是不是?
2、 解析 Dockerfile 並不容易
Dockerfile 是一個沒有正式規範的新格式。如果你需要在你的基礎設施(比如,讓構建過程自動化一點)中去處理 Dockerfile 將會很複雜。僅有的規範是 這個程式碼[6],它是 dockerd 的一部分。問題是你不能使用它作為一個庫來使用。最容易的解決方案是你自己寫一個解析器,然後祈禱它執行的很好。使用一些眾所周知的標記語言不是更好嗎?比如,YAML 或者 JSON。
3、 管理困難
如果你熟悉容器映象的內部結構,你可能知道每個映象是由層構成的。一旦容器被建立,這些層就使用聯合檔案系統技術堆疊在一起(像煎餅一樣)。問題是,你並不能顯式地管理這些層 — 你不能說,“這兒開始一個新層”,你被迫使用一種可讀性不好的方法去改變你的 Dockerfile。最大的問題是,必須遵循一套最佳實踐以去達到最優結果 — 新來的人在這個地方可能很困難。
Ansible 語言和 Dockerfile 比較
相比 Ansible,Dockerfile 的最大缺點,也是 Ansible 的優點,作為一個語言,Ansible 更強大。例如,Dockerfile 沒有直接的變數概念,而 Ansible 有一個完整的模板系統(變數只是它其中的一個特性)。Ansible 包含了很多更易於使用的模組,比如,wait_for[7],它可以被用於服務就緒檢查,比如,在處理之前等待服務準備就緒。在 Dockerfile 中,做任何事情都透過一個 shell 指令碼。因此,如果你想去找出已準備好的服務,它必須使用 shell(或者獨立安裝)去做。使用 shell 指令碼的其它問題是,它會變得很複雜,維護成為一種負擔。很多人已經發現了這個問題,並將這些 shell 指令碼轉到 Ansible。
關於作者
Tomas Tomecek – 工程師、Hacker、演講者、Tinker、Red Hatter。喜歡容器、linux、開源軟體、python 3、rust、zsh、tmux。More about me[8]
via: https://opensource.com/article/17/10/dockerfiles-ansible-container
作者:Tomas Tomecek[8] 譯者:qhwdw 校對:wxy
本文由 LCTT 原創編譯,Linux中國 榮譽推出