• 【云原生】五、Docker 网络管理



    前言

     本文将学习 Docker 网络管理相关知识,将会涉及容器端口映射,实现容器互联等知识点。

    一、网络

     在开始下面的内容之前,为了不出现命名上的冲突,也为了显示更为直观,首先需要将前面创建或启动的容器全部删除。

    # 暂停所有运行中的容器
    docker container ls -q | xargs docker container stop
    
    # 删除所有的容器
    docker container ls -aq | xargs docker container rm
    
    • 1
    • 2
    • 3
    • 4
    • 5

    请添加图片描述
     当我们安装 Docker 后,默认会自动创建三个网络。我们可以使用下面的命令来查看这些网络:

    docker network ls
    
    • 1

    请添加图片描述

     如上图所示,三种默认的网络,分别为 bridgehostnone

    二、桥接网络

     bridge 即桥接网络,在安装 Docker 后会创建一个桥接网络,该桥接网络的名称为 docker0。我们可以通过下面两条命令去查看该值。

    # 查看 bridge 网络的详细信息,并通过 grep 获取名称项
    docker network inspect bridge | grep name
    
    # 使用 ifconfig 查看 docker0 网络
    ifconfig
    
    • 1
    • 2
    • 3
    • 4
    • 5

    请添加图片描述
     在上图中,我们可以查看到对应的值。默认情况下,我们创建一个新的容器都会自动连接到 bridge 网络。使用 docker network inspect bridge 查看网桥网络的详细信息,结果如下所示:
    请添加图片描述
     可以看到 docker0 的默认网段 Subnet 项。我们可以尝试创建一个容器,该容器会自动连接到 bridge 网络,例如我们创建一个名为 xiaoniuma001 的容器:

    docker container run --name xiaoniuma001 -itd ubuntu /bin/bash
    
    • 1

     上述命令中默认使用 --network bridge ,即指定 bridge 网络。创建后,再次查看 bridge 的信息:
    请添加图片描述
    请添加图片描述
     这时可以查看到相应的容器的网络信息,该容器在连接到 bridge 网络后,会从子网的地址池中获得一个 IP 地址。

     使用 docker container attach xiaoniuma001 命令,也可查看相应的地址信息:

    如果提示无 ifconfig 命令,可以在容器中执行 apt update && apt install net-tools 安装。

    请添加图片描述
    请添加图片描述
     并且对于连接到默认的 bridge 之间的容器可以通过 IP 地址互相通信。例如我们启动一个 xiaoniuma002 的容器,它可以与 xiaoniuma001 通过 IP 地址进行通信。

    如果提示无 ping 命令,可以在容器中执行 apt update && apt install -y iputils-ping 安装。

    请添加图片描述
    请添加图片描述
     上述的操作我们通过 ping 命令演示了 IP 相关的内容。但是对于应用程序来讲,如果需要在外部进行访问,我们还会涉及到端口的使用,而 Docker 对于 bridge 网络使用端口的方式为设置端口映射,通过 iptables 实现。

     下面我们通过 iptables 来为大家演示在 docker 中实现端口映射的方式,主要针对 nat 表和 filter 表:

     首先删除掉上面创建的两个容器,这里不再给出具体的命令。

     此时,我们查看 nat 表的转发规则,使用如下命令

    sudo iptables -t nat -nvL
    
    • 1

    请添加图片描述
     由于此时并未创建 docker 容器,nat 表中没有什么特殊的规则。接下来,我们使用之前在 Docker 镜像管理中构建的 xiaoniuma:1.0 镜像创建一个容器 xiaoniuma001。构建镜像 xiaoniuma:1.0 的 DockerFile 如下,具体的构建过程请参考之前的文章 Docker 镜像管理

    # 指定基础镜像
    FROM ubuntu:14.04
    
    # 维护者信息
    MAINTAINER xiaoniuma/xiaoniuma001@simplecloud.cn
    
    # 镜像操作命令
    RUN \
        apt-get -yqq update && \
        apt-get install -yqq apache2
    
    # 容器启动命令
    CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

     构建好 xiaoniuma:1.0 镜像后,启动一个容器 xiaoniuma001,并将本机的端口 10001 映射到容器中的 80 端口上。

    docker run -d -p 10001:80 --name xiaoniuma001 xiaoniuma:1.0
    
    • 1

     其中 docker container run 命令的 -p 参数是通过端口映射的方式,将容器的端口发布到主机的端口上。其使用格式为 -p ip:hostPort:containerPort。并且还可以指定范围,例如 -p 10001-10100:1-100,代表将容器 1-100 的端口映射到主机上的 10001-10100 端口上,两者一一对应。

     创建成功后,我们可以在浏览器中输入 localhost:10001 访问到容器 xiaoniuma001 的 apache 服务。
    请添加图片描述
     查看此时 iptables 中 nat 表和 filter 表的规则,其中分别新增了一条比较重要的内容,如下图所示:

    sudo iptables -t nat -nvL
    
    • 1

    请添加图片描述

    sudo iptables -nvL
    
    • 1

    请添加图片描述

    三、自定义网络

     对于默认的 bridge 网络来说,使用端口可以通过端口映射的方式来实现,并且在上面的内容中我们也演示了容器之间通过 IP 地址互相进行通信。但是对于默认的 bridge 网络来说,每次重启容器,容器的 IP 地址都是会发生变化的,因为对于默认的 bridge 网络来说,并不能在启动容器的时候指定 ip 地址,在启动单个容器时并不容易看到这一区别。

    旧版的容器互联

     容器间都是通过在 /etc/hosts 文件中添加相应的解析,通过容器名,别名,服务名等来识别需要通信的容器。

     我们先把之前的 xiaoniuma001 容器删除,这里不再给出具体的命令。

     现在启动两个容器,来演示旧的容器互联:

     首先启动一个名为 xiaoniuma001 的容器,使用镜像 busybox:

    docker run -it --rm --name xiaoniuma001 busybox /bin/sh
    
    • 1

     然后,打开一个新的终端,启动一个名为 xiaoniuma002 的容器,并使用 --link 参数与容器 xiaoniuma001 互联。

    docker run -it --rm --name xiaoniuma002 --link xiaoniuma001 busybox /bin/sh
    
    • 1

     docker run 命令的 --link 参数的格式为 --link <name or id>:alias。格式中的 name 为容器名,alias 为别名。即可以通过 alias 访问到该容器。

     如下图所示,上面的环境为 xiaoniuma001,下面的为 xiaoniuma002
    请添加图片描述
    请添加图片描述
     如果此时 xiaoniuma001 容器退出,这时我们启动一个 xiaoniuma003,再次启动一个 xiaoniuma001

    docker run -itd --name xiaoniuma003 --rm busybox /bin/sh
    docker run -it --name xiaoniuma001 --rm busybox /bin/sh
    
    • 1
    • 2

    请添加图片描述
    请添加图片描述
     如上所示,旧的容器 xiaoniuma002 通过 --link 连接到 xiaoniuma001。而在 xiaoniuma001 重启后,由于 IP 地址的变化,此时 xiaoniuma002 并不能正确的访问到 xiaoniuma001

     除了使用 --link 链接的方式来达到容器间互联的效果,在 Docker 中,容器间通信的推荐方式为自定义网络。

    自定义网络

     Docker 在安装时会默认创建一个桥接网络,除了使用默认网络之外,我们还可以创建自己的 bridge 或 overlay 网络。

     如下所示,我们创建一个名为 network1 的桥接网络,简单命令如下:

    docker network create network1
    docker network ls
    
    • 1
    • 2

     创建成功后,可以使用 ifconfig 或者 ip addr show 命令查看该桥接网络的网络接口信息,如下所示:
    请添加图片描述
     而对于该网络的详细信息可以通过 docker network inspect network1 命令来查看,如下图所示:
    请添加图片描述
     其相应的网络接口名称和子网都是由 docker 随机生成,当然,我们也可以手动指定:

    # 首先删除掉刚刚创建的 network1
    docker network rm network1
    # 再次创建 network1,指定子网
    docker network create -d bridge --subnet=192.168.16.0/24 --gateway=192.168.16.1 network1
    
    • 1
    • 2
    • 3
    • 4

     此时,我们可以运行一个容器 xiaoniuma001(需要把之前创建运行的 xiaoniuma001 容器删除),指定其网络为 network1,使用 --network network1

    docker run -it --name xiaoniuma001 --network network1 --rm busybox /bin/sh
    
    • 1

    请添加图片描述
     使用 exit 退出该容器使其自动删除,这时我们再次创建该容器,但是不指定其 --network

    docker run -it --name xiaoniuma001 --rm busybox /bin/sh
    
    • 1

    请添加图片描述
     此时,该容器连接到默认的 bridge 网络,这时,可以新打开一个终端,在其中运行如下命令,将 xiaoniuma001 连接到 network1 网络中:

    # 在新打开的终端中运行,将容器 xiaoniuma001 连接到 network1 网络中
    docker network connect network1 xiaoniuma001
    
    • 1
    • 2

    请添加图片描述
     如上图中所示,出现了一个 eth1 接口,此时,eth0 连接到默认的 bridge 网络,eth1 连接到 network1 网络。

     对于自定义的网络来说,docker 嵌入的 DNS 服务支持连接到该网络的容器名的解析。这意味着连接到同一个网络的容器都可以通过容器名去ping另一个容器。

     如下所示,启动两个容器,连接到 network1

    docker run -itd --name xiaoniuma_1 --network network1 --rm busybox /bin/sh
    docker run -it --name xiaoniuma_2 --network network1 --rm busybox /bin/sh
    
    • 1
    • 2

     启动之后,由于上述的两个容器都是连接到 network1 网络,所以可以通过容器名 ping 通:
    请添加图片描述

     除此之外,在用户自定义的网络中,是可以通过 --ip 指定 IP 地址的,但在默认的 bridge 网络不能指定 IP 地址:

    # 连接到 network1 网络,运行成功
    docker run -it --network network1 --ip 192.168.16.100 --rm busybox /bin/sh
    # 连接到默认的 bridge 网络,下面的命令运行失败
    docker run -it --rm busybox --ip 192.168.16.100 --rm busybox /bin/sh
    
    • 1
    • 2
    • 3
    • 4

    请添加图片描述

    四、host 和 none

     当容器的网络为 host 时,容器可以直接访问主机上的网络。

     例如,我们启动一个容器,指定网络为 host

    docker run -it --network host --rm busybox /bin/sh
    
    • 1

     如下所示,该容器可以直接访问主机上的网络:
    请添加图片描述
    none 网络,容器中不提供其它网络接口。none 网络的容器创建之后还可以自己 connect 一个网络,比如使用 docker network connect bridge 容器名 可以将这个容器添加到 bridge 网络中。

    docker run -it --network none --rm busybox /bin/sh
    
    • 1

    请添加图片描述

    总结

    本文讲解以下内容:

    • docker 容器端口映射
    • 自定义网络实现容器互联
    • host 和 none 网络的使用

    下文将通过完成一个实例来学习 Dockerfile 的编写。

  • 相关阅读:
    数据库管理-第112期 Oracle Exadata 03-网络与ILOM(20231020)
    【云原生之Docker】使用docker部署talebook个人图书管理平台
    为什么说 java中的Synchronized是非公平锁
    Codeforces Round #797 (Div. 3)个人题解
    Linux下的clock_gettime()获取系统时间跳变问题
    Linux中的权限机制
    前端登录退出:处理Token问题(获取、缓存、失效处理)以及代码实现
    SIP通话分析
    LeetCode 43. 字符串相乘
    Flutter 视频video_player与缓存flutter_cache_manager
  • 原文地址:https://blog.csdn.net/weixin_44009656/article/details/125563041