前言
前面学习了docker镜像与仓库
docker容器技术1–镜像篇
docker容器技术2 --企业级仓库管理harbor使用
这里开始学习docker网络
-
docker的镜像是令人称道的地方,但网络功能还是相对薄弱的
部分。 -
docker安装后会自动创建3种网络:bridge、host、none
1、docker的基本网络部署
1.1 docker默认网络模式
docker安装后会自动创建3种网络:bridge、host、none
查看命令:docker network ls
1.2 bridge网络模式
docker安装时会创建一个名为 docker0 的Linux bridge,新建的容器
会自动桥接到这个接口。
yum install -y bridge-utils.x86_64 ##安装brctl命令工具
ip addr show docker0
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:2e:b4:70:c8 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
inet6 fe80::42:2eff:feb4:70c8/64 scope link
valid_lft forever preferred_lft forever
brctl show
bridge name bridge id STP enabled interfaces
br-681724d5d5c4 8000.02428c1a34e2 no
docker0 8000.02422eb470c8 no
docker run -d nginx
74399ee9d8d03abd6aa601bc5cd3e03231a6c9b331baacb37efda0be001c6625
brctl show
bridge name bridge id STP enabled interfaces
br-681724d5d5c4 8000.02428c1a34e2 no
docker0 8000.02422eb470c8 no veth1ded719
bridge模式下容器没有一个公有ip,只有宿主机可以直接访问,外部主机是
不可见的,但容器通过宿主机的NAT规则后可以访问外网。
1.3 host网络模式
host网络模式需要在容器创建时指定–network=host
docker run -d --name demo --network=host nginx
b6aaaed51b40a0951f501292a1e65ea7927c752b2bcfc4517e4f41f8b3c5a9ef
brctl show
bridge name bridge id STP enabled interfaces
br-681724d5d5c4 8000.02428c1a34e2 no
docker0 8000.02422eb470c8 no #共享宿主机网络栈,所以没有bridge记录
host模式可以让容器共享宿主机网络栈,这样的好处是外部主
机与容器直接通信,但是容器的网络缺少隔离性。
1.4 none模式
none模式是指禁用网络功能,只有lo接口,在容器创建时使用
–network=none指定。
docker run -it --rm --network=none busybox
/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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
1.5 Container 网络模式
Container 网络模式是 Docker 中一种较为特别的网络的模式。
在容器创建时使用–network=container:vm1指定。(vm1指定的
是运行的容器名)
处于这个模式下的 Docker 容器会共享一个网络栈,这样两个
容器之间可以使用localhost高效快速通信。
2、高级网络配置之自定义网桥
自定义网络模式,docker提供了三种自定义网络驱动:
bridge
overlay 跑在应用层,适合IT专家
macvlan 跑在链路层 通信更快;适合CT专家
bridge驱动类似默认的bridge网络模式,但增加了一些新的功能,overlay和macvlan是用于创建跨主机网络。
建议使用自定义的网络来控制哪些容器可以相互通信,还可以自动DNS解析容器名称到IP地址。
2.1 自定义网桥
测试bridge的ip自动回收与顺序重分配
docker images ##查看镜像
docker ps -a ##保证没有任何进程,有的话删除
docker run -d --name demo webserver ##运行demo
docker inspect demo | grep "IPAddress" ##查看IP
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.2",
"IPAddress": "172.17.0.2",
docker stop demo ##停止运行demo
docker run -d --name demo2 reg.westos.org/nginx # 运行demo2
docker inspect demo2 | grep "IPAddress" #查看ip 拿到刚才demo的.2
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.2",
"IPAddress": "172.17.0.2",
docker start demo ##重新启动demo
docker inspect demo | grep "IPAddress" ##ip只能递增拿到3
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.3",
"IPAddress": "172.17.0.3",
指定网段和网关
使用--ip参数可以指定容器ip地址,但必须是在自定义网桥上,默认的bridge模式不支持,同一网桥上的容器是可以互通的。
docker network ls
docker network create --subnet 172.20.0.0/24 --gateway 172.20.0.1 net1 ##自定义子网和网关
docker inspect net1
ip addr
docker run -it --rm --ip 172.20.0.10 --network net1 busybox
/ # ip addr
那么如何使两个不同网桥的容器通信呢
net1网卡在上面已经设置为172.20.0.0网段了。demo还是默认的172.17.0.0网段。只需要把net1网卡加上就可以了
docker network connect net1 demo #使用 docker network connect命令为demo添加一块net1 的网卡
docker inspect demo
2.2 容器间的通信
2.2.1 docker内的dns解析
- 容器之间除了使用ip通信外,还可以使用容器名称通信
- docker 1.10开始,内嵌了一个DNS server。
- dns解析功能必须在自定义网络中使用。
- 启动容器时使用 --name 参数指定容器名称。
2.2.2 link
--link 可以用来链接2个容器。
--link的格式:
--link <name or id>:alias
name和id是源容器的name和id,alias是源容器在link下的别名。
2.3 容器如何访问外网是通过iptables的SNAT实现的
容器如何访问外网是通过iptables的SNAT实现的
2.4 外网如何访问容器
2.4.1 需要做端口映射
- 端口映射
- -p 选项指定映射端口
2.4.2 外网访问容器用到了docker-proxy和iptables DNAT
外网访问容器用到了docker-proxy和iptables DNAT
- 宿主机访问本机容器使用的是iptables DNAT
- 外部主机访问容器或容器之间的访问是docker-proxy实现
proxy和DNAT只要存在一种就可以进行通讯,是一种双冗余设置,localhost使用docker-proxy转发
3、高级网络配置之跨主机网络(网络进阶)
3.1 跨主机网络解决方案
- docker原生的overlay和macvlan
- 第三方的flannel、weave、calico
众多网络方案是如何与docker集成在一起的
- libnetwork
- docker容器网络库
- CNM (Container Network Model)这个模型对容器网络进行了抽
象
CNM分三类组件
- Sandbox:容器网络栈,包含容器接口、dns、路由表。(namespace)
- Endpoint:作用是将sandbox接入network (veth pair)
- Network:包含一组endpoint,同一network的endpoint可以通信。
3.2 macvlan 网络方案实现
介绍
Linux kernel提供的一种网卡虚拟化技术。(内核自带)
无需Linux bridge,直接使用物理接口,性能极好。
搭建步骤
- 在两台docker主机上各添加一块网卡,打开网卡混杂模式
- 在两台docker主机上各创建macvlan网络
macvlan网络结构分析
- 没有新建linux bridge
- 容器的接口直接与主机网卡连接,无需NAT或端口映射。
[root@server2 ~]# brctl show
bridge name bridge id STP enabled interfaces
br-283cf1fc96c1 8000.02426d0e4f33 no
docker0 8000.024257e101e8 no
macvlan会独占主机网卡,但可以使用vlan子接口实现多macvlan网络
vlan可以将物理二层网络划分为4094个逻辑网络,彼此隔离,vlan id取值为1~4094。
macvlan网络间的隔离和连通
- macvlan网络在二层上是隔离的,所以不同macvlan网络的容器是不能通信的。
- 可以在三层上通过网关将macvlan网络连通起来。
- docker本身不做任何限制,像传统vlan网络那样管理即可。
步骤截图
server1和server2都添加成俩个网卡
实现不同主机之间通信
server1和server2同样的操作
ip link set up eth1 ##激活网卡
ip link set eth1 promisc on ##打开混杂模式PROMISC
ip addr show eth1
36: eth1: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 52:54:00:64:dd:fd brd ff:ff:ff:ff:ff:ff
inet6 fe80::5054:ff:fe64:ddfd/64 scope link
valid_lft forever preferred_lft forever
docker network create -d macvlan --subnet 172.21.0.0/24 --gateway=172.21.0.1 -o parent=eth1 mac_net1
##使用eth1网卡
docker inspect mac_net1 | grep "parent"
"parent": "eth1"
docker run -it --rm --network mac_net1 --ip 172.21.0.11 busybox ##server1设置为11,server2设置为12
WARNING: IPv4 forwarding is disabled. Networking will not work.
/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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
37: eth0@if36: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:15:00:0b brd ff:ff:ff:ff:ff:ff
inet 172.21.0.11/24 brd 172.21.0.255 scope global eth0
valid_lft forever preferred_lft forever
/ # ping 172.21.0.12
PING 172.21.0.12 (172.21.0.12): 56 data bytes
64 bytes from 172.21.0.12: seq=0 ttl=64 time=0.375 ms
vlan可以将物理二层网络划分为4094个逻辑网络,彼此隔离,vlan id取值为1~4094。
3.3 docker network 子命令小结
docker network 【参数】 【网络名称】
connect 连接容器到指定网络
create 创建网络
disconnect 断开容器与指定网络的连接
inspect 显示指定网络的详细信息
ls 显示所有网络
rm 删除网络