一、Docker为什么必要网络管理
容器的网络默认与宿主机及其他容器都是相互隔离, 但同时我们也要考虑下面的一些问题, 比如:
- 多个容器之间是怎样通讯的
- 容器和宿主机是怎样通讯的
- 容器和外界主机是怎样通讯的
- 容器中要运行一些网络应用(如 nginx、 web 应用、数据库等),假如要让外部也可以访问这些容器内运行的网络应用应该怎样实现
- 容器不想让它的网络与宿主机、与其他容器隔离应该怎样实现
- 容器根本不必要网络的时候应该怎样实现
- 容器必要更高的定制化网络(如定制特殊的集群网络、定制容器间的局域网)应该怎样实现
- …
上述的这些问题都必要我们对容器的网络进行合理的管理才气办理,这就体现出了容器网络管理的重要性。
二、Docker网络架构简介
Docker 容器网络 是为应用步伐所创造的假造环境的一部分,它能让应用从宿主机操纵系统的网络环境中独立出来,形成容器自有的网络装备、 IP 协议栈、端口套接字、 IP路由表、防火墙等等与网络相关的模块。
Docker 为实现容器网络,重要采用的架构由三部分构成:CNM、 Libnetwork 和驱动。
CNM
Docker 网络架构采用的计划规范是 CNM(Container Network Model)。 CNM 中规定了 Docker 网络的底子构成要素: Sandbox、 Endpoint、 Network。
- Sandbox:提供了容器的假造网络栈,也即端口、套接字、 IP 路由表、防火墙、DNS 设置等内容。重要用于隔离容器网络与宿主机网络,形成了完全独立的容器网络环境。
- Network: Docker 内部的假造子网,使得网络内的到场者可以或许进行通讯。
- Endpoint:就是假造网络的接口,就像普通网络接口一样, Endpoint 的重要职责是负责创建毗连。 Endpoint 类似于常见的网络适配器,那也就意味着一个 Endpoint 只能接入某一个网络, 当容器必要接入到多个网络,就必要多个 Endpoint。
如上图所示,容器 B 有两个 Endpoint 并且分别接入 Networkd A 和 Network B。那么容器 A 和容器 B 之间是可以实现通讯的,因为都接入了 NetworkA。但是容器 A 和容器 C 不可以通过容器 B 的两个 Endpoint 通讯。
Libnetwork
Libnetwork 是 CNM 的一个标准实现。 Libnetwork 是开源库,采用 Go 语言编写(跨平台的),也是 Docker 所使用的库, Docker 网络架构的核心代码都在这个库中。Libnetwork 实现了 CNM 中定义的全部三个组件,此外它还实现了当地服务发现、基于 Ingress 的容器负载均衡,以及网络控制层和管理层等功能。
驱动
驱动 重要负责实现数据层相关内容,比方网络的连通性和隔离性是由驱动来处理惩罚的。驱动通过实现特定网络范例的方式扩展了 Docker 网络栈,比方桥接网络和覆盖网络。
Docker 内置了若干驱动,通常被称作原生驱动或者当地驱动。比方 Bridge Driver、Host Driver、 Overlay Driver、 MacVLan Driver、 IPVLan Driver、 None Driver 等等。每个驱动负责创建其上所有网络资源的创建和管理。
三、常见网络范例
- bridge网络
bridge 驱动会在 Docker 管理的主机上创建一个 Linux 网桥。默认情况下,网桥上的容器可以相互通讯。也可以通过 bridge 驱动步伐设置,实现对外部容器的访问。Docker 容器的默认网络驱动.当我们必要多个容器在同一个 Docker 主机上通讯时,桥接网络是最佳选择。
- host 网络
对于独立容器,移除容器和 Docker 主机之间的网络隔离,并直接使用主机的网络。当网络堆栈不应该与 Docker 主机隔离,但是希望容器的其他资源被隔离时,主机网络是最佳选择。
- container 网络
这个模式指定新创建的容器和引进存在的一个容器共享一个网络 ,而不是和宿主机共享。新创建的容器不会创建自己的网卡,设置自己的 ip,而是和一个指定的容器共享 ip,端口等,两个容器除了网络方面,其他的如文件系统、历程列表等还是隔离的。两个容器的历程可以通过 lo 网卡装备通讯。
- none 网络
Docker 容器拥有自己的 Network Namespace,但是,并不为Docker 容器进行任何网络设置。也就是说,这个 Docker 容器没有网卡、IP、路由等信息。容器完全网络隔离。
- overlay 网络
借助 Docker 集群模块 Docker Swarm 搭建的跨 Docker Daemon 网络。将多个Docker 守护历程毗连在一起,使集群服务可以或许相互通讯。当我们必要运行在不同Docker 主机上的容器进行通讯时,或者当多个应用步伐使用集群服务协同工作时,覆盖网络是最佳选择。
别的,在 Docker 安装时,会主动安装一块 Docker 网卡称为 docker0,它是一个网桥装备,重要用于 Docker 各容器及宿主机的网络通讯。
四、Docker网络管理下令
docker network create
- docker network create [OPTIONS] NETWORK
复制代码
- 关键参数
- -d, --driver: 网络驱动
- --gateway: 网关地点
- --subnet: 体现网段的 CIDR 格式的子网
- --ipv6: 启用 ipv6
- 样例
- #创建自定义网络
- docker network create mynet1 --subnet=192.168.0.0/16
- #查看网络列表
- docker network ls
- #查看网络详细信息
- docker network inspect mynet1
复制代码
docker network inspect
- docker network inspect [OPTIONS] NETWORK [NETWORK...]
复制代码
- #查看mynet1、mynet2网络详情
- docker network inspect mynet1 mynet2
复制代码
我们创建的容器默认使用的是桥接网络
- docker network inspect bridge
复制代码
docker network connect
- 功能
于将容器毗连到网络。可以按名称或 ID 毗连容器。 一旦毗连,容器可以与同一网络中的其他容器通讯。
- 语法
- docker network connect [OPTIONS] NETWORK CONTAINER
复制代码
- 关键参数
- --ip: 指定 IP 地点
- --ip6: 指定 IPv6 地点
- 样例
- #创建自定义网络mynet3
- docker network create mynet3 --subnet=10.2.0.0/16
- #运行一个容器busybox
- docker run -dit --name busybox1 busybox:1.36.0
复制代码
- docker network connect mynet3 busybox1
复制代码
- docker network inspect mynet3
复制代码
docker network disconnect
- docker network disconnect [OPTIONS] NETWORK CONTAINER
复制代码
- docker network inspect mynet3
复制代码
- docker network disconnect mynet3 busybox1
复制代码
- docker exec -it busybox1 sh
复制代码
docker network prune
- docker network prune
- [OPTIONS]
复制代码
docker network rm
- docker network rm NETWORK [NETWORK...]
复制代码
- docker network create mynet1
- docker network create mynet2
- docker network create mynet3
- docker run -itd --name busybox2 busybox:1.36.0
复制代码
- docker network connect mynet3 busybox2
- docker inspect mynet3
- docker network rm mynet1 mynet2 mynet3
复制代码
docker network ls
- docker network ls [OPTIONS]
复制代码
- 关键参数
- -f, --filter:指定过滤条件
- --format:指定格式
- --no-trunc:不截断
- -q, --quiet :仅仅表现 id
- 样例
- #返回名字为host的网络
- docker network ls -f name=host
- #以json形式返回网络列表
- docker network ls --format json
- #不截断返回列表
- docker network ls --no-trunc
- #仅仅返回网络id
- docker network ls -q
复制代码
网络下令根本操纵
- docker network create mynet6 --subnet=10.15.0.0/16
复制代码
- docker run -itd --name busybox3 --network mynet6 busybox:1.36.0
- docker inspect busybox3
- docker inspect mynet6
复制代码
- docker run -itd --name busybox4 busybox:1.36.0
- docker network connect mynet6 busybox4
复制代码
五、网络详解
docker Bridge网络
网络介绍
Docker Bridge 网络采用内置的 bridge 驱动, bridge 驱动底层采用的是 Linux 内核中Linux bridge 技能。就网络而言, bridge 网络是在网络段之间转发流量的链路层装备,而网桥可以是在主机内核中运行的硬件装备或软件装备;就 Docker 而言,桥接网络使用软件网桥 docker0,它允许毗连到同一网桥网络的容器进行通讯,同时提供与未毗连到该网桥网络容器的隔离。
Docker Container 的 bridge 桥接模式 可以参考下图:
默认情况下,创建的容器在没有使用 --network 参数指定要加入的 docker 网络时,默认都是加入 Docker 默认的单机桥接网络,即下面的 name 为 bridge 的网络。
默认的 bridge 网络会被映射到内核中为 docker0 的网桥上。Docker 默认的 bridge 网络和 Linux 内核中的 docker0 网桥是逐一对应的关系。bridge 是 Docker 对网络的定名,而 docker0 是内核中网桥的名字。
生存案例
bridge 就像一个立交桥一样,有许多条路可以四通八达,每条路都毗连了 2 个方向的通道。
操纵案例
容器间的网络通讯
- #创建两个容器
- docker run -itd --name b1 busybox:1.36.0
- docker run -itd --name b2 busybox:1.36.0
- #分别进入两个容器
- docker exec -it b1 sh
- docker exec -it b2 sh
复制代码
创建自定义bridge
在默认情况下, 我们创建的容器都会毗连在 docker0 这个 bridge 上。那其实我们也可以创建一些自定义的 bridge,让运行的容器通过自定义 bridge 进行通讯。
- docker network create mynet4
复制代码
- docker run -itd --name b3 --network mynet4 busybox:1.36.0
- docker run -itd --name b4 --network mynet4 busybox:1.36.0
复制代码
DNS解析
Docker 自定义桥接网络是支持通过 Docker DNS 服务进行域名解析的, 也就是说我们可以直接使用容器名进行通讯,因为 DNS 服务可以解析容器名到 IP 地点的映射, 但是默认的 bridge 网络是不支持 DNS 的。
- docker run -itd --name b51 busybox:1.36.0
- docker run -itd --name b52 busybox:1.36.0
复制代码
- 分别在两个容器中ping对方的名称, 发现可以ping通
因此,这里我们可以得出结论:默认的bridge网络不支持DNS域名解析,而自己创建的自定义bridge网络则支持。
端口暴露和转发
- 暴露方式
端口暴露有 2 种方式,在启动容器的时候添加端口参数,一种 -P 暴露所有端口,一种是-p,暴露指定端口
- -P
将指定的容器端口映射至主机所有地点的一个动态端口, ·“动态端口”指随机端口,详细的映射结果可使用 docker port 下令查看
- -p <hostPort>:<containerPort>
将容器端口映射至指定的主机端口
- 端口转发
毗连 bridge 网络的容器只能与毗连在当前网络中的容器进行通讯。假如一个容器想要对外提供一些网络服务的话,必要进行端口转发才可以实现。
端口转发将 Docker 容器的端口映射到宿主机的端口上,那么任何发送到宿主机该端口的流量,都会被转发到容器的端口中。如下图所示,两个容器内部均开放 80 端口,它们分别映射到宿主机的 8088 和 8089 端口, 即体现任何发送到 8088 端口的流量都会转发到 Container 1 容器的 80 端口, 发送到 8089 端口的流程都会转发到Container 2 容器的 80 端口。
- docker run -d --name mynginx1 -p 8060:80 nginx:1.24.0
- docker port mynginx1
复制代码
docker Host 网络
网络介绍
Docker 容器运行默认都会分配独立的 Network Namespace 隔离子系统, 但是假如基于 host 网络模式,容器将不会获得一个独立的 Network Namespace, 而是和宿主机共用同一个 Network Namespace,容器将不会假造出自己的网卡, IP 等,而是直接使用宿主机的 IP 和端口。
毗连到 host 网络的容器共享宿主机的网络栈,容器的网络设置与宿主机完全一样。我们可以通过 --network=host 指定使用 host 网络。
操纵案例
- 创建两个容器,分别使用两种网络(桥接网络和host网络)
- docker run -itd --name b61 busybox:1.36.0
- docker run -itd --name b62 --network host busybox:1.36.0
复制代码
这里我们必要注意一下,host网络的缺点就是宿主机的端口假如被占用,那么容器将不能使用该端口。
- docker run -d --name mynginx2 --network host nginx:1.24.0
- #查看容器日志信息
- docker logs mynginx2
复制代码
- 之前我们提到 bridge 网络在通讯的时候必要进行端口转发以及 NAT 地点转换,这势必会消耗掉一些资源以及性能。
- 那么直接使用 host 网络最大的利益就是性能好,假如容器对网络传输服从有较高的要求,发起选择 host 网络。固然也会牺牲一些东西,比如要考虑端口冲突问题,其他服务已经被占用的端口就不能再使用了。
docker Container 网络
网络介绍
Docker Container 的 other container 网络模式是 Docker 中一种较为特殊的网络的模式。之所以称为“other container 模式”,是因为这个模式下的 Docker Container,会使用其他容器的网络环境。之所以称为“特殊”,是因为这个模式下容器的网络隔离性会处于 bridge 桥接模式与 host 模式之间。 Docker Container 共享其他容器的网络环境,则至少这两个容器之间不存在网络隔离,而这两个容器又与宿主机以及除此之外其他的容器存在网络隔离。
Docker Container 的 other container 网络模式实现逻辑如下:
- 查找 other container(即必要被共享网络环境的容器)的网络 namespace;
- 将新创建的 Docker Container(也是必要共享其他网络的容器)的 namespace,使用 other container 的 namespace
操纵案例
- 创建两个容器,并将第二个容器加入第一个容器网络中。
- docker run -itd --name b71 busybox:1.36.0
- docker run -itd --name b72 --network container:b71 busybox:1.36.0
复制代码
在这种模式下的 Docker Container 可以通过 localhost 来访问 namespace 下的其他容器,传输服从较高。但是两个容器之间存在依赖,假如依赖容器重启了,会导致别的一个服务的网络不可用。
docker none 网络
网络介绍
none 网络 就是指没有网络。挂在这个网络下的容器除了 lo(当地回环),没有其他任何网卡。
操纵案例
在运行容器的时候,可以通过 --network=none 参数来指定容器使用 none 网络。
- docker run -itd --name b8 --network none busybox:1.36.0
复制代码
- 针对一些对安全性要求比较高并且不必要联网的应用, 可以使用 none 网络, 比如生成随秘密码, 制止生成密码被第三方获取。
- 一些第三方的应用可能必要 docker 帮助创建一个没有网络的容器, 网络由第三方自己来设置。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |