docker是什么:
docker是 Linux 容器的一種封裝,提供了簡(jiǎn)單易用的容器使用接口。
容器和虛擬機(jī)的區(qū)別:

docker三要素:
鏡像
docker 鏡像可以看作是一個(gè)特殊的文件系統(tǒng),除了提供容器運(yùn)行時(shí)所需的程序、庫(kù)、資源、配置等文件外,還包含了一些為運(yùn)行時(shí)準(zhǔn)備的一些配置參數(shù)(如匿名卷、環(huán)境變量、用戶等)。
鏡像是分層的,每層鏡像都有一個(gè)指向下層鏡像的指針,所有鏡像組合在一起統(tǒng)一對(duì)外提供服務(wù)。
個(gè)人理解: 鏡像相當(dāng)于OS上的一個(gè)軟件。系統(tǒng)鏡像、組件鏡像、服務(wù)鏡像 組合在一起提供一個(gè)定制化的只有指定服務(wù)和服務(wù)依賴的服務(wù)系統(tǒng)。
容器
容器 = 鏡像 + 讀寫(xiě)層。
個(gè)人理解:容器是運(yùn)行起來(lái)的鏡像,提供了服務(wù)的輸入和產(chǎn)出
倉(cāng)庫(kù):
倉(cāng)庫(kù)是鏡像文件存儲(chǔ)的地方,類似git。分共有倉(cāng)庫(kù)、私有倉(cāng)庫(kù)和本地倉(cāng)庫(kù)
公有倉(cāng)庫(kù):相當(dāng)于github,最大的公有倉(cāng)庫(kù): Docker Hub。
私有倉(cāng)庫(kù):相當(dāng)于gitlab
本地倉(cāng)庫(kù):搭建本地Docker Registry
為什么要用docker
一次構(gòu)建,到處安裝
普通服務(wù)的部署,在需要遷移或者部署多份時(shí)都需要從頭搭建一次服務(wù)依賴環(huán)境,這可能需要耗費(fèi)運(yùn)維人員大量的時(shí)間。docker把服務(wù)及相關(guān)依賴封裝到一個(gè)包中,部署時(shí)只需要依賴docker服務(wù)器即可,一份docker鏡像可以在不同的環(huán)境中同時(shí)部署不需要除docker外的底層環(huán)境的依賴。
服務(wù)隔離
docker能夠隔離服務(wù)之間對(duì)于環(huán)境的依賴,普通服務(wù)部署多個(gè)服務(wù)可能同時(shí)依賴同一個(gè)組件,在部分服務(wù)的依賴組件需要升級(jí)時(shí),可能會(huì)影響到別的服務(wù)的運(yùn)行。使用docker部署后,各個(gè)服務(wù)之間的依賴都是單獨(dú)的,升級(jí)時(shí)只需要對(duì)當(dāng)前服務(wù)的底層依賴升級(jí)即可。
當(dāng)然, docker的好處遠(yuǎn)不止這些。我們會(huì)在使用中發(fā)現(xiàn)docker帶給我們的更多便利。
docker怎么用
編寫(xiě)Dockerfile
參考鏈接:
https://www.cnblogs.com/panwenbin-logs/p/8007348.html
這里只列出我用到的命令,更多命令可以點(diǎn)擊鏈接或者查看相關(guān)資料了解
FROM 指定基礎(chǔ)鏡像,必須為第一條命令
FROM <image>
FROM <image>:<tag>
FROM <image>@<digest>
COPY、ADD 復(fù)制本地文件到鏡像中
ADD <src>... <dest>
ADD ["<src>",... "<dest>"] 用于支持包含空格的路徑
ENV 設(shè)置鏡像環(huán)境變量
ENV <key> <value> #<key>之后的所有內(nèi)容均會(huì)被視為其<value>的組成部分,因此,一次只能設(shè)置一個(gè)變量
ENV <key>=<value> ... #可以設(shè)置多個(gè)變量,每個(gè)變量為一個(gè)"<key>=<value>"的鍵值對(duì),如果<key>中包含空格,可以使用\來(lái)進(jìn)行轉(zhuǎn)義,也可以通過(guò)""來(lái)進(jìn)行標(biāo)示;另外,反斜線也可以用于續(xù)行
CMD 設(shè)置鏡像要執(zhí)行的命令
CMD ["executable","param1","param2"] (執(zhí)行可執(zhí)行文件,優(yōu)先)
CMD ["param1","param2"] (設(shè)置了ENTRYPOINT,則直接調(diào)用ENTRYPOINT添加參數(shù))
CMD command param1 param2 (執(zhí)行shell內(nèi)部命令)
我的第一個(gè)Dockerfile文件
FROM centos:7.4
RUN yum install -y golang
COPY 我的服務(wù)二進(jìn)制文件 /
COPY 我的服務(wù)配置文件 /
ENV TZ Asia/Shanghai
CMD ["/服務(wù)可執(zhí)行文件","指定服務(wù)執(zhí)行所需的參數(shù)"]
構(gòu)建服務(wù)鏡像
docker build -t 服務(wù)名稱:版本號(hào) .
啟動(dòng)服務(wù)
docker run -d --net=host 服務(wù)名稱:版本號(hào)
#-net=host指定容器使用宿主機(jī)IP
#-p 指定容器使用端口映射到主機(jī)相應(yīng)端口
問(wèn)題
這樣我每次更新服務(wù)都需要重git上拉取最近代碼,然后編譯成二進(jìn)制文件,再?gòu)?fù)制到docker目錄下構(gòu)建docker影響,最后在查詢當(dāng)前容器ID,停到當(dāng)前容器的運(yùn)行后再部署新的容器,仍舊是個(gè)很麻煩的流程,并沒(méi)有給我的上線流程減輕負(fù)擔(dān)。并且舊的容器及鏡像還需要在清除。
優(yōu)化
編寫(xiě)一個(gè)上線腳本,把所有的相關(guān)操作都集成到一個(gè)shell腳本中,每次git上代碼更新時(shí)只需要執(zhí)行一次腳本就OK了
cd 文件原路徑
git pull
go build
mv s服務(wù)可執(zhí)行文件 docker目錄下
cd docker目錄
sudo docker ps -a | grep 服務(wù)名 | awk '{printf $1 "\t"}'| xargs sudo docker kill | xargs sudo docker rm #停用舊容器,并刪除容器
sudo docker images | grep 服務(wù)名 | awk '{printf $3 "\t"}'| xargs sudo docker rmi #刪除舊鏡像
sudo docker build -t 服務(wù)名:$1 .
sudo docker run -d --net=host 服務(wù)名:$1
執(zhí)行腳本 帶上最新版本號(hào)作為參數(shù)
以上,成功把服務(wù)遷移到docker上部署,并且每次上線只需要一條命令即可。服務(wù)升級(jí)時(shí)也只需要修改Dockerfile文件即可。