第一章 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í)交付軟件吱窝。
二、為什么當(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)的工具集
四、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ù)集成流程
第二章 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安全組開放端口:
5000
、6001
彬向、6002
兼贡、6003
、8080
娃胆、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>
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 配置鏡像加速器(非必要)
二仇祭、安裝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”]
}
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
三徙缴、安裝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
https
443端口用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
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
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
)
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
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
我們可以看到項(xiàng)目的訪問地址為IP生棍,不是容器ID了颤霎,SSH地址后面是6003
端口,HTTP地址后面是6001
端口。
3.5 GitLab創(chuàng)建用戶
3.6 項(xiàng)目授權(quán)
將devops
項(xiàng)目授權(quán)給chenyan
用戶
用chenyan
賬號(hào)登錄GitLab友酱,即可以看到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
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
設(shè)置項(xiàng)目名稱
添加Spring Web依賴
覆蓋剛剛clone的項(xiàng)目目錄
4.2 編寫restful接口
編寫controller
代碼
@RestController
@RequestMapping("devops")
public class DevOpsController {
@GetMapping("hello")
public String hello(){
return "AlanChen";
}
}
自動(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
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
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)目目錄如下
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)不再推薦使用該插件:
上面說(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)目目錄如下
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
8.2 Jenkins集成
8.2.1 Jenkins創(chuàng)建持續(xù)集成任務(wù)
填入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
執(zhí)行maven構(gòu)建
clean package -f pom_docker_registry.xml -DskipTests dockerfile:build
拉取鏡像,創(chuàng)建容器肃弟,啟動(dòng)容器
shell命令
docker run --name devops -p 8002:8080 -idt 120.24.95.76:5000/devops:0.0.1-SNAPSHOT
配置完了玷室,點(diǎn)擊保存
點(diǎn)擊保存按鈕后的界面
8.2.2 手動(dòng)構(gòu)建
8.2.3 構(gòu)建成功
1、顯示構(gòu)建成功
2愕乎、訪問docker私有倉(cāng)庫(kù)http://120.24.95.76:5000/v2/_catalog
阵苇,顯示了devops
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)
2堡赔、安裝Gitlab插件
安裝完插件后要重啟Jenkins插件才會(huì)生效
勾選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ò)誤,如下
取消authentication的勾選選項(xiàng)操作如下:
8.3.2 GitLab配置webhook(鉤子)
1艘包、登錄GitLab的猛,在Network里找到這兩個(gè)選項(xiàng)并進(jìn)行勾選耀盗,點(diǎn)擊保存。
2卦尊、進(jìn)入devops
項(xiàng)目叛拷,點(diǎn)擊Settings-Webhooks,粘貼Jenkins那邊得到的URL地址岂却,點(diǎn)擊【Add webhook】按鈕進(jìn)行保存忿薇。
3、在Test里選擇Push events進(jìn)行Push測(cè)試躏哩。
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)建
4瑰抵、刷新接口,接口返回修改后的Kyra
http://120.24.95.76:8002/devops/hello