docker容器二探—docker網絡、存儲卷和Dockerfile
---------------------------------------------------------------------------------------------------------------------------------------------
一、docker網絡
建立一組虛拟網卡
一半在虛拟機或容器上,作為通信接口
另一半在主控端上,并且被關聯到一個標明的橋裝置
要想docker内的某個服務被外網通路,需要将該docker做dnat
容器之間雖然可以隔離,不過可以通過網絡回環連接配接起來
二、docker四種網絡模式
docker network ls

bridge:橋接網絡,docker0橋預設172.17.0.0/16網段,網關是172.17.0.1,NAT模式
host:共享主控端的網絡
none:回環網絡
注意:作為vmware主控端的windows應該可以ping通docker0,如果ping不通,windows以管理者身份運作cmd,添加路由:route add -p 172.17.0.0 mask 255.255.255.0 192.168.239.1
其中172.17.0.0是我docker0的網段,192.168.239.1是我windows連接配接vmware的ip
三、docker容器可加入的4種網絡示範:
1、封閉式容器,回環網絡,--net none
docker run --name bbox1 -it --network none busybox
進入ifconfig -a隻有lo網卡,是個完全式的隔離容器
2、橋接式網絡,--net bridge
docker run --name bbox -it --network bridge --rm busybox
docker run --name bbox2 -it --network bridge --rm busybox
進入互動界面兩個可以互ping通
3、聯盟式容器:獨立的運作空間,但底層網絡共享
還是剛才的網絡,退出bb2,此時bb2會自動被删除,繼續建立bb2,不過更換--net選項
docker run --namebb2 -it --net container:bb2
在bb1上執行以下指令
注:wget -O - -q:此指令可以将wget當做浏覽器使用,-O - 表示輸入到目前終端,-q 表示靜默輸出
4、容器之間共享主控端的網絡,監聽主控端IP位址
docker run --name bb2 -it --network host --rm busybox
在bb2上mkdir /data,vi /data/index.html,輸入内容,之後httpd -h /data,完成後在windows浏覽器輸入dokcer0的ip可以打開看到bb2編寫的index.html
四、暴露服務
示例
1、docker port :檢視docker端口
docker port -p 80
docker port tiny-web1
然後,32768是系統随機選擇的一個端口
2、docker容器内的80映射到主控端的11800,主控端的80不能被占用
docker run --name tiny-web11 --rm -p 11800:80 tiny-httpd:v0.0.5
如果是已建好鏡像添加端口映射,有兩種方法:
(1)将容器送出為鏡像,docker commit -a "container id" -m "a NEWIMAGE" web aaa:v1,之後再建立并添加端口(不推薦)
(2)修改/var/lib/docker/containers/CONTAINERID/hostconfig.json,CONTAINERID使用指令docker inspect NAME來檢視,
"PortBindings": {
"888/tcp": [
{
"HostIp": "",
"HostPort": "12888"
}
],
"21/tcp": [ #此行新添映射端口
"HostPort": "21"
]
}
這裡888是容器端口, 12888是本地端口
相同的目錄下找到config.v2.json,該檔案中有兩處需要修改
"ExposedPorts": {
"888/tcp": {},
"21/tcp": {}
"Ports": {
{
"HostIp": "0.0.0.0",
"HostPort": "12888"
}
"21/tcp": [ #此行新添映射端口
"HostPort": "21"
修改完重新開機docker服務,啟動docker容器
3、建立一個容器,容器80端口号映射到主控端172.20.0.66的8080端口上,該容器關閉後自動删除
4、一個容器映射多個端口
docker run --name tiny-web1 --rm -p 80 -p 445 -p 22 -p 139 httpd:2.4
三、docker network相關指令
docker network -h
1、docker network create -d bridge --gateway 10.0.0.1 --subnet 10.0.0.0/16 mynet0
改名 ifconfig br......down
ip link set br.... name docker1
docker run --name c1 --network mynet0 -it busybox,此時該容器就在mynet0網段
不過目前為止,更改名稱後無法建立docker,系統報錯找不到br-xxxxxxxx,但未改名稱就可以建立容器,之後有結果
2、将容器加入網絡
将容器上剝離網絡
3、移除網絡
docker network rm mynet0
四、docker的存儲卷
1、聯合挂載
關閉并重新開機容器,其資料不受影響,但删除Docker容器,則其修改的資料全部丢失
新增在可寫層新增
修改複制上一層到本層進行修改
删除給該檔案加隐藏标簽
是以所有操作不影響底層鏡像
2、資料卷特定:
容器之間可以共享資料卷,并且也可以重複利用
對于存儲卷的改變是直接儲存在資料卷上
當更新一個鏡像不會影響更改存儲卷
删除容器時并不會删除存儲卷
五、存儲卷類型
一個存儲器可以建立多個存儲卷,即-v多指定幾個
1、綁定挂載卷:手工建立容器的目錄與主控端目錄的對應關系
2、docker管理卷,非固定的動态卷,docker自行決定
docker run --name v1 -it -v /data busybox
-v指明容器内的路徑,不存在則自動建立
主控端docker volume ls可看到有主控端,看到VOLUMENAME
docker volume inspect VOLUMENAME,可以看到對應的路徑
docker container inspect bb1,檢視該容器卷目錄
删除容器後,存儲卷内容依然存在,此時如果用一個同樣的指令創造容器,将不會顯示存儲卷内容
3、删除容器後再建立一個同位于卷目錄的容器,容器内容依然存在,
4、如果建立多個容器,但它們的卷一樣,則這兩個容器共享存儲卷
或者複制使用其它容器的卷,使用指令--volumes-from
使用b2容器輸入指令
建立b4容器啟動後驗證
6、檢視container inspect資訊中,引用Mounts中的内容,.代表根
指令執行效果
注:一個存儲器可以用多個存儲卷,不過就是指令選項中多加幾次-v
六、配置容器化應用
1、docker run 時通過自定義要運作的指令,并向傳遞指令行參數,進而達到配置它的目的
docker run --name ap1 -it httpd:latest /bin/bash
2、自定義鏡像,将修改好的配置檔案直接寫進鏡像層,做成鏡像
3、通過環境變量更改配置
docker run -e
4、存儲卷,将/etc/目錄做成存儲卷,容器使用存儲卷啟動
5、容器應該對自己進行周期性健康狀态監測,并在不健康時通過restart自愈,或者其它操作來實作自愈的目的
七、Dockerfile注意點
Dockerfile是用來建立docker鏡像的源碼
1、第一條指令必須有FROM,需要基于基礎鏡像做,是以必須需要基礎鏡像
2、因為輸入一條指令鏡像便會啊向上生成一層,是以指令越少越好,能合成一條指令就不要用兩條三條來完成
3、容器中的指令隻基于基礎鏡像,和主控端作業系統無關
八、Dockfile格式
1、檔案格式
#後是注釋,否則就會認為是指令+參數的格式
指令使用全大寫,用來差別指令和參數
執行順序:自上而下依次執行,不支援判斷和循環
第一條指令必須用FROM 跟随基礎鏡像
2、環境變量
需要用ENV定義
定量表示:$variable_name或者${variarble_name}
${variable:-word},如果變量未聲明或為空,則傳回word的字元串值,即variable有值就傳回它,沒值就傳回word
${variable:+word},如果變量variable有值就傳回word,否則就為傳回空
3、dockerignore file
九、Dockerfile介紹
1、FROM IMAGE:VERSION
FROM IMAGE@校驗碼
2、LABEL <key>=<value> <key>=<value> <key>=<value> ...
LABEL maintainer="chenux <[email protected]>"
3、COPY
使用者從Docker主機複制檔案至建立的新映像檔案
COPY <src> <dest>
COPY ["<src>",... "<dest>"]
示例:
mkdir /docker
vim /docker/Dockerfile
FROM alpine:3.6
COPY virt.repo /etc/yum.repos.d/ ------->拷貝workdir内的檔案到容器内目錄下
COPY httpd /etc/httpd/ -------->複制目錄
cp /etc/yum.repos.d/virt.repo /docker
cp -r /etc/httpd /docker/
vim /docker/.dockerignore,排除複制時候拷貝的目錄
docker image build -t testapp:v0.0.1 /docker ------>建構根據Dockerfile做出配置的鏡像
啟動容器檢視
4、ADD類似于COPY指令,ADD支援使用TAR檔案和URL路徑,ADD自動将.tar檔案展開到容器目标目錄,将URL連結指向的檔案自動下載下傳到容器目錄
5、WORKDIR
(1)當容器内目錄太長時可用此選項,之後目标目錄的可以用相對路徑表示,為Dockerfile中所有的RUN、CMD、ENTRYPOINT、COPY和ADD指定設定工作目錄
(2)WORKDIR可使用多次,每次路徑的表示都以最近的WORKDIR為參考
6、VOLUME,不支援綁定挂載
用于在image中傳建一個挂載點目錄,以挂載Docker host上的卷或者其它容器上的卷
VOLUME <mountpoint>
VOLUME ["<mountpoint>"]
結果檢視
7、EXPOSE
用于指定要暴露的端口
EXPOSE 80/tcp 8080/tcp
docker build -t bbi .
docker container run --name bmw -it -P --rm bbi
-P,暴露對應的容器鏡像當中,暴露所有使用EXPOSE指令鏡像的端口
8、ENV
用于為鏡像定義所需的環境變量,-e選項用來傳遞環境變量
ENV <key> <value>或者
ENV <key>=<value>
9、RUN,位于docker build的階段中
用于指定docker build過程中運作的程式,這個程式可以是任何指令
RUN <command>
RUN ["<executable>","<param1>","<param2>"]
本着能執行一條指令,就不執行兩條指令的原則,可改成
結果
10、CMD,運作在docker container run階段中,RUN指令運作于映像檔案建構過程中,而CMD指令運作于基于Dockerfile建構出的新映像檔案啟動一個容器時
CMD <command>
CMD ["<executable>","<param1>","<param2>"]
CMD ["<param1>","<param2>"]
11、ENTRYPOINT,運作在docker container run階段中,用于為容器指定預設運作程式,進而使得容器像是一個單獨的可執行程式
ENTRYPOINT <command>
ENTRYPOINT ["<executable>","<param1>","<param2>"]
既有CMD,又有ENTRYPOINT的話,CMD的參數将會傳遞給ENTRYPOINT,如果ENTRYPOINT和CMD都有很多條,将以最後一條為準。二者同時有指令,會先執行ENTRYPOINT的,之後将CMD指令傳給ENTRYPOINT的結果
如果預設使用一個指令或者鏡像或者一個應用程式自身是不支援加載環境變量的,我們也能通過ENTRYPOINT腳本環境變量來擷取新配置
簡單舉例
Dockerfile中RUN、CMD、ENTRYPOINT差別:
1、RUN指令通常用于安裝應用和軟體包,在建構鏡像時就已經執行了指令
2、CMD指令允許使用者指定容器的預設執行的指令,此指令在容器啟動且開啟容器docker run沒有指定其它指令時運作,如果鏡像中寫入的是CMD httpd -f /data,而在啟動鏡像時用指令docker run --name xxx -it xx:xx /bin/bash,此時進入鏡像後/bin/bash便會覆寫掉CMD的指令httpd -f /data
3、ENTRYPOINT指令與CMD類似,隻不過它的指令不會被docker run指令後的參數覆寫
第2條說明示範:
CMD結果
第3條說明示範:
如果想覆寫ENTRYPOINT,加入--entrypoint
12、user
用于指定運作image時的或運作Dockerfile中任何RUN、CMD、ENTryPOINT指令指定的程式時的使用者名或UID
預設情況下,container的運作身份為root使用者
USER UID,UID必須為/etc/passwd中某使用者的有效UID
USER UserName
13、HEALTHCHECK
健康狀态監測
HEALTHCHECK [OPTIONS] CMD commad
--interval=30,預設30秒,間隔時長,每多長時間檢測一次
--timeout=30,逾時時長
--start-period=0,預設0秒,容器啟動多久後開始檢測
--retries=3,預設3此,重新嘗試次數
退出碼
0:success,容器健康
1:unhealthy,容器工作異常
2:reserved,不使用退出碼
舉例:
HEALTHCHECK --interval=5m --timeout=3s \
CMD curl -f http://localhost/ || exit 1
HEALTHCHECK NONE,不檢測健康狀态
14、SHELL,改變系統要調用的預設的shell程式,Linux預設["/bin/sh","-c"],windows預設["cmd","/S","/C"]
15、STOPIGNAL:停止信号
16、ARG,參數
17、ONBUILD,用于在Dockerfile中定義一個觸發器,鑲嵌在第二層中
示範有
将此作為鏡像trig:1後,在此目錄内繼續建立一個目錄,進入目錄并再寫一個Dockerfile,
之後建立鏡像trig:2,啟動後有
九、建立私有鏡像倉庫
1、yum -y install docker-registry,但包名叫做docker-distribution,查詢相關安裝路徑rpm -ql docker-distribution,預設5000端口
2、vim /etc/docker-distribution/registry/config.yml,配置docker-distrubution服務
3、配置好後systemctl start docker-distribution,修改标簽
此時直接推會報錯,因為registry需要https協定的位址
4、關閉本地registry倉庫的https安全要求,vim /etc/docker/daemon.json
儲存退出後systemctl restart docker,再推送就成功了
十、在docker容器安裝wordpress
1、由于wordpress已經被官方和熱心網友做成了鏡像,是以可以直接拿來使用
docker pull wordpress:4.9-php7.2-fpm-alpine,完成之後按照資料庫
2、開啟資料庫
docker run --name wpdb -d -v /data/mydata:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=chenux mysql:5.5.62
3、進入資料庫容器授權
建立wpuser使用者,對本機和網橋的裝置進行授權
4、因為容器每一次的通路ip都會改變,是以這裡最好指定容器的主機名
docker container run --name wordpress -d \
> -e WODPRESS_DB_HOST=localhost \
> -e WORDPRESS_DB_USER=wpuser \
> -e WORDPRESS_DB_PASSWORD=wppass \
> -e WORDPRESS_DB_NAME=wpdb \
> --network container:wpdb \
> wordpress:4.9-php7.2-fpm-alpine