目錄
前言:我們以前是如何部署項目的?
1、鏡像由哪幾部分構(gòu)成的
2、如何手動自定義一個鏡像
2.1、Dockerfile
2.2、dockerfile文本文件中,最終要寫什么?
2.3、構(gòu)建鏡像
3、案例:部署java項目
4、如何與其他容器相互訪問,例如:java項目鏡像創(chuàng)建的容器與mysql容器相互訪問
4.1、使用默認(rèn)的網(wǎng)絡(luò)?
4.1、網(wǎng)絡(luò)相關(guān)命令
4.3、創(chuàng)建新的網(wǎng)絡(luò)?
前言:我們以前是如何部署項目的?
? ? ? ? 這個我在這篇文章中,有做說明,剛興趣的小伙伴,可以去看看:
? ? ? ? 另外,是來學(xué)習(xí)的伙伴們,需要自己準(zhǔn)備一個java項目,并準(zhǔn)備好他的jar包~??
1、鏡像由哪幾部分構(gòu)成的
? ? ? ? 傳統(tǒng)的部署項目,大致有以下幾個步驟:
- 準(zhǔn)備一個Linux服務(wù)器
- 安裝jdk并配置環(huán)境變量
- 拷貝jar包【關(guān)于數(shù)據(jù)庫,我們后面會單獨說】
- 運行jar包
? ? ? ? 看到這些步驟,我們就要回顧一下,鏡像是什么了?
? ? ? ? 鏡像就是包含了應(yīng)用程序、程序運行的系統(tǒng)函數(shù)庫、運行配置等文件的文件包。那我們構(gòu)建鏡像其實就是上述這些文件打包的過程~
? ? ? ? 到這里,就理解了,我們接下來,要構(gòu)建的鏡像就會包含以下幾個方面:
????????有一個Linux運行環(huán)境【鏡像自己內(nèi)部準(zhǔn)備一個運行環(huán)境,那就不用擔(dān)心系統(tǒng)不兼容等問題了】、有安裝jre并配置環(huán)境變量、有拷貝jar包、并將運行jar包設(shè)置為一個啟動腳本文件。這個文件糅合在一起,構(gòu)成了一個我們的java應(yīng)用鏡像~
那我們一起來看看,他到底是怎么去糅合在一起的呢:
? ? ? ? 因為我們搞一個什么運行環(huán)境,整一個系統(tǒng)函數(shù)庫【因為我們不知道這個項目需要依賴哪些系統(tǒng)函數(shù)庫,所以我們直接就把整個庫都搬過來】,這一堆文件;而我們整個jre,再去配置環(huán)境變量和配置也是一堆文件;jar包也是個文件;運行腳本還是一個文件。那docker呢,就將這些個文件都進(jìn)行分別壓縮,最后這些壓縮包合并在一起構(gòu)成最終的一個鏡像。因此鏡像其實就是由很多個壓縮包合并而成的,在Docker中,他們被稱為LER,也就是層的意思?!疚覀兤鋵嵲诶$R像的時候,也會看到,他會打印幾行日志,其實這一行就是對應(yīng)了一層~】
? ? ? ? 我們看圖理解:
Docker為什么要把這些文件分別分層打包呢?
- 可以實現(xiàn)某些層的共享
? ? ? ? 例如:我們大部分鏡像的第一層都是基礎(chǔ)鏡像【應(yīng)用依賴的系統(tǒng)函數(shù)庫、環(huán)境、配置、文件等】,我們上面說的是不知道要用哪些系統(tǒng)函數(shù)庫,所以我們?nèi)肯螺d下來。那如果說,有一個大佬,把JRE所依賴的網(wǎng)絡(luò)函數(shù)全部單獨挑出來了,那這樣的話,就可以大大的縮小鏡像的體積。這樣一來,就可以實現(xiàn)層的共享了~
- 提升本地下載鏡像的速度
? ? ? ? 我們在本地拉取鏡像時,按層一層一層拉取,如果說,第一個鏡像拉取下來后,拉取第二個鏡像時,他和第一層的某幾層相同,那我們是不是就可以直接跳過,不用拉取這個層了,直接使用你本地的這個就可以了。這樣一來,就可以提升本地下載鏡像的速度了~
2、如何手動自定義一個鏡像
? ? ? ? 通過上面的了解,我們在制作鏡像中,需要我們?nèi)ソo每一層打包,但我們真的這么操作的話,豈不是比以前部署項目還要復(fù)雜的多,就沒必要了~
? ? ? ? 所以Docker中,不需要我們手動去制作鏡像,我們只需要描述清楚我們的鏡像結(jié)構(gòu),描述清楚這個鏡像的入口是什么?中間有哪些層?基礎(chǔ)是什么? 描述清楚這些后,Docker就可以自動幫我們完成構(gòu)建鏡像這個操作了~
接下來,需要我們?nèi)チ私庖幌翫ockerfile,使用Dockerfile描述鏡像結(jié)構(gòu)~
2.1、Dockerfile
? ? ? ? Dockerfile就是一個文本文件,其中包含了一個個的指令,用指令來說明要執(zhí)行什么操作來構(gòu)建鏡像。如何來書寫這個文本文件呢?就需要借助他的相關(guān)指令了:
- FROM? :指定基礎(chǔ)鏡像——例如,我們這里的基礎(chǔ)鏡像就是centos:6 / 7? ,例:FROM CentOS:6
- ENV? :設(shè)置環(huán)境變量
- COPY:拷貝本地文件到鏡像的的指定目錄,例:COPY? ./jdk8.tar.gz? /tmp
- RUN? :執(zhí)行Linux的shell命令,一般就是安裝過程的命令,例:RUN? tar -axvf? /tmp/jdk8.tar.gz &&? EXPORTS path=/tmp/jdk8:$path
- EXPOSE:指定容器運行時監(jiān)聽的端口?,是給鏡像使用者看的 ,例: EXPOSE 8080
- ENTRYPOINT:鏡像中應(yīng)用的啟動命令,容器運行時調(diào)用,例:ENTRYPOINT java -jar xx.jar &
舉例該文本文件內(nèi)部到底如何下:
# 制定基礎(chǔ)鏡像
FROM centos:6
# 配置環(huán)境變量,JDK的安裝目錄,容器內(nèi)時區(qū)
ENV JAVA_DIR=/usr/local
# 拷貝jdk和java項目的包
COPY ./jdk8.tar.gz $JAVA_DIR/
COPY ./xx.jar /tmp/app.jar
# 安裝jdk
RUN cd $JAVA_DIR && tar -xf ./jdk8.tar.gz && mv ./jdk1.8.0_144 ./java8
# 配置環(huán)境變量
ENV JAVA_HOME=$JAVA_DIR/java8
ENV PATH=$PATH:$JAVA_HOME/bin
# 入口,java項目的啟動命令
ENTRYPOINT ["java","-jar","/app.jar"]
說明:
????????這個文件寫完后,等我們下次再要制作新的java項目的鏡像時,需要更改的內(nèi)容有哪些呢:
????????我們需要修改的,可能就只有這個待拷貝的java的jar包不同,那我們是不是可以對這個文本文件再優(yōu)化~
2.2、dockerfile文本文件中,最終要寫什么?
? ? ? ? 上述我們已經(jīng)看到了,文本文件內(nèi)大致要寫的內(nèi)容,我們現(xiàn)在要做的是,可不可以繼續(xù)優(yōu)化一下:
? ? ? ? 我們提到,文本文件中,每次要修改的只有拷貝jar包時,命令要稍微改一下,那思考一下,前面我們把基礎(chǔ)鏡像從拷貝全部的系統(tǒng)庫函數(shù)到寫一個鏡像,只把我們要使用的庫提出來,那在這里我們也可以這樣做,我們把上述的基礎(chǔ)鏡像、拷j(luò)dk包、安裝jdk,配置環(huán)境變量等操作,也可以做成一個鏡像,供我們后續(xù)使用,例如已經(jīng)有人做好的:
# 基礎(chǔ)鏡像
FROM openjdk:11.0-jre-buster
# 拷貝jar包
COPY xx.jar /app.jar
# 入口
ENTRYPOINT ["java","-jar","/app.jar","&"]
說明:
2.3、構(gòu)建鏡像
? ? ? ? 當(dāng)我們編寫好Dockerfile后,使用如下命令,來構(gòu)建鏡像,例如:
docker build -t myImage:1.0 .
說明:
- docker build -t 后面跟你給這個鏡像氣的名字,冒號后面為版本,不寫的話,默認(rèn)為最新版
- 后面的一個 .? 指的是dockerfile所在的目錄,當(dāng)前目錄就為 .?
3、案例:部署java項目
? ? ? ? ?首先,我們創(chuàng)建一個目錄,為構(gòu)建鏡像做準(zhǔn)備,任意命名,例如我的:
?一定要進(jìn)到這個目錄中來~
? ? ? ? 然后,把你的java項目的jar扔到這個目錄來:
然后創(chuàng)建一個文件,名為:Dockerfile:
?打開文件,填寫內(nèi)容:
?保存后,執(zhí)行命令:docker build -t 鏡像名【自定義】:
有了鏡像,我們就去創(chuàng)建運行容器了:
然后,你的項目就可以正常與運行了~
? ? ? ? 但是,項目雖然部署好了,我們?nèi)Q部署也沒有提到數(shù)據(jù)庫MySQL呀,那我的項目就是要用到MySQL的呀。我們前面已經(jīng)運行的有mysql容器了是不是【沒有的伙伴,可以看:】所以,下面我們需要繼續(xù)學(xué)習(xí),可以把我們讓我們的容器與容器之間相互訪問:
4、如何與其他容器相互訪問,例如:java項目鏡像創(chuàng)建的容器與mysql容器相互訪問
? ? ? ? 在這里,就需要我們學(xué)習(xí)另一個知識點:網(wǎng)絡(luò)~
4.1、使用默認(rèn)的網(wǎng)絡(luò)?
? ? ? ? 我們在安裝docker時,docker就創(chuàng)建一張?zhí)摂M的網(wǎng)卡,默認(rèn)名字為docker0,并且會給這個虛擬的網(wǎng)卡創(chuàng)建一個虛擬的網(wǎng)橋,在我們不指定的情況下,我們創(chuàng)建的容器都會與默認(rèn)的網(wǎng)卡建立連接,如下:
例如我們查看一下,我們之前的容器mysql和Nginx:
查看容器信息,輸入命令:docker inspect 容器名
mysql:
Nginx:
? ? ? ? 我們會看到,他倆的網(wǎng)關(guān)都是默認(rèn)的127.17.0.1 ; 那是不是說明,他倆就可以相互訪問了呢?例,進(jìn)入我們剛才部署的java項目的這個容器】:
? ? ? ? 一定要是進(jìn)入我們創(chuàng)建的項目的容器內(nèi),進(jìn)行ping操作,因為mysql容器和Nginx容器中,都沒有提供ping的這個操作,安裝的話,會比較麻煩~
? ? ? ? 這個時候,有伙伴們就會說,那我們就不需要配置了唄,只要在我自己的項目中訪問數(shù)據(jù)庫的配置信息修改一下不就好了嗎?
? ? ? ? 例如:
改好后,重新部署一下不就好了嗎?
? ? ? ? ?不!不好?。?!? 為什么呢?我們想想,當(dāng)我們把mysql容器停掉后,重啟;或者是我們把鏡像推給別人~想一想這兩種情況能夠保證mysql容器每次的ip都一樣嗎?那不一樣,不就會報錯了嗎?
? ? ? ? 大家可能會說,可以把ip用容器名替代嗎?他可以通過容器名解析到這個ip嗎?
? ? ? ? 回答是:可以但不完全可以。詳細(xì)的說,就是默認(rèn)的這個網(wǎng)卡是不可以的,但是如果我們不使用默認(rèn)的網(wǎng)卡,我們自己去創(chuàng)建一個網(wǎng)絡(luò),把這些容器加入到這個新的網(wǎng)絡(luò)中是可以做到的。例如,我們現(xiàn)在在默認(rèn)網(wǎng)卡中試試:
? ? ? ? 對吧?這是做不到的,所以我們又要學(xué)習(xí)新的知識,網(wǎng)絡(luò)相關(guān)的:?
4.1、網(wǎng)絡(luò)相關(guān)命令
- docker network create : 創(chuàng)建一個網(wǎng)絡(luò)
- docker network ls : 查看所有網(wǎng)絡(luò)
- docker network rm : 刪除指定網(wǎng)絡(luò)
- docker network prune :清楚未使用的網(wǎng)絡(luò)
- docker network connect :使指定容器連接加入某網(wǎng)絡(luò)
- docker network disconnect:使指定容器連接離開某網(wǎng)絡(luò)
- docker network inspect :查看網(wǎng)絡(luò)詳細(xì)信息
4.3、創(chuàng)建新的網(wǎng)絡(luò)?
先查看我們原本有哪些網(wǎng)絡(luò):
創(chuàng)建一個網(wǎng)絡(luò):
使mysql容器加入該網(wǎng)絡(luò):
????????我們可以看到這個mysql容器,先是創(chuàng)建容器時就自動加入了默認(rèn)網(wǎng)絡(luò)中,然后也加入了剛才我們指定的網(wǎng)絡(luò)中,在這個網(wǎng)絡(luò)中,這個網(wǎng)絡(luò)的網(wǎng)關(guān)是172.18.0.1,這個容器在這個網(wǎng)絡(luò)中的ip為172.18.0.2
如果說我們的java項目的容器不想讓他加入默認(rèn)的網(wǎng)絡(luò)中呢?那需要我們把之前的啟動的項目容器刪掉,然后重新創(chuàng)建容器,在創(chuàng)建容器時就需要指定他所在的網(wǎng)絡(luò):
? ? ? ? 此時,我們再來查看這個容器的信息:
就只一個這一個了~
此時,兩個容器就可以一起相互訪問了~ 可通過容器名,來直接訪問,如下:
這時呢,我們只需要把項目的配置文件改一下:
好啦,我們重新打包上傳的操作就不演示啦~文章來源:http://www.zghlxwxcb.cn/news/detail-767275.html
本期就結(jié)束啦!!下期見~?文章來源地址http://www.zghlxwxcb.cn/news/detail-767275.html
到了這里,關(guān)于Docker——如何自定義鏡像【將自己的項目制作成鏡像】?的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!