DevOps入門(mén)及過(guò)程搭建
在如今互聯(lián)網(wǎng)的格局下,搶占市場(chǎng)變得尤為重要,因此敏捷開(kāi)發(fā)越來(lái)越被大家所推崇。于是,慢慢的有了DevOps這個(gè)概念,大致意思是開(kāi)發(fā)-運(yùn)維一體化。
1 DevOps概念
1.1 基本概念
可以看到上圖是一個(gè)無(wú)窮大的一個(gè)符號(hào),Dev對(duì)應(yīng)開(kāi)發(fā),Ops對(duì)應(yīng)運(yùn)維。
- DevOps的方式可以讓公司能夠更快地應(yīng)對(duì)更新和市場(chǎng)發(fā)展變化,開(kāi)發(fā)可以快速交付,部署也更加穩(wěn)定。
- 核心就在于簡(jiǎn)化Dev和Ops團(tuán)隊(duì)之間的流程,使整體軟件開(kāi)發(fā)過(guò)程更快速。
1.2 流程
DevOps的開(kāi)發(fā)過(guò)程及常用工具:
整體的軟件開(kāi)發(fā)流程包括:
- PLAN:開(kāi)發(fā)團(tuán)隊(duì)根據(jù)客戶(hù)的目標(biāo)制定開(kāi)發(fā)計(jì)劃
- CODE:根據(jù)PLAN開(kāi)始編碼過(guò)程,需要將不同版本的代碼存儲(chǔ)在一個(gè)庫(kù)中。
- BUILD:編碼完成后,需要將代碼構(gòu)建并且運(yùn)行。
- TEST:成功構(gòu)建項(xiàng)目后,需要測(cè)試代碼是否存在BUG或錯(cuò)誤。
- DEPLOY:代碼經(jīng)過(guò)手動(dòng)測(cè)試和自動(dòng)化測(cè)試后,認(rèn)定代碼已經(jīng)準(zhǔn)備好部署并且交給運(yùn)維團(tuán)隊(duì)。
- OPERATE:運(yùn)維團(tuán)隊(duì)將代碼部署到生產(chǎn)環(huán)境中。
- MONITOR:項(xiàng)目部署上線(xiàn)后,需要持續(xù)的監(jiān)控產(chǎn)品。
- INTEGRATE:然后將監(jiān)控階段收到的反饋發(fā)送回PLAN階段,整體反復(fù)的流程就是DevOps的核心,即持續(xù)集成、持續(xù)部署。
總的來(lái)說(shuō)就是:
- Code階段(編碼):Git+GitLab
- Build階段(構(gòu)建):Maven或Gradle
- Operate(運(yùn)行):Docker
- Integrate(集成):Jenkins
- CI/CD(持續(xù)集成):操作Jenkins,編寫(xiě)對(duì)應(yīng)腳本文件
- Code review(代碼質(zhì)量檢測(cè)):Jenkins集成Sonar Qube
- 自定義鏡像:Harbor
- Jenkins流水線(xiàn)操作
- WebHook:通知操作,如:釘釘機(jī)器人通知
- K8S編排:更加方便我們管理容器
2 搭建DevOps環(huán)境
本項(xiàng)目全部采用docker安裝,如果服務(wù)器上沒(méi)有docker環(huán)境的,
參考:https://editor.csdn.net/md/?articleId=127816970安裝即可。
- 也可以參考本文檔的2.2 Docker 章節(jié)
2.1 GitLab
在項(xiàng)目的Code(編碼)階段,我們需要將不同版本的代碼存儲(chǔ)到一個(gè)倉(cāng)庫(kù)中,常見(jiàn)的版本控制工具就是SVN或者Git,這里我們采用Git作為版本控制工具,GitLab作為遠(yuǎn)程倉(cāng)庫(kù)。
git的安裝:參考官網(wǎng),無(wú)腦下一步即可
官網(wǎng)地址:https://git-scm.com/
GitLab安裝:
- 查看docker上gitlab的鏡像,并拉取
# 查看鏡像
docker search gitlab
# 拉取鏡像
docker pull gitlab/gitlab-ce
- 準(zhǔn)備docker-compose.yml文件
文檔中的external_url等參考自己服務(wù)器上的ip
version: '3.1'
services:
gitlab:
image: 'gitlab/gitlab-ce:latest'
container_name: gitlab
restart: always
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'http://192.168.11.11:8929'
gitlab_rails['gitlab_shell_ssh_port'] = 2224
ports:
- '8929:8929'
- '2224:2224'
volumes:
- './config:/etc/gitlab'
- './logs:/var/log/gitlab'
- './data:/var/opt/gitlab'
- 啟動(dòng)容器,并訪(fǎng)問(wèn)
# 啟動(dòng)容器
docker-compose up -d
訪(fǎng)問(wèn):http://192.168.11.11:8929即可。
效果:
4. 查看初始的用戶(hù)名和密碼
docker exec -it gitlab cat /etc/gitlab/initial_root_password
5. 登錄并修改密碼
以root身份登錄gitlab,首次登錄需要修改密碼
然后我們就可以像GitHub、Gitee一樣操作GitLab了
2.2 Docker
構(gòu)建Java項(xiàng)目的工具一般有兩種選擇,一個(gè)是Maven,一個(gè)是Gradle。
- 這里我們選擇Maven作為項(xiàng)目的編譯工具。
- 具體安裝Maven流程不做闡述,但是需要確保配置好Maven倉(cāng)庫(kù)私服以及JDK編譯版本。
部署過(guò)程,會(huì)采用Docker進(jìn)行部署,暫時(shí)只安裝Docker即可,后續(xù)還需安裝Kubenetes
2.2.1 Docker安裝
①準(zhǔn)備測(cè)試環(huán)境&生產(chǎn)環(huán)境
②下載Docker依賴(lài)組件
yum -y install yum-utils device-mapper-persistent-data lvm2
③設(shè)置下載Docker的鏡像源為阿里云
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
④安裝docker服務(wù)
yum -y install docker-ce
⑤設(shè)置docker開(kāi)機(jī)自啟
# 啟動(dòng)Docker服務(wù)
systemctl start docker
# 設(shè)置開(kāi)機(jī)自動(dòng)啟動(dòng)
systemctl enable docker
⑥測(cè)試安裝成功
docker version
2.2.2 Docker-compose安裝
-
下載Docker/Compose:https://github.com/docker/compose
-
將下載好的docker-compose-Linux-x86_64文件移動(dòng)到Linux操作系統(tǒng):……
-
設(shè)置docker-compose-Linux-x86_64文件權(quán)限,并移動(dòng)到$PATH目錄中
# 設(shè)置文件權(quán)限
chmod a+x docker-compose-Linux-x86_64
# 移動(dòng)到/usr/bin目錄下,并重命名為docker-compose
mv docker-compose-Linux-x86_64 /usr/bin/docker-compose
2.3 Jenkins
2.3.1 介紹
在DevOps中持續(xù)集成和持續(xù)部署是很重要的一個(gè)環(huán)節(jié),類(lèi)似的工具也有很多,其中Jenkins是一個(gè)開(kāi)源的持續(xù)集成平臺(tái)。
Jenkins涉及到將編寫(xiě)完畢的代碼發(fā)布到測(cè)試環(huán)境和生產(chǎn)環(huán)境的任務(wù),并且還涉及到了構(gòu)建項(xiàng)目等任務(wù)。
Jenkins需要大量的插件保證工作,安裝成本較高,下面會(huì)基于Docker搭建Jenkins。
- Jenkins是一個(gè)開(kāi)源項(xiàng)目,基于Java開(kāi)發(fā)的
- 大多數(shù)互聯(lián)網(wǎng)公司都是采永Jenkins配合GitLab、Docker、K8s作為DevOps的核心工具
- Jenkins官方提供了大量的插件庫(kù),用于完成自動(dòng)化的CI/CD過(guò)程。
Jenkins主要工作:
- 拉取GitLab上的代碼并進(jìn)行構(gòu)建
- 根據(jù)流程可以選擇發(fā)布到測(cè)試環(huán)境或是生產(chǎn)環(huán)境
GitLab上的代碼經(jīng)過(guò)大量測(cè)試后,確定發(fā)型版本,再發(fā)布到生產(chǎn)環(huán)境
CI/CD概念:
- CI過(guò)程:JenKins將代碼拉取、構(gòu)建、制作鏡像交給測(cè)試人員
- 持續(xù)集成:讓軟件代碼可以持續(xù)的集成到主干上,并自動(dòng)構(gòu)建和測(cè)試
- CD過(guò)程:通過(guò)Jenkins將打好標(biāo)簽的發(fā)行版本代碼進(jìn)行拉取、構(gòu)建、制作鏡像后交給運(yùn)維人員部署
- 持續(xù)交付:讓經(jīng)過(guò)持續(xù)集成的代碼可以進(jìn)行手動(dòng)部署
- 持續(xù)部署:讓可以持續(xù)交付的代碼隨時(shí)隨地的自動(dòng)化部署
2.3.2 Jenkins安裝
- 拉取鏡像
docker pull jenkins/jenkins
- 編寫(xiě)對(duì)應(yīng)的docker-compose.yml
version: "3.1"
services:
jenkins:
image: jenkins/jenkins
container_name: jenkins
ports:
- 8080:8080
- 50000:50000
volumes:
- ./data/:/var/jenkins_home/
- 設(shè)置數(shù)據(jù)卷data目錄的權(quán)限,否則會(huì)包沒(méi)有對(duì)應(yīng)權(quán)限
chmod -R a+w data/
- 設(shè)置Jenkins的下載地址
重新啟動(dòng)Jenkins容器后,由于Jenkins需要下載大量?jī)?nèi)容,但是由于默認(rèn)下載地址下載速度較慢,需要重新設(shè)置下載地址為國(guó)內(nèi)鏡像站
# 修改數(shù)據(jù)卷中的hudson.model.UpdateCenter.xml文件
<?xml version='1.1' encoding='UTF-8'?>
<sites>
<site>
<id>default</id>
<url>https://updates.jenkins.io/update-center.json</url>
</site>
</sites>
# 將下載地址替換為http://mirror.esuni.jp/jenkins/updates/update-center.json
<?xml version='1.1' encoding='UTF-8'?>
<sites>
<site>
<id>default</id>
<url>http://mirror.esuni.jp/jenkins/updates/update-center.json</url>
</site>
</sites>
# 清華大學(xué)的插件源也可以https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json
- 再次重啟Jenkins容器,訪(fǎng)問(wèn)JenKins
- 查看JenKins登錄密碼,并登錄JenKins然后安裝對(duì)應(yīng)插件
docker exec -it jenkins cat /var/jenkins_home/secrets/initialAdminPassword
輸入管理員密碼 - 選擇插件來(lái)安裝 - 選擇對(duì)應(yīng)的插件進(jìn)行安裝
推薦安裝:
①Git Parameter
②Publish Over SSH
然后等待插件安裝成功進(jìn)入首頁(yè)。(可能會(huì)出現(xiàn)下載失敗的插件,重新下載即可)
7. 創(chuàng)建管理員用戶(hù),設(shè)置Jenkins URL
2.3.3 Jenkins實(shí)現(xiàn)拉取-構(gòu)建-發(fā)布
準(zhǔn)備好GitLab倉(cāng)庫(kù)中的項(xiàng)目,并且通過(guò)Jenkins配置實(shí)現(xiàn)當(dāng)前項(xiàng)目的DevOps流程。(Idea創(chuàng)建之后推送到遠(yuǎn)程即可)
-
構(gòu)建Maven工程發(fā)布到GitlLab、Gitee、GitHub均可
-
點(diǎn)擊Jenkins左側(cè)新建任務(wù)(選擇自由風(fēng)格的項(xiàng)目)
-
配置源碼拉取地址
-
點(diǎn)擊立即構(gòu)建,查看構(gòu)建日志
-
配置Maven構(gòu)建代碼
代碼拉取到Jenkins本地后,需要在Jenkins中對(duì)代碼進(jìn)行構(gòu)建,這里需要Maven的環(huán)境,而Maven需要Java的環(huán)境,接下來(lái)需要在Jenkins中安裝JDK和Maven,并且配置到Jenkins服務(wù)。
- 準(zhǔn)備jdk、maven壓縮包,通過(guò)數(shù)據(jù)卷映射到Jenkins容器內(nèi)部
- 解壓壓縮包,并配置Maven的settings.xml
<!-- 阿里云鏡像地址 -->
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
<!-- JDK1.8編譯插件 -->
<profile>
<id>jdk-1.8</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
- Jenkins配置JDK&Maven并保存
maven配置同理 - 配置Jenkins任務(wù)構(gòu)建代碼
- 立即構(gòu)建測(cè)試,查看target下的jar包
- 配置Publish發(fā)布&遠(yuǎn)程操作
jar包構(gòu)建好后,就可以根據(jù)情況發(fā)布到測(cè)試或者生產(chǎn)環(huán)境,此處需要用到之前下載好的插件Publish Over SSH
- 配置Publish Over SSH連接測(cè)試環(huán)境、生產(chǎn)環(huán)境
- 配置任務(wù)構(gòu)建后的操作,發(fā)布jar包到目標(biāo)服務(wù)
- 立即構(gòu)建任務(wù),并去目標(biāo)服務(wù)查看
2.3.4 CI/CD操作
- 基于Jenkins拉取GitLab的SpringBoot代碼進(jìn)行構(gòu)建發(fā)布到測(cè)試環(huán)境實(shí)現(xiàn)持續(xù)集成
- 基于Jenkins拉取GitLab指定發(fā)行版本的SpringBoot進(jìn)行構(gòu)建發(fā)布到生產(chǎn)環(huán)境實(shí)現(xiàn)CD(持續(xù)部署)
為了讓程序代碼可以自動(dòng)推送到測(cè)試環(huán)境基于Docker服務(wù)運(yùn)行,需要添加Docker配置和腳本文件讓程序可以在集成到主干的同時(shí)運(yùn)行起來(lái)。
①持續(xù)集成
-
添加Dockerfile文件
-
添加docker-compose.yml文件
-
追加Jenkins構(gòu)建后操作腳本命令
-
發(fā)布到GitLab后由Jenkins立即構(gòu)建并推送到目標(biāo)服務(wù)器
-
測(cè)試部署到目標(biāo)服務(wù)器程序
②持續(xù)交付、部署
程序代碼在經(jīng)過(guò)多次集成操作到達(dá)最終可以交付,持續(xù)交付整體流程和持續(xù)集成類(lèi)似,不過(guò)需要選取指定的發(fā)行版本
-
下載Git Parameter插件
-
設(shè)置項(xiàng)目參數(shù)化構(gòu)建
-
在GitLab上給項(xiàng)目添加tag版本
-
任務(wù)構(gòu)建時(shí),采用Shell方式構(gòu)建,拉取指定tag版本
-
基于Parameter構(gòu)建任務(wù),任務(wù)發(fā)布到目標(biāo)服務(wù)器
2.4 Sonar Qube
2.4.1 Sonar Qube介紹與安裝
Sonar Qube是一個(gè)開(kāi)源的代碼分析平臺(tái),支持Java、Python、PHP、JavaScript、CSS等25種以上的語(yǔ)言,可以檢測(cè)出重復(fù)代碼、代碼漏洞、代碼規(guī)范和安全性漏洞的問(wèn)題。
- Sonar Qube可以與多種軟件整合進(jìn)行代碼掃描,比如:Maven、Gradle、Git、Jenkins等,并且會(huì)將代碼檢測(cè)結(jié)果推送回Sonar Qube,進(jìn)而在系統(tǒng)提供的UI界面上顯示出來(lái)。
安裝過(guò)程:
Sonar Qube在7.9版本中已經(jīng)放棄了對(duì)MySQL的支持,并且建議在商業(yè)環(huán)境中采用PostgreSQL,那么安裝Sonar Qube時(shí)需要依賴(lài)PostgreSQL。
①拉取PostgreSQL鏡像
docker pull postgres
docker pull sonarqube:8.9.3-community
②編寫(xiě)docker-compose.yml
更易管理
version: "3.1"
services:
db:
image: postgres
container_name: db
ports:
- 5432:5432
networks:
- sonarnet
environment:
POSTGRES_USER: sonar
POSTGRES_PASSWORD: sonar
sonarqube:
image: sonarqube:8.9.3-community
container_name: sonarqube
depends_on:
- db
ports:
- "9000:9000"
networks:
- sonarnet
environment:
SONAR_JDBC_URL: jdbc:postgresql://db:5432/sonar
SONAR_JDBC_USERNAME: sonar
SONAR_JDBC_PASSWORD: sonar
networks:
sonarnet:
driver: bridge
③設(shè)置sysctl.conf文件信息,并啟動(dòng)容器
設(shè)置
vm.max_map_count=262144
,至少是這個(gè)數(shù)
# 執(zhí)行命令進(jìn)行刷新
sysctl -p
# 啟動(dòng)容器
docker-compose up -d
重新啟動(dòng)需要一定時(shí)間,可以查看容器日志,如果看到如下內(nèi)容代表啟動(dòng)成功
④訪(fǎng)問(wèn)Sonar Qube首頁(yè)
登錄成功之后,會(huì)要求我們修改默認(rèn)密碼
首頁(yè)圖片:
- 安裝中文插件
安裝成功后需要重啟,若安裝失敗,重新點(diǎn)擊install即可
2.4.2 Sonar Qube基本使用
Sonar Qube的使用方式很多,Maven可以整合,也可以采用sonar-scanner的方式,再查看Sonar Qube的檢測(cè)效果
①M(fèi)aven實(shí)現(xiàn)代碼檢測(cè)
- 修改配置文件信息
修改本地Maven的settings.xml文件,配置Sonar Qube信息
<profile>
<id>sonar</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<sonar.login>admin</sonar.login>
<sonar.password>123456789</sonar.password>
<sonar.host.url>http://192.168.11.11:9000</sonar.host.url>
</properties>
</profile>
- 在代碼所在位置的cmd執(zhí)行命令
mvn sonar:sonar
- 檢測(cè)結(jié)果:
②Sonar-scanner實(shí)現(xiàn)代碼檢測(cè)
- 下載對(duì)應(yīng)版本
- 下載Sonar-scanner:https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/
- 下載4.6.x版本即可,要求Linux版本
- 解壓并配置sonar服務(wù)端信息
下載下來(lái)的Sonar-scanner是zip壓縮包,因此需要在linux上安裝unzip插件
# 安裝unzip解壓插件
yum -y install unzip
# 解壓壓縮包
unzip sonar-scanner-cli/sonar-scanner-cli-4.6.0.2311-linux.zip
配置sonarQube服務(wù)端地址,修改conf下的sonar-scanner.properties
- 執(zhí)行命令檢測(cè)代碼
# 在項(xiàng)目所在目錄執(zhí)行以下命令
~/sonar-scanner/bin/sonar-scanner -Dsonar.sources=./ -Dsonar.projectname=demo -Dsonar.projectKey=java -Dsonar.java.binaries=target/
- 查看SonarQube界面檢測(cè)結(jié)果
③Jenkins集成Sonar Qube
Jenkins集成Sonar Qube實(shí)現(xiàn)代碼掃描需要下載整合插件
- Jenkins安裝插件【系統(tǒng)管理-插件管理】
- 安裝SonarQube Scanner插件
- Jenkins配置Sonar Qube
在SonarQube中開(kāi)啟Sonar Qube的權(quán)限驗(yàn)證
在Sonar Qube中生成一個(gè)令牌,獲取Sonar Qube的令牌
- 在Jenkins中配置Sonar Qube信息
Dashboard - 系統(tǒng)配置
- 在Jenkins中配置Sonar-scanner
將Sonar-scanner添加到Jenkins數(shù)據(jù)卷中并全局配置
- 配置任務(wù)的Sonar-scanner
- 構(gòu)建任務(wù)
Jenkins界面:
SonarQube界面:
2.5 Harbor(鏡像倉(cāng)庫(kù))
2.5.1 Harbor介紹與安裝
- 介紹
前面我們?cè)诓渴饡r(shí),主要流程如下:
- Jenkins推送jar包到服務(wù)器
- 通過(guò)腳本命令讓目標(biāo)服務(wù)器對(duì)當(dāng)前jar進(jìn)行部署
但是這種方式在項(xiàng)目比較多的時(shí)候,每個(gè)服務(wù)器都需要將jar包制作成自定義鏡像,然后再通過(guò)docker進(jìn)行啟動(dòng),重復(fù)操作較多,降低部署效率。
Harbor:私有的Docker鏡像倉(cāng)庫(kù)。我們可以讓Jenkins統(tǒng)一將項(xiàng)目打包并制作成Docker鏡像發(fā)布到Harbor倉(cāng)庫(kù)中。然后我們只需要通知目標(biāo)服務(wù),讓目標(biāo)服務(wù)統(tǒng)一去Harbor倉(cāng)庫(kù)上拉取鏡像并在本地部署即可。
- 安裝(通過(guò)原生的方式安裝)
- 下載Harbor安裝包
https://github.com/goharbor/harbor/releases/download/v2.3.4/harbor-offline-installer-v2.3.4.tgz - 傳送到linux上并解壓
# 通過(guò)xftp或其他方式將壓縮包傳送到linux上
# 解壓
tar -zxvf harbor-offline-installer-v2.3.4.tgz -C /usr/local/
- 修改Harbor配置文件
設(shè)置harbor地址,注釋https,查看密碼
# 備份原有配置
cp harbor.yml.tmpl harbor.yml
4. 啟動(dòng)Harbor并登錄Harbor
# 啟動(dòng)Harbor
./install.sh
首頁(yè)信息:
2.5.2 Harbor基礎(chǔ)使用
Harbor作為鏡像倉(cāng)庫(kù),主要的交互方式就是將鏡像上傳到Harbor,以及從Harbor上下載拉取指定版本的鏡像。
- 在傳輸鏡像前,可以先使用Harbor提供的權(quán)限管理,將項(xiàng)目設(shè)置為私有項(xiàng)目,并對(duì)不同用戶(hù)設(shè)置不同角色,從而更方便管理鏡像。
①添加用戶(hù)構(gòu)建項(xiàng)目
- 創(chuàng)建用戶(hù)
系統(tǒng)管理-用戶(hù)管理-創(chuàng)建用戶(hù)
- 構(gòu)建項(xiàng)目(設(shè)置為私有)
- 給項(xiàng)目追加用戶(hù)
②發(fā)布鏡像到Harbor
- 修改鏡像名稱(chēng)
名稱(chēng)要求:harbor地址/項(xiàng)目名/鏡像名:版本
- 修改daemon.json,支持Docker倉(cāng)庫(kù),并重啟Docker
- 設(shè)置登錄倉(cāng)庫(kù)信息
docker login -u 用戶(hù)名 -p 密碼 Harbor地址
- 推送鏡像到Harbor
③從Harbor中拉取鏡像
跟傳統(tǒng)方式一樣,不過(guò)需要先配置/etc/docker/daemon.json文件
{
"registry-mirrors": ["https://pee6w651.mirror.aliyuncs.com"],
"insecure-registries": ["192.168.11.11:80"]
}
拉取鏡像:
拓展:Jenkins容器使用宿主機(jī)Docker并編寫(xiě)構(gòu)建腳本
- 構(gòu)建鏡像和發(fā)布鏡像到harbor都需要使用到docker命令。而在Jenkins容器內(nèi)部安裝Docker官方推薦直接采用宿主機(jī)帶的Docker即可。
①設(shè)置Jenkins容器使用宿主機(jī)Docker
- 設(shè)置宿主機(jī)docker.sock權(quán)限
sudo chown root:root /var/run/docker.sock
sudo chmod o+rw /var/run/docker.sock
- 添加數(shù)據(jù)卷
version: "3.1"
services:
jenkins:
image: jenkins/jenkins
container_name: jenkins
ports:
- 8080:8080
- 50000:50000
volumes:
- ./data/:/var/jenkins_home/
- /usr/bin/docker:/usr/bin/docker
- /var/run/docker.sock:/var/run/docker.sock
- /etc/docker/daemon.json:/etc/docker/daemon.json
②添加構(gòu)建操作
③編寫(xiě)構(gòu)建腳本
- 部署項(xiàng)目需要通過(guò)Publish Over SSH插件,讓目標(biāo)服務(wù)器執(zhí)行命令。為了方便一次性實(shí)現(xiàn)拉取鏡像和啟動(dòng)的命令,推薦采用腳本文件的方式。
- 添加腳本文件到目標(biāo)服務(wù)器,再通過(guò)Publish Over SSH插件讓目標(biāo)服務(wù)器執(zhí)行腳本即可。
- 編寫(xiě)腳本文件,添加到目標(biāo)服務(wù)器
deploy.sh:
harbor_url=$1
harbor_project_name=$2
project_name=$3
tag=$4
port=$5
imageName=$harbor_url/$harbor_project_name/$project_name:$tag
containerId=`docker ps -a | grep ${project_name} | awk '{print $1}'`
if [ "$containerId" != "" ] ; then
docker stop $containerId
docker rm $containerId
echo "Delete Container Success"
fi
imageId=`docker images | grep ${project_name} | awk '{print $3}'`
if [ "$imageId" != "" ] ; then
docker rmi -f $imageId
echo "Delete Image Success"
fi
docker login -u DevOps -p P@ssw0rd $harbor_url
docker pull $imageName
docker run -d -p $port:$port --name $project_name $imageName
echo "Start Container Success"
echo $project_name
- 設(shè)置文件權(quán)限為可執(zhí)行:
chmod a+x deploy.sh
④配置構(gòu)建后操作
2.6 Jenkins流水線(xiàn)(pipeline)、自動(dòng)化腳本
2.6.1 Jenkins流水線(xiàn)任務(wù)介紹
之前采用的都是Jenkins的自由風(fēng)格,每個(gè)流程都要通過(guò)不同的方式設(shè)置,并且構(gòu)建過(guò)程中整體流程時(shí)不可見(jiàn)的,無(wú)法確認(rèn)每個(gè)流程花費(fèi)的時(shí)間,同時(shí)不方便問(wèn)題的定位。
Jenkins的Pipeline可以讓項(xiàng)目的發(fā)布整體流程可視化,明確執(zhí)行的階段,快速定位問(wèn)題。讓整個(gè)項(xiàng)目的生命周期可以通過(guò)一個(gè)Jenkinsfile文件管理,而且Jenkinsfile文件是可以放在項(xiàng)目中維護(hù)。
①構(gòu)建Jenkins流水線(xiàn)任務(wù)
- 構(gòu)建任務(wù)
- 生成Groovy腳本
- 構(gòu)建后查看視圖
②Groovy腳本
- Groovy腳本基本語(yǔ)法
// 所有腳本命令包含在pipeline{}中
pipeline {
// 指定任務(wù)在哪個(gè)節(jié)點(diǎn)執(zhí)行(Jenkins支持分布式)
agent any
// 配置全局環(huán)境,指定變量名=變量值信息
environment{
host = '192.168.11.11'
}
// 存放所有任務(wù)的合集
stages {
// 單個(gè)任務(wù)
stage('任務(wù)1') {
// 實(shí)現(xiàn)任務(wù)的具體流程
steps {
echo 'do something'
}
}
// 單個(gè)任務(wù)
stage('任務(wù)2') {
// 實(shí)現(xiàn)任務(wù)的具體流程
steps {
echo 'do something'
}
}
// ……
}
}
- 編寫(xiě)例子測(cè)試
- 查看效果
Ps:涉及到特定腳本,Jenkins給予了充足的提示,可以自動(dòng)生成命令
③JenkinsFile實(shí)現(xiàn)
Jenkinsfile方式需要將腳本內(nèi)容編寫(xiě)到項(xiàng)目中的Jenkinsfile文件中,每次構(gòu)建會(huì)自動(dòng)拉取并且獲取項(xiàng)目中的Jenkinsfile文件來(lái)對(duì)項(xiàng)目進(jìn)行構(gòu)建
- 配置pipeline
- 準(zhǔn)備Jenkinsfile
- 測(cè)試效果
2.6.2 Jenkins流水線(xiàn)任務(wù)實(shí)現(xiàn)
- 參數(shù)化構(gòu)建
添加參數(shù)化構(gòu)建,方便選擇不同的項(xiàng)目版本
2. 拉取Git代碼
通過(guò)流水線(xiàn)語(yǔ)法生成Checkout代碼的腳本
將*/master更改為標(biāo)簽${tag}
pipeline {
agent any
stages {
stage('拉取Git代碼') {
steps {
checkout([$class: 'GitSCM', branches: [[name: '${tag}']], extensions: [], userRemoteConfigs: [[url: 'http://49.233.115.171:8929/root/test.git']]])
}
}
}
}
- 構(gòu)建代碼
通過(guò)腳本執(zhí)行mvn的構(gòu)建命令
pipeline {
agent any
stages {
stage('拉取Git代碼') {
steps {
checkout([$class: 'GitSCM', branches: [[name: '${tag}']], extensions: [], userRemoteConfigs: [[url: 'http://49.233.115.171:8929/root/test.git']]])
}
}
stage('構(gòu)建代碼') {
steps {
sh '/var/jenkins_home/maven/bin/mvn clean package -DskipTests'
}
}
}
- 代碼質(zhì)量檢測(cè)
通過(guò)腳本執(zhí)行sonar-scanner命令即可
pipeline {
agent any
stages {
stage('拉取Git代碼') {
steps {
checkout([$class: 'GitSCM', branches: [[name: '${tag}']], extensions: [], userRemoteConfigs: [[url: 'http://49.233.115.171:8929/root/test.git']]])
}
}
stage('構(gòu)建代碼') {
steps {
sh '/var/jenkins_home/maven/bin/mvn clean package -DskipTests'
}
}
stage('檢測(cè)代碼質(zhì)量') {
steps {
sh '/var/jenkins_home/sonar-scanner/bin/sonar-scanner -Dsonar.sources=./ -Dsonar.projectname=${JOB_NAME} -Dsonar.projectKey=${JOB_NAME} -Dsonar.java.binaries=target/ -Dsonar.login=31388be45653876c1f51ec02f0d478e2d9d0e1fa'
}
}
}
}
- 制作自定義鏡像并發(fā)布
- 生成自定義鏡像腳本
pipeline {
agent any
environment{
harborHost = '192.168.11.11:80'
harborRepo = 'repository'
harborUser = 'DevOps'
harborPasswd = 'P@ssw0rd'
}
// 存放所有任務(wù)的合集
stages {
stage('拉取Git代碼') {
steps {
checkout([$class: 'GitSCM', branches: [[name: '${tag}']], extensions: [], userRemoteConfigs: [[url: 'http://49.233.115.171:8929/root/test.git']]])
}
}
stage('構(gòu)建代碼') {
steps {
sh '/var/jenkins_home/maven/bin/mvn clean package -DskipTests'
}
}
stage('檢測(cè)代碼質(zhì)量') {
steps {
sh '/var/jenkins_home/sonar-scanner/bin/sonar-scanner -Dsonar.sources=./ -Dsonar.projectname=${JOB_NAME} -Dsonar.projectKey=${JOB_NAME} -Dsonar.java.binaries=target/ -Dsonar.login=31388be45653876c1f51ec02f0d478e2d9d0e1fa'
}
}
stage('制作自定義鏡像并發(fā)布Harbor') {
steps {
sh '''cp ./target/*.jar ./docker/
cd ./docker
docker build -t ${JOB_NAME}:${tag} ./'''
sh '''docker login -u ${harborUser} -p ${harborPasswd} ${harborHost}
docker tag ${JOB_NAME}:${tag} ${harborHost}/${harborRepo}/${JOB_NAME}:${tag}
docker push ${harborHost}/${harborRepo}/${JOB_NAME}:${tag}'''
}
}
}
}
- 生成Publish Over SSH腳本
pipeline {
agent any
environment{
harborHost = '192.168.11.11:80'
harborRepo = 'repository'
harborUser = 'DevOps'
harborPasswd = 'P@ssw0rd'
}
// 存放所有任務(wù)的合集
stages {
stage('拉取Git代碼') {
steps {
checkout([$class: 'GitSCM', branches: [[name: '${tag}']], extensions: [], userRemoteConfigs: [[url: 'http://49.233.115.171:8929/root/test.git']]])
}
}
stage('構(gòu)建代碼') {
steps {
sh '/var/jenkins_home/maven/bin/mvn clean package -DskipTests'
}
}docker
stage('檢測(cè)代碼質(zhì)量') {
steps {
sh '/var/jenkins_home/sonar-scanner/bin/sonar-scanner -Dsonar.sources=./ -Dsonar.projectname=${JOB_NAME} -Dsonar.projectKey=${JOB_NAME} -Dsonar.java.binaries=target/ -Dsonar.login=7d66af4b39cfe4f52ac0a915d4c9d5c513207098'
}
}
stage('制作自定義鏡像并發(fā)布Harbor') {
steps {
sh '''cp ./target/*.jar ./docker/
cd ./docker
docker build -t ${JOB_NAME}:${tag} ./'''
sh '''docker login -u ${harborUser} -p ${harborPasswd} ${harborHost}
docker tag ${JOB_NAME}:${tag} ${harborHost}/${harborRepo}/${JOB_NAME}:${tag}
docker push ${harborHost}/${harborRepo}/${JOB_NAME}:${tag}'''
}
}
stage('目標(biāo)服務(wù)器拉取鏡像并運(yùn)行') {
steps {
sshPublisher(publishers: [sshPublisherDesc(configName: 'testEnvironment', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "/usr/bin/deploy.sh $harborHost $harborRepo $JOB_NAME $tag $port ", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
}
}
Ps:由于采用變量,記得使用雙引號(hào)
2.6.3 Jenkins流水線(xiàn)整合釘釘
在程序部署成功之后,可以通過(guò)釘釘?shù)臋C(jī)器人及時(shí)向開(kāi)發(fā)人員發(fā)送部署的最終結(jié)果通知
步驟:Jenkins安裝插件 - 釘釘創(chuàng)建群組并構(gòu)建機(jī)器人 - Jenkins配置系統(tǒng)添加釘釘通知 - 任務(wù)中追加釘釘流水線(xiàn)配置
- 安裝插件
- 釘釘內(nèi)部創(chuàng)建群組并構(gòu)建機(jī)器人
最終獲取到Webhook信息:
https://oapi.dingtalk.com/robot/send?access_token=kej4ehkj34gjhg34jh5bh5jb34hj53b4
- Jenkins系統(tǒng)配置添加釘釘通知
- 任務(wù)線(xiàn)中追加流水線(xiàn)配置
pipeline {
agent any
environment {
sonarLogin = '2bab7bf7d5af25e2c2ca2f178af2c3c55c64d5d8'
harborUser = 'admin'
harborPassword = 'Harbor12345'
harborHost = '192.168.11.12:8888'
harborRepo = 'repository'
}
stages {
stage('拉取Git代碼'){
steps {
checkout([$class: 'GitSCM', branches: [[name: '$tag']], extensions: [], userRemoteConfigs: [[url: 'http://49.233.115.171:8929/root/lsx.git']]])
}
}
stage('Maven構(gòu)建代碼'){
steps {
sh '/var/jenkins_home/maven/bin/mvn clean package -DskipTests'
}
}
stage('SonarQube檢測(cè)代碼'){
steps {
sh '/var/jenkins_home/sonar-scanner/bin/sonar-scanner -Dsonar.sources=./ -Dsonar.projectname=${JOB_NAME} -Dsonar.projectKey=${JOB_NAME} -Dsonar.java.binaries=target/ -Dsonar.login=${sonarLogin}'
}
}
stage('制作自定義鏡像'){
steps {
sh '''cd docker
mv ../target/*.jar ./
docker build -t ${JOB_NAME}:$tag .
'''
}
}
stage('推送自定義鏡像'){
steps {
sh '''docker login -u ${harborUser} -p ${harborPassword} ${harborHost}
docker tag ${JOB_NAME}:$tag ${harborHost}/${harborRepo}/${JOB_NAME}:$tag
docker push ${harborHost}/${harborRepo}/${JOB_NAME}:$tag'''
}
}
stage('通知目標(biāo)服務(wù)器'){
steps {
sshPublisher(publishers: [sshPublisherDesc(configName: 'centos-docker', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: "/usr/bin/deploy.sh $harborHost $harborRepo $JOB_NAME $tag $port", execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: '', remoteDirectorySDF: false, removePrefix: '', sourceFiles: '')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
}
post {
success {
dingtalk (
robot: 'Jenkins-DingDing',
type:'MARKDOWN',
title: "success: ${JOB_NAME}",
text: ["- 成功構(gòu)建:${JOB_NAME}項(xiàng)目!\n- 版本:${tag}\n- 持續(xù)時(shí)間:${currentBuild.durationString}\n- 任務(wù):#${JOB_NAME}"]
)
}
failure {
dingtalk (
robot: 'Jenkins-DingDing',
type:'MARKDOWN',
title: "fail: ${JOB_NAME}",
text: ["- 失敗構(gòu)建:${JOB_NAME}項(xiàng)目!\n- 版本:${tag}\n- 持續(xù)時(shí)間:${currentBuild.durationString}\n- 任務(wù):#${JOB_NAME}"]
)
}
}
}
- 查看效果
2.7 Kubernetes
2.7.1 介紹及安裝
Kubernetes又稱(chēng)為k8s,是一個(gè)開(kāi)源的,用于管理云平臺(tái)中多個(gè)主機(jī)上的容器。目的是讓容器化部署更加簡(jiǎn)單、高效。
①k8s主要作用:
- 服務(wù)發(fā)現(xiàn)和負(fù)載均衡(DNS名稱(chēng)或自己IP地址公開(kāi)容器)
- 存儲(chǔ)編排(類(lèi)似Docker的數(shù)據(jù)卷)
- 自動(dòng)部署和回滾(可以按照你的需求調(diào)整容器狀態(tài))
- 自動(dòng)完成裝箱計(jì)算(允許你設(shè)置每個(gè)容器的資源,CPU、內(nèi)存等)
- 自我修復(fù)(可以重啟失敗的容器、替換容器、檢查容器狀況等)
- 密鑰與配置管理(允許存儲(chǔ)和管理敏感信息,可以在不重建容器的情況下完成部署和更新密鑰)
②k8s的架構(gòu)
k8s搭建至少需要兩個(gè)節(jié)點(diǎn),一個(gè)Master負(fù)責(zé)管理,一個(gè)Slave搭建在工作服務(wù)器上負(fù)責(zé)分配
各個(gè)組件的基本功能
- API Server:k8s通訊的核心組件,負(fù)責(zé)k8s內(nèi)部交互及接收發(fā)送指令的組件
- controller-manage:資源調(diào)度,根據(jù)集群情況分配資源
- etcd:key-value數(shù)據(jù)庫(kù),存儲(chǔ)集群的狀態(tài)信息
- scheduler:負(fù)責(zé)調(diào)度每個(gè)工作節(jié)點(diǎn)
- cloud-controller-manage:負(fù)責(zé)調(diào)度其他云服務(wù)產(chǎn)品
- kubelet:管理Pods上面的容器
- kube-proxy:負(fù)責(zé)處理其他Slave或客戶(hù)端的請(qǐng)求
- Pod:運(yùn)行的容器
③k8s安裝
本文采用https://kuboard.cn/提供的方式安裝K8s,安裝單Master節(jié)點(diǎn)
- 要求:至少使用Centos7.8版本
- 至少2臺(tái)2核4G服務(wù)器
準(zhǔn)備好服務(wù)器之后開(kāi)始安裝:
1. 重新設(shè)置hostname,不允許為localhost
# 修改 hostname,名字不允許使用下劃線(xiàn)、小數(shù)點(diǎn)、大寫(xiě)字母,不能叫master
hostnamectl set-hostname your-new-host-name
# 查看修改結(jié)果
hostnamectl status
# 設(shè)置 hostname 解析
echo "127.0.0.1 $(hostname)" >> /etc/hosts
要求2臺(tái)服務(wù)器之間可以相互通訊
2. 安裝kuboard軟件
# 阿里云 docker hub 鏡像
export REGISTRY_MIRROR=https://registry.cn-hangzhou.aliyuncs.com
curl -sSL https://kuboard.cn/install-script/v1.19.x/install_kubelet.sh | sh -s 1.19.5
3. 初始化Master節(jié)點(diǎn)
關(guān)于初始化時(shí)用到的環(huán)境變量
-
APISERVER_NAME 不能是 master 的 hostname
-
APISERVER_NAME 必須全為小寫(xiě)字母、數(shù)字、小數(shù)點(diǎn),不能包含減號(hào)
-
POD_SUBNET 所使用的網(wǎng)段不能與 master節(jié)點(diǎn)/worker節(jié)點(diǎn) 所在的網(wǎng)段重疊。該字段的取值為一個(gè) CIDR 值,如果您對(duì) CIDR 這個(gè)概念還不熟悉,請(qǐng)仍然執(zhí)行 export POD_SUBNET=10.100.0.0/16 命令,不做修改
-
設(shè)置ip,域名,網(wǎng)段并執(zhí)行初始化操作
# 只在 master 節(jié)點(diǎn)執(zhí)行
# 替換 x.x.x.x 為 master 節(jié)點(diǎn)實(shí)際 IP(請(qǐng)使用內(nèi)網(wǎng) IP)
# export 命令只在當(dāng)前 shell 會(huì)話(huà)中有效,開(kāi)啟新的 shell 窗口后,如果要繼續(xù)安裝過(guò)程,請(qǐng)重新執(zhí)行此處的 export 命令
export MASTER_IP=192.168.11.32
# 替換 apiserver.demo 為 您想要的 dnsName
export APISERVER_NAME=apiserver.demo
# Kubernetes 容器組所在的網(wǎng)段,該網(wǎng)段安裝完成后,由 kubernetes 創(chuàng)建,事先并不存在于您的物理網(wǎng)絡(luò)中
export POD_SUBNET=10.100.0.1/16
echo "${MASTER_IP} ${APISERVER_NAME}" >> /etc/hosts
curl -sSL https://kuboard.cn/install-script/v1.19.x/init_master.sh | sh -s 1.19.5
- 檢查Master啟動(dòng)狀態(tài)
# 只在 master 節(jié)點(diǎn)執(zhí)行
# 執(zhí)行如下命令,等待 3-10 分鐘,直到所有的容器組處于 Running 狀態(tài)
watch kubectl get pod -n kube-system -o wide
# 查看 master 節(jié)點(diǎn)初始化結(jié)果
kubectl get nodes -o wide
Ps:如果出現(xiàn)NotReady的情況執(zhí)行(最新版本的BUG,1.19一般沒(méi)有)
docker pull quay.io/coreos/flannel:v0.10.0-amd64
mkdir -p /etc/cni/net.d/
cat <<EOF> /etc/cni/net.d/10-flannel.conf
{"name":"cbr0","type":"flannel","delegate": {"isDefaultGateway": true}}
EOF
mkdir /usr/share/oci-umount/oci-umount.d -p
mkdir /run/flannel/
cat <<EOF> /run/flannel/subnet.env
FLANNEL_NETWORK=172.100.0.0/16
FLANNEL_SUBNET=172.100.1.0/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=true
EOF
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.9.1/Documentation/kube-flannel.yml
- 安裝網(wǎng)絡(luò)服務(wù)插件
export POD_SUBNET=10.100.0.0/16
kubectl apply -f https://kuboard.cn/install-script/v1.22.x/calico-operator.yaml
wget https://kuboard.cn/install-script/v1.22.x/calico-custom-resources.yaml
sed -i "s#192.168.0.0/16#${POD_SUBNET}#" calico-custom-resources.yaml
kubectl apply -f calico-custom-resources.yaml
4. 初始化worker節(jié)點(diǎn)
- 獲取join命令參數(shù),在Master節(jié)點(diǎn)執(zhí)行
# 只在 master 節(jié)點(diǎn)執(zhí)行
kubeadm token create --print-join-command
- 在worker節(jié)點(diǎn)初始化
# 只在 worker 節(jié)點(diǎn)執(zhí)行
# 替換 x.x.x.x 為 master 節(jié)點(diǎn)的內(nèi)網(wǎng) IP
export MASTER_IP=192.168.11.32
# 替換 apiserver.demo 為初始化 master 節(jié)點(diǎn)時(shí)所使用的 APISERVER_NAME
export APISERVER_NAME=apiserver.demo
echo "${MASTER_IP} ${APISERVER_NAME}" >> /etc/hosts
# 替換為 master 節(jié)點(diǎn)上 kubeadm token create 命令的輸出
kubeadm join apiserver.demo:6443 --token vwfilu.3nhndohc5gn1jv9k --discovery-token-ca-cert-hash sha256:22ff15cabfe87ab48a7db39b3bbf986fee92ec92eb8efc7fe9b0abe2175ff0c2
5. 檢查最終運(yùn)行結(jié)果
- 在Master節(jié)點(diǎn)運(yùn)行
# 只在 master 節(jié)點(diǎn)執(zhí)行
kubectl get nodes -o wide
Ps:如果出現(xiàn)NotReady的情況執(zhí)行(最新版本的BUG,1.19一般沒(méi)有)
docker pull quay.io/coreos/flannel:v0.10.0-amd64
mkdir -p /etc/cni/net.d/
cat <<EOF> /etc/cni/net.d/10-flannel.conf
{"name":"cbr0","type":"flannel","delegate": {"isDefaultGateway": true}}
EOF
mkdir /usr/share/oci-umount/oci-umount.d -p
mkdir /run/flannel/
cat <<EOF> /run/flannel/subnet.env
FLANNEL_NETWORK=172.100.0.0/16
FLANNEL_SUBNET=172.100.1.0/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=true
EOF
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.9.1/Documentation/kube-flannel.yml
- 獲取節(jié)點(diǎn)信息
kubectl get nodes
6. 安裝Kuboard管理k8s集群
- 安裝Kuboard
kubectl apply -f https://addons.kuboard.cn/kuboard/kuboard-v3.yaml
# 您也可以使用下面的指令,唯一的區(qū)別是,該指令使用華為云的鏡像倉(cāng)庫(kù)替代 docker hub 分發(fā) Kuboard 所需要的鏡像
# kubectl apply -f https://addons.kuboard.cn/kuboard/kuboard-v3-swr.yaml
- 查看啟動(dòng)情況
watch kubectl get pods -n kuboard
- 在瀏覽器中打開(kāi)鏈接 http://your-node-ip-address:30080
- 輸入初始用戶(hù)名和密碼,并登錄
- 用戶(hù)名:
admin
- 密碼:
Kuboard123
2.7.2 k8s操作
首先k8s在運(yùn)行我們的資源時(shí),關(guān)聯(lián)到了哪些內(nèi)容呢?
- 資源的構(gòu)建方式:
- 采用kubectl的命令方式
- yaml文件方式
①namespace
命名空間:對(duì)k8s中運(yùn)行的資源進(jìn)行隔離,但是網(wǎng)絡(luò)是互通的。類(lèi)似于docker的容器,可以將多個(gè)資源配置到一個(gè)namespace中。而namespace可以對(duì)不同環(huán)境進(jìn)行資源隔離,默認(rèn)情況下k8s提供了default命名空間。
命令方式:
# 查看現(xiàn)有的全部命名空間
kubectl get ns
# 構(gòu)建命名空間
kubectl create ns 命名空間名稱(chēng)
# 刪除現(xiàn)有命名空間, 并且會(huì)刪除空間下的全部資源
kubectl delete ns 命名空間名稱(chēng)
yaml文件方式(構(gòu)建源時(shí),設(shè)置命名空間)
apiVersion: v1
kind: Namespace
metadata:
name: test
②Pod
k8s中運(yùn)行的一組容器,Pod是k8s的最小單位。但是對(duì)于Docker而言,Pod中會(huì)運(yùn)行多個(gè)Docker容器
- 命令方式
# 查看所有運(yùn)行的pod
kubectl get pods -A
# 查看指定Namespace下的Pod
kubectl get pod [-n 命名空間] #(默認(rèn)default)
# 創(chuàng)建Pod
kubectl run pod名稱(chēng) --image=鏡像名稱(chēng)
# 查看Pod詳細(xì)信息
kubectl describe pod pod名稱(chēng)
# 刪除pod
kubectl delete pod pod名稱(chēng) [-n 命名空間] #(默認(rèn)default)
# 查看pod輸出的日志
kubectl logs -f pod名稱(chēng)
# 進(jìn)去pod容器內(nèi)部
kubectl exec -it pod名稱(chēng) -- bash
# 查看kubernetes給Pod分配的ip信息,并且通過(guò)ip和容器的端口,可以直接訪(fǎng)問(wèn)
kubectl get pod -owide
- yaml方式(推薦)
apiVersion: v1
kind: Pod
metadata:
labels:
run: 運(yùn)行的pod名稱(chēng)
name: pod名稱(chēng)
namespace: 命名空間
spec:
containers:
- image: 鏡像名稱(chēng)
name: 容器名稱(chēng)
# 啟動(dòng)Pod:kubectl apply -f yaml文件名稱(chēng)
# 刪除Pod:kubectl delete -f yaml文件名稱(chēng)
- Pod中運(yùn)行多個(gè)容器
apiVersion: v1
kind: Pod
metadata:
labels:
run: 運(yùn)行的pod名稱(chēng)
name: pod名稱(chēng)
namespace: 命名空間
spec:
containers:
- image: 鏡像名稱(chēng)
name: 容器名稱(chēng)
- image: 鏡像名稱(chēng)
name: 容器名稱(chēng)
…………
Kuboard效果:
③Deployment
部署時(shí),可以通過(guò)Deployment管理和編排Pod
- 命令方式
# 基于Deployment啟動(dòng)容器
kubectl create deployment deployment名稱(chēng) --image=鏡像名稱(chēng)
# 用deployment啟動(dòng)的容器會(huì)在被刪除后自動(dòng)再次創(chuàng)建,達(dá)到故障漂移的效果
# 需要使用deploy的方式刪除deploy
# 查看現(xiàn)在的deployment
kubectl get deployment
# 刪除deployment
kubectl delete deployment deployment名稱(chēng)
# 基于Deployment啟動(dòng)容器并設(shè)置Pod集群數(shù)
kubectl create deployment deployment名稱(chēng) --image=鏡像名稱(chēng) --replicas 集群個(gè)數(shù)
- 配置文件方式
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
正常使用kubectl運(yùn)行yaml即可
彈性伸縮功能:
# 基于scale實(shí)現(xiàn)彈性伸縮
kubectl scale deploy/Deployment名稱(chēng) --replicas 集群個(gè)數(shù)
# 或者修改yaml文件
kubectl edit deploy Deployment名稱(chēng)
灰度發(fā)布:
Deploy可以在部署新版本數(shù)據(jù)時(shí),成功啟動(dòng)一個(gè)Pod,才會(huì)下線(xiàn)一個(gè)老版本Pod
kubectl set image deployment/Deployment名稱(chēng) 容器名=鏡像:版本
④service
可以將多個(gè)Pod整合為一個(gè)Service,讓客戶(hù)端通過(guò)這一個(gè)Service訪(fǎng)問(wèn)到這一組Pod,并且可以實(shí)現(xiàn)負(fù)載均衡
- ClusterIP方式:
ClusterIP是集群內(nèi)部Pod之間的訪(fǎng)問(wèn)方式
命令實(shí)現(xiàn)效果
# 通過(guò)生成service映射一個(gè)Deployment下的所有pod中的某一個(gè)端口的容器
kubectl expose deployment Deployment名稱(chēng) --port=Service端口號(hào) --target-port=Pod內(nèi)容器端口
之后通過(guò)kubectl get service
查看Service提供的ip,即可訪(fǎng)問(wèn)
也可以通過(guò)Deployment名稱(chēng).namespace名稱(chēng).svc
作為域名訪(fǎng)問(wèn)
- NodePort方式
ClusterIP方式只能在Pod內(nèi)部實(shí)現(xiàn)訪(fǎng)問(wèn),但是一般需要對(duì)外暴露網(wǎng)關(guān),所以需要NodePort的方式將Pod對(duì)外暴露訪(fǎng)問(wèn)
命令實(shí)現(xiàn)方式:
# 通過(guò)生成service映射一個(gè)Deployment下的所有pod中的某一個(gè)端口的容器
kubectl expose deployment Deployment名稱(chēng) --port=Service端口號(hào) --target-port=Pod內(nèi)容器端口 --type=NodePort
Service通過(guò)yaml方式實(shí)現(xiàn):
apiVersion: v1
kind: Service
metadata:
labels
app: nginx
name: nginx
spec:
selector:
app: nginx
ports:
- port: 8888
protocol: TCP
targetPort: 80
通過(guò)apply啟動(dòng)就可以創(chuàng)建Service
測(cè)試:通過(guò)Deployment部署,通過(guò)Service部署
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx-deployment
spec:
replicas: 2
selector:
matchLabels:
app: nginx-deployment
template:
metadata:
labels:
app: nginx-deployment
spec:
containers:
- name: nginx-deployment
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx-service
name: nginx-service
spec:
selector:
app: nginx-deployment
ports:
- port: 8888
protocol: TCP
targetPort: 80
type: NodePort
可以查看到暴露信息:
⑤Ingress(入口)
k8s推薦將Ingress作為所有Service的入口,提供統(tǒng)一的入口,避免多個(gè)服務(wù)之間需要記錄大量的IP或域名(IP可能變化,域名太多記錄不方便)
- Ingress底層就是一個(gè)Nginx,可以直接在kuboard上點(diǎn)擊安裝
因?yàn)楦北緮?shù)默認(rèn)為1,但是k8s整體集群就2個(gè)節(jié)點(diǎn),所以顯示下面即為安裝成功
可以將Ingress接收到的請(qǐng)求轉(zhuǎn)發(fā)到不同的Service中
推薦使用yaml文件方式
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
spec:
ingressClassName: ingress
rules:
- host: nginx.mashibing.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 8888
Kuboard安裝的Ingress有admission的校驗(yàn)配置,需要先刪除配置再啟動(dòng)
找到指定的ingress的校驗(yàn)信息,刪除即可
# 查看校驗(yàn)webhook的配置
kubectl get -A ValidatingWebhookConfiguration
# 刪除指定的校驗(yàn)
kubectl delete ValidatingWebhookConfiguration ingress-nginx-admission-my-ingress-controller
配置本地hosts文件:
下面就可以訪(fǎng)問(wèn)在Service中暴露的Nginx信息:
2.8 Jenkins集成K8s
2.8.1 準(zhǔn)備部署的yaml文件
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: test
name: pipeline
labels:
app: pipeline
spec:
replicas: 2
selector:
matchLabels:
app: pipeline
template:
metadata:
labels:
app: pipeline
spec:
containers:
- name: pipeline
image: 192.168.11.102:80/repo/pipeline:v4.0.0
imagePullPolicy: Always
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
namespace: test
labels:
app: pipeline
name: pipeline
spec:
selector:
app: pipeline
ports:
- port: 8081
targetPort: 8080
type: NodePort
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
namespace: test
name: pipeline
spec:
ingressClassName: ingress
rules:
- host: mashibing.pipeline.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: pipeline
port:
number: 8081
2.8.2 Harbor私服配置
在嘗試用kubernetes的yml文件啟動(dòng)pipeline服務(wù)時(shí),會(huì)出現(xiàn)Kubernetes無(wú)法拉取鏡像的問(wèn)題,這里需要在kubernetes所在的Linux中配置Harbor服務(wù)信息,并且保證Kubernetes可以拉取Harbor上的鏡像
- 設(shè)置Master和Worker的私服地址信息
- 在Kuboard上設(shè)置私服密文信息
將上圖復(fù)制好的指定執(zhí)行,測(cè)試結(jié)果如下:
2.8.3 測(cè)試使用效果
執(zhí)行kubectl命令,基于yml啟動(dòng)服務(wù),并且基于部署后服務(wù)的提示信息以及Ingress的設(shè)置,直接訪(fǎng)問(wèn)
2.8.4 Jenkins遠(yuǎn)程調(diào)用
- 將pipeline.yml配置到GitLab中
- 配置Jenkins目標(biāo)服務(wù)器,可以將yml文件傳輸?shù)絢8s的Master上
- 修改Jenkinsfile,重新設(shè)置流水線(xiàn)任務(wù)腳本,并測(cè)試效果
- 設(shè)置Jenkins無(wú)密碼登錄k8s-master
將Jenkins中公鑰信息復(fù)制到k8s-master的~/.ssh/authorized_keysz中,保證遠(yuǎn)程連接無(wú)密碼
5. 設(shè)置執(zhí)行kubectl的腳本到Jenkinsfile
查看效果:
可以查看到y(tǒng)ml文件是由變化的, 這樣k8s就會(huì)重新加載
Ps:這種方式更適應(yīng)與CD操作,將項(xiàng)目將基于某個(gè)版本部署到指定的目標(biāo)服務(wù)器
2.9 基于GitLab的WebHooks
實(shí)現(xiàn)一個(gè)自動(dòng)化的CI(開(kāi)發(fā)人員push代碼到Git倉(cāng)庫(kù)之后,Jenkins會(huì)自動(dòng)構(gòu)建項(xiàng)目,將最新的提交點(diǎn)代碼構(gòu)建并進(jìn)行打包部署)。這里區(qū)別于上面的CD,CD需要基于某個(gè)版本進(jìn)行部署,而這里每次都是將最新的提交點(diǎn)集成到主干上并測(cè)試。
2.9.1 WebHooks通知
-
開(kāi)啟Jenkins自動(dòng)構(gòu)建
-
設(shè)置GitLab的Webhooks
-
關(guān)閉Jenkins的GitLab認(rèn)證
-
再次測(cè)試
拓展:實(shí)現(xiàn)滾動(dòng)更新
因?yàn)閜ipeline沒(méi)有改變時(shí),每次不會(huì)重新加載,這樣會(huì)導(dǎo)致Pod中的容器不會(huì)動(dòng)態(tài)更新,這里需要使用kubectl的rollout restart命令滾動(dòng)更新文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-416436.html
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-416436.html
到了這里,關(guān)于DevOps概念及搭建全過(guò)程(Jenkins、Harbor、SonarQube、K8s)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!