1. 程式人生 > >openstack+docker設計與實現CI/CD(持續整合/持續交付)

openstack+docker設計與實現CI/CD(持續整合/持續交付)

老規矩我們先了解下相關概念:

本次主要說明下基於docker容器技術的openstack研發、測試、運維及其相關的CI/CD、devops等活動。

IaaS雲和容器雲不是可有可無、相互競爭的關係,而是相互彌補彼此缺陷的關係。容器改變了應用部署和管理的模式,我們都知道IaaS雲通過提供基本的計算、儲存和網路來執行VM,在IaaS(基礎設施即服務)之上,還有PaaS(平臺即服務)、SaaS(軟體即服務)、CaaS(容器即服務)。openstack作為一個IaaS雲的基礎設施管理平臺,為使用者提供了建立VM和其他資源的服務,至於具體怎麼使用這些虛擬機器、怎麼執行業務應用,如Hadoop大資料、Docker微服務、CI/CD工具鏈等,使用者可以按需使用。

docker的生命週期,一般分為:

  1. Build——使用dockerfile檔案或手動方式生成映象
  2. Push——將構建好的映象上傳到映象倉庫中
  3. Pull——從映象倉庫中拉取映象到使用環境中
  4. Run——啟動映象為容器服務
  5. Stop/Remove——停止或刪除容器、映象

docker適用於CI/CD的場景主要是基於:

  • docker容器是把應用程式和環境打包在一起,所以是一次構建,處處執行。docker最大的好處就是標準化了應用交付,只要系統能執行docker,就能無差別的執行應用。
    • docker映象統一封裝了軟體服務及其依賴環境,可以讓映象成為一個標準的軟體交付物。
    • 容器比虛擬機器執行效率更高,在開發測試工作日益繁重的CI/CD環境中,Job(定時執行)任務執行的速度是至關重要的。
    • 通過容器雲平臺如kubernetes,可以方便的實施叢集和容器管理。openstack和docker整合現狀:
    • OK,首先docker是一種集namespace、cgroups等技術於一體的容器技術,可以將應用和環境等進行打包。形成一個獨立且隔離的環境,讓每個應用彼此相互隔離,並在同一臺主機上同時執行多個應用,進行更細粒度的資源管理。

開源軟體專案介紹:

  1. kubernetes:

這是谷歌開發的一款開源的docker管理工具,用於跨主機叢集部署容器。kubernetes還提供了讓容器彼此互通的方法,不需要手動開啟網路埠或執行其他操作。提出了兩個概念:

pods:每個pod都是一個容器集合並部署在同一臺主機上,共享IP和儲存空間,比如講apache、Redis之類的應用分為一個容器集合。
labels:提供服務標籤,方便pod容器之間的協調作用。

2.docker compose:

docker compute是容器編排工具,讓使用者可以自定義容器的映象、容器之間的依賴關係等。定義好這些資訊後,只需要一條命令就可以按照順序啟動容器,然後整個應用就部署好了。

3、docker machine:

docker machine是一個便捷的容器建立工具,即從0到1地安裝docker,極大地簡化了安裝過程。使用docker-machine create命令,引數-d指定虛擬化的驅動,即可在相應的平臺上建立docker。

4、docker swarm:

docker swarm是docker的叢集管理工具,能夠通過master/slave的方式管理跨主機的docker,為docker叢集化部署提供了非常好的支援。

5、docker datacenter:

docker datacenter是docker的自動化叢集管理工具,並非第三方工具,它其實是一個基於docker的管理平臺。

6、apache mesos:

mesos的名氣比較大,基於它可以做很好的擴充套件,開發個性化的docker叢集管理工具。

7、marathon:

marathon是一個與mesos結合在一起的docker叢集管理工具,支援在mesos之外排程容器。

8、panamax:

因為docker佔用資源少,在單機伺服器上部署成百上千個容器也是可能的,panamax提供了人性化的web管理介面用來安裝軟體,讓部署變的更簡單。並且,panamax還提供了豐富的容器模板,讓線上建立服務成為可能,所有操作都可以在web介面上完成。

9、tutum:

tutum提供了一套非常友好的dashboard介面,支援建立docker容器的應用。

10、harbor:

使用harbor可以管理大規模的docker映象,以及基於同步複製功能的HA主備高可用性、細粒度的角色許可權和專案管理。除此之外,還有一些docker效能監控工具,如docker status、CAdvisor、Scoun、datadog以及sensu等。

11、openstack整合docker專案:

openstack社群為了整合docker做了很多努力,如開發了nova+docker driver、heat+docker driver等模組,但都存在諸多不足。為了更好地與docker整合,社群陸續開發了幾個新專案,如magnum、Murano、solum和kolla等。

目前,kolla是openstack整合docker最火熱的一個專案,將大部分的openstack服務docker容器化,便於安裝部署升級。其他的如magnum,則提供了CaaS,solum、Murano和docker有些關係。但solum更偏重於CI/CD,可以理解為一個應用軟體的持續整合/持續交付環境,Murano是一個app store,solum可以將開發的應用釋出到Murano中。

基於openstack+docker設計CI/CD:

目前,在docker容器中部署和執行openstack雲端計算服務,以成為主流趨勢之一。設計與實現基於openstack雲端計算+docker容器技術的CI/CD服務,其核心是在openstack IaaS雲端計算平臺上建立虛擬機器,實現基於openstack研發測試業務背景下的CI/CD服務。

這裡涉及到三個重要部分:
一是基於原生openstack研發的雲端計算產品,以及基於openstack基礎設施平臺構建的CI/CD應用
二是包括諸如Jenkins、citlab、gerrit、harbor等系統在內的CI/CD應用
三是將openstack每個服務容器化,並使用kolla方式部署。

注:
Jenkins是一個開源軟體專案,旨在提供一個開放易用的軟體平臺,使持續整合變成可能經濟界;

基於雲服務的CI/CD服務,可以實現彈性伸縮和橫向擴充套件,首先在物理伺服器上搭建好openstack IaaS雲平臺,以及建立數臺可用的虛擬機器等,後續使用。

其他:
在生產環境中,通過建立並掛載雲硬碟到虛擬機器中執行的服務資料目錄下,或者通過rsync同步備份資料的方式,以保證資料的高可用和完整性。對於CI/CD系統的HA等,可以通過計算節點HA或虛擬機器HA的方式實現。

另外在實際的企業研發測試和CI/CD環境下,建議使用三個harbor系統並相互關聯,一個是開發系統,用於存放和管理平時開發人員上傳的開發docker映象,該系統允許存放同一個映象的不同副本(tag);一個是測試系統,用於存放經過了CI/CD流程驗證測試的docker映象;一個是生產系統,用於存放釋出的docker映象,其產出物便是用於交付的最終產品。

基於docker的軟體持續交付

從軟體開發,到持續整合和持續交付,再到生產環境上的微服務應用等。除了docker技術本身發展以外,還不斷湧現出一系類與容器相關的生態應用,包括容器編排、高可用性、運維監控和日誌收集等各個方面。在基於容器的持續交付實現當中,以映象為內容傳遞的單元,通過CI(持續整合)的測試以及驗證,完成映象從開發、測試到可釋出的狀態轉變和軟體的交付流程。

開發人員:編寫和提交程式碼,從提交程式碼起,這一過程均自動化完成,完成所屬範圍的工作內容,負責輸出待測試的映象。
測試人員:編寫測試用例,手動或自動部署環境,執行各種測試,完成所屬範圍的工作內容,負責輸出預釋出的映象。
運維人員:將預釋出的映象部署到預生產環境中,執行驗收測試,完成所屬範圍的工作內容,負責生產環境的部署和運維。

整合和持續交付:

建立持續整合和持續交付流水線的核心問題是如何定義企業的軟體交付價值流動。基於容器的CI/CD流水線的設計應該遵循以下一些基本原則:

視覺化:流水線的執行和停止、成功和失敗應對所有人直觀可見,以掌握全域性變化。
資訊反饋:流水線應通過郵件等多種手段,及時將失敗資訊傳達給相關團隊成員。
可控制:從開發到生產釋出總有一些環節需要人手動驗證,比如迴歸測試、環境配置等,也就需要流水線在某些環節可以暫停,等待手動繼續。
門禁:流水線中任何一個環節失敗,都應該讓流水線停下來,並通知團隊解決,比如自動化測試不通過、程式碼或映象構建失敗等。

基於openstack+docker的應用部署

  • docker產生應用映象有兩種方法:一種是啟動一個基礎映象(比如基於CentOS的linux映象),然後在容器中執行各種命令來安裝相應的軟體包,進行配置後,在通過docker
    commit命令把已經更新的容器儲存為相應的映象;另一種方法則是通過編寫dockerfile檔案,然後使用docker
    build命令自動化構建相應的映象。

  • 相比第一種手工方式,通過dockerfile檔案的方式可以更好的維護映象,並將dockerfile提交到版本庫進行管理。並且通過CI/CD系統的自動化build、push、pull、run等工作流,可以與研發測試業務更緊密地結合起來。維護的不再是一條條零散的命令,而是一個檔案集合。這樣,dockerfile檔案便如同程式碼一樣,做到隨時維護修改和協作開發。

將所有的原始碼存放在私有倉庫GitLab中,docker映象則託管在私有Registry中,並使用諸如ansible之類的自動化工具將容器部署到伺服器環境中,這些都是一個完全自動化的過程。docker典型應用場景:

1、開發:開發人員使用同一個docker映象,同時修改原始碼都掛載到本地磁碟上,然後對映到容器中。不在為因為環境的不同而造成不同的程式行為而傷透腦筋,同時新人到崗時也能迅速建立起開發、編譯環境。

2、PaaS雲服務:docker可以支援命令列封裝與程式設計,通過自動載入與服務自發現,可以很方便地將封裝於docker映象中的服務擴充套件成雲服務,根據業務請求的規模隨時增加或減少容器的執行數量,實現彈性伸縮和橫向擴充套件。

基於openstack+docker的CI/CD流程設計

其核心元件包括:
    Jenkins持續整合系統,可參考:http://blog.csdn.net/wangmuming/article/details/22924815
    GitLab程式碼倉庫管理系統,可參考:http://www.ywlinux.com/archives/166
    Harbor私有映象倉庫管理系統,可參考:https://www.dwhd.org/20161023_110618.html
    Gerrit程式碼評審系統,可參考:http://blog.csdn.net/u011130578/article/details/46408243
流程步驟簡要:
    1、開發者準備好一個單節點環境,將開發工具連結到遠端開發目錄,並使用Git將程式碼提交到程式碼評審系統Grrrit中,目的是通過協作發現一些明顯的問題,減少BUG帶到軟體中的概率。
    2、當Jenkins持續整合系統檢測到Gerrit系統的程式碼提交事件後,觸發相關的Job任務,自動化執行程式碼編譯、打包、構建、部署和測試等工作流。相應地,會執行如下任務:
    執行原始碼編譯、打包,如RPM、WAR包等。
    構建docker映象
    部署環境,如使用Kolla自動化部署openstack。
    自動化執行測試,如單元測試、整合測試等。測試結果兩種,一種測試失敗,流程返回;一種是測試成功,流程繼續。
    3、根據測試結果和其他資訊綜合決定此次開發人員提交的程式碼是否合併,這樣保證只有通過了測試和稽核的程式碼才能合併到GitLab倉庫中。
    4、GitLab的Webhooks會觸發Jenkins系統中的兩個構建任務,一個是原始碼編譯、打包任務;一個是原始碼打包後的docker映象構建任務。docker映象構建後,Jenkins系統會自動將映象推送到私有Registry倉庫中。

很多企業內部都有一套標準化規範,在這套規範中定義了開發所使用的語言、框架、軟體包版本及依賴環境等,這樣做可以統一開發環境並解決因差異化帶來的其他問題。基於此,根據不同的服務進行邏輯或物理上的分組,把docker映象分為三層:基礎映象層、服務映象層和應用映象層。上層映象的構建依賴於下層映象,越下層的映象越穩定,也越不會經常更換。

基礎映象層:負責安裝最基本的、所有映象都需要的軟體及環境,例如作業系統等。
服務映象層:負責構建符合企業標準化規範的映象,這一層很想SaaS,例如python環境、某個專案的公共軟體包等。
應用映象層:負責部署和執行應用程式,這個階段是CI的產出物,例如rpm包、python原始檔等。

構建映象倉庫管理系統(Harbor):

Harbor的每個元件都是以Docker容器的方式執行的,並使用docker compose進行自動化部署。harbor使用Go語言開發,web框架採用beego。harbor系統由六個容器組成,即:

proxy:提供反向代理服務,使用者的不同請求由proxy分發到後端的UI或者pegistry,其使用Nginx映象。
jobservice:harbor專案的核心元件,主要提供許可權管理、審計、管理介面UI、token service,以及可供其他系統呼叫的API等功能。
mysql:提供資料持久化服務,使用的是mysql映象。
UI:提供web前段操作管理頁面。
registry:docker官方開源的registry映象,主要提供映象的儲存和分發功能。
log collector:負責收集系統執行和使用者操作的日誌。

安裝harbor:

1、安裝epel源:

yum install -y epel-release

2、加入docker源:

tee /etc/yum.repo.d/Docker.repo << 'EOF'

3、安裝版本為1.11的docker-engine:

yum install -y docker-engine-1.11.2-1.e17.centos.x86_64

4、啟動docker服務:

systemctl daemon-reload
systemctl enable docker
systemctl start docker

5、在正式安裝前,必須安裝docker-compose:

yum -y install python-pip
pip install -U docker-compose

6、修改/usr/lib/systemd/system/docker.service檔案,新增–insecure-registry配置項:

ExecStart=/usr/bin/docker daemon -H fd:// --insecure-registry 公網IP

7、重啟docker服務:

systemctl daemon-reload
systemctl restart docker

注:harbor使用docker-compose進行部署,並提供了線上安裝和離線安裝兩種方式:
8、下載離線安裝包,各版本連線地址:https://github.com/vmware/harbor/releases
下載後解壓:

tar xvf harbor-offline-installer-版本.tgz

9、配置相關檔案:
切換到harbor目錄下,對harbor.cfg檔案進行簡單配置:

  • hostname:外部可訪問的映象倉庫管理地址,通常設定為本地公有IP地址。若內部使用DNS,可設定為主機名。
  • harbor_admin_password:登陸harbor介面的admin使用者的密碼。

將主機的4000埠對映為registry容器的5000埠(埠可自定義)。修改docker-compose.yml,在registry部分的ports配置項中新增“- 4000:5000”這一行資料。

10、配置儲存後端(可選):
在預設情況下,docker映象儲存在本地檔案系統中。在生產環境中,可以考慮使用其他的儲存後端系統,如AWS S3、openstack swift、ceph等。因此,需要編輯Deploy/templates/registry/config.yml檔案中的storage配置部分。

11、執行./prepare指令碼更新配置,完成配置後,就可以使用install.sh指令碼部署harbor了:

./install.sh

12、執行./install.sh命令後,然後檢視:

docker -compose ps

若需要重新安裝harbor,執行如下命令即可:

docker kill $ (docker ps -q)
docker-compose stop
docker-compose rm
docker-compose up -d

使用harbor:

1、測試,從docker hub上下載hello-world映象:

docker pull hello-world

2、給映象打上tag,以便上傳到私有倉庫中,其中library是harbor預設提供的專案:

docker tag hello-world IP/library/hello-world

3、登陸和上傳映象:

先登入到映象倉庫,輸入使用者名稱和密碼
docker login IP
上傳映象:
docker push IP/library/hello-world

上傳成功後,就可以從harbor倉庫中使用docker pull拉取私有映象了:
docker pull IP/library/hello-world

4、在瀏覽器中訪問IP,登陸成功後,點選library專案,即可看到映象。

構建持續整合系統(Jenkins)

    Jenkins是一個用Java編寫並開源的自動化持續整合系統,可以用來自動化編譯、打包、分發部署應用,並支援Ant/Maven/Gradle等多種第三方構建工具,同時與SVN、Git無縫整合,也直接支援第三方原始碼託管系統,如GitHub、GitLab、Bitbucket等。它具有監控並觸發持續重複的任務、支援多平臺和外掛擴充套件、介面化管理、與第三方應用高度整合的特點。
    Jenkins的工作原理是,先將原始碼從Git系統中拷貝一份到本地,然後根據所編寫的指令碼執行一系列任務。整個系統的關鍵是指令碼,用來告訴Jenkins在一次整合中需要完成的任務。

部署和使用Jenkins
1、安裝Jenkins:
選擇一臺openstack虛擬機器上安裝Jenkins持續整合系統:

rpm -ivh jdk-8-linux-x64.rpm
yum install -y git
rpm -ivh jenkins-2.1-1.1.noarch.rpm

檢視Jenkins安裝路徑:

rpm -ql jenkins

最終配置檔案如下:

egrep '^[^#]' /etc/sysconfig/jenkins

2、啟動Jenkins,並設定服務為自啟動:

systemctl start Jenkins
chkconfig jenkins on

配置Jenkins
1、安裝外掛
這次實驗需安裝GitLab、E-mail、Git、Gerrit等相關外掛。如果因為網路原因安裝失敗,則可以在Jenkins官網上手動下載所需的外掛,然後通過Jenkins頁面上的“外掛管理→高階→上傳外掛”來安裝。Jenkins外掛安裝地址:https://wiki.jenkins-ci.org/display/JENKINS/Plugins

相關的具體外掛:
要讓Jenkins可以自動構建Git倉庫中的程式碼,需要安裝Git Client Plugin和Git Plugin。
要讓Jenkins可以收到GitLab發來的hook從而自動構建。需要安裝GitLab Hook Plugin。
要讓Jenkins可以在構建完成之後根據TAP檔案生成圖表,需要安裝TAP Plugin。
要讓使用者可以收到自定義格式的郵件,需要安裝Email Extension Plugin。

新增Slave節點
新增Jenkins Slave節點,用於執行具體的Job任務。新增Slave可以分為三個步驟:一是建立和配置Slave節點;二是在Jenkins系統中新增Slave節點資訊;三是將專案任務分配到Slave節點。
1、配置Slave節點:
在Slave節點上執行:

yum install -y java-1.7.0-openjdk git           #裝JDK/Git
ssh-keygen -t rsa                               #生成金鑰對
cd ~/.ssh/
cat id_rsa.pub > authorized_keys
chmod 700 authorized_keys

2、新增Slave節點的私鑰
首先在Jenkins頁面的左側面板中點選”Credentials”,直接選擇預設的”Global credentials”,點選”Add Credentials”新增訪問伺服器的憑證。在Kind中選擇”SSH Username with private key”;在Username中輸入登陸Slave節點的使用者名稱”root”;”Private Key”選擇”Enter directly”,輸入內容就是上面步驟中建立的id_rsa私鑰檔案內容。

3、新增Slave節點
在Jenkins頁面上的”系統管理” → “管理節點”中點選“新建節點“,在“啟動方法”中選擇”Launch slave agent on Unix machines via SSH”;在”Credentials”處選擇上一步建立的憑證;其他保持預設。

4、建立Jenkins專案
在Jenkins頁面的左側面板中點選”My Views” → “新建”,在”Enter an item name”框中輸入”test_GitLab”,並勾選“構建一個自由風格的軟體專案”,點選”OK”按鈕。在構建觸發器部分,勾選”Build when a change is pushed to GitLab”,並將後面的URL地址貼上到後續所建立的GitLab專案中的Webhooks中。

Jenkins備份和還原

Jenkins備份
1、全備份Jenkins
備份JENKINS_HOME下的所有檔案和資料夾,恢復時需要先停止Jenkins服務。該方式也適用於遷移。
2、備份Job
備份JENKINS_HOME/jobs目錄下的所有檔案和資料夾,恢復時要先停止Jenkins服務。
3、備份外掛
備份JENKINS_HOME/plugins資料夾,恢復時需要先停止Jenkins服務。
4、使用ThinBackUp外掛備份

    不同於上面的備份,Jenkins的ThinBackUp外掛備份的是Jenkins中的配置,包括Jenkins系統的配置、每個Job的配置,而這些配置基本都是XML檔案,並且是Jenkins的重要檔案。相比於全備份,這種備份速度更快,佔用空間小。可以在外掛管理中下載安裝ThinBackUp外掛。
    這裡通過編寫指令碼的方式,將其設定成linux Crontab定時執行任務來備份Jenkins系統中的jobs、plugins資料夾,並自動刪除4天之前備份的檔案。該指令碼運行於Jenkins Master節點上並存放於/var/lib/jenkins目錄下。指令碼內容(參考):
#!/bin/bash
i='date + %Y-%m-%d'
mkdir -p jenkins_backups
tar -zxvf jenkins_backins_backups/jenkins_backup_$i.tar.gz jobsplugins
backup_file="./jenkins_backups"
find $backup_file -mtime +4 -type f | xargs rm -f

設定Crontab任務,編輯/etc/crontab檔案,讓指令碼每隔2天自動執行一次

echo "0 0 */2 * * root bash /var/lib/Jenkins/jenkins_backup.sh" >> /etc/crontab

重啟crontab服務:

/sbin/service crond restart

Jenkins還原:
1、停止Jenkins服務:

systemctl stop jenkins.service
將jobs、plugins備份資料夾拷貝至新Jenkins系統的/var/lib/jenkins/目錄中

2、重啟Jenkins服務:

systemctl restart jenkins.service

注:其他安裝(GitLab、Gerrit) 請檢視之上文章的連結!