Jenkins持續(xù)集成入門

第一章 DevOps概念

一、什么是DevOps

DevOps是一種思想或方法論,它涵蓋開發(fā)、測(cè)試兑巾、運(yùn)維的整個(gè)過(guò)程(不僅限于Java)。DevOps強(qiáng)調(diào)軟件開發(fā)人員與軟件測(cè)試忠荞、軟件運(yùn)維蒋歌、質(zhì)量保障(QA)部門之間有效的溝通與協(xié)作帅掘。強(qiáng)調(diào)通過(guò)自動(dòng)化的方法管理軟件變更、軟件集成堂油。使軟件從構(gòu)建到測(cè)試修档、發(fā)布更加快捷、可靠府框,最終按時(shí)交付軟件吱窝。

DevOps

二、為什么當(dāng)今大公司一定要使用DevOps

2.1 傳統(tǒng)瀑布模型
  • 完整迫靖、清晰院峡、固定的需求
  • 完整、清晰系宜、固定的產(chǎn)品定義
2.2 敏捷開發(fā)模型
  • 需求頻繁變化
  • 需要快速開發(fā)
2.3 DevOps開發(fā)模型
  • 需求頻繁變化
  • 開發(fā)需要敏捷
  • 操作需要敏捷

DevOps這種軟件開發(fā)方法照激,涉及到軟件整個(gè)開發(fā)生命周期,這些活動(dòng)只能在DevOps中實(shí)現(xiàn)盹牧,而不是敏捷或瀑布俩垃。DevOps是在較短的開發(fā)周期內(nèi)開發(fā)高質(zhì)量軟件的首選方法,同時(shí)可以提高客戶滿意度汰寓。這就是為什么頂級(jí)互聯(lián)網(wǎng)公司選擇DevOps作為其業(yè)務(wù)目標(biāo)的前進(jìn)方向口柳。

三、如何落地實(shí)現(xiàn)DevOps這種理念

DevOps興起于2009年有滑,近年來(lái)由于云計(jì)算啄清、互聯(lián)網(wǎng)的發(fā)展,促進(jìn)了DevOps的基礎(chǔ)設(shè)施及工具的發(fā)展俺孙,涌現(xiàn)出了一大批優(yōu)秀的工具辣卒,這些工具包括開發(fā)、測(cè)試睛榄、運(yùn)維的各個(gè)領(lǐng)域荣茫,例如:GitHub、Git\SVN场靴、Docker啡莉、Jenkins、Hudson旨剥、Ant\Maven\Gradle咧欣、Selenium、QUnit轨帜、JMeter等等魄咕。下圖是DevOps相關(guān)的工具集

DevOps相關(guān)的工具集

四、Docker一把瑞士軍刀蚌父,讓DevOps真正落地于實(shí)踐

Docker是一個(gè)開源的應(yīng)用容器引擎哮兰,誕生于2013年初毛萌,基于Go語(yǔ)言開發(fā),dotCloud公司出品(后改名為Docker Inc)喝滞。

Docker可以讓開發(fā)者打包他們的應(yīng)用以及依賴包到一個(gè)輕量級(jí)阁将、可移植的容器中,然后發(fā)布到任何流行的Linux機(jī)器上右遭。容器是完全使用沙箱機(jī)制做盅,相互隔離。容器性能開銷極低窘哈。

Docker從17.03版本之后分為CE(Community Edition言蛇,社區(qū)版)和EE(Enterprise Edition,企業(yè)版)宵距。

  • 鏡像(Image): Docker鏡像(Image),就相當(dāng)于是一個(gè)root文件系統(tǒng),比如官方鏡像Ubuntu:16.04就包含了完整的一套Ubuntu16.04最小系統(tǒng)的root文件系統(tǒng)吨拗。

  • 容器(Container): 鏡像(Image)和容器(Container)的關(guān)系满哪,就像是面向?qū)ο蟪绦蛟O(shè)計(jì)中的類和對(duì)象一樣,鏡像是靜態(tài)的定義劝篷,容器是鏡像運(yùn)行時(shí)的實(shí)體哨鸭,容器可以被創(chuàng)建、啟動(dòng)娇妓、停止像鸡、刪除、暫停等哈恰。

  • 倉(cāng)庫(kù)(Repository): 倉(cāng)庫(kù)可以看成一個(gè)代碼控制中心只估,用來(lái)保存鏡像。

五着绷、持續(xù)集成流程

持續(xù)集成流程

第二章 DevOps實(shí)踐

一蛔钙、DevOps基礎(chǔ)環(huán)境安裝

1.1 使用系統(tǒng)說(shuō)明
  • 遠(yuǎn)程服務(wù)器:阿里云ECS,2核16G荠医,Ubuntu 18.04.64位 (服務(wù)器配置最少2核8G起步)吁脱,IP地址120.24.95.76

  • 阿里云ECS安全組開放端口:50006001 彬向、6002兼贡、60038080娃胆、8001

  • 本地電腦:Mac OS

1.2 安裝Git
1.2.1 ssh登錄ECS
AC-2:~ AC$ ssh root@120.24.95.76
root@120.24.95.76's password: 

# 按提示輸入密碼進(jìn)行登錄
1.2.2 安裝Git

更新服務(wù)器上的包索引

sudo apt-get update

安裝git

sudo apt-get install git
1.2.3 配置Git全局環(huán)境
git config --global user.name "alanchen"

git config --global user.email "chenyan900520@126.com"
1.2.4 生成ssh密鑰
ssh-keygen -t rsa -C "chenyan900520@126.com"
1.2.5 查看拷貝公鑰

如果后面需要在GitLab配置SSH Keys時(shí)遍希,可以從這里拷貝公鑰,當(dāng)然也可以用賬號(hào)密碼進(jìn)行操作

cd ~/.ssh
cat id_rsa.pub
1.3 安裝Maven
1.3.1 安裝步驟

1里烦、首先檢查是否有maven

mvn -v

2孵班、search

apt-cache search maven

3涉兽、安裝

sudo apt-get install maven

4、檢查是否安裝成功

mvn -v

安裝成功會(huì)顯示版本號(hào)

root@iZwz96ew7wfkgebgbq9crbZ:~# mvn -v
Apache Maven 3.6.0
Maven home: /usr/share/maven
Java version: 11.0.13, vendor: Ubuntu, runtime: /usr/lib/jvm/java-11-openjdk-amd64
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "4.15.0-166-generic", arch: "amd64", family: "unix"
root@iZwz96ew7wfkgebgbq9crbZ:~#
1.3.2 配置maven國(guó)內(nèi)鏡像篙程,提高下載速度

1枷畏、找到配置文件settings.xml位置
通過(guò)mvn -v可以顯示maven的安裝目錄,在安裝目錄下就有settings.xml配置文件虱饿。

cd /usr/share/maven/conf

2拥诡、編輯settings.xml配置文件

vi settings.xml

3、修改settings.xml配置文件
找到<mirrors></mirrors>標(biāo)簽氮发,在這個(gè)標(biāo)簽中加入國(guó)內(nèi)的鏡像即可渴肉,這里我推薦maven阿里云中央倉(cāng)庫(kù)。

<mirrors>

  <mirror>
      <id>alimaven</id>
      <name>aliyun maven</name>
      <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
      <mirrorOf>central</mirrorOf>        
    </mirror>

</mirrors>
加入國(guó)內(nèi)鏡像
1.4 安裝Docker
1.4.1 安裝

使用官方安裝腳本自動(dòng)安裝爽冕,安裝命令如下:

curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun

也可以使用國(guó)內(nèi) daocloud 一鍵安裝命令:

curl -sSL https://get.daocloud.io/docker | sh
1.4.2 配置鏡像加速器(非必要)
容器鏡像服務(wù)

二仇祭、安裝Docker私有倉(cāng)庫(kù)

2.1 安裝步驟

1、搜索鏡像

docker search registry

2颈畸、拉取鏡像

docker pull registry

3乌奇、創(chuàng)建容器

#創(chuàng)建存放鏡像的目錄

mkdir -p /opt/data/docker/  
#創(chuàng)建容器 -p指定端口 -v數(shù)據(jù)卷掛載

docker run -it -d -p 5000:5000 -v /opt/data/docker:/tmp/registry registry

ECS安全組需要開放5000端口

2.2 配置私有倉(cāng)庫(kù)地址
vi /etc/docker/deamon.json

配置內(nèi)容

{
  “insecure-registries”:[“120.24.95.76:5000”]
}
配置內(nèi)容
2.3 重啟

1、重啟配置

sudo systemctl daemon-reload

2眯娱、重啟Docker

sudo systemctl restart docker

3礁苗、查看倉(cāng)庫(kù)容器狀態(tài)

docker ps -a

倉(cāng)庫(kù)容器當(dāng)前為退出狀態(tài)

root@iZwz96ew7wfkgebgbq9crbZ:/usr/share/maven/conf# docker ps -a
CONTAINER ID   IMAGE      COMMAND                  CREATED         STATUS         PORTS                                       NAMES
22db63715a88   registry   "/entrypoint.sh /etc…"   4 minutes ago   Up 4 minutes   0.0.0.0:5000->5000/tcp, :::5000->5000/tcp   thirsty_euclid
root@iZwz96ew7wfkgebgbq9crbZ:/usr/share/maven/conf# 

4、啟動(dòng)本地倉(cāng)庫(kù)容器

docker start 22db63715a88

啟動(dòng)

root@iZwz96ew7wfkgebgbq9crbZ:/usr/share/maven/conf# docker start 22db63715a88
22db63715a88
root@iZwz96ew7wfkgebgbq9crbZ:/usr/share/maven/conf#
2.4 訪問Docker私有倉(cāng)庫(kù)

在瀏覽器中訪問http://120.24.95.76:5000/v2/_catalog

訪問結(jié)果

三徙缴、安裝GitLab

下面將通過(guò)Docker安裝GitLab试伙,如果在ECS宿主機(jī)上直接安裝GitLab,可參考我另外一篇文章 Ubuntu部署GitLab

3.1 Docker安裝GitLab步驟

1于样、查找GitLab鏡像

docker search gitlab

2疏叨、拉取GitLab鏡像

docker pull gitlab/gitlab-ce

3、查看本地鏡像

docker images
root@iZwz96ew7wfkgebgbq9crbZ:/usr/share/maven/conf# docker images
REPOSITORY         TAG       IMAGE ID       CREATED        SIZE
gitlab/gitlab-ce   latest    508bfaaaf273   4 days ago     2.36GB
registry           latest    b8604a3fe854   2 months ago   26.2MB
root@iZwz96ew7wfkgebgbq9crbZ:/usr/share/maven/conf# 

4穿剖、建立映射文件
在本機(jī)建立3個(gè)目錄考廉,分別為:配置文件、數(shù)據(jù)文件携御、日志文件昌粤。GitLab容器通過(guò)掛載本機(jī)目錄啟動(dòng)后就可以映射到本機(jī)。主要出于以下兩點(diǎn)原因:
1啄刹、后續(xù)可以直接在本機(jī)查看和編輯涮坐,不用再進(jìn)入容器操作。
2誓军、容器是一個(gè)虛擬化的技術(shù)袱讹,容器掛了之后,容器里的數(shù)據(jù)就沒了,數(shù)據(jù)不安全

創(chuàng)建文件:

# 配置文件
mkdir -p /home/gitlab/etc

# 數(shù)據(jù)文件
mkdir -p /home/gitlab/data

# 日志文件
mkdir -p /home/gitlab/logs

5捷雕、啟動(dòng)容器

docker run --name='gitlab' -d \
--publish 6002:443  --publish 6001:80 --publish 6003:22 \
-v /home/gitlab/etc:/etc/gitlab \
-v /home/gitlab/data:/var/opt/gitlab \
-v /home/gitlab/logs:/var/log/gitlab \
gitlab/gitlab-ce:latest

https443端口用6002端口映射椒丧,web訪問端口80用6001端口映射(GitLab默認(rèn)用的是80端口),ssh端口22用6003端口映射救巷。(備注ECS阿里云要開放6001壶熏、6002、6003端口)

root@iZ0jldusfvkkz0zfl9gsdaZ:/home/gitlab/etc# docker run --name='gitlab' -d \
> --publish 6002:443  --publish 6001:80 --publish 6003:22 \
> -v /home/gitlab/etc:/etc/gitlab \
> -v /home/gitlab/data:/var/opt/gitlab \
> -v /home/gitlab/logs:/var/log/gitlab \
> gitlab/gitlab-ce:latest
56a55cb01c9df7c9a5bee514b04adf131b158ae83c44fedf9570c469a6328f75

可以通過(guò)docker logs -f gitlab 命令查看啟動(dòng)日志浦译,通過(guò)docker ps -a 查看容器啟動(dòng)狀態(tài)棒假。

root@iZwz96ew7wfkgebgbq9crbZ:~# docker ps -a
CONTAINER ID   IMAGE                     COMMAND                  CREATED         STATUS                            PORTS                                                                                                                   NAMES
02bde20ab6df   gitlab/gitlab-ce:latest   "/assets/wrapper"        2 minutes ago   Up 2 minutes (health: starting)   0.0.0.0:6003->22/tcp, :::6003->22/tcp, 0.0.0.0:6001->80/tcp, :::6001->80/tcp, 0.0.0.0:6002->443/tcp, :::6002->443/tcp   gitlab
22db63715a88   registry                  "/entrypoint.sh /etc…"   5 hours ago     Up 5 hours                        0.0.0.0:5000->5000/tcp, :::5000->5000/tcp                                                                               thirsty_euclid
root@iZwz96ew7wfkgebgbq9crbZ:~# 

狀態(tài)為health: starting表示還在啟動(dòng)中。

6精盅、訪問GitLab
http://120.24.95.76:6001

成功訪問GitLab
3.2 修改root默認(rèn)密碼
3.2.1 查看容器帽哑,GitLab是否正常運(yùn)行
docker ps -a

Up為啟動(dòng)狀態(tài)

root@iZwz96ew7wfkgebgbq9crbZ:~# docker ps -a
CONTAINER ID   IMAGE                     COMMAND                  CREATED         STATUS                   PORTS                                                                                                                   NAMES
02bde20ab6df   gitlab/gitlab-ce:latest   "/assets/wrapper"        6 minutes ago   Up 6 minutes (healthy)   0.0.0.0:6003->22/tcp, :::6003->22/tcp, 0.0.0.0:6001->80/tcp, :::6001->80/tcp, 0.0.0.0:6002->443/tcp, :::6002->443/tcp   gitlab
22db63715a88   registry                  "/entrypoint.sh /etc…"   5 hours ago     Up 5 hours               0.0.0.0:5000->5000/tcp, :::5000->5000/tcp                                                                               thirsty_euclid
root@iZwz96ew7wfkgebgbq9crbZ:~# 

3.2.2 進(jìn)入GitLab的容器中
# docker exec -it(gitlab的容器名稱或id) bash

docker exec -it 63cc520288bd bash

// 或者
docker exec -it gitlab bash
root@iZwz96ew7wfkgebgbq9crbZ:~# docker exec -it gitlab bash
root@02bde20ab6df:/# 

3.2.3 修改密碼

1、使用以下命令啟動(dòng)Ruby on Rails控制臺(tái)

gitlab-rails console

2叹俏、等待控制臺(tái)加載完畢并找到root用戶妻枕,稍微要多等待一會(huì)

user = User.where(id: 1).first

或者

user = User.find_by(email: 'admin@example.com')

3、更改密碼

user.password='123456abc'

user.password_confirmation='123456abc'

4粘驰、保存更改

user.save

操作過(guò)程:

root@iZwz96ew7wfkgebgbq9crbZ:~# docker exec -it gitlab bash
root@02bde20ab6df:/# gitlab-rails console
--------------------------------------------------------------------------------
 Ruby:         ruby 2.7.5p203 (2021-11-24 revision f69aeb8314) [x86_64-linux]
 GitLab:       14.6.2 (0a901d60f8a) FOSS
 GitLab Shell: 13.22.1
 PostgreSQL:   12.7
--------------------------------------------------------------------------------
Loading production environment (Rails 6.1.4.1)
irb(main):001:0> user = User.where(id: 1).first
=> #<User id:1 @root>
irb(main):002:0> user = User.find_by(email: 'admin@example.com')
=> #<User id:1 @root>
irb(main):003:0> user.password='123456abc'
=> "123456abc"
irb(main):004:0> user.password_confirmation='123456abc'
=> "123456abc"
irb(main):005:0> user.save
=> true
irb(main):006:0> 

5屡谐、用root賬號(hào)以及剛設(shè)置的密碼登錄GitLab


登錄GitLab

6、登錄成功


登錄成功
3.3 配置

按上面的方式晴氨,GitLab容器運(yùn)行沒問題,但在GitLab上創(chuàng)建項(xiàng)目的時(shí)候碉输,生成項(xiàng)目的URL訪問地址是按容器的hostname來(lái)生成的籽前,也就是容器id(如:http://02bde20ab6df/root/test.git)。作為GitLab服務(wù)器敷钾,我們需要一個(gè)固定的URL訪問地址枝哄,于是需要配置gitlab.rb(宿主機(jī)路徑:/home/gitlab/comfig/gitlab.rb

訪問地址為容器id
3.3.1 配置gitlab.rb
cd /home/gitlab/etc

vi gitlab.rb

可以使用/來(lái)查找關(guān)鍵字,找到指定的內(nèi)容阻荒,然后通過(guò)n來(lái)下一個(gè)查找挠锥,編輯內(nèi)容:

# 在GitLab創(chuàng)建項(xiàng)目時(shí)候http地址的host(如果不加端口,端口默認(rèn)為80)
external_url 'http://120.24.95.76:6001'

# 在GitLab創(chuàng)建項(xiàng)目時(shí)候ssh地址的host(不用添加端口侨赡,不用加http)
gitlab_rails['gitlab_ssh_host'] = '120.24.95.76'

# Docker run 的時(shí)候我們把22端口映射為外部的6003了蓖租,這里修改下
gitlab_rails['gitlab_shell_ssh_port'] = 6003
改配置

跳坑重點(diǎn)強(qiáng)調(diào):

  • 22端口映射問題:如果不映射22端口,ssh克隆時(shí)一直提示輸入密碼羊壹,且密碼錯(cuò)誤蓖宦。ssh傳輸都是通過(guò)22端口傳輸?shù)模话惚凰拗鞯膕shd服務(wù)占用油猫。所以GitLab容器的22端口不能直接映射到宿主的22端口稠茂,要換個(gè)其他端口,比如6003情妖。這樣睬关,通過(guò)端口映射诱担,客戶端的ssh傳輸請(qǐng)求就能達(dá)到容器中的GitLab服務(wù)。

  • external_url默認(rèn)為80端口問題:請(qǐng)注意电爹,我上面的配置external_url是有寫端口號(hào)6001的蔫仙,如果不寫,則默認(rèn)為80端口藐不。此處有兩個(gè)坑:

第一個(gè)坑:如果external_url不寫端口6001匀哄,而用默認(rèn)的80端口,那項(xiàng)目的Clone with HTTP地址也是不帶端口的(默認(rèn)為80端口)雏蛮,由于80端口的原因涎嚼,我們?cè)趃it clone http 地址時(shí)會(huì)clone失敗。即使在下面要修改的gitlab.yml文件里挑秉,將port端口設(shè)置為6001法梯,保存退出遭殉,當(dāng)容器一啟動(dòng)再來(lái)看該文件內(nèi)容脉课,port又會(huì)變成默認(rèn)的80端口。

第二個(gè)坑:如果external_url寫了端口6001苦银,重啟配置姻灶,容器也能正常重啟成功铛绰,但GitLab卻訪問不了了。問題的原因就出在external_url地址設(shè)置上产喉。
GitLab默認(rèn)的http訪問端口號(hào)為80端口捂掰,如果想更改端口號(hào),一般是通過(guò)docker run時(shí)設(shè)置端口映射曾沈,將80端口映射為其他端口这嚣。例如前面的操作:

docker run --name='gitlab' -d \
--publish 6002:443  --publish 6001:80 --publish 6003:22 \
-v /home/gitlab/etc:/etc/gitlab \
-v /home/gitlab/data:/var/opt/gitlab \
-v /home/gitlab/logs:/var/log/gitlab \
gitlab/gitlab-ce:latest

這里將GitLab的http端口改為6001,如果你這時(shí)修改external_url地址為http://ip:6001塞俱,那GitLab肯定訪問不了姐帚,因?yàn)槟阋呀?jīng)將內(nèi)部的端口號(hào)修改為6001端口了,而你通過(guò)docker run映射出來(lái)的端口號(hào)是80端口障涯,所以不可能訪問到罐旗。那該怎么辦?既然你已經(jīng)將內(nèi)部的端口號(hào)由80端口改為6001端口唯蝶,這時(shí)候你就將容器停止并刪除尤莺,啟動(dòng)容器時(shí),將端口由80改成6001

docker run --name='gitlab' -d \
--publish 6002:443  --publish 6001:6001 --publish 6003:22 \
-v /home/gitlab/etc:/etc/gitlab \
-v /home/gitlab/data:/var/opt/gitlab \
-v /home/gitlab/logs:/var/log/gitlab \
gitlab/gitlab-ce:latest
3.3.2 配置gitlab.yml
cd /home/gitlab/data/gitlab-rails/etc

vi gitlab.yml
  gitlab:
    ## Web server settings (note: host is the FQDN, do not include http://)
    host: 120.24.95.76
    port: 6001
    https: false
舊的內(nèi)容
修改后的內(nèi)容
3.3.3 停用GitLab容器
docker stop gitlab
3.3.4 刪除GitLab容器
docker rm -f gitlab

# 或者通過(guò)id刪除
docker rm -f 0535d33bf034
3.3.5 啟動(dòng)GitLab容器
docker run --name='gitlab' -d \
--publish 6002:443  --publish 6001:6001 --publish 6003:22 \
-v /home/gitlab/etc:/etc/gitlab \
-v /home/gitlab/data:/var/opt/gitlab \
-v /home/gitlab/logs:/var/log/gitlab \
gitlab/gitlab-ce:latest

注意:兩個(gè)端口都是6001

3.4 登錄GitLab創(chuàng)建devops項(xiàng)目

http://120.24.95.76:6001

創(chuàng)建項(xiàng)目
創(chuàng)建項(xiàng)目

我們可以看到項(xiàng)目的訪問地址為IP生棍,不是容器ID了颤霎,SSH地址后面是6003端口,HTTP地址后面是6001端口。

項(xiàng)目地址
3.5 GitLab創(chuàng)建用戶
Admin管理
用戶列表
創(chuàng)建賬號(hào)
修改密碼
3.6 項(xiàng)目授權(quán)

devops項(xiàng)目授權(quán)給chenyan用戶

項(xiàng)目用戶管理
邀請(qǐng)用戶加入項(xiàng)目

chenyan賬號(hào)登錄GitLab友酱,即可以看到devops項(xiàng)目

chenyan賬號(hào)登錄
devops項(xiàng)目
3.7 GitLab配置SSH Keys

chenyan用戶配置SSH Keys

3.7.1 配置Git全局環(huán)境

在本地電腦操作

git config --global user.name "chenyan"

git config --global user.email "271961730@qq.com"
3.7.2 生成ssh密鑰
ssh-keygen -t rsa -C "271961730@qq.com"
3.7.3 拷貝公鑰
cd ~/.ssh
cat id_rsa.pub
AC-2:~ AC$ cd ~/.ssh
AC-2:.ssh AC$ cat id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2kYvXyZRehV65k96uuVlfCxbQrlCTTtdYdSOm8ZOeywo6+vqWpQjVyDobeQKANOswOr09YR8UwRd5VjssLI7dh4SHuvvZpgWaPGZf1HxT9N5ssIUNTKLe36O5QXeQQ41wTF6nNRoFkWbErzzw+DqUTBYvVJGVpfrJMO4V/SFZk4WceQT1zJ2E3lBI6hjbtuIgGSqYK6trutuCnEw+DW7zkrTxzKQqVzB1h1m0dTpqT+rwl3j16avmyiKFWfL1uMvGJfeTP7XNEsTaQXo0eseByVxI8NNPguPihGPp0Rt7Bx7SUFam+2zhg6LdMqXwPiXft8DPI8YiC0zHvKpYC5fB 271961730@qq.com
AC-2:.ssh AC$ 
3.7.4 配置SSH Keys

chenyan賬號(hào)登錄GitLab

設(shè)置
配置SSH Keys
3.7.5 拉取項(xiàng)目到本地

進(jìn)入本地電腦code晴音,用來(lái)存放devops項(xiàng)目

cd ~/code/

1、通過(guò)SSH方式clone代碼

git clone ssh://git@120.24.95.76:6003/root/devops.git
AC-2:.ssh AC$ cd ~/code/
AC-2:code AC$ git clone ssh://git@120.24.95.76:6003/root/devops.git
Cloning into 'devops'...
The authenticity of host '[120.24.95.76]:6003 ([120.24.95.76]:6003)' can't be established.
ECDSA key fingerprint is SHA256:iwQBJ3+2tzc3oM1K4l8qaLg5Nl6UtM0EM8fXiNhpyyU.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[120.24.95.76]:6003' (ECDSA) to the list of known hosts.
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (3/3), done.
AC-2:code AC$ 

2缔杉、或者可以通過(guò)HTTP輸入賬號(hào)密碼的方式clone代碼
先將剛clone的代碼刪除

git clone http://120.24.95.76:6001/root/devops.git
AC-2:code AC$ git clone http://120.24.95.76:6001/root/devops.git
Cloning into 'devops'...
Username for 'http://120.24.95.76:6001': chenyan
Password for 'http://chenyan@120.24.95.76:6001': 
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
AC-2:code AC$ 

四锤躁、編寫devops項(xiàng)目代碼并提交到遠(yuǎn)程倉(cāng)庫(kù)

4.1 創(chuàng)建SpringBoot項(xiàng)目devops
創(chuàng)建項(xiàng)目
創(chuàng)建項(xiàng)目

設(shè)置項(xiàng)目名稱


項(xiàng)目名稱

添加Spring Web依賴


加依賴

覆蓋剛剛clone的項(xiàng)目目錄


項(xiàng)目存放目錄
4.2 編寫restful接口

編寫controller代碼

@RestController
@RequestMapping("devops")
public class DevOpsController {

    @GetMapping("hello")
    public String hello(){
        return "AlanChen";
    }
}
項(xiàng)目截圖

自動(dòng)生成的pom.xml文件為

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.alanchen</groupId>
    <artifactId>devops</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>devops</name>
    <description>Demo project for DevOps</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

訪問controller服務(wù)接口
http://127.0.0.1:8080/devops/hello

訪問hello接口
4.3 將本地的devops項(xiàng)目代碼提交到遠(yuǎn)程倉(cāng)庫(kù)
cd ~/code/devops

git add .

git commit -m "add hello"

git push
4.4 登錄GitLab查看項(xiàng)目情況
剛提交的代碼

五、Docker制作SpringBoot項(xiàng)目工程鏡像容器

5.1 打包devops項(xiàng)目為jar
打包
jar文件
5.2 將jar包上傳到阿里云ECS服務(wù)器

先在ECS服務(wù)器上或详,建立/data/docker-demo目錄

mkdir -p /data/devops-demo

上傳jar文件

scp /Users/AC/code/devops/target/devops-0.0.1-SNAPSHOT.jar root@120.24.95.76:/data/devops-demo/devops-0.0.1-SNAPSHOT.jar

5.3 編寫Dockerfile文件

阿里云ECS系羞,進(jìn)入/data/devops-demo目錄,編寫Dockerfile文件

cd /data/devops-demo
vi Dockerfile

文件內(nèi)容

# 基礎(chǔ)鏡像使用java
FROM java:8
# 作者
MAINTAINER eangulee chenyan900520@126.com
# VOLUME 指定了臨時(shí)文件目錄為/tmp霸琴。
# 其效果是在主機(jī) /var/lib/docker 目錄下創(chuàng)建了一個(gè)臨時(shí)文件椒振,并鏈接到容器的/tmp
VOLUME /tmp 
# 將jar包添加到容器中并更名為app.jar
ADD *.jar app.jar 
# 運(yùn)行jar包
RUN bash -c 'touch /app.jar'
#指定容器啟動(dòng)時(shí)要執(zhí)行的命令,但如果存在CMD指令梧乘,CMD中的參數(shù)會(huì)被附加到ENTRYPOINT指令的后面
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

VOLUME指定了臨時(shí)文件目錄為/tmp澎迎。其效果是在主機(jī)/var/lib/docker 目錄下創(chuàng)建了一個(gè)臨時(shí)文件,并鏈接到容器的/tmp选调。該步驟是可選的夹供,如果涉及到文件系統(tǒng)的應(yīng)用就很有必要了。/tmp目錄用來(lái)持久化到Docker數(shù)據(jù)文件夾仁堪,因?yàn)镾pring Boot使用的內(nèi)嵌 Tomcat 容器默認(rèn)使用/tmp作為工作目錄項(xiàng)目的 jar 文件作為 app.jar添加到容器的ENTRYPOINT執(zhí)行項(xiàng)目app.jar哮洽。為了縮短Tomcat啟動(dòng)時(shí)間,添加一個(gè)系統(tǒng)屬性指向/dev/./urandom作為Entropy Source弦聂。如果是第一次打包鸟辅,它會(huì)自動(dòng)下載Java 8的鏡像作為基礎(chǔ)鏡像,以后再制作鏡像的時(shí)候就不會(huì)再下載了横浑。

/data/devops-demo目錄文件如下

root@iZwz9doa4kcnsjcv8fgt8pZ:/data/devops-demo# ls
devops-0.0.1-SNAPSHOT.jar  Dockerfile
root@iZwz9doa4kcnsjcv8fgt8pZ:/data/devops-demo# 
5.4 制作鏡像

/data/devops-demo目錄下執(zhí)行命令剔桨,-t 參數(shù)是指定此鏡像的tag名

docker build -t devopsdemo .

注意:最后有一個(gè)點(diǎn).

執(zhí)行過(guò)程

root@iZwz9doa4kcnsjcv8fgt8pZ:/data/devops-demo# docker build -t devopsdemo .
Sending build context to Docker daemon  17.56MB
Step 1/6 : FROM java:8
8: Pulling from library/java
5040bd298390: Pull complete 
fce5728aad85: Pull complete 
76610ec20bf5: Pull complete 
60170fec2151: Pull complete 
e98f73de8f0d: Pull complete 
11f7af24ed9c: Pull complete 
49e2d6393f32: Pull complete 
bb9cdec9c7f3: Pull complete 
Digest: sha256:c1ff613e8ba25833d2e1940da0940c3824f03f802c449f3d1815a66b7f8c0e9d
Status: Downloaded newer image for java:8
 ---> d23bdf5b1b1b
Step 2/6 : MAINTAINER eangulee chenyan900520@126.com
 ---> Running in 614c9c58a554
Removing intermediate container 614c9c58a554
 ---> ec0fb00f60c5
Step 3/6 : VOLUME /tmp
 ---> Running in 6bc1644cad98
Removing intermediate container 6bc1644cad98
 ---> a808a7c8ff24
Step 4/6 : ADD *.jar app.jar
 ---> 92fa72757b8c
Step 5/6 : RUN bash -c 'touch /app.jar'
 ---> Running in 17dbf2e59690
Removing intermediate container 17dbf2e59690
 ---> 2929030bfdb3
Step 6/6 : ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
 ---> Running in 5cdb4c0029ec
Removing intermediate container 5cdb4c0029ec
 ---> f2149993ff24
Successfully built f2149993ff24
Successfully tagged devopsdemo:latest
root@iZwz9doa4kcnsjcv8fgt8pZ:/data/devops-demo# 

制作完成后通過(guò)docker images命令查看我們制作的鏡像

root@iZwz9doa4kcnsjcv8fgt8pZ:/data/devops-demo# docker images
REPOSITORY         TAG       IMAGE ID       CREATED              SIZE
devopsdemo         latest    f2149993ff24   About a minute ago   678MB
gitlab/gitlab-ce   latest    508bfaaaf273   4 days ago           2.36GB
registry           latest    b8604a3fe854   2 months ago         26.2MB
java               8         d23bdf5b1b1b   4 years ago          643MB
root@iZwz9doa4kcnsjcv8fgt8pZ:/data/devops-demo# 
5.5 啟動(dòng)容器
docker run -d -p 8001:8080 devopsdemo

-d參數(shù)是讓容器后臺(tái)運(yùn)行
-p 是做端口映射屉更,此時(shí)將服務(wù)器中的8001端口映射到容器中的8080端口(項(xiàng)目中端口默認(rèn)是8080)徙融。

注意:阿里云ECS要開放8001端口

5.6 驗(yàn)證

在瀏覽器中訪問http://120.24.95.76:8001/devops/hello,如果能訪問到hello接口瑰谜,表示Dcoker部署SpringBoot項(xiàng)目成功欺冀。

六、使用maven構(gòu)建鏡像

上邊構(gòu)建的過(guò)程是通過(guò)手工一步一步完成萨脑,maven提供docker-maven-plugin插件可以完成從打包到構(gòu)建鏡像隐轩、構(gòu)建容器等過(guò)程。

更多信息渤早,請(qǐng)參考:docker-maven-plugin官方地址

6.1 編寫pom_docker.xml

1职车、創(chuàng)建pom_docker.xml文件
2、將項(xiàng)目中pom.xml文件的內(nèi)容全部復(fù)制到pom_docker.xml文件中
3、在pom_docker.xml文件中加入docker-maven-plugin插件內(nèi)容

        <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>1.2.2</version>

                <!--docker 鏡像相關(guān)的配置信息-->
                <configuration>
                    <!--鏡像名悴灵,這里用工程名:devops-->
                    <imageName>${project.artifactId}</imageName>
                    <!--<imageName>devopsdemo</imageName>-->

                    <!-- 指定 Dockerfile 路徑-->
                    <dockerDirectory>${project.basedir}/src/main/resources</dockerDirectory>
                    <!--<dockerDirectory>${basedir}/docker</dockerDirectory>-->

                    <!--TAG,這里用工程版本號(hào) -->
                    <imageTags>
                        <imageTag>${project.version}</imageTag>
                    </imageTags>

                    <!--構(gòu)建鏡像的配置信息 -->
                    <resources>
                        <resource>
                            <targetPath>/</targetPath>
                            <directory>${project.build.directory}</directory>
                            <include>${project.artifactId}-${project.version}.jar</include>
                        </resource>
                    </resources>
                </configuration>
            </plugin>

pom_docker.xml文件全部?jī)?nèi)容如下

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.alanchen</groupId>
    <artifactId>devops</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>devops</name>
    <description>Demo project for DevOps</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>1.2.2</version>

                <!--docker 鏡像相關(guān)的配置信息-->
                <configuration>
                    <!--鏡像名扛芽,這里用工程名:devops-->
                    <imageName>${project.artifactId}</imageName>
                    <!--<imageName>devopsdemo</imageName>-->

                    <!-- 指定 Dockerfile 路徑-->
                    <dockerDirectory>${project.basedir}/src/main/resources</dockerDirectory>
                    <!--<dockerDirectory>${basedir}/docker</dockerDirectory>-->

                    <!--TAG,這里用工程版本號(hào) -->
                    <imageTags>
                        <imageTag>${project.version}</imageTag>
                    </imageTags>

                    <!--構(gòu)建鏡像的配置信息 -->
                    <resources>
                        <resource>
                            <targetPath>/</targetPath>
                            <directory>${project.build.directory}</directory>
                            <include>${project.artifactId}-${project.version}.jar</include>
                        </resource>
                    </resources>
                </configuration>
            </plugin>

        </plugins>
    </build>

</project>


6.2 編寫Dockerfile文件

在工程的resources目錄下新建Dockerfile文件,文件內(nèi)容和上面的Dockerfile文件內(nèi)容一樣积瞒。

# 基礎(chǔ)鏡像使用java
FROM java:8
# 作者
MAINTAINER eangulee chenyan900520@126.com
# VOLUME 指定了臨時(shí)文件目錄為/tmp川尖。
# 其效果是在主機(jī) /var/lib/docker 目錄下創(chuàng)建了一個(gè)臨時(shí)文件,并鏈接到容器的/tmp
VOLUME /tmp 
# 將jar包添加到容器中并更名為app.jar
ADD *.jar app.jar 
# 運(yùn)行jar包
RUN bash -c 'touch /app.jar'
#指定容器啟動(dòng)時(shí)要執(zhí)行的命令茫孔,但如果存在CMD指令叮喳,CMD中的參數(shù)會(huì)被附加到ENTRYPOINT指令的后面
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

項(xiàng)目目錄如下

項(xiàng)目目錄
6.3 提交代碼

將本地項(xiàng)目devops編輯的代碼全部都提交到遠(yuǎn)程GitLab倉(cāng)庫(kù)。

6.4連接登錄阿里云ECS宿主機(jī)
AC-2:devops AC$ ssh root@120.24.95.76

# 按提示輸入密碼登錄
6.5 拉取devops項(xiàng)目代碼

1缰贝、進(jìn)入目錄

cd /data/devops-demo

2馍悟、clone代碼

git clone http://120.24.95.76:6001/root/devops.git
root@iZwz96ew7wfkgebgbq9crbZ:/data/devops-demo# ls
devops
root@iZwz96ew7wfkgebgbq9crbZ:/data/devops-demo#

3、進(jìn)入工程目錄

cd devops

4揩瞪、打包構(gòu)建鏡像

mvn -f pom_docker.xml clean package -DskipTests docker:build

打包過(guò)程會(huì)去下載依賴包赋朦,如果下載速度慢,可以將下載鏡像地址改成國(guó)內(nèi)地址李破。

成功構(gòu)建結(jié)果如下:

 ---> Running in 0e76046ca6e7
Removing intermediate container 0e76046ca6e7
 ---> 6b505550ff52
Step 6/6 : ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

 ---> Running in 1bd9886f3c3a
Removing intermediate container 1bd9886f3c3a
 ---> ce9d7605919b
ProgressMessage{id=null, status=null, stream=null, error=null, progress=null, progressDetail=null}
Successfully built ce9d7605919b
Successfully tagged devops:latest
[INFO] Built devops
[INFO] Tagging devops with 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  04:38 min
[INFO] Finished at: 2022-01-16T16:37:09+08:00
[INFO] ------------------------------------------------------------------------
root@iZwz96ew7wfkgebgbq9crbZ:/data/devops-demo/devops#

5宠哄、制作完成后通過(guò)docker images命令查看我們制作的鏡像

docker images 
root@iZwz96ew7wfkgebgbq9crbZ:/data/devops-demo/devops# docker images 
REPOSITORY         TAG              IMAGE ID       CREATED          SIZE
devops             0.0.1-SNAPSHOT   ce9d7605919b   38 seconds ago   678MB
devops             latest           ce9d7605919b   38 seconds ago   678MB
gitlab/gitlab-ce   latest           508bfaaaf273   4 days ago       2.36GB
registry           latest           b8604a3fe854   2 months ago     26.2MB
java               8                d23bdf5b1b1b   5 years ago      643MB
root@iZwz96ew7wfkgebgbq9crbZ:/data/devops-demo/devops# 

5、創(chuàng)建啟動(dòng)容器

docker run -d -p 8002:8080 devops:0.0.1-SNAPSHOT

備注:阿里云ECS安全組要開放8002端口嗤攻。

6毛嫉、驗(yàn)證
在瀏覽器中訪問http://120.24.95.76:8002/devops/hello,如果能訪問到hello接口妇菱,表示maven構(gòu)建鏡像啟動(dòng)容器成功承粤。

成功

七、ECS宿主機(jī)安裝Jenkins

安裝步驟可參考我另外一篇文章Ubuntu安裝Jenkins

八闯团、Jenkins持續(xù)集成

目標(biāo):通過(guò)Jenkins持續(xù)集成辛臊,git提交代碼后,自動(dòng)編譯打包發(fā)布程序房交。

8.1 使用dockerfile-maven-plugin插件

在上面介紹了使用Spotify公司開發(fā)的docker-maven-plugin插件來(lái)構(gòu)建Docker鏡像彻舰。然而在如下所示官方申明中,Spotify官方已經(jīng)不再推薦使用該插件:

docker-maven-plugin

上面說(shuō)明了不再推薦使用該插件的原因候味,轉(zhuǎn)而推薦了另外一款由該公司開發(fā)的Maven插件dockerfile-maven-plugin刃唤。下面我們使用dockerfile-maven-plugin插件來(lái)構(gòu)建Docke鏡像

8.1.1 編寫pom_docker_registry.xml文件

在devops工程目錄下編寫pom_docker_registry.xml文件。

1白群、創(chuàng)建pom_docker_registry文件

2尚胞、將項(xiàng)目中pom_docker.xml文件的內(nèi)容全部復(fù)制到
pom_docker_registry.xml文件中

3、在pom_docker_registry.xml文件中更改plugins標(biāo)簽內(nèi)的內(nèi)容

          <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>dockerfile-maven-plugin</artifactId>
                <version>1.4.13</version>

                <executions>
                    <execution>
                        <id>default</id>
                        <goals>
                            <goal>build</goal>
                            <goal>push</goal>
                        </goals>
                    </execution>
                </executions>

                <!--docker 鏡像相關(guān)的配置信息-->
                <configuration>
                    <repository>120.24.95.76:5000/${project.artifactId}</repository>
                    <tag>${project.version}</tag>
                    <buildArgs>
                        <JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
                    </buildArgs>
                </configuration>
            </plugin>
        </plugins></imageName>

pom_docker_registry.xml文件全部?jī)?nèi)容如下

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.alanchen</groupId>
    <artifactId>devops</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>devops</name>
    <description>Demo project for DevOps</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>dockerfile-maven-plugin</artifactId>
                <version>1.4.13</version>

                <executions>
                    <execution>
                        <id>default</id>
                        <goals>
                            <goal>build</goal>
                            <goal>push</goal>
                        </goals>
                    </execution>
                </executions>

                <!--docker 鏡像相關(guān)的配置信息-->
                <configuration>
                    <repository>120.24.95.76:5000/${project.artifactId}</repository>
                    <tag>${project.version}</tag>
                    <buildArgs>
                        <JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
                    </buildArgs>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

可以看到帜慢,該插件的配置比docker-maven-plugin更簡(jiǎn)單了笼裳。repository指定docker鏡像的repo名字唯卖。tag指定docker鏡像的tag。buildArgs可以指定一個(gè)或多個(gè)變量躬柬,傳遞給Dockerfile耐床,在Dockerfile中通過(guò)ARG指令進(jìn)行引用。

另外楔脯,可以在execution中同時(shí)指定build和push目標(biāo)撩轰。當(dāng)運(yùn)行mvn package時(shí),會(huì)自動(dòng)執(zhí)行build目標(biāo)昧廷,構(gòu)建Docker鏡像堪嫂。當(dāng)運(yùn)行mvn deploy命令時(shí),會(huì)自動(dòng)執(zhí)行push目標(biāo)木柬,將Docker鏡像push到Docker倉(cāng)庫(kù)皆串。

4、增加Dockerfile文件
在項(xiàng)目根目錄(和pom文件在同一級(jí))新建一個(gè)Dokerfile文件眉枕,文件內(nèi)容如下:

# 基礎(chǔ)鏡像使用java
FROM java:8
# 作者
MAINTAINER eangulee chenyan900520@126.com
# VOLUME 指定了臨時(shí)文件目錄為/tmp恶复。
# 其效果是在主機(jī) /var/lib/docker 目錄下創(chuàng)建了一個(gè)臨時(shí)文件,并鏈接到容器的/tmp
VOLUME /tmp
# 將jar包添加到容器中并更名為app.jar
ARG JAR_FILE
ADD target/${JAR_FILE} /app.jar
# 運(yùn)行jar包
RUN bash -c 'touch /app.jar'
#指定容器啟動(dòng)時(shí)要執(zhí)行的命令速挑,但如果存在CMD指令谤牡,CMD中的參數(shù)會(huì)被附加到ENTRYPOINT指令的后面
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

5、項(xiàng)目目錄如下


項(xiàng)目目錄

6姥宝、提交代碼
將本地項(xiàng)目devops編輯的代碼全部都提交到遠(yuǎn)程GitLab倉(cāng)庫(kù)翅萤。

8.1.2 修改maven setting.xml配置

先找到配置文件settings.xml位置,通過(guò)mvn -v可以顯示maven的安裝目錄腊满,在安裝目錄下就有settings.xml配置文件套么。在pluginGroups中增加一個(gè)com.spotify

vi /usr/share/maven/conf/settings.xml
setting.xml配置
8.2 Jenkins集成
8.2.1 Jenkins創(chuàng)建持續(xù)集成任務(wù)
新建Item
創(chuàng)建任務(wù)
描述
配置git地址,添加憑證
配置憑證賬號(hào)密碼
選擇憑證碳蛋、修改分支
shell構(gòu)建步驟

填入shell腳本內(nèi)容

#!/bin/bash
result=$(docker ps | grep "120.24.95.76:5000/devops")
# -n 表示:result字符串長(zhǎng)度大于0胚泌,注意[[ ]]內(nèi)部?jī)蛇呌锌崭?if [[ -n "$result" ]]
then
echo "stop devops"
docker stop devops
fi
result1=$(docker ps -a | grep "120.24.95.76:5000/devops")
if [[ -n "$result1" ]]
then
echo "rm devops"
docker rm devops
fi
result2=$(docker images | grep "1120.24.95.76:5000/devops")
if [[ -n "$result2" ]]
then
echo "120.24.95.76:5000/devops:0.0.1-SNAPSHOT"
docker rmi 120.24.95.76:5000/devops:0.0.1-SNAPSHOT
fi
shell腳本內(nèi)容
maven構(gòu)建

執(zhí)行maven構(gòu)建

clean package -f pom_docker_registry.xml -DskipTests dockerfile:build
maven腳本命令

拉取鏡像,創(chuàng)建容器肃弟,啟動(dòng)容器


shell

shell命令

docker run --name devops -p 8002:8080 -idt 120.24.95.76:5000/devops:0.0.1-SNAPSHOT
shell命令

配置完了玷室,點(diǎn)擊保存


保存配置

點(diǎn)擊保存按鈕后的界面


點(diǎn)擊保存按鈕后的界面
8.2.2 手動(dòng)構(gòu)建
手動(dòng)構(gòu)建
8.2.3 構(gòu)建成功

1、顯示構(gòu)建成功


構(gòu)建成功

2愕乎、訪問docker私有倉(cāng)庫(kù)http://120.24.95.76:5000/v2/_catalog阵苇,顯示了devops

image.png
8.2.4 構(gòu)建失敗情況
8.2.4.1 構(gòu)建失敗情況一

問題描述:在shell腳本運(yùn)行docker報(bào)權(quán)限問題壁公,錯(cuò)誤信息如下

Got permission denied while trying to connect to the Docker daemon socket at unix

解決方法:將Jenkins用戶加入docker組感论,重啟Jenkins服務(wù)

sudo gpasswd -a jenkins docker
sudo service jenkins restart
8.2.4.2 構(gòu)建失敗情況二

問題描述:鏡像推送時(shí)出現(xiàn) server gave HTTP response to HTTPS client 問題

[?[1;31mERROR?[m] Failed to execute goal ?[32mcom.spotify:docker-maven-plugin:1.2.2:build?[m ?[1m(default-cli)?[m on project

[36mdevops?[m: ?[1;31mException caught?[m: Get "https://120.24.95.76:5000/v2/": http: server gave HTTP response to HTTPS client

原因分析:因?yàn)?Docker引擎默認(rèn)通過(guò) https 協(xié)議與 Docker Registry 通信,所以如果搭建的Docker 私有鏡像庫(kù)是 http 協(xié)議的話紊册,就會(huì)輸出上述日志比肄。

解決方法:
情況1.這種寫法是沒有配置Docker加速器的情況下快耿,在 /etc/docker/daemon.json中設(shè)置以下

// 沒有配置加速器的

// 單個(gè)私服的寫法
{
    "insecure-registries": ["registry的IP地址:端口號(hào)"]
}
// 多個(gè)私服的寫法
{
    "insecure-registries": ["registry1的IP地址:端口號(hào)","registry2的IP地址:端口號(hào)"]
}

情況2.這種寫法是配置過(guò)Docker加速器的情況下,在 /etc/docker/daemon.json 中設(shè)置以下:

// 沒有配置加速器的

// 單個(gè)私服的寫法
{
    "registry-mirrors": ["http://f1361db2.m.daocloud.io"],
    "insecure-registries": ["registry的IP地址:端口號(hào)"]
}
// 多個(gè)私服的寫法
{
    "registry-mirrors": ["http://f1361db2.m.daocloud.io"],
    "insecure-registries": ["registry1的IP地址:端口號(hào)","registry2的IP地址:端口號(hào)"]
}

我的配置為:

{"insecure-registries":["120.24.95.76:5000"]}

以上配置完成以后使用命令

systemctl daemon-reload
systemctl restart docker.service
systemctl enable docker.service

注意:執(zhí)行完上面命令后芳绩,需要去重新啟動(dòng)gitlab掀亥、docker私有倉(cāng)庫(kù)服務(wù)。

8.2.4.3 構(gòu)建失敗情況三

構(gòu)建失敗錯(cuò)誤信息

docker: Error response from daemon: Conflict. The container name "/devops" is already in use by container "30ae08c83d81b79d8688cf67affb1edd1b742e2ad1eff513d5be2a81c90a6532". You have to remove (or rename) that container to be able to reuse that name.

查看鏡像和容器情況妥色,可以看出在重新構(gòu)建后搪花,之前的那個(gè)容器沒有被停掉,導(dǎo)致再啟動(dòng)容器時(shí)嘹害,啟動(dòng)失敗


查看鏡像撮竿、容器

問題原因:
在Jenkins里的shell腳本有問題,導(dǎo)致腳本執(zhí)行失敗笔呀,重新構(gòu)建時(shí)沒有刪除舊的容器和鏡像幢踏。比如,在[[ ]]]內(nèi)兩邊沒有留空格许师,導(dǎo)致shell腳本錯(cuò)誤房蝉。

錯(cuò)誤的寫法:

if [[-n "$result"]]

正確的寫法

# -n 表示:result字符串長(zhǎng)度大于0,注意[[ ]]內(nèi)部?jī)蛇呌锌崭?if [[ -n "$result" ]]

為了避免shell腳本錯(cuò)誤導(dǎo)致執(zhí)行失敗微渠,我們可以在服務(wù)器目錄下搭幻,新建一個(gè)shell腳本文件,然后執(zhí)行測(cè)試逞盆,看是否能正常執(zhí)行粗卜,比如

vi test.sh

內(nèi)容為將要在Jenkins要執(zhí)行的shell腳本

#!/bin/bash
result=$(docker ps | grep "120.24.95.76:5000/devops")
# -n 表示:result字符串長(zhǎng)度大于0,注意[[ ]]內(nèi)部?jī)蛇呌锌崭?if [[ -n "$result" ]]
then
echo "stop devops"
docker stop devops
fi
result1=$(docker ps -a | grep "120.24.95.76:5000/devops")
if [[ -n "$result1" ]]
then
echo "rm devops"
docker rm devops
fi
result2=$(docker images | grep "1120.24.95.76:5000/devops")
if [[ -n "$result2" ]]
then
echo "120.24.95.76:5000/devops:0.0.1-SNAPSHOT"
docker rmi 120.24.95.76:5000/devops:0.0.1-SNAPSHOT
fi

執(zhí)行test.sh腳本

sudo bash ./test.sh

執(zhí)行過(guò)程

root@iZwz9f4eh9lmah6qiq41zvZ:~# sudo bash ./test.sh
120.24.95.76:5000/devops:0.0.1-SNAPSHOT
Untagged: 120.24.95.76:5000/devops:0.0.1-SNAPSHOT
Deleted: sha256:48288cce36ea8c2eead8e3a58dc0890b7a3c2edf3ab95a77fd75cc140a7d73f8
Deleted: sha256:3a9b395bca1c89fb12aedfb0dab365b212dffdc775ef1a646acc7d80fd072d86
Deleted: sha256:b3e98485e2b5e7b8c7a89c64cdf44039de5ff796152ce800e906f20d2756ca33
Deleted: sha256:48b6b69723281b1c4bc221bcda5ff0b4db1175a3db2a97a47c6ef4a4624c27d9
Deleted: sha256:19b3570f0e1341cb71f3b35b307a5aa088fac708663965ca213cecde0c89164b
root@iZwz9f4eh9lmah6qiq41zvZ:~# 
8.2.4.4 構(gòu)建失敗情況四

錯(cuò)誤信息

Must specify baseImage if dockerDirectory is null

問題原因:
JenkinsInvoke top-level Maven targets錯(cuò)誤地設(shè)置成docker:build纳击,dockerDirectory是插件docker-maven-plugin的配置续扔,所以報(bào)錯(cuò)。

解決方案:
檢查Jenkins Invoke top-level Maven targets設(shè)置焕数,因?yàn)槲覀兪褂玫氖?code>dockerfile-maven-plugin纱昧,因此命令是dockerfile:build而不是docker:build

clean package -f pom_docker_registry.xml -DskipTests dockerfile:build
8.3 Jenkins自動(dòng)構(gòu)建
8.3.1 Jenkins中拿到鉤子地址

1、Jenkins安裝Gitlab插件前Build Triggers的選項(xiàng)


Jenkins安裝Gitlab插件前Build Triggers的選項(xiàng)

2堡赔、安裝Gitlab插件


安裝Gitlab插件

安裝完插件后要重啟Jenkins插件才會(huì)生效

Gitlab插件

勾選GitLab webhook選項(xiàng)识脆,點(diǎn)擊保存,并復(fù)制URL地址http://120.79.114.234:8080/project/devops善已,該地址需要配置到GitLab設(shè)置里

勾選

3灼捂、GitLab authentication設(shè)置
由于我們Jenkins訪問GitLab用的是賬號(hào)名密碼,不是用的ssh keys换团,因此我們要取消authentication的勾選選項(xiàng)悉稠,否則使用鉤子時(shí)會(huì)報(bào)403錯(cuò)誤,如下

提示403錯(cuò)誤

取消authentication的勾選選項(xiàng)操作如下:


設(shè)置
取消authentication勾選項(xiàng)
8.3.2 GitLab配置webhook(鉤子)

1艘包、登錄GitLab的猛,在Network里找到這兩個(gè)選項(xiàng)并進(jìn)行勾選耀盗,點(diǎn)擊保存。

Network勾選選項(xiàng)

2卦尊、進(jìn)入devops項(xiàng)目叛拷,點(diǎn)擊Settings-Webhooks,粘貼Jenkins那邊得到的URL地址岂却,點(diǎn)擊【Add webhook】按鈕進(jìn)行保存忿薇。

Settings-Webhooks
URL地址
Add webhook

3、在Test里選擇Push events進(jìn)行Push測(cè)試躏哩。


Push測(cè)試
測(cè)試成功
自動(dòng)構(gòu)建
8.3.3 修改代碼push后自動(dòng)構(gòu)建

1煌恢、將hello方法里的代碼改成Kyra

@RestController
@RequestMapping("devops")
public class DevOpsController {

    @GetMapping("hello")
    public String hello(){
        return "Kyra";
    }
}

2、git提交代碼

AC-2:devops AC$ git add .
AC-2:devops AC$ git commit -m "Kyra"
[main 094c6d7] Kyra
 1 file changed, 1 insertion(+), 1 deletion(-)
AC-2:devops AC$ git push
Counting objects: 10, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (10/10), 719 bytes | 719.00 KiB/s, done.
Total 10 (delta 2), reused 0 (delta 0)
To http://120.79.114.234:6001/root/devops.git
   3eec4b3..094c6d7  main -> main
AC-2:devops AC$ 

3震庭、git push后Jenkins會(huì)自動(dòng)構(gòu)建


git push后Jenkins會(huì)自動(dòng)構(gòu)建

4瑰抵、刷新接口,接口返回修改后的Kyra

http://120.24.95.76:8002/devops/hello
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末器联,一起剝皮案震驚了整個(gè)濱河市二汛,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌拨拓,老刑警劉巖肴颊,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異渣磷,居然都是意外死亡婿着,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門醋界,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)竟宋,“玉大人,你說(shuō)我怎么就攤上這事形纺∏鹣溃” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵逐样,是天一觀的道長(zhǎng)蜗字。 經(jīng)常有香客問我,道長(zhǎng)脂新,這世上最難降的妖魔是什么挪捕? 我笑而不...
    開封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮争便,結(jié)果婚禮上级零,老公的妹妹穿的比我還像新娘。我一直安慰自己始花,他們只是感情好妄讯,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著酷宵,像睡著了一般亥贸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上浇垦,一...
    開封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天炕置,我揣著相機(jī)與錄音,去河邊找鬼男韧。 笑死朴摊,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的此虑。 我是一名探鬼主播甚纲,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼朦前!你這毒婦竟也來(lái)了介杆?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤韭寸,失蹤者是張志新(化名)和其女友劉穎春哨,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體恩伺,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡赴背,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了晶渠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片凰荚。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖褒脯,靈堂內(nèi)的尸體忽然破棺而出浇揩,到底是詐尸還是另有隱情,我是刑警寧澤憨颠,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布胳徽,位于F島的核電站,受9級(jí)特大地震影響爽彤,放射性物質(zhì)發(fā)生泄漏养盗。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一适篙、第九天 我趴在偏房一處隱蔽的房頂上張望往核。 院中可真熱鬧,春花似錦嚷节、人聲如沸聂儒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)衩婚。三九已至窜护,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間非春,已是汗流浹背柱徙。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留奇昙,地道東北人护侮。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像储耐,于是被迫代替她去往敵國(guó)和親羊初。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容