如何使用Docker、Docker-Compose和Rancher搭建部署Pipeline(三)

在這一部分,咱們將一步步的走進Rancher,細緻的探討Rancher將如何解決在部署與容器管理時出現的種種的問題。回顧教程的第二部分,你會發現咱們已經將應用的部署遷移至Docker Compose,而且已經創建了一系列工做步驟來部署咱們的應用。這將使得開發人員可以輕鬆的對他們的應用部署邏輯進行修正,運維人員也能夠查看應用的部署時間。固然,在上一個部分教程的一系列操做中,也存在一些顯而易見的問題須要解決。java

使用Docker-Compose時面臨的挑戰

首先,運維人員必須手動地調整全部服務的執行計劃。部署人員須要決定將哪個應用部署至哪一臺主機,這意味着部署人員須要時刻對每一臺主機的剩餘可用資源都有了解,若是某一臺主機或者容器崩潰了,部署的操做人員將須要對應用進行從新部署。實際生產中,這意味着主機經常處於負載失衡的狀態,而且服務在崩潰以後須要很長時間才能獲得恢復。python

其次,使用Docker-Compose時,想要得到你的服務的當前狀態是十分困難的。舉個例子來講,咱們常常會從運維人員、項目經理以及開發者口中聽到這樣的問題:「如今部署環境中運行的究竟是XX應用程序的哪一個版本?」若是咱們採用的是手動調整服務的執行計劃的方式,想要獲得這個問題的答案一般須要詢問指定的進行操做的工程師,工程師們須要登錄服務器並運行docker中的ps命令來查看容器的信息。然而面對這些問題,Rancher將會給咱們提供極大的便利:每一個人均可以很是容易地獲取已經部署的服務的信息,而不須要臨時請求運維人員的幫助。git

使用Rancher以前,咱們試着瞭解過很多其餘可以管理Docker主機或集羣的解決方案。然而這些解決方案都沒有注意到這是對Docker主機或集羣在多種環境(multi-environment)下的管理,這將成爲最大的麻煩與負擔之一。若是有服務以不一樣的負載運行在8種不一樣的環境下,咱們須要的是一個統一的方式來管理集羣,而不會想要訪問8個不一樣的服務。而且,咱們但願讓從新構建環境對於咱們而言,變成分分鐘就能完成的任務,這樣開發者就能夠隨意地更改開發環境。然而,對於生產環境而言,咱們但願提供給他們的只是有限的只讀訪問權限。面對這樣的需求,一個採用基於角色的訪問控制(RBAC)模型的集中管理方案就顯得十分必要了。咱們最初決定嘗試Rancher就是由於它在部署上很是簡單。github

當Rancher面臨這些挑戰

在短短半天的時間裏,使用AWS ELB、Elasticache、RDS和現有的Docker主機,咱們已經將Rancher部署好併成功運行。可以方便地配置認證信息也是Rancher的優勢之一docker

咱們並不會深刻Rancher自己部署的細節,Rancher部署文檔中已經說的很明白了。相反,咱們將從剛剛完成初始設置那一步開始,說明將如何將原有的設置(教程第一部分第二部分中所說起的)遷移進來。shell

咱們就從建立不一樣的環境開始吧,爲了使得這個過程儘可能簡單些,咱們將對開發環境(dev)、部署環境(stage)以及生產環境(prod)分別進行設置。每一個環境都已有運行在Ubuntu之上的Docker主機,且這些Docker主機是由內部的Ansible配置的,Ansible安裝了Docker、咱們的監控代理、並進行了一些組織特定的更改。在Rancher上,你只須要運行一條命令,將Docker主機在Rancher server內部進行註冊,就能夠將已有的Docker主機添加至每一個環境中。json

添加一臺Rancher主機

在大多數狀況下,想要添加一臺主機須要通過一系列的操做:經過鼠標在網頁上完成一些點擊,接下來切換至某個特定的環境,最後在終端系統上輸入命令。然而,若是你使用Rancher API,咱們能夠在Ansible工具的幫助下使得這一系列的操做轉化爲徹底自動化的設置。出於好奇,在下面咱們截取了playbook中有關這一操做的部份內容(大可能是根據 Hussein Galas的repo中的內容作出的邏輯上的修改而獲得的)。後端

name: install dependencies for uri module
  apt: name=python-httplib2 update_cache=yes
name: check if the rancher-agent is running
  command: docker ps –filter ‘name=rancher-agent’
  register: containers
name: get registration command from rancher
  uri:
    method: GET
    user: 「{{ RANCHER_API_KEY }}」
    password: 「{{ RANCHER_SECRET_KEY }}」
    force_basic_auth: yes
    status_code: 200
    url: 「https://rancher.abc.net/v1/projects/{{ RANCHER_PROJECT_ID }}/registrationtokens」
    return_content: yes
    validate_certs: yes
  register: rancher_token_url
  when: 「‘rancher-agent’ not in containers.stdout」
name: register the host machine with rancher
  shell: >
    docker run -d –privileged
    -v /var/run/docker.sock:/var/run/docker.sock
    {{ rancher_token_url.json[‘data’][0][‘image’] }}
    {{ rancher_token_url.json[‘data’][0][‘command’].split() | last}}
  when: 「‘rancher-agent’ not in containers.stdout」

隨着工做的一步步進行,咱們已經完成了環境的建立並已經將主機在Rancher server中註冊,如今就讓咱們來了解一下,如何將咱們的部署工做流整合至Rancher中。咱們知道,對於每一臺Docker來講,其中都有着一些正在運行的容器,這些系統的部署是經過Ansible工具藉助Jenkins完成的。Rancher提供瞭如下開箱即用的功能:服務器

  • 管理已有的容器(好比:啓動、修改、查看日誌、啓動一個交互式的shell)
  • 得到關於運行中的和中止運行的容器的信息(好比:鏡像信息、初始化命令信息、命令信息,端口映射信息以及環境變量信息)
  • 查看主機和容器層級上的資源使用狀況(好比:CPU使用率、內存佔用率、以及磁盤和網絡的使用狀況)

獨立的容器微信

很快,咱們就已經將Docker主機註冊至Rancher Server中,如今咱們能夠查看容器在各類環境下的運行狀態信息了。不只如此,若是想要將這些信息分享給其餘團隊,咱們僅僅須要針對某個環境給予他們一些有限的權限。經過以上的方式,在想要得到狀態信息時咱們就徹底沒有必要請求操做人員登陸Docker主機,再經過人工的方式去查詢,同時這樣也減小了申請得到環境信息的請求的數目,由於咱們已經將某些訪問權限分配至各個團隊了。舉個例子來講,若是爲開發團隊分配環境信息的只讀權限,那麼將會在開發團隊與部署操做團隊之間架起一座溝通的橋樑,這樣兩個團隊都會對這個環境的狀態比以往更加的關心。在這個基礎上,故障的排除也變成了一種小組間相互合做的過程,而不是以往的那種單向的、依賴同步信息流的解決方式,相互合做的方式也會減小解決突發事件的總時間。

到如今爲止,咱們已經將已有的Docker主機加入Rancher Server,而且基於已經閱讀完了的教程的第一部分關於Jenkins和Rancher的內容,下一步,咱們打算改進的部分是咱們已有的部署流水線,咱們將會對已有的部署流水線進行修改,以便於使用Rancher compose,Rancher Compose將代替以前Ansible工具提到的Docker compose。不過在咱們深刻下一部分以前,咱們首先須要瞭解關於Rancher的應用、調度、Docker Compose和Rancher Compose的一些信息。

**應用與服務:**Rancher將每一個獨立的容器(指的是部署在Rancher以外的容器,或者是經過Rancher UI生成的一次性功能的容器)、應用和服務彼此分離開。簡單地說,應用是一組服務,而全部容器都須要利用服務(關於應用和服務的內容以後將會由更加詳細的介紹)以構建一個應用。獨立的容器須要手動地進行調度。

**調度:**在以前的部署技術中,運維人員須要決定容器應當在哪一臺主機上運行。若是使用的是部署腳本,那麼意味着運維人員須要決定部署腳本在哪一臺或哪幾臺主機上運行;若是使用Ansible,這將意味着運維人員須要決定哪些主機或組須要到Jenkins中工做。不管是哪種方式,都須要運維人員去作一些決定,可是在大多數狀況下,他們作出的決定都缺少一些可靠的依據,這對咱們的部署工做非常不利(好比說某一臺主機的CPU使用率高達100%)。不少解決方案,好比像Docker Swarm、Kubernetes、Mesos和Rancher都採用了調度器來解決這類問題。對於須要執行的某個操做,調度器將會請求得到一組主機的信息,並判斷出哪幾臺是適合執行這個操做的。調度器會根據默認的需求設定或者用戶定義的特定需求,好比CPU使用率高低、親和性或反親和性規則(好比:禁止在同一臺主機上部署兩個相同容器)等相似的需求,以逐漸縮小主機選擇的範圍。若是我是一個負責部署的運維人員,調度器將會極大的減小個人工做負擔(尤爲是我在深夜加班忙於部署時),由於調度器對以上信息的計算比我快的多,也準的多。Rancher在咱們經過應用部署服務的時候可以提供一個開箱即用調度器。

**Docker compose:**Rancher使用Docker compose來建立應用並定義服務。因爲咱們已經將服務轉化爲Docker compose的文件,咱們在此基礎上建立應用就變得容易了許多。應用能夠手動的從UI界面中建立,也能夠經過Rancher compose在命令行(CLI)下快速的建立。

**Rancher compose:**Rancher compose是一種經過命令行(CLI)讓咱們得以對Rancher中的每一種環境的應用和服務進行方便的管理的工具。同時,經過rancher-compse.yml文件,Rancher compose還能容許對Rancher工具進行一些其餘訪問。這是一個純粹的附加的文件,將不會取代原有的docker-compose.yml文件。在rancher-compose.yml文件中,你能夠定義如下內容,好比說:

  • 每種服務的升級策略信息
  • 每種服務的健康檢查信息
  • 每種服務的需求規模信息

這些都是Rancher中很是實用的亮點,若是你使用Docker Compose或者Docker daemon,這些內容你都是獲取不到的。若是想要查看Rancher Compose能提供的全部特性,你能夠查看這個文檔

經過將已有的部署工做交給Rancher Compose來替代以前的Ansible工具,咱們可以很輕鬆的將服務遷移並部署爲Rancher應用的形式。以後,咱們就可以去除DESTINATION參數了,但咱們依然保留VERSION參數,由於咱們在插入docker-compose.uml文件的時候還要使用它。如下是使用Jenkins部署時,部署邏輯的shell片斷:

export RANCHER_URL=http://rancher.abc.net/
export RANCHER_ACCESS_KEY=…
export RANCHER_SECRET_KEY=…

if [ -f docker/docker-compose.yml ]; then
  docker_dir=docker
elif [ -f /opt/abc/dockerfiles/java-service-1/docker-compose.yml ]; then
  docker_dir=/opt/abc/dockerfiles/java-service-1
else
  echo 「No docker-compose.yml found. Can’t continue!」
  exit 1
fi

if ! [ -f ${docker_dir}/rancher-compose.yml ]; then
  echo 「No rancher-compose.yml found. Can’t continue!」
  exit 1
fi

/usr/local/bin/rancher-compose –verbose \
  -f ${docker_dir}/docker-compose.yml \
  -r ${docker_dir}/rancher-compose.yml \
  up -d –upgrade

閱讀完代碼段,咱們能夠發現其主要包括如下內容:

  1. 咱們定義了以環境變量的方式如何訪問咱們的Rancher server。
  2. 須要找到docker-compose.yml文件,不然將會任務將會報錯退出。
  3. 須要找到rancher-compose.yml文件,不然任務將會報錯退出。
  4. 運行Rancher-compose,並告訴它不要block而且使用-d命令輸出日誌,使用-upgrade命令更新一個已經存在的服務。

也許你已經發現了,在絕大部分,代碼的邏輯都是相同的,而最大的區別就是使用rancher-compose代替使用Ansible工具完成部署,並對每個服務添加了rancher-compose.yml文件。具體到咱們的java-service-1應用,docker-compose文件和rancher-compose文件如今是這樣的:

docker-compose.yml
java-service-1:
image: registry.abc.net/java-service-1:${VERSION}
container_name: java-service-1
expose:
– 8080
ports:
– 8080:8080
rancher-compose.yml
java-service-1:
scale: 3

在開始部署工做以前,咱們先回顧一下部署工做的流程:

  • 開發人員將代碼的修改推送至git上
  • 使用Jenkins對代碼進行單元測試,在測試工做結束以後觸發下游工做
  • 下游工做採用新的代碼構建一個docker鏡像,並將其推送至咱們本身的Docker鏡像倉庫中
  • 建立包含應用名、版本號、部署環境的deployment ticket
DEPLOY-111:
  App: JavaService1, branch 「release/1.0.1」
  Environment: Production

部署工程師針對應用運行Jenkins的部署工做,運行時須要將版本號做爲參數。 Rancher compose開始運行,對於某個環境建立或更新應用,而且當達到所需規模的時候,結束這個工做 部署工程師以及開發工程師分別手動地對服務進行校驗 部署工程師在Rancher UI中確認完成升級

關鍵點

**使用Rancher進行咱們的服務部署時,咱們從Rancher內建的調度、彈性伸縮、還原、升級、和回滾等工具中得到極大的便利,使得咱們在部署過程當中沒有花太大的力氣。**同時咱們發現,在將部署工做從Ansible工具中遷移至Rancher的工做量也是很小的,僅僅須要在原有的基礎上增長rancher-compose.yml文件。然而,使用Rancher來處理咱們容器的調度意味着咱們將難以確認咱們的應用究竟是在哪臺主機上運行的。比方說,以前咱們並無決定java-service-1應用在哪裏運行,對於後端,在進行負載均衡相關操做時,該應用就沒有一個靜態的IP。咱們須要找到一種辦法,使得咱們的各類應用之間可以相互察覺到對方。最終,對於咱們的java-service-1應用,咱們將明確地將應用容器所在的docker主機的8080端口與應用綁定,不過,若是有其餘服務與應用綁定爲相同的端口,它將會啓動失敗。一般負責調度決策的工程師將會對以上的事務進行處理。然而,咱們最好將這些信息通知調度器以免這樣的事情發生。

在本教程的最後一個部分,咱們將繼續探索一些方案來解決在使用親和性規則、主機標籤、服務探索以及智能升級和回滾等特性時出現的問題。

歡迎關注Rancher官方微信公衆號(RancherLabs),獲取第一手技術乾貨推送;歡迎添加客服微信(RancherLabsChina)爲好友,加入Rancher官方技術交流羣,獲取免費技術支持,與數千Docker/Rancher使用者互動。

9月27日,北京海航萬豪酒店,容器技術大會Container Day 2017即將舉行。

CloudStack之父、海航科技技術總監、華爲PaaS部門部長、恆豐銀行科技部總經理、阿里雲PaaS工程總監、民生保險CIO······均已加入豪華講師套餐!

11家已容器落地企業,15位真·雲計算大咖,13場純·技術演講,結合實戰場景,聚焦落地經驗。免費參會+超高規格,詳細議程及註冊連接請戳 輸入圖片說明

相關文章
相關標籤/搜索