侧边栏壁纸
博主头像
再见理想博主等级

只争朝夕,不负韶华

  • 累计撰写 112 篇文章
  • 累计创建 64 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

Docker-网络

再见理想
2022-05-25 / 0 评论 / 0 点赞 / 395 阅读 / 1,999 字

一,Docker 网络详解

理解 Docker0

查看ip地址:

# 命令
ip addr

image.png

可以看到有3个网络(lo、eth0和docker0),问题:

思考:docker 是如何处理容器网络访问的?

查看容器的内部网络地址:

# 命令
docker exec -it 容器 ip addr

image.png
可以发现容器启动时会得到一个 eth0@ 开头的 ip 地址,是 docker 分配的。

思考:linux 能否 ping 同容器内部?

ping 172.17.0.4
image.png
可以看到,linux 是可以 ping 同容器内部的。那么,容器和容器间能互相 ping 通吗?
image.png
可以看到,容器内去 ping 另一个容器也是可以 ping 通的!

原理

1,只要安装了 docker,就会有一个网卡 docker0 桥接模式,使用的技术是 evth-pair 技术;

evth-pair 技术:就是一对虚拟设备接口,它们是成对出现的,一端连接协议,另一端彼此相连; 正因为有这个特性,evth-pair 充当一个桥梁,连接各种虚拟网络设备。

2,我们每启动一个 docker 容器,docker 就会给 docker 容器分配一个 ip,和一对网卡;
3,所有的 docker 容器共用着一个路由器,就是 docker0。所有的容器在不知道网络的情况下,都是 docker0 路由的,docker 会给我们的容器分配一个默认的可以 ip。
image.png

image.png

小结

  • docker 使用的是 linux 的桥接,宿主机中是一个 Docker 容器的网桥 docker0;
  • docker 中所有的网络接口都是虚拟的,转发效率高;
  • docker 容器一删除,对应的网桥也被删除;

image.png

思考:是否可以通过容器名访问容器,避免容器重启后,ip地址改变而导致访问不到。就像微服务中,也可以通过服务名就像访问。

二,自定义网络

我们可以通过 --link 实现通过容器名访问, 但不建议这么干。 --link 的实现原理是在 hosts 配置中添加了容器名访问的映射。这种方式太不方便,所有容器启动时都需要配置 --link 指向需要容器名访问的容器。
我们可以通过自定义网络实现!即容器互联

实现步骤:

  1. 创建自定义网络;
  2. 指定网络启动容器;

好处:

  1. 功能比 docker0 更完善,也可以通过容器名连接;
  2. 不同的集群可使用不同的网络,保证集群的安全和健康;

查看所有的docker网络:

# 命令
docker network ls

image.png

网络模式:

  • bridge:桥接(默认);
    • 同一主机的容器实例能够通信,但不能跨主机通信
    • 此时docker引擎会创建一个veth对,一端连接到容器实例并命名为eth0,另一端连接到指定的网桥中(比如docker0),因此同在一个主机的容器实例由于连接在同一个网桥中,它们能够互相通信。容器创建时还会自动创建一条SNAT规则,用于容器与外部通信时。如果用户使用了-p或者-Pe端口端口,还会创建对应的端口映射规则。
  • none:不配置网络;
    • 不设置网络,相当于容器内没有配置网卡,用户可以手动配置。
  • host:主机模式,和宿主机共享网络;
    • 此时容器没有使用网络的namespace,宿主机的所有设备,如Dbus会暴露到容器中,因此存在安全隐患。
  • container:容器内网络连通,用得少,局限很大;
  • 自定义模式:自定义网络;
    • 使用自定义网络,可以使用 docker network create 创建,并且默认支持多种网络驱动,用户可以自由创建桥接网络或者overlay网络。

创建自定义网络

# 命令
docker network create
Usage:	docker network create [OPTIONS] NETWORK
Options:
      --attachable             Enable manual container attachment
      --aux-address map        Auxiliary IPv4 or IPv6 addresses used by Network driver (default map[])
  -d, --driver string          Driver to manage the Network (default "bridge")
      --gateway stringSlice    IPv4 or IPv6 Gateway for the master subnet
      --help                   Print usage
      --internal               Restrict external access to the network
      --ip-range stringSlice   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 (default [])
  -o, --opt map                Set driver specific options (default map[])
      --subnet stringSlice     Subnet in CIDR format that represents a network segment
      
# 使用示例
docker network create --subnet 172.18.0.0/16 --gateway 172.18.0.1 mynet

启动容器

我们需要 --net 命令指定网络启动容器,不指定网络启动的话,默认使用 docker0 网络。

# 使用示例
docker run -p 3309:3306 -d --name mysql3309-net --net mynet -e MYSQL_ROOT_PASSWORD=admin mysql-lzh:1.0
docker run -p 3310:3306 -d --name mysql3310-net --net mynet -e MYSQL_ROOT_PASSWORD=admin mysql-lzh:1.0

查看是否能通过容器名连接:

# 命令
docker exec -it mysql3309-net ping mysql3310-net

image.png
可以看到能够正常连接。

查看自定义网络元数据:

# 命令
docker network inspect [自定义网络名]

# 使用示例
docker network inspect mynet

image.png
可以看到刚指定该网络启动的两个容器。

三,不同网络的容器连通

不同网段的容器正常不能相互连通,这时打通容器与另一个网段的连接,可以使用以下命令:

# 命令
docker network connect [OPTIONS] NETWORK CONTAINER
Connect a container to a network
Options:
      --alias stringSlice           Add network-scoped alias for the container
      --help                        Print usage
      --ip string                   IP Address
      --ip6 string                  IPv6 Address
      --link list                   Add link to another container (default [])
      --link-local-ip stringSlice   Add a link-local address for the container

# 使用示例
# docker0 网络下的 mysql3307 容器与 mynet 网络打通
docker network connect mynet mysql3307

image.png
可以看到,打通容器与自定义网络后,不同网络的容器能成功连接上该自定义网络下的容器!

用 docker network inspect mynet 命令查看下自定义网络下的元数据:
image.png
可以看到,mysql3307 容器加入到了 自定义网络mynet 下!即mysql3307 容器拥有2个ip地址!类似于阿里云服务器同时拥有公网ip和私网ip。

验证一下,使用 docker inspect mysql3307 命令查看下mysql3307 容器的元数据:
image.png
验证成功,mysql3307容器中添加了2个网络!

结论:

假设要跨网络连接容器,就需要使用 docker network connect 连通!

四,Overlay 网络-容器跨主机通信

定义:
Overlay网络是通过网络虚拟化技术,在同一张Underlay网络上构建出的一张或者多张虚拟的逻辑网络。
不同的Overlay网络虽然共享Underlay网络中的设备和线路,但是Overlay网络中的业务与Underlay网络中的物理组网和互联技术相互解耦。

解决什么问题:
overlay网络用于连接不同机器上的docker容器,允许不同机器上的容器相互通信,同时支持对消息进行加密,当我们初始化一个swarm或是加入到一个swarm中时,在docker主机上会出现两种网络:
1、称为 ingress 的 overlay 网络,用于传递集群服务的控制或是数据消息,若在创建 swarm 服务时没有指定连接用户自定义的overlay网络,将会加入到默认的ingress网络;
2、名为docker_gwbridge桥接网络会连接swarm中所有独立的docker系统进程
可以使用docker network create创建自定义的overlay网络,容器以及服务可以加入多个网络,只有同一网络中的容器可以相互交换信息;

0

评论区