侧边栏壁纸
博主头像
周乐的个人博客 博主等级

行动起来,活在当下

  • 累计撰写 7 篇文章
  • 累计创建 9 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

Docker网络

Administrator
2024-03-01 / 0 评论 / 0 点赞 / 0 阅读 / 0 字

1. Docker四种网络模式

1)bridge模式(默认)

Docker使用Linux虚拟网络技术在宿主机虚拟一个名为docker0的虚拟网桥。

Docker启动一个容器时会根据Docker0网桥的网段分配给容器一个IP地址(可通过:docker inspect 容器名/ID 查看容器地址),同时Docker网桥作为每个容器的默认网关,虚拟网桥的工作方式和物理交换机类似,因为在同一宿主机内的容器都接入同一个网桥,这样主机上的所有容器就通过交换机(docker0)连在了一个二层网络中直接通信。

当创建一个 Docker 容器的时候,同时会创建了一对 veth pair接口(当数据包发送到一个接口时,另外一个接口也可以收到相同的数据包)。这对接口一端在容器内,即 eth0;另一端在本地并被挂载到docker0 网桥,名称以 veth 开头(例如 vethAQI2QT)。通过这种方式,主机可以跟容器通信,容器之间也可以相互通信。Docker 就创建了在主机和所有容器之间一个虚拟共享网络。

Docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法通过直接容器IP访问到容器,如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主机。

img

示例:创建容器并指定bridge模式

格式:--net=bridge

[root@localhost ~]# docker run -id --name=nginx --net=bridge -p 81:80 nginx:1.20.2

查看容器网络:

[root@localhost ~]# docker inspect nginx
...
   "bridge": {
   

2)Host模式

在Host类型的网络中,容器不会虚拟出自己的网卡,而是与物理机共享网络,拥有物理机的IP地址和网卡信息,而容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。

Host最大的优势就是网络性能比较好,不需要进行NAT,可以直接使用宿主机的IP地址/端口与外界通信。

示例:创建容器并指定Host模式

提示:此模式无法通过-p为容器指定端口,容器内部的服务使用的是宿主机端口,各个host模式的容器不能有端口冲突。

格式:--net=host

[root@localhost ~]# docker run -id --name=nginx_host --net=host  nginx:1.20.2

查看容器网络

[root@localhost ~]# docker inspect nginx_host
...
   host": {
   

查看宿主机端口信息

[root@localhost ~]# netstat -ntlp

访问宿主机地址:http://192.168.0.10/

3)Container模式

这个模式指定新创建的容器和已经存在的一个容器共享一个网络,而不是和宿主机共享。

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

同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo(回环) 网卡设备通信。

示例:创建容器并与其他容器公用网络

格式:--net=container:容器名/容器ID

[root@localhost ~]# docker run -id --name=ngx_container --net=container:nginx nginx:1.20.2

4)None模式

None类型的网络,即没有网络,Docker容器不会设置容器内网络的任何信息,不会对网络进行任何配置,但是我们自己可以给该容器添加配置,给予其网络环境。

示例:创建容器并使用None模式

格式:--net=none

[root@localhost ~]# docker run -id --name=nginx_none --net=none nginx:1.20.2

查看容器网络

[root@localhost ~]# docker inspect nginx_none
...
 "none": {
​

2. Docker自定义网络

自定义容器网络可使不同的集群使用不通的网络,保证了集群是安全和健康的。

查看所有docker网络:docker network ls

[root@localhost ~]# docker network ls
NETWORK ID     NAME        DRIVER    SCOPE
网络 ID        网络名称      网络模式    作用域

自定义docker网络:docker network create --driver bridge --subnet 192.168.1.0/24 --gateway 192.168.1.254 mynet

  • create #创建网络

  • --driver #定义网络模式

  • --subnet #定义网络IP

  • --gateway #指定网关

  • mynet #是自己定义的网络名称

示例:创建一个自定义网络

[root@localhost ~]# docker network create --driver bridge --subnet 192.168.1.0/24 --gateway 192.168.1.254 mynet
​
#创建容器并指定容器使用mynetwork网络
[root@localhost ~]# docker run -id --net mynetwork --ip 172.15.1.10 --name=myngx nginx:1.20.2

创建容器使用自定义网络:--net=名称

[root@localhost ~]# docker run -id --name=ngx_mynet --net=mynet -p 82:80 nginx:1.20.2

创建容器使用自定义网络并自定义容器IP:--ip 地址

[root@localhost ~]# docker run -id --name=ngx_mynet_v1 --net=mynet --ip 192.168.1.10 -p 83:80 nginx:1.20.2

查看网络详细信息:docker network inspect 网络名称/ID

[root@localhost ~]# docker network inspect mynet

容器加入网络:docker network connect 网络名 容器名

自定义网络和默认网络是不通的,这样就起到了隔离的作用,那如果我们想要打通这两个网络要使用 connect 将容器加入到该网络

[root@localhost ~]# docker network connect mynet nginx

查看容器网络(该容器有两个网络)

[root@localhost ~]# docker inspect nginx
...
   "bridge": {                                      "mynet": {

提示:打通后,默认网络和自定义网络就可以互相通信

删除网络:docker network rm 网络名

[root@localhost ~]# docker network rm  mynet

提示:如果有其他容器使用该网络,需要先清理容器。

容器之间如果想要通过容器名称进行通信的话,可以通过--link来实现容器互联(单方向互联)

格式:--link name:alias

  • name表示要链接的容器的名称

  • alias是别名(也可以不指定别名)

示例:启动centos_1容器

[root@localhost ~]# docker run -id --name=centos_1 centos:7

启动centos_2容器,并与centos_1互联

[root@localhost ~]# docker run -id --name=centos_2 --link centos_1 centos:7

进入容器验证(注意:是单方向互联)

[root@localhost ~]# docker exec -it centos_2 /bin/bash
[root@d6f1a8fd8cd2 /]# ping centos_1

查看容器的/etc/hosts文件

[root@d6f1a8fd8cd2 /]# cat /etc/hosts
172.17.0.3  centos_1 c64ac9f7fbb0

注:当容器创建并启动后,会自动在hosts文件里添加解析,对于容器来说,它自己知道自己的IP地址,在没有添加--link的时候是没有172.17.0.3的解析的,当添加--link的时候,这条会自动添加。

4. Docker容器跨主机通信

docker默认的自定义网络的类型就是bridge,但是跨主机的时候bridge就明显不可用的

原生的docker跨主机通信方案有macvlan和overlay两种。

4.1 什么叫Macvlan网络?

macvlan 本身是 linxu kernel 模块,其功能是允许在同一个物理网卡上配置多个 MAC 地址,即多个 interface,每个 interface 可以配置自己的 IP。macvlan 本质上是一种网卡虚拟化技术。

使用Macvlan需要注意以下几点: 容器直接连接物理网络,由物理网络负责分配IP地址,可能的结果是物理网络IP地址被耗尽,另一个后果是网络性能问题,物理网络中接入的主机变多,广播包占比快速升高而引起的网络性能下降问题;宿主机上的物理网卡(ens33)需要工作在 混乱模式 下;前面说到,工作在混乱模式下的物理网卡,其MAC地址会失效,所以,此模式中运行的容器并不能与外网进行通信,但是不会影响宿主机与外网通信;从长远来看bridge网络与overlay网络是更好的选择,原因就是虚拟网络应该与物理网络隔离而不是共享。

Macvlan本身不创建网络,本质上首先使宿主机物理网卡工作在‘混杂模式’,这样物理网卡的MAC地址将会失效,所有二层网络中的流量物理网卡都能收到。接下来就是在这张物理网卡上创建虚拟网卡,并为虚拟网卡指定MAC地址,实现一卡多用,在物理网络看来,每张虚拟网卡都是一个单独的接口。

4.2 什么叫做overlay网络?

overlay网络用于连接不同机器上的docker容器,允许不同机器上的容器相互通信,同时支持对消息进行加密。

字面意思就是叠加的网络,指的就是在物理网络层上再搭建一层网络,通过某种技术再构建一张相同的网络,这张称为逻辑网。

也就是说我们想要两台主机的容器进行通讯,首先这两台主机自己要可以通讯,然后在这个物理机的基础之上部署一张逻辑层的网络,他具有物理网络的所有特性,跟物理网络一模一样。

VLAN是什么,我们想要划分网络就叫做VLAN,VLAN只是单纯的对物理网络进行划分,隔离ip,Mac。VLAN是划分广播域的最基础概念。

vxlan是在物理网络基础之上构建出来的网络,这个网络可以通过 vxlan进行划分,ip,Mac只需要在一个vxlan中就可以进行通讯。

因此,Overlay网络实际上是目前最主流的容器跨节点数据传输和路由方案。

4.3 Overlan环境准备

主机名

IP地址

角色

docker10

192.168.0.10

docker主机

docker11

192.168.0.11

docker主机

consul

192.168.0.12

consul主机

注:每个节点安装Docker服务,每台宿主机的hostname必须不同。

4.4 运行consul服务

Docker Overlay 网络需要一个 key-value数据库用于保存网络状态信息, 包括 Network、Endpoint(节点)、IP 等。

Consul、Etcd 和 ZooKeeper 都是 Docker 支持的 key-vlaue 软件,我们这里使用 Consul。

在consul主机执行如下命令:

[root@consul ~]# docker run -d -p 8500:8500 -h consul --name consul --restart always progrium/consul -server -bootstrap
​
解释:
- -server -bootstrap    #指定运行模式(该模式指定本机为server端)
- -h                    #设置容器主机名
--restart always        #设置容器退出后自动自动容器

4.5 Docker节点加入consul

修改其他节点配置文件,使得每一台都通过本机的2376(docker监听端口)端口被转发到192.168.0.12:8500,consul收集存储并使用这些信息实现网络一致。

docker10主机修改/usr/lib/systemd/system/docker.service文件,将文件中的ExecStart参数替换成如下参数(根据自己的环境修改consul地址)

[root@docker10 ~]# vim /usr/lib/systemd/system/docker.service
...
ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2376 --cluster-store=consul://192.168.0.12:8500 --cluster-advertise=ens32:2376
​
解释:
--cluster-store    #指定consul地址
--clusteradvertise #指定本机网卡及端口

重启服务

[root@docker10 ~]# systemctl daemon-reload
[root@docker10 ~]# systemctl restart docker

直接将配置文件拷贝到docker11与consul主机即可

#拷贝到docker11主机
[root@docker10 ~]# scp /usr/lib/systemd/system/docker.service root@192.168.0.11:/usr/lib/systemd/system/docker.service
​
#拷贝到consul主机
[root@docker10 ~]# scp /usr/lib/systemd/system/docker.service root@192.168.0.12:/usr/lib/systemd/system/docker.service

docker11重启docker服务

[root@docker11 ~]# systemctl daemon-reload
[root@docker11 ~]# systemctl restart docker

consul重启docker服务

[root@consul ~]# systemctl daemon-reload
[root@consul ~]# systemctl restart docker

4.6 访问consul

最后我们可以通过浏览器访问consul服务:http://192.168.0.12:8500/

不同主机的docker已经添加到了一起。

4.7 创建Overlan网络

在任意一个节点创建一个网络,我们在docker10创建一个网络

[root@docker10 ~]# docker network create -d overlay myovernet

提示:网络默认使用的10.0.0.0/24网段,如果需要自定义网络地址通过下边命令创建。(别跟宿主机在同一个网络,容易发生地址冲突)

docker network create -d overlay --subnet 172.16.1.0/24 --gateway 172.16.1.254  myovernet

4.8 验证Overlan网络

这时候每一个节点都会有这个网络

#docker10主机查看
[root@docker10 ~]# docker network ls
60210366228b   myovernet   overlay   global
​
#docker11主机查看
[root@docker11 ~]# docker network ls
60210366228b   myovernet   overlay   global
​
#consul主机查看
[root@consul ~]# docker network ls
60210366228b   myovernet   overlay   global

Overlan默认的网段是10.0.0.0/24

[root@docker11 ~]# docker network inspect myovernet
                {
                    "Subnet": "10.0.0.0/24",
                    "Gateway": "10.0.0.1"
                }

docker10、docker1、consul分别创建centos容器测试跨主机通信

[root@docker10 ~]# docker run -it --name=c10 --net=myovernet centos:7 /bin/bash
​
[root@docker11 ~]# docker run -it --name=c11 --net=myovernet centos:7 /bin/bash
​
[root@consul ~]# docker run -it --name=c12 --net=myovernet centos:7 /bin/bash

测试连通性:docker自定义的网落是自带域名解析的,所以直接ping名字

[root@097d21377fcc /]# ping c11
[root@097d21377fcc /]# ping c12

查看容器IP

[root@097d21377fcc /]# hostname -I
10.0.0.2 172.18.0.2 
​
#注:10.0.0.2是容器内部的地址,172.18.0.2是容器与宿主机之间的网关,如果宿主机可以访问外网,容器借助该网关转可换成宿主机IP访问外网。


0
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区