【Docker】网络模式详解及容器间网络通信

目录

一、概述

二、默认网络

三、网络模式及应用

[1. Bridge模式](#1. Bridge模式)

[2. Host模式](#2. Host模式)

[3. none网络模式](#3. none网络模式)

四、自定义网络应用

[1. 网络相连](#1. 网络相连)

[2. 自定义通讯](#2. 自定义通讯)

[3. 自定义IP](#3. 自定义IP)

每篇一获


一、概述

在 Docker 中,网络设置包括 IP 地址、子网掩码、网关、DNS 和端口号等关键组成部分。下面我将为您详细介绍这些概念:

  1. IP 地址:IP 地址是 Docker 容器在网络中的唯一标识。每个 Docker 容器都会被分配一个 IP 地址,用于在网络中进行通信。在 Docker 的默认网络模式下,Docker 容器的 IP 地址是由 Docker 内部的 IPAM(IP 地址管理)系统自动分配的。

  2. 子网掩码:子网掩码用于划分 IP 地址的网络部分和主机部分。在 Docker 中,您可以在创建自定义网络时指定子网掩码,以划分您的 Docker 网络。

  3. 网关:网关是 Docker 容器访问外部网络的入口。在 Docker 的默认网络模式下,Docker 容器的网关是由 Docker 内部的 IPAM 系统自动分配的。

  4. DNS:DNS(域名系统)用于将域名解析为 IP 地址。在 Docker 中,您可以在创建 Docker 容器时指定 DNS 服务器,以便 Docker 容器可以解析域名。

  5. 端口号:端口号用于标识 Docker 容器内部的特定网络服务。在 Docker 中,您可以在创建 Docker 容器时指定端口映射,以便外部网络可以访问 Docker 容器内部的网络服务。

以上就是 Docker 中关于网络的 IP 地址、子网掩码、网关、DNS 和端口号的详细介绍。理解这些概念对于管理和配置 Docker 容器的网络环境非常重要。

子网掩码:

子网掩码是网络地址的一部分,用于划分网络地址和主机地址。它是一个 32 位的二进制数,其中网络部分全为 1,主机部分全为 0。子网掩码的主要作用是帮助网络设备判断一个 IP 地址的哪些位代表网络地址,哪些位代表主机地址。

在 Docker 中,当我们创建自定义网络时,可以指定子网掩码。例如,我们可以创建一个子网掩码为 255.255.255.0 的网络,这意味着这个网络的前 24 位(即 255.255.255)是网络地址,后 8 位是主机地址。这样,我们就可以在这个网络中创建最多 256(2 的 8 次方)个 Docker 容器。

子网掩码的设置对于 Docker 网络的划分和管理非常重要。通过合理地设置子网掩码,我们可以有效地管理 Docker 容器的网络资源,例如避免 IP 地址的冲突,或者根据需要划分不同的网络区域。

网关:

网关在网络中起着非常重要的作用,它是一个网络设备,用于连接两个或更多的网络,使得这些网络可以互相通信。在 Docker 中,网关通常被用于连接 Docker 容器和外部网络。

在 Docker 的默认网络模式下,每个 Docker 容器都会被分配一个网关地址。这个网关地址是 Docker 容器访问外部网络的入口,所有从 Docker 容器发出的网络请求都会通过这个网关地址转发到外部网络。
例如,如果一个 Docker 容器需要访问互联网上的一个网站,它会将网络请求发送到它的网关地址,然后由网关将请求转发到互联网。同样,所有发往 Docker 容器的网络响应也会通过网关地址转发回 Docker 容器。

在创建自定义网络时,我们可以指定网关地址。这样,我们就可以控制 Docker 容器的网络访问,例如限制 Docker 容器访问特定的外部网络,或者设置网络路由规则。

二、默认网络

安装 Docker 以后,会默认创建三种网络,可以通过 docker network ls 命令查看。

  1. Bridge:Bridge 网络是 Docker 的默认网络模型。当您启动一个新的 Docker 容器时,如果没有指定网络,Docker 就会自动将这个容器连接到 Bridge 网络。Bridge 网络允许容器之间通过 IP 地址或者容器名进行通信,但是,不同的 Bridge 网络之间的容器是无法进行通信的。

  2. Host:在 Host 网络模式下,Docker 容器将直接使用主机的网络,无需进行任何的网络转发。这意味着,如果您在容器中启动了一个网络服务,那么这个服务将直接使用主机的网络端口。

  3. None:None 网络模式下,Docker 容器将运行在自己的网络命名空间中,但是不会进行任何网络配置。这意味着,这个容器没有网络接口,无法进行网络通信。

三、网络模式及应用

1. Bridge模式

Bridge 网络模式 是 Docker 的默认网络模式,又称网桥模式,它为 Docker 容器提供了一种简单且有效的网络连接方式。以下是 Bridge 网络模式的主要作用和应用:

  1. 容器间通信:在 Bridge 网络模式下,同一 Bridge 网络中的 Docker 容器可以通过 IP 地址或者容器名进行通信。这使得在同一主机上运行的不同容器可以方便地共享数据和服务。

  2. 网络隔离:每个 Bridge 网络都是独立的,不同 Bridge 网络之间的容器无法直接通信。这为 Docker 容器提供了一种有效的网络隔离机制,可以防止不同应用之间的网络干扰。

  3. 端口映射:Bridge 网络模式支持 Docker 容器和主机之间的端口映射。这意味着,您可以将 Docker 容器的网络服务通过特定的端口暴露给主机,从而使得外部网络可以访问到 Docker 容器的服务。

在实际应用中,Bridge 网络模式被广泛用于部署和运行各种 Docker 应用。例如,您可以使用 Bridge 网络模式来部署一个 Web 服务器和数据库服务器,然后通过端口映射将 Web 服务器的服务暴露给外部网络,同时保持数据库服务器在网络中的隔离。

命令:

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

t1名称 9999主机端口 8080虚拟机端口 tomcat镜像 镜像版本8.5.20

查看:

docker inspect t1

t1 容器名称

查看信息如下:

  1. Gateway:这是 Docker 容器的默认网关,也就是容器发送的所有非本地地址的网络流量都会通过这个网关路由。在大多数情况下,这个网关就是 Docker 容器所在的主机。

  2. IPAddress:这是 Docker 容器在其网络内的 IP 地址。每个 Docker 容器在其所连接的网络中都会有一个唯一的 IP 地址,其他容器可以通过这个 IP 地址与其进行通信。

查看默认网络【bridge】:

docker inspect bridge

  1. Container ID:这是 Docker 容器的唯一标识符,由 Docker 在创建容器时自动生成。

  2. Name:这是 Docker 容器的名称,可以在创建容器时由用户自定义,也可以由 Docker 自动生成。

  3. IPv4Address:这是 Docker 容器在 Bridge 网络中的 IPv4 地址。其他容器可以通过这个地址与其进行通信。

  4. IPv6Address:这是 Docker 容器在 Bridge 网络中的 IPv6 地址。如果 Docker 容器的网络配置支持 IPv6,那么这个地址就会被显示出来。

  5. EndpointID:这是 Docker 容器在 Bridge 网络中的端点标识符。Docker 使用这个标识符来跟踪容器的网络连接。

  6. MacAddress:这是 Docker 容器的 MAC 地址。虽然 Docker 容器是虚拟的,但是它们在网络中的行为就像真实的物理设备一样,包括拥有自己的 MAC 地址。

  • 外部访问

设置端口映射

docker run -itd --name bridge -p 8081:8080 spring:1.0
在这个 Docker 命令中,-p 8081:8080 是一个端口映射参数。这个参数的作用是将 Docker 容器内的端口映射到宿主机的端口上。

具体来说,8081:8080 的含义是:

  • 8081 是宿主机的端口号。
  • 8080 是 Docker 容器内的端口号。

这个参数的设置意味着,Docker 容器内运行的应用如果监听在 8080 端口,那么这个应用的服务就可以通过宿主机的 8081 端口进行访问。
例如,如果您的 spring:1.0 容器是运行一个 Web 服务,并且这个服务在容器内监听 8080 端口,那么您就可以通过访问宿主机的 8081 端口来使用这个 Web 服务。

端口映射是 Docker 的一个重要特性,它使得 Docker 容器内的应用可以方便地对外提供服务,而无需关心容器的网络环境和配置。

-p 参数可以出现多次,绑定多个端口号

docker run -itd --name bridge -p 8081:8080 -p 8082:8080 spring:1.0

在这个的 Docker 命令中,-p 8081:8080 -p 8082:8080 是端口映射参数,这里映射了两个宿主机端口到同一个 Docker 容器内的端口。

具体来说:

  • -p 8081:8080 表示将 Docker 容器内的 8080 端口映射到宿主机的 8081 端口。
  • -p 8082:8080 表示将 Docker 容器内的 8080 端口映射到宿主机的 8082 端口。

这个设置意味着,Docker 容器内运行的应用如果监听在 8080 端口,那么这个应用的服务就可以通过宿主机的 8081 端口和 8082 端口进行访问。
这种绑定多个端口的方式可以让您有更多的选择来访问 Docker 容器内的服务,也可以用来处理一些特殊的网络需求,例如负载均衡和端口冲突等问题。

2. Host模式

Host 网络模式 是 Docker 的一种网络模式,又称主机模式,它允许 Docker 容器共享宿主机的网络命名空间。以下是 Host 网络模式的主要作用和应用:

  1. 性能优化:在 Host 网络模式下,Docker 容器可以直接使用宿主机的网络,无需通过 Docker 的网络桥接,这可以减少网络延迟,提高网络性能。

  2. 端口管理:在 Host 网络模式下,Docker 容器内的端口会直接映射到宿主机的端口,无需进行额外的端口映射设置。这使得端口管理更加简单,也避免了端口映射可能带来的端口冲突问题。

  3. 网络服务部署:对于需要直接使用宿主机网络的网络服务,例如需要监听宿主机所有 IP 地址的服务,或者需要使用特定网络接口或协议的服务,Host 网络模式是一个很好的选择。

在实际应用中,Host 网络模式常常被用于部署需要高性能网络或者特殊网络需求的 Docker 应用。例如,您可以使用 Host 网络模式来部署一个需要监听所有 IP 地址的 Web 服务器,或者一个需要使用特定网络接口的 VPN 服务。
需要注意的是,Host 网络模式下的 Docker 容器会直接共享宿主机的网络,这可能会带来一些安全风险,因此在使用 Host 网络模式时,需要对 Docker 容器的网络访问进行适当的控制和限制。

创建:

docker run -itd --name t2 -p8848:8080 --net host tomcat:8.5.20

创建完成之后,可以直接在主机上通过虚拟机ip访问:


在这个模式下不用映射端口也可以访问,默认8080直接映射:

删除容器:docker rm -f t2 (删除已有容器t2)

创建:docker run -itd --name t2 --net host tomcat:8.5.20

3. none网络模式

None 网络模式 是 Docker 的一种网络模式,它为 Docker 容器提供了一个最小化的网络环境。
在 None 网络模式下,Docker 容器拥有自己的网络命名空间,但是不会进行任何网络设备、IP 地址和路由的配置。这意味着,Docker 容器在 None 网络模式下无法进行网络通信。

以下是 None 网络模式的主要应用:

  1. 网络隔离:None 网络模式可以为 Docker 容器提供一个完全隔离的网络环境,这对于需要高度网络隔离的应用非常有用。例如,您可以使用 None 网络模式来运行一些安全敏感的应用,以防止这些应用被网络攻击。

  2. 自定义网络配置:虽然 None 网络模式下的 Docker 容器默认无法进行网络通信,但是您可以在容器内部进行自定义的网络配置,以满足特殊的网络需求。例如,您可以在 None 网络模式下的 Docker 容器内部设置 VPN,以实现容器的网络通信。

需要注意的是,None 网络模式下的 Docker 容器默认无法进行网络通信,因此在使用 None 网络模式时,需要对 Docker 容器的网络需求进行详细的评估和规划。

  • none 网络模式是指禁用网络功能,只有 lo 接口 local 的简写,代表 127.0.0.1,即 localhost 本地环回接口。在创建容器时通过参数 --net none 或者 --network none 指定;
  • none 网络模式即不为 Docker Container 创建任何的网络环境,容器内部就只能使用 loopback 网络设备,不会再有其他的网络资源。可以说 none 模式为 Docke Container 做了极少的网络设定,但是俗话说得好"少即是多",在没有网络配置的情况下,作为 Docker 开发者,才能在这基础做其他无限多可能的网络定制开发。这也恰巧体现了 Docker 设计理念的开放。
    我们可以通过 docker network inspect none 查看所有 none 网络模式下的容器,在 Containers 节点中可以看到容器名称。

四、自定义网络应用

1. 网络相连

删除所有容器,看容器中的网络是否相互连得通,当然也可以不删除,保证容器不一致即可
删除所有容器:docker rm -f $(docker ps -aq)

创建:docker run -it --name c1 centos

并且查看ip:ip addr

创建:docker run -it --name c2 centos

并且查看ip:ip addr

在c1中看看可不可以连接到c2中,进行网络相连

命令:ping 172.17.0.3 (172.17.0.3是c2的ip)

在c2中看看可不可以连接到c1中,进行网络相连

命令:ping 172.17.0.2 (172.17.0.2是c1的ip)

由以上看出两容器是网络相连的

2. 自定义通讯

创建路径:

mkdir -p /mysql/{conf,data}

创建一个mysql目录在其中创建了两个文件夹,名为conf,data

将主机(自己的电脑)上的mysql配置文件拖到虚拟机的新建路径中的conf文件夹中

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

创建目录:mkdir mode

将主机(自己的电脑)上的war拖到虚拟机的新建路径中

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

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

之后在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
输入创建时的密码即可,也就是在mysql目录中执行命令中的MYSQL_ROOT_PASSWORD

在mysql中创建一个名为jun的用户,可以进行远程访问
命令:grant all on *.* to jun@'%' identified by '123456';
并且退出:exit

重新启动mysql容器

命令:docker restart m1
在启动的war中的配置文件进行修改/mode/bs/WEB-INF/classes/中的application.yml的mysql

配置:


在这里也可以写容器的ip进行目录,查看容器信息即可查看容器IP

3. 自定义IP

需要先创建一个网络

docker network create --subnet 172.18.0.0/16 mode

其中mode为网络名称,可以直接修改名称,subnet是指定IP

查看我们创建网络的网段:docker inspect mode (mode是需要查看的网络名称)

创建并指定容器的IP:

  1. tomcat

    docker run -it --name t1
    -p 8080:8080
    -v /mode:/usr/local/tomcat/webapps \
    --net mode
    --ip 172.18.0.2 \
    tomcat:8.5.20

  1. 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
    --net mode
    --ip 172.18.0.3
    -d mysql/mysql-server:5.7

之后修改根据容器的名称修改war中的配置连接mysql,/mode/bs/WEB-INF/classes/中的application.yml,如何修改上面由讲述。

每篇一获

学习 Docker 的网络模式以及如何自定义网络和 IP,可以带给我们以下几方面的收获:

  1. 更好的网络管理:理解 Docker 的网络模式可以帮助我们更好地管理 Docker 容器的网络环境,例如选择合适的网络模式来满足特定的网络需求,或者解决 Docker 容器的网络问题。

  2. 更高的网络性能:通过选择合适的网络模式,例如 Host 网络模式,我们可以提高 Docker 容器的网络性能。同时,通过自定义网络和 IP,我们可以进一步优化 Docker 容器的网络配置,以提高网络性能。

  3. 更强的网络安全:理解 Docker 的网络模式可以帮助我们更好地保护 Docker 容器的网络安全,例如使用 None 网络模式来实现网络隔离,或者使用自定义网络和 IP 来限制 Docker 容器的网络访问。

  4. 更大的网络灵活性:通过自定义网络和 IP,我们可以为 Docker 容器创建更灵活的网络环境,例如创建多个网络来隔离不同的 Docker 容器,或者为 Docker 容器分配特定的 IP 地址。

总的来说,学习 Docker 的网络模式以及如何自定义网络和 IP,可以帮助我们更好地使用 Docker,提高我们的工作效率和产品质量。

相关推荐
@东辰6 分钟前
【golang-技巧】-自定义k8s-operator-by kubebuilder
开发语言·golang·kubernetes
乐悠小码13 分钟前
数据结构------队列(Java语言描述)
java·开发语言·数据结构·链表·队列
史努比.15 分钟前
Pod控制器
java·开发语言
陈小肚15 分钟前
k8s 1.28.2 集群部署 docker registry 接入 MinIO 存储
docker·容器·kubernetes
敲敲敲-敲代码23 分钟前
游戏设计:推箱子【easyx图形界面/c语言】
c语言·开发语言·游戏
A陈雷32 分钟前
springboot整合elasticsearch,并使用docker desktop运行elasticsearch镜像容器遇到的问题。
spring boot·elasticsearch·docker
ROC_bird..32 分钟前
STL - vector的使用和模拟实现
开发语言·c++
小扳37 分钟前
Docker 篇-Docker 详细安装、了解和使用 Docker 核心功能(数据卷、自定义镜像 Dockerfile、网络)
运维·spring boot·后端·mysql·spring cloud·docker·容器
MavenTalk38 分钟前
Move开发语言在区块链的开发与应用
开发语言·python·rust·区块链·solidity·move
运维佬1 小时前
CentOS 9 配置网卡
linux·centos