CICD詳解之gitlab,Jenkins

 

 

 持續集成概念

  1. 持續集成Continuous Integration
  2. 持續交付Continuous Delivery
  3. 持續部署Continuous Deployment

什麼是持續集成:

持續集成是指開發者在代碼的開發過程中,可以頻繁的將代碼部署集成到主幹,並進程自動化測試 

 

 

 

什麼是持續交付:

持續交付指的是在持續集成的環境基礎之上,將代碼部署到預生產環境 

 

 

 

持續部署:

在持續交付的基礎上,把部署到生產環境的過程自動化,持續部署和持續交付的區別就是最終部署到生產環境是自動化的。 

 

 

 

部署代碼上線流程

  1. 代碼獲取(直接了拉取)
  2. 編譯      (可選)
  3. 配置文件放進去
  4. 打包
  5. scp到目標服務器
  6. 將目標服務器移除集羣
  7. 解壓並放置到Webroot
  8. Scp 差異文件
  9. 重啓      (可選)
  10. 測試
  11. 加入集羣

 Gitlab介紹

  GitLab是一個利用 Ruby on Rails 開發的開源應用程序,實現一個自託管的Git項目倉庫,可通過Web界面進行訪問公開的或者私人項目。 
  GitLab擁有與Github類似的功能,能夠瀏覽源代碼,管理缺陷和註釋。可以管理團隊對倉庫的訪問,它非常易於瀏覽提交過的版本並提供一個文件歷史庫。它還提供一個代碼片段收集功能可以輕鬆實現代碼複用,便於日後有需要的時候進行查找。

清華源鏡像:https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/

gitlab部署

[root@mcw01 ~]$ ls
anaconda-ks.cfg  gitlab-ce-10.0.0-ce.0.el7.x86_64.rpm
[root@mcw01 ~]$ cat /etc/yum.repos.d/gitlab-ce.repo 
[gitlab-ce]
name=gitlab-ce
baseurl=http://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7
repo_gpgcheck=0
gpgcheck=0
enabled=1
gpgkey=https://packages.gitlab.com/gpg.key
[root@mcw01 ~]$ 
[root@mcw01 ~]$ yum localinstall gitlab-ce-10.0.0-ce.0.el7.x86_64.rpm 
Loaded plugins: fastestmirror
Examining gitlab-ce-10.0.0-ce.0.el7.x86_64.rpm: gitlab-ce-10.0.0-ce.0.el7.x86_64
[root@mcw01 ~]$ yum install -y git
配置並啓動gitlab-ce

[root@linux-node1 ~]# gitlab-ctl reconfigure
#時間可能比較長,耐心你等待即可!----


gitlab常用命令:
關閉gitlab:[root@linux-node2 ~]# gitlab-ctl stop
啓動gitlab:[root@linux-node2 ~]# gitlab-ctl start
重啓gitlab:[root@linux-node2 ~]# gitlab-ctl restart
重載配置文件: gitlab-ctl reconfigure


可以使用gitlab-ctl管理gitlab,例如查看gitlab狀態:
[root@mcw01 ~]$ gitlab-ctl status
run: gitaly: (pid 17644) 1226s; run: log: (pid 17193) 1366s
run: gitlab-monitor: (pid 17671) 1224s; run: log: (pid 17339) 1339s
run: gitlab-workhorse: (pid 17659) 1225s; run: log: (pid 17254) 1359s
run: logrotate: (pid 17279) 1351s; run: log: (pid 17278) 1351s
run: nginx: (pid 17261) 1358s; run: log: (pid 17260) 1358s
run: node-exporter: (pid 17324) 1345s; run: log: (pid 17323) 1345s
run: postgres-exporter: (pid 17693) 1223s; run: log: (pid 17447) 1321s
run: postgresql: (pid 17019) 1444s; run: log: (pid 17018) 1444s
run: prometheus: (pid 17680) 1224s; run: log: (pid 17374) 1327s
run: redis: (pid 16959) 1455s; run: log: (pid 16958) 1455s
run: redis-exporter: (pid 17354) 1333s; run: log: (pid 17353) 1333s
run: sidekiq: (pid 17176) 1372s; run: log: (pid 17175) 1372s
run: unicorn: (pid 17138) 1378s; run: log: (pid 17137) 1378s
[root@mcw01 ~]$ 


提示: 我們要保證80端口不被佔用
我們可以查看一下端口


[root@mcw01 ~]$ gitlab-ctl restart
ok: run: gitaly: (pid 2137) 0s
ok: run: gitlab-monitor: (pid 2148) 1s
ok: run: gitlab-workhorse: (pid 2151) 0s
ok: run: logrotate: (pid 2159) 0s
ok: run: nginx: (pid 2166) 0s
ok: run: node-exporter: (pid 2169) 1s
ok: run: postgres-exporter: (pid 2176) 0s
ok: run: postgresql: (pid 2181) 0s
ok: run: prometheus: (pid 2194) 1s
ok: run: redis: (pid 2200) 0s
ok: run: redis-exporter: (pid 2209) 0s
ok: run: sidekiq: (pid 2232) 0s
ok: run: unicorn: (pid 2240) 0s
[root@mcw01 ~]$



lsof -i:80

頁面操作

版本:gitlab-ce-10.0.0-ce.0.el7.x86_64.rpm

訪問:

提示:啓動gitlab需要時間!

Web頁面提示我們需要設置一個賬號密碼(我們要設置最少8位數的一個賬號密碼)我們設置密碼爲:12345678

 我們在後面的頁面設置用戶名 

 

 12345678

 

 

我們現在是以管理員的身份登陸 

 

第一步:我們關閉自動註冊,因爲我們內部使用不需要用戶自己註冊,由運維分配用戶即可 

提示:Save在頁面最下放!!!!!! 記得點保存!!!!!!!!!!!!

現在在查看首頁就沒有註冊頁面了

 

 

 

第二步:我們創建一個用戶,在創建一個項目

先創建一個組 

 

 

 

**提示:**gitlab上面有一個項目跟組的概念,我們要創建一個組,纔可以在創建一個項目。因爲gitlab的路徑上首先是ip地址,其次是組 

私有,只有項目組成員才能訪問

 

 

 

 

 

 

 

然後我們在組裏面創建項目

 

下一步,填寫項目名稱。項目可以從其它地方導入。項目路徑已經有了,私有,點擊創建項目 

 

 

 

 項目創建成功。項目組,項目名稱

 

 

 

 

 

 

創建完成之後它提示我們可以創建一個key對它進行管理

我們點擊上面的README然後我們隨便在裏面寫點東西 

 

 

 

 

 

項目名稱下,文件

 

 

填寫完成我們點擊前面進行查看

 

 

 

 

 

 

 

 我們複製項目地址,去10.0.0.11主機上克隆項目。這時是需要輸入用戶密碼的,我們一般是想要進行免密克隆

 

 

 我們要做免密驗證,現在去10.0.0.11複製下面的.ssh/id_rsa.pub,目前沒有公鑰,那就需要創建

[root@mcw01 ~]$ ssh-keygen 
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:6ofcUS0A/xWeS9DJrpORLdPRemBMPPwJgTLDrFdj3no root@mcw01
The key's randomart image is:
+---[RSA 2048]----+
|      .+  .O++   |
|       .B =o&o.  |
|       ..O X=B . |
|      . ..OoB.+  |
|       .S..O..   |
|       .. = E    |
|     ..o . o     |
|     .o o        |
|      ..         |
+----[SHA256]-----+
[root@mcw01 ~]$ ls -a
.   anaconda-ks.cfg  .bash_logout   .bashrc  gitlab-ce-10.0.0-ce.0.el7.x86_64.rpm  .ssh     .viminfo
..  .bash_history    .bash_profile  .cshrc   .pki                                  .tcshrc
[root@mcw01 ~]$ ls .ssh/
id_rsa  id_rsa.pub
[root@mcw01 ~]$ 

[root@mcw01 ~]$ cat .ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDa2frV273ZGG8BKHKCBOuuLYIOM/1XhYolKPKFyBw2aTwdW5F5faQ2sFqI2E7mdSoa6CL2MpBtFnURCVNG74YkQ5F10ur7jNOgx1CET8lL84UBlR4OOWJ8AfqMppILrtqMvcuXGtLWFvW5a8V9ceQmllAY0a0X63JZgg7ovLys5wkERGLkwlG0Yo4ZvSDw4QLjNnqsGc6vdM2jSKl+9Dvfp3pllYIcWdV1IiQWS1Q4JWImmPQngegUSVmTuAR1Bq0nj7TxdP5isjh/60IuJXMm7lreyA8Ht6TIPQnk+4H3tNZbArCXtm3mZ2TtM4TBYi7G4J6LYqp+oASSw3NUluBJ root@mcw01
[root@mcw01 ~]$

 

 

 將公鑰複製過來,title自動生成,點擊添加

 

 

 

 點擊你的項目

 

 

 

 

選擇SSH,我們要將代碼拉下來

 

 由於是第一次連接,所以確認了一次,不過已經不用輸入用戶密碼即可克隆項目文件了

[root@mcw01 ~]$ ls
anaconda-ks.cfg  gitlab-ce-10.0.0-ce.0.el7.x86_64.rpm
[root@mcw01 ~]$ git clone [email protected]:web/web-demo.git
Cloning into 'web-demo'...
The authenticity of host 'gitlab.example.com (10.0.0.11)' can't be established.
ECDSA key fingerprint is SHA256:1TxynA6n0UD3ZO0xutB2zsCTeq3wtp+O3L5p34As/4Q.
ECDSA key fingerprint is MD5:b0:3d:ab:dd:d7:93:68:ae:3d:b8:7a:35:c6:03:49:1d.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'gitlab.example.com,10.0.0.11' (ECDSA) to the list of known hosts.
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (3/3), done.
[root@mcw01 ~]$ ls
anaconda-ks.cfg  gitlab-ce-10.0.0-ce.0.el7.x86_64.rpm  web-demo
[root@mcw01 ~]$ ls web-demo/
README.md
[root@mcw01 ~]$ 

我們來模擬開發繼續寫代碼提交

[root@mcw01 ~]$ vim web-demo/index.html
[root@mcw01 ~]$ cd web-demo/
[root@mcw01 ~/web-demo]$ ls
index.html  README.md
[root@mcw01 ~/web-demo]$ git add *
[root@mcw01 ~/web-demo]$ git commit -m "add index.html"

*** Please tell me who you are.

Run

  git config --global user.email "[email protected]"
  git config --global user.name "Your Name"

to set your account's default identity.
Omit --global to set the identity only in this repository.

fatal: unable to auto-detect email address (got 'root@mcw01.(none)')

需要身份驗證:

[root@mcw01 ~/web-demo]$ git config --global user.email "[email protected]"
[root@mcw01 ~/web-demo]$ git config --global user.name "Your Name"
[root@mcw01 ~/web-demo]$ git commit -m "add index.html"
[master 0f2d55a] add index.html
 1 file changed, 1 insertion(+)
 create mode 100644 index.html


git push命令用於將本地分支的更新,推送到遠程主機。它的格式與git pull命令相仿。

[root@mcw01 ~/web-demo]$ git push
warning: push.default is unset; its implicit value is changing in
Git 2.0 from 'matching' to 'simple'. To squelch this message
and maintain the current behavior after the default changes, use:

  git config --global push.default matching

To squelch this message and adopt the new behavior now, use:

  git config --global push.default simple

See 'git help config' and search for 'push.default' for further information.
(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode
'current' instead of 'simple' if you sometimes use older versions of Git)

Counting objects: 4, done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 283 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To [email protected]:web/web-demo.git
   2696039..0f2d55a  master -> master
[root@mcw01 ~/web-demo]$ 

push上去之後,就可以在gitlab上刷新網頁,查看到多了index.html文件了

 

 


gitlab配置文件存放在/etc/gitlab/gitlab.rb 

 

 我們想把上面標記的改爲ip訪問

編輯配置文件,將域名改爲ip。

[root@mcw01 ~]$ ls /etc/gitlab/gitlab.rb 
/etc/gitlab/gitlab.rb
[root@mcw01 ~]$ grep external_url /etc/gitlab/gitlab.rb |grep -v "#"
external_url 'http://10.0.0.11'
[root@mcw01 ~]$ 

[root@mcw01 ~]$ gitlab-ctl reconfigure
Starting Chef Client, version 12.12.15

  1. #提示:修改完需要使用reconfigure重載配置纔會生效

我們重新登陸進行查看 。刷新頁面之後就變成ip了

 

 

 

自動化運維之DevOps

  DevOps(英文Development開發)和Operations技術運營)的組合)是一組過程、方法與系統的統稱,用於促進開發(應用程序/軟件工程)、技術運營和質量保障(QA)部門之間的溝通、協作與整合。 
  它的出現是由於軟件行業日益清晰地認識到:爲了按時交付軟件產品和服務,開發和運營工作必須緊密合作

簡單的來說DevOps是一種文化,是讓開發開發、運維、測試能夠之間溝通和交流

  自動化運維工具:saltstackjenkins、等。因爲他們的目標一樣,爲了我們的軟件、構建、測試、發佈更加的敏捷、頻繁、可靠 
  如果運維對git不熟,是無法做自動化部署。因爲所有的項目都受制於開發

Jenkins 介紹

1.5Jenkins 介紹
Jenkins只是一個平臺,真正運作的都是插件。這就是jenkins流行的原因,因爲jenkins什麼插件都有 
Hudson是Jenkins的前身,是基於Java開發的一種持續集成工具,用於監控程序重複的工作,Hudson後來被收購,成爲商業版。後來創始人又寫了一個jenkins,jenkins在功能上遠遠超過hudson
Jenkins官網:https://jenkins.io/
安裝 
安裝JDK 
  Jenkins是Java編寫的,所以需要先安裝JDK,這裏採用yum安裝,如果對版本有需求,可以直接在Oracle官網下載JDK。

yum安裝,發現下載repo文件出錯了。

[root@mcw01 ~]$ yum install -y java-1.8.0
[root@mcw01 ~]$  cd /etc/yum.repos.d/
[root@mcw01 /etc/yum.repos.d]$ wget http://pkg.jenkins.io/redhat/jenkins.repo
--2022-09-27 22:44:39--  http://pkg.jenkins.io/redhat/jenkins.repo
Resolving pkg.jenkins.io (pkg.jenkins.io)... 151.101.110.133, 2a04:4e42:8c::645
Connecting to pkg.jenkins.io (pkg.jenkins.io)|151.101.110.133|:80... connected.
HTTP request sent, awaiting response... 301 Moved Permanently
Location: https://pkg.jenkins.io/redhat/jenkins.repo [following]
--2022-09-27 22:44:39--  https://pkg.jenkins.io/redhat/jenkins.repo
Connecting to pkg.jenkins.io (pkg.jenkins.io)|151.101.110.133|:443... connected.
ERROR: cannot verify pkg.jenkins.io's certificate, issued by ‘/C=US/O=Let's Encrypt/CN=R3’:
  Issued certificate has expired.
To connect to pkg.jenkins.io insecurely, use `--no-check-certificate'.
[root@mcw01 /etc/yum.repos.d]$ rpm --import http://pkg.jenkins.io/redhat/jenkins.io.key

頁面訪問下,發現配置是需要堅持,那麼就手動添加爲不檢查

 

 

[jenkins]
name=Jenkins
baseurl=http://pkg.jenkins.io/redhat
gpgcheck=0

然後yum安裝,可以成功安裝

[root@mcw01 ~]$ yum install -y jenkins

 

 啓動Jenkins

[root@mcw01 ~]$ systemctl start jenkins
Job for jenkins.service failed because the control process exited with error code. See "systemctl status jenkins.service" and "journalctl -xe" for details.
[root@mcw01 ~]$ 

新版本的jenkins爲了保證安全,在安裝之後有一個鎖,需要設置密碼之後纔可以解鎖

Jenkins Web訪問地址:10.0.0.11:8080 
友情提示:jenkins如果跟gitlab在一臺服務器需要將jenkins的端口進行修改,需要將jenkins8080修改爲8081 

 

Jenkins部署

網上下載的包沒有管用的, 還是用以前下載的包安裝的。

[root@mcw01 ~]$ ls
anaconda-ks.cfg  gitlab-ce-10.0.0-ce.0.el7.x86_64.rpm  jenkins-2.73.1-1.1.noarch.rpm  web-demo
[root@mcw01 ~]$ yum localinstall jenkins-2.73.1-1.1.noarch.rpm
[root@mcw01 ~]$ java -version
openjdk version "1.8.0_345"
OpenJDK Runtime Environment (build 1.8.0_345-b01)
OpenJDK 64-Bit Server VM (build 25.345-b01, mixed mode)
[root@mcw01 ~]$ systemctl start jenkins
[root@mcw01 ~]$ grep 8081 /etc/sysconfig/jenkins  #gitlab也在用8080端口
JENKINS_PORT="8081"
[root@mcw01 ~]$ 

 

 啓動的過程有點慢,感覺過了三四分鐘吧

 

 

複製這個文件下面的ID,否則不可以進行安裝。

我們選擇推薦安裝即可

[root@mcw01 ~]$ cat /var/lib/jenkins/secrets/initialAdminPassword
e7d3087517bc4bd39ba88bb7e9e07109
[root@mcw01 ~]$

 

 

 

 

 

 點擊安裝推薦插件沒反應,先跳過插件安裝吧

 

 

 

 

 

 

jenkins基礎功能的瞭解

我們點擊新建 

這裏就是構建一個項目

用戶界面:主要是一些用戶的管理 

可以看到當前登陸用戶及用戶權限等

任務歷史:可以查看到所有構建過的項目的歷史 

#之所以叫構建,是因爲都是java,因爲如果不是java程序就沒有構建這個詞。但是我們也可以把一些工作稱之爲構建

系統管理:存放jenkins所有的配置 

 

 

My Views視圖功能,我們可以自己創建一個自己的視圖 

 

 

構建隊列:如果當前有視圖任務都會顯示在這裏 

構建執行狀態:顯示在正構建的任務 

系統管理:-系統設置

設置Jenkins全局設置&路徑 

 

 

Jenkins系統管理比較重要的就是插件管理 

#因爲jenkins所有的東西都需要靠插件來完成,

點擊已安裝可以查看我們的安裝 

我們想安裝什麼插件,我們可以選擇可選插件 

手動將很多插件傳到插件目錄,前端頁面上傳一個後,發現這個是已經安裝,可卸載。其它也在已安裝列表,但是是灰色的,也沒有可卸載

 

Jenkins插件下載地址:
https://wiki.jenkins-ci.org/display/JENKINS/Plugins
清華源國內 Jenkins插件下載地址:
https://mirrors.tuna.tsinghua.edu.cn/jenkins/war

 

把插件地址更新爲國內ch地址插件:

 

 將地址替換:

 

 替換爲下面地址:右擊複製地址

https://mirror.tuna.tsinghua.edu.cn/jenkins/updates/

 

 點擊提交:

我們爲了和gitlab和在一起,我們需要安裝一個插件 

查看還可以去jenkins官網下載,然後上傳插件 

因爲很多插件需要FQ纔可以繼續下載,jenkins還提供了代理的設置

    1. 還是在服務器目錄下進行上傳插件
    2. 目錄路徑= /var/lib/jenkins/plugins/
    3. 這個目錄下是我們安裝所有的插件

2.漢化jenkins

 

 

 

 

 

 

 

3.修改admin密碼

 

 

 

 

 

 

 

 

 

 點擊退出

 

 

 

 

 

 已成功修改

 

4.修改安裝源爲清華鏡像源

1、系統設置->插件管理-> 高級,滑動到下方找到“升級站點”

 

 https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json  用這個替換掉升級站點裏面的地址

 

 2、將    http://mirror.esuni.jp/jenkins/updates/update-center.json    這個下載源 複製粘貼到輸入框內,然後提交。

 備用:https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/current/update-center.json

3、再重啓jenkins!!!重啓才生效(方法:在url後添加  restart,回車即可)

jenkins的插件網址:http://updates.jenkins-ci.org/download/plugins/

 

使用git+jenkins實現持續集成

 

開始構建 

 

General 

源碼管理 

web項目的項目文件地址

 

 

源碼管理 
我們安裝的是git插件,還可以安裝svn插件 。將gitlab上項目文件地址複製過來

我們將git路徑存在這裏還需要權限認證,否則會出現error 

我們添加一個認證 

 

 

 

 之前在gitlab上已經做了免密克隆了,將mcw01主機的公鑰複製到gitlab裏面,實現正常在mcw01主機上git免密克隆gitlab上的項目文件。可參考前面gitlab的內容。這次將mcw01主機上的私鑰放入到Jenkins裏,注意,gitlab上放的是公鑰,Jenkins上放的是私鑰

 

 

 使用剛剛創建的密鑰,這樣權限認證失敗的錯誤就沒有了

再開一個頁面,可以看到權限認證的剛剛創建的gitlab-demo

 

 

 

剛剛返回剛剛的區域,繼續配置。點擊剛剛保存的部分設置的項目

 

 點擊配置,因爲還沒有配置完

 返回到配置頁面

 

 

 

 

我們選擇gitlaburl如下圖 。填寫源碼庫瀏覽器。我們這裏選擇gitlab。填寫gitlab上源碼的地址,以及gitlab的版本號

 

 源碼地址url,也就是gitlab上這個項目文件的訪問地址

查看gitlab版本

[root@mcw01 ~]$  rpm -qa|grep gitlab
gitlab-ce-10.0.0-ce.0.el7.x86_64
[root@mcw01 ~]$ 

這個url這裏配置錯了,源碼庫瀏覽器下的url需要是http方式的。上面那個是ssh。下面這個使用ssh方式,結果不能拉取程序下了,卡了我半天時間。重新修改爲http方式後,也不行,回到住房重新開機,相當於重啓的服務,這纔好了

我們現在就添加了一個git倉庫,現在保存就可以了!

 

保存完畢後,我們選擇立即構建 

 

 

 

 

 

點擊Console Output 可以顯示控制檯的輸出 

 

 ssh方式錯了,這裏的參數用http方式。這點要注意了。

 

 然後構建任務:

 

 

 這次成功了。現在基本就算是構建成功了

 

持續集成之代碼質量管理-Sonar

Sonar介紹

  Sonar 是一個用於代碼質量管理的開放平臺。通過插件機制,Sonar 可以集成不同的測試工具,代碼分析工具,以及持續集成工具。與持續集成工具(例如 Hudson/Jenkins )不同,Sonar 並不是簡單地把不同的代碼檢查工具結果(例如 FindBugsPMD 等)直接顯示在 Web 頁面上,而是通過不同的插件對這些結果進行再加工處理,通過量化的方式度量代碼質量的變化,從而可以方便地對不同規模和種類的工程進行代碼質量管理。 
  在對其他工具的支持方面,Sonar 不僅提供了對 IDE 的支持,可以在 Eclipse IntelliJ IDEA 這些工具裏聯機查看結果;同時 Sonar 還對大量的持續集成工具提供了接口支持,可以很方便地在持續集成中使用 Sonar 
  此外,Sonar 的插件還可以對 Java 以外的其他編程語言提供支持,對國際化以及報告文檔化也有良好的支持。

Sonar部署

  Sonar的相關下載和文檔可以在下面的鏈接中找到:http://www.sonarqube.org/downloads/。需要注意最新版的Sonar需要至少JDK 1.8及以上版本。

 上篇文章我們已經可以成功的使用git進行拉去,Sonar的功能就是來檢查代碼是否有BUG。除了檢查代碼是否有bug還有其他的功能,比如說:你的代碼註釋率是多少,代碼有一些建議,編寫語法的建議。所以我們叫質量管理

Sonar還可以給代碼打分,並且引用了技術宅的功能(告訴你有很多地方沒改) 

Sonar部署

[root@linux-node1 ~]# yum install -y java-1.8.0
[root@linux-node1 ~]# cd /usr/local/src
軟件包我們通過wget或者下載,rz上傳到服務器
#軟件包下載:https://sonarsource.bintray.com/Distribution/sonarqube/sonarqube-5.6.zip

http://www.sonarqube.org/downloads/

 

 下載上傳

Sonar部署
[root@linux-node1 ~]# yum install -y java-1.8.0
[root@linux-node1 ~]# cd /usr/local/src
軟件包我們通過wget或者下載,rz上傳到服務器
#軟件包下載:https://sonarsource.bintray.com/Distribution/sonarqube/sonarqube-5.6.zip


[root@mcw01 ~]$ unzip sonarqube-8.9.9.56886.zip
[root@mcw01 ~]$ mv sonarqube-8.9.9.56886 /opt/
[root@mcw01 ~]$ ln -s /opt/sonarqube-8.9.9.56886 /opt/sonarqube

準備Sonar數據庫 
如果沒有數據庫請執行
[root@mcw01 ~]$ yum install -y mariadb mariadb-server
 [root@mcw01 ~]$ systemctl start mariadb
[root@mcw01 ~]$ systemctl enable mariadb
Created symlink from /etc/systemd/system/multi-user.target.wants/mariadb.service to /usr/lib/systemd/system/mariadb.service.
[root@mcw01 ~]$ mysql_secure_installation
[root@mcw01 ~]$ mysql

update mysql.user set Password=password('123456') where User='root' and Host='127.0.0.1';
update mysql.user set Password=password('123456') where User='root' and Host='localhost';
CREATE DATABASE sonar CHARACTER SET utf8 COLLATE utf8_general_ci;
GRANT ALL ON sonar.* TO 'sonar'@'localhost' IDENTIFIED BY 'sonar@pw';
GRANT ALL ON sonar.* TO 'sonar'@'%' IDENTIFIED BY 'sonar@pw';
FLUSH PRIVILEGES;


Welcome to the MariaDB monitor.  Commands end with ; or \g.
MariaDB [(none)]> 
MariaDB [(none)]> update mysql.user set Password=password('123456') where User='root' and Host='127.0.0.1';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

MariaDB [(none)]> CREATE DATABASE sonar CHARACTER SET utf8 COLLATE utf8_general_ci;
Query OK, 1 row affected (0.00 sec)

MariaDB [(none)]> GRANT ALL ON sonar.* TO 'sonar'@'localhost' IDENTIFIED BY 'sonar@pw';
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> GRANT ALL ON sonar.* TO 'sonar'@'%' IDENTIFIED BY 'sonar@pw';
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> update mysql.user set Password=password('123456') where User='root' and Host='localhost';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

MariaDB [(none)]> 
[root@mcw01 ~]$ cd /opt/sonarqube/conf/
[root@mcw01 /opt/sonarqube/conf]$ ls
sonar.properties  wrapper.conf
[root@mcw01 /opt/sonarqube/conf]$ 

編寫配置文件,修改數據庫配置
[root@mcw01 /opt/sonarqube/conf]$ vim sonar.properties

#我們只需要去配置文件裏面修改數據庫的認證即可

sonar.jdbc.username=sonar            #數據庫用戶
sonar.jdbc.password=sonar@pw     #數據庫密碼
sonar.jdbc.url=jdbc:mysql://localhost:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance


配置Java訪問數據庫驅動(可選) 
  默認情況Sonar有自帶的嵌入的數據庫,那麼你如果使用類是Oracle數據庫,必須手動複製驅動類到${SONAR_HOME}/extensions/jdbc-driver/oracle/目錄下,其它支持的數據庫默認提供了驅動。其它數據庫的配置可以參考官方文檔: 
http://docs.sonarqube.org/display/HOME/SonarQube+Platform
啓動Sonar 
  你可以在Sonar的配置文件來配置Sonar Web監聽的IP地址和端口,默認是9000端口。

[root@mcw01 /opt/sonarqube/conf]$ vim sonar.properties
99 #sonar.web.host=0.0.0.0
06 #sonar.web.port=9000

啓動命令如下:
[root@mcw01 ~]$ sh /opt/sonarqube/bin/linux-x86-64/sonar.sh start
Starting SonarQube...
Started SonarQube.
[root@mcw01 ~]$ ss -lntup|grep 9000
[root@mcw01 ~]$
如果有什麼問題可以看一下日誌[/opt/sonarqube/logs/sonar.log]
檢查是否有相應的端口

[root@mcw01 ~]$ tail /opt/sonarqube/logs/sonar.20220928.log 
WrapperSimpleApp: Encountered an error running main: java.lang.IllegalStateException: SonarQube requires Java 11 to run
java.lang.IllegalStateException: SonarQube requires Java 11 to run

[root@mcw01 ~]$ ln -s /usr/lib/jvm/java-11-openjdk/bin/java /usr/bin/java2
[root@mcw01 ~]$ java2 -version
openjdk version "11.0.16.1" 2022-08-12 LTS
OpenJDK Runtime Environment (Red_Hat-11.0.16.1.1-1.el7_9) (build 11.0.16.1+1-LTS)
OpenJDK 64-Bit Server VM (Red_Hat-11.0.16.1.1-1.el7_9) (build 11.0.16.1+1-LTS, mixed mode, sharing)
[root@mcw01 ~]$ 



java.lang.RuntimeException: can not run elasticsearch as root


[root@mcw02 ~]$ su - machangwei
[machangwei@mcw02 ~]$ logout
[root@mcw02 ~]$ chown machangwei.machangwei -R /opt/sonarqube/
[root@mcw02 ~]$ su - machangwei
Last login: Wed Sep 28 23:22:52 CST 2022 on pts/0
[machangwei@mcw02 ~]$ sh /opt/sonarqube/bin/linux-x86-64/sonar.sh start
Starting SonarQube...
Started SonarQube.
過了一陣子端口才起來
[machangwei@mcw02 ~]$ ss -lntup|grep 9000
tcp    LISTEN     0      25       :::9000                 :::*                   users:(("java",pid=2201,fd=12))
[machangwei@mcw02 ~]$ 

Web登陸:IP:9000 

提示: 
sonarjenkins類似,也是以插件爲主 
sonar安裝插件有2種方式:第一種將插件下載完存放在sonar的插件目錄,第二種使用web界面來使用安裝 
存放插件路徑[/usr/local/sonarqube/extensions/plugins/]

安裝中文插件 
登陸:用戶名:admin 密碼:admin 

 輸入密碼登錄後,讓更新密碼,更新爲87654321

 

 

 

 

 

 安裝中文插件

 

 

 

 沒有安裝的按鈕。從後面三個點找到插件地址,下載下來插件

 將插件上傳到插件目錄,重啓sonar。安裝插件需要重啓纔會生效

[machangwei@mcw02 ~]$ cd /opt/sonarqube/extensions/plugins/
[machangwei@mcw02 /opt/sonarqube/extensions/plugins]$ ls
README.txt
[machangwei@mcw02 /opt/sonarqube/extensions/plugins]$ rz

[machangwei@mcw02 /opt/sonarqube/extensions/plugins]$ ls
README.txt  sonar-l10n-zh-plugin-8.9.jar
[machangwei@mcw02 /opt/sonarqube/extensions/plugins]$ cd
[machangwei@mcw02 ~]$ /opt/sonarqube/bin/linux-x86-64/sonar.sh restart
Gracefully stopping SonarQube...
Stopped SonarQube.
Starting SonarQube...
Started SonarQube.
[machangwei@mcw02 ~]$ 

重新訪問,過一會兒,就呈現中文展示頁面

 

 查看插件安裝,可以看到剛剛安裝的插件

 

 再看看全部,可以看到已經有了安裝和卸載按鈕

 

 

安裝掃描器sonar-scanner

下載:https://docs.sonarqube.org/latest/analysis/scan/sonarscanner/      (含簡單的使用說明)

我下載了sonar-scanner-cli-4.2.0.1873-linux.zip   sonar-scanner-cli-4.7.0.2747-linux.zip

 

 

解壓到/opt/目錄下(任意目錄都可以,這裏只是爲了方便管理),得到如下文件夾:

 (6.2)切換到root用戶,修改/etc/profile,添加sonnar環境變量,如下:

export MAVEN_HOME=/usr/share/maven
export SONAR_SCANNER_HOME=/opt/sonar-scanner
export PATH=$PATH:${MAVEN_HOME}/bin:${SONAR_SCANNER_HOME}/bin

 保存退出後,執行source /etc/profile 使環境變量生效

(6.3)輸入sonar-scanner -v 顯示如下,則表示安裝成功了:

(6.4)關聯sonarqube 和sonnar scanner

               在/opt/sonar-scanner/conf/sonar-scanner.properties中添加如下內容:

 sonar.host.url=http://sonnar_ip:9000
 sonar.login=admin
 sonar.password=admin
 sonar.jdbc.username=sonar
 sonar.jdbc.password=sonar123
 sonar.jdbc.url=jdbc:mysql://sonnar_ip:3306/sonar?useUnicode=true&characterEncoding=utf8

 

 

使用sonarqube + sonar-scanner做代碼檢測:

(7.1)打開要進行代碼分析的項目根目錄,新建sonar-project.properties文件

(7.2)輸入以下信息:

# must be unique in a given SonarQube instance
sonar.projectKey=my:project
# this is the name displayed in the SonarQube UI
sonar.projectName=apiautocore
sonar.projectVersion=1.0
 
# Path is relative to the sonar-project.properties file. Replace "" by "/" on Windows.
# Since SonarQube 4.2, this property is optional if sonar.modules is set. 
# If not set, SonarQube starts looking for source code from the directory containing 
# the sonar-project.properties file.
sonar.sources=src
 
# Encoding of the source code. Default is default system encoding
#sonar.sourceEncoding=UTF-8

其中:projectName是項目名字,sources是源文件所在的目錄

 (7.3)設置成功後,啓動sonarqube服務

(7.4)進入項目所在的根目錄,輸入命令:sonar-runner,分析成功後會有success信息

(7.5)瀏覽器輸入http://sonar_ip:9000登陸sonnarqube,就能看到你剛纔掃描的工程信息

sonar 啓動失敗,es報錯(查看logs目錄下的es.log即可):

es[][o.e.b.BootstrapChecks] max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]

            解決:

                     在   /etc/sysctl.conf文件最後添加一行

                    vm.max_map_count=262144

 

 

 

 

 

 

代碼流水線管理

  Pipeline名詞顧名思義就是流水線的意思,因爲公司可能會有很多項目。如果使用jenkins構建完成後,開發構建項目需要一項一項點擊,比較麻煩。所以出現pipeline名詞。 
  代碼質量檢查完畢之後,我們需要將代碼部署到測試環境上去,進行自動化測試

新建部署代碼項目(腳本執行任務)

使用Jenkins構建一個自由風格的項目。其它不管,構建裏增加構建步驟 ,選擇執行shell,然後在命令框裏填寫執行命令,點擊保存,然後立即構建任務。命令框裏可以寫Jenkins主機遠程ssh連接其它主機執行命令,執行的命令放到雙引號裏。執行的命令可以是執行某個腳本。或許可以是個部署腳本,這樣就能直接部署了。不過Jenkins主機上,程序用戶是Jenkins,它想要遠程連接其它主機執行命令,需要有權限,可以將Jenkins主機的公鑰分發到要連接的主機,保證可以免密ssh登錄遠程主機,保證Jenkins用戶有該腳本的執行權限。

點擊新建 

 

 

 

 

這裏只需要寫一下描述 

 

 

 

 

溫馨提示:執行命令主要涉及的是權限問題,我們要明白,jenkins是以什麼權限來執行命令的。那麼問題來了,我們現在192.168.56.11上,如果在想192.168.56.12上執行命令。需要怎麼做呢?

我們做無祕鑰有2種分案:

1、使用jenkins用戶將祕鑰分發給192.168.56.12 
2、使用root用戶將祕鑰分發給192.168.56.12上,如果使用root用戶還要進行visudo授權。因爲Web上默認執行命令的用戶是jenkins

1.我們使用root做密碼驗證 
#這裏我們的key已經做好,如果沒做可以直接 ssh-keygen -t ras 來生成祕鑰 
我們將192.168.56.11上的公鑰複製到192.168.56.12

  1. [root@linux-node1 ~]# cat .ssh/id_rsa.pub
  2. ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQChVQufrGwqP5dkzIU4ZwXCjRuSvMVGN5lJdvL/QFckmlVphWMsQw06VsPhgcI1NDjGbKOh5pbjrylyJUCig5YIJ1xuMOZ2YAK32SceMxnVhEb/G4wNb9VMsGQ/Vs4CxrU1HdATktH9zDAV4Qz81x2POYJW5B5LAvwZ4owqnIpZ7o3ya6xBxEvCIMSVtD17oKrNqAphsg+e68KvRexiNCEbCbRGGq3bKevgiDsWpSGnCYsJC0+cSrUxuzEO3G6AqGI/qR3nOeg91rOsoAP3FpFjBKgb/sXggkwwjmGIqFXJrUG+XmczeF4kG/rUrNbdy84e5RyHoIS3XKnJuRjTxHyD root@linux-node1
  3. [root@linux-node2 ~]# vim .ssh/authorized_keys
  4. ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQChVQufrGwqP5dkzIU4ZwXCjRuSvMVGN5lJdvL/QFckmlVphWMsQw06VsPhgcI1NDjGbKOh5pbjrylyJUCig5YIJ1xuMOZ2YAK32SceMxnVhEb/G4wNb9VMsGQ/Vs4CxrU1HdATktH9zDAV4Qz81x2POYJW5B5LAvwZ4owqnIpZ7o3ya6xBxEvCIMSVtD17oKrNqAphsg+e68KvRexiNCEbCbRGGq3bKevgiDsWpSGnCYsJC0+cSrUxuzEO3G6AqGI/qR3nOeg91rOsoAP3FpFjBKgb/sXggkwwjmGIqFXJrUG+XmczeF4kG/rUrNbdy84e5RyHoIS3XKnJuRjTxHyD root@linux-node1
  5. [root@linux-node1 ~]# ssh 192.168.56.12
  6. The authenticity of host '192.168.56.12 (192.168.56.12)' can't be established.
  7. ECDSA key fingerprint is b5:74:8f:f1:03:2d:cb:7d:01:28:30:12:34:9c:35:8c.
  8. Are you sure you want to continue connecting (yes/no)? yes
  9. Warning: Permanently added '192.168.56.12' (ECDSA) to the list of known hosts.
  10. Last login: Sat Dec 17 02:14:31 2016 from 192.168.56.1
  11. [root@linux-node2 ~]# ll
  12. total 4
  13. -rw-------. 1 root root 1021 Dec 13 05:56 anaconda-ks.cfg
  14. #現在SSH連接就不需要密碼了
  15. 授權jenkins用戶,使用visudo或者編輯配置文件/etc/sudoers
  16. [root@linux-node1 ~]# vim /etc/sudoers
  17. 92 jenkins ALL=(ALL)       NOPASSWD:/usr/bin/ssh
  18. #jenkins授權所有主機,不需要密碼執行ssh。切記不要授權ALL

我們在192.168.56.12上寫一個簡單shell腳本,檢測是否可以執行成功。正式環境可以寫一個自動化部署的腳本

  1. [root@linux-node2 ~]# echo "echo "hello word"" >demo.sh
  2. [root@linux-node2 ~]# chmod +x demo.sh
  3. [root@linux-node2 ~]# ll demo.sh
  4. -rwxr-xr-x 1 root root 16 Dec 17 02:24 demo.sh

jenkins編寫執行腳本 

 保存後點擊立即構建

 我們可以看到成功執行

 

 構建任務完成後會觸發構建另一個任務

需要安裝插件。在某個項目的設置構建下面的構建後操作裏,添加操作步驟。也就是該項目構建完成後,我們選擇的是觸發構建其它項目。然後指定那個要構建的Jenkins項目名稱。

 

 

現在我們要將代碼質量管理和測試部署連接起來。

 

這時候就用到了git鉤子 
我們需要安裝jenkins插件parameterized 

我們選擇demo-deploy 

再次點擊項目設置的時候就會出現Trigger parameterized build on other projects 

 

提示:Projects to build是爲構建設置一個項目。例如我們想構建完代碼項目後執行測試的,這裏就填寫測試的就可以。

最後點擊保存,點擊構建。我們查看效果 

 

 

#這樣我們每次點擊demo-deploy 它就會在構建完成之後在對auto-deploy進行構建

 

Pipeline簡介

概念
Pipeline,就是一套運行在Jenkins 上的工作流框架,將原來獨立運行於單個或者多個節點的任務連接起來,實現單個任務難以完成的複雜流程編排和可視化的工作。

使用Pipeline有以下好處: ·

●代碼: Pipeline以代碼的形式實現,通常被檢入源代碼控制,使團隊能夠編輯,審查和迭代其傳送流程。

●持久:無論是計劃內的還是計劃外的服務器重啓,Pipeline都是可恢復的。

●可停止: Pipeline可接收交互式輸入,以確定是否繼續執行Pipeline。

●多功能: Pipeline支持現實世界中複雜的持續交付要求。它支持fork/join、循環執行,並行執行任務的功能。

●可擴展: Pipeline插件支持其DSL的自定義擴展,以及與其他插件集成的多個選項。

3)如何創建Jenkins Pipeline呢

Pipeline 腳本是由Groovy語言實現的,但是我們沒必要單獨去學習Groovy

Pipeline 支持兩種語法: Declarative (聲明式)和 scripted Pipeline(腳本式〉語法 Pipeline有兩種創建方法:

●直接在Jenkins 的web UI界面中輸入腳本:

●通過創建一個Jenkinsfile 腳本文件放入項目源碼庫中(一般我們都推薦在Jenkins 中直接從源代碼控制(scm)中直接載入、JenkinsilePipeline這種方法)。

安裝Pipeline插件
(推薦的插件己默認安裝) Manage Jenkins -> Manage Plugins ->可選插件->安裝Pipeline

Pipeline語法快速入門

Scripted腳本式Pipeline

新建item ->任務名稱(web_demo_pipeline) Pipeline ->確定

流水線->定義選擇Pipeline script ->選擇scripted Pipeline

 

下載pipeline。這樣只需要構建一個項目,就會幫我們完成所有相關項目 
插件管理裏搜索下載插件pipeline 

 

 

 

我們點擊首頁+號,新建一個視圖

 

 

 

點擊OK 

沒有發現構建pipeline視圖的選項,那新建pipeline項目應該差不多意思吧。

 

 

 

 

 寫一個簡單的腳本式Pipeline

定義stage,也就是階段,一般設置拉取代碼,代碼編譯,代碼檢測,項目部署等等階段。每個階段就是stage (){}  ,stage小括號花括號。小括號寫‘階段名稱,名稱在視圖和控制檯都能明顯的看到,花括號裏放,命令

node {
    def mvnHome
    stage('拉取代碼') {
        echo '拉取代碼'
    }
    
    stage('代碼編譯') {
        echo '代碼編譯'
    }
    
    stage('項目部署') {
        echo '項目部署'
    }
}

將腳本放到框中,點擊保存,點擊立即構建,結果如下

 

 

 案例:

node {
    def mvnHome
    stage('Preparation') { // for display purposes
        // Get some code from a GitHub repository
        git 'https://github.com/jglick/simple-maven-project-with-tests.git'
        // Get the Maven tool.
        // ** NOTE: This 'M3' Maven tool must be configured
        // **       in the global configuration.
        mvnHome = tool 'M3'
    }
    stage('Build') {
        // Run the maven build
        withEnv(["MVN_HOME=$mvnHome"]) {
            if (isUnix()) {
                sh '"$MVN_HOME/bin/mvn" -Dmaven.test.failure.ignore clean package'
            } else {
                bat(/"%MVN_HOME%\bin\mvn" -Dmaven.test.failure.ignore clean package/)
            }
        }
    }
    stage('Results') {
        junit '**/target/surefire-reports/TEST-*.xml'
        archiveArtifacts 'target/*.jar'
    }
}
● Node:節點,一個Node 代表一個Jenkins節點,Master或者Agent 節點,是執行 Step的具體運行環境,後續講到Jenkins的Master-slave架構的時候用到。

● Stage:階段,一個 Pipeline可以劃分爲若干個stage,每個stage 代表一組操作,比如: Build、Test、Deploy,Stage是一個邏輯分組的概念。

● Step:步驟,Step 是最基本的操作單元,可以是打印一句話,也可以是構建一個 Docker鏡像,由各類venkins 插件提供,比如命令:sh ‘make',就相當於我們平時shell 終端中執行make 命令一樣。

 

Declarative聲明式Pipeline

流水線->選擇Helloworld模板

生成內容如下:

pipeline {
    agent any
​
    stages {                 #stages:代表整個流水線的所有執行階段。通常stages只有1個,裏面包含多個stage
        stage('Hello') {     #stage:代表流水線中的某個階段,可能出現n個。一般分爲拉取代碼,編譯構建,部署等階段
            steps {          #steps:代表一個階段內需要執行的邏輯。steps裏面是shell腳本,git拉取代碼,ssh遠程發佈等任意內容
                echo 'Hello World'
            }
        }
    }
}

簡單構建聲明式Pipeline

pipeline {
    agent any
    
    stages {
        stage('拉取代碼') {
            steps {
                echo 'pull code'
            }
        }
        
        stage('編譯構建') {
            steps {
                echo 'make & build'
            }
        }
        
        stage('部署項目') {
            steps {
                echo 'deploy project'
            }
        }
    }
}

將上面聲明式的放入到下面框中。點擊保存,點擊立即構建

 

 

 

 

 

 

使用代碼生成器生成流水線腳本()

流水線->流水線語法->片段生成器

生成一個pull stage 選擇checkout : check out from version control

 

 

 

 

 

SCM選擇Git,Repository URL: [email protected]:devops_group/web_demo.git

Credentials下拉選擇gitlab-auth-ssh 指定分支 * /master 點擊生成流水線腳本 把生成的腳本複製到流水線中後,點擊保存,嘗試構建;認證就用之前創建的認證就行,參考前面的。

 連接的認證憑證用之前創建好的。

 

指定分支,點擊生成流水線腳本,複製腳本放到配置中

 

 將生成的拉取代碼的流水線代碼放到拉取代碼的階段.點擊保存,點擊立即構建

 

 

 構建結果如下

 

 看控制檯輸出,可以看到已經將gitlab上的程序拉取過來了。Jenkins服務器將代碼拉取下來了

 

jenkens將gitlab上的項目文件拉取到了Jenkins項目工作目錄中了,如下,如果是java程序,那麼就可以使用命令去打包,然後上傳到web服務器中,

 

生成一個構建stage 

選擇sh: shell script shell script輸入mvn clean package點擊生成流水線腳本 把生成的腳本複製到流水線中後,點擊保存,嘗試構建;

 

複製粘貼保存構建

 

 

[root@mcw01 ~]$ mvn
-bash: mvn: command not found
[root@mcw01 ~]$ yum install -y maven

[root@mcw02 ~]$ rz -E
rz waiting to receive.
[root@mcw02 ~]$ java -version
openjdk version "1.8.0_345"
OpenJDK Runtime Environment (build 1.8.0_345-b01)
OpenJDK 64-Bit Server VM (build 25.345-b01, mixed mode)
[root@mcw02 ~]$ ls
anaconda-ks.cfg              mcw
apache-tomcat-8.0.27.tar.gz  sonarqube
demo.sh                      sonar-scanner-cli-4.7.0.2747-linux.zip
jpress-web-newest.war        tomcat
[root@mcw02 ~]$ mv tomcat/
bin/           LICENSE        RELEASE-NOTES  webapps/
conf/          logs/          RUNNING.txt    work/
lib/           NOTICE         temp/          
[root@mcw02 ~]$ mv jpress-web-newest.war tomcat/webapps/
[root@mcw02 ~]$ 
[root@mcw02 ~]$ ls tomcat/
bin   lib      logs    RELEASE-NOTES  temp     work
conf  LICENSE  NOTICE  RUNNING.txt    webapps
[root@mcw02 ~]$ ls tomcat/webapps/
docs  examples  host-manager  jpress-web-newest.war  manager  ROOT
[root@mcw02 ~]$ ./tomcat/bin/startup.sh 
Using CATALINA_BASE:   /root/tomcat
Using CATALINA_HOME:   /root/tomcat
Using CATALINA_TMPDIR: /root/tomcat/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /root/tomcat/bin/bootstrap.jar:/root/tomcat/bin/tomcat-juli.jar
Tomcat started.
[root@mcw02 ~]$ systemctl stop firewalld.service 
[root@mcw02 ~]$ ls tomcat/webapps/
docs      host-manager       jpress-web-newest.war  ROOT
examples  jpress-web-newest  manager
[root@mcw02 ~]$ ls tomcat/webapps/jpress-web-newest
META-INF  robots.txt  static  templates  WEB-INF
[root@mcw02 ~]$ 

訪問加上路徑就行:後臺http://10.0.0.12:8080/jpress-web-newest/admin,不寫路徑默認訪問上面的了

 

 這下我們有java程序,而不是war包了,將java程序上傳到git服務器,

將java程序上傳到代碼倉庫
[root@mcw01 ~]$ ls tomcat/webapps/
jpress-web-newest
[root@mcw01 ~]$ cd tomcat/webapps/
[root@mcw01 ~/tomcat/webapps]$ ls
jpress-web-newest
[root@mcw01 ~/tomcat/webapps]$ git add .
fatal: Not a git repository (or any of the parent directories): .git
[root@mcw01 ~/tomcat/webapps]$ git init 
Initialized empty Git repository in /root/tomcat/webapps/.git/
[root@mcw01 ~/tomcat/webapps]$ ls
jpress-web-newest
[root@mcw01 ~/tomcat/webapps]$ ls -a
.  ..  .git  jpress-web-newest
[root@mcw01 ~/tomcat/webapps]$ git add .
[root@mcw01 ~/tomcat/webapps]$ git commit -m 'java pro'
[master (root-commit) fb7ab68] java pro
 605 files changed, 78419 insertions(+)
 create mode 100644 jpress-web-newest/.ehcache/.ehcache-diskstore.lock
......
[root@mcw01 ~/tomcat/webapps]$ git push
fatal: No configured push destination.
Either specify the URL from the command-line or configure a remote repository using

    git remote add <name> <url>

and then push using the remote name

    git push <name>

[root@mcw01 ~/tomcat/webapps]$ 

由於沒有指定上傳的遠程倉庫地址,我們需要添加一個。在gitlab上新建一個項目,寫項目名稱,然後創建。

 

 在git服務器上添加遠程倉庫,然後上傳代碼。

 因爲該目錄已經初始化爲本地倉庫了,並且代碼已經提交到本地倉庫了。所以直接push到遠程倉庫gitlab上

[root@mcw01 ~/tomcat/webapps]$ ls /root/
anaconda-ks.cfg  gitlab-ce-10.0.0-ce.0.el7.x86_64.rpm  jenkins-2.73.1-1.1.noarch.rpm  jpress-web-newest.tar.gz  sonarqube-8.9.9.56886.zip  tomcat
[root@mcw01 ~/tomcat/webapps]$ ls
jpress-web-newest
[root@mcw01 ~/tomcat/webapps]$ git remote add origin git@10.0.0.11:root/javaPro.git  #添加遠程倉庫
[root@mcw01 ~/tomcat/webapps]$ git push -u origin master  #上傳代碼
Counting objects: 752, done.
Compressing objects: 100% (686/686), done.
Writing objects: 100% (752/752), 19.17 MiB | 9.49 MiB/s, done.
Total 752 (delta 80), reused 0 (delta 0)
remote: Resolving deltas: 100% (80/80), done.
To git@10.0.0.11:root/javaPro.git
 * [new branch]      master -> master
Branch master set up to track remote branch master from origin.
[root@mcw01 ~/tomcat/webapps]$ 

然後在gitlab頁面上,該項目下可以看到上傳的代碼

 

 生成拉取代碼的流水線代碼,指定倉庫地址爲剛剛創建的javaPro倉庫

 將流水線代碼複製粘貼到流水線任務配置的代碼拉取中。將編譯構建命令改成當前目錄創建目錄命令,因爲mvn構建命令目前沒成功,先跳過這個步驟。目前Jenkins的工作目錄下是這樣的。

保存構建:

 

 

 拉取代碼和創建目錄都是成功的

 查看Jenkins工作目錄中,可以看到拉取的代碼和執行shell命令創建的目錄。如果拉取過來的不是代碼而是war,其實我們直接可以執行shell命令將war包上傳到指定主機的Tomcat中,這樣就完成了部署。這個任務的重新構建,使得上次構建在工作目錄中保存的文件刪掉了。

 

 在目錄中的權限是這樣的。

 由於我這裏打包有問題,那麼i我直接將war包放到這個目錄下,前面的拉取代碼和編譯打包改成打印操作。模擬後面的部署操作

將war包上傳到Jenkins工作目錄中,授權爲Jenkins用戶。

生成一個部署stage

選擇deploy: Deploy war/ear to a containerwAR files 輸入targer/* . war containers -> Add container ->Tomcat 8.x Remote -> Credentials 下拉選擇 tomcat-authTomcat URL輸入http://192.168.37.108:8080/ 點擊生成流水線腳本 把生成的腳本複製到流水線中後,點擊保存,嘗試構建部署。
沒有找到deploy這個語法,暫且先用sh腳本的方式將Jenkins工作目錄中的war包上傳到Tomcat服務器上把

 將主機2這個Tomcat服務器上的包和解壓文件移走。保證主機1的Jenkins用戶有權限免密scp上傳文件到這個目錄

[root@mcw01 ~]$ grep scp /etc/sudoers
jenkins ALL=(ALL) NOPASSWD:/usr/bin/ssh,/usr/bin/scp
[root@mcw01 ~]$

 將其它階段的執行操作註釋掉,然後部署項目階段的配置修改爲剛剛根據語法生成的上傳war包到Tomcat服務器目錄的命令,點擊保存立即構建

沒加sudo,上傳失敗

 

 加上sudo之後,就能使用scp將war包從Jenkins工作目錄上傳到Tomcat服務器站點目錄

 

 控制檯輸出

 可以看到Tomcat服務器目錄已經存在war包了,並且在Tomcat的機制下自動解壓了

 http://10.0.0.12:8080/jpress-web-newest/

頁面又可以正常訪問了,這樣就實現的自動部署

 

上面的pipeline程序

pipeline {
    agent any
    
    stages {
        stage('拉取代碼') {
            steps {
                echo 'pull code'
            //   checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'cec19ba3-6eaf-49c9-b83f-f21d605beebe', url: '[email protected]:root/javaPro.git']]])
                
            }
        }
        
        stage('編譯構建') {
            steps {
                echo 'make & build'
                // sh 'mvn clean  package'
                // sh 'mkdir mcw123'
            }
        }
        
        stage('部署項目') {
            steps {
                sh 'sudo scp -rp  *.war [email protected]:/root/tomcat/webapps/'
            }
        }
    }
}

 

管理Jenkinsfile腳本文件 

之前我們都是直接在Jenkins的 Ur界面編寫Pipeline代碼,這樣不方便腳本維護,而且如果Jenkins服務器崩潰也會導致Pipeline代碼丟失,所以建議把Pipeline 腳本放在項目中來一起進行版本控制。

在項目根目錄中建立Jenkinsfile文件,把 Pipeline 代碼內容複製到該文件中,並上傳到 Gitlab

將war包上傳到git倉庫

[root@mcw01 ~/mcw2]$ ls
jpress-web-newest.war
[root@mcw01 ~/mcw2]$ git init
Initialized empty Git repository in /root/mcw2/.git/
[root@mcw01 ~/mcw2]$ git remote add origin git@10.0.0.11:root/warbao.git
[root@mcw01 ~/mcw2]$ git add .
[root@mcw01 ~/mcw2]$ git commit -m "war bao"
[master (root-commit) eb04021] war bao
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 jpress-web-newest.war
[root@mcw01 ~/mcw2]$ git push -u origin master
Counting objects: 3, done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 19.76 MiB | 33.90 MiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To git@10.0.0.11:root/warbao.git
 * [new branch]      master -> master
Branch master set up to track remote branch master from origin.
[root@mcw01 ~/mcw2]$ 

 

添加Jenkinsfile文件到代碼倉庫,文件中包含從gitlab拉取war包,將war包從Jenkins工作目錄複製到Tomcat服務器站點目錄,從而實現部署

[root@mcw01 ~/mcw2]$ vim  Jenkinsfile
[root@mcw01 ~/mcw2]$ cat Jenkinsfile 
pipeline {
    agent any
​ 
    stages {
        stage('拉取代碼') {
            steps {
                echo 'pull code'
               checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'cec19ba3-6eaf-49c9-b83f-f21d605beebe', url: '[email protected]:root/warbao.git']]])
            }
        }
        
        stage('編譯構建') {
            steps {
                echo 'make & build'
                // sh 'mvn clean package'
            }
        }
        
        stage('部署項目') {
            steps {
                echo 'deploy project'
                // deploy adapters: [tomcat9(credentialsId: '3506afe2-2e3c-4bfd-abab-e27489305d6c', path: '', url: 'http://192.168.37.108:8080/')], contextPath: null, war: 'target/*.war'
                sudo scp -rp jpress-web-newest.war root@10.0.0.12:/root/tomcat/webapps/
            }
        }
    }
}
[root@mcw01 ~/mcw2]$ git add .

[root@mcw01 ~/mcw2]$ git commit -m "add Jenkinsfile"   

[master 608ee0c] add Jenkinsfile  
1 file changed, 27 insertions(+)
create mode 100644 Jenkinsfile
[root@mcw01 ~/mcw2]$
[root@mcw01 ~/mcw2]$ git push -u origin master  #添加文件到倉庫
Counting objects: 4, done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 820 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To [email protected]:root/warbao.git
eb04021..608ee0c master -> master
Branch master set up to track remote branch master from origin.
[root@mcw01 ~/mcw2]$

 

 

 

在項目中引用該Jenkinsfile文件

流水線->定義下拉選擇Pipeline script from SCM

 

 

 #此處需與腳本文件名稱相同 點擊保存,嘗試構建部署

 

 測試將Tomcat主機的war包刪除

[root@mcw02 ~]$ ls tomcat/webapps/
docs  examples  host-manager  jpress-web-newest  jpress-web-newest.war  manager  ROOT
[root@mcw02 ~]$ rm -rf tomcat/webapps/jpress-web-newest*
[root@mcw02 ~]$ ls tomcat/webapps/
docs  examples  host-manager  manager  ROOT
[root@mcw02 ~]$ 

將Jenkins主機這個項目的工作目錄清空

[root@mcw01 ~/mcw2]$ ls /var/lib/jenkins/workspace/demo-pipeline
jpress-web-newest  jpress-web-newest.war
[root@mcw01 ~/mcw2]$ rm -rf /var/lib/jenkins/workspace/demo-pipeline/jpress-web-newest*
[root@mcw01 ~/mcw2]$ ls /var/lib/jenkins/workspace/demo-pipeline
[root@mcw01 ~/mcw2]$ 

點擊保存立即構建

 

 Jenkinsfile格式有問題,報錯了

 

 改正後如下:

[root@mcw01 ~/mcw2]$ cat Jenkinsfile 
pipeline {
    agent any

    stages {
        stage('拉取代碼') {
            steps {
                echo 'pull code'
               checkout([$class: 'GitSCM', branches: [[name: '*/master']], doGenerateSubmoduleConfigurations: false, extensions: [], submoduleCfg: [], userRemoteConfigs: [[credentialsId: 'cec19ba3-6eaf-49c9-b83f-f21d605beebe', url: '[email protected]:root/warbao.git']]])
            }
        }
        
        stage('編譯構建') {
            steps {
                echo 'make & build'
                // sh 'mvn clean package'
            }
        }
        
        stage('部署項目') {
            steps {
                echo 'deploy project'
                // deploy adapters: [tomcat9(credentialsId: '3506afe2-2e3c-4bfd-abab-e27489305d6c', path: '', url: 'http://192.168.37.108:8080/')], contextPath: null, war: 'target/*.war'
                sh 'sudo scp -rp  *.war [email protected]:/root/tomcat/webapps/'
            }
        }
    }
}
[root@mcw01 ~/mcw2]$ 

然後重新上傳到gitlab,重新構建任務。

這次pipeline流水線代碼來自gitlab上定義好的Jenkinsfile,運行成功

 

 

 

 拉取Jenkinsfile和war包

 

 部署到Tomcat服務器

 

 再次訪問,可以成功訪問了。

 

 查看Jenkins項目工作目錄

 

 查看Tomcat服務器站點目錄,有war包,且讓Tomcat解壓了。

 

Jenkins 項目構建細節

1、內置構建觸發器

1、常用的內置構建觸發器 前面我們使用的都是手動點擊觸發構建,而Jenkins 內置4種構建觸發器來實現觸發構建:

  ●觸發遠程構建

  ●其他工程構建後觸發(Build after other projects are build)

  ●定時構建(Build periodically)

  ●輪詢SCM( Poll SCM)

1)觸發遠程構建(需要第三方應用調用URL地址傳遞加密token字符串來觸發遠程構建)
demo-pipeline項目下點擊配置->構建觸發器->勾選觸發遠程構建

還是上面那個pipeline項目,做下修改

複製框框下方URL地址然後修改一下:JENKINS_URL/job/demo-pipeline/build?token=TOKEN_NAME

生成遠程訪問地址:http://10.0.0.11:8081/job/demo-pipeline/build?token=abc123

點擊保存,然後在新建瀏覽器窗口訪問: http://10.0.0.11:8081/job/demo-pipeline/build?token=abc123

 

 目前是任務12

 

 在瀏覽器上通過地址欄訪問地址的方式,再去Jenkins平臺上查看,可以看到該項目構建信任併成功運行

 

 通過網址(api)做訪問請求,成功構建並運行任務

 其他工程構建後觸發(當前項目需要依賴一個前置項目工程構建完成後才能觸發構建)

#創建一個前置項目工程 新建

item ->任務名稱(pre_job) Freestyle Project ->確定

構建->添加構建步驟-> Execute shell,命令輸入echo "構建前置工程"


 

 該任務起個名字後,選擇執行shell,echo打印一個輸出,點擊保存

 

 

#配置需要觸發的工程

demo-pipeline 項目下點擊配置-→構建觸發器-→勾選加build after other projects are built,並取消其它勾選項,關注的項自輸入pre_job 點擊保存

 

 

 目前最後一個任務是13;

 

 #構建前置工程來觸發項目工程構建 先構建pre_job前置項目工程,當此工程構建完成後則會立即引發構建demo-pipeline項目工程

 

 當前置工程構建完成後,這個任務也構建了一次

 

 時間有先後,後面那個是觸發構建的

 

 

定時構建

定時字符串從左往右分別爲:分時日月周

#定時表達式的示例

●每分鐘構建一次:

* * * * *
● 每小時構建一次:H爲形參,代表以傳入值爲起點

H * * * * 
●每10分鐘構建一次:

H/10 * * * *
●每2個小時構建一次:

5 5/2 * * *
●每天的8點,12點,22點,一天構建3次:(多個時間點中間用逗號隔開)

0 8,12,22 * * *
●每天中午12點定時構建一次:

H 12 * * *
●每天下午6點定時構建一次:

H 18 * * *
●在每個小時的前半個小時內的每10分鐘:

H(0-29)/10 * * * * 
●每兩小時一次,每個工作日上午9點到下午5點(也許是上午10:38,下午12:38,下午2:38,下午4:38):

H H(9-16)/2 * * 1-5

 demo-pipeline 項目下點擊配置->構建觸發器->勾選 Build periodically,並取消其它勾選項日程表輸入

H/2 * * * *

點擊保存,嘗試構建 會發現前後兩次構建相隔2分鐘

 

 

 如下,可以看到項目每兩分鐘構建一次

 

 

輪詢SCM

        輪詢SCM,是指定時掃描本地代碼倉庫的代碼是否有變更,如果代碼有變更就觸發項目構建:如果沒有變更則不會觸發項目構建。

demo-pipeline 項目下點擊配置->構建觸發器->勾選 poll SCM,並取消其它勾選項

目前是這個

 

 

 上傳代碼到gitlab

 

 會發現代碼有變更,會觸發項目構建。設置的是兩分鐘輪詢一次,發現倉庫有變化就構建一次項目

注意:輪詢scw構建觸發器,Jenkins會定時掃描本地整個項目的代碼,會增大系統的開銷,不建議使用輪詢sCM。

 

 下載插件地址:https://updates.jenkins-ci.org/download/plugins/multibranch-scan-webhook-trigger/

查看Jenkins版本:

[root@mcw01 ~/mcw2]$ grep version /var/lib/jenkins/config.xml
<?xml version='1.0' encoding='UTF-8'?>
<version>1.0</version>
[root@mcw01 ~/mcw2]$

 

在Jenkins的內置構建觸發器中,雖然輪詢sCM可以實現Gitlab代碼更新,項目自動構建,但是該方案的性能不佳。我們利用Gitlab的webhook實現代碼push到倉庫,立即觸發項目自動構建。

輪詢SCM原理:

Jenkins --發生定時請求--> Gitlab變更

webhook原理:

Gitlab變更--發送構建請求--> Jenkins

安裝Gitlab Hook插件:

Manage Jenkins -> Manage Plugins >可選插件->安裝GitLab和Generic webhook Trigger

gitlab-hook下載地址: https://mirrors.tuna.tsinghua.edu.cn/jenkins/plugins/gitlab-hook/

 

 jenkins插件地址集合:

國內雲廠商提供的鏡像 參考 https://github.com/lework/jenkins-update-center

tencent mirrors.cloud.tencent.com/jenkins
huawei mirrors.huaweicloud.com/jenkins
tsinghua mirrors.tuna.tsinghua.edu.cn/jenkins
ustc mirrors.ustc.edu.cn/jenkins
bit http://mirror.bit.edu.cn/jenkins

對應的文件

https://cdn.jsdelivr.net/gh/lework/jenkins-update-center/updates/tencent/update-center.json

https://cdn.jsdelivr.net/gh/lework/jenkins-update-center/updates/huawei/update-center.json

https://cdn.jsdelivr.net/gh/lework/jenkins-update-center/updates/tsinghua/update-center.json

https://cdn.jsdelivr.net/gh/lework/jenkins-update-center/updates/ustc/update-center.json

https://cdn.jsdelivr.net/gh/lework/jenkins-update-center/updates/bit/update-center.json

 

 上圖gitlab-plugin就是gitlab hook插件,在網上找了半天gitlab-hook名字的插件都不能用,卻不知道自己已經有了,白白浪費了好多時間。

Jenkins 設置自動構建

demo-pipeline 項目下點擊配置-〉構建觸發器→取消其它勾選項,勾選 Build when a change is pushed to GitLab. GitLab CI Service URL: http://10.0.0.11:8081/project/demo-pipeline等會需要把生成的webhook URL配置到Gitlab中 其它保持默認值,點擊保存

 

 

#Gitlab配置 webhook

1)開啓webhook功能 使用root賬戶登錄到後臺,

點擊管理中心->點擊左邊菜單 設置-〉選擇子菜單網絡->點擊外發請求展開勾選“Allow requests to the local network from web hooks and services"讓網絡鉤子允許請求本地網絡

點擊save changes

 

 

 

 

在項目添加webhook
點擊項目->點擊左邊菜單設置->選擇子菜單集成 URL輸入http://10.0.0.11:8081/project/demo-pipeline  Trigger '勾選Push events,其它可根據使用場景自行選擇 點擊Add webhook Webhooks 下方即會出現保存的 webhook,但此時若點擊Test ->選擇 Push events測試連接,會報錯

地址是填的Jenkins上構建觸發器時顯示的服務url

 

報錯:

 

 解決方法:在Jenkins 中,Manage Jenkins -> Configure System -> Gitlab -〉取消勾選Enable authentication for '/project ' end-point點擊保存

 

 

 

 

 在gitlab上再次測試:

 

 成功了

 

 此時,已經構建,當我們再次修改代碼,上傳到gitlab時,鉤子自動發現自動構建

目前是這樣的

 

 web服務器情況,沒有war包:

 

 git服務器修改代碼,然後推送到gitlab倉庫

 

 

 

 再看Jenkins上,可以看到自動構建部署任務,開始於gitlab的推送

 

 再去web服務器查看,成功部署

 在瀏覽器上成功訪問到服務:http://10.0.0.12:8080/jpress-web-newest/

 

 以上,成功實現,當程序員將代碼push到gitlab上時,gitlab發現變動會自動推送到Jenkins上構建任務並運行。

Jenkins 的參數化構建

有時在項目構建的過程中,我們需要根據用戶的輸入來動態傳入一些參數,從而影響整個構建結果,這時我們可以使用參數化構建。比如在原來Jenkinsfile中只指定了 master 分支,那麼我們可以使用參數替換分支。

通過輸入gitlab項目的分支名稱來部署不同分支項目:

Jenkins設置參數化構建
web_demo_pipeline項目下點擊配置->構建觸發器->取消構建觸發器勾選項點擊應用 General ->勾選 This project is parameterized ->添加參數選擇string Parameter名稱branch

默認值master 描述請輸入一個分支的名稱 點擊保存,此時左邊菜單會多出一個Build with Parameter選項

 

 添加參數,可以添加和刪除多個參數,點擊保存

 

 向git傳入分支傳入代碼。將原來的分支改成變量

 

 

 

 

 將修改推送到gitlab,

 

 點擊構建參數任務

 

 

點擊構建

 

 構建成功

 

 我再加兩個參數,有個參數名字相同了,這樣估計調用參數的時候不一定會是你要的那個值

 

 

 點擊構建,可以看到我們設置的參數。Jenkinsfile中使用了變量,就會調用這裏的參數值。

 

 

 

原文鏈接:https://blog.csdn.net/weixin_53443677/article/details/125518696

 

 

 


原文鏈接:https://blog.csdn.net/qq_15290209/article/details/126230624

https://blog.csdn.net/qq_27229113/article/details/125522388

https://blog.csdn.net/weixin_39850981/article/details/111257716

https://blog.csdn.net/weixin_48404074/article/details/125250175

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章