測開必知:Docker 從入門到精通(新手大全)!

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

1.5 Docker 技術的基礎:
namespace,容器隔離的基礎,保證A容器看不到B容器. 6個名空間:User,Mnt,Network,UTS,IPC,Pid cgroups,容器資源統(tǒng)計和隔離。主要用到的cgroups子系統(tǒng):cpu,blkio,device,freezer,memory unionfs,典型:aufs/overlayfs,分層鏡像實現(xiàn)的基礎
1.6 Docker 組件
docker Client客戶端 -->向docker服務器進程發(fā)起請求,如:創(chuàng)建、停止、銷毀容器等操作 docker Server服務器進程 -->處理所有docker的請求,管理所有容器 docker Registry鏡像倉庫 -->鏡像存放的中央倉庫,可看作是存放二進制的scm
二、安裝部署
2.1 準備條件
2.2 安裝 Docker
yum install docker -y #安裝systemctl start docker #啟動systemctl enable docker #設置開機自啟動
2.3 基本命令
docker search centos #搜索鏡像默認從國外拉去,速度很慢,可以使用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)建一個容器但是不啟動它docker run # 創(chuàng)建并啟動一個容器docker stop # 停止容器運行,發(fā)送信號SIGTERMdocker start # 啟動一個停止狀態(tài)的容器docker restart # 重啟一個容器docker rm # 刪除一個容器docker kill # 發(fā)送信號給容器,默認SIGKILLdocker attach # 連接(進入)到一個正在運行的容器docker wait # 阻塞一個容器,直到容器停止運行
獲取容器信息:
docker ps # 顯示狀態(tài)為運行(Up)的容器docker ps -a # 顯示所有容器,包括運行中(Up)的和退出的(Exited)docker inspect # 深入容器內(nèi)部獲取容器所有信息docker logs # 查看容器的日志(stdout/stderr)docker events # 得到docker服務器的實時的事件docker port # 顯示容器的端口映射docker top # 顯示容器的進程信息docker diff # 顯示容器文件系統(tǒng)的前后變化
導出容器:
docker exec # 在容器里執(zhí)行一個命令,可以執(zhí)行bash進入交互式執(zhí)行:
docker exec # 在容器里執(zhí)行一個命令,可以執(zhí)行bash進入交互式2.5 簡單實踐操作
運行并進入容器操作:
docker run -i -t docker.io/1832990/centos6.5 /bin/bash-t 表示在新容器內(nèi)指定一個偽終端或終端; -i 表示允許我們對容器內(nèi)的 (STDIN) 進行交互; -d 表示將容器在后臺運行; /bin/bash 。這將在容器內(nèi)啟動 bash shell;
所以當容器(container)啟動之后,我們會獲取到一個命令提示符:

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

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


docker save -o centos6.5.tar centos6.5 或docker export f9c99092063c >centos6.5.tar
從本地將鏡像導入:
docker load --input centos6.5.tar 或docker load < centos6.5.tar
docker rm刪除已經(jīng)終止的容器docker -f rm 可以刪除正在運行的容器
修改已經(jīng)運行的后臺容器:
docker exec -it CONTAINER ID /bin/bash
三、存儲
3.1 數(shù)據(jù)盤
Docker 的鏡像使用一層一層文件組成的,Docker 的一些存儲引擎可以處理怎么樣存儲這些文件。
docker inspect centos #查看容器詳細信息信息下方的Layers,就是centos的文件,這些東西都是只讀的不能去修改,我們基于這個鏡像去創(chuàng)建的鏡像和容器也會共享這些文件層,而docker會在這些層上面去添加一個可讀寫的文件層。
如果需要修改一些文件層里面的東西的話,docker會復制一份到這個可讀寫的文件層里面,如果刪除容器的話,那么也會刪除它對應的可讀寫的文件層的文件。
如果有些數(shù)據(jù)你想一直保存的話,比如:web服務器上面的日志,數(shù)據(jù)庫管理系統(tǒng)里面的數(shù)據(jù),那么我們可以把這些數(shù)據(jù)放到data volumes數(shù)據(jù)盤里面。
它上面的數(shù)據(jù),即使把容器刪掉,也還是會永久保留。創(chuàng)建容器的時候,我們可以去指定數(shù)據(jù)盤。其實就是去指定一個特定的目錄。
docker run -i -t -v /mnt --name nginx docker.io/nginx /bin/bash-v:制定掛載到容器內(nèi)的目錄


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




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

3.3 數(shù)據(jù)盤管理
在刪除容器時,docker默認不會刪除其數(shù)據(jù)盤。
docker volume ls #查看數(shù)據(jù)盤docker volume ls -f dangling=true #查看未被容器使用的數(shù)據(jù)盤docker volume rm VOLUME NAME #刪除數(shù)據(jù)盤
如果想要刪除容器時,同時刪除掉其數(shù)據(jù)盤,那么可以使用-v參數(shù)。
docker rm -v newnginx四、網(wǎng)絡
docker提供幾種網(wǎng)絡,它決定容器之間和外界和容器之間如何去相互通信。
docker network ls #查看網(wǎng)絡
虛擬網(wǎng)橋的工作方式和物理交換機類似,這樣主機上的所有容器就通過交換機連在了一個二層網(wǎng)絡中。從docker0子網(wǎng)中分配一個IP給容器使用,并設置docker0的IP地址為容器的默認網(wǎng)關。
4.1 bridge橋接
網(wǎng)絡除非創(chuàng)建容器的時候指定網(wǎng)絡,不然容器就會默認的使用橋接網(wǎng)絡。屬于這個網(wǎng)絡的容器之間可以相互通信,不過外界想要訪問到這個網(wǎng)絡的容器呢,需使用橋接網(wǎng)絡,有點像主機和容器之間的一座橋,對容器有一點隔離作用。
4.2 host 主機網(wǎng)絡
但是,容器的其他方面,如文件系統(tǒng)、進程列表等還是和宿主機隔離的。只用這種網(wǎng)絡的容器會使用主機的網(wǎng)絡,這種網(wǎng)絡對外界是完全開放的,能夠訪問到主機,就能訪問到容器。
4.3 使用 none 模式
使用none模式Docker容器擁有自己的Network Namespace,但是,并不為Docker容器進行任何網(wǎng)絡配置。也就是說,這個Docker容器沒有網(wǎng)卡、IP、路由等信息。需要我們自己為Docker容器添加網(wǎng)卡、配置IP等。使用此種網(wǎng)絡的容器會完全隔離。
4.4 簡單演示
啟動兩個容器,查看其容器內(nèi)部IP地址
for i in `docker ps |grep -v "CONTAINER"|awk '{print $1}'`;do docker inspect $i|grep 'IPAddress';done查看橋接模式下主機內(nèi)部容器之間和容器與宿主機直接均可正常通訊

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

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

docker run -d -p 80:80 docker.io/sergeyzh/centos6-nginx #將宿主機的80端口映射到容器的80端口原文鏈接:https://juejin.im/post/5c491406e51d4518c1551fd6
推薦閱讀:
END

長按二維碼/微信掃碼 添加作者


