欢迎来到我的CSDN主页!

我是Java方文山,一个在CSDN分享笔记的博主。

推荐给大家我的专栏《Docker实战》。

点击这里,就可以查看我的主页啦!

Java方文山的个人主页

如果感觉还不错的话请给我点赞吧!

期待你的加入,一起学习,一起进步!

目录

✨前言

一、网络相关

1.子网掩码

1.1.子网掩码的组成

1.2.子网掩码的表示方法

 1.3.子网掩码的分类

2.网关

3.规则

二、Dockers的网络配置

1.bridge模式

2.host模式

三、容器之间相互通讯

四、自定义IP通讯

1.容器之间连接mysql

 2.自定义容器IP

五、注意事项

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

②不同容器相互连接

 

✨前言

在使用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有几个网络

 

现在就可以进行连接了

到这里我的分享就结束了,欢迎到评论区探讨交流!!

如果觉得有用的话还请点个赞吧 

好文推荐

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。