5.0 網絡模式基本介紹
Docker 單機網絡模式分為以下幾種:
1) bridge NetWork,啟動容器時使用--net=bridge參數指定,預設設定。
2) Host NetWork ,啟動容器時使用--net=host參數指定。
3) None NetWork, 啟動容器時使用--net=none參數指定。
4) Container NetWork,啟動容器時使用--net=container:NAME_or_ID參數指定。
5.1 Docker 網絡模式詳解
5.1.1 host 模式
如果啟動容器的時候使用host 模式,那麼這個容器将不會獲得一個獨立的Network Namespace,而是和主控端共用一個Network Namespace。容器将不會虛拟出自己的網卡,配置自己的IP 等,而是使用主控端的IP 和端口。但是容器的其他方面,如檔案系統、程序清單等還是和主控端隔離的。用主機網絡的時候,一個主控端,相同的容器,隻能啟動一個?
5.1.1.1 案例:容器網絡host模式
#注意如果是host模式,指令行參數不能帶-p/-P 主機端口:容器端口
# WARNING: Published ports are discarded when using host network mode
[root@master ~]# docker run --name host_demo -it --network host gliderlabs/alpine /bin/sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:d0:f0:73 brd ff:ff:ff:ff:ff:ff
inet 192.168.91.8/24 brd 192.168.91.255 scope global ens32 valid_lft forever preferred_lft forever inet6 fe80::c634:c8f0:327e:10a8/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN link/ether 02:42:da:53:55:ff brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 valid_lft forever preferred_lft forever
/ # ping www.baidu.com
PING www.baidu.com (14.215.177.38): 56 data bytes
64 bytes from 14.215.177.38: seq=0 ttl=128 time=10.177 ms
[root@demo ~]# docker run --name nginx_host1111 -d --network host nginx
/
5.1.2 bridge 模式
bridge 模式是Docker 預設的網絡設定,此模式會為每一個容器配置設定Network Namespace、設定IP等,并将一個主機上的Docker 容器連接配接到一個虛拟網橋上。
當Docker程序啟動時,會在主機上建立一個名為docker0的虛拟網橋,此主機上啟動的 Docker容器會連接配接到這個虛拟網橋上。虛拟網橋(根據MAC位址進行資料交換)的工作方式和實體交換機類似,這樣主機上的所有容器就通過交換機連在了一個二層網絡中。
從docker0子網中配置設定一個IP給容器使用,并設定docker0的IP位址為容器的預設網關。在主機上建立一對虛拟網卡veth pair裝置,Docker将veth pair裝置的一端放在新建立的容器中,并命名為eth0(容器的網卡),另一端放在主機中,以vethxxx這樣類似的名字命名,并将這個網絡裝置加入到docker0網橋中。可以通過brctl show指令檢視。如果不寫--net參數,就是bridge模式。使用docker run -p時,docker實際是在iptables做了DNAT規則,實作端口轉發功能。可以使用iptables -t nat -vnL檢視。
5.1.2.1 案例:容器網絡模式橋接
#此模式可以添加端口映射參數:-p 2000:22
[root@master ~]# docker run --name host_demo_bridge -it --network bridge gliderlabs/alpine /bin/sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever
6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever
5.1.3 container 模式
Container 模式指定新建立的容器和已經存在的一個容器共享一個Network Namespace,而不是和主控端共享。新建立的容器不會建立自己的網卡,配置自己的IP,而是和一個指定的容器共享IP、端口範圍等。同樣,兩個容器除了網絡方面,其他的如檔案系統、程序清單等還是隔離的。兩個容器的程序可以通過localhost 網卡裝置通信。
5.1.3.1 案例:容器網絡使用container
#使用其他容器的橋接網卡出外網, 此模式不支援-p主機端口:容器端口
[root@master ~]# docker run --name host_demo_container -it \
--network container:host_demo_bridge gliderlabs/alpine /bin/sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever
8: eth0@if9: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever
5.1.4 none 模式
使用none 模式,Docker 容器擁有自己的Network Namespace,但是,并不為Docker 容器進行任何網絡配置。也就是說,這個Docker 容器沒有網卡、IP、路由等資訊。需要我們自己為Docker 容器添加網卡、配置IP 等。
5.1.4.1 案例容器網絡模式為none模式
[root@master ~]# docker run --name host_demo_none -it --network none gliderlabs/alpine /bin/sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever
5.2 容器網絡操作
5.2.1 容器網絡配置檢視
文法:docker container inspect 容器ID
#系統預設配置設定的IP 位址段為172.17.0.0/16
[root@docker chapter]# docker container inspect 658273be34ee
........省略.........
"NetworkSettings": {
"Bridge": "",
"SandboxID": "d2e6b8e57c55a552abb825b11ed3faff4541fe28fa20244caa29ee2b2ed8ce74",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"80/tcp": [
{
"HostIp": "0.0.0.0",
"HostPort": "80"
}
]
},
"SandboxKey": "/var/run/docker/netns/d2e6b8e57c55",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "73023ec84983ee451e065700c61c8b43bc67fafb3997946002a7a48ca24923cf",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
5.2.2 容器端口映射
容器中可以運作一些網絡應用,要讓外部也可以通路這些應用,可以通過 -P 或 -p 參數來指定端口映射。當使用 -P(大寫) 标記時,Docker 會随機映射一個端口到内部容器開放的網絡端口。當使用 -p(小寫)标記時,Docker 指定一個主控端端口映射到到内如容器開放的網絡端口。使用 docker ps 可以看到,本地主機的端口被映射到了容器端口。
在一個指定端口上隻可以綁定一個容器。
指定映射(docker 會自動添加一條iptables規則來實作端口映射)
-p hostPort:containerPort
#映射主機指定端口8080到容器的端口80
[root@docker master ]# docker run --name nginx-demo -p 8080:80 -d nginx
#檢視 iptables
[root@master ~]# iptables -L -n -t nat | grep 8080
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8080 to:172.17.0.4:80
-p ip:hostPort:containerPort
#映射主機的指定IP 與指定 8180端口到容器80端口
[root@master ~]# docker run --name nginx-demo-8180 -p 192.168.91.8:8180:80 -d nginx
#檢視 iptables
[root@master ~]# iptables -L -n -t nat | grep 8180
DNAT tcp -- 0.0.0.0/0 192.168.91.8 tcp dpt:8180 to:172.17.0.5:80
-p ip::containerPort(随機端口)
[root@master ~]# docker run --name nginx-1 -p 192.168.91.8::80 -d nginx
[root@master ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f5fb8604f330 nginx "nginx -g 'daemon of…" 7 seconds ago Up 6 seconds 192.168.91.8:32768->80/tcp nginx-1
-p hostPort:containerPort/udp
[root@master ~]# docker run --name dns-udp -p 53:53/udp -d andyshinn/dnsmasq #指令成功
-p 81:80 –p 443:443 可以指定多個-p
[root@master ~]# docker run --name nginx-demo-81 -p 81:80 -p 32:22 -d nginx
-P 主控端随機端口映射
[root@master ~]# docker run --name nginx-port -P -d nginx
[root@master ~]# docker ps | grep nginx-port
e08c51faced1 nginx "nginx -g 'daemon of…" 7 seconds ago Up 5 seconds 0.0.0.0:32769->80/tcp
#檢視容器的端口映射
[root@master ~]# docker port 4a52c7b5035b 80/tcp -> 192.168.91.8:8110