一、概述
1.1 基本概念:
Docker 是一個開源的應用容器引擎,基于 Go 語言 并遵從Apache2.0協定開源。Docker 可以讓開發者打包他們的應用以及依賴包到一個輕量級、可移植的容器中,然後釋出到任何流行的 Linux 機器上,也可以實作虛拟化。容器是完全使用沙箱機制,互相之間不會有任何接口(類似 iPhone 的 app),更重要的是容器性能開銷極低。
1.2 優勢:
簡化程式:
Docker 讓開發者可以打包他們的應用以及依賴包到一個可移植的容器中,然後釋出到任何流行的 Linux 機器上,便可以實作虛拟化。Docker改變了虛拟化的方式,使開發者可以直接将自己的成果放入Docker中進行管理。友善快捷已經是 Docker的最大優勢,過去需要用數天乃至數周的 任務,在Docker容器的處理下,隻需要數秒就能完成。
節省開支:
一方面,雲計算時代到來,使開發者不必為了追求效果而配置高額的硬體,Docker 改變了高性能必然高價格的思維定勢。Docker 與雲的結合,讓雲空間得到更充分的利用。不僅解決了硬體管理的問題,也改變了虛拟化的方式。
1.3 與傳統VM特性對比:
作為一種輕量級的虛拟化方式,Docker在運作應用上跟傳統的虛拟機方式相比具有顯著優勢:
Docker容器很快,啟動和停止可以在秒級實作,這相比傳統的虛拟機方式要快得多。
Docker容器對系統資源需求很少,一台主機上可以同時運作數千個Docker容器。
Docker通過類似Git的操作來友善使用者擷取、分發和更新應用鏡像,指令簡明,學習成本較低。
Docker通過Dockerfile配置檔案來支援靈活的自動化建立和部署機制,提高工作效率。
Docker容器除了運作其中的應用之外,基本不消耗額外的系統資源,保證應用性能的同時,盡量減小系統開銷。
Docker利用Linux系統上的多種防護機制實作了嚴格可靠的隔離。從1.3版本開始,Docker引入了安全選項和鏡像簽名機制,極大地提高了使用Docker的安全性。
特性
容器
虛拟機
啟動速度
秒級
分鐘級
硬碟使用
一般為MB
一般為GB
性能
接近原生
弱于原生
系統支援量
單機支援上千個容器
一般幾十個
隔離性
安全隔離
完全隔離
1.4 基礎架構
Docker 使用用戶端-伺服器 (C/S) 架構模式,使用遠端API來管理和建立Docker容器。
Docker 容器通過 Docker 鏡像來建立。
容器與鏡像的關系類似于面向對象程式設計中的對象與類。
Docker
面向對象
容器
對象
鏡像
類
<a href="https://s4.51cto.com/oss/201711/03/de4146cd809a9f320512b316ed5e4570.png" target="_blank"></a>
1.5 Docker技術的基礎:
namespace,容器隔離的基礎,保證A容器看不到B容器. 6個名空間:User,Mnt,Network,UTS,IPC,Pid
cgroups,容器資源統計和隔離。主要用到的cgroups子系統:cpu,blkio,device,freezer,memory
unionfs,典型:aufs/overlayfs,分層鏡像實作的基礎
1.6 Docker元件:
docker Client用戶端————>向docker伺服器程序發起請求,如:建立、停止、銷毀容器等操作
docker Server伺服器程序—–>處理所有docker的請求,管理所有容器
docker Registry鏡像倉庫——>鏡像存放的中央倉庫,可看作是存放二進制的scm
二、安裝部署
2.1 準備條件
目前,CentOS 僅發行版本中的核心支援 Docker。
Docker 運作在 CentOS 7 上,要求系統為64位、系統核心版本為 3.10 以上。
Docker 運作在 CentOS-6.5 或更高的版本的 CentOS 上,要求系統為64位、系統核心版本2.6.32-431 或者更高版本。
2.2 安裝docker
1
2
3
<code>yum </code><code>install</code> <code>docker -y </code><code>#安裝</code>
<code>systemctl start docker </code><code>#啟動 </code>
<code>systemctl </code><code>enable</code> <code>docker </code><code>#設定開機自啟動</code>
2.3 基本指令
<code>docker search centos </code><code>#搜尋鏡像</code>
預設從國外拉去,速度很慢,可以使用daocloud配置加速
4
<code> </code><code>curl -sSL https:</code><code>//get</code><code>.daocloud.io</code><code>/daotools/set_mirror</code><code>.sh | sh -s http:</code><code>//d6f11267</code><code>.m.daocloud.io</code>
<code>腳本是寫入</code>
<code>echo</code> <code>"{\"registry-mirrors\": [\"http://d6f11267.m.daocloud.io\"]}"</code><code>> </code><code>/etc/docker/daemon</code><code>.json</code>
<code>systemctl restart docker </code><code>#重新開機失效</code>
<a href="https://s5.51cto.com/oss/201711/03/584a343d165a20c2f995d00e63b73342.png" target="_blank"></a>
根據需求拉取鏡像:
<code>docker pull docker.io</code><code>/ansible/centos7-ansible</code>
拉去search到的全部鏡像:
<code>for</code> <code>i </code><code>in</code> <code>`docker search centos|</code><code>awk</code> <code>'!/NAME/{print $2}'</code><code>`;</code><code>do</code> <code>docker pull $i;</code><code>done</code>
檢視本地鏡像:
<code>docker images</code>
<a href="https://s5.51cto.com/oss/201711/03/a5970eaa0596c0531afaadc340b34cff.png" target="_blank"></a>
2.4 指令整理:
容器操作:
5
6
7
8
9
<code>docker create </code><code># 建立一個容器但是不啟動它</code>
<code>docker run </code><code># 建立并啟動一個容器</code>
<code>docker stop </code><code># 停止容器運作,發送信号SIGTERM</code>
<code>docker start </code><code># 啟動一個停止狀态的容器</code>
<code>docker restart </code><code># 重新開機一個容器</code>
<code>docker </code><code>rm</code> <code># 删除一個容器</code>
<code>docker </code><code>kill</code> <code># 發送信号給容器,預設SIGKILL</code>
<code>docker attach </code><code># 連接配接(進入)到一個正在運作的容器</code>
<code>docker wait </code><code># 阻塞一個容器,直到容器停止運作</code>
擷取容器資訊:
<code>docker </code><code>ps</code> <code># 顯示狀态為運作(Up)的容器</code>
<code>docker </code><code>ps</code> <code>-a </code><code># 顯示所有容器,包括運作中(Up)的和退出的(Exited)</code>
<code>docker inspect </code><code># 深入容器内部擷取容器所有資訊</code>
<code>docker logs </code><code># 檢視容器的日志(stdout/stderr)</code>
<code>docker events </code><code># 得到docker伺服器的實時的事件</code>
<code>docker port </code><code># 顯示容器的端口映射</code>
<code>docker </code><code>top</code> <code># 顯示容器的程序資訊</code>
<code>docker </code><code>diff</code> <code># 顯示容器檔案系統的前後變化</code>
導出容器:
<code>docker </code><code>cp</code> <code># 從容器裡向外拷貝檔案或目錄</code>
<code>docker </code><code>export</code> <code># 将容器整個檔案系統導出為一個tar包,不帶layers、tag等資訊</code>
執行:
<code>docker </code><code>exec</code> <code># 在容器裡執行一個指令,可以執行bash進入互動式</code>
鏡像操作:
<code>docker images </code><code># 顯示本地所有的鏡像清單</code>
<code>docker </code><code>import</code> <code># 從一個tar包建立一個鏡像,往往和export結合使用</code>
<code>docker build </code><code># 使用Dockerfile建立鏡像(推薦)</code>
<code>docker commit </code><code># 從容器建立鏡像</code>
<code>docker rmi </code><code># 删除一個鏡像</code>
<code>docker load </code><code># 從一個tar包建立一個鏡像,和save配合使用</code>
<code>docker save </code><code># 将一個鏡像儲存為一個tar包,帶layers和tag資訊</code>
<code>docker </code><code>history</code> <code># 顯示生成一個鏡像的曆史指令</code>
<code>docker tag </code><code># 為鏡像起一個别名</code>
鏡像倉庫(registry)操作:
<code>docker login </code><code># 登入到一個registry</code>
<code>docker search </code><code># 從registry倉庫搜尋鏡像</code>
<code>docker pull </code><code># 從倉庫下載下傳鏡像到本地</code>
<code>docker push </code><code># 将一個鏡像push到registry倉庫中</code>
2.5 簡單實踐操作
運作并進入容器操作:
<code>docker run -i -t docker.io</code><code>/1832990/centos6</code><code>.5 </code><code>/bin/bash</code>
-t 表示在新容器内指定一個僞終端或終端;
-i表示允許我們對容器内的 (STDIN) 進行互動;
-d表示将容器在背景運作;
/bin/bash 。這将在容器内啟動 bash shell;
是以當容器(container)啟動之後,我們會擷取到一個指令提示符:
<a href="https://s5.51cto.com/oss/201711/03/de50febadf6ddcbce18fc348b1ab0c0e.png" target="_blank"></a>
在容器内我們安裝mysql并設定開機自啟動,将修改後的鏡像送出:
<code>docker </code><code>ps</code> <code>-l 查詢容器ID</code>
<code>docker commit -m </code><code>"功能"</code> <code>-a </code><code>"使用者資訊"</code> <code>ID tag 送出修改後的鏡像</code>
<a href="https://s1.51cto.com/oss/201711/03/492c5f98644dc2e9b0a230bf69068311.png" target="_blank"></a>
<code>docker inspect ID 檢視詳細資訊</code>
<code>docker push ID 上傳docker鏡像</code>
利用DockerFile建立鏡像
使用指令 docker build , 需要建立一個 Dockerfile 檔案,其中包含一組指令來告訴 Docker 如何建構鏡像。
<code>mkdir</code> <code>DockerFile</code>
<code>cd</code> <code>DockerFile</code>
<code>cat</code> <code>> Dockerfile <<EOF</code>
<code>FROM 603dd3515fcc</code>
<code>MAINTAINER Docker xuel</code>
<code>RUN yum </code><code>install</code> <code>mysql mysql-server -y</code>
<code>RUN mddir </code><code>/etc/sysconfig/network</code>
<code>RUN </code><code>/etc/init</code><code>.d</code><code>/mysqld</code> <code>start</code>
<code>EOF</code>
<a href="https://s5.51cto.com/oss/201711/03/370397346f81e7b732c4ee2b9279def4.png" target="_blank"></a>
<code>docker build -t </code><code>"centos6.8:mysqld"</code> <code>.</code>
-t 制定repository 與tag
. 指定Dockerfile的路徑
注意一個鏡像不能超過 127 層
此外,還可以利用 ADD 指令複制本地檔案到鏡像;
用 EXPOSE 指令來向外部開放端口;
用 CMD 指令來描述容器啟動後運作的程式等。
CMD ["/usr/sbin/apachectl", "-D", "FOREGROUND"]
2.6 Dockerfile詳解
Dockerfile的指令是忽略大小寫的,建議使用大寫,使用 # 作為注釋,每一行隻支援一條指令,每條指令可以攜帶多個參數。
Dockerfile的指令根據作用可以分為兩種,建構指令和設定指令。
建構指令:用于建構image,其指定的操作不會在運作image的容器上執行;
設定指令:用于設定image的屬性,其指定的操作将在運作image的容器中執行。
FROM(指定基礎image)
建構指令,必須指定且需要在Dockerfile其他指令的前面。後續的指令都依賴于該指令指定的image。FROM指令指定的基礎image可以是官方遠端倉庫中的,也可以位于本地倉庫。
該指令有兩種格式:
<code>FROM <image> </code><code>#指定基礎image為該image的最後修改的版本</code>
<code>FROM <image>:<tag> </code><code>#指定基礎image為該image的一個tag版本。</code>
MAINTAINER(用來指定鏡像建立者資訊)
建構指令,用于将image的制作者相關的資訊寫入到image中。當我們對該image執行docker inspect指令時,輸出中有相應的字段記錄該資訊。
<code>MAINTAINER <name></code>
RUN(安裝軟體用)
建構指令,RUN可以運作任何被基礎image支援的指令。如基礎image選擇了ubuntu,那麼軟體管理部分隻能使用ubuntu的指令。
<code>RUN <</code><code>command</code><code>> (the </code><code>command</code> <code>is run </code><code>in</code> <code>a shell - `</code><code>/bin/sh</code> <code>-c`) </code>
<code>RUN [</code><code>"executable"</code><code>, </code><code>"param1"</code><code>, </code><code>"param2"</code> <code>... ] (</code><code>exec</code> <code>form)</code>
CMD(設定container啟動時執行的操作)
設定指令,用于container啟動時指定的操作。該操作可以是執行自定義腳本,也可以是執行系統指令。該指令隻能在檔案中存在一次,如果有多個,則隻執行最後一條。
<code>CMD [</code><code>"executable"</code><code>,</code><code>"param1"</code><code>,</code><code>"param2"</code><code>] (like an </code><code>exec</code><code>, this is the preferred form) </code>
<code>CMD </code><code>command</code> <code>param1 param2 (as a shell)</code>
ENTRYPOINT指定的是一個可執行的腳本或者程式的路徑,該指定的腳本或者程式将會以param1和param2作為參數執行。是以如果CMD指令使用上面的形式,那麼Dockerfile中必須要有配套的ENTRYPOINT。當Dockerfile指定了ENTRYPOINT,那麼使用下面的格式:
<code>CMD [</code><code>"param1"</code><code>,</code><code>"param2"</code><code>] (as default parameters to ENTRYPOINT)</code>
ENTRYPOINT(設定container啟動時執行的操作)
設定指令,指定容器啟動時執行的指令,可以多次設定,但是隻有最後一個有效。
<code>ENTRYPOINT [</code><code>"executable"</code><code>, </code><code>"param1"</code><code>, </code><code>"param2"</code><code>] (like an </code><code>exec</code><code>, the preferred form) </code>
<code>ENTRYPOINT </code><code>command</code> <code>param1 param2 (as a shell)</code>
該指令的使用分為兩種情況,一種是獨自使用,另一種和CMD指令配合使用。
當獨自使用時,如果你還使用了CMD指令且CMD是一個完整的可執行的指令,那麼CMD指令和ENTRYPOINT會互相覆寫隻有最後一個CMD或者ENTRYPOINT有效。
<code># CMD指令将不會被執行,隻有ENTRYPOINT指令被執行 </code>
<code>CMD </code><code>echo</code> <code>“Hello, World!” </code>
<code>ENTRYPOINT </code><code>ls</code> <code>-l</code>
另一種用法和CMD指令配合使用來指定ENTRYPOINT的預設參數,這時CMD指令不是一個完整的可執行指令,僅僅是參數部分;ENTRYPOINT指令隻能使用JSON方式指定執行指令,而不能指定參數。
<code>FROM ubuntu </code>
<code>CMD [</code><code>"-l"</code><code>] </code>
<code>ENTRYPOINT [</code><code>"/usr/bin/ls"</code><code>]</code>
USER(設定container容器的使用者)
設定指令,設定啟動容器的使用者,預設是root使用者
<code># 指定memcached的運作使用者 </code>
<code>ENTRYPOINT [</code><code>"memcached"</code><code>] </code>
<code>USER daemon </code>
<code>或 </code>
<code>ENTRYPOINT [</code><code>"memcached"</code><code>, </code><code>"-u"</code><code>, </code><code>"daemon"</code><code>]</code>
EXPOSE(指定容器需要映射到主控端器的端口)
設定指令,該指令會将容器中的端口映射成主控端器中的某個端口。當你需要通路容器的時候,可以不是用容器的IP位址而是使用主控端器的IP位址和映射後的端口。要完成整個操作需要兩個步驟,首先在Dockerfile使用EXPOSE設定需要映射的容器端口,然後在運作容器的時候指定-p選項加上EXPOSE設定的端口,這樣EXPOSE設定的端口号會被随機映射成主控端器中的一個端口号。也可以指定需要映射到主控端器的那個端口,這時要確定主控端器上的端口号沒有被使用。EXPOSE指令可以一次設定多個端口号,相應的運作容器的時候,可以配套的多次使用-p選項。
10
11
<code># 映射一個端口 </code>
<code>EXPOSE port1 </code>
<code># 相應的運作容器使用的指令 </code>
<code>docker run -p port1 image </code>
<code> </code>
<code># 映射多個端口 </code>
<code>EXPOSE port1 port2 port3 </code>
<code>docker run -p port1 -p port2 -p port3 image </code>
<code># 還可以指定需要映射到主控端器上的某個端口号 </code>
<code>docker run -p host_port1:port1 -p host_port2:port2 -p host_port3:port3 image</code>
端口映射是docker比較重要的一個功能,原因在于我們每次運作容器的時候容器的IP位址不能指定而是在橋接網卡的位址範圍内随機生成的。主控端器的IP位址是固定的,我們可以将容器的端口的映射到主控端器上的一個端口,免去每次通路容器中的某個服務時都要檢視容器的IP的位址。對于一個運作的容器,可以使用docker port加上容器中需要映射的端口和容器的ID來檢視該端口号在主控端器上的映射端口。
ENV(用于設定環境變量)
建構指令,在image中設定一個環境變量。
<code>ENV <key> <value></code>
設定了後,後續的RUN指令都可以使用,container啟動後,可以通過docker inspect檢視這個環境變量,也可以通過在docker run --env key=value時設定或修改環境變量。
假如你安裝了JAVA程式,需要設定JAVA_HOME,那麼可以在Dockerfile中這樣寫:
<code>ENV JAVA_HOME </code><code>/path/to/java/dirent</code>
ADD(從src複制檔案到container的dest路徑)
建構指令,所有拷貝到container中的檔案和檔案夾權限為0755,uid和gid為0;如果是一個目錄,那麼會将該目錄下的所有檔案添加到container中,不包括目錄;如果檔案是可識别的壓縮格式,則docker會幫忙解壓縮(注意壓縮格式);如果<src>是檔案且<dest>中不使用斜杠結束,則會将<dest>視為檔案,<src>的内容會寫入<dest>;如果<src>是檔案且<dest>中使用斜杠結束,則會<src>檔案拷貝到<dest>目錄下。
<code>ADD <src> <dest></code>
<src> 是相對被建構的源目錄的相對路徑,可以是檔案或目錄的路徑,也可以是一個遠端的檔案url;
<dest> 是container中的絕對路徑
VOLUME(指定挂載點)
設定指令,使容器中的一個目錄具有持久化存儲資料的功能,該目錄可以被容器本身使用,也可以共享給其他容器使用。我們知道容器使用的是AUFS,這種檔案系統不能持久化資料,當容器關閉後,所有的更改都會丢失。當容器中的應用有持久化資料的需求時可以在Dockerfile中使用該指令。
<code>FROM base </code>
<code>VOLUME [</code><code>"/tmp/data"</code><code>]</code>
WORKDIR(切換目錄)
設定指令,可以多次切換(相當于cd指令),對RUN,CMD,ENTRYPOINT生效。
<code># 在 /p1/p2 下執行 vim a.txt </code>
<code>WORKDIR </code><code>/p1</code> <code>WORKDIR p2 RUN vim a.txt</code>
2.7 鏡像導入導出
<a href="https://s3.51cto.com/oss/201711/03/7cf8917e844e1e50e23757cf08714b5a.png" target="_blank"></a>
導出鏡像到本地:
<a href="https://s1.51cto.com/oss/201711/03/98c9b4e84d6cfd09a8521039e0e5e9ad.png" target="_blank"></a>
<code>docker save -o centos6.5.</code><code>tar</code> <code>centos6.5 或</code>
<code>docker </code><code>export</code> <code>f9c99092063c >centos6.5.</code><code>tar</code>
從本地将鏡像導入:
<code>docker load --input centos6.5.</code><code>tar</code> <code>或 </code>
<code>docker load < centos6.5.</code><code>tar</code>
<a href="https://s3.51cto.com/oss/201711/03/d2bc592a3168c50ea6dfd809dad3c58c.png" target="_blank"></a>
<code>docker </code><code>rm</code><code>删除已經終止的容器</code>
<code>docker -f </code><code>rm</code> <code>可以删除正在運作的容器</code>
修改已經運作的背景容器:
<code>docker </code><code>exec</code> <code>-it CONTAINER ID </code><code>/bin/bash</code>
<a href="https://s5.51cto.com/oss/201711/06/9e258035ff6c1c09fd8a87410b77c316.png" target="_blank"></a>
三、存儲
3.1資料盤
docker的鏡像使用一層一層檔案組成的,docker的一些存儲引擎可以處理怎麼樣存儲這些檔案。
<code>docker inspect centos </code><code>#檢視容器詳細資訊</code>
資訊下方的Layers,就是centos的檔案,這些東西都是隻讀的不能去修改,我們基于這個鏡像去建立的鏡像和容器也會共享這些檔案層,而docker會在這些層上面去添加一個可讀寫的檔案層。如果需要修改一些檔案層裡面的東西的話,docker會複制一份到這個可讀寫的檔案層裡面,如果删除容器的話,那麼也會删除它對應的可讀寫的檔案層的檔案。
如果有些資料你想一直儲存的話,比如:web伺服器上面的日志,資料庫管理系統裡面的資料,那麼我們可以把這些資料放到data volumes資料盤裡面。它上面的資料,即使把容器删掉,也還是會永久保留。建立容器的時候,我們可以去指定資料盤。其實就是去指定一個特定的目錄。
<code>docker run -i -t -</code><code>v</code> <code>/mnt</code> <code>--name nginx docker.io</code><code>/nginx</code> <code>/bin/bash</code>
-v:制定挂載到容器内的目錄
<a href="https://s1.51cto.com/oss/201711/07/272c9f983d98694569447ad89df78dc2.png" target="_blank"></a>
使用docker inspect 容器ID可以檢視挂載目錄對應于主控端的實體檔案路徑
<a href="https://s1.51cto.com/oss/201711/07/2a6510c525616589c661aef41b3e985a.png" target="_blank"></a>
同樣,我們可以使用将制定實體主控端的目錄挂載到容器的制定目錄下:
将主控端目錄挂載到容器内:
<code>docker run -d -p 80:80 --name nginx -</code><code>v</code> <code>/webdata/wordpress</code><code>:</code><code>/usr/share/nginx/html</code> <code>docker.io</code><code>/sergeyzh/centos6-nginx</code>
-d 背景運作
--name 給運作的容器命名
-v 主控端目錄:容器目錄 将主控端目錄挂載在容器内
-p 主控端端口:容器監聽端口 将容器内應用監聽端口映射到實體主控端的特定端口上
<a href="https://s4.51cto.com/oss/201711/07/1577f28ec87c4e75ea9d71a9563c8417.png" target="_blank"></a>
<a href="https://s3.51cto.com/oss/201711/07/f8aee4bc4051778ba59e0c00d3f2bdf0.png" target="_blank"></a>
映射多個實體目錄:(多寫幾個-v即可)
<a href="https://s4.51cto.com/oss/201711/07/720666caee8fa6edac22ef6179febb65.png" target="_blank"></a>
<a href="https://s3.51cto.com/oss/201711/07/7d506a6000fd3bf06c0c3226fd9094ea.png" target="_blank"></a>
3.2 資料容器:
可以建立一個資料容器,也就是再建立容器是指定這個容器的資料盤,然後讓其他容器可以使用這個容器作為他們的資料盤,有點像繼承了這個資料容器指定的資料盤作為資料盤。
首先建立一個資料容器命名為newnginx
<code>docker create -</code><code>v</code> <code>/mnt</code> <code>-it --name newnginx docker.io</code><code>/nginx</code> <code>/bin/bash</code>
利用此資料容器容器運作一個容器nginx1,在資料目錄/mnt 下建立一個檔案
<code>docker run --volumes-from newnginx --name nginx1 -it docker.io</code><code>/nginx</code> <code>/bin/bash</code>
利用資料容器在建立一個容器nginx2,檢視資料目錄下容器nginx1建立的檔案依舊存在,同理在nginx2的/mnt下建立檔案,其他基于資料容器運作的新容器也可以看到檔案
<a href="https://s2.51cto.com/oss/201711/07/ae9d1b83d7cabde598433ef444c65daf.png" target="_blank"></a>
3.3 資料盤管理:
在删除容器時,docker預設不會删除其資料盤。
<code>docker volume </code><code>ls</code> <code>#檢視資料盤</code>
<code>docker volume </code><code>ls</code> <code>-f dangling=</code><code>true</code> <code>#檢視未被容器使用的資料盤</code>
<code>docker volume </code><code>rm</code> <code>VOLUME NAME </code><code>#删除資料盤</code>
<a href="https://s4.51cto.com/oss/201711/07/6babe72eac1d5deda7b6baa5d408ae89.png" target="_blank"></a>
如果想要删除容器時,同時删除掉其資料盤,那麼可以使用<code>-v</code>參數。
<code>docker </code><code>rm</code> <code>-</code><code>v</code> <code>newnginx</code>
四、網絡
docker提供幾種網絡,它決定容器之間和外界和容器之間如何去互相通信。
<code>docker network </code><code>ls</code> <code>#檢視網絡</code>
<a href="https://s5.51cto.com/oss/201711/07/3c3b558dc81e98f69dab30c0a9d50cec.png" target="_blank"></a>
當Docker程序啟動時,會在主機上建立一個名為docker0的虛拟網橋,此主機上啟動的Docker容器會連接配接到這個虛拟網橋上。虛拟網橋的工作方式和實體交換機類似,這樣主機上的所有容器就通過交換機連在了一個二層網絡中。從docker0子網中配置設定一個IP給容器使用,并設定docker0的IP位址為容器的預設網關。在主機上建立一對虛拟網卡veth pair裝置,Docker将veth pair裝置的一端放在新建立的容器中,并命名為eth0(容器的網卡),另一端放在主機中,以vethxxx這樣類似的名字命名,并将這個網絡裝置加入到docker0網橋中。
4.1 bridge橋接網絡
除非建立容器的時候指定網絡,不然容器就會預設的使用橋接網絡。屬于這個網絡的容器之間可以互相通信,不過外界想要通路到這個網絡的容器呢,需使用橋接網絡,有點像主機和容器之間的一座橋,對容器有一點隔離作用。實際是在iptables做了DNAT規則,實作端口轉發功能。可以使用iptables -t nat -vnL檢視。
4.2 host主機網絡
如果啟動容器的時候使用host模式,那麼這個容器将不會獲得一個獨立的Network Namespace,而是和主控端共用一個Network Namespace。容器将不會虛拟出自己的網卡,配置自己的IP等,而是使用主控端的IP和端口。但是,容器的其他方面,如檔案系統、程序清單等還是和主控端隔離的。隻用這種網絡的容器會使用主機的網絡,這種網絡對外界是完全開放的,能夠通路到主機,就能通路到容器。
4.3 使用none模式
Docker容器擁有自己的Network Namespace,但是,并不為Docker容器進行任何網絡配置。也就是說,這個Docker容器沒有網卡、IP、路由等資訊。需要我們自己為Docker容器添加網卡、配置IP等。使用此種網絡的容器會完全隔離。
4.4 簡單示範:
啟動兩個容器,檢視其容器内部IP位址
<code>for</code> <code>i </code><code>in</code> <code>`docker </code><code>ps</code> <code>|</code><code>grep</code> <code>-</code><code>v</code> <code>"CONTAINER"</code><code>|</code><code>awk</code> <code>'{print $1}'</code><code>`;</code><code>do</code> <code>docker inspect $i|</code><code>grep</code> <code>'IPAddress'</code><code>;</code><code>done</code>
檢視橋接模式下主機内部容器之間和容器與主控端直接均可正常通訊
<a href="https://s4.51cto.com/oss/201711/07/e1623e4a2f17c581957424a4aa4f2995.png" target="_blank"></a>
<code>docker inspect 容器ID</code>
<a href="https://s2.51cto.com/oss/201711/07/135cdfff43e9a32e96819c69c2a18840.png" target="_blank"></a>
檢視host建立的容器内部沒有IP位址,它使用的為主控端的位址
<code>docker run -d --net host docker.io</code><code>/sergeyzh/centos6-nginx</code>
<a href="https://s3.51cto.com/oss/201711/07/a3d6239b861d62172cf7b8235a2d57a1.png" target="_blank"></a>
<a href="https://s3.51cto.com/oss/201711/07/1965c24d718ca5d6437c4991110176f4.png" target="_blank"></a>
<code>docker run -d --net none docker.io</code><code>/sergeyzh/centos6-nginx</code>
<a href="https://s4.51cto.com/oss/201711/07/002f07ebb53e60920fdaa25e59ffea5d.png" target="_blank"></a>
4.5 容器端口:
如果想讓外界可以通路到,基于bridge網絡建立的容器提供的服務,那你可以告訴Docker你要使用哪些接口。如果想檢視鏡像會使用哪些端口,ExposedPorts,可以獲悉鏡像使用哪些端口。
<code>docker run -d -p 80 docker.io</code><code>/sergeyzh/centos6-nginx</code>
<code>docker port 09648b2ff7f6</code>
-p 參數會在主控端随機映射一個高端口到容器内的指定端口
<a href="https://s4.51cto.com/oss/201711/07/a0025b5366276690b9d24b79e3d2a49c.png" target="_blank"></a>
<code>docker run -d -p 80:80 docker.io</code><code>/sergeyzh/centos6-nginx</code> <code>#将主控端的80端口映射到容器的80端口</code>
<a href="https://s5.51cto.com/oss/201711/07/3010e7d100c43e8692ca25e7cc4c986b.png" target="_blank"></a>
本文轉自 KaliArch 51CTO部落格,原文連結:http://blog.51cto.com/kaliarch/1979872,如需轉載請自行聯系原作者