Docker(八)网络

一    引入

        当你开始大规模使用Docker时,你会发现需要了解很多关于网络的知识。Docker作为目前最火的轻量级容器技术,有很多令人称道的功能,如Docker的镜像管理。然而Docker同样有着很多不完善的地方,网络方面就是Docker比较薄弱的部分。因此我们有必要深入了解Docker的网络知识,以满足更高的网络需求。本文首先介绍了Docker自身3种网络工作方式,然后介绍一些自定义网络模式。

二   默认Docker的网络模式

Docker自身的3种网络工作方式,和一些自定义网络模式

安装Docker时,Docker引擎它会自动创建三个网络,bridge(创建容器默认连接到此网络)、 none 、host

[root@docker1 yum.repos.d]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
69e31f353b66        bridge              bridge              local  # 桥接
6cfb7a5ce613        host                host                local  # 仅主机模式
ac8b433a59ba        none                null                local  # 禁用(localhost)

#  yum whatprovides */brctl-->brctl的工具!

#  bridge-utils-1.5-9.el7.x86_64

网络的相关参数

[root@docker1 ~]# docker run --network 
bridge      host        none        overlay     
container:  macvlan     null

相关参数解释说明

Docker内置这三个网络,运行容器时,你可以使用该--network标志来指定容器应连接到哪些网络

(1)bridge网络

         如果运行容器的时候,不指定network,,Docker守护程序默认将容器连接到docker0所有Docker安装中存在的网络

说明:docker安装时会创建一个名为 docker0 的Linux bridge,新建的容器会自动桥接到这个接口

[root@docker1 ~]# brctl show
bridge name	bridge id		STP enabled	interfaces	
docker0		8000.0242fc73f70c	no              # 说明:由于没有建立容器,所以没有接口

特点:此模式会为每一个容器分配、设置IP等,并将容器连接到一个docker0虚拟网桥,通过docker0网桥以及iptables nat表配置与宿主机通信

备注:默认IP是会递增的,是该网段的一个IP,一旦容器关闭或者删除会释放IP资源

缺点:bridge模式下容器没有一个公有ip(缺点1),只有宿主机可以直接访问外部主机是不可见的(缺点-->私有网络,内部隔离),但容器()通过宿主机的SNAT规则(地址伪装--MASQUERADE)后可以访问外网

补充:SNAT使用固定IP地址,MASQUERADE使用网卡上的地址

细节:看镜像的构建历史(docker history image),了解一些必要的信息才能更好的构建

图谱

通信机理:容器访问外界,通过docker0接口网关(gateway),然后进行路由转发(不同的网段--ip_forward)与宿主机通信!

虚拟网络对:一根网线的两根,连接各自的namespace(网络命名空间)!

说明:docker安装的时候默认帮我们开启了路由转发!

SDN( Software Define Network),软件定义网络,用户不需要直接操作硬件,鼠标点一点,隔离了用户对于硬件的依赖!

(2)host网络

  host网络模式需要在容器创建时指定--network=host,host模式可以让容器共享宿主机网络栈,这样的好处是外部主机与容器直接通信,但是容器的网络缺少隔离性

说明:host模式是桥接模式的有力补充,即桥接模式下容器没有公共的IP(解决bridge的问题)!

缺点:宿主机和容器共享一份网络资源,端口不能冲突,使用一个网络命名空间,所以有资源争抢的问题!

仅主机模式,容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口,共享网络栈,同一个命名空间!   

对比

说明:由于共享网络资源,所以没有接口(用bridge,会有接口)

核心:会引起安全问题,宿主机和网络机共享不经过docker0!

host的其它好处:可以直接用localhost来访问!

其它好处:如果全部采用host网络方式,容器间共享一个网络资源

(3)Container

特点:创建的容器不会创建自己的网卡、不会配置自己的IP,而是和一个指定的容器共享IP、端口范围。

Container 网络模式是 Docker 中一种较为特别的网络的模式,在容器创建时使用--network=container:connam指定

好处:处于这个模式下的 Docker 容器会共享一个网络栈,这样两个容器之间可以使用localhost高效快速通信

弊端:容器之间的隔离性能被破坏!

一个应用不知道IP的情况下,这种模式容器之间可以通过localhost:3306(数据库)来访问,原来通过TCP,现在通过回环地址lo搞定,加快网络通信的速度!

说明:这里举一个Nginx的案例

(4)None

特点:该模式禁用(关闭)容器的网络功能只有lo接口,在容器创建时使用,--network=none指定

应用:容器特殊存在,生成token,存储一些敏感密码文件不需要网络通信,必须做这些隔离

[root@docker2 ~]# docker run -it --name vm2 --network=none ubuntu
root@eff58bc49e6e:/# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    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
root@eff58bc49e6e:/# mysql数据库

说明:没有网络,必须在本机,否则无法访问!

三    高级网络

 (1)自定义网络模式,docker提供了三种自定义网络驱动:

#   bridge overlay macvlan 

bridge驱动类似默认的bridge网络模式,但增加了一些新的功能, overlay和macvlan是用于创建跨主机网络

建议:使用自定义的网络来控制哪些容器可以相互通信,还可以自动DNS解析容器名称到IP地址

自定义的桥接和默认原生的桥接区别自定义内置DNS解析!

自定义bridge网络

[root@docker2 ~]# docker network create --help|grep '\-d'
  -d, --driver string        Driver to manage the Network (default "bridge") # 默认的驱动
      --ipam-driver string   IP Address Management Driver (default "default")
[root@docker2 ~]# docker network create -d 
bridge   macvlan  overlay
[root@docker2 ~]# docker network create my_net1
6f56371978a715ced6917edffccad05c9bff9fe735fff4df229671a897a534d7
[root@docker2 ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
21e12cecf441        bridge              bridge              local
94120fcefcf0        host                host                local
6f56371978a7        my_net1             bridge              local  # 增加的
0a9bf240468c        none                null                local

容器之间除了使用ip通信外,还可以使用容器名称通信,因为做了DNS解析

docker 1.10开始,内嵌了一个DNS server,dns解析功能必须在自定义网络中使用

说明:自定义网络又增加了一个桥接口(不同的网段)

docker引擎又自动给我们创建了桥接口,默认是动态单调递增释放后会回收

# 查看创建网段的相关的信息

docker network inspect vm1

进一步需求:创建自定义网桥,指定网段和网关

说明:是不是还不满足,分配的IP资源虽然是自己递增的,如果容器有多个,并不知道容器的IP,可以自定义ip

补充:--ip指定容器ip地址,但必须是在自定义网桥上(自定义网络相关信息等),同一网桥上的容器是可以互通

###########################

需求:创建两个容器,并桥接到不同的网桥上,默认彼此是不通信的(隔离)!

iptables -S

-A DOCKER-ISOLATION-STAGE-1 -i br-d39efc8fa01f ! -o br-d39efc8fa01f -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -i br-6f56371978a7 ! -o br-6f56371978a7 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -j RETURN

docker在设计上就是要隔离不同network的

需求:使不同网桥的进行通信

[root@docker1 ~]# docker network connect --help

Usage:	docker network connect [OPTIONS] NETWORK(网络) CONTAINER(容器)

# 说明--->容器也使用该网络

实质:使用 docker network connect命令为vm1容器添加一块my_net2 的网卡,便于不同网段的通信

root@18c49c18bae4:/# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    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
20: eth0@if21: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
       valid_lft forever preferred_lft forever
22: eth1@if23: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:1e:00:03 brd ff:ff:ff:ff:ff:ff
    inet 172.30.0.3/24 brd 172.30.0.255 scope global eth1
       valid_lft forever preferred_lft forever
root@18c49c18bae4:/# 多块网卡-->不同网段!

现象又增加一块网卡两个网段的IP

[root@docker2 ~]# brctl show
bridge name	bridge id		STP enabled	interfaces
br-6f56371978a7		8000.0242a53d3aa3	no	veth1a9ed7d
br-d39efc8fa01f		8000.02424ad6e5e1	no	veth0edde9d  # 看此处的信息!
					                veth24cff9e
docker0		8000.02427b9fda13	no	

########link的三个作用#########

#     说明:ctrl+(p|q)->打入后太   --->docker container attach vm1

(1) link方式做了本地解析

(2)应用变量的传递

# env -->查看环境变量

WEB_ENV_NGINX_VERSION=1.17.2
WEB_PORT_80_TCP_PORT=80
WEB_PORT_80_TCP=tcp://172.17.0.2:80
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/
SHLVL=1
HOME=/root
WEB_NAME=/vm1/web                # nginx的环境变量1
WEB_PORT_80_TCP_PROTO=tcp        
WEB_PORT_80_TCP_ADDR=172.17.0.2  # nginx的环境变量2
LESSOPEN=| /usr/bin/lesspipe %s  # nginx的环境变量3
WEB_PORT=tcp://172.17.0.2:80
LESSCLOSE=/usr/bin/lesspipe %s %s
_=/usr/bin/env

说明:会把变量信息(应用)注册到当前的容器中!

(3)把关闭的容器,重新拉起来

docker container stop nginx  # 注意是停止而不是删除!

docker run -d nginx:1.16     # 上面停止之后,会释放IP资源,所以这里开启一个容器先占用IP!

docker container start nginx # 把容器起起来

/etc/hosts发生变化!          # 结果:IP发生变化,环境变量不变!

四    高级网络配置

##############容器内部访问外界#####################

(1)容器如何访问外网是通过iptables的SNAT实现的

#################外网如何访问容器#####################

外网如何访问容器: 端口映射

说明:-p(指定端口的关联)和P(宿主机随机开启一个端口)参数的区别

相关说明

外网访问容器用到了docker-proxy和iptables DNAT
宿主机访问本机容器使用的是iptables DNAT
外部主机访问容器或容器之间的访问是docker-proxy实现

 

###########网络的高级的进阶###########

(1)跨主机网络解决方案

docker原生的overlay和macvlan

第三方的flannel、weave、calico

众多网络方案是如何与docker集成在一起的

libnetwork     docker容器网络库

CNM (Container Network Model)这个模型对容器网络进行了抽象

CNM的补充

其它

(2)overlay

作用:应用层(开发人员),可以支持更多的虚拟子网,用于跨主机!

(3)macvlan

作用:用在底层二层(CT人员),通过物理接口(etho网卡),用在跨主机,运营开发商!

特点:macvlan网络方案实现 LInux kernel提供的一种网卡虚拟化技术, 无需Linux bridge,直接使用物理接口,性能极好

# 说明:最好是my2 ,创建容器的ip一定要不一样!
ip link set up eth1           # 在两台docker主机上各添加一块网卡,并且开启网卡
ip link set eth1 promisc on   # 打开网卡混杂模式
docker network create -d macvlan --subnet 172.100.0.0/24 --gateway 172.100.0.1 -o parent=eth1 mac_net1
docker run -it --name my2 --network mac_net1 --ip 172.100.0.10 ubuntu

# 测试 : ping 跨主机的ip  -->可以ping通

# 说明:必须自定义一些网络参数

# 说明:另一台主机也必须操作相同的步骤,IP必须不一样,容器的名字可以不一样(隔离),最好不一样!

# 注意:一定要在两台docker主机上各创建macvlan网络,最后ping ip测试!

macvlan网络结构分析

(1)没有新建linux bridge

brctl show

(2)容器的接口直接与主机网卡连接,无需NAT或端口映射

docker exec vm1 ip link   # 对于一些应用可以通过exec交互

问题:macvlan会独占主机网卡,但是网络资源是有限的

可以使用vlan子接口实现多macvlan网络,vlan可以将物理二层网络划分为4094个逻辑网络,彼此隔离,vlan id取值为1~4094

创建方式

docker network create -d macvlan --subnet 172.100.0.0/24 --gateway 172.100.0.1 -o parent=eth1.1 mac_net1

docker network create -d macvlan --subnet 172.100.0.0/24 --gateway 172.100.0.1 -o parent=eth1.2 mac_net1

总结:macvlan网络间的隔离和连通

(1)macvlan网络在二层上是隔离的,所以不同macvlan网络的容器是不能通信的

(2)可以在三层上通过网关(路由器)将macvlan网络(不同的网段)连通起来。

(3)docker本身不做任何限制,像传统vlan网络那样管理即可

补充:可以通过 docker network connect nt container 的方式在容器增加一个网卡的方式来进行通信!

(3)网络插件

地址:后续补充

底层原理1

底层原理2

补充

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值