Linux中國

用 Ansible Container 去管理 Linux 容器

Image by : opensource.com

我喜歡容器,並且每天都使用這個技術。即便如此,容器並不完美。不過,在過去幾個月里,一系列項目已經解決了我遇到的一些問題。

我剛開始時,用 Docker 使用容器,這個項目使得這種技術非常流行。除了使用這個容器引擎之外,我學到了怎麼去使用 docker-compose 以及怎麼去用它管理我的項目。使用它使得我的生產力猛增!一個命令就可以運行我的項目,而不管它有多複雜。因此,我太高興了。

使用一段時間之後,我發現了一些問題。最明顯的問題是創建容器鏡像的過程。Docker 工具使用一個定製的文件格式作為生成容器鏡像的依據:Dockerfile。這個格式易於學習,並且很短的一段時間之後,你就可以自己製作容器鏡像了。但是,一旦你希望進一步掌握它或者考慮到複雜場景,問題就會出現。

讓我們打斷一下,先去了解一個不同的東西:Ansible 的世界。你知道它嗎?它棒極了,是嗎?你不這麼認為?好吧,是時候去學習一些新事物了。Ansible 是一個允許你通過寫一些任務去管理你的基礎設施,並在你選擇的環境中運行它們的項目。不需要去安裝和設置任何的服務;你可以從你的筆記本電腦中很容易地做任何事情。許多人已經接受 Ansible 了。

想像一下這樣的場景:你在 Ansible 中,你寫了很多的 Ansible 角色 role 劇本 playbook ,你可以用它們去管理你的基礎設施,並且你想把它們運用到容器中。你應該怎麼做?通過 shell 腳本和 Dockerfile 去寫容器鏡像定義?聽起來好像不對。

來自 Ansible 開發團隊的一些人問到這個問題,並且他們意識到,人們每天編寫和使用的那些同樣的 Ansible 角色和劇本也可以用來製作容器鏡像。但是 Ansible 能做到的不止這些 —— 它可以被用於去管理容器化項目的完整生命周期。從這些想法中,Ansible Container 項目誕生了。它利用已有的 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 官方鏡像 中拿來的一段。它看起來並不好看,是不是?

2、 解析 Dockerfile 並不容易

Dockerfile 是一個沒有正式規範的新格式。如果你需要在你的基礎設施(比如,讓構建過程自動化一點)中去處理 Dockerfile 將會很複雜。僅有的規範是 這個代碼,它是 dockerd 的一部分。問題是你不能使用它作為一個 library 來使用。最容易的解決方案是你自己寫一個解析器,然後祈禱它運行的很好。使用一些眾所周知的標記語言不是更好嗎?比如,YAML 或者 JSON。

3、 管理困難

如果你熟悉容器鏡像的內部結構,你可能知道每個鏡像是由 layer 構成的。一旦容器被創建,這些層就使用聯合文件系統技術堆疊在一起(像煎餅一樣)。問題是,你並不能顯式地管理這些層 — 你不能說,「這兒開始一個新層」,你被迫使用一種可讀性不好的方法去改變你的 Dockerfile。最大的問題是,必須遵循一套最佳實踐以去達到最優結果 — 新來的人在這個地方可能很困難。

Ansible 語言和 Dockerfile 比較

相比 Ansible,Dockerfile 的最大缺點,也是 Ansible 的優點,作為一個語言,Ansible 更強大。例如,Dockerfile 沒有直接的變數概念,而 Ansible 有一個完整的模板系統(變數只是它其中的一個特性)。Ansible 包含了很多更易於使用的模塊,比如,wait_for,它可以被用於服務就緒檢查,比如,在處理之前等待服務準備就緒。在 Dockerfile 中,做任何事情都通過一個 shell 腳本。因此,如果你想去找出已準備好的服務,它必須使用 shell(或者獨立安裝)去做。使用 shell 腳本的其它問題是,它會變得很複雜,維護成為一種負擔。很多人已經發現了這個問題,並將這些 shell 腳本轉到 Ansible。

關於作者

Tomas Tomecek - 工程師、Hacker、演講者、Tinker、Red Hatter。喜歡容器、linux、開源軟體、python 3、rust、zsh、tmux。More about me

via: https://opensource.com/article/17/10/dockerfiles-ansible-container

作者:Tomas Tomecek 譯者:qhwdw 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出


本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive

對這篇文章感覺如何?

太棒了
0
不錯
0
愛死了
0
不太好
0
感覺很糟
0
雨落清風。心向陽

    You may also like

    Leave a reply

    您的電子郵箱地址不會被公開。 必填項已用 * 標註

    此站點使用Akismet來減少垃圾評論。了解我們如何處理您的評論數據

    More in:Linux中國