閒聊一下,算是緩解一下白天的工作,也算是宣泄一下自己的情緒吧。上週末跟以前的老同事小聚了一下,他們都是長沙NETCORE開源社區的(這裏吐槽一下,netcore被他們推成這樣了),一羣搞技術的圍在一個桌子上,除了聊技術也沒啥乾的,其中說到了一個話題,.NET行情很一般,也確實如此。據說有個NET架構師,先去了一家醫療公司(還是挖過去的),在裏面架構了兩年,走的時候,他搞的技術棧團滅。然後又去了另外一家,這家公司之前有50號人左右的NET團隊,他在裏面架構了兩年也走了,他走了之後,整個公司的技術平臺從NET轉java。其實有好幾家我熟悉的公司,幾年前沒有java,發展到現在沒有NET了。當然這些肯定主要原因不是leader,但是多少有那麼一點點影響吧,在長沙這種“1”線城市(個人感覺2線都不算),IT技術推進還是比較滯後。當然我只是一個坐板凳的聽衆,閒聊就到這吧。
今天主要簡單介紹下CI/CD持續集成 & 交付 & 部署,以及延伸出來的Devops。Devops我也不知道是啥,百度百科給出的定義是(過程、方法與系統的統稱),不知道看官明白沒,反正我是沒看明白,我給的定義就是“只能意會,不能言傳”。通俗點說就是開發+測試+運維,一條龍服務。在早期團隊裏面,開發人員寫完代碼,自測以後,通知測試團隊,並且手動發佈部署到測試服務器,包括後期的bug處理完,也是一樣,重新手動發佈部署。那麼週而復始的這樣發佈部署就成了一項繁瑣的工作。當然這裏面還有很多的問題,比如增加時間成本,代碼量積壓,項目推進進度慢等等問題。CI CD就是爲了解決這些問題誕生的。我們先看一張圖。
針對上面這張圖,我簡單介紹一下整個實現流程(我下面的部署環境完全是按照這幅圖實施的)。
開發者---》提交代碼到Git(github/lab/svn)都可以--->git通過webhook推送通知到jenkins---》jenkins接收到通知執行命令腳本(freestyle/pipeline,還有多種方式,我這裏用的是pipeline)---》在pipeline腳本里面,先從gitlab拉去源代碼---》通過dockerfire構建鏡像---》通過docker push到docker倉庫---》通知遠程測試服務器---》測試服務器通過docker拉取鏡像---》run容器---》完成---》最後測試人員幾分鐘以後就能測試開發人員剛剛處理的bug。
整套流程下來都是全自動的,不需要任何人蔘與,敏捷再敏捷,當然你也可以集成其它工具進來,比如代碼規範控制等等。理論就到這吧,下面簡單看看實操吧。
實踐環境我這邊準備了4臺centos,當然都是虛擬機。看圖。
這裏簡單注意下,gitlab服務器內存最少要4個g,本來打算還搭一個nuget包管理器,無奈內存不夠了,我們先簡單看下效果。
本來想截圖,發現要截圖的太多,索性錄製了一張gif圖片。這張gif圖片錄製的就是整個效果,開發人員改完代碼,推送git,等1分鐘不到,測試人員就可以在遠程做集成測試。速度的快慢主要還是取決於項目的大小,也就是編譯,鏡像推送的是本地倉庫。下面簡單介紹下環境搭建,主要搭建流程網上很多,我這邊搭建就簡單一點。
公共環境
首先搭建一個公共環境,也就是我上面的template,公共環境主要是一些基礎配置和docker環境安裝,準備好公共環境之後,後面的環境直接clone就行,減少操作嘛。注意,我這邊的所有環境搭建都是基於docker,沒有直接在虛擬機裏面搭建。
harbor倉庫
docker images倉庫我這邊使用的是harbor,harbor也是vmware公司開發,可以在本地搭建鏡像倉庫,harbor的搭建比較簡單,稍微需要注意的就是自簽證書的問題。下面我們簡單操作部署harbor倉庫。
安裝harbor需要預先安裝python2.7+、docker-compose、docker。
1.github上面去下載tgz包,git地址自己搜吧,因爲harbor包比較大,最好用迅雷下載,我這邊下載的包是harbor-offline-installer-v2.0.2.tgz,然後通過sftp傳輸到虛擬機,tar zxvf解壓。解壓後的文件夾。
1 [root@reg harbor]# ls
2 common common.sh harbor.v2.0.2.tar.gz harbor.yml harbor.yml.tmpl install.sh LICENSE prepare
3
4
2.修改harbor.yml.tmpl,需要修改的地方有三處hostname自簽證書路徑,最後cp到harbor.yml,這個文件默認是沒有的。
1 http:
2 # port for http, default is 80. If https enabled, this port will redirect to https port
3 port: 80
4
5
6 # https related config
7 https:
8 # https port for harbor, default is 443
9 port: 443
10 # The path of cert and key files for nginx
11 certificate: /hostfs/data/cert/harbor.com.crt
12 private_key: /hostfs/data/cert/harbor.com.key
13
14
15
3.執行shell腳本install.sh
4.查看docker容器
1 [root@reg harbor]# docker ps -a
2 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3 71853559898c goharbor/nginx-photon:v2.0.2 "nginx -g 'daemon of…" 8 minutes ago Up 8 minutes (healthy) 0.0.0.0:80->8080/tcp, 0.0.0.0:443->8443/tcp nginx
4 ee26f5e4280b goharbor/harbor-jobservice:v2.0.2 "/harbor/entrypoint.…" 8 minutes ago Up 8 minutes (healthy) harbor-jobservice
5 ea2ba64e7b01 goharbor/harbor-core:v2.0.2 "/harbor/entrypoint.…" 8 minutes ago Up 8 minutes (healthy) harbor-core
6 8464e2f008be goharbor/redis-photon:v2.0.2 "redis-server /etc/r…" 8 minutes ago Up 8 minutes (healthy) 6379/tcp redis
7 e5c299d64169 goharbor/harbor-portal:v2.0.2 "nginx -g 'daemon of…" 8 minutes ago Up 8 minutes (healthy) 8080/tcp harbor-portal
8 34b6414cd943 goharbor/harbor-db:v2.0.2 "/docker-entrypoint.…" 8 minutes ago Up 8 minutes (healthy) 5432/tcp harbor-db
9 56ac7263eb17 goharbor/registry-photon:v2.0.2 "/home/harbor/entryp…" 8 minutes ago Up 8 minutes (healthy) 5000/tcp registry
10 a277518da566 goharbor/harbor-registryctl:v2.0.2 "/home/harbor/start.…" 8 minutes ago Up 8 minutes (healthy) registryctl
11 34986a658b2a goharbor/harbor-log:v2.0.2 "/bin/sh -c /usr/loc…" 8 minutes ago Up 8 minutes (healthy) 127.0.0.1:1514->10514/tcp harbor-log
12
13
14
5.簽發證書
1 openssl req -newkey rsa:4096 -nodes -sha256 -keyout ca.key -x509 -days 365 -out ca.crt #創建CA證書
2 openssl req -newkey rsa:4096 -nodes -sha256 -keyout myharbor.com.key -out myharbor.com.csr # 生成簽名請求,這裏需要注意,commonname需要填寫域名或者ip
3 echo subjectAltName = IP:192.168.159.111 > extfile.cnf
4 openssl x509 -req -days 365 -in myharbor.com.csr -CA ca.crt -CAkey ca.key -CAcreateserial -extfile extfile.cnf -out myharbor.com.crt
5
6.配置daemon.json,需要寫入harbor域名或者ip地址。
7.如果是域名地址,需要修改hosts文件配置轉發,好了以上就是harbor倉庫環境部署的流程以及需要注意的地方。下面部署gitlab。
gitlab
gitlab源代碼管理服務器,它跟github有個區別就是lab可以本地部署,hub不能,並且hub好像創建私有倉庫需要收費,免費的還限制人數。lab目前有兩個版本吧,社區和企業版,我這裏使用的是社區版ce,社區版是免費的。lab很喫內存,企業級應用需要稍微注意,需要優化。下面簡單介紹下環境搭建。
1.拉取lab鏡像,我這裏直接是從本地harbor上拉取的。
1 [root@localhost ~]# docker images
2 REPOSITORY TAG IMAGE ID CREATED SIZE
3 gitlab_test v1.0 fad0a00dde08 12 days ago 1.91GB
4 myharbor.com/images/gitlab-ce v1.0 fad0a00dde08 12 days ago 1.91GB
5
6
2.創建容器,需要注意掛載數據卷的目錄。
1 docker run \
2 -p 443:443 -p 80:80 \
3 --name gitlab \
4 --volume /home/gitlab/config:/etc/gitlab \
5 --volume /home/gitlab/logs:/var/log/gitlab \
6 --volume /home/gitlab/data:/var/opt/gitlab \
7 myharbor.com/images/gitlab-ce
3.通過瀏覽訪問lab,配置項目、用戶、權限等等問題,這部分就不說了,很簡單。
Jenkins
jenkins基於java開發的一款插件系統,算是ci&cd這塊的佼佼者吧,它大部分功能都是基於插件實現,下面直接部署吧。
1.拉取鏡像,我這邊也是本地harbor拉取的,如果外網拉取,最好找lts長期維護版本。
2.創建容器
1 docker run \
2 -d \
3 -p 80:8080 \
4 -p 50000:50000 \
5 -v /data/jenkins:/var/jenkins_home \ # 掛載jenkins數據卷
6 -v /var/run/docker.sock:/var/run/docker.sock \ # 掛載docker
7 jenkins
3.如果沒有錯誤,可以通過瀏覽器訪問jenkins後臺,首次訪問需要解鎖jenkins admin賬戶,密碼在容器裏面,地址不貼了,首次訪問就會告訴你。
4.插件,有些鏡像默認安裝大部分插件,如果有些插件沒有安裝需要額外安裝,gitlab插件一般都要安裝。安裝插件我有個小建議,自己宿主機裏面下載比較快,地址我是從插件安裝失敗的錯誤信息裏面找的,當然你也可以直接找到所有插件,選擇對應的版本即可。jenkins的基本配置到此就差不多了,下面介紹重頭戲,jenkins vs gitlab hook通信。
Jenkins vs Gitlab
1.打開jenkins系統配置界面,不截圖了,看單詞就懂了。這裏主要配置gitlab插件。
這裏需要注意的就是憑據配置,我這裏使用的api-token的方式,這個token是從gitlab生成出來,我們過會再去看gitlab那邊的token是怎麼創建的。這邊配置完以後,點擊test connection按鈕,只要不報錯,就ok了。
2.Gitlab-token獲取
賬戶下面有個settins---》左邊導航的access-token,scope選擇api即可,取個名稱,點擊生成,生成出來的token-copy到jenkins的token文本框即可。
到此jenkins vs gitlab的訪問就ok了,接下來,我們在jenkins上面創建任務。
3.jenkins創建pipeline任務,當然這裏你也可以創建freestyle任務,個人覺得pipeline具有更靈活的操作,創建好任務之後,開始配置觸發器以及流水線。
選擇我圈起來的部分,然後打開Advanced Project Options選項卡,下拉選擇Pipeline script from SCM項。SCM選擇Git,再配置Repositories,最後配置Script Path爲Jenkinsfire,保存ok。
到此jenkins vs gitlab的大部分關節都打通了,還差一步,配置webhook。站在我們代碼的角度你可以理解爲callback。我們再次打開gitlab後臺,找到admin area,然後找到左邊導航的settins,點擊Integrations,隨後就可以配置web hook了。
這裏有兩個需要填寫的信息,url-secret均來源與jenkins-buildtriggers裏面的項。看圖
secrettoken需要點擊紅圈裏面的按鈕。到此關節部分全部打通,最後所有的任務落在了shell腳本上了,因爲我這裏創建的是pipeline任務,所以最後一步我們需要編寫pipeline腳本。還記得前面有個script path的輸入框嗎?沒錯我們的流水線腳本就是寫在jenkinsfire文件裏面。
1 pipeline {
2 agent any
3 stages {
4 stage("pull code") {
5 steps{
6 # 這裏面就是拉取代碼
7 }
8 }
9 }
10 stage("build") {
11 steps {
12 # 通過dockerfire構建鏡像
13 # 登陸到harbor,push鏡像到harbor
14 }
15 }
16 stage("dep") {
17 steps{
18 # 通知遠程測試服務器,執行腳本,剩下的就是測試服務器通過docker從harbor拉取鏡像,判斷容器是否運行,如果運行rm&rmi -f掉容器和鏡像,pull新的鏡像,run。 這裏需要注意:需要配置jenkins容器和測試服務器 ssh免密登陸
19 }
20 }
21 }
22 }
裏面的代碼我就不寫了,pipeline裏面的流水線隨意定製的,你也可以寫更多的stage階段和step步驟,這都沒關係。好了,到此整套CI VS CD就走完了,不早了,明天還要上班,就這樣吧。