本文章會涉及Docker常見命令基礎(chǔ)知識點結(jié)合不同場景實操一起使用。
本文章會涉及結(jié)合工作過程中部署不同環(huán)境服務(wù)器的項目案例場景為初心進行實際細(xì)講。
本文章主要講述Docker、Jenkins、GitLab、Git、JDK、SpringBoot、Maven等技術(shù)結(jié)合實現(xiàn)自動化運維部署(DevOps)應(yīng)用工程,適合SpringCloud部署。
初衷想法:在學(xué)習(xí)過程中遇到比較有趣的問題、然而花了點心血和時間去整理,然而進行梳理出來一份文章比較完整有知識體系的DevOps自動化構(gòu)建與部署工程文章,技術(shù)知識內(nèi)容比較多,而且文章內(nèi)容較長,然而分了幾個章程來講述
DevOps(Development和Operations的組合詞)是一組過程、方法與系統(tǒng)的統(tǒng)稱,用于促進開發(fā)(應(yīng)用程序/軟件工程)、技術(shù)運營和質(zhì)量保障(QA)部門之間的溝通、協(xié)作與整合,它是一種重視“軟件開發(fā)人員(Dev)”和“IT運維技術(shù)人員(Ops)”之間溝通合作的文化、運動或慣例。透過自動化“軟件交付”和“架構(gòu)變更”的流程,來使得構(gòu)建、測試、發(fā)布軟件能夠更加地快捷、頻繁和可靠。
它的出現(xiàn)是由于軟件行業(yè)日益清晰地認(rèn)識到:為了按時交付軟件產(chǎn)品和服務(wù),開發(fā)和運營工作必須緊密合作。
見附錄
特別說明
1、如何使用Maven結(jié)合Docker把SpringBoot應(yīng)用編譯成可用的鏡像進行部署。
2、其中JDK和Maven是傳統(tǒng)方式進行安裝,由于本人Centos操作系統(tǒng)是有其他軟件依賴它們,有時候傳統(tǒng)方式安裝軟件會更好,這里不過多的闡述。有些軟件在Docker安裝過程與使用過程并沒傳統(tǒng)方式的簡單,比如:Jenkins。
環(huán)境配置特別說明
注意事項:其中Gitlab、Registry、Jenkins都安裝在node1機器上面,也就是node1作為主機(master),node2作為slave(從機或副機),機器名起有意義或能區(qū)分即可,推薦起master和slave,這里就不作過多的闡述,為了避免看文章有疑問,請看清單列表.
<dependencies>
<!-- Springboot依賴的Jar包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Springboot熱部署jar-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!--yml配置文件提示插件-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- spring-boot測試jar -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>springboot</finalName>
<!-- 一定要聲明如下配置 打包xml 到Jar包 -->
<!-- <resources>
<resource>
<directory>src/main/java</directory>
是否替換資源中的屬性
<filtering>false</filtering>
</resource>
</resources>
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
-->
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<!-- 默認(rèn)支持jdk1.8編譯 -->
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<!--docke rmaven編譯插件-->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.12</version>
<configuration>
<dockerDirectory>${project.basedir}</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.flong.SpringbootApplication</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.flong.SpringbootApplication</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
JAVA_OPTS_DEFAULT=-Xmx512m
FROM frolvlad/alpine-oraclejdk8:slim
MAINTAINER jilongliang@sina.com
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN mkdir -p /home/devsoft/springboot_dev
WORKDIR /home/devsoft/springboot_dev
EXPOSE 7011
ADD ./target/springboot.jar ./
CMD java ${JAVA_OPTS_DEFAULT} -Djava.security.egd=file:/dev/./urandom -jar springboot.jar
docker exec -it 容器名稱或容器id /bin/sh
或要使用sh和bash要看COMMAND,-it
docker exec -it 容器名稱或容器id/bin/bash
注意點1:經(jīng)過測試動態(tài)變量的【等號】不能有空格和tab鍵置位,否則獲取不了值,而且在shell腳本代碼里面不支持空格格式化,支持tab置位格式化。在終端(ssh軟件端)或Jenkins客戶端shell命令,『位置變量』的參數(shù)以空格隔開。
如:sh build.sh 192.168.1.235 springboot 0.0.1 7011 /home/jenkins/workspace/springboot_dev
$IMG_NAME:$IMG_VERSION這個IMG_VERSION
版本(tag)參數(shù)不指定默認(rèn)latest
注意點2:通常情況下Docker是默認(rèn)執(zhí)行Dockerfile,但是可以自定義后綴文件進行編譯,前提必須要-f(force)強制指定文件進行運行
#!/usr/bin/env bash
# 動態(tài)變量的【等號】不能有空格和tab鍵置位,否則獲取不了值,而且在shell腳本代碼里面不支持空格格式化,支持tab置位格式化。
# 在終端(ssh軟件端)或Jenkins客戶端shell命令,參數(shù)以空格隔開。如:sh build.sh 192.168.1.235 springboot 0.0.1 7011 /home/jenkins/workspace/springboot_dev
IMG_SERVER="$1"
IMG_NAME="$2"
IMG_VERSION="$3"
IMG_PORT="$4"
RUN_EVN="$5"
IMG_PATH="$6"
echo "服務(wù)地址:$IMG_SERVER"
echo "工程鏡像名稱:$IMG_NAME"
echo "工程版本號:$IMG_VERSION"
echo "工程端口:$IMG_PORT"
echo "服務(wù)環(huán)境:$RUN_EVN"
#私服訪問url路徑和編譯之后鏡像文件存放到指定路徑固定,不動態(tài)參數(shù)進行處理傳值.
REGISTRY_URL="192.168.1.235:5000"
IMG_TAR_GZ_PATH="/home/img_tar_gz_path/"
# 判斷動態(tài)參數(shù)不為空字符串的時候才執(zhí)行下面操作
if [ "$IMG_SERVER" != "" ] && [ "$IMG_NAME" != "" ] && [ "$IMG_VERSION" != "" ] && [ "$IMG_PORT" != "" ]; then
echo " .......進入刪除 Container & Images 操作 ......."
# 清理虛懸鏡像,釋放磁盤空間
#docker images|grep none|awk '{print $3 }'|xargs docker rmi
# 獲取容器ID
CONTAINER_ID=`docker ps -a | grep $IMG_NAME | awk '{ print $1 }'`
# 獲取鏡像ID
IMAGE_ID=`docker images | grep $IMG_NAME | awk '{ print $3 }'`
# 判斷是否存在刪除開發(fā)容器
if [[ "$CONTAINER_ID" != "" ]]; then
docker rm -f $CONTAINER_ID
fi
# 判斷是否存在刪除開發(fā)鏡像
if [[ "$IMAGE_ID" != "" ]]; then
docker rmi -f $IMAGE_ID
fi
# $IMG_NAME:$IMG_VERSION 這個IMG_VERSION版本(tag)參數(shù)不指定默認(rèn)latest,通過不同參數(shù)執(zhí)行不同環(huán)境文件
# -f 表示強制指定Dockerfile文件進行編譯
echo " .......進入Building & Images 操作 ....... "
#方法1、指定不同文件存放默認(rèn)的Dockerfile,使用-f進行強制編譯
#docker build -t $IMG_NAME:$IMG_VERSION -f $IMG_PATH"env/"$RUN_EVN/Dockerfile $IMG_PATH
#方法2、跟據(jù)不同Dockerfile文件的后綴進行編譯不同環(huán)境的文件
docker build -t $IMG_NAME:$IMG_VERSION -f $IMG_PATH"env/"Dockerfile_$RUN_EVN $IMG_PATH
# 將鏡像打一下標(biāo)簽,然后安照標(biāo)簽進行推送到私服里面,標(biāo)簽名就以服務(wù)名即可
docker tag $IMG_NAME:$IMG_VERSION $REGISTRY_URL/$IMG_NAME:$IMG_VERSION
# 推鏡像到私服里面
docker push $REGISTRY_URL/$IMG_NAME:$IMG_VERSION
# 判斷是否存在文件夾
if [ -d "$IMG_PATH" ];then
echo "已經(jīng)存在:"$IMG_PATH
else
mkdir -p $IMG_PATH
fi
# 保存編譯之后鏡像文件存放到指定路徑
docker save $IMG_NAME -o $IMG_TAR_GZ_PATH/$IMG_NAME.tar.gz
echo " .......進入Runing操作 ....."
docker run -d --network default_network --restart=always --env-file=./.env -e spring.profiles.active=$RUN_EVN --expose=$IMG_PORT --name=$IMG_NAME -p $IMG_PORT:$IMG_PORT $IMG_NAME:$IMG_VERSION
echo " .......Build & Run Finish Success~...."
else
echo " .......Illegal Command Operation ......."
fi
docker save 鏡像名 -o 路徑/鏡像名.tar.gz
或
docker save 鏡像名 -o 路徑/鏡像名.tar
docker load 命令是用于導(dǎo)入使用 docker save
命令導(dǎo)出的鏡像,此命令非常重要,由于有些客戶要求項目工程要求部署在內(nèi)網(wǎng),此時這個命令在無網(wǎng)絡(luò)的內(nèi)網(wǎng)情況下部署項目的時候就體現(xiàn)它重要的地位了.語法 docker load [OPTIONS]
,在加載的過程有點慢,因為文件有點大,其中顯示Loady Layer [======]
輸出信息,證實鏡像是分層關(guān)系。
docker load -i /home/img_tar_gz_path/springboot.tar.gz
docker tag
和docker push
命令是一起結(jié)合使用,先tag后push,每個鏡像名和版本是以冒號區(qū)分,而docker pull根據(jù)情況使用.# 將鏡像打一下標(biāo)簽,然后安照標(biāo)簽進行推送到私服里面,標(biāo)簽名就以服務(wù)名即可
docker tag 鏡像名:版本號 私服路徑/鏡像名:版本號
# 推鏡像到私服里面
docker push私服路徑/鏡像名:版本號
瀏覽器驗證docker push推送上私服的鏡像
<none>
。一般來說,虛懸鏡像已經(jīng)失去了存在的價值,是可以隨意刪除的。配置參數(shù)
不同環(huán)境配置參數(shù)內(nèi)容
server:
port: 7011
runEvn: '開發(fā)環(huán)境'
server:
port: 7011
runEvn: '測試環(huán)境'
@RestController
public class SimpleController {
//讀取配置動態(tài)參數(shù)
@Value("${runEvn}")
private String runEvn;
@GetMapping("/test")
public String test() {
return "this spring boot " + runEvn +" date long "
+ System.currentTimeMillis();
}
}
表示忽略測試單元類進行編譯
clean install -U -Dmaven.test.skip=true
http://jenkins地址:端口/jenkins/configure
設(shè)置好進行選擇${serverPath}
獲取${serverPath}
獲取#!/bin/bash
表示告訴終端使用bash解析器進行執(zhí)行,而且只有第一行bash才有效。#!/bin/bash
# 創(chuàng)建目錄
mkdir -p ${serverPath}
# 切換目錄
cd ${serverPath}
# 運行腳本
sh build.sh $server ${appName} ${version} ${port} ${env} ${serverPath}
http://jenkins地址:端口/jenkins/configure
設(shè)置好進行選擇${serverPath}
獲取${serverPath}
獲取#!/bin/bash
表示告訴終端使用bash解析器進行執(zhí)行,而且只有第一行bash才有效。#!/bin/bash
# 打印信息
echo "用戶名${userName}"
echo "服務(wù)器${server}"
echo "服務(wù)器目錄${serverPath}"
# 遠(yuǎn)程創(chuàng)建存放遠(yuǎn)程上傳的代碼目錄路徑
ssh $server mkdir -p ${targetServerPath}
# 遠(yuǎn)程拷貝代碼到目標(biāo)機器指定路徑
scp -r ${serverPath}/ ${userName}@${server}:${targetServerPath}
#!/bin/bash
# 切換文件目錄
cd ${serverPath}
# 執(zhí)行腳本
sh build.sh ${server} ${appName} ${version} ${port} ${env} ${serverPath}
1、此文章僅供提供參考學(xué)習(xí)指引,如需要系統(tǒng)得學(xué)習(xí)可以根據(jù)自身找資料去學(xué)習(xí)。
2、以上問題都是根據(jù)個人實際學(xué)習(xí)過程中遇到的問題進行一個一個問題進行梳理與總結(jié)整理,除了技術(shù)問題查很多網(wǎng)上資料通過進行學(xué)習(xí)之后整理與分享。
3、在學(xué)習(xí)過程中也遇到很多困難和疑點,如有問題或誤點,望各位老司機多多指出或者提出建議。本人會采納各種好建議和正確方式不斷完善現(xiàn)況,人在成長過程中的需要優(yōu)質(zhì)的養(yǎng)料。
4、當(dāng)遇到問題的時候建議多問『谷歌 、必應(yīng)、stackoverflow、度娘』這些大神。
5、建議看官方手冊更權(quán)威,由于隨著技術(shù)的發(fā)展與迭代,通常官方的文檔更新較快,國內(nèi)的網(wǎng)站資料更新較慢。
6、計算機是一門『做中學(xué)』的學(xué)科,不是會了再去做,而是做了才會。多練,常言道熟能生巧。
7、建議學(xué)什么技術(shù)『先Know how,再Know Why』,意思就說先入門,搞一個HelloWorld,再深究的意思。
8、希望此文章能幫助你更好了解什么(DevOps)是自動化構(gòu)建鏡像與部署,如何在Docker+Jenkins+GitLab+Maven+SpringBoot&SpringCloud自動構(gòu)建鏡像與部署服務(wù)應(yīng)用,整個學(xué)習(xí)流程與搭建會有點小曲折,并不會那么順利,也希望你看了此文章或者通過找資料進行親身經(jīng)歷學(xué)習(xí)效果會更好。
https://docs.docker.com/engine/reference/commandline/docker/
https://yeasy.gitbooks.io/docker_practice/
https://github.com/spotify/docker-maven-plugin
https://dmp.fabric8.io/
https://github.com/jilongliang/springboot
https://www.cnblogs.com/kakaln/p/7872873.html
https://www.cnblogs.com/lucoo/p/10209892.html