• Docker 网络


    “醉也从容,悲也从容” 


    Docker Network

    Docker 为什么需要网络管理?

            网络出现的需求,就在于通信!Docker启动一个个容器,这些容器是什么??其本质就是一个个进程,进程需要通信,那么容器也就需要通信。容器之间的隔离是进程级别的,容器的网络默认与宿主机及其他容器都是相互隔离。

            所以,我们就得考虑以下问题:

    •  多个容器之间是如何通信的
    •  容器和宿主机是如何通信的
    容器和外界主机是如何通信的

    • 容器需要更高的定制化网络(如定制特殊的集群网络、定制容器间的局域网) 应该如何实现

    • 容器根本不需要网络的时候应该如何实现

            ……上述的这些问题都需要我们对容器的网络进行合理的管理才能解决,这就体现出了容
    器网络管理的重要性。

        

    Docker 网络架构简介

            Docker 容器网络是为应用程序所创造的虚拟环境的一部分,它能让应用从宿主机操作系统的网络环境中独立出来,形成容器自有的网络设备、IP 协议栈、端口套接字、IP路由表、防火墙等等与网络相关的模块。

            为实现这种隔离性,Docker主要采用的架构由三部分组成:CNMLibnetwork 和驱动。

    👑 CNM

            Docker 网络架构采用的设计规范是 CNM。CNM 中规定 了 Docker 网络的基础组成要素:

            Sandbox、EndpointNetwork

    Sandbox: 提供了容器的虚拟网络栈,也即端口、套接字、IP 路由表、防火墙、DNS 配置等内容。主要用于隔离容器网络与宿主机网络,形成了完全独立的容器网络环境.
    •  Endpoint:  就是虚拟网络的接口,像普通网络接口一样,Endpoint 的主要职责是负责创建连接.
    •  Network: Docker 内部的虚拟子网,使得网络内的参与者能够进行通讯.

    👑 Libnetwork

            Libnetwork CNM 的一个标准实现。采用 Go 语言编写(跨平台的),也是 Docker 所使用的库,Docker 网络架构的核心代码都在这个库中。

    👑 驱动

            驱动主要负责实现数据层相关内容,例如网络的连通性和隔离性是由驱动来处理的。驱动通过实现特定网络类型的方式扩展了 Docker 网络栈,例如桥接网络和覆盖网络

    常见的网络类型

    💎 bridge 网络

            Docker 容器的默认网络驱动。bridge 驱动会在 Docker 管理的主机上创建一个 Linux 网桥,默认情况下,网桥上的容器可以相互通信,也可以通过 bridge 驱动程序配置,实现对外部容器的访问。

    💎 host 网络

            对于独立容器,移除容器和 Docker 主机之间的网络隔离,并直接使用主机的网络。

    💎 container 网络

            这个模式指定新创建的容器和引进存在的一个容器共享一个网络 ,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 ip,而是和一个指定的容器共享 ip,端口等。

    💎 none 网络

            Docker 容器拥有自己的 Network Namespace,但是,并不为 Docker容器进行任何网络配置。

    💎 overlay 网络

            借助 Docker 集群模块 Docker Swarm 搭建的跨 Docker Daemon 网络。将多个Docker 守护
    进程连接在一起,使集群服务能够相互通信。

    💎 docker0

            在 Docker 安装时,会自动安装一块 Docker 网卡称为 docker0,它是一个网桥设备,主要用于 Docker容器及宿主机的网络通信。


     

    Docker 网络命令详解

    命令清单:

    命令别名功能
    docker network create
    创建网络
    docker network connect
    连接网络
    docker network disconnect
    断开网络
    docker network ls
    docker network list
    列出网络
    docker network prune
    删除不使用的网络
    docker network inspect
    查看网络详情
    docker network rmdocker network remove
    删除 1 个或者多个网络
    🧱 docker network create
    语法:
    1. # 创建自定义网络
    2. docker network create [OPTIONS] NETWORK
    3. OPTIONS:
    4. -d, --driver:网络驱动
    5. --gateway:网关地址
    6. --subnet:表示网段的 CIDR 格式的子网
    7. --ipv6:启用 ipv6
    🧱 docker network inspect
    语法:
    1. # 查看网络详情
    2. docker network inspect [OPTIONS] NETWORK [NETWORK...]
    3. OPTIONS:
    4. -f,--format:指定格式
    🧱 docker network connect\disconnect
    语法:
    1. # 将容器连接到网络
    2. docker network connect [OPTIONS] NETWORK CONTAINER
    3. # 指定要分配给容器网络接口的 IP 地址
    4. OPTIONS:
    5. --ip:指定 IP 地址
    6. --ip6:指定 IPv6 地址
    7. # 断开网络
    8. docker network disconnect [OPTIONS] NETWORK CONTAINER

    🧱 docker network prune

    语法:
    1. # 删除不使用的网络
    2. docker network prune
    3. OPTIONS:
    4. -f, --force :不提示

    🧱 docker network rm

    语法:
    1. # 删除 1 个或者多个网络
    2. docker network rm NETWORK [NETWORK...]
    3. OPTIONS:
    4. -f:强制退出

    🧱 docker network ls

    语法:
    1. # 列出网络
    2. docker network ls [OPTIONS]
    3. OPTIONS:
    4. -f, --filter:指定过滤条件
    5. --format:指定格式
    6. --no-trunc:不截断
    7. -q, --quiet :仅仅显示 id

    网络命令基本操作

            创建网络并指定 ip 地址段:

    docker network create --subnet=172.20.0.0/16 mynetwork

            查看创建的网络:

            创建一个容器并加入网络:

    1. docker run -itd --name mynginx
    2. --network mynetwork nginx:1.24.0
    3. docker container inspect mynginx
    4. docker network inspect mynetwork

            创建一个新的 nginx 容器 mynginx2,但是不加入我们的自定义网络:

    docker run -itd --name mynginx2 nginx:1.23.0

            查看该容器的网络配置,可以看到采用的是 docker0 桥:

            我们将该容器加入到我们自己创建的网络:

    docker network connect mynetwork mynginx2

             再次查看我们的容器 2 的网络配置,可以看到它多了一个 mynetwork:

            我们让容器二断开网络呢?

    docker network disconnect mynetwork mynginx2

             删除网络,可以看到网络被使用了,无法删除,停止正在使用这段网络的容器后,就可以删除了。


    网络类型详解

    🎁 docker Bridge 网络

    网络介绍

            Docker Bridge 网络采用内置的 bridge 驱动。bridge 驱动底层采用的是 Linux 内核中Linux bridge 技术。bridge Docker 对网络的命名,而 docker0 是内核中网桥的名字。

            就网络而言,bridge 网络是在网络段之间转发流量的链路层设备;就网桥而言可以是在主机内核中运行的硬件设备或软件设备。 

            就 Docker而言,bridge桥接网络使用软件网桥 docker0。从而允许连接到同一网桥网络的容器进行通信,同时提供与未连接到该网桥网络容器的隔离。

             默认情况下,创建的容器在没有使用--network 参数指定要加入的 docker 网络时,都是加入 Docker 默认的单机桥接网络

            Docker 默认的 bridge 网络和 Linux 内核中的 docker0 网桥是一一对应的关系

     

    操作案例        

    基于docker0的容器间的网络通信

            多台主机该如何进行网络通信??对于两台主机而言,进行网络通信的法子很简单,就是双方插同一根网线。但遇到多台主机时,需要新增路由器/交换机。

            把多台主机连接到路由器/交换机上, 通过路由器/交换机来达到交换数据, 即通信的目的。

            容器之间的通信方式,与上述方法如出一辙。当我们创建容器,不明指 --network时,就会把该容器分配给 docker0这个网桥设备,此时这个docker0就可以类比上述的 交换机\路由器。我们接下来进行验证:

            使用 busybox 镜像创建两个容器, 并且保持在后台运行:

            我们获取两个容器的ip,可以使用docker network inspect查询: 

    1. "Containers": {
    2. "1754c377b55d9aa25f6784d5b86a5da6462a6974bba3a03b01fd43ccf231b2fb": {
    3. "Name": "busybox1",
    4. "EndpointID": "efeedbaeb1e0754d8831127e14a9ff930d81259c441049a1e38e4164f05c3cb5",
    5. "MacAddress": "02:42:ac:11:00:03",
    6. "IPv4Address": "172.17.0.3/16",
    7. "IPv6Address": ""
    8. },
    9. "383e713d9dd6d9032b9fc08877f305a23baea6b1eee505fc2dad027386d57900": {
    10. "Name": "busybox2",
    11. "EndpointID": "884768140d6e0ce97c4977d899f22669d300742cdedf00832b51a2ef8bbeebfd",
    12. "MacAddress": "02:42:ac:11:00:06",
    13. "IPv4Address": "172.17.0.6/16",
    14. "IPv6Address": ""
    15. },
    16. }

            也可以启用命令行的形式 ifconfig:

    1. docker container exec -it busybox1 ifconfig
    2. docker container exec -it busybox2 ifconfig

            进入到两个容器中,尝试互相使用ping命令,结果发现它们能互相通信。

    基于自定义bridge的容器间网络通信

            在默认情况下, 我们创建的容器都会连接在 docker0 这个 bridge 上。那其实我们也可以创建一些自定义的 bridge,让运行的容器通过自定义 bridge 进行通信。

            首先,我们创建一个新的bridge:

    1. docker network create -d bridge new-bridge
    2. -d,--driver 选项指定网络驱动程序

            查看新bridge网段信息:

            重新创建两个新的容器,并在创建之初给它们指定到 新bridge上。

    1. docker run -itd --name busybox3 --network new-bridge busybox:latest
    2. docker run -itd --name busybox4 --network new-bridge busybox:latest

            我们查看new-bridge后,会发现新容器已经连接在里面了:

            接下来,重复测试 busybox1\busybox2的动作,检查这两个同属new-bridge的容器,是否可以进行通信:

            结果显然是我们预料的,它们能进行通信。

    DNS 解析

            Docker 自定义桥接网络是支持通过 Docker DNS 服务进行域名解析的。也就是说我们可以直接使用容器名进行通信,因为 DNS 服务可以解析容器名到 IP 地址的映射。但是默认的 bridge 网络是不支持 DNS 的。

            其中,busybox1、2默认连接到 brige,busybox3、4则是连接到了自定义桥接 new-bridge。

            默认桥段,是不能进行DNS的。 

            反观自定义桥段,则可以:

    端口暴露和转发

    • 端口暴露

            端口暴露有 2 种方式:

    🎉 -P:将指定的容器端口映射至主机所有地址的一个动态端口

    🎉 -p:: 指定的主机端口 : 容器端口

    • 端口转发

            连接 bridge 网络的容器只能与连接在当前网络中的容器进行通信。如果一个容器想要对外提供一些网络服务的话,需要进行端口转发才可以实现。  

            端口转发将 Docker 容器的端口映射到宿主机的端口上,那么任何发送到宿主机该端口
    的流量,都会被转发到容器的端口中。

            例如,我们想要容器里的nginx服务能被浏览器访问到,所以在启动时会输入, "-p 80:80",这个过程就叫做端口暴露,当浏览器向我们的机器发起请求,将请求打到宿主机的80号端口时,这个请求又会被转发到,映射容器内部的端口,这个过程也就叫做端口转发。 

    🎁 docker Host 网络

    网络介绍

            Docker 容器运行默认都会分配独立的 Network Namespace 隔离子系统但是如果基于 host 网络模式,容器将不会获得一个独立的 Network Namespace。

            此时,宿主机和容器共用同一个 Network Namespace。容器将不会虚拟出自己的网卡,IP 等等,而是直接使用宿主机的 IP 和端口。

            连接到 host 网络的容器,共享宿主机的网络栈,容器的网络配置与宿主机完全一样。我们可以通过 --network=host 指定使用 host 网络。

    操作案例     

    docker container run --name busybox -itd --network=host busybox:latest

            查看busybox的网络配置信息:

            这完完全全就是咱们宿主机的网络配置!

    使用场景: 

            使用bridge网络在通信的时候需要进行端口转发以及 NAT 地址转换,这势必会消耗掉一些资源以及性能。直接使用 host 网络就没那么麻烦,性能也更好。但,选择host网络要考虑端口冲突问题,其他服务已经被占用的端口就不能再使用了。

    🎁 docker Container 网络

    网络介绍

            docker container是一种较为特别的网络的模式,又称为“other container模式”。在这个模式下,Docker Container,会使用其他容器的网络环境。在这个模式下,容器的网络隔离性会处在bridge 桥接模式与 host 模式之间。    

            简单来说,就是一个容器使用另一个容器的网络配置。

    操作案例     

            创建一个 busybox 容器:

    docker run -itd --name netcontainer1 busybox

            使用 netcontainer1 的网络创建另外一个容器: 

    1. docker run -itd --name netcontainer2
    2. --network container:netcontainer1 busybox

            进入两个容器,查看容器的 ip 信息,发现两个 ip mac 完全一样: 

            

            我们停止容器 1,再次看下容器 2 的网络,发现 eth0 网卡消失了,只有一个本地网络了。

            再次重启容器1和容器2然后可以看到容器2网络恢复。

    使用场景:

            在这种模式下的 Docker Container 可以通过 localhost 来访问 namespace 下的其他容器,传输效率较高。但是两个容器之间存在依赖,如果依赖容器重启了,会导致另外一个服务的网络不可用。

    🎁 docker none 网络

    网络介绍

            none 网络就是指没有网络。挂在这个网络下的容器除了 lo(本地回环),没有其他任何网卡。

    操作案例     

            在运行容器的时候,可以通过--network=none 参数来指定容器使用 none 网络:

    1. docker container run -itd --name c3
    2. --network none busybox

    使用场景:

           针对一些对安全性要求比较高并且不需要联网的应用, 可以使用 none 网络, 比如随机密码, 避免生成密码被第三方获取。

            一些第三方的应用可能需要 docker 帮忙创建一个没有网络的容器, 网络由第三方自己来配置。


    本篇到此结束,感谢你的阅读。

    祝你好运,向阳而生~

  • 相关阅读:
    『C++成长记』C++入门——内联函数
    多线程-进阶
    Laravel artisan 常用命令
    【附源码】Python计算机毕业设计汽车租赁管理
    机器学习第十一课--K-Means聚类
    【QT开发(4)】Qt Creator编译器修改,应用程序二进制接口(ABI)的版本;API、ABI、系统调用是什么?版本的选择(ABI和CPU版本)
    数据结构之:数组
    SpringCloud 服务限流与熔断
    观成科技:证券行业加密业务安全风险监测与防御技术研究
    2023年,PMP的知识是否过时了?
  • 原文地址:https://blog.csdn.net/RNGWGzZs/article/details/136302009