docker安装完之后,自动提供了3种网络:html
$ docker network ls NETWORK ID NAME DRIVER SCOPE 9ac63d7fc6e8 bridge bridge local b46032ae4b5f host host local 60f69f2c7987 none null local $
使用 inspect 命令能够查看docker对象的底层信息。好比能够查看容器的信息,其中网络部分的信息以下:node
"Networks": { "bridge": { "IPAMConfig": null, "Links": null, "Aliases": n ll, "NetworkID": "9ac63d7fc6e871eb47e39f9ec4e3fda6a23cb95a906a9ddc6431ed716e000fa1", "EndpointID": "c8b64271d3d7ea5a0a8357c51fa5c80d398dbd07ad7e920792ebbaab628cb00d", "Gateway": "172.17.0.1", "IPAddress": "172.17.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "02:42:ac:11:00:02", "DriverOpts": null } }
这里能够查看容器内部网卡的IP地址。docker
每个容器都有各自一组独立的6个Namespaces:Mount、PID、User、UTS、IPC、Network。
还有一种方案,让每个容器值只拥有独立的Mount、PID、User。而其余的3个UTS、IPC、Network是共享的。就是有本身隔离的名称空间,但也能够共享其中一部分名称空间。通常只共享网络通讯相关的,主机名(UTS)、进程间通讯(IPC)、网络(Network)。
这样作带来了一个便利。如今不一样的容器共享了网络接口,使用的是同一个网络。每一个容器内部的lo接口是同一个lo接口。这样一个容器只要往本地的lo接口发请求,或者是往127.0.0.1发请求,共享网络接口的其余容器也可以接收到。shell
直接和宿主机共享名称空间
仍是上面的共享名称空间,还能够直接和宿主机共享名称空间。那么这个和宿主机共享名称空间的容器,容器内部的接口就是宿主机的网络接口。容器对网络的修改也就是对宿主机的网络进行了修改。这个容器就有了管理网络的特权。
这种就是网络类型中的host类型,就是让容器使用宿主机的网络名称空间。json
Docker一共有4种网络模型数组
Bridged containers
桥接式容器通常拥有两个接口:一个环回接口和一个链接至主机上某桥设备的以太网接口。
docker启动时默认会建立一个名为docker0的网络桥,而且建立的容器为桥接式容器,其以太网接口桥接至docker0。
docker0桥为NET桥,所以桥接式容器可经过此桥接口访问外部网络。浏览器
Closed containers
不参与网络通讯,运行于此容器中的进程仅能访问本地环回接口。
仅适用于进程无须网络通讯的场景中,例如备份、进程诊断及各类离线任务等。bash
建立容器时(run或create),使用参数能够对容器的网络进行设定。服务器
使用--nework参数能够指定容器的网络模式,默认值是default,这个就是bridge模式。网络
brideg模式
正常启动容器,不使用任何网络参数:
$ docker container run --name b1 --rm -it busybox / # ifconfig eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02 inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:12 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:1032 (1.0 KiB) TX bytes:0 (0.0 B) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) / #
以默认的网络模式启动容器。若是启动容器是加上参数--network bridge
效果也是同样的。
none模式
使用--network none启动一个没有任何网络的容器:
$ docker container run --name b1 --rm -it --network none busybox / # ifconfig -a lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) / #
这里显示,只有一个lo接口,没有其余网络接口。
其余网络模式
剩下的还有host模式和联盟式网络,这部分须要单独再展开说明。
在网络上提供服务的时候,通常不是直接提供IP地址。而是提供主机名或域名,不但方便记忆也会有一些其余的便利。因此Docker容器的主机名也是一个重要的网络属性。
主机名
容器的主机名就是它的ID:
/ # hostname 6fb514e1fa3b / #
能够在启动容器时,使用-h参数来设定容器的主机名:
$ docker container run --name b1 --rm -it -h b1.busybox busybox / # hostname b1.busybox / #
DNS服务器
先看一下默认使用的DNS服务器,就是网关的地址:
/ # cat /etc/resolv.conf # Generated by NetworkManager nameserver 192.168.1.1 / # nslookup -type=a baidu.com Server: 192.168.1.1 Address: 192.168.1.1:53 Non-authoritative answer: Name: baidu.com Address: 220.181.38.148 Name: baidu.com Address: 123.125.114.144 / #
使用参数指定DNS服务器启动容器,而后查看容器的DNS的设置:
$ docker container run --name b1 --rm -it -h b1.busybox --dns 223.5.5.5 busybox / # cat /etc/resolv.conf nameserver 223.5.5.5 / #
搜索域
另外还有个参数是--dns-search,是用来指定搜索域的。这个搜索域就是当给的名称不是FQDN主机名格式的时候,自动补的后缀。
$ docker container run --name b1 --rm -it -h b1.busybox --dns 223.5.5.5 --dns-search baidu.com busybox / # cat /etc/resolv.conf search baidu.com nameserver 223.5.5.5 / # nslookup -type=a www Server: 223.5.5.5 Address: 223.5.5.5:53 Non-authoritative answer: www.baidu.com canonical name = www.a.shifen.com Name: www.a.shifen.com Address: 39.156.66.14 Name: www.a.shifen.com Address: 39.156.66.18 / #
指定主机名的时候,没有给完整的域名后缀,不过由于设置了搜索域,因此就自动补全了。
hosts文件
除了域名服务器,还能够经过本地hosts文件来管理主机名:
$ docker container run --name b1 --rm -it -h busybox1.idx.net --dns 223.5.5.5 --dns-search idx.net busybox / # cat /etc/hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters 172.17.0.2 busybox1.idx.net busybox1 / #
能够看到默认就把主机名写入到本地的hosts文件中了。这里加了2个名称,前一个是完整的主机名,后一个是主机名除去后缀的部分。
还可使用参数向hosts文件中注入信息:
$ docker container run --name b1 --rm -it -h busybox1.idx.net --dns 223.5.5.5 --dns-search idx.net --add-host host1.idx.net:192.168.100.1 --add-host host2.idx.net:192.168.100.2 busybox / # cat /etc/hosts 127.0.0.1 localhost ::1 localhost ip6-localhost ip6-loopback fe00::0 ip6-localnet ff00::0 ip6-mcastprefix ff02::1 ip6-allnodes ff02::2 ip6-allrouters 192.168.100.1 host1.idx.net 192.168.100.2 host2.idx.net 172.17.0.2 busybox1.idx.net busybox1 / #
添加记录使用(host:ip)的格式。这个参数是list属性,若是有多个记录,就调用屡次参数。
Docker0为NET桥,所以容器得到的是私有网络地址(内网地址)。
从拓扑结构上看,容器就是一台在宿主机NET服务以后的一台主机。若是容器须要对外提供服务,就要在宿主机上为其定义DNAT规则。
-p选项的使用格式
-p <containerPort>
将指定的容器端口映射至主机全部地址的一个动态端口
-p <hostPort>:<containerPort>
将容器端口containerPort映射至主机端口hostPort
-p <ip>::<containerPort>
将指定的容器端口containerPort映射至主机指定ip的动态端口
命令中间是两个冒号,至关于下面的3个变量的命令省略了中间的变量。
-p <ip>:<hostPort>:<containerPort>
将指定的容器端口containerPort映射至主机指定ip的端口hostPort
动态端口指随机端口,具体映射结果可使用docker port
命令查看
-P(大写),随机映射端口到内部容器开放的全部网络端口。
这里开放的网络端口是镜像制做时设定的,启动容器时也可使用参数--expose指定计划要开放的端口。只有使用-P参数,才须要指定具体要开放哪些端口,能够是镜像中设定也能够是参数--expose设定。使用-p参数时,是指定要映射的端口,所处没有设置要开放的端口也没问题。
能够指定使用的协议,默认是tcp。udp须要指定
-p 127.0.0.1:5000:5000/udp
-p参数能够屡次使用来绑定多个端口
用httpd镜像测试端口映射
不使用端口映射:
$ docker container run -dit --name app1 --rm httpd:alpine 78e4e42fdd0c33a0410077731d26e418423a27827ab62e83dfe×××bca40f671 $ curl http://172.17.0.2 <html><body><h1>It works!</h1></body></html> $ curl http://127.0.0.1 curl: (7) Failed connect to 127.0.0.1:80; 拒绝链接 $
因为没有作端口映射,容器能够经过NAT访问外部网络,可是没法被外部网络访问到,就是容器没有暴露任何接口到公网。宿主机能够经过容器的私网地址访问页面,可是没法经过宿主机的接口地址访问页面,这样外网也没法访问到页面。
使用-P参数:
$ docker container run -dit --name app1 --rm -P httpd:alpine fde094cc000be912e68b8f6321f38d97c76cbabb54454da11c65e0aabd90dc1e $ docker container port app1 80/tcp -> 0.0.0.0:32769 $ curl http://127.0.0.1:32769 <html><body><h1>It works!</h1></body></html> $
此次能够用个宿主机的环回口访问了,直接用浏览器使用宿主机的地址也可以访问。可是端口是随机的,这就是须要使用port命令查看随机分配的端口号。
联盟式是容器之间共享网络名称空间,而开放式是容器共享使用宿主机的网络名称空间。在原理上这二者是同样的。
联盟式容器(joined containrs),是指使用某个已经存在容器的网络接口的容器。接口被联盟内的各容器共享使用。
联盟式容器彼此间共享的是同一个网络名称空间,UTS、IPC、Network。其余名称空间仍是隔离的,Mount、PID、User。
联盟式容器彼此间存在端口冲突的可能性。所以,一般只会在多个容器上的程序须要程序loopback接口互相通讯、或对某已存的容器的网络属性进行监控时才使用此种模式的网络类型。
介绍共享网络名称空间的时候,也讲过共享后的便利,就是多个容器可使用本地环回口实现互相间的通讯。
启动第一个容器
使用交互式接口,开启一个容器:
$ docker container run --name b1 --rm -it busybox / # ifconfig eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02 inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:6 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:516 (516.0 B) TX bytes:0 (0.0 B) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) / #
启动第二个容器
上一个终端被占用着,因此再开一个终端依然使用交互式接口开启第二个容器。这里多了--network参数,就是创建联盟式容器的:
$ docker container run --name b2 --rm -it --network container:b1 busybox / # ifconfig eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02 inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:8 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:656 (656.0 B) TX bytes:0 (0.0 B) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) / #
查看两个容器的ip地址、MAC地址,可见两个容器的网络接口是同一个。效果就至关于传统模式时,同一个主机里的两个进程。和传统的模式相比,容器之间有更多个隔离。
联盟式容器的应用场景
联盟式容器能够直接向本地的lo接口发送请求,联盟的其余容器也能够收到这个请求,就比如联盟中的容器是运行在同一个主机上的两个进程同样。
好比,首先有一个brideg模式的容器,提供一个静态Web页面的服务。而后对于动态页面的请求则发送给另一个容器处理。
这时启动第二个动态页面的容器。若是这个容器也是brideg模式,因为ip地址出动态得到的,那么静态页面容器就没法肯定向哪一个ip地址发送请求。此时若是这两个容器是联盟式的网络,直接向本地的lo接口发送请求就能够了。
要使用开放式网络,指定--network的参数为host便可:
[root@Docker ~]# docker container run --name b3 --rm -it --network host busybox / # ifconfig docker0 Link encap:Ethernet HWaddr 02:42:3C:BE:06:75 inet addr:172.17.0.1 Bcast:172.17.255.255 Mask:255.255.0.0 inet6 addr: fe80::42:3cff:febe:675/64 Scope:Link UP BROADCAST MULTICAST MTU:1500 Metric:1 RX packets:71 errors:0 dropped:0 overruns:0 frame:0 TX packets:82 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:4773 (4.6 KiB) TX bytes:7313 (7.1 KiB) eth0 Link encap:Ethernet HWaddr 00:15:5D:03:67:56 inet addr:192.168.24.170 Bcast:192.168.24.175 Mask:255.255.255.240 inet6 addr: fe80::4c95:4028:8e1:a795/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:36462 errors:0 dropped:0 overruns:0 frame:0 TX packets:20392 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:42167574 (40.2 MiB) TX bytes:1953899 (1.8 MiB) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:48 errors:0 dropped:0 overruns:0 frame:0 TX packets:48 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:3777 (3.6 KiB) TX bytes:3777 (3.6 KiB) / #
不要退出终端,继续在容器里开放一个httpd:
/ # echo "<h1>Hello b3, network host</h1>" > /var/www/index.html / # httpd -h /var/www/ / # netstat -tnl Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN tcp 0 0 192.168.24.170:10010 0.0.0.0:* LISTEN tcp 0 0 :::80 :::* LISTEN tcp 0 0 :::22 :::* LISTEN tcp 0 0 ::1:25 :::* LISTEN / #
启动httpd服务后,也检查了本地监听端口,没有问题。
防火墙问题
在宿主机上是能够直接访问这个Web页面的:
$ curl 172.17.0.1 <h1>Hello b3, network host</h1> $
可是外部网络依然没法访问,这个主要是宿主机的防火墙问题。
以前也开放过服务,而且访问都没有问题。这个应该是宿主机将访问容器的流量都默认放行了。而此次是要直接访问宿主机,虽然服务是在容器内的,可是使用的网络是宿主机的,因此须要防火墙放开策略。
临时开放宿主机上的http服务
$ firewall-cmd --add-service=http success $ firewall-cmd --list-all public (active) target: default icmp-block-inversion: no interfaces: eth0 sources: services: ssh dhcpv6-client http ports: protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules: $
这个只是临时测试,防火墙firewalld服务重启后就会回复原样。
宿主机防火墙策略开放后,就可使用浏览器访问宿主机的80端口打开页面了。
开放式容器的应用场景
部署方式简单,方便迁移。充分利用容器的优点,并能保证程序工做在宿主机上的要求,至少是经过宿主机的网络接口对外提供服务。
以开放式容器的方式运行和进程差很少。都是在一个机器上运行多个进程。进程之间本来就是互相隔离的,可是使用容器后,还能够隔离文件系统和用户。另一个好处就是部署和迁移方便。以往工做为宿主机首部进程的那些系统级管理的进程,之后就可使用容器的方式来运行。
上一节的内容是使用docker默认建立好的3个网络,容器选择其中一个网络,并在运行容器时对可选的参数进行设置。
本节的内容是不使用默认提供的网络,而是先对网络进行自定义。自定义有两种实现方式,一种是对默认的网络进行修改,还有一种是彻底建立一个新的网络。
默认设置,docker使用的是172.17.0.1/16的网络。这个网络的网络类型是bridge,对应的网络名称也是bridge,对应在宿主机上的网卡是docker0。
使用ifconfig命令查看docker0桥的信息:
$ ifconfig docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255 inet6 fe80::42:3cff:febe:675 prefixlen 64 scopeid 0x20<link> ether 02:42:3c:be:06:75 txqueuelen 0 (Ethernet) RX packets 71 bytes 4773 (4.6 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 82 bytes 7313 (7.1 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
这个默认的dockr0桥接口是能够修改的。另外还能够额外定义新的桥接口网络。
docker0桥是在docker daemon启动时建立的,会根据默认属性自动建立,也能够经过修改配置文件来进行自定义。
配置文件就是/etc/docker/daemon.json
,在添加镜像加速器的时候已经用过了。主要的属性有以下这些:
json配置内容示例:
{ "bip": "192.168.10.1/24", "fixed-cidr": "192.168.10.128/25", "fixed-cidr-v6": "2001:db8::/64", "mtu": 1500, "default-gateway": "192.168.1.1", "default-gateway-v6": "2001:db8:abcd::89", "dns": ["114.114.114.114", "223.5.5.5"] }
核心选项是bip(bridge ip),用于指定docker0桥自身的IP地址。根据须要进行自定义,能够只设置一个bip,其余保持默认。其余选项会根据bip自动计算得出,还有一些是默认使用宿主机的网络属性。
实际修改本机的配置
修改后的配置文件以下:
{ "registry-mirrors": ["http://hub-mirror.c.163.com", "https://docker.mirrors.ustc.edu.cn"], "bip": "192.168.101.1/24", "fixed-cidr": "192.168.101.128/25", "dns": ["114.114.114.114", "223.5.5.5"] }
重启服务后,先查看宿主机的docker0桥:
$ systemctl restart docker $ ifconfig docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 192.168.101.1 netmask 255.255.255.0 broadcast 192.168.101.255 inet6 fe80::42:3cff:febe:675 prefixlen 64 scopeid 0x20<link> ether 02:42:3c:be:06:75 txqueuelen 0 (Ethernet) RX packets 81 bytes 5445 (5.3 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 92 bytes 8125 (7.9 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
此时docker0的网络属性已经变了。
新建容器查看网络
建立容器,查看容器内的网络属性:
$ docker container run --name b4 --rm -it busybox / # ifconfig eth0 Link encap:Ethernet HWaddr 02:42:C0:A8:65:80 inet addr:192.168.101.128 Bcast:192.168.101.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:6 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:516 (516.0 B) TX bytes:0 (0.0 B) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) / # cat /etc/resolv.conf nameserver 114.114.114.114 nameserver 223.5.5.5 / # exit $
这里能够确认到自动获取的ip地址也符合设置要求了,还有dns服务器的地址也是自定义的。
查看已有的网络:
$ docker network ls NETWORK ID NAME DRIVER SCOPE 8ec74d5bd709 bridge bridge local d086953087bb host host local fa0c7f1fb6ca none null local $
查看网络插件
这里先展开一下,看看docker支持哪些类型的网络。
命令docker info里的插件Plugins的内容:
$ docker info Plugins: Volume: local Network: bridge host macvlan null overlay Log: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog
在Network插件中,除了bridge、host、nul以外,还有overlay(叠加网络)、macvlan(基于mac的vlan虚拟网络),这两种网络类型没有展开。这些网络插件在下面建立网路时,经过-d参数能够指定,默认是bridge。
建立网络
使用命令docker network create
命令来建立网络:
$ docker network create -d bridge --subnet "192.168.111.0/24" mybr1 7128a28bbbf39a6ca483ecad03d5d85c8179507aff66ced73ca8de5233f16fee [root@Docker ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 8ec74d5bd709 bridge bridge local d086953087bb host host local 7128a28bbbf3 mybr1 bridge local fa0c7f1fb6ca none null local [root@Docker ~]# ifconfig br-7128a28bbbf3: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 192.168.111.1 netmask 255.255.255.0 broadcast 192.168.111.255 ether 02:42:1f:ff:fd:5d 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 docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 192.168.101.1 netmask 255.255.255.0 broadcast 192.168.101.255 inet6 fe80::42:3cff:febe:675 prefixlen 64 scopeid 0x20<link> ether 02:42:3c:be:06:75 txqueuelen 0 (Ethernet) RX packets 81 bytes 5445 (5.3 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 92 bytes 8125 (7.9 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
-d参数能够省略,默认就是bridge。更多的参数可使用--help选项查看:
指定网卡的名称
在ifconfig查看的时候,网卡显示的名称是根据这个docker网络额ID号自动生成的。在建立网络时使用-o参数能够进行指定:
$ docker network create --subnet "192.168.112.0/24" -o "com.docker.network.bridge.name=docker1" mybr2 b8a2639ce1baef83e54b5a0bca5ba6c7bbd2e6b607e62016c930350235bea965 $ ifconfig br-7128a28bbbf3: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 192.168.111.1 netmask 255.255.255.0 broadcast 192.168.111.255 ether 02:42:1f:ff:fd:5d 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 docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 192.168.101.1 netmask 255.255.255.0 broadcast 192.168.101.255 inet6 fe80::42:3cff:febe:675 prefixlen 64 scopeid 0x20<link> ether 02:42:3c:be:06:75 txqueuelen 0 (Ethernet) RX packets 81 bytes 5445 (5.3 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 92 bytes 8125 (7.9 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 docker1: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500 inet 192.168.112.1 netmask 255.255.255.0 broadcast 192.168.112.255 ether 02:42:74:95:cd:0b 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
此次建立的网卡的名字就舒服多了。
关于-o参数,主要有下面这些:
选项 | 等同 | 描述 |
---|---|---|
com.docker.network.bridge.name | - | 建立Linux bridge使用的bridge名称 |
com.docker.network.bridge.enable_ip_masquerade | ip-masq | 启用IP假装 |
com.docker.network.bridge.enable_icc | icc | 启用或禁用容器间链接 |
com.docker.network.bridge.host_binding_ipv4 | ip | 绑定容器端口时默认绑定的IP |
com.docker.network.driver.mtu | mtu | 设置容器网络MTU |
这里没有网络基础可能不太好理解,不过咱们还能够参考默认的bridge网络的设置:
$ docker network inspect bridge [ { "Name": "bridge", "Id": "80631c00ea3ece0280c786b90f5157be68fe76c26d52f4d9d870a7f5b59edde1", "Created": "2019-07-21T10:16:03.635792707+08:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": null, "Config": [ { "Subnet": "172.17.0.0/16", "Gateway": "172.17.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": {}, "Options": { "com.docker.network.bridge.default_bridge": "true", "com.docker.network.bridge.enable_icc": "true", "com.docker.network.bridge.enable_ip_masquerade": "true", "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0", "com.docker.network.bridge.name": "docker0", "com.docker.network.driver.mtu": "1500" }, "Labels": {} } ] $
这个是默认的没有修改过的bridge桥的信息。除了Options参数,其余参数也能够参考一下。
使用自定义网络
这个以前已经用到过了。以前可选的网络只有默认提供的3个,brideg、host、none,如今建立的自定义网络也可使用了。命令docker network ls
能够查看,引用的时候使用--network参数指定网络的名称(NAME):
$ docker container run --rm -it --network mybr2 busybox / # ifconfig eth0 Link encap:Ethernet HWaddr 02:42:C0:A8:70:02 inet addr:192.168.112.2 Bcast:192.168.112.255 Mask:255.255.255.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:12 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:1032 (1.0 KiB) TX bytes:0 (0.0 B) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) / #
经过容器内的eth0的IP地址能够判断使用的是刚才建立的自定义网络。
docker守护进程是C/S构架,默认只监听本机的UNIX sock文件。该文件位于/var/run/
目录下:
$ ls /var/run/*.sock /var/run/docker.sock $
能够设置为监听TCP端口,这样就可让网络上其余主机上的客户端链接到本地的服务端。
服务端须要修改配置文件,让服务监听网络端口。配置文件/etc/docker/daemon.json
添加一个hosts属性:
{ "hosts": ["tcp://0.0.0.0:2375", "unix:///var/run/docker.sock"] }
修改配置文件后须要重启服务。默认本地的UNIX sock文件仍是保留着。
客户端要链接到服务端,使用-H或--host参数来添加服务器。直接不带任何参数执行docker命令,能够查看到帮助信息:
-H, --host list Daemon socket(s) to connect to
以前使用客户端的时候,都是不带这个参数的,也就是默认链接本机的UNIX sock文件。加上参数后,就能够指定链接的服务端了。
使用-H参数,不过指定的服务器依然是本地的UNIX sock文件:
$ docker -H unix:///var/run/docker.sock network ls
若是开启了网络的监听,能够这样:
$ docker -H 127.0.0.1 version
协议和端口号均可以省略,默认是tcp的2375端口。
不能指定多个服务器
看帮助,这个参数是个list,就是能够屡次调用-H来添加多个服务端。参数是这么设计的,可是程序的逻辑不容许:
$ docker -H unix:///var/run/docker.sock -H 127.0.0.1 images Please specify only one -H $
这里找到了源码中对应的处理函数:
func getServerHost(hosts []string, tlsOptions *tlsconfig.Options) (string, error) { var host string switch len(hosts) { case 0: host = os.Getenv("DOCKER_HOST") case 1: host = hosts[0] default: return "", errors.New("Please specify only one -H") } return dopts.ParseHost(tlsOptions != nil, host) }
参数只能是0个或1个,不然就返回错误。
设置环境变量
若是不使用-H参数指定,还能够经过环境变量DOCKER_HOST指定。好处是不用每次链接都加上-H参数了。
下面是设置和验证的命令:
$ export DOCKER_HOST="unix:///var/run/docker.sock" $ echo $DOCKER_HOST unix:///var/run/docker.sock $
这里设置的环境变量是临时生效的,从新登陆就没有了。若是想让环境变量永久生效请写入 ~/.bashrc 。