在這一系列文章的第一篇中,咱們分享了只用Docker時咱們開發的初步的工做流,如何建立一個基礎的構建和部署流水線。容器的部署方式再也不是在登錄server的時候從內存中輸入Docker命令。咱們已經經過Jenkins server實現了鏡像的自動化構建。咱們使用腳本將Docker命令進行封裝,將其存儲到GitHub中而且設置版本。目前咱們正採起措施,經過逐步改善現有過程來實現持續部署。然而,仍有一些痛點須要咱們去解決。在這篇文章中,咱們將看看如何使用Docker Compose 和 Ansible來改善此設計。java
在部署鏡像時,工程師須要登陸到服務器,並從shell運行咱們的Docker wrapper腳本。這不是很好的解決方法,由於它也須要開發者進行等待。沒有任何一方會從在這種方式中獲益(做爲一個工程師,當你去作某件你很瞭解而且很容易自動化的事情時,你有多少次被打斷了?)因爲每一次部署都是經過操做者電腦中的SSH會話來執行的,所以部署過程是不可見的。git
若是你對咱們的部署腳本還有印象,你會發現它看起來像下面的代碼段:docker
實際上,咱們作的是將Docker run命令語句進行抽象,由此工程師將不須要知道每一個圖像成功運行時所須要的確切的參數。雖然這改善了必須所有記住而且手動輸入全部Docker參數的現狀,但同時也會帶來新的問題:shell
在咱們的工做流中,Docker Compose是一個更適合使用的工具,它一樣能夠將部署參數進行編碼,而且在YAML文件中指定,此文件就是docker-compose.yml。Docker Compose不只幫助咱們解決了上面提到的難點,並且也可使咱們從社區將來的工做中獲益。下面讓咱們理清部署腳本,而且爲咱們的JAVA程序示例建立一個Compose文件。首先,咱們須要基於原來的部署邏輯建立一個docker-compose.yml文件:安全
如今,部署容器只須要在與docker-compose.yml文件相同目錄下輸入如下命令:服務器
docker-compose up
它將根據compose文件中設置的參數啓動一個容器。在compose文件中一個重要的變量是${VERSION} 。Docker Compose能夠從當前的shell環境中插入compose文件裏所列出的參數。咱們能夠經過簡單地運行如下語句來設置參數:微信
VERSION=1.0.0 docker-compose up
它將從咱們的私有鏡像倉庫挑出標記1.0.0的鏡像,以此啓動java-service-1程序。若是沒有設置VERSION變量,Docker Compose將產生一條警告信息,而且用空字符串代替變量值,由此,具備最新版本標籤的鏡像將會被挑出。所以,正確地設置變量是至關重要的。網絡
做爲開發過程的一部分,咱們但願開發人員可以在本地創建服務而且測試他們的服務。然而,因爲docker-compose.yml指向私有鏡像倉庫的鏡像,運行docker-compose將從最近構建的鏡像中開啓服務而不是從本地資源中開啓。理想狀況下,開發者能夠經過運行如下代碼使用典型的docker-compose工做流:app
Docker Compose能在不修改docker-compose.yml文件的狀況下,讓咱們作到這一點。咱們可使用多個文件來覆蓋咱們在本地測試中想要改變的任何參數。在docker-compose.override.yml中,咱們指定一個key而不是一個鏡像,而且移除了對VERSION變量的需求。因爲這是一個覆蓋文件,咱們不須要複製任何額外的設置,如端口設置:less
使用Docker Compose而非部署腳本以後,咱們能夠:
如今咱們有了java-service-1程序的compose文件,咱們能夠將它從咱們的部署腳本中刪除,所以文件組織與下面的結構相似:
此時,咱們仍然沒有解決鏡像構建和部署之間的問題。在docker-compose.yml文件中包含了全部的部署邏輯,可是它如何在環境中運行直至結束的呢?正好如今咱們在運行與UNIX和TPC socket相關的Docker守護進程,是時候討論一些與安全有關的問題了。
咱們的狀況是,工程師登陸到服務器上,手動運行每一個服務器所需容器的部署腳本。默認狀況下,當在局部運行Docker命令時,它將使用UNIX socket /var/run/docker.sock鏈接Docker守護進程;或者讓守護進程監聽TCP socket,這容許用戶遠程鏈接到每一個Docker守護進程,使得工程師可以像登陸到主機同樣運行命令。這爲鏈接方式提供了更大的靈活性,可是沒有考慮到一些開銷和安全問題:
另外一種可能的方法是不使用基於UNIX socket的方式運行Docker守護進程,而使用SSH來運行命令。已經創建的ACLs將保護SSH端口,而且它只容許經過SSH受權的特定的用戶才能使用Docker守護進程。雖然這不是最簡潔的方法,可是它有助於保持較低的運行開銷,而且使安全隱患降到最低。這點是很是重要的,尤爲是對於細粒度的稀疏的任務隊列而言。
爲了有利於經過SSH運行Docker命令,咱們可使用Ansible——一個流行的編排和配置管理工具。它是無代理的,而且容許經過SSH鏈接運行「劇本」(服務器任務集合)。一個運行docker-compose命令的簡單的劇本以下所示:
若是你對Ansible沒有過多瞭解,你也許能夠經過上面的劇本大體瞭解到咱們想作什麼。它們按順序一步步執行,具體以下所示:
一個shell腳本能夠被運用在同一個事件中。然而在Ansible中,咱們將很容易的使任務並行化而且獲得通過良好測試的模塊,經過使Ansible與新的部署劇本相結合,咱們能夠遠程啓動容器,相較於工程師登陸到主機、人工運行命令,這是一個重要的進步。爲了在部署過程和狀態中提供更大的可視性,咱們將創建Jenkins任務來運行Ansible代碼。經過使用Jenkins,在將來咱們能夠輕鬆地將構建和部署任務集成起來,從而獲得額外的好處。
Jenkins任務須要兩個參數:目標主機(傳遞給劇本中的DESTINATION變量)和部署鏡像的版本(在docker-compose.yml文件中插入VERSION變量)。大多數任務的構建部分是一個shell構建器,它將試圖找到程序中的docker-compose.yml文件,而後經過傳遞變量(用-e)到劇本中,運行ansible-playbook命令:
雖然看起來咱們彷佛只對工做流作了微小的變化,可是咱們正一步一步地向構建一個持續部署模型邁進:
雖然這些改進解決了某些問題,可是它們所帶來的新的問題也成爲了焦點:
在這一系列接下來的文章中,咱們將探討怎樣運行Rancher以及使用它的緣由,尤爲是它如何解決上述的問題。與此同時,咱們也討論它在業務和開發團隊中所起到的意想不到的橋樑做用。
歡迎關注Rancher官方微信公衆號(RancherLabs),獲取第一手技術乾貨推送;歡迎添加客服微信(RancherLabsChina)爲好友,加入Rancher官方技術交流羣,獲取免費技術支持,與數千Docker/Rancher使用者互動。
9月27日,北京海航萬豪酒店,容器技術大會Container Day 2017即將舉行。
CloudStack之父、海航科技技術總監、華爲PaaS部門部長、恆豐銀行科技部總經理、阿里雲PaaS工程總監、民生保險CIO······均已加入豪華講師套餐!
11家已容器落地企業,15位真·雲計算大咖,13場純·技術演講,結合實戰場景,聚焦落地經驗。免費參會+超高規格,詳細議程及註冊連接請戳