前言
? 上篇文章講述了有關(guān)docker的資源控制,主要是三個方面:CPU、內(nèi)存以及IO。本文將講述docker的4種網(wǎng)絡(luò)模式。
- 揭開Docker的面紗 – 基礎(chǔ)理論梳理和安裝流程演示 http://www.sfodin.cn/Linux/2020-04/163003.htm
- Docker基礎(chǔ)命令詳解 – 鏡像及容器操作 http://www.sfodin.cn/Linux/2020-04/163005.htm
- 深入理解Docker的硬件資源控制與驗證 http://www.sfodin.cn/Linux/2020-04/163006.htm
一、簡述VMware中三種網(wǎng)絡(luò)模式
? 可能,對于許多接觸Linux操作系統(tǒng)的朋友而言,起初都是通過虛擬機軟件進行層層深入的學習。而對于其中一種軟件——VMware軟件的網(wǎng)絡(luò)連接可能就是初學者的一個難題??赡芤恢倍疾⒉涣私馑峁┑娜N網(wǎng)絡(luò)模式的原理和意義。那么本小節(jié)將簡單講述一下有關(guān)VMware的三種網(wǎng)絡(luò)模式:Bridged(橋接模式)、NAT(網(wǎng)絡(luò)地址轉(zhuǎn)換模式)、Host-Only(僅主機模式)。而此三種分別對應于網(wǎng)卡設(shè)備中的VMnet0、VMnet1(或者后期新增創(chuàng)建的)、VMnet8(NAT網(wǎng)卡也只能有一個)
1.1橋接模式
? 概念:橋接模式就是一種將主機(好比是你的筆記本上的)的網(wǎng)卡與虛擬機的網(wǎng)卡利用虛擬網(wǎng)橋進行通信。
? 原理理解:對這種模式的理解可以認為是將物理機虛擬為一個交換機,所有橋接設(shè)置的虛擬機連接到這個交換機的一個接口上,當然物理機也一樣需要連接到這個交換機,也就是說橋接模式下的所有網(wǎng)卡都是交換模式,相互可以訪問而且互不干擾。
? 典型特征:虛擬機的IP地址需要與主機在同一網(wǎng)段,如果需要聯(lián)網(wǎng)則網(wǎng)關(guān)與DNS需要與主機網(wǎng)卡一致。
? 具體可以再通過下面的圖示理解:
1.2網(wǎng)絡(luò)地址轉(zhuǎn)換模式
? NAT模式的話相對來說應該是最熟悉的了。網(wǎng)絡(luò)地址轉(zhuǎn)換,既然有地址轉(zhuǎn)換,肯定是發(fā)生了轉(zhuǎn)變了。NAT模式就比較適合于IP資源緊缺,而且希望虛擬機可以聯(lián)網(wǎng)的情況。
? NAT模式借助的是虛擬的NAT設(shè)備以及虛擬的DHCP服務(wù)器,從而使得虛擬機可以聯(lián)網(wǎng)。如下圖所示:
1.3僅主機模式
? 僅主機模式呢,其實說白了就是沒有NAT設(shè)備的網(wǎng)絡(luò)模式,僅使用的是VMnet1虛擬網(wǎng)卡與虛擬交換機連接,從而與虛擬機通信,而這種模式就實現(xiàn)了虛擬機與外網(wǎng)的隔離,即獨立的一臺服務(wù)器,只與主機互相通信。如下圖所示:
? 好的,現(xiàn)在大概了解了VMware中三種網(wǎng)絡(luò)模式的原理了吧,現(xiàn)在繼續(xù)來聊聊在docker中的網(wǎng)絡(luò)模式。
二、docker的網(wǎng)絡(luò)模式
2.1docker網(wǎng)絡(luò)實現(xiàn)原理
? docker使用Linux橋接的方式,即在宿主機虛擬一個docker容器網(wǎng)橋(docker0),docker啟動一個 容器時會根據(jù)docker網(wǎng)橋的網(wǎng)段分配給容器一個IP地址,這個地址就是容器ip,同時docker就是每個容器的默認網(wǎng)關(guān)。因此,同一個宿主機內(nèi)的容器就可以通過容器ip地址直接通信。
? 一般情況下,我們在安裝和啟動docker服務(wù)之后使用ifconfig命令即可查看到這個docker0的虛擬網(wǎng)橋設(shè)備:
[root@localhost ~]# ifconfig | head -7 docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255 ether 02:42:58:71:c9:ba txqueuelen 0 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
從上面顯示的結(jié)果來看,默認的容器網(wǎng)關(guān)地址為172.17.0.1/16哈!當然loopback網(wǎng)卡是回環(huán)網(wǎng)卡,測試驗證(TCP/IP連接),virtual bridge則是虛擬網(wǎng)橋(想想KVM【云原生】)
? 當然,docker網(wǎng)橋是宿主機虛擬出來的,并不是真實存在的網(wǎng)絡(luò)設(shè)備,外部網(wǎng)絡(luò)是無法通過ip地址直接尋址的,這就表明我們需要通過其他的方式來使外部網(wǎng)絡(luò)可以訪問容器,一般會通過訪問宿主機ip結(jié)合容器的端口(并且端口一般是進行了端口映射,之后會講述)進行容器的訪問。
2.2docker四種網(wǎng)絡(luò)模式
下面直接通過下面的表格來區(qū)分理解一下docker的四種網(wǎng)絡(luò)模式
docker網(wǎng)絡(luò)模式 | 配置 | 說明 |
---|---|---|
host | 容器和宿主機共享Network namespace | |
container模式 | 容器和另外一個容器共享Network namespace | |
none模式 | 容器有獨立的Network namespace,但并沒有對其進行任何網(wǎng)絡(luò)設(shè)置,如分配veth pair 和網(wǎng)橋連接,配置IP等 | |
bridge模式 | 默認的模式 |
其實啟動docker服務(wù)之后,可以使用docker network相關(guān)命令控制管理網(wǎng)絡(luò),下面我們查看一下網(wǎng)絡(luò)列表:(默認存在下面三個)下面逐一介紹(結(jié)合第一小節(jié)的內(nèi)容來理解docker 中的網(wǎng)絡(luò)原理)
[root@localhost ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 3763f78eb404 bridge bridge local 3bb2f50eb211 host host local e12cd7b98c54 none null local
2.2.1host模式
host模式結(jié)合VMware中的僅主機模式即可理解,通過下圖表示一下:
從上圖可以看出,如果在啟動容器后使用的是host模式,那么這個容器將不會獲得一個獨立的Network Namespace(網(wǎng)絡(luò)命名空間),而是和宿主機系統(tǒng)共用一個Network Namespace。并且這就意味著容器將不會虛擬出自己的網(wǎng)卡以及配置自己的ip等,而是使用宿主機的ip以及端口。不過呢,在其他方面例如文件系統(tǒng)等還是與之隔離的。
這種方式最大優(yōu)勢在于網(wǎng)絡(luò)性能比較好但是缺點也很明顯——網(wǎng)絡(luò)的隔離性很弱。
2.2.2container模式
? 這個模式正如上述表格中的說明一般,是表示指定新創(chuàng)建的容器和已經(jīng)存在的一個容器共享一個Network Namespace。當然這也表示新建的這個容器不會創(chuàng)建自己的網(wǎng)卡等相關(guān)操作,而是和與指定的容器共享這些資源。
? 這種模式也和上述的host差不多,除了網(wǎng)絡(luò)方面,其文件系統(tǒng)、進程列表等都是隔離的。
參照下圖:
2.2.3none模式
? 使用none模式,Docker容器擁有自己的Network Namespace,但是,不會對Docker容器進行任何的網(wǎng)絡(luò)配置。這就表明這個Docker容器沒有網(wǎng)卡、IP、路由等信息。需要我們自己為Docker容器添加網(wǎng)卡、配置IP等。這種方式網(wǎng)絡(luò)的隔離性最為徹底,即表明關(guān)閉了容器的網(wǎng)絡(luò)功能,也無法訪問這個容器。
示意圖如下:
2.2.4bridge模式
? 該模式就是我們在啟動docker服務(wù)后默認的docker網(wǎng)絡(luò)模式,其會在主機上創(chuàng)建一個名為docker0的虛擬網(wǎng)橋,這個主機上的所有啟動的容器就會連接到這個虛擬網(wǎng)橋上。結(jié)合VMware中網(wǎng)橋模式原理,想想物理交換機的原理,就不難理解了。
? 從docker0子網(wǎng)中分配一個IP給容器使用,并設(shè)置docker0的IP地址為容器的默認網(wǎng)關(guān)。在主機上創(chuàng)建一對虛擬網(wǎng)卡veth pair設(shè)備,Docker將veth pair設(shè)備的一端放在新創(chuàng)建的容器中(這個veth對我們在OpenStack中見過,筆者覺得可以將之理解為一個橋梁,建立橋兩岸的關(guān)系而存在的一種虛擬設(shè)備),并命名為eth0(容器的網(wǎng)卡),另一端放在主機中,以vethxxx這樣類似的名字命名,并將這個網(wǎng)絡(luò)設(shè)備加入到docker0網(wǎng)橋中。
? 使用docker run -p 命令時,docker實際是在防火墻做了DNAT規(guī)則,實現(xiàn)端口轉(zhuǎn)發(fā)的功能。
下面通過一個節(jié)點的服務(wù)器結(jié)構(gòu)圖來理解:
當然,這四種模式都不需要手動配置,真正需要配置的是自定義網(wǎng)絡(luò)。
三、docker網(wǎng)絡(luò)控制相關(guān)命令配置
上面已經(jīng)給出了對應docker網(wǎng)絡(luò)控制的命令docker network,下面具體看一下這個命令的具體說明:
docker network的命令用法: Usage: docker network COMMAND Manage networks Commands: connect Connect a container to a network create Create a network disconnect Disconnect a container from a network inspect Display detailed information on one or more networks ls List networks prune Remove all unused networks rm Remove one or more networks
3.1橋接命令設(shè)置
我們通過嘗試、排錯和驗證的方式來配置docker網(wǎng)絡(luò)。
因為需要NAT地址轉(zhuǎn)換功能,所以需要開啟防火墻,但是核心防護還是關(guān)了吧。
[root@localhost ~]# systemctl start firewalld.service [root@localhost ~]# systemctl status firewalld.service ● firewalld.service - firewalld - dynamic firewall daemon Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled) Active: active (running) since 一 2020-04-06 10:18:40 CST; 2s ago Docs: man:firewalld(1) Main PID: 65611 (firewalld) ...
初始化環(huán)境:(后面會返回到這個環(huán)境狀態(tài))
[root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE [root@localhost ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
我們嘗試通過docker網(wǎng)橋方式(橋接)給一個容器設(shè)置一個ip地址(自定義的),下面看一下命令執(zhí)行的結(jié)果:
[root@localhost ~]# docker run -itd --name test --network bridge --ip 172.17.0.10 CentOS:7 /bin/bash Unable to find image 'centos:7' locally 7: Pulling from library/centos ab5ef0e58194: Pull complete Digest: sha256:4a701376d03f6b39b8c2a8f4a8e499441b0d567f9ab9d58e4991de4472fb813c Status: Downloaded newer image for centos:7 29f9e9cbb398085d7c89bed2982d626bfb7e564371a76a6cb693cffa68b917af docker: Error response from daemon: user specified IP address is supported on user defined networks only.
首先,由于沒有改鏡像,所以會先拉取鏡像之后創(chuàng)建以及嘗試運行容器,但是會遇到報錯,報錯原因是因為用戶自己設(shè)置的ip地址只適合于他們自己定義的網(wǎng)絡(luò)。但是這并不影響鏡像的獲取與創(chuàng)建,我們嘗試運行看看結(jié)果:
[root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos 7 5e35e350aded 4 months ago 203MB [root@localhost ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 29f9e9cbb398 centos:7 "/bin/bash" About a minute ago Created test [root@localhost ~]# docker start 29f9e9cbb398 Error response from daemon: user specified IP address is supported on user defined networks only Error: failed to start containers: 29f9e9cbb398
? 很顯然,結(jié)果告訴我們還是上述的原因?qū)е铝诉@個問題,好吧只能刪除這個容器了。索性還原為初始化環(huán)境吧(其實可以去掉–network bridge就不會報錯,但是設(shè)置的ip地址會不生效,可以自行嘗試一下),我們不指定ip地址來試一下,順便驗證一下不加這個參數(shù)試試,最后還原為初始化狀態(tài)后我們再通過自定義的方式來設(shè)置ip地址吧。
[root@localhost ~]# docker run -itd --name demo centos:7 /bin/bash 984545df8ebf2c30f4ccf3f5f4699ed67bd2a93cbc068f2ace4865a828b4a4d1 [root@localhost ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 984545df8ebf centos:7 "/bin/bash" 8 seconds ago Up 6 seconds demo
進入容器查看ip地址
[root@localhost ~]# docker exec -it 984545df8ebf /bin/bash [root@984545df8ebf /]# yum install -y net-tools Loaded plugins: fastestmirror, ovl Determining fastest mirrors [root@984545df8ebf /]# ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.17.0.2 netmask 255.255.0.0 broadcast 172.17.255.255 ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet) RX packets 2201 bytes 15042254 (14.3 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 1999 bytes 111171 (108.5 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 loop txqueuelen 1000 (Local Loopback) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
那么首先我們需要創(chuàng)建一個自定義的子網(wǎng)段,并且給他一個名稱,通過這個網(wǎng)段給對應的容器設(shè)置固定的ip地址。
[root@localhost ~]# docker network create --subnet=172.18.0.0/24 mynetwork Error response from daemon: Failed to Setup IP tables: Unable to enable SKIP DNAT rule: (iptables failed: iptables --wait -t nat -I DOCKER -i br-4cd28c051bec -j RETURN: iptables: No chain/target/match by that name. (exit status 1))
看來很不幸啊,又error了,不要慌,我們看看是什么原因?qū)е碌?,這個報錯的根源看似是防火墻,說是無法跳過DNAT(目標網(wǎng)絡(luò)地址轉(zhuǎn)換)規(guī)則,其實導致這個問題的原因是我們剛剛開啟了防火墻,卻沒有重啟docker服務(wù),就有點類似更改了配置文件沒有重啟服務(wù)。
[root@localhost ~]# systemctl restart docker [root@localhost ~]# docker network create --subnet=172.18.0.0/24 mynetwork 723d0fd514eb219d57667f72c3eb75fc4864af0cd94c21b6c70e868fb8d520a1
[root@localhost ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 00008a1e778b bridge bridge local 3bb2f50eb211 host host local 723d0fd514eb mynetwork bridge local e12cd7b98c54 none null local [root@localhost ~]#
此時進行驗證自定義設(shè)置一個容器的固定IP地址的測試:
[root@localhost ~]# docker run -itd --name test2 --network mynetwork --ip 172.18.0.10 centos:7 /bin/bash Unable to find image 'centos:7' locally 7: Pulling from library/centos ab5ef0e58194: Pull complete Digest: sha256:4a701376d03f6b39b8c2a8f4a8e499441b0d567f9ab9d58e4991de4472fb813c Status: Downloaded newer image for centos:7 683ad76f7789b5c16f251577047a288a3a4a00777128a216adfee15985b94c04
查看容器的狀態(tài),進入容器查看ip地址
[root@localhost ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 683ad76f7789 centos:7 "/bin/bash" 23 seconds ago Up 22 seconds test2 [root@localhost ~]# docker exec -it 683ad76f7789 /bin/bash [root@683ad76f7789 /]# yum install -y net-tools Loaded plugins: fastestmirror, ovl ... [root@683ad76f7789 /]# ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.18.0.10 netmask 255.255.255.0 broadcast 172.18.0.255 ether 02:42:ac:12:00:0a txqueuelen 0 (Ethernet) RX packets 2302 bytes 15050471 (14.3 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 2049 bytes 113777 (111.1 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 loop txqueuelen 1000 (Local Loopback) RX packets 62 bytes 7019 (6.8 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 62 bytes 7019 (6.8 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
此時發(fā)現(xiàn)自定義的網(wǎng)絡(luò)設(shè)置容器ip地址成功了。
四、總結(jié)
? 本文通過對VMware軟件中的三種網(wǎng)絡(luò)模式工作的原理,層層遞進深入講解docker的各種網(wǎng)絡(luò)模式,并且通過案例結(jié)合排障思路詳細介紹了有關(guān)docker網(wǎng)橋模式是如何配置容器ip地址的,有默認模式以及自定義模式。
?最后,需要注意的是命令還是需要多記多敲多練,謝謝閱讀!