Docker网络
Docker网络
类型
Closed container
:封闭式容器,Loopback interface,
bridge
:包括private interface和Loopback interface, 默认docker使用的网络类型,通常为172.17.0.0/16段的私有地址来连接到docker桥虚拟接口上。
Joined Container
:联盟式容器网络,容器的部分名称空间可以共享,但诸如User、Mount等还是完全隔离的。
$ docker exec -it b1 sh
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:03
`inet addr:172.17.0.3 Bcast:172.17.255.255 Mask:255.255.0.0`
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:34 errors:0 dropped:0 overruns:0 frame:0
TX packets:20 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:3982 (3.8 KiB) TX bytes:1458 (1.4 KiB)
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:1 errors:0 dropped:0 overruns:0 frame:0
TX packets:1 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:28 (28.0 B) TX bytes:28 (28.0 B)
# --network container:b1 ,b2可以采用b1容器的部分名称空间
$ docker run --name b2 --network container:b1 -it --rm busybox:latest
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:03
`inet addr:172.17.0.3 Bcast:172.17.255.255 Mask:255.255.0.0`
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:34 errors:0 dropped:0 overruns:0 frame:0
TX packets:20 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:3982 (3.8 KiB) TX bytes:1458 (1.4 KiB)
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:1 errors:0 dropped:0 overruns:0 frame:0
TX packets:1 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:28 (28.0 B) TX bytes:28 (28.0 B)
# 注意,事实上,两个容器的文件系统实际上还是隔离的,网络是共享的。
# 在b2容器写入信息
$ echo "hello world!!!" > /tmp/index.html \
> && httpd -h /tmp/ \
> && netstat -tnl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 :::80 :::* LISTEN
# 在b1容器进行访问
$ wget -O - -q 127.0.0.1
hello world!!!
# 上述演示,再一次表明,b1和b2是共享网络的。
Open container
:容器共享宿主机的名称空间。开放的是物理网卡。docker network ls 看到 的“host”就是采用此类型。
$ docker run --name b2 --network host -it --rm busybox:latest
/ # ifconfig 就可以看到是共享了宿主机的网络。
$ echo "hello container!!!" > /tmp/index.html \
> && httpd -h /tmp/ \
> && netstat -tnl
# 然后在宿主机上打开
$ curl 172.16.4.4:80
hello container!!!
$ docker network ls
# 安装工具包
$ yum install bridge-utils -y
$ docker network inspect bridge
同一宿主机之间的容器互相访问:bridge
采用物理机访问容器,可以采用curl命令,比如:
curl http://172.17.0.2
不同宿主机之间的容器需要互相访问:
除了NAT桥接,可以采用共享命名空间,或者共享物理命名空间。
创建容器时指定网络
# 指定bridge,事实上,不指定默认也是bridge, --rm表示容器退出时,自动销毁。
$ docker run --name t1 -it --network bridge --rm busybox:latest
# 指定无网络
$ docker run --name t1 -it --network none --rm busybox:latest
# -h从容器外部指定容器主机名, --hostname HOSTNAME。
$ docker run --name t1 -it --network none -h test --rm busybox:latest
/ # 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)
# 为容器指定所使用的dns服务器地址,--dns DNS_SERVER_IP
$ docker run --name t1 -it --network bridge -h test --dns 114.114.114.114 --rm busybox:latest
# 指定dns搜索域,--dns-search
docker run \
> --name t1 \^C
[root@docker1 ~]# docker run -it \
> --name t1 \
> --network bridge \
> -h test \
> --dns 114.114.114.114 \
> --dns-search ilinux.io \
> --rm busybox:latest
# 为容器指定本地主机名解析项。--add-host
$ docker run -it --name t1 --network bridge -h test --dns 114.114.114.114 --dns-search ilinux.io --add-host www.baidu.com:8.8.8.8 --rm busybox:latest
开放容器端口
-
-p 选项的使用格式
-
-p containerPort
将指定的容器端口映射到宿主机所有地址的一个动态端口
$ docker run --name myweb --rm -p 80 gezr17/httpd:v0.2 # 如下,可以发现是32768端口被映射到了。 $ iptables -t nat -vnL | grep docker 0 0 MASQUERADE all -- * !docker0 172.17.0.0/16 0.0.0.0/0 0 0 RETURN all -- docker0 * 0.0.0.0/0 0.0.0.0/0 0 0 DNAT tcp -- !docker0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:32768 to:172.17.0.4:80
-
-
-p hostPort:containerPort
将容器端口containerPort映射到指定的主机端口
$ docker run --name myweb --rm -p 80:80 gezr17/httpd:v0.2 $ docker port myweb 80/tcp -> 0.0.0.0:80
-
-p ip::containerPort
将指定的容器端口映射到主机指定ip的动态端口。
$ docker run --name myweb --rm -p 172.16.4.4::80 gezr17/httpd:v0.2 $ docker port myweb 80/tcp -> 172.16.4.4:32768
-
-p ip : hostPort:containerPort
将指定的容器端口containerPort映射到主机指定ip的端口hostPort
$ docker run --name myweb --rm -p 172.16.4.4:8080:80 gezr17/httpd:v0.2 $ xdocker port myweb 80/tcp -> 172.16.4.4:8080
注意:“动态端口”指的是随机端口与,具体映射结果可使用docker port查看,并且可以暴露多个端口。
自定义docker0桥的网络信息
修改/etc/docker/daemon.json文件
{
"bip":"192.168.169.0/24",
"fixed-cidr":"10.20.0.0/16",
"mtu":1500,
"default-gateway":"10.20.1.1",
"default-gateway-v6":"2001:db8:abcd :: 89",
"dns":["202.201.0.131","202.201.0.132","202.201.0.133"]
}
# bip为核心选项,即bridge ip之意,用于指定docker0桥自身的IP地址;其他选项可通过此地址计算得出。
# dockerd守护进程的C/S,其默认仅监听Unix Socket格式的地址,/var/run/docker.sock;如果使用TCP套接字,/etc/docker/daemon.json:
"hosts": ["tcp://0.0.0.0:2375","unix:///var/run/docker.sock"]
# 也可向dockerd直接传递“—H|--host”选项
创建网络
$ docker network create --help
Usage: docker network create [OPTIONS] NETWORK
Create a network
Options:
--attachable Enable manual container attachment
--aux-address map Auxiliary IPv4 or IPv6 addresses used by Network driver (default map[])
--config-from string The network from which copying the configuration
--config-only Create a configuration only network
-d, --driver string Driver to manage the Network (default "bridge")
--gateway strings IPv4 or IPv6 Gateway for the master subnet
--ingress Create swarm routing-mesh network
--internal Restrict external access to the network
--ip-range strings Allocate container ip from a sub-range
--ipam-driver string IP Address Management Driver (default "default")
--ipam-opt map Set IPAM driver specific options (default map[])
--ipv6 Enable IPv6 networking
--label list Set metadata on a network
-o, --opt map Set driver specific options (default map[])
--scope string Control the network's scope
--subnet strings Subnet in CIDR format that represents a network segment
# 自定义网络桥
$ docker network create -d bridge --subnet "172.26.0.0/16" --gateway "172.26.0.1" mybr0
# 通过修改桥的设备名,使其易于记忆
$ ip link set dev br-b28d19d35788 down
$ ip link set dev br-b28d19d35788 name docker1
$ ip link set dev dokcer1 up
$ ifconfig
docker1: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.26.0.1 netmask 255.255.0.0 broadcast 172.26.255.255
ether 02:42:b7:ac:d1:52 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
# 通过自定义网桥,可以用于创建新的容器中。
$ docker run -it --name t1 --net mybr0 busybox:latest
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:1A:00:02
`inet addr:172.26.0.2 Bcast:172.26.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:1 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:1032 (1.0 KiB) TX bytes:42 (42.0 B)
# 现在假设宿主机有原来的container t1,那么如上的“172.26.0.2”和“172.17.0.2”怎么通信?
$ docker run -it --name t2 --net bridge busybox:latest
/ # 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:1 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:656 (656.0 B) TX bytes:42 (42.0 B)
# 查看网络的核心转发是否打开?
$ cat /proc/sys/net/ipv4/ip_forward
1