###### tags: `教學` `Docker` `學習筆記` `Dockerfile` # Docker and Container 007 - Network 網路模式 [TOC] --- ## 0. 網路模式 - Network 也是 Docker 的元件。正如其名,它是在管理網路相關設定的指令。 - 使用 Network 建立一個虛擬網路,container 在這個網路裡就可以使用 container name 或 hostname 互相連結。 - 常見四種:none, bridage, container, host - none:容器沒有與任何外界接觸,所以他不能向外連,外面也不能連進去,是一個封閉的網路空間 - briage:我們會把容器在啟動的時候放到某個 bridge network 之中。在這個網路空間中,有所謂的 IP 的概念。 - container:**{TODO}** - host:**{TODO}** ## 1. none模式 - `$ docker network ls`,列出所有網路模式 - `$ docker run -d --network none none-mode alpine tail -f /dev/null` - none-mode,container的名稱 - alpine,使用的image - 修正後可動:`$ docker run -d --net=none alpine tail -f /dev/null` -  - `$ docker network inspect none`,查看none的網路介面,查看相關資料 -  - `$ docker exec -it 30833ebcba10 /bin/sh`,進入none模式下的container裡面,確認網路無法與外界聯繫 -  --- ## 2. bridge模式 > 預設的網路模式 ### 2.1. 建立一個網路空間 - `$ docker network create --driver bridge my-bridge` - create,建(一個網路空間) - --driver,指定driver - bridge,driver類別為bridge - my-bridge,bridge的網路名稱 -  - `$ docker network inspect my-bridge`,查看none的網路介面,查看相關資料 -  - "Subnet": "172.19.0.0/16" - "Gateway": "172.19.0.1" - `$ docker run -d --network my-bridge bridge-mode001 alpine tail -f /dev/null` - bridge-mode001,container的名稱 - `$ docker network inspect my-bridge`,查看none的網路介面,查看相關資料 -  - `$ docker exec -it 8d113ec5c116 /bin/sh`,進到container裡面 - ip addr ls,看有什麼ip ### 2.2. 同時建另一個container - `$ docker run -d --network my-bridge alpine tail -f /dev/null` - `$ docker container rename eager_sinoussi bridge-mode002` - `$ docker network inspect my-bridge`,查看none的網路介面,查看相關資料 -  - ip a,查看所在container的ip - ping 8.8.8.8,確認是否連到外網 - ping 172.19.0.2,確認是否可連到另一個container ### 2.3. 另外建立一個網路空間 - `$ docker network create --driver bridge their-bridge` - `$ docker network inspect their-bridge` - `$ docker run -d --network their-bridge --name bridge-mode003 alpine tail -f /dev/null` -  - `$ docker exec -it 8d113ec5c116 /bin/sh`,進到container裡面 - ip addr ls,看有什麼ip - ping 8.8.8.8,外網 - ping 172.19.0.2,之前的bridge-mode001(這邊會不通) - 不同bridge之間的container是不能互通的 - `$ docker network connect my-bridge bridge-mode003`,把bridge-mode003連結到my-bridge - `$ docker network inspect my-bridge` -  - 現在bridge-mode003有兩個ip,一個在my-bridge,一個在their-bridge --- ## 3. container模式 - `$ docker container ls` - `$ docker run -d --network container:bridge-mode001 --name container-mode001 alpine tail -f /dev/null,複製一個container` - `$ docker network inspect my-bridge`,查看image的內容 - `$ docker exec -it 10afd27d835d /bin/sh`,進到container裡面,查看ip - 可以發現ip跟複製的container一樣,container模式就是複製特定的網路設定 --- ## 4. host模式 > container不再屬於container,而是當作host(VM linux host) > 讓container的網路世界跟VM linux host一樣 - 修改dockerfile(copy之後的拿掉) ```dockerfile= FROM alpine:latest LABEL name="MyName" ENV myworkdir=/var/www/localhost/htdocs ARG whoami="Sean" WORKDIR ${myworkdir} RUN apk --update add apache2 RUN rm -rf /var/cache/apk/* RUN echo "<h3>I am ${whoami}, this is a test page. line 1st</h3>" >> index.html RUN echo "<h3>I am ${whoami},, this is a test page. line 2nd</h3>" >> index.html RUN echo "<h3>I am ${whoami},, this is a test page. line 3rd</h3>" >> index.html RUN echo "<h3>I am ${whoami},, this is a test page. line 9th</h3>" >> index.html ENTRYPOINT ["httpd", "-D", "FOREGROUND"] ``` - $ `docker build -t kihifung/my-apache .` - $ `docker run -d --network host --name my-apache kihifung/my-apache`, - 這邊就沒有-p(port mapping) - 圖417 - $ `docker exec -it a7a0ebc81647 /bin/sh` - $ `netstat -tulpn`, -  --- ##### 參數 * -d|--driver 使用的 driver,預設 bridge,其他參數可以參考[官網](https://docs.docker.com/network/#network-drivers) * --link 連結 container,參數為 container name 或 hostname,也可以設定 alias * --network 指定網路設定 --- ##### 其他指令 - 幫container更名,`$ docker container rename eager_sinoussi bridge-mode002` --- ## troubleshooting ### 摸不到網路 :::warning ``` $ ping 8.8.8.8 connect: Network is unreachable ``` ::: - MAC衝突 :::warning MAC address 18:31:BF:A1:B2:C3 of adapter 'Ethernet0' is within the reserved address range or is.. Adapter 'Ethernet0' may not have network connectivity. :::  * [設定方法](https://www.itread01.com/content/1521193139.html) ``` $ ifconfig ens33 down $ cd /etc/sysconfig/network-scripts $ vi ifcfg-ens33 修改其中的"HWADDR=xx:xx:xx:xx:xx:xx"為"MACADDR=xx:xx:xx:xx:xx:xx" $ ifconfig ens33 up $ service network start --- note:HWADDR和MACADDR是有區別的。 1、HWADDR地址其實是網卡的硬挺物理地址,只有廠商才能修改。 2、MACADDR是系統的網卡物理地址,可以用MACADDR來覆蓋HWADDR,但兩這個參數不能同時使用。 而ifconfig命令中顯示的物理地址其實是MACADDR的值,雖然顯示的名稱寫的是HWADDR。所以HWADDR 一般註釋掉,或改為MACADDR ``` --- ## 回顧 ## 課後複習/測驗 ### Q3:容器的網路運作和虛擬機的網路運作有何不同? 面試官提出這樣問題的動機是,點出虛擬機網路與容器網路比較後所帶出的複雜性,對於具備虛擬化技術背景的人來說,了解如何使用Docker容器下的Port來開通服務,以及如何將靜態IP位址分配給容器,能夠區分容器與VM的使用方式是非常重要。表3條列出容器與虛擬機在網路運作方面的差異。 表3 容器與虛擬機網路運作的差異比較  --- ### Q15:請列出容器網路運作為何如此重要的原因? 以下是為何需要容器網路的理由: * 容器需要跟外部環境溝通 * 從外部環境連接到容器,進而使用容器所提供的服務。 * 允許容器與Host主機溝通 * 單一主機內或跨主機之間的容器相互連接 * 自動探索容器所提供的服務 * 負載平衡同一服務不同容器的網路流量 * 提供安全的多用戶服務 --- ### Q16:請說明CNM是什麼?它的組成元件有那些? CNM是容器網路模型(Container Network Model)的縮寫,由Docker公司所提出的標準及規範,它構成了Docker環境中容器網路運作的基礎要素,是Docker提供容器網路支持多種網路驅動程式的方法模型,CNM在網路和容器之間提供以下協議: * 相同網段上的所有容器可以相互自由通訊 * 多個網段是分隔容器間流量的方式,所有網路驅動程式皆應支援。 * 讓容器連接到多個網段的方法,是在單一容器上提供多個端點。 * 單一端點加入到網路沙箱中,以便提供網路的可連通性。 如圖4所示,CNM的主要組成元件是:  ▲圖4 CNM容器網路模型。 * 網路(Network) * 沙箱(Sandbox) * 端點(Endpoint) 沙箱(Sandbox)只是個通用術語,指的是用來隔離Docker Host主機上網路堆疊的作業系統層之特定技術,Docker在Linux上是使用內核命名空間來提供這沙箱功能,沙箱內的網路「堆疊(Stacks)」,包括網路介面(Interfaces)、路由表和DNS等。CNM術語中的網路是指一個或多個可以通訊的端點,相同網路內的所有端點可以相互通訊,不同網路上的端點在沒有外部繞送的情況下是無法進行溝通(圖5)。  ▲圖5 中間容器具不同網段的兩個端點。 --- ### Q17:什麼是不同類型的Docker Networking驅動程式? Docker的網路子系統允許插入各種驅動程式使用,預設情況下包含多種驅動程式,用來提供核心網路功能,表4是各種不同的Docker網路驅動程式簡介。 表4 Docker網路驅動程式比較表  下面是Docker網路驅動程式的詳細資訊: - Bridge:預設的網路驅動程式,若未指定驅動程式,便會是在容器建立時所用的網路類型。當應用程式在獨立的容器中執行,需要網路通訊時,通常會使用橋接器(Bridge)網路。 - Host:針對單獨容器,移除容器和Docker主機之間的網路隔離,並直接使用Host主機的網路,Swarm服務的Host模式僅適用在Docker 17.06及更高版本。 - Overlay:層疊網路將多個Docker Daemon連接在一起,並讓Swarm服務能夠彼此相互溝通,也可以使用層疊網路來促成叢集服務與獨立容器之間的通訊,或者在不同Docker Daemon上的兩個各自獨立的容器可以進行溝通,此方法無須在這些容器之間執行作業系統層級的路由設定,詳細請參閱官方文件(https://docs.docker.com/network/overlay/)。 - MacVLAN:Macvlan網路允許使用者為容器分配MAC位址(OSI Layer2),使其表現就像網路上的實體設備,Docker Daemon透過其MAC位址將網路封包繞送到容器,當需要直接連接實體網路的高效率低延遲應用情境時,使用macvlan驅動程式可能是最佳選擇,而不再透過Docker主機上網路堆疊來進行NAT路由。 - None:對於此一容器,禁用所有網路功能,通常會在客製化網路驅動程式的情境中使用,none並不適用於Swarm服務。 --- ### Q19:Docker Bridge網路與傳統的Linux橋接器有何不同? 以網路方面術語,橋接器網路是鏈路層(Layer2)設備,它在不同網段間轉發封包流量,網路橋接器可以是硬體設備或是Host主機內核所執行的軟體模擬裝置。 以Docker技術來說,橋接器網路是使用軟體橋接器,此橋接器可以讓連接到同一橋接網路的容器相互通訊,同時提供未連接到此橋接網路之容器的隔離功能,Docker橋接器驅動程式會自動在主機中新增橋接規則,以便讓不同橋接網路上的容器無法直接相互溝通(圖6)。  ▲圖6 Docker Bridge網路示意圖。 --- ### Q20:如何建立使用者定義的Bridge網路? 要建立使用者定義的橋接器網路,可使用docker network create命令,指令範例如圖7所示:  ▲圖7 新增Docker Network。 `$ docker network create mynet`,可以指定子網路、IP位置範圍、閘道器和其他選項,相關詳細訊息,請參閱[docker network create官方文件](https://docs.docker.com/engine/reference/commandline/network_create/)或用「`$ docker network create -help`」指令查詢。 --- ### Q21:如何刪除使用者定義的Bridge網路? 使用docker network rm指令刪除使用者定義的橋接網路(圖8),如果目前已有容器連接到網路,請先將它們斷線:  ▲圖8 刪除Docker Network。 `$ docker network rm mynet` --- ### Q22:如何將Docker容器連接到使用者定義的橋接網路? 可以使用以下的指令來進行: `$ docker create --name my-nginx --network my-net --publish 8080:80 nginx:latest` 當建立新容器時,可以指定一個或多個--network參數,此範例將Nginx容器連接到my-net網路,還將容器中的埠號80對應到Docker主機上的埠號8080,因此外部使用者可以存取此連接埠,而其他任何連接到my-net網路的容器都可以存取my-nginx容器上的所有連接埠,當然my-nginx也可存取到其他容器的所有連接埠(圖9)。  ▲圖9 容器與Host主機的埠號對應。 想將正在執行中的容器連接到現有的使用者定義的橋接網路,請使用docker network connect指令,下列指令將已經在運行的my-nginx容器連接到已存在的my-net網路: `$ docker network connect my-net my-nginx` --- ### Q23:Docker是否支援IPv6? * 是的,Docker支援IPv6,只有在Linux平台上運行的Docker版本支援IPv6網路,自從Docker Engine 1.5發布以來,皆支援IPv6位址。 * 如要在Docker Daemon程序中啟用IPv6功能,需要編輯「`/etc/docker/daemon.json`」並設置ipv6值為true: `{ "ipv6": true }`,然後重新載入Docker配置檔,重啟Docker:`$ systemctl reload docker`。 * 現在就可以使用--ip6參數來新增網路,並使用--ip6參數來配置容器IPv6位址。 --- ### Q25:層疊網路(Overlay)與橋接網路(Bridge)有何不同? 橋接網路連接兩個網路,讓來自多個通訊網路或網段組成單一合併網路,因此稱為橋接。層疊網路通常用在兩台分隔的主機之間建立虛擬網路,那為何稱為虛擬?因為其網路利用現有網路上所疊架而成的。 **橋接網路適用於單一主機中,而層疊網路則是應用於多台主機上**(圖10)。  ▲圖10 多台主機以層疊網路連接。 --- ### Q27:如何禁用容器上的網路堆疊? 如果要完全禁用容器中的網路堆疊,可以在啟動容器時使用「--network none」參數,在容器內,就會只新增loopback裝置,圖11為其示意圖。  ▲圖11 無網路容器之拓樸圖。 --- ### Q28:如何替Docker容器建立MacVLAN網路? 要建立Macvlan網路並配合實體網路介面的橋接器,可以使用--driver macvlan和docker network create指令,還需要指定實際運作介面,就是在Docker主機上網路流量會實際通過的網路介面: `$ docker network create -d macvlan --subnet = 172.16.86.0/24 --gateway = 172.16.86.1 -o parent = eth0 collabnet` ### Q29:是否可以排除在MacVLAN網路中已使用的IP位址? 如果需要排除在Macvlan網路中所使用的IP位址,例如當IP位址已經被使用時,請使用--aux-addresses: `$ docker network create -d macvlan –subnet=192.168.32.0/24 –ip-range=192.168.32.128/25 –gateway=192.168.32.254 –aux-address="my-router=192. 168.32.129" -o parent=eth0 collabnet32` MacVLAN相關詳細說明,請參閱[官方文件](https://docs.docker.com/network/macvlan/) --- --- - [回到目錄](https://hackmd.io/@Hualiteq/r1lye3M3d)
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.