Docker

docker簡(jiǎn)介:

物理機(jī)(平常使用的電腦)是一棟樓,虛擬機(jī)(vmware)就是一個(gè)套間,docker是套間里面的隔斷。

?

一臺(tái)虛擬機(jī)在物理機(jī)里體現(xiàn)為一個(gè)進(jìn)程,docker對(duì)于虛擬機(jī)來(lái)說(shuō)也是一個(gè)進(jìn)程,進(jìn)程和進(jìn)程是沒(méi)有聯(lián)系的,即每個(gè)docker容器都是獨(dú)立的,互不影響。

虛擬機(jī)和docker的區(qū)別

虛擬機(jī)起到隔離運(yùn)行環(huán)境的作用,占用的資源較大

docker起到隔離應(yīng)用程序的作用,占用的資源較小

docker里面運(yùn)行的是鏡像(自帶操作系統(tǒng)),也就是說(shuō)實(shí)際應(yīng)用中需要用到多臺(tái)電腦的時(shí)候,可以使用docker來(lái)代替多臺(tái)電腦,從而在一臺(tái)電腦中運(yùn)行多個(gè)程序或虛擬機(jī)。

docker的版本:

  • docker-ce 社區(qū)版(一些程序員在維護(hù),免費(fèi)的)
    • stable版
      • 穩(wěn)定版,一個(gè)季度更新一次
    • edge版
      • 非穩(wěn)定版,一個(gè)月更新一次
  • docker-ee 企業(yè)版(收費(fèi)的)

docker組成

示意圖
1555225471244.png

客戶端:就是一個(gè)終端,由很多指令組成,類似于xshell5來(lái)操作linux,xshell5就是一個(gè)linux的終端(客戶端)

服務(wù)器:docker服務(wù)器是一個(gè)守護(hù)進(jìn)程,沒(méi)有操作終端,主要是管理docker容器和docker鏡像。所謂守護(hù)進(jìn)程,就是不能喝用戶進(jìn)行交互(輸入和輸出),在后臺(tái)周期性的執(zhí)行某些操作,類似于apache服務(wù)器,不能用戶進(jìn)行交互,在后臺(tái)默默的輔助解析PHP代碼。

docker容器:通過(guò)docker操作命令可以啟動(dòng)磁盤(pán)上的鏡像啟動(dòng),啟動(dòng)之后就是docker容器,容器中運(yùn)行的是一個(gè)操作系統(tǒng)。即,運(yùn)行操作系統(tǒng)的媒介或容器。

docker鏡像:所謂鏡像就是一些系統(tǒng)磁盤(pán)文件,如vmware.vm等文件。用戶可以自己制作也可以在官網(wǎng)下載。nginx鏡像,意思是有一個(gè)操作系統(tǒng),里面安裝了nginx;redis鏡像,意思是有一個(gè)操作系統(tǒng),里面安裝了redis;ubuntu鏡像,意思是純凈的ubuntu操作系統(tǒng)。

鏡像倉(cāng)庫(kù):docker hub 是官方提供的鏡像倉(cāng)庫(kù)。

docker的安裝和卸載

安裝命令:

# 1.更新軟件列表
sudo apt-get update #不會(huì)更新軟件,是更新本地系統(tǒng)中自帶的軟件列表,可以讓下載的時(shí)候下載到最新的軟件版本
# 2.安裝一些小工具
sudo apt-get install apt-transport-https ca-certificates curl software-properties-commonlrzsz -y # 為后面的安裝座準(zhǔn)備,-y的意思是碰到提示輸入yes或no的時(shí)候默認(rèn)選擇yes
# 3.下載阿里云的公鑰,通過(guò)管道將秘鑰添加到本地受信任的數(shù)據(jù)庫(kù)(trusted)中
sudo curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/gpg | sudo apt-key add - # curl是一個(gè)下載工具
# 4.添加阿里云的docke軟件包到apt倉(cāng)庫(kù)
sudo add-apt-respository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -ce) stable"
# 5.將阿里云的軟件源升級(jí)到最新版本
sudo apt-get update 
# 6.安裝docker
sudo apt-get install docker docker-ce -y
# 7.測(cè)試docker
docker version 

docker加速器設(shè)置:

目的:

? docker安裝成功以后,啟動(dòng)docker需要鏡像,鏡像需要從官方下載,配置加速器九尾了提高下載鏡像的速度

# 1.訪問(wèn)https://dashboard.daocloud.io網(wǎng)站,登錄進(jìn)去,點(diǎn)擊右上角的“小火箭”圖標(biāo),復(fù)制“配置docker加速器”中的linux命令,在中斷中執(zhí)行該命令即可,不同的用戶登錄會(huì)有不同的網(wǎng)址,但是都可以用
curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io 
# 這個(gè)命令會(huì)在/etc/docker目錄下生成daemon.json文件,寫(xiě)入執(zhí)行成功的提示命令{"registy-mirrors":["http://f1361db2.m.daocloud.io"]}
# 2.重啟docker服務(wù)
sudo systemctl restart docker

docker的權(quán)限問(wèn)題:

當(dāng)安裝好docker執(zhí)行docker version命令,效果如下:

Client:
 Version:           18.09.2
 API version:       1.39
 Go version:        go1.10.6
 Git commit:        6247962
 Built:             Sun Feb 10 04:13:47 2019
 OS/Arch:           linux/amd64
 Experimental:      false
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.39/version: dial unix /var/run/docker.sock: connect: permission denied

最后的提示是說(shuō)權(quán)限不夠,解決方案:

# 方案1:每次執(zhí)行命令使用sudo
sudo docker version
# 方案2:將當(dāng)前用戶添加到docker組中,設(shè)置一次就好了(但重啟電腦還不行)
    # 使用命令:sudo gpasswd -a 當(dāng)前用戶 組名
sudo gpasswd -a itcast docker
    # 這個(gè)時(shí)候如果還不行的話,再進(jìn)行組的切換(因?yàn)楫?dāng)前用戶默認(rèn)不在docker組,所以現(xiàn)在執(zhí)行命令雖然也是當(dāng)前用戶,但不屬于docker組的操作,所以要進(jìn)行組的切換),使用命令:newgrp - 組名
newgrp - docker # 如果下次重啟,還沒(méi)權(quán)限的話,只需要切換組即可
# 方案3:修改docker文件的權(quán)限。文件:/ver/run/docker.sock
sudo chmod 666 docker.sock # 這個(gè)命令只需要設(shè)置一次即可

docker服務(wù)器操作相關(guān)指令:

# 重啟命令
sudo systemctl restart docker
# 啟動(dòng)命令
sudo systemctl start docker
# 關(guān)閉命令
sudo systemctl stop docker
# 查看狀態(tài)
sudo systemctl status docker

卸載命令:

# 1.卸載軟件
sudo apt-get purge docker-ce #刪除對(duì)應(yīng)的信息文件+應(yīng)用程序,如刪除人和人的信息,包括姓名,衣服,身份證
# 或者
sudo apt-get remove docker-ce # 只刪除應(yīng)用程序,但是信息還在
# 2.刪除兩個(gè)目錄,一個(gè)是身份認(rèn)證目錄 /etc/docker,另一個(gè)是存儲(chǔ)鏡像的目錄 /var/lib/docker
sudo rm /etc/docker /var/lib/docker

docker鏡像管理

查看docker中的所有指令:

docker --help

鏡像的搜索:

操作鏡像需要知道這個(gè)鏡像是否存在,也就是需要搜索一下

注意:搜索范圍是在docker hub,也就是官方的倉(cāng)庫(kù)中搜索

# 使用命令:docker search 鏡像名   例:
docker search ubuntu

會(huì)搜索很多結(jié)果出來(lái),其中有些是官方的,有些是自己制作好上傳的,具體結(jié)果字段如下:

NAME:鏡像的名稱
DESCRIPTION:鏡像的描述
STARS:鏡像的下載量
OFFICIAL:是否為官方出品的鏡像
AUTOMATED:會(huì)不會(huì)啟動(dòng)一些腳本之類的程序

鏡像的下載:

# 下載指令:docker pull 鏡像名       例:
docker pull ubuntu

下載成功后,會(huì)存儲(chǔ)到本地的鏡像倉(cāng)庫(kù),對(duì)應(yīng)一個(gè)本地目錄:/var/lib/docker,這個(gè)目錄需要root用戶才能進(jìn)去查看,可以使用命令切換到root用戶su - root,使用這個(gè)命令切換的root用戶,連環(huán)境變量也切換到了root用戶,如果不加-那代表雖然用戶切換到了root,但使用環(huán)境變量還是普通用戶的

該目錄中有很多文件夾,下載好的鏡像不是一個(gè)文件,而是由很多小文件組成的,所以是找不到單獨(dú)的某個(gè)鏡像文件的,所以在后期需要?jiǎng)h除這個(gè)鏡像的話,就將這個(gè)目錄刪掉就好了。

鏡像的查看:

# 查看所有的鏡像
docker images
# 或
docker image ls

# 查看某一個(gè)鏡像
docker image ls 鏡像名
# 或
docker images 鏡像名

查看的結(jié)果中包含很多字段,如下:

REPOSITORY:鏡像名稱
TAG:鏡像的版本(latest代表最新版本)
IMAGE ID:鏡像id(類似于身份證,是唯一的)
CREATED:創(chuàng)建時(shí)間
SIZe:鏡像的大小

通常在描述一個(gè)鏡像的時(shí)候,描述方式如下:

語(yǔ)法:
    鏡像名:tag    
例:
    nginx:latest
# 如果tag的值為latest,那么latest可以省略不寫(xiě),例: nginx == nginx:latest

給docker起別名:

語(yǔ)法:
    docker tag 鏡像名:tag 別名:tag的別名
例:
    docker tag ubuntu:latest uuuu:v1.0
# 這里的別名和tag的別名都可以自定義

當(dāng)再次查看的時(shí)候,會(huì)發(fā)現(xiàn)列表中多了一個(gè)鏡像,這個(gè)鏡像是多出來(lái)的一個(gè)名字不是復(fù)制了一個(gè)新的鏡像。

刪除鏡像:

語(yǔ)法:
    docker rmi 鏡像id/鏡像名
# 如果鏡像有別名,就不能用鏡像id進(jìn)行刪除,因?yàn)殓R像id不是唯一的,只能使用鏡像名來(lái)刪除,且tag不是latest的話,也必須加上tag,而且刪除的只是一個(gè)名字,鏡像還在的,只是廢棄了一個(gè)名字,如果用鏡像名刪除不了的話,可以在后面加一個(gè)參數(shù)  -f   表示強(qiáng)制刪除

鏡像的導(dǎo)入導(dǎo)出

由于鏡像在使用過(guò)程中難免會(huì)發(fā)生誤刪的情況,所以鏡像需要備份。目的是鏡像文件的備份和分發(fā)(備份以后傳送給別人進(jìn)行導(dǎo)入使用)。

導(dǎo)出的本質(zhì)就是將本地倉(cāng)庫(kù)中的鏡像備份到本地磁盤(pán)中。導(dǎo)入的本質(zhì)就是將本地磁盤(pán)中保存的鏡像放到本地倉(cāng)庫(kù)中。

導(dǎo)出:

導(dǎo)出命令:
    docker save -o 目標(biāo)路徑(帶名字) 要導(dǎo)出的鏡像名帶tag
或
    docker save --output 目標(biāo)路徑(帶名字) 要導(dǎo)出的鏡像名帶tag
例:
    docker save -o /home/itcast/docker-test/ubuntu.img uuuu:v1.0
或
    docker save --output /home/itcast/docker-test/ubuntu.img uuuu:v1.0
# 這時(shí)候在目標(biāo)文件夾中就能看到導(dǎo)出的文件了(文件名是自定義的),這個(gè)單獨(dú)的文件就是整個(gè)鏡像文件

導(dǎo)入:

導(dǎo)入命令:
    docker load -i 鏡像文件路徑
或
    docker load --input 鏡像文件路徑
# 如果這個(gè)鏡像本身就存在的話,該命令不會(huì)進(jìn)行任何操作
還有另外一種命令:
    docker load < 鏡像文件路徑

查看鏡像的歷史記錄

命令:
    docker history 鏡像名:tag
# 查看的是鏡像制作過(guò)程中一些比較重要的步驟

查看鏡像的詳細(xì)信息

命令:
    docker inspect 鏡像名/鏡像id
# 查看的是鏡像的屬性信息(id,大小,名稱等),結(jié)果以json格式輸出

這個(gè)命令還可以查看網(wǎng)絡(luò)等信息,參考地址:https://yq.aliyun.com/articles/230067

鏡像管理總結(jié):

示意圖
1555249738442.png

docker容器管理

容器是基于鏡像的,鏡像(鏡像可看做可執(zhí)行程序)啟動(dòng)之后,就變成了容器。鏡像啟動(dòng)之前只占用磁盤(pán)空間,當(dāng)鏡像啟動(dòng)之后會(huì)占用內(nèi)存、CPU等資源。

每個(gè)容器啟動(dòng)之后,都是一個(gè)進(jìn)程。

查看容器

命令:
    docker ps
# 因?yàn)槿萜鲉?dòng)后是進(jìn)程,所以查看容器和查看進(jìn)程的指令類似。
命令后面的參數(shù):
    docker ps -a/--all # 顯示所有的容器,默認(rèn)只顯示running狀態(tài)的
    docker ps -q/--quiet # 直線容器的id

查看結(jié)果會(huì)有很多字段,如下:

CONTAINER ID:容器啟動(dòng)之后的id,是唯一的
IMAGE:當(dāng)前容器是基于哪個(gè)鏡像啟動(dòng)的
COMMAND:容器啟動(dòng)之后,默認(rèn)執(zhí)行了什么命令
CREATED:容器的創(chuàng)建時(shí)間
STATUS:容器當(dāng)前的狀態(tài)
    created:容器被創(chuàng)建,但是不能使用的狀態(tài)
    running:運(yùn)行的狀態(tài)
    pause:暫停的狀態(tài)
    exited:容器終止運(yùn)行,但是容器還在的狀態(tài)
PORTS:映射的端口,主機(jī)和容器直接的端口映射
NAMES:容器啟動(dòng)之后的名字,如果沒(méi)有指定,會(huì)隨機(jī)生成一個(gè),這個(gè)不能重復(fù)(是唯一的)

創(chuàng)建容器:

命令:
    docker create -it [--rm] --name 容器名 鏡像名:tag commad(執(zhí)行的命令)
# 其中-i參數(shù),也可以是--interactive,表示給容器關(guān)聯(lián)標(biāo)準(zhǔn)輸入,-t參數(shù),也可以是--tty,表示給容器綁定終端,這個(gè)位置還可以有-a/--attach list參數(shù),表示給容器關(guān)聯(lián)標(biāo)準(zhǔn)輸入輸出或錯(cuò)誤,--rm參數(shù)表示容器終止運(yùn)行的時(shí)候自動(dòng)刪除這個(gè)容器,--name參數(shù)表示手動(dòng)指定容器的名字(不指定容器名會(huì)自動(dòng)生成一個(gè)),command可以不寫(xiě),如果必須的寫(xiě)的話,就寫(xiě)bash,所謂bash,就是一個(gè)shell命令解析器,沒(méi)有實(shí)際意義
例:
    docker create -it --name myubuntu --rm uuuu:v1.0 bash

啟動(dòng)已創(chuàng)建好的容器:

命令:
    docker start -ia 容器名/容器id
例:
    docker start -ia myubuntu

這時(shí)候,操作的用戶會(huì)發(fā)生改變,因?yàn)閱?dòng)容器加了參數(shù)后,會(huì)進(jìn)入到容器內(nèi)部,而容器就是一個(gè)微型操作系統(tǒng),這時(shí)候輸入exit可以退出容器

啟動(dòng)容器可以不加參數(shù),就不會(huì)進(jìn)入到容器內(nèi)部,容器正在運(yùn)行的狀態(tài)會(huì)顯示up狀態(tài)

容器創(chuàng)建并啟動(dòng):

命令:
    docker run -aitd --name 容器名 鏡像名:tag command
# 參數(shù)意義和用法與docker create一樣,多的-d/--detach參數(shù)意思是以守護(hù)進(jìn)程的形式運(yùn)行(在后臺(tái)運(yùn)行),并在啟動(dòng)成功以后打印一個(gè)容器的id,加了-d參數(shù)后不會(huì)進(jìn)入到容器內(nèi)部了
例:
    docker run -itd --name newubun uuuu:v1.0 bash

這時(shí)候查看容器的話,可以看到這個(gè)容器已經(jīng)創(chuàng)建好并在運(yùn)行了,狀態(tài)是up(正在運(yùn)行)

暫停容器:

命令:
    docker pause 容器名/容器id
例:
    docker pause newubun

再次查看容器的時(shí)候,在正在運(yùn)行的容器狀態(tài)up后面會(huì)有一個(gè)(Paused),表示這個(gè)容器暫停運(yùn)行了,這個(gè)命令可以同時(shí)操作多個(gè)容器,多個(gè)容器名之間使用空格隔開(kāi)

恢復(fù)容器:

命令:
    docker unpause 容器名/容器id
例:
    docker unpause newubun

容器重啟:

命令:
    docker restart -t 容器名/容器id
# -t,--time int:延時(shí)時(shí)間,默認(rèn)是10s
例:
    docker restart -t 5 newubun # 表示容器在5秒鐘之后重啟

關(guān)閉和終止容器:

關(guān)閉容器和終止容器都沒(méi)有刪除容器,只是讓容器從up狀態(tài)到了exited狀態(tài),關(guān)閉容器有延時(shí),終止容器沒(méi)有延時(shí)

關(guān)閉命令:
    docker stop [-t] 容器名/容器id
# -t,--time int:延時(shí)時(shí)間,默認(rèn)為10s
終止命令:
    docker kill [-s] 容器名/容器id
# -s.--signal string:指定發(fā)出的信號(hào),默認(rèn)為kill(linux默認(rèn)有64個(gè)信號(hào),實(shí)際有62個(gè),sigkill為9號(hào)信號(hào)(使用kill -l命令可以進(jìn)行查看所有信號(hào)),不能被攔截,只會(huì)有一個(gè)結(jié)果,就是kill),一般不用
例:
    docker stop -t 5 newubun # 表示容器在5s之后關(guān)閉,容器從up狀態(tài)變成了exited狀態(tài)
    docker kill newubun # 結(jié)果同樣是容器關(guān)閉

容器的刪除:

? 刪除未運(yùn)行的容器:

命令:
    docker rm 容器名/容器id

? 刪除運(yùn)行的容器:

命令:
    docker rm -f 容器名/容器id
# -f參數(shù)表示強(qiáng)制刪除,也可以加在命令的最末尾

? 批量刪除容器:

命令:
    docker rm `docker ps -aq` -f
或
    docker rm $(docker ps -aq) -f

進(jìn)入容器中:

創(chuàng)建并啟動(dòng)并進(jìn)入容器

命令:
    docker run -it [--name 容器名] 鏡像名:tag [command] 

進(jìn)入已創(chuàng)建但未啟動(dòng)的容器:

命令:
    docker start -ia 容器名/容器id

進(jìn)入已啟動(dòng)的容器:

命令:
    docker exec -it 容器名/容器id command
# -i,--interactive:表示給容器關(guān)聯(lián)標(biāo)準(zhǔn)輸入
# -t,--tty:表示給容器綁定終端
# 命令的最后面的command是不能被省略的
# command:shell指令,一般就是用bash
例:
    docker exec -it 456b55bb7850 bash # 進(jìn)入到容器內(nèi)部,-it兩個(gè)參數(shù)必不可少,且command必須是bash

退出容器:

退出容器,不會(huì)影響容器的運(yùn)行

# 方式1:
    exit
# 方式2:
    ctrl+D

容器的其他命令:

? 小知識(shí):我們平??吹降淖泳W(wǎng)掩碼為:255.255.255.0,這個(gè)代表24位,因?yàn)閕p地址是32的,四個(gè)整數(shù),每個(gè)代表8位,其中3個(gè)有值,那就24位,如果說(shuō)子網(wǎng)掩碼為16位,那這個(gè)子網(wǎng)掩碼就是255.255.0.0

? 查看容器日志:

命令:
    docker logs 容器名/容器id

? 查看容器的詳細(xì)信息(屬性):

命令:
    docker inspect 容器名/容器id
# 參考網(wǎng)址: https://yq.aliyun.com/articles/230067

? 查看容器的端口信息:

命令:
    docker port 容器名/容器id
# 查看的是主機(jī)和容器的端口映射

容器重命名:

命令:
    docker rename 容器名/容器id 新的容器名
例:
    docker rename newubun myu

基于容器的進(jìn)行導(dǎo)出:

命令:
    # 方式1
    docker export -o 鏡像文件名 容器名/容器id
    # 方式2
    docker export 容器名/容器id > 鏡像文件名
例:
    docker export -o ~/docker-test/myub.img myu # 將容器中的鏡像導(dǎo)入到了本地文件

鏡像的導(dǎo)入:

鏡像的導(dǎo)入本質(zhì)是將本地的鏡像文件導(dǎo)入到本地的鏡像倉(cāng)庫(kù)

命令:
    cat 鏡像文件 | docker import - 新的鏡像名:tag
例:
    cat myub.img | docker import - ub:1

導(dǎo)入使用的docker import命令,但是在使用的時(shí)候,docker import 需要接收數(shù)據(jù)(數(shù)據(jù)來(lái)源于文件或者url),所以需要使用cat配合管道使用

鏡像導(dǎo)出的對(duì)比:

save export
導(dǎo)出方式 通過(guò)鏡像導(dǎo)出 通過(guò)容器導(dǎo)出
是否可以修改 不能對(duì)鏡像進(jìn)行修改 原始鏡像可以通過(guò)啟動(dòng)的容器進(jìn)行修改
是否丟失數(shù)據(jù) 不會(huì)丟失 若沒(méi)有通過(guò)容器對(duì)進(jìn)行修改直接導(dǎo)出,會(huì)丟失鏡像的歷史記錄
大小 和原始鏡像一樣 會(huì)比原始鏡像小(丟失了歷史記錄)

鏡像導(dǎo)入的對(duì)比:

load import
是否可以修改鏡像名 無(wú)法修改 可以修改

docker命令總結(jié):

示意圖
1555477156230.png

數(shù)據(jù)卷

容器和宿主機(jī)之間的數(shù)據(jù)拷貝:

宿主機(jī)拷貝到容器:
    docker cp 宿主機(jī)的文件路徑 容器名:容器中的文件路徑
例:
    docker cp ./a.txt myu:/b.txt 
    # 將當(dāng)前目錄下的a.txt文件拷貝到容器中的根目錄下,并改名為b.txt,也可以不改名,即目標(biāo)之路經(jīng)中不寫(xiě)文件名
容器拷貝到宿主機(jī):
    docker cp 容器:容器中的文件路徑 宿主機(jī)的文件路徑
例:
    docker cp myu:/b.txt ./c.html 
    # 將容器中的根目錄下的b.txt拷貝到當(dāng)前目錄下,并改名為c.html,也可以不改名,即目標(biāo)之路經(jīng)中不寫(xiě)文件名

數(shù)據(jù)卷和使用:

所謂數(shù)據(jù)卷,就是在創(chuàng)建或啟動(dòng)容器的時(shí)候,讓容器中的某個(gè)目錄或文件掛載到宿主機(jī)上的某個(gè)目錄或文件,讓宿主機(jī)和容器之間形成一種數(shù)據(jù)的映射關(guān)系,從而達(dá)到宿主機(jī)和容器之間數(shù)據(jù)共享的目的。

掛載命令:
    # 創(chuàng)建并啟動(dòng)容器的時(shí)候進(jìn)行掛載
    docker run -itd --name 容器名 -v 宿主機(jī)路徑:容器路徑:ro 鏡像名:tag command
    # 創(chuàng)建容器的時(shí)候掛載
    docker create -it --name 容器名 -v 宿主機(jī)路徑:容器路徑:ro 鏡像名:tag command
# -v,--volume list:list就是路徑的意思;ro是容器對(duì)于掛載目錄是只讀的權(quán)限,可以不寫(xiě),默認(rèn)為讀寫(xiě)權(quán)限;宿主機(jī)路徑必須是絕對(duì)路徑,否則會(huì)映射失敗,但不會(huì)報(bào)錯(cuò);容器路徑可以隨便定義,不存在會(huì)創(chuàng)建
例:
    docker run -itd --name myub -v /home/itcast/docker-test/ub:/d-test uuuu:v1.0 bash
    # 宿主機(jī)/home/itcast/docker-test/ub文件夾和容器/d-test文件夾中的數(shù)據(jù)可以共享了

? 文件的掛載和目錄的掛載命令一樣,同樣可以讓宿主機(jī)和容器共享一個(gè)文件,文件名可以重命名,也可以不重命名(不重命名就不寫(xiě)文件名即可)

數(shù)據(jù)卷容器和宿主機(jī)共享目錄的示意圖
1555492695097.png

數(shù)據(jù)卷容器和使用:

所謂數(shù)據(jù)卷容器,本質(zhì)上是一個(gè)容器,只不過(guò)這個(gè)容器只做一件事情,就是只提供共享目錄,只為了共享數(shù)據(jù)而存在,不做其他任何事情。

如果創(chuàng)建了數(shù)據(jù)卷和宿主機(jī)進(jìn)行了映射,而且容器什么也不做,也可以叫做數(shù)據(jù)卷容器。數(shù)據(jù)卷容器可以不和宿主機(jī)進(jìn)行映射,而只為了和其他容器進(jìn)行數(shù)據(jù)共享,創(chuàng)建命令如下:

創(chuàng)建[并啟動(dòng)]數(shù)據(jù)卷容器:
    docker run -itd --name 容器名 -v 數(shù)據(jù)卷容器的目錄 鏡像名:tag command
    # 除了可以創(chuàng)建并啟動(dòng),也可以光創(chuàng)建不啟動(dòng)
    docker create -it --name 容器名 -v 數(shù)據(jù)卷容器的目錄 鏡像名:tag command
    # 這個(gè)容器可以不啟動(dòng),目錄存在就好
例:
    docker create -it --name u1 -v /backup ub:1 bash

創(chuàng)建好以后,關(guān)鍵是和其他容器共享這個(gè)目錄,其他容器要啟動(dòng)才能用,命令如下:

創(chuàng)建掛載數(shù)據(jù)卷容器的容器命令:
    docker run -itd --name 容器名 --volumes-from 數(shù)據(jù)卷容器名 鏡像名:tag command
例:
    docker run -itd --name u2 --volumes-from u1 uuuu:v1.0 bash
    # 會(huì)在容器內(nèi)自動(dòng)生成backup目錄,并與數(shù)據(jù)卷容器共享這個(gè)目錄

數(shù)據(jù)卷容器和容器以及宿主機(jī)之間的關(guān)系有兩種,一種是沒(méi)有宿主機(jī)參與,一種是有宿主機(jī)參與

有宿主機(jī)參與的:

示意圖1
1555493020066.png

沒(méi)有宿主機(jī)參與的:

示意圖2
1555493125532.png

數(shù)據(jù)卷容器的數(shù)據(jù)備份與還原:

  • 備份分兩種情況:

    1. 數(shù)據(jù)卷容器在創(chuàng)建或啟動(dòng)時(shí)已經(jīng)掛載到宿主機(jī)上

      ? 這種情況基本不用進(jìn)行任何操作,因?yàn)閿?shù)據(jù)卷容器中的數(shù)據(jù)和宿主機(jī)中的數(shù)據(jù)是共享的,要丟一起丟,要有一起有。如果非要備份的話,就是將宿主機(jī)中的數(shù)據(jù)進(jìn)行備份到另一個(gè)地方即可,或者給宿主機(jī)中的共享文件夾創(chuàng)建硬鏈接。

    2. 數(shù)據(jù)卷容器創(chuàng)建并啟動(dòng)時(shí)并未掛載到宿主機(jī)上

      ? 創(chuàng)建或啟動(dòng)時(shí)沒(méi)有掛載宿主機(jī)上,到運(yùn)行一段時(shí)間之后再來(lái)備份已經(jīng)來(lái)不及了,所以需要另外一個(gè)“備份容器”作為宿主機(jī)和數(shù)據(jù)卷容器的媒介來(lái)連接宿主機(jī)和數(shù)據(jù)卷容器,以便達(dá)到數(shù)據(jù)卷容器中的數(shù)據(jù)備份到宿主機(jī)的目的。

      示意圖
      1555496756594.png

|

 例:

 ```shell
 # 1.創(chuàng)建數(shù)據(jù)卷容器
 docker create -it --name container -v /backup ub:1 bash
 # 2.創(chuàng)建兩個(gè)容器共享數(shù)據(jù)卷容器的數(shù)據(jù)
 docker run -itd --name ub1 --volumes-from container ub:1 bash
 docker run -itd --name ub2 --volumes-from container ub:1 bash
 # 3.進(jìn)入容器ub1的共享目錄中寫(xiě)入文件數(shù)據(jù)
 docker exec -it ub1 bash
 echo aaaaaaaaaaaaaaaaa > /backup/a.txt
 # 4.進(jìn)入容器ub2的共享目錄中查看數(shù)據(jù)
 docker exec -it ub2 bash
 cat /backup/a.txt # 可以看到數(shù)據(jù)和前面寫(xiě)進(jìn)去的一致
 # 5.在宿主機(jī)上創(chuàng)建本地備份目錄
 mkdir /home/itcast/docker-test/temp
 # 6.創(chuàng)建備份容器,映射到宿主機(jī)的備份目錄,并共享數(shù)據(jù)卷容器的數(shù)據(jù)(注意:這兩個(gè)目錄不要做成一個(gè),否則會(huì)有意想不到的錯(cuò)誤)
 docker run -itd --name tmp -v /home/itcast/docker-test/temp:/test1 --volumes-from container ub:1 bash
 # 7.進(jìn)入備份容器將數(shù)據(jù)卷容器的數(shù)據(jù)(/backup文件夾)打包拷貝到和宿主機(jī)共享的目錄中(/test1)
 tar zcvf /test1/backup.tar.gz /backup 
 # 8.然后可以在宿主機(jī)上的temp目錄中查看到備份好的數(shù)據(jù)文件
 ls /home/itcast/docker-test/temp
 ```

 命令優(yōu)化(合并第6~第7):

 ```shell
 docker run -itd --rm --name tmp -v /home/itcast/docker-test/temp:/test1 --volumes-from container ub:1 tar zcvf /test1/backup.tar.gz /backup
 # 這個(gè)容器創(chuàng)建出來(lái)就是為了備份文件,備份以后這個(gè)容器就沒(méi)用了,所以直接加--rm參數(shù);最后的command反正也是shell命令,打包也是shell命令,直接進(jìn)行替換
 ```
  • 還原

    還原的過(guò)程其實(shí)就是將備份的過(guò)程反過(guò)來(lái)。

    第1第5一樣,第6第7將壓縮換成解壓即可

    # 1.創(chuàng)建數(shù)據(jù)卷容器
    docker create -it --name container -v /backup ub:1 bash
    # 2.創(chuàng)建兩個(gè)容器共享數(shù)據(jù)卷容器的數(shù)據(jù)
    docker run -itd --name ub1 --volumes-from container ub:1 bash
    docker run -itd --name ub2 --volumes-from container ub:1 bash
    # 3.進(jìn)入容器ub1的共享目錄中寫(xiě)入文件數(shù)據(jù)
    docker exec -it ub1 bash
    echo aaaaaaaaaaaaaaaaa > /backup/a.txt
    # 4.進(jìn)入容器ub2的共享目錄中查看數(shù)據(jù)
    docker exec -it ub2 bash
    cat /backup/a.txt # 可以看到數(shù)據(jù)和前面寫(xiě)進(jìn)去的一致
    # 5.在宿主機(jī)上創(chuàng)建本地備份目錄
    mkdir /home/itcast/docker-test/temp
    # 創(chuàng)建恢復(fù)容器,并將數(shù)據(jù)放入和數(shù)據(jù)卷容器共享的文件夾中
    docker run -itd --rm --name tmp -v /home/itcast/docker-test/temp:/test1 --volumes-from container ub:1 tar zxvf /test1/backup.tar.gz -C /
    

端口映射:

示意圖
1555513504076.png

命令:

都是創(chuàng)建并啟動(dòng)容器的時(shí)候設(shè)置

隨機(jī)端口映射(不推薦):
    docker run -itd --name 容器名 -P 鏡像名:tag
指定端口映射(推薦):
    docker run -itd --name 容器名 -p [宿主機(jī)ip:]宿主機(jī)端口:容器端口 鏡像名:tag
    # 指定一個(gè)宿主機(jī)的空閑端口,容器端口指定一個(gè)協(xié)議端口,例:http為80,https為443
# 在啟動(dòng)系統(tǒng)自帶的容器的時(shí)候,在最后面不要加command了,因?yàn)樯婕暗椒?wù)的啟動(dòng),指定command后,服務(wù)不能啟動(dòng)
例:
    docker run -itd --name myweb -p 8088:80 nginx

容器的網(wǎng)絡(luò)管理

docker network --help
    docker network command
    commands:
        connect     連接容器到指定的網(wǎng)絡(luò)中
        create      創(chuàng)建一個(gè)網(wǎng)絡(luò)
        disconnect  將容器從網(wǎng)絡(luò)中刪除
        inspect     查看網(wǎng)絡(luò)相關(guān)的信息
        ls          查看現(xiàn)有的所有網(wǎng)絡(luò)
        prune       刪除所有的未使用的網(wǎng)絡(luò)
        rm          刪除一個(gè)或多個(gè)指定的網(wǎng)絡(luò)

docker中的網(wǎng)絡(luò)

查看所有網(wǎng)絡(luò)列表:
NETWORK ID          NAME                DRIVER              SCOPE # 頭
64d83b763e85        bridge              bridge              local # 橋接網(wǎng)絡(luò),單獨(dú)生成網(wǎng)卡
89d9ce6dd16d        host                host                local # 主機(jī)網(wǎng)絡(luò),和宿主機(jī)共用網(wǎng)卡
b53a004ffcb7        none                null                local # 網(wǎng)絡(luò)一切都需要手動(dòng)設(shè)置

# 查看bridge網(wǎng)絡(luò)
docker network inspect bridge
    # "IPv4Address": "172.17.0.3/16", 表示ip地址和子網(wǎng)掩碼,子網(wǎng)掩碼是255.255.0.0
    "Containers": {
            "16a17991c9d7034eba09fdc9a5c90d3121b5607f062002d6e01b7375bd2803b9": {
                "Name": "ub2",
                "EndpointID": "89b4d01ab4b2be864a4e56fc115b1c6ce8880fdb4842c8c1c4981e4114e79ea8",
                "MacAddress": "02:42:ac:11:00:03",
                "IPv4Address": "172.17.0.3/16", # 每個(gè)容器都由對(duì)應(yīng)的ip地址和子網(wǎng)掩碼
                "IPv6Address": ""
            },
            "250c697739db1a291e17a24efccbf88a64de4c600d24e839f14740c22b724c0e": {
                "Name": "myweb",
                "EndpointID": "52ccff4ef2237641fdbb39557f2a15fc62d1226d510dbf1a49dce654b94114b5",
                "MacAddress": "02:42:ac:11:00:05",
                "IPv4Address": "172.17.0.5/16",
                "IPv6Address": ""
            },
 # container項(xiàng),表示在網(wǎng)絡(luò)中包含了的容器

docker容器默認(rèn)都在bridge網(wǎng)絡(luò)中

bridge網(wǎng)絡(luò)模式

創(chuàng)建網(wǎng)絡(luò)

docker network create [OPTIONS] NETWORK
Options:
      --attachable           Enable manual container attachment
      --aux-address map      Auxiliary IPv4 or IPv6 addresses used by
                             Network driver (default map[])
      --config-from string   The network from which copying the configuration
      --config-only          Create a configuration only network
  -d, --driver string        # 指定網(wǎng)絡(luò)的驅(qū)動(dòng),默認(rèn)是橋接模式
      --gateway strings      # 指定網(wǎng)關(guān)(一般就是192.168.0.1)
      --ingress              Create swarm routing-mesh network
      --internal             Restrict external access to the network
      --ip-range strings     Allocate container ip from a sub-range
      --ipam-driver string   IP Address Management Driver (default "default")
      --ipam-opt map         Set IPAM driver specific options (default map[])
      --ipv6                 Enable IPv6 networking
      --label list           Set metadata on a network
  -o, --opt map              Set driver specific options (default map[])
      --scope string         Control the network's scope
      --subnet strings       # 指定網(wǎng)段(一般是192.168.0.255)
例:
   docker network create mynetwork # 再次查看網(wǎng)絡(luò)列表的時(shí)候,可以看見(jiàn)網(wǎng)絡(luò)列表中多了一個(gè)自己創(chuàng)建的mynetwork網(wǎng)絡(luò)
   # 查看mynetwork屬性信息的時(shí)候,可以看到默認(rèn)的驅(qū)動(dòng)、網(wǎng)關(guān)、網(wǎng)段等信息,并且在新創(chuàng)建的這個(gè)網(wǎng)絡(luò)沒(méi)有容器

創(chuàng)建自定義網(wǎng)段和網(wǎng)關(guān)的網(wǎng)絡(luò):
    docker network create --subnet IP地址/子網(wǎng)掩碼 --gateway 自定義網(wǎng)關(guān) 網(wǎng)絡(luò)名
例:
    docker network create --subnet 180.17.0.0/16 --gateway 180.17.0.1 mynetwork1
    # ip地址自定義,子網(wǎng)掩碼參考bridge網(wǎng)絡(luò),網(wǎng)關(guān)是1

查看容器的屬性信息可以看出這個(gè)容器處在哪個(gè)網(wǎng)絡(luò)中

docker inspect myweb
    "Networks": {
        "bridge": { # 網(wǎng)絡(luò)名稱
            "IPAMConfig": null,
            "Links": null,
            "Aliases": null,
            "NetworkID": "64d83b763e85d40d83381787cc621ace063233e594ab32f95f5b911b331d2d7a",
            "EndpointID": "52ccff4ef2237641fdbb39557f2a15fc62d1226d510dbf1a49dce654b94114b5",
            "Gateway": "172.17.0.1",
            "IPAddress": "172.17.0.5", 
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "MacAddress": "02:42:ac:11:00:05",
            "DriverOpts": null
        }
    }

啟動(dòng)并創(chuàng)建容器的時(shí)候?qū)⑷萜骷尤氲骄W(wǎng)絡(luò)中

docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
Options:
      --network string                 # 將一個(gè)容器添加到網(wǎng)絡(luò)中  
例:
    docker run -itd --name nginxnetwork --network mynetwork ub:1 bash
    # 查看容器詳細(xì)信息的時(shí)候,可以看到容器的網(wǎng)絡(luò)是mynetwork,或者查看mynetwork網(wǎng)絡(luò)的詳細(xì)信息的時(shí)候可以看到container項(xiàng)中會(huì)有nginxnetwork容器

從網(wǎng)絡(luò)中刪除容器

命令:
    docker network disconnect [OPTIONS] NETWORK CONTAINER
例:
    docker network disconnect mynetwork nginxnetwork # 再次查看網(wǎng)絡(luò)或者容器的詳細(xì)信息會(huì)發(fā)現(xiàn)容器已經(jīng)不在這個(gè)網(wǎng)絡(luò)中

將容器添加到指定網(wǎng)絡(luò)中

命令:
    docker network connect [OPTIONS] NETWORK CONTAINER
例:
    docker network connect mynetwork nginxnetwork   

刪除網(wǎng)絡(luò):

命令:
    docker network rm NETWORK [NETWORK...] # 可以同時(shí)刪除多個(gè)網(wǎng)絡(luò)
例:
    docker network rm mynetwork1
#刪除網(wǎng)絡(luò)的時(shí)候,要確保網(wǎng)絡(luò)中沒(méi)有包含容器

容器在啟動(dòng)的時(shí)候會(huì)加入到默認(rèn)的網(wǎng)絡(luò)中;一個(gè)容器可以同時(shí)加入到多個(gè)網(wǎng)絡(luò)中;容器和容器之間要進(jìn)行通信的前提是這些容器必須處于同一個(gè)網(wǎng)絡(luò)中;

host網(wǎng)絡(luò)模式

host網(wǎng)絡(luò)是和宿主機(jī)共享同一個(gè)網(wǎng)卡,所以不能重建,也就是說(shuō)host網(wǎng)絡(luò)只有一個(gè)。操作host網(wǎng)絡(luò)只能是在容器創(chuàng)建啟動(dòng)或者后期將容器添加到這個(gè)網(wǎng)絡(luò)中。

docker run -itd --network host --name nyweb2 nginx bash # 創(chuàng)建啟動(dòng)容器nyweb2并加入到host網(wǎng)絡(luò)
docker inspect nyweb2 # 查看nyweb2容器的詳細(xì)信息
    "Networks": {
        "host": { # 這個(gè)容器已經(jīng)加入到host網(wǎng)絡(luò)中了
            "IPAMConfig": null,
            "Links": null,
            "Aliases": null,
            "NetworkID": "89d9ce6dd16d7808daa82fdada549392e02ba7e0cea496bed5e0ad9091471986",
            "EndpointID": "c6f601bb153671834675a5c8c44ca5ce918489ac99ea661075eb6a33c1dd64ed",
            "Gateway": "",
            "IPAddress": "",
            "IPPrefixLen": 0,
            "IPv6Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "MacAddress": "",
            "DriverOpts": null
        }
    }

dockerfile

簡(jiǎn)介:

shell命令就是linux命令,shell腳本是一個(gè)可執(zhí)行的文件,這個(gè)文件寫(xiě)了很多的shell命令以及一些簡(jiǎn)單的邏輯(判斷和循環(huán))。dockerfile也是一個(gè)文件,這個(gè)文件中寫(xiě)了很多的docker命令,一般情況,里面寫(xiě)的是制作鏡像的步驟,以便重復(fù)使用和快速制作鏡像。

即:一般情況,手動(dòng)下載鏡像,創(chuàng)建容器,在容器中搭建環(huán)境或者安裝軟件 ------>使用dockerfile文件執(zhí)行即可。也就是將手動(dòng)操作的步驟,同過(guò)dockerfile的規(guī)則和命令書(shū)寫(xiě)到dockerfile文件中,執(zhí)行這個(gè)文件得到容器并將這個(gè)鏡像導(dǎo)出。

規(guī)則:

  1. dockerfile文件名首字母大寫(xiě)(例:Dockerfile)
  2. 盡量將dockerfile放到空目錄中
  3. 每個(gè)容器盡量只有一個(gè)功能
  4. dockerfile中要執(zhí)行的命令越少越好

dockerfile基礎(chǔ)指令

dockerfile里面的注釋是#

FROM

指定原始鏡像,最后制作出來(lái)的鏡像是從容器中導(dǎo)出的,制作容器是需要原始鏡像的

命令:
    FROM 鏡像名:tag # 這里的鏡像名指的是原始鏡像   
例:
    FROM ubuntu

FROM必須寫(xiě)在Dockerfile的第一行(除注釋),可以連續(xù)寫(xiě)多個(gè)FROM原始鏡像,如果指定的鏡像名在本地鏡像倉(cāng)庫(kù)中不存在,會(huì)自動(dòng)從遠(yuǎn)程倉(cāng)庫(kù)下載到本地倉(cāng)庫(kù),如果遠(yuǎn)程倉(cāng)庫(kù)中也沒(méi)指定的鏡像,就報(bào)錯(cuò)終止執(zhí)行了

MAINTAINER

維護(hù)者信息

命令:
    MAINTAINER 維護(hù)人員信息
例:
    MAINTAINER zhangsan zhangsan@163.com

RUN

構(gòu)建鏡像要執(zhí)行的shell命令,如果命令中有需要確認(rèn)的操作,在后面必須有-y;命令太長(zhǎng)需要換行,行尾要加\

命令: 
    RUN shell命令
例:
    RUN mkdir /home/itcast/go -p
或:
    RUN ["mkdir","/home/itcast/go","-p"]

EXPOSE

設(shè)置docker容器對(duì)外開(kāi)放的端口。容器和外部環(huán)境是隔離的,要從外部訪問(wèn)到容器內(nèi)部,需要容器開(kāi)放端口

命令:
    EXPOSE 端口號(hào)
例:
    EXPOSE 80
    # 還可以使用docker命令進(jìn)行:docker run -itd -p 8888:80

執(zhí)行dockerfile文件的命令:

docker build [OPTIONS] dockerfile的文件路徑或者網(wǎng)上能訪問(wèn)到dockerfile的url
# 后面的路徑必須是一個(gè)目錄,而不能是具體文件
Options:
      -t, --tag list                指定最后制作出來(lái)的鏡像(執(zhí)行到最后從容器中導(dǎo)出的鏡像)的名字
# 最后制作好的鏡像在本地鏡像倉(cāng)庫(kù)中

例:

先創(chuàng)建一個(gè)空目錄,然后在目錄中新建文件名為Dockerfile,寫(xiě)入如下內(nèi)容

# 構(gòu)建一個(gè)基于ubuntu的docker訂制鏡像
# 基礎(chǔ)鏡像
FROM ubuntu
# 鏡像作者
MAINTAINER wangjie wangjie.912@163.com
# 執(zhí)行命令
RUN mkdir hello
RUN mkdir world
RUN sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
RUN sed -i 's/security.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
# sed的意思是替換下載庫(kù)地址,后面的/g代表整行替換
RUN apt-get update
RUN apt-get install nginx -y
# 對(duì)外開(kāi)放端口
EXPOSE 80

運(yùn)行這個(gè)文件:

# 運(yùn)行docker文件
    docker build -t mytest:v1.0 . # 在當(dāng)前文件夾可以使用一個(gè)點(diǎn)來(lái)表示路徑
# 查看制作好的鏡像
    docker images

運(yùn)行最后結(jié)果:

示意圖
1555639757579.png

dockerfile的運(yùn)行指令

CMD

這個(gè)指令是用來(lái)執(zhí)行shell命令的,這個(gè)shell命令代表容器啟動(dòng)后默認(rèn)要執(zhí)行的命令(CMD就是command的簡(jiǎn)寫(xiě))。一個(gè)dockerfile只能有一個(gè)CMD,如果寫(xiě)多個(gè),以最后一個(gè)為準(zhǔn)。在后期執(zhí)行docker run的時(shí)候,這個(gè)指令會(huì)被覆蓋。

CMD shell命令
CMD ["shell命令","命令參數(shù)1","命令參數(shù)2"]

ENTRYPOINT

ENTRYPOINT的用法和意義跟CMD一樣,區(qū)別只在ENTRYPOINT默認(rèn)不會(huì)被docker run覆蓋,若想覆蓋,需要在docker run后面加--entrypoint參數(shù)

CMD和ENTRYPOINT綜合使用:

# 要先寫(xiě)ENTRYPOINT后寫(xiě)CMD,CMD通常作為ENTRYPOINT的參數(shù)
ENTRYPOINT mkdir /home/itcast/go
CMD -p
# 意思為:mkdir /homt/itcast/go -p

dockerfile的文件編輯指令

ADD

這個(gè)指令是將宿主機(jī)的文件拷貝到容器中的。ADD指令在拷貝的同時(shí),如果這個(gè)文件是壓縮文件,會(huì)將宿主機(jī)的壓縮文件拷貝到容器中進(jìn)行解壓(前提是宿主機(jī)中的壓縮文件是可識(shí)別的壓縮包,例:.gz或.bz2)。

命令:
    ADD 宿主機(jī)文件 容器目錄/文件名
    ADD ["宿主機(jī)文件","容器目錄/文件名"]
    # 宿主機(jī)的文件一般放到和dockerfile所在的目錄中
例:
    # 文件
    ADD ["a.txt","/home/itcast/go/b.txt"] #容器中目錄不存在會(huì)自動(dòng)創(chuàng)建;文件存在則覆蓋,不存在則拷貝
    # 目錄 a.tar.gz ---> mytest文件夾
    Add ["a.tar.gz","/home/itcast/go"] # 會(huì)在/home/itcast/go目錄下得到一個(gè)mytest錄

COPY

COPY的用法和意義跟ADD是一樣的,區(qū)別只在于COPY不會(huì)解壓。

VOLUME

這個(gè)指令是在鏡像中創(chuàng)建掛載點(diǎn),這樣只要通過(guò)該鏡像創(chuàng)建的容器都由了掛載點(diǎn)(可以是在容器中創(chuàng)建數(shù)據(jù)卷,也可以把這個(gè)容器當(dāng)做數(shù)據(jù)卷容器),通過(guò)VOLUME指定的掛載點(diǎn)目錄是自動(dòng)生成的。

命令:
    VOLUME ["/data"]
例:
    VOLUME ["/data","/home/itcast/mytest"]

dockerfile的環(huán)境指令

ENV

這個(gè)指令是用來(lái)設(shè)置容器的環(huán)境變量的,一般寫(xiě)在RUN指令之前。

命令:
    ENV <key> <value> # 設(shè)置一個(gè)
    ENV <key>=<value> <key>=<value> # 設(shè)置多個(gè) 
例:
    ENV name zhangsan
    ENV name=zhangsan age=12

WORKDIR

這個(gè)指令是用來(lái)切換工作目錄的,類似于shell命令的cd,主要是為后續(xù)的RUN、ENTRYPOINT、CMD等指令在指定的目錄中執(zhí)行??梢赃M(jìn)行多次切換。

命令:
    WORKDIR 目錄
例:
    WORKDIR /home/itcast/go
    RUN a.sh
    
    WORKDIR /home
    WORKDIR itcast # 代表相對(duì)路徑
    WORKDIR go
    RUM pwd # /home/itcast/go

USER

這個(gè)指令用來(lái)指定執(zhí)行命令的用戶,默認(rèn)是root

命令:
    USER 用戶名
例:
    USER root

ARG

這個(gè)指令是用來(lái)向dockerfile命令傳參的。如果在dockerfile中需要用到外部傳來(lái)的參數(shù),在dockerfile中就用ARG來(lái)表示。

命令:
    ARG <name>[=value]
例:
    FROM ubuntu
    ARG myname
    ARG index
# 在執(zhí)行dockerfile的時(shí)候
    docker build --build-arg myname=zhangsan index=1

dockerfile觸發(fā)器指令

ONBUILD

ONBUILD指令的意思示意圖
1555645862355.png

制作鏡像A的時(shí)候,設(shè)置輸出1,但是不會(huì)被輸出,當(dāng)使用鏡像A作為原始鏡像制作鏡像B的時(shí)候才會(huì)輸出1。

命令:
    ONBUILD [command]
例:
    ONBUILD ["echo","1"]

dockerfile案例

用dockerfile來(lái)部署一個(gè)go的運(yùn)行環(huán)境,并搭建beego框架至可以運(yùn)行。

步驟:

  1. 手動(dòng)搭建go運(yùn)行環(huán)境并搭建beego框架

    #1、docker環(huán)境配置
    #1.1 獲取docker鏡像
    #獲取一個(gè)ubuntu的模板文件
    cat ubuntu-16.04-x86_64.tar.gz | docker import - ubuntu-nimi
    #1.2 啟動(dòng)docker容器
    #啟動(dòng)容器,容器名稱叫g(shù)o-test
    docker run -itd --name go-test ubuntu-nimi
    #進(jìn)入容器
    docker exec -it go-test /bin/bash
    #2、go環(huán)境部署
    #2.1 基礎(chǔ)環(huán)境配置
    #配置國(guó)內(nèi)源
    vim /etc/apt/sources.list
    #文件內(nèi)容如下
    deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted
    deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted
    deb http://mirrors.aliyun.com/ubuntu/ xenial universe
    deb http://mirrors.aliyun.com/ubuntu/ xenial-updates universe
    deb http://mirrors.aliyun.com/ubuntu/ xenial multiverse
    deb http://mirrors.aliyun.com/ubuntu/ xenial-updates multiverse
    deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse
    deb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted
    deb http://mirrors.aliyun.com/ubuntu/ xenial-security universe
    deb http://mirrors.aliyun.com/ubuntu/ xenial-security multiverse
    #如果由于網(wǎng)絡(luò)環(huán)境原因不能進(jìn)行軟件源更新可以使用如下內(nèi)容
    sudo sed -i 's/cn.archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list 
    
    #更新軟件源,安裝基本軟件
    apt-get update
    apt-get install gcc libc6-dev git vim lrzsz -y
    #2.2 go環(huán)境配置
    #安裝go語(yǔ)言軟件
    //apt-get install golang -y
    由于軟件源問(wèn)題改使用新版本go
    將go1.10.linux-amd64.tar.gz拷貝到容器中進(jìn)行解壓
    tar -C /usr/local  -zxf go1.10.linux-amd64.tar.gz
    
    #配置go基本環(huán)境變量
    export GOROOT=/usr/local/go                
    export PATH=$PATH:/usr/local/go/bin   
    export GOPATH=/root/go
    export PATH=$GOPATH/bin/:$PATH
    #3、go項(xiàng)目部署
    #3.1 獲取beego代碼
    #下載項(xiàng)目beego
    go get github.com/astaxie/beego
    #3.2 項(xiàng)目文件配置
    #創(chuàng)建項(xiàng)目目錄
    mkdir /root/go/src/myTest
    cd /root/go/src/myTest
    #編輯go項(xiàng)目測(cè)試文件test.go
    package main
    import (
    "github.com/astaxie/beego"
    )
    type MainController struct {
    beego.Controller
    }
    func (this *MainController) Get() {
    this.Ctx.WriteString("hello world\n")
    }
    func main() {
    beego.Router("/", &MainController{})
    beego.Run()
    }
    #3.3 項(xiàng)目啟動(dòng)
    #運(yùn)行該文件
    go run test.go
    #可以看到:
    #這個(gè)go項(xiàng)目運(yùn)行起來(lái)后,開(kāi)放的端口是8080
    #4、測(cè)試
    #4.1宿主機(jī)測(cè)試
    #查看容器的ip地址
    docker inspect go-test
    #瀏覽器查看效果:
    curl 172.17.0.2:8080
    
  1. 修改為dockerfile方案

    # 構(gòu)建一個(gè)基于ubuntu 的docker 定制鏡像
    # 基礎(chǔ)鏡像
    FROM ubuntu
    
    # 鏡像作者
    MAINTAINER panda kstwoak47@163.com
    
    # 增加國(guó)內(nèi)源
    #COPY sources.list /etc/apt/
    
    RUN sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
    RUN sed -i 's/security.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
    
    # 執(zhí)行命令
    
    RUN apt-get update
    RUN apt-get install gcc libc6-dev git lrzsz -y
    #將go復(fù)制解壓到容器中
    ADD go1.10.linux-amd64.tar.gz  /usr/local/
    
    # 定制環(huán)境變量
    
    ENV GOROOT=/usr/local/go                
    ENV PATH=$PATH:/usr/local/go/bin   
    ENV GOPATH=/root/go
    ENV PATH=$GOPATH/bin/:$PATH
    
    # 下載項(xiàng)目
    
    RUN go get github.com/astaxie/beego
    
    # 增加文件
    
    COPY test.go /root/go/src/myTest/
    
    # 定制工作目錄
    
    WORKDIR /root/go/src/myTest/
    
    # 對(duì)外端口
    
    EXPOSE 8080
    
    # 運(yùn)行項(xiàng)目
    
    ENTRYPOINT ["go","run","test.go"]
    
    #把sources.list和test.go文件放到這個(gè)目錄中
    #構(gòu)建鏡像
    docker build -t go-test:v0.1 .
    #運(yùn)行鏡像
    docker run -p 8080:8080 -itd go-test:v0.1
    #訪問(wèn)鏡像,查看效果
    

    注意順序:如果最后的端口開(kāi)放和運(yùn)行項(xiàng)目反了就啟動(dòng)不了了;最后這個(gè)運(yùn)行項(xiàng)目是bash命令,且不能夠被command覆蓋,所以只能使用ENTRYPOINT。

docker-compose

docker-compose是一款管理docker的工具,可以批量操作docker。這款工具是用python開(kāi)發(fā)的。

docker-compose是docker容器進(jìn)行編排的工具,定義和運(yùn)行多容器的應(yīng)用,可以一條命令啟動(dòng)多個(gè)容器,使用Docker Compose不再需要使用shell腳本來(lái)啟動(dòng)容器。

簡(jiǎn)單來(lái)說(shuō),就是使用docker-compose自身的命令來(lái)批量操作容器。操作步驟:

  1. 安裝docker-compose工具
  2. 編寫(xiě)docker-compose配置文件
  3. 使用命令啟動(dòng)docker-compose

安裝

# 安裝依賴工具
sudo apt-get install python-pip -y
# 安裝編排工具
sudo pip install docker-compose
# 查看編排工具版本(可以用來(lái)檢測(cè)是否安裝好)
sudo docker-compose version
# 查看命令幫助
docker-compose --help

如下圖所示,則表示docker-compose工具安裝成功

示意圖
1555688569313.png

YAML文件格式

docker-compose的配置文件格式是yaml或者yml(后綴為yaml或者yml)。

YAM格式文件的基本規(guī)則:

  1. 大小寫(xiě)敏感
  2. 使用縮進(jìn)表示層級(jí)關(guān)系
  3. 進(jìn)制使用tab縮進(jìn),只能使用空格表達(dá)縮進(jìn)
  4. 縮進(jìn)長(zhǎng)度沒(méi)有限制,只要元素對(duì)齊就表示這些元素是同一層級(jí)
  5. 使用#注釋
  6. 字符串可以不適用引號(hào)標(biāo)注,建議用雙引號(hào)標(biāo)注字符串

YAM格式文件的3中數(shù)據(jù)類型:

  1. map-散列表

    # 使用冒號(hào)標(biāo)注鍵值對(duì),相同縮進(jìn)的鍵值對(duì)屬于同一個(gè)map
    例:
     age:12
     name:zhangsan
     # age和name屬于同一個(gè)map
    
  1. list-數(shù)組

    # 使用連字符表示數(shù)組中的元素,相同縮進(jìn)的元素屬于同一個(gè)數(shù)組
    例:
     - a
     - b
         - c
         - d
     # a和b屬于同一個(gè)數(shù)組,c和d屬于數(shù)組b
    
  1. scalar-純量

    # 字符串
     "hello"
     world
    # 布爾值
     true
     false
    # 整型
     12
    # 浮點(diǎn)型
     3.14
    # null
     在YML中使用~來(lái)表示空
    

數(shù)據(jù)類型示例:

# 例1
Websites:
    YAML:yaml.org
    Ruby:ruby-lang.org
    Python:python.org
    Perl:use.perl.org
# 使用json表示:整體上是一個(gè)map,這個(gè)map的結(jié)構(gòu)如下:
# {"Website":{"YAML":yaml.org","Ruby":"ruby-lang.org","Python":"python.org","Perl":"use.perl.org"}}

# 例2
languages:
- Ruby
- Perl
- Python
- C
# 使用json表示,整體上是一個(gè)map,該map結(jié)構(gòu)如下:
# {"languages":["Ruby","Perl","Python","C"]}

# 例3
-
  - Ruby
  - Perl
  - Python
-
  - C
  - C++
  - Java
# 使用json表示,整體上是由兩個(gè)元素組成的數(shù)組,這兩個(gè)元素也是數(shù)組,各有3個(gè)字符串元素,具體結(jié)構(gòu)如下:
# [["Ruby","Perl","Python"],["C","C++","Java"]]

# 例4
- 
  id:1
  name:zhangsan
-
  id:2
  name:lisi
# 使用json表示,整體上是兩個(gè)map組成的數(shù)組,具體結(jié)構(gòu)如下:
# [{"id":1,"name":"zhangsan"},{"id":2,"name":"lisi"}]

YML配置文件的關(guān)鍵字

在docker-compose的配置文件中,有三大部分(是不用縮進(jìn)的):

  1. version

    表示docker-compose的版本,一般情況寫(xiě)成固定的2就行,例:

    version: '2' # docker-compose的版本
    
  1. services

    表示每個(gè)docker啟動(dòng)后的在linux中的服務(wù),服務(wù)名自定義,每個(gè)服務(wù)名代表一個(gè)docker容器,例:

    # common.yaml
    version: '2' # docker-compose的版本
    services:    # 服務(wù)
     webapp  
            environment:     # 環(huán)境變量
                  RACK_ENV: development
                  SHOW: 'true'
                  SESSION_SECRET: docker-compose
    
# test.yaml
services:        # 服務(wù)
  web:           # 服務(wù)名, 自己起的, 每個(gè)服務(wù)器名對(duì)應(yīng)一個(gè)啟動(dòng)的容器
    image: nginx:latest  # 容器是基于那個(gè)鏡像啟動(dòng) 的
    container_name: myweb # 容器名字
    extends: # 繼承自另一個(gè)服務(wù)
      file: common.yml
      service: webapp
    command: /urs/local/nginx -g daemon off # docker容器啟動(dòng)之后, 執(zhí)行的命令
    networks:    # 容器啟動(dòng)之后所在的網(wǎng)絡(luò)
      - network1
    ports:       # 端口映射
      - "6789:8080"
      - 12:12  -> yaml解析的時(shí)候如果60以下, 解析會(huì)有問(wèn)題
      # 6789: 宿主機(jī)端口, 8080: 容器端口
    extra_hosts:
      - "host1:162.242.195.82"
      - "host2:50.31.209.229"
      # host1: 主機(jī)名(域名)
      # 域名解析: 
         - 先查本地hosts文件
         - 本地的dns緩存
         - 通過(guò)dns服務(wù)器查詢
 
  sql:
    image: mysql
    volumes:
      - /home/test:/root/workdir 
    ports:
      - 9999:3306
    networks:
      - network1
      - network2
    depend_on:
      - web
      - redis
      
  redis:
    image: redis
    volumes:
      - /home/go/redis.conf:/redis/redis.conf
    ports:
      - 8989:6379
    networks:
      - network1

多學(xué)一招:設(shè)置臨時(shí)的環(huán)境變量就是直接是變量名=變量值,然后在該終端關(guān)閉之前都可以用$變量名來(lái)得到變量值。變量名習(xí)慣是大寫(xiě)。

  1. networks

    聲名容器會(huì)用到的網(wǎng)絡(luò),例:

    networks:
      network1:  # 網(wǎng)絡(luò)名
        driver: bridge # 網(wǎng)絡(luò)驅(qū)動(dòng), 可以省略
      network2   # 網(wǎng)絡(luò)名
        driver: bridge
    

sevices關(guān)鍵字中的具體描述:

  • image

    image 則是指定服務(wù)的鏡像名稱或鏡像 ID。如果鏡像在本地不存在,Compose 將會(huì)嘗試?yán)∵@個(gè)鏡像。

  • command

    使用 command 可以覆蓋容器啟動(dòng)后默認(rèn)執(zhí)行的命令。

  • container_name

    容器啟動(dòng)之后的名字

  • depends_on

    一般項(xiàng)目容器啟動(dòng)的順序是有要求的,如果直接從上到下啟動(dòng)容器,必然會(huì)因?yàn)槿萜饕蕾噯?wèn)題而啟動(dòng)失敗。例如在沒(méi)啟動(dòng)數(shù)據(jù)庫(kù)容器的時(shí)候啟動(dòng)了應(yīng)用容器,這時(shí)候應(yīng)用容器會(huì)因?yàn)檎也坏綌?shù)據(jù)庫(kù)而退出,為了避免這種情況我們需要加入一個(gè)標(biāo)簽,就是 depends_on,這個(gè)標(biāo)簽解決了容器的依賴、啟動(dòng)先后的問(wèn)題。例:

    version: '2'
    services:
      web:
        image: ubuntu
        depends_on: # 表示在啟動(dòng)web服務(wù)之前,先啟動(dòng)db和redis服務(wù)
          - db
          - redis
      redis:
        image: redis
      db:
        image: mysql
    
  • evironment

    environment 和 Dockerfile 中的 ENV 指令一樣會(huì)把變量一直保存在鏡像、容器中。

  • ports

    映射端口的標(biāo)簽。
    使用HOST:CONTAINER格式或者只是指定容器的端口,宿主機(jī)會(huì)隨機(jī)映射端口,例:

    # docker run -p 宿主機(jī)端口:容器端口
    ports:
     - "3000"  # 宿主機(jī)的端口是隨機(jī)分配的, 3000是容器開(kāi)發(fā)的對(duì)外端口  // -P
     - "8000:8000"   -> 一般這樣寫(xiě)就可以
     - "127.0.0.1:8001:8001"
    
  • volumes

    掛載一個(gè)目錄或者一個(gè)已存在的數(shù)據(jù)卷容器,可以直接使用 [HOST:CONTAINER] 這樣的格式,或者使用 [HOST:CONTAINER:ro] 這樣的格式,后者對(duì)于容器來(lái)說(shuō),數(shù)據(jù)卷是只讀的,這樣可以有效保護(hù)宿主機(jī)的文件系統(tǒng)。
    Compose的數(shù)據(jù)卷指定路徑可以是相對(duì)路徑,使用 . 或者 .. 來(lái)指定相對(duì)目錄。例:

    # docker run -v /home/go:/xxx
    # 宿主機(jī)或容器的映射路徑如果不存在, 會(huì)自動(dòng)創(chuàng)建出來(lái)
    volumes:
      # 這是宿主機(jī)目錄, 容器的映射目錄會(huì)自動(dòng)創(chuàng)建,但是不知道在容器中是哪個(gè)目錄
      - /var/lib/mysql -> 不推薦使用
      # 按照絕對(duì)路徑映射
      - /opt/data:/var/lib/mysql
      # 相對(duì)路徑的映射
      # ./ 目錄是docker-compose配置文件所在的目錄
      # 如果是相對(duì)路徑, ./是必須要寫(xiě)的, ../
      - ./cache:/tmp/cache
      # 指定容器中對(duì)文件的操作權(quán)限, 默認(rèn)rw
      - /home/go/configs:/etc/configs/:ro
      # 文件映射
      - ../temp/a.txt:/temp/b.sh
    
  • volumes_from

    從其它容器或者服務(wù)掛載數(shù)據(jù)卷,可選的參數(shù)是 :ro或者 :rw,前者表示容器只讀,后者表示容器對(duì)數(shù)據(jù)卷是可讀可寫(xiě)的。默認(rèn)情況下是可讀可寫(xiě)的。例:

    # docker run --volumes_from 數(shù)據(jù)卷容器名
    volumes_from:
      - service_name  # 服務(wù)名
      - service_name:ro
      - container:container_name  # 掛載容器
      - container:container_name:rw   
    
  • extends

    這個(gè)標(biāo)簽可以擴(kuò)展另一個(gè)服務(wù),擴(kuò)展內(nèi)容可以是來(lái)自在當(dāng)前文件,也可以是來(lái)自其他文件,相同服務(wù)的情況下,后來(lái)者會(huì)有選擇地覆蓋原有配置。

  • networks

    加入指定網(wǎng)絡(luò),格式如下:

    services:
      some-service:
        networks:
         - some-network
         - other-network
    

    關(guān)于這個(gè)標(biāo)簽還有一個(gè)特別的子標(biāo)簽aliases,這是一個(gè)用來(lái)設(shè)置服務(wù)別名的標(biāo)簽,例如:

    services:
      some-service:
        networks:
          some-network:
            aliases:
             - alias1
          other-network:
            aliases:
             - alias2
    
  • extra_hosts

    添加主機(jī)映射, 最終被添加到hosts文件中 /etc/hosts,例:

    extra_hosts:
     - "somehost:162.242.195.82"
     - "otherhost:50.31.209.229"
    

docker-compose的命令

配置文件的命名自定義,但是推薦使用docker-compose.yaml或docker-compose.yml

服務(wù)

服務(wù)的啟動(dòng):

docker-compose -f 配置文件路徑 up [-d]
# -d參數(shù)表示以守護(hù)進(jìn)程的方式運(yùn)行

服務(wù)的關(guān)閉:

docker-compose -f 配置文件路徑 down

查看服務(wù):

docker-compose -f 配置文件路徑 ps

如果配置文件的名字是docker-compose,那么在服務(wù)的所有命令都可以不加-f參數(shù)

容器

啟動(dòng)某個(gè)容器:

docker-compose start 服務(wù)名

關(guān)閉某個(gè)容器:

docker-compose stop 服務(wù)名

刪除某個(gè)容器:

docker-compose rm 服務(wù)名
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請(qǐng)通過(guò)簡(jiǎn)信或評(píng)論聯(lián)系作者。

相關(guān)閱讀更多精彩內(nèi)容

  • 《Docker從入門(mén)到實(shí)踐》閱讀筆記 原書(shū)地址: https://yeasy.gitbooks.io/docker...
    GuoYuebo閱讀 11,649評(píng)論 1 39
  • 一 、什么是 Docker Docker 最初是 dotCloud 公司創(chuàng)始人 Solomon Hykes 在法國(guó)...
    Blazzer閱讀 3,239評(píng)論 0 13
  • docker基本概念 1. Image Definition 鏡像 Image 就是一堆只讀層 read-only...
    慢清塵閱讀 9,005評(píng)論 1 21
  • 今天,是一年一度的母親節(jié)! 過(guò)節(jié),成了身邊人重要的談資! 今天,是一帶一路高峰論壇第一天! 帶路藍(lán),成了人們口中的...
    槑頭槑腦兒閱讀 464評(píng)論 5 10
  • 車在高速路上高速行使 我輕握方向盤(pán) 駕馭著車的方向 我可以掌控車的速度 卻無(wú)法控制思維的蔓延 車?yán)锏囊魳?lè)觸動(dòng)了我的...
    靜若青蓮閱讀 289評(píng)論 12 38

友情鏈接更多精彩內(nèi)容