Docker 從入門到實(shí)戰(zhàn),收藏起來(lái)有備無(wú)患~
一、概述
1.1 基本概念
Docker 是一個(gè)開(kāi)源的應(yīng)用容器引擎,基于 Go 語(yǔ)言 ? 并遵從 Apache2.0 協(xié)議開(kāi)源。
Docker 可以讓開(kāi)發(fā)者打包他們的應(yīng)用以及依賴包到一個(gè)輕量級(jí)、可移植的容器中,然后發(fā)布到任何流行的 Linux 機(jī)器上,也可以實(shí)現(xiàn)虛擬化。
1.2 優(yōu)勢(shì)
1.3 與傳統(tǒng)VM特性對(duì)比:
作為一種輕量級(jí)的虛擬化方式,Docker在運(yùn)行應(yīng)用上跟傳統(tǒng)的虛擬機(jī)方式相比具有顯著優(yōu)勢(shì):
Docker 容器很快,啟動(dòng)和停止可以在秒級(jí)實(shí)現(xiàn),這相比傳統(tǒng)的虛擬機(jī)方式要快得多。 Docker 容器對(duì)系統(tǒng)資源需求很少,一臺(tái)主機(jī)上可以同時(shí)運(yùn)行數(shù)千個(gè)Docker容器。 Docker 通過(guò)類似Git的操作來(lái)方便用戶獲取、分發(fā)和更新應(yīng)用鏡像,指令簡(jiǎn)明,學(xué)習(xí)成本較低。 Docker 通過(guò)Dockerfile配置文件來(lái)支持靈活的自動(dòng)化創(chuàng)建和部署機(jī)制,提高工作效率。 Docker 容器除了運(yùn)行其中的應(yīng)用之外,基本不消耗額外的系統(tǒng)資源,保證應(yīng)用性能的同時(shí),盡量減小系統(tǒng)開(kāi)銷。 Docker 利用Linux系統(tǒng)上的多種防護(hù)機(jī)制實(shí)現(xiàn)了嚴(yán)格可靠的隔離。從1.3版本開(kāi)始,Docker引入了安全選項(xiàng)和鏡像簽名機(jī)制,極大地提高了使用Docker的安全性。
| 特性 | 容器 | 虛擬機(jī) |
|---|---|---|
| 啟動(dòng)速度 | 秒級(jí) | 分鐘級(jí) |
| 硬盤使用 | 一般為MB | 一般為GB |
| 性能 | 接近原生 | 弱于原生 |
| 系統(tǒng)支持量 | 單機(jī)支持上千個(gè)容器 | 一般幾十個(gè) |
1.4 基礎(chǔ)架構(gòu)
| 容器 | 對(duì)象 |
|---|---|
| 鏡像 | 類 |

1.5 Docker 技術(shù)的基礎(chǔ):
namespace,容器隔離的基礎(chǔ),保證A容器看不到B容器. 6個(gè)名空間:User,Mnt,Network,UTS,IPC,Pid cgroups,容器資源統(tǒng)計(jì)和隔離。主要用到的cgroups子系統(tǒng):cpu,blkio,device,freezer,memory unionfs,典型:aufs/overlayfs,分層鏡像實(shí)現(xiàn)的基礎(chǔ)
1.6 Docker 組件
docker Client客戶端 -->向docker服務(wù)器進(jìn)程發(fā)起請(qǐng)求,如:創(chuàng)建、停止、銷毀容器等操作 docker Server服務(wù)器進(jìn)程 -->處理所有docker的請(qǐng)求,管理所有容器 docker Registry鏡像倉(cāng)庫(kù) -->鏡像存放的中央倉(cāng)庫(kù),可看作是存放二進(jìn)制的scm
二、安裝部署
2.1 準(zhǔn)備條件
2.2 安裝 Docker
yum install docker -y #安裝systemctl start docker #啟動(dòng)systemctl enable docker #設(shè)置開(kāi)機(jī)自啟動(dòng)
2.3 基本命令
docker search centos #搜索鏡像
默認(rèn)從國(guó)外拉去,速度很慢,可以使用daocloud配置加速
curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://d6f11267.m.daocloud.io腳本是寫入echo "{\"registry-mirrors\": [\"http://d6f11267.m.daocloud.io\"]}"> /etc/docker/daemon.jsonsystemctl restart docker #重啟失效

根據(jù)需求拉取鏡像:
docker pull docker.io/ansible/centos7-ansible
拉去search到的全部鏡像:
for i in `docker search centos|awk '!/NAME/{print $2}'`;do docker pull $i;done
查看本地鏡像:
docker images

2.4 命令整理
容器操作:
docker create # 創(chuàng)建一個(gè)容器但是不啟動(dòng)它docker run # 創(chuàng)建并啟動(dòng)一個(gè)容器docker stop # 停止容器運(yùn)行,發(fā)送信號(hào)SIGTERMdocker start # 啟動(dòng)一個(gè)停止?fàn)顟B(tài)的容器docker restart # 重啟一個(gè)容器docker rm # 刪除一個(gè)容器docker kill # 發(fā)送信號(hào)給容器,默認(rèn)SIGKILLdocker attach # 連接(進(jìn)入)到一個(gè)正在運(yùn)行的容器docker wait # 阻塞一個(gè)容器,直到容器停止運(yùn)行
獲取容器信息:
docker ps # 顯示狀態(tài)為運(yùn)行(Up)的容器docker ps -a # 顯示所有容器,包括運(yùn)行中(Up)的和退出的(Exited)docker inspect # 深入容器內(nèi)部獲取容器所有信息docker logs # 查看容器的日志(stdout/stderr)docker events # 得到docker服務(wù)器的實(shí)時(shí)的事件docker port # 顯示容器的端口映射docker top # 顯示容器的進(jìn)程信息docker diff # 顯示容器文件系統(tǒng)的前后變化
導(dǎo)出容器:
docker exec # 在容器里執(zhí)行一個(gè)命令,可以執(zhí)行bash進(jìn)入交互式
執(zhí)行:
docker exec # 在容器里執(zhí)行一個(gè)命令,可以執(zhí)行bash進(jìn)入交互式
2.5 簡(jiǎn)單實(shí)踐操作
運(yùn)行并進(jìn)入容器操作:
docker run -i -t docker.io/1832990/centos6.5 /bin/bash
-t 表示在新容器內(nèi)指定一個(gè)偽終端或終端; -i 表示允許我們對(duì)容器內(nèi)的 (STDIN) 進(jìn)行交互; -d 表示將容器在后臺(tái)運(yùn)行; /bin/bash 。這將在容器內(nèi)啟動(dòng) bash shell;
所以當(dāng)容器(container)啟動(dòng)之后,我們會(huì)獲取到一個(gè)命令提示符:

在容器內(nèi)我們安裝MySQL并設(shè)置開(kāi)機(jī)自啟動(dòng),將修改后的鏡像提交:
docker ps -l 查詢?nèi)萜鱅Ddocker commit -m "功能" -a "用戶信息" ID tag 提交修改后的鏡像

docker inspect ID 查看詳細(xì)信息docker push ID 上傳docker鏡像
利用DockerFile創(chuàng)建鏡像
mkdir DockerFilecd DockerFilecat > Dockerfile <FROM 603dd3515fccMAINTAINER Docker xuelRUN yum install mysql mysql-server -yRUN mddir /etc/sysconfig/networkRUN /etc/init.d/mysqld startEOF
docker build -t "centos6.8:mysqld" .
-t 制定repository 與tag
. 指定Dockerfile的路徑
注意一個(gè)鏡像不能超過(guò) 127 層
此外,還可以利用 ADD 命令復(fù)制本地文件到鏡像;
用 EXPOSE 命令來(lái)向外部開(kāi)放端口;
用 CMD 命令來(lái)描述容器啟動(dòng)后運(yùn)行的程序等。
CMD [“/usr/sbin/apachectl”, “-D”, “FOREGROUND”]
2.6 Dockerfile 詳解
FROM(指定基礎(chǔ)image)
該指令有兩種格式:
FROM#指定基礎(chǔ)image為該image的最后修改的版本 FROM: #指定基礎(chǔ)image為該image的一個(gè)tag版本。
MAINTAINER(用來(lái)指定鏡像創(chuàng)建者信息)
MAINTAINER
RUN(安裝軟件用)
RUN(the command is run in a shell - `/bin/sh -c`) RUN ["executable", "param1", "param2" ... ] (exec form)
CMD(設(shè)置container啟動(dòng)時(shí)執(zhí)行的操作)
CMD ["executable","param1","param2"] (like an exec, this is the preferred form)CMD command param1 param2 (as a shell)
ENTRYPOINT 指定的是一個(gè)可執(zhí)行的腳本或者程序的路徑,該指定的腳本或者程序?qū)?huì)以 param1 和param2作為參數(shù)執(zhí)行。
CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
ENTRYPOINT(設(shè)置container啟動(dòng)時(shí)執(zhí)行的操作)
設(shè)置指令,指定容器啟動(dòng)時(shí)執(zhí)行的命令,可以多次設(shè)置,但是只有最后一個(gè)有效。
ENTRYPOINT ["executable", "param1", "param2"] (like an exec, the preferred form)ENTRYPOINT command param1 param2 (as a shell)
該指令的使用分為兩種情況,一種是獨(dú)自使用,另一種和CMD指令配合使用。
# CMD指令將不會(huì)被執(zhí)行,只有ENTRYPOINT指令被執(zhí)行CMD echo “Hello, World!”ENTRYPOINT ls -l
FROM ubuntuCMD ["-l"]ENTRYPOINT ["/usr/bin/ls"]
USER(設(shè)置container容器的用戶)
設(shè)置指令,設(shè)置啟動(dòng)容器的用戶,默認(rèn)是root用戶
# 指定memcached的運(yùn)行用戶ENTRYPOINT ["memcached"]USER daemon或ENTRYPOINT ["memcached", "-u", "daemon"]
EXPOSE(指定容器需要映射到宿主機(jī)器的端口)
# 映射一個(gè)端口EXPOSE port1# 相應(yīng)的運(yùn)行容器使用的命令 (主機(jī)(宿主)端口:容器端口)docker run -p port1 image# 映射多個(gè)端口EXPOSE port1 port2 port3# 相應(yīng)的運(yùn)行容器使用的命令docker run -p port1 -p port2 -p port3 image# 還可以指定需要映射到宿主機(jī)器上的某個(gè)端口號(hào)docker run -p host_port1:port1 -p host_port2:port2 -p host_port3:port3 image
ENV(用于設(shè)置環(huán)境變量)
構(gòu)建指令,在image中設(shè)置一個(gè)環(huán)境變量。
ENV
ENV JAVA_HOME /path/to/java/dirent
ADD(從src復(fù)制文件到container的dest路徑)
如果是一個(gè)目錄,那么會(huì)將該目錄下的所有文件添加到container中,不包括目錄;如果文件是可識(shí)別的壓縮格式,則docker會(huì)幫忙解壓縮(注意壓縮格式);
如果是文件且中不使用斜杠結(jié)束,則會(huì)將視為文件,的內(nèi)容會(huì)寫入;
是文件且中使用斜杠結(jié)束,則會(huì)文件拷貝到目錄下。ADD
VOLUME(指定掛載點(diǎn))
設(shè)置指令,使容器中的一個(gè)目錄具有持久化存儲(chǔ)數(shù)據(jù)的功能,該目錄可以被容器本身使用,也可以共享給其他容器使用。
我們知道容器使用的是AUFS,這種文件系統(tǒng)不能持久化數(shù)據(jù),當(dāng)容器關(guān)閉后,所有的更改都會(huì)丟失。當(dāng)容器中的應(yīng)用有持久化數(shù)據(jù)的需求時(shí)可以在Dockerfile中使用該指令。
FROM baseVOLUME ["/tmp/data"]
WORKDIR(切換目錄)
設(shè)置指令,可以多次切換(相當(dāng)于cd命令),對(duì)RUN,CMD,ENTRYPOINT生效。
# 在 /p1/p2 下執(zhí)行 vim a.txtWORKDIR /p1 WORKDIR p2 RUN vim a.txt
2.7 鏡像導(dǎo)入導(dǎo)出


docker save -o centos6.5.tar centos6.5 或docker export f9c99092063c >centos6.5.tar
從本地將鏡像導(dǎo)入:
docker load --input centos6.5.tar 或docker load < centos6.5.tar
docker rm刪除已經(jīng)終止的容器docker -f rm 可以刪除正在運(yùn)行的容器
修改已經(jīng)運(yùn)行的后臺(tái)容器:
docker exec -it CONTAINER ID /bin/bash

三、存儲(chǔ)
3.1 數(shù)據(jù)盤
Docker 的鏡像使用一層一層文件組成的,Docker 的一些存儲(chǔ)引擎可以處理怎么樣存儲(chǔ)這些文件。
docker inspect centos #查看容器詳細(xì)信息
信息下方的Layers,就是centos的文件,這些東西都是只讀的不能去修改,我們基于這個(gè)鏡像去創(chuàng)建的鏡像和容器也會(huì)共享這些文件層,而docker會(huì)在這些層上面去添加一個(gè)可讀寫的文件層。
如果需要修改一些文件層里面的東西的話,docker會(huì)復(fù)制一份到這個(gè)可讀寫的文件層里面,如果刪除容器的話,那么也會(huì)刪除它對(duì)應(yīng)的可讀寫的文件層的文件。
如果有些數(shù)據(jù)你想一直保存的話,比如:web服務(wù)器上面的日志,數(shù)據(jù)庫(kù)管理系統(tǒng)里面的數(shù)據(jù),那么我們可以把這些數(shù)據(jù)放到data volumes數(shù)據(jù)盤里面。
它上面的數(shù)據(jù),即使把容器刪掉,也還是會(huì)永久保留。創(chuàng)建容器的時(shí)候,我們可以去指定數(shù)據(jù)盤。其實(shí)就是去指定一個(gè)特定的目錄。
docker run -i -t -v /mnt --name nginx docker.io/nginx /bin/bash
-v:制定掛載到容器內(nèi)的目錄


同樣,我們可以使用將制定物理宿主機(jī)的目錄掛載到容器的制定目錄下:
將宿主機(jī)目錄掛載到容器內(nèi):
docker run -d -p 80:80 --name nginx -v /webdata/wordpress:/usr/share/nginx/html docker.io/sergeyzh/centos6-nginx
-d 后臺(tái)運(yùn)行
—name 給運(yùn)行的容器命名
-v 宿主機(jī)目錄:容器目錄 將宿主機(jī)目錄掛載在容器內(nèi)
-p 宿主機(jī)端口:容器監(jiān)聽(tīng)端口 將容器內(nèi)應(yīng)用監(jiān)聽(tīng)端口映射到物理宿主機(jī)的特定端口上




3.2 數(shù)據(jù)容器
首先創(chuàng)建一個(gè)數(shù)據(jù)容器命名為newnginx
docker create -v /mnt -it --name newnginx docker.io/nginx /bin/bash
利用此數(shù)據(jù)容器容器運(yùn)行一個(gè)容器nginx1,在數(shù)據(jù)目錄/mnt 下創(chuàng)建一個(gè)文件
docker run --volumes-from newnginx --name nginx1 -it docker.io/nginx /bin/bash利用數(shù)據(jù)容器在創(chuàng)建一個(gè)容器nginx2,查看數(shù)據(jù)目錄下容器nginx1創(chuàng)建的文件依舊存在,同理在nginx2的/mnt下創(chuàng)建文件,其他基于數(shù)據(jù)容器運(yùn)行的新容器也可以看到文件

3.3 數(shù)據(jù)盤管理
在刪除容器時(shí),docker默認(rèn)不會(huì)刪除其數(shù)據(jù)盤。
docker volume ls #查看數(shù)據(jù)盤docker volume ls -f dangling=true #查看未被容器使用的數(shù)據(jù)盤docker volume rm VOLUME NAME #刪除數(shù)據(jù)盤
如果想要?jiǎng)h除容器時(shí),同時(shí)刪除掉其數(shù)據(jù)盤,那么可以使用-v參數(shù)。
docker rm -v newnginx
四、網(wǎng)絡(luò)
docker提供幾種網(wǎng)絡(luò),它決定容器之間和外界和容器之間如何去相互通信。
docker network ls #查看網(wǎng)絡(luò)

虛擬網(wǎng)橋的工作方式和物理交換機(jī)類似,這樣主機(jī)上的所有容器就通過(guò)交換機(jī)連在了一個(gè)二層網(wǎng)絡(luò)中。從docker0子網(wǎng)中分配一個(gè)IP給容器使用,并設(shè)置docker0的IP地址為容器的默認(rèn)網(wǎng)關(guān)。
4.1 bridge橋接
網(wǎng)絡(luò)除非創(chuàng)建容器的時(shí)候指定網(wǎng)絡(luò),不然容器就會(huì)默認(rèn)的使用橋接網(wǎng)絡(luò)。屬于這個(gè)網(wǎng)絡(luò)的容器之間可以相互通信,不過(guò)外界想要訪問(wèn)到這個(gè)網(wǎng)絡(luò)的容器呢,需使用橋接網(wǎng)絡(luò),有點(diǎn)像主機(jī)和容器之間的一座橋,對(duì)容器有一點(diǎn)隔離作用。
4.2 host 主機(jī)網(wǎng)絡(luò)
但是,容器的其他方面,如文件系統(tǒng)、進(jìn)程列表等還是和宿主機(jī)隔離的。只用這種網(wǎng)絡(luò)的容器會(huì)使用主機(jī)的網(wǎng)絡(luò),這種網(wǎng)絡(luò)對(duì)外界是完全開(kāi)放的,能夠訪問(wèn)到主機(jī),就能訪問(wèn)到容器。
4.3 使用 none 模式
使用none模式Docker容器擁有自己的Network Namespace,但是,并不為Docker容器進(jìn)行任何網(wǎng)絡(luò)配置。也就是說(shuō),這個(gè)Docker容器沒(méi)有網(wǎng)卡、IP、路由等信息。需要我們自己為Docker容器添加網(wǎng)卡、配置IP等。使用此種網(wǎng)絡(luò)的容器會(huì)完全隔離。
4.4 簡(jiǎn)單演示
啟動(dòng)兩個(gè)容器,查看其容器內(nèi)部IP地址
for i in `docker ps |grep -v "CONTAINER"|awk '{print $1}'`;do docker inspect $i|grep 'IPAddress';done
查看橋接模式下主機(jī)內(nèi)部容器之間和容器與宿主機(jī)直接均可正常通訊

docker inspect 容器ID

查看host創(chuàng)建的容器內(nèi)部沒(méi)有IP地址,它使用的為宿主機(jī)的地址:
docker run -d --net host docker.io/sergeyzh/centos6-nginx


docker run -d --net none docker.io/sergeyzh/centos6-nginx

4.5 容器端口
如果想讓外界可以訪問(wèn)到,基于bridge網(wǎng)絡(luò)創(chuàng)建的容器提供的服務(wù),那你可以告訴Docker 你要使用哪些接口。如果想查看鏡像會(huì)使用哪些端口,ExposedPorts,可以獲悉鏡像使用哪些端口。
docker run -d -p 80 docker.io/sergeyzh/centos6-nginxdocker port 09648b2ff7f6
-p 參數(shù)會(huì)在宿主機(jī)隨機(jī)映射一個(gè)高端口到容器內(nèi)的指定端口。

docker run -d -p 80:80 docker.io/sergeyzh/centos6-nginx #將宿主機(jī)的80端口映射到容器的80端口原文鏈接:https://juejin.im/post/5c491406e51d4518c1551fd6
轉(zhuǎn)自:高效運(yùn)維


