通過Jenkins與Docker構建CI/CD基礎架構
提到容器平臺,最早接觸的便是LXC(Linux Container),是2010年剛剛接觸虛擬化平臺的時候,當時開源解決方案是xen的天下(後來KVM才後來者居上),且性能各方面都不弱,價值當時還不是移動互聯網時代,業務量遠遠沒有那麽大,大部分公司都是物理機部署應用,用虛擬化平臺的公司也是寥寥無幾,可想而知,沒有業務,沒有場景,那就沒有技術的用武之地了,所以,LXC生而偉大而用不逢時,Docker之所以能夠青出於藍而勝於藍,取得如此大的成功的原因還是歸咎於移動互聯網帶來的流量大爆炸,普通基於物理機,虛擬機甚至雲主機(雖然彈性伸縮應該是雲主機的特性,但是當時國內看起來根本沒有做到的,比起AWS來,差距之大,只能意會)的業務架構已經不能滿足目前的應用場景了。
關於Docker,在2013年的時候就開始接觸了,當時在一家做私有雲解決方案的公司裏面以Openstack/Cloudstack私有雲管理平臺+VMWare/Xen/KVM等虛擬化平臺在各大行業進行雲平臺的推廣與實施,Docker當時對我們而言就是個實驗室裏面的Demo產品,並沒有作過多的關註。
後來於2014年在騰訊遊戲任職業務運維,中心有一個部門就已經專門研究Docker技術,我也跟著湊了一把熱鬧,只是當時比較火的還是雲主機,而且騰訊雲當時才剛剛起步,加之當時維護的更多的還是端遊業務,考慮到遊戲的穩定性,當時內部使用虛擬機的場景都不是非常多,更不用提Docker容器技術的大規模應用了,本著業務運維以業務穩定為第一原則,加之業務運維的職責不在於基礎架構的研究,所以就沒再深入了。
直到2015年,一個運維朋友問我後面什麽比較火,我就隨口一答:Docker以後肯定會流行的,你去看看吧,於是他就去了DaoCloud,Docker在後面的幾年真的就火起來了,一時間Docker正在以星星之火可以燎原之勢在整個中國掀起了一陣風,國內比較知名的DaoCloud,靈雀雲等創業公司發展得非常迅猛,且資本不斷進入,大公司也紛紛布局,如阿裏雲,騰訊雲等,更不用說現在還有更多運維公司進場想分一杯羹了。
2016年,我跟另外一個朋友選擇了開發自動化運維平臺作為創業方向,現在想來,應該抓著Docker一起做的,由於自動化運維平臺更多還是聚焦在運維層面的工作,如果需要實現持續集成/持續發布等工作支撐還需要做大量的設計,且成本不菲,算不得真正的DevOps整套解決方案,而有了Docker,這一切變得就簡單多了,也變得順理成章了許多。
當然,創業方向雖然不是容器雲方向,但是在做運維平臺項目的時候,我自己都會不斷關註Docker發展以及客戶的Docker訴求,如今Docker+K8S已經成為了一個運維的技能標配,也是更多企業選擇業務架構設計的底層架構,作為一個技術人,我們不得不去正視Docker在未來的更大的發展,加之本人從2018年開始轉做區塊鏈架構設計與開發工作,接觸到的Hyperledger Fabric在進行模塊啟動的時候也是通過Docker實現,更加堅定了將Docker技術研究徹底的決心。
由於時間有限,概念性的東西大家自己有不清楚的可以自行翻閱相關資料,本文主要將這幾天學習到的東西進行整理並通過實戰分享,在今後的學習與工作中,我會更多的把重心放在區塊鏈架構與Docker的整合之上,將最好的技術整合在一起,為業務提供最好的架構設計與服務支撐。
###一. 部署環境
本文描述的就是一個測試環境(操作系統:CentOS7U5 X64),測試代碼用的是JAVA的開源博客系統solo(https://github.com/b3log/solo),通過域名的方式進行角色的劃分,大家在自己的實際環境中根據實際用途進行不同主機不同角色的劃分。
角色 | IP地址 | 訪問域名 | 部署服務 |
---|---|---|---|
Git版本控制器 | 172.16.222.180 | git.brucefeng.com | Git |
Docker主機 | 172.16.222.180 | docker01.brucefeng.com | Docker|docker-compose |
Docker倉庫註冊服務器 | 172.16.222.180 | reg.brucefeng.com | Docker主機服務+Harbor |
Jenkins服務器(Master) | 172.16.222.180 | jenkins.brucefeng.com | JDK|Tomcat|Jenkins |
Jenkins客戶端(Slave) | 172.16.222.180 | docker01.brucefeng.com | JDK|Tomcat|Maven |
需要在服務器與自己用於訪問域名的機器上面都進行/etc/hosts的解析配置
二. 安裝Git服務器
####1.概念簡述
Git是一個開源的分布式版本控制系統,是Linus Torvalds(Linux之父)為了幫助管理Linux內核開發而開發的一個開放源碼的版本控制軟件。
2. 安裝Git
(1) 安裝git並創建用戶
# yum install git -y ; useradd git ; echo git123|passwd --stdin git
註意: 類似安裝之前的yum源配置等基礎運維操作本文都不會贅述,下文如此。
(2) 創建倉庫
# su - git # 切換至git用戶
$ mkdir solo.git ; cd solo.git
$ git --bare init #初始化倉庫
此時可以通過git clone命令訪問這個倉庫了,目前沒有代碼數據
# git clone [email protected]:/home/git/solo.git
####3. 將項目傳至私有倉庫
將solo項目從https://github.com/b3log/solo獲取到之後提交至剛剛創建的git倉庫(私有倉庫)
(1) 從github.com拉取代碼
$ git clone https://github.com/b3log/solo.git
(2) 添加至私有倉庫
$ cd solo
$ git remote remove origin
$ git remote add origin [email protected]:/home/git/solo.git
(3) 提交至私有倉庫
$ git add .
$ git commit -m "All Solo Files To Local Git Server"
$ git push origin master
至此,我們已經將solo項目成功傳至我們創建的本地git倉庫中solo.git
###三.安裝Docker CE
CentOS安裝Docker的官方文檔
https://docs.docker.com/install/linux/docker-ce/centos/
####1.安裝依賴組件
# yum install -y yum-utils device-mapper-persistent-data lvm2
2.添加docker專用yum源
# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
####3.安裝Docker CE
# yum install docker-ce
自己根據需要可以再配置一個Docker加速器(國內鏡像源),Daocloud跟阿裏雲都有,自己決定即可。
####4.啟動與停止命令
# systemctl start docker #啟動docker
# systemctl stop docker #停止docker
####5.安裝docker-compose
Compose 是一個用戶定義和運行多個容器的 Docker 應用程序。在 Compose 中你可以使用 YAML 文件來配置你的應用服務。然後,只需要一個簡單的命令,就可以創建並啟動你配置的所有服務。
使用 Compose 基本會有如下三步流程:
- 在 Dockfile 中定義你的應用環境,使其可以在任何地方復制。
- 在 docker-compose.yml 中定義組成應用程序的服務,以便它們可以在隔離的環境中一起運行。
- 運行dcoker-compose up,Compose 將啟動並運行整個應用程序。
(1)直接下載
# curl -L https://github.com/docker/compose/releases/download/1.18.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
(2) 添加可執行權限
# chmod +x /usr/local/bin/docker-compose
# ln -s /usr/local/bin/docker-compose /usr/bin/
(3) 查看版本
# docker-compose version
返回結果
docker-compose version 1.18.0, build 8dd22a9
docker-py version: 2.6.1
CPython version: 2.7.13
OpenSSL version: OpenSSL 1.0.1t 3 May 201
或者通過pip工具進行安裝
pip install -U -i https://pypi.tuna.tsinghua.edu.cn/simple docker-compose
5.拉取所需基礎鏡像
# docker pull centos:7
6.創建Tomcat鏡像
(1) 創建Dockerfile文件 Dockfile-tomcat-85
FROM centos:7
MAINTAINER git.brucefeng.com
ENV TOMCAT_VERSION=8.5.32
ENV TOMCAT_MIRROR=http://mirrors.shu.edu.cn/apache/tomcat/tomcat-8/
ENV JDK_MIRROR=http://172.16.222.182:8888/jdk-8u181-linux-x64.tar.gz
ENV JAVA_HOME /usr/local/jdk
RUN yum install wget curl unzip iproute net-tools -y && yum clean all && rm -rf /var/cache/yum/*
RUN wget ${TOMCAT_MIRROR}/v${TOMCAT_VERSION}/bin/apache-tomcat-${TOMCAT_VERSION}.tar.gz && tar zxf apache-tomcat-${TOMCAT_VERSION}.tar.gz && mv apache-tomcat-${TOMCAT_VERSION} /usr/local/tomcat && rm -rf apache-tomcat-${TOMCAT_VERSION}.tar.gz /usr/local/tomcat/webapps/* && mkdir /usr/local/tomcat/webapps/ROOT && echo "${TOMCAT_VERSION} INSTALL DONE" > /usr/local/tomcat/webapps/ROOT/status.html && sed -i ‘1a JAVA_OPTS="-Djava.security.egd=file:/dev/urandom"‘ /usr/local/tomcat/bin/catalina.sh && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN wget ${JDK_MIRROR} && tar zxf jdk-8u181-linux-x64.tar.gz && mv jdk1.8.0_181 /usr/local/jdk && rm -rf jdk-8u181-linux-x64.tar.gz
ENV PATH $PATH:/usr/local/tomcat/bin
ENV PATH $PATH:/usr/local/jdk/bin
WORKDIR /usr/local/tomcat
EXPOSE 8080
CMD ["catalina.sh","run"]
(2) 構建docker鏡像
鏡像名: tomcat-85
docker build -t tomcat-85 -f Dockfile-tomcat-85 .
(3) 創建容器進行測試
docker container run -d --name=tomcat-1 -p 8888:8080 tomcat-85
這一步務必做好,在後面Jenkins的Pipline中會用到
###四.配置Harbor服務器
以上我們通過docker pull命令都是從公網拉取的鏡像文件,為了方便企業內部開發需要,我們有必要搭建一套Docker的私有倉庫管理常用鏡像。
VMWare Harbor是我們常用的也是比較優秀的Docker私有倉庫開源解決方案,項目地址為:https://github.com/vmware/harbor/,關於項目介紹以及特性相關內容可自行查閱。
Harbor的安裝有多種方式,在線安裝|離線安裝|OVA安裝,為了避免由網絡穩定性帶來的問題,我們采用離線安裝的方式進行Harbor的安裝(所需的Docker與Docker-Compose上文已經安裝完畢,此處不再寫安裝配置)
####1.下載離線安裝包
https://github.com/vmware/harbor/releases
選擇 Harbor offline installer
https://storage.googleapis.com/harbor-releases/release-1.5.0/harbor-offline-installer-v1.5.2.tgz
####2. 自簽TLS證書
Harbor可以通過兩種方式進行部署,HTTP與HTTPS,本文直接通過HTTPS的方式進行部署,大家可以參考官方文檔的配置:https://github.com/vmware/harbor/blob/master/docs/configure_https.md
(1) 創建CA證書
# mkdir /tmp/ssl ; cd /tmp/ssl #創建一個ssl目錄,存放證書文件
# openssl req -newkey rsa:4096 -nodes -sha256 -keyout ca.key -x509 -days 365 -out ca.crt
設置這兩處即可
Country Name (2 letter code) [XX]:CN
Common Name (eg, your name or your server‘s hostname) []:brucefeng.com
生成文件
ca.crt ca.key
(2) 生成證書簽名
# openssl req -newkey rsa:4096 -nodes -sha256 -keyout brucefeng.com.key -out brucefeng.com.csr
註意:
Country Name (2 letter code) [XX]:CN
Common Name (eg, your name or your server‘s hostname) []:brucefeng.com
生成文件
brucefeng.com.csr brucefeng.com.key
(3) 生成註冊證書
# openssl x509 -req -days 365 -in brucefeng.com.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out brucefeng.com.crt
返回結果
Signature ok
subject=/C=CN/L=Default City/O=Default Company Ltd
Getting CA Private Key
全部的生成文件
brucefeng.com.crt brucefeng.com.csr brucefeng.com.key ca.crt ca.key ca.srl
####3. Harbor安裝與配置
(1) 解壓文件
# tar zxvf harbor-offline-installer-v1.5.2.tgz
# mv /tmp/ssl harbor/ #將ssl目錄拷貝進harbor目錄下
(2)修改配置
# cd harbor
# vim harbor.cfg
需要修改的參數如下
hostname = reg.brucefeng.com
ui_url_protocol = https
ssl_cert = ./ssl/reg.brucefeng.com.crt
ssl_cert_key = ./ssl/reg.brucefeng.com.key
harbor_admin_password = 123456
註意: 本人發現harbor的安裝腳本有BUG,hostname必須是直接修改,不能註釋後修改,否則報錯!
如下為錯誤配置
# hostname = reg.mydomain.com
hostname = reg.brucefeng.com
(3) 生成用於安裝的配置文件
#./prepare
(4) 安裝並啟動Harbor
#./install.sh
(5)查看運行狀態
# docker-compose ps
返回結果
Name Command State Ports
------------------------------------------------------------------------------------------
harbor-adminserver /harbor/start.sh Up
harbor-db /usr/local/bin/docker-entr ... Up 3306/tcp
harbor-jobservice /harbor/start.sh Up
harbor-log /bin/sh -c /usr/local/bin/ ... Up 127.0.0.1:1514->10514/tcp
harbor-ui /harbor/start.sh Up
nginx nginx -g daemon off; Up 0.0.0.0:443->443/tcp, 0.0.0.0:4443->4443/tcp, 0.0.0.0:80->80/tcp
redis docker-entrypoint.sh redis ... Up 6379/tcp
registry /entrypoint.sh serve /etc/ ... Up 5000/tcp
####4. 測試網頁登錄
訪問鏈接:https://reg.brucefeng.com/harbor/projects
用戶名:admin
密碼: 123456
密碼是我們在配置文件harbor.cfg中配置的harbor_admin_password參數值
(1) 創建項目
創建新項目名稱:bruce-test
(2) 創建用戶
創建新用戶為:bruce-test-user
(3) 關聯項目與用戶
填寫剛剛創建的新用戶:
Name:bruce-test-user
Role角色:Project Admin
####5.為Docker主機添加信任
(1) 拷貝證書文件
# mkdir /etc/docker/certs.d/reg.brucefeng.com/
# cp /tmp/ssl/reg.brucefeng.com.crt /etc/docker/certs.d/reg.brucefeng.com/
(2) 測試登錄
此處用的測試賬戶仍未之前創建的brucefeng,項目按照之前創建的幾個項目進行操作
$ docker login -u brucefeng -p password(自定義的密碼) reg.brucefeng.com
返回結果
Login Succeeded
認證成功,可以通過命令行進行數據交互。
####6. 上傳下載鏡像
以Harbor上的fabric項目為例進行鏡像的上傳與下載操作
(1) 將本地鏡像打標簽
命令格式
docker tag SOURCE_IMAGE[:TAG] reg.brucefeng.com/fabric/IMAGE[:TAG]
本文以centos7鏡像為例測試
# docker tag docker.io/centos:7 reg.brucefeng.com/fabric/centos:v1.0
查看當前的centos7鏡像
# docker image ls |grep centos
返回結果
docker.io/centos 7 49f7960eb7e4 7 weeks ago 200 MB
reg.brucefeng.com/fabric/centos v1.0 49f7960eb7e4 7 weeks ago 200 MB
(2) 推送(上傳)鏡像
# docker push reg.brucefeng.com/fabric/centos:v1.0
(3) 拉取(下載)鏡像
- 刪除本地鏡像
# docker image rm reg.brucefeng.com/fabric/centos:v1.0
- 從Harbor上拉取鏡像
# docker pull reg.brucefeng.com/fabric/centos:v1.0
###五.Jenkins Master/Slave配置
Jenkins下載地址:https://jenkins.io/download/
本文通過Jenkins.war包啟動Jenkins服務,而Slave需要通過maven工具進行代碼構建,所以此處需要配置JDK|Tomcat|Maven環境
####1. 依賴環境安裝
# tar zxf jdk-8u181-linux-x64.tar.gz
# tar zxf apache-tomcat-8.5.32.tar.gz
# tar zxf apache-maven-3.5.4-bin.tar.gz
# mv jdk1.8.0_181 /usr/local/jdk
# mv apache-tomcat-8.5.32 /usr/local/tomcat
# mv apache-maven-3.5.4 /usr/local/maven3.5
2.環境變量配置
# vim /etc/profile
添加如下信息
JAVA_HOME=/usr/local/jdk
PATH=$PATH:$JAVA_HOME/bin
export JAVA_HOME PATH
# source /etc/profile
# java -version #檢查環境變量是否配置成功,查看java版本
返回結果
java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)
####3. 啟動Jenkins
(1) 部署Jenkins包
# rm -rf /usr/local/tomcat/webapps/ROOT
# unzip jenkins.war -d /usr/local/tomcat/webapps/ROOT
# cd /usr/local/tomcat/bin ; ./startup.sh
(2) 獲取Jenkins初始化密碼
# tailf ../logs/catalina.out #查看日誌信息
# cat /root/.jenkins/secrets/initialAdminPassword //查看Jenkins初始化密碼
####4. 初始化 Jenkins
登錄地址: http://jenkins.brucefeng.com:8080
按照默認的方式進行安裝即可,此處不深入。
5. Jenkins Slave配置
Master/Slave相當於Server和agent的概念。Master提供web接口讓用戶來管理job和slave,job可以運行在master本機或者被分配到slave上運行。一個master可以關聯多個slave用來為不同的job或相同的job的不同配置來服務。
(1) 創建認證方法
點擊Add credentials 創建新的憑據
可以選擇多種認證方式,一般我們可以采用ssh的用戶名跟密碼或者秘鑰登錄,此處我選擇秘鑰登錄。
(2) 新建Slave節點
Jenkins-Manage Jenkins-Manage Node-New Node
註意配置項
- Labels:docker01.brucefeng.com #用於標識Slave的標簽
- Remote root directory: /var/jenkins_home #用於指定通過jenkins構建的項目路徑
- JavaPath: /usr/local/jdk/bin/java #並非JAVA_HOME的配置項
####6.配置Docker主機與Git服務器免密登錄
通過ssh-keygen與ssh-copy-id密碼實現
六.通過Jenkins創建項目
####1.新建任務
New Item 類型選擇Pipeline,進行參數化設置
選擇字符串參數
定義參數名為Tag,用於傳入項目代碼版本號
####2.定義Pipline
關於Pipline就是一條任務流水線,便於分階段執行與排錯
腳本內容如下
node ("docker01.brucefeng.com") { //指定Slave的標簽
// 拉取代碼,$Tag引用用戶交互輸入的tag
stage(‘Git Checkout‘){
checkout([$class: ‘GitSCM‘, branches: [[name: ‘$Tag‘]], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[url: ‘[email protected]:/home/git/solo.git‘]]])
}
// 代碼編譯
stage(‘Mavin Build‘)
{
sh ‘‘‘
export JAVA_HOME=/usr/local/jdk
/usr/local/maven3.5/bin/mvn clean package -Dmaven.test.skip=true
‘‘‘
}
// 項目打包到鏡像並推送至鏡像倉庫
stage(‘Build and Push Image‘){
sh ‘‘‘
REPOSIROTY=reg.brucefeng.com/jenkins/solo:$Tag
cat >> DockerFile << EOF
FROM reg.brucefeng.com/libray/tomcat-85:latest
RUN rm -rf /usr/local/tomcat/webapps/ROOT
COPY target/*.war /usr/local/tomcat/webapps/ROOT.war
CMD["catalina.sh","run"]
EOF
docker build -t $REPOSIROTY .
docker login -u brucefeng -p Cpic@1234 reg.brucefeng.com
docker push $REPOSIROTY
‘‘‘
}
//根據$Tag作為鏡像版本號
stage(‘Deploy to Docker‘){
sh ‘‘‘
REPOSIROTY=reg.brucefeng.com/jenkins/solo:$Tag
docker rm -f blog-solo|true
docker image rm $REPOSIROTY |true
docker login -u brucefeng -p Cpic@1234 reg.brucefeng.com
docker container run -d --name blog-solo -v /usr/local/jdk:/usr/local/jdk -p 88:8080 $REPOSIROTY
‘‘‘
}
}
####3.模擬更新代碼
# vim solo/src/main/resources/latke.properties
修改內容
# Browser visit domain name
serverHost=docker01.brucefeng.com
# Browser visit port, 80 as usual, THIS IS NOT SERVER LISTEN PORT!
serverPort=88
4.提交代碼
# git add .
# git commit -m "modify latke.properties"
# git tag 1.0.1
# git push origin 1.0.1
5. 發布測試
選擇Build with Patameters
填寫Tag:1.0.1
6.登錄訪問
發布成功返回日誌
Digest: sha256:dc45052ad607de3757d330c389071bcbd985dd9981aba1c4f8196d05265c62a8
Status: Downloaded newer image for reg.brucefeng.com/jenkins/solo:1.0.0
c639e3bd71ca3935486c9f49bb8ba414031dc85927664f2c0d5d8d7b5eef4066
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
通過瀏覽器訪問http://docker01.brucefeng.com:88
更多內容,後續再聊。
通過Jenkins與Docker構建CI/CD基礎架構