Docker网络配置的三种方式

 更新时间:2024年01月18日 09:20:57   作者:Java方文山  
在使用Docker时,网络通信是必不可少的,它可以使不同的Docker容器相互通信,也可以将容器与外部网络连接起来,本文给大家介绍了Docker网络配置的三种方式,文中通过图文给大家讲解非常详细,需要的朋友可以参考下

前言

在使用Docker时,网络通信是必不可少的,它可以使不同的Docker容器相互通信,也可以将容器与外部网络连接起来。以下是一个场景的示例:

假设你正在开发一个包含前端和后端的Web应用程序。你可以使用Docker来创建两个容器,一个用于运行前端代码,另一个用于运行后端代码。

在这种情况下,网络通信非常重要。前端容器需要能够与后端容器进行通信,以便从后端获取数据并将其呈现给用户。同时,前端容器还需要能够通过网络将用户的请求发送到后端容器。

通过创建一个自定义的Docker网络,你可以实现这种通信。你可以将两个容器连接到同一个网络中,使它们能够通过网络进行通信。这样,前端容器就可以通过网络请求来获取后端容器提供的数据,然后将结果呈现给用户。

此外,你还可以配置Docker网络,使得外部网络可以通过特定端口访问你的应用程序。这样,用户可以通过他们的Web浏览器访问你的应用程序,并与前端容器进行通信,通过网络请求与后端容器进行交互。

一、网络相关

在学习网络模式的配置之前我们需要了解以下几个东西,分别是子网掩码网关规则这些东西对于后面我们对ip的理解有很大的帮助。

1.子网掩码

IP地址是以网络号和主机号来标示网络上的主机的,我们把网络号相同的主机称之为本地网络,网络号不相同的主机称之为远程网络主机,本地网络中的主机可以直接相互通信;远程网络中的主机要相互通信必须通过本地网关(Gateway)来传递转发数据。

  • 子网掩码是“255.255.255.0”的网络:

最后面一个数字可以在 0~255 范围内任意变化,因此可以提供 256 个 IP 地址。但是实际可用的 IP 地址数量是256-2 ,即 254 个,因为主机号不能全是 “0” 或全是 “1” 。

  • 子网掩码是“255.255.0.0”的网络:

后面两个数字可以在 0~255 范围内任意变化,可以提供 255² 个 IP 地址。但是实际可用的 IP 地址数量是255²-2 ,即 65023 个。

1.1.子网掩码的组成

①同IP地址一样,子网掩码是由长度为32位二进制数组成的一个地址。
②子网掩码32位与IP地址32位相对应,IP地址如果某位是网络地址,则子网掩码为1,否则为0。
③举个栗子:如:11111111.11111111.11111111.00000000

注:左边连续的1的个数代表网络号的长度,(使用时必须是连续的,理论上也可以不连续),右边连续的0的个数代表主机号的长度。

1.2.子网掩码的表示方法

①、点分十进制表示法
二进制转换十进制,每8位用点号隔开
例如:子网掩码二进制11111111.11111111.11111111.00000000,表示为255.255.255.0

②、CIDR斜线记法
IP地址/n
例1:192.168.1.100/24,其子网掩码表示为255.255.255.0,二进制表示为11111111.11111111.11111111.00000000
例2:172.16.198.12/20,其子网掩码表示为255.255.240.0,二进制表示为11111111.11111111.11110000.00000000
不难发现,例1中共有24个1,例2中共有20个1,所以n是这么来的。运营商ISP常用这样的方法给客户分配IP地址。

注:n为1到32的数字,表示子网掩码中网络号的长度,通过n的个数确定子网的主机数=2^(32-n)-2(-2的原因:主机位全为0时表示本网络的网络地址,主机位全为1时表示本网络的广播地址,这是两个特殊地址)。

1.3.子网掩码的分类

①、缺省子网掩码

也叫默认子网掩码,即未划分子网,对应的网络号的位都置 1 ,主机号都置 0 。

未做子网划分的IP地址:网络号+主机号

A类网络缺省子网掩码: 255.0.0.0,用CIDR表示为/8

B类网络缺省子网掩码: 255.255.0.0,用CIDR表示为/16

C类网络缺省子网掩码: 255.255.255.0,用CIDR表示为/24

②、自定义子网掩码

将一个网络划分子网后,把原本的主机号位置的一部分给了子网号,余下的才是给了子网的主机号。其形式如下:

做子网划分后的IP地址:网络号+子网号+子网主机号

举个例子:

如:192.168.1.100/25,其子网掩码表示:255.255.255.128

意思就是将192.168.1.0这个网段的主机位的最高1位划分为了子网。关于子网划分将在下篇文章讲到,这里不在阐述。

2.网关

网关实质上是一个网络通向其他网络的 IP 地址。 路由器( Windows 下叫默认网关,网关就是路由,路由就是网关不要蒙)

在如下拓扑图示例中,A与B,C与D,都可以直接相互通信(都是属于各自同一网段,不用经过路由器),但是A与C,A与D,B与C,B与D它们之间不属于同一网段,所以它们通信是要经过本地网关,然后路由器根据对方IP地址,在路由表中查找恰好有匹配到对方IP地址的直连路由,于是从另一边网关接口转发出去实现互连。

注意:网关的主机部分通常占用的是.1

3.规则

计算机的 IP 地址由两部分组成,一部分为网络标识,一部分为主机标识,同一网段内的计算机网络部分相同,主机部分不同同时重复出现。 路由器连接不同网段,负责不同网段之间的数据转发,交换机连接的是同一网段的计算机。通过设置网络地址和主机地址,在互相连接的整个网络中保证每台主机的IP 地址不会互相重叠,即 IP 地址具有了唯一性。

在计算机网络中,主机 ID 全部为 0 的地址为网络地址,而主机 ID 全部为 1 的地址为广播地址 这 2 个地址是不能分配给主机用的

二、Dockers的网络配置

当你安装了 docker, 它会自动创建 3 个网络,可以使用 docker network ls 命令来查看

docker network ls

Docker提供了以下常用的网络模式:

Bridge模式(桥接模式):默认的网络模式,容器通过虚拟网桥连接到主机的物理网络接口上,可以通过端口映射将容器的端口映射到主机上。

Host模式(主机模式):容器与主机共享网络命名空间,容器直接使用主机的网络栈,可以轻松访问主机上的网络资源,但会损失一定的隔离性。

None模式(无网络模式):容器不连接到任何网络,只能通过内部与其他容器进行通信,不能与外部进行网络通信。

当你运行一个容器的时候,可以使用 --network 参数来指定你的容器连接到哪一个网络。

1.bridge模式

当 Docker 进程启动时,会在主机上创建一个名为 docker0 的虚拟网桥,此主机上启动的 Docker 容器会连接到这个虚拟网桥上。

虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。 从 docker0 子网中分配一个 IP 给容器使用,并设置 docker0 的 IP 地址为容器的默认网关。 在主机上创建一对虚拟网卡 veth pair 设备, Docker 将 veth pair 设备的一端放在新创建的容器中,并命名为eth0 (容器的网卡),另一端放在主机中,以 vethxxx 这样类似的名字命名,并将这个网络设备加入 到 docker0 网桥中。

bridge模式是docker的默认网络模式,不写--net参数,就是bridge模式。每个bridge模式的容器都有一个独立的IP,如果外部需要访问需要进行端口映射。

docker run -itd --name t1 -p 8080:8080 tomcat:8.5.20

创建一个容器后我们查看一下它的bridge信息

docker inspect t1

可以看到它网桥是172.17.0.2,它的网关是172.17.0.1,网络模式是bridge

我们再来看一下这个网络模式bridge

docker inspect bridge

这里有个Containers容器集合,bridge的容器中就会有个“t1”容器它的IP是172.17.0.2/16说明它的子网掩码是255.255.0.0,用CIDR表示为/16

docker0 就像是一个路由器,容器就像是路由器下的设备,它们在同一个网段内可以互相 ping 通。

注意:
-p 参数可以出现多次,绑定多个端口号
docker run - itd -- name t1  - p 8082:8080 - p 8083:8080 tomcat:8.5.20

2.host模式

如果启动容器的时候使用 host 模式,那么这个容器将不会获得一个独立的 Network Namespace ,而是 和宿主机共用一个Network Namespace 。 容器将不会虚拟出自己的网卡,配置自己的 IP 等,而是使用宿主机的 IP 和端口。 但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。

创建一个容器指定为host模式

docker run -itd --name t2  --net=host tomcat:8.5.20

如果你的虚拟机是和主机一个网络那么可直接访问8080,不需要做端口映射

使用host模式可能会导致安全隐患。由于容器共享主机网络栈,容器内的进程可以访问主机上的所有网络资源,包括主机上未公开的端口和共享文件。因此,如果容器本身存在安全漏洞,则容易受到攻击。

三、容器之间相互通讯

我们了解了bridge模式,下面我们来尝试一下看看是否真的可以建立连接

docker run -it --name c1   centos
 
docker run -it --name c2   centos

首先创建两个容器,因为默认是bridge模式所以不用指定,下面再查看一下c2的IP是多少

ip addr

可以看到我们的c2的IP是172.17.0.3我们使用c1连接一下

四、自定义IP通讯

1.容器之间连接mysql

我们现在宿主机上创建一个目录名为soft并往目录下放入一个war包

创建一个基于tomcat的容器并进行目录挂载

docker run -it \
--name t1 \
-p 8080:8080 \
-v /soft:/usr/local/tomcat/webapps \
tomcat:8.5.20

可以看到跑成功了

但是我们接下来做一个操作进行数据访问

进行数据访问它会去连接我们的mysql,因为没有mysql所以报错,现在我们来搞一个mysql,创建mysql之前需要做一个事情,mysql需要一个my.cnf的配置文件,目前我们还没有所以需要在宿主机上创建一个将该文件放入到目录中

mkdir -p /mysql/{conf,data}

这是my.cnf的内容

[client]
default-character-set=utf8
 
[mysql]
default-character-set=utf8
 
[mysqld]
# Remove leading # and set to the amount of RAM for the most important data
# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
# innodb_buffer_pool_size = 128M
#
# Remove leading # to turn on a very important data integrity option: logging
# changes to the binary log between backups.
# log_bin
#
# Remove leading # to set options mainly useful for reporting servers.
# The server defaults are faster for transactions and fast SELECTs.
# Adjust sizes as needed, experiment to find the optimal values.
# join_buffer_size = 128M
# sort_buffer_size = 2M
# read_rnd_buffer_size = 2M
skip-host-cache
skip-name-resolve
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
secure-file-priv=/var/lib/mysql-files
user=mysql
 
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
 
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
 
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
# default: sql_mode= STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
# modeified: 
sql_mode= STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
max_allowed_packet=10M
default-time_zone='+8:00'
default_authentication_plugin=mysql_native_password

我们进入到mysql/data目录下创建mysql容器

docker run \
--name m1 \
-v /mysql/conf/my.cnf:/etc/my.cnf \
-v /mysql/data:/var/lib/mysql \
--privileged=true \
-e MYSQL_ROOT_PASSWORD=123456 \
-d mysql/mysql-server:5.7

进入我们的mysql容器进行登录

 docker exec -it m1 bash
 
 
mysql -uroot -p

登录成功以后,我们现在需要一个账户进行远程连接所以创建一个账户并赋予权限

grant all on *.* to ww@'%' identified by '密码'

记得重启一下docker restart m1

我们进入到被解压的war的配置文件中修改配置文件中的mysql连接

我们查看指定容器的日志并以实时方式跟踪输出看一下现在会怎么样。

docker -logs -f t1

2.自定义容器IP

虽然现在容器之间是可以相互访问了,但是我们的ip是docker0发放的,也就是说,这个ip和创建容器的顺序有关系,如果我是先创建mysql容器后创建tomcat容器,那么我们的ip是不是又发生了改变,是不是有需要去修改mysql的配置连接?太麻烦了我只能说。

我们就可以使用自定义网络的方式,自定义网络不但支持自定义IP还可以支持以容器名的方式进行访问。

①我们首先需要创建一个网络

docker network create --subnet 172.18.0.0/16 --gateway 172.18.1.1 [name]

②我们需要查看该网络的网段是多少

docker inspect net

③为我们的容器指定IP

docker run -it \
--name t1 \
-p 8080:8080 \
-v /soft:/usr/local/tomcat/webapps \
--net net \
--ip 172.18.0.2 \
tomcat:8.5.20
docker run \
--name m1 \
-v /mysql/conf/my.cnf:/etc/my.cnf \
-v /mysql/data:/var/lib/mysql \
--privileged=true \
-e MYSQL_ROOT_PASSWORD=123456 \
--net net \
--ip 172.18.0.3 \
-d mysql/mysql-server:5.7

④修改mysql连接的配置文件

我们前面说过自定义网络的方式可以通过容器名来访问

五、注意事项

①根据自定义网络创建容器失败

如果在使用自定义网络创建容器的时候出现这个问题

因为docker中,只有使用 --subnet创建的网络才能指定静态IP。因此在使用docker-compose或者docker run命令创建容器时,如果需要指定,则可以使用 :

  • –subnet创建网络(用来指定ip段)
  • –gateway(用来指定网关)
  • name为创建的名字
docker network create --subnet 172.18.0.0/16 --gateway 172.18.1.1 [name]

②不同容器相互连接

我现在有两个容器他们的IP分别是172.17.0.2和172.18.0.2根本不在一个网段里面,此时我想要172.17.0.2的这个容器去ping172.18.0.2是根本不可能的

运行以下命令将c1容器连接到自定义的net网络

docker network connect net c1

现在我们看一下我们c1有几个网络

现在就可以进行连接了​

以上就是Docker网络配置的三种方式的详细内容,更多关于Docker网络配置的资料请关注脚本之家其它相关文章!

相关文章

  • docker run起来之后执行多条命令

    docker run起来之后执行多条命令

    docker run :创建一个新的容器并运行一个命令。这篇文章主要介绍了docker run起来之后执行多条命令 ,需要的朋友可以参考下
    2017-11-11
  • linux下如何使用docker安装minio

    linux下如何使用docker安装minio

    这篇文章主要介绍了linux下如何使用docker安装minio问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04
  • docker run -v 挂载数据卷异常,容器状态一直是restarting的解决

    docker run -v 挂载数据卷异常,容器状态一直是restarting的解决

    这篇文章主要介绍了docker run -v 挂载数据卷异常,容器状态一直是restarting的解决方案,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-03-03
  • Docker常用命令Study03详解

    Docker常用命令Study03详解

    这篇文章主要介绍了Docker常用命令Study03详解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12
  • 基于Docker与Jenkins实现自动化部署的原理解析

    基于Docker与Jenkins实现自动化部署的原理解析

    这篇文章主要介绍了基于Docker与Jenkins实现自动化部署,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-04-04
  • 详解ASP.NET Core 网站在Docker中运行

    详解ASP.NET Core 网站在Docker中运行

    本篇文章主要介绍了详解ASP.NET Core 网站在Docker中运行,非常具有实用价值,需要的朋友可以参考下
    2017-05-05
  • docker images 如何建立自己的原生镜像

    docker images 如何建立自己的原生镜像

    这篇文章主要介绍了docker images 如何建立自己的原生镜像的相关资料,需要的朋友可以参考下
    2017-04-04
  • docker 安装solr8.6.2 配置中文分词器的方法

    docker 安装solr8.6.2 配置中文分词器的方法

    这篇文章主要介绍了docker 安装solr8.6.2 配置中文分词器的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • Dockerfile文件详解

    Dockerfile文件详解

    Dockerfile是一个用来构建镜像的文本文件,文本内容包含一条条构建镜像所需的指令和说明。本文详细讲解了Dockerfile文件,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • 如何在Docker中设置Redis的密码

    如何在Docker中设置Redis的密码

    这篇文章主要介绍了在Docker中设置Redis的密码的相关知识,通过使用Docker,我们可以轻松地启动Redis容器并设置密码来保护我们的Redis实例,这提供了一个简单和可移植的方法来部署和管理Redis服务器,感兴趣的朋友一起看看吧
    2023-11-11

最新评论