docker网络

-----------------Docker 网络---------------------------

桥接模式是一种用于连接两个不同网络段的设备,使它们能够共享通信的一种方式。
桥接设备工作在OSI模型的第二层,即数据链路层,通常基于MAC地址进行帧转发。

物理层连接: 桥接设备通常有两个或多个网络接口,用于连接不同的物理网络。
这些接口可以是以太网接口,Wi-Fi接口等。

MAC地址学习: 当桥接设备启动时,它开始学习连接的网络上设备的MAC地址。
桥接设备通过观察网络流量并记录源MAC地址来建立MAC地址表。

帧转发: 当设备发送帧(数据包)时,桥接设备查看目标MAC地址。
如果目标MAC地址在桥接设备的MAC地址表中,它会将帧仅发送到相应接口。
如果目标MAC地址不在表中,桥接设备会将帧发送到所有其他接口

桥接模式在物理和数据链路层上工作,通过学习和转发MAC地址,连接不同的网络,
从而使它们看起来像是一个单一的网络。这种模式通常用于局域网的扩展和连接。

#Docker 网络实现原理
桥接模式是一种网络模式,它在 Docker 中的工作方式可以分为以下几个步骤:

虚拟网络桥创建: 当您启动 Docker 守护进程时,Docker 创建一个虚拟网络桥(通常称为 docker0),
它是一个虚拟的网络设备,类似于物理网络设备的交换机。

分配唯一的 IP 地址: 每次您运行一个容器时,Docker 分配一个唯一的 IP 地址给该容器。
这个 IP 地址是在桥接模式网络的子网中。

连接容器到桥接网络: 当容器启动时,Docker 将容器的虚拟网络接口(veth pair)连接到虚拟网络桥上。
其中一个端点位于容器内,而另一个端点位于主机上。

容器与主机通信: 通过桥接模式,容器可以直接与主机通信。这意味着容器可以访问主机上运行的服务,
而主机也可以通过容器的 IP 地址访问容器内的服务。

容器之间的通信: 如果有多个容器在相同的桥接网络上运行,它们可以通过各自的 IP 地址直接通信。
Docker 会自动在桥接网络上设置路由,使得容器之间可以直接交流。

NAT(网络地址转换): 默认情况下,Docker 使用 Network Address Translation(NAT)技术,
将容器的私有 IP 地址映射到主机上的公共 IP 地址。这样,容器可以与外部网络通信,
而外部网络看到的是主机的 IP 地址。

Docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,
这也意味着外部网络无法直接通过 Container-IP 访问到容器。
如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主主机(端口映射),
即 docker run 创建容器时候通过 -p 或 -P 参数来启用,访问容器的时候就通过[宿主机IP]:[容器端口]访问容器。

docker run -itd --name test1 -P nginx:1.22.0 /bin/bash            #随机映射端口(从32768开始)

docker run -d --name test2 -p 43000:80 nginx:1.22.0    /bin/bash    #指定映射端口

docker网络_第1张图片

docker网络_第2张图片

宿主机端口:主机上用于接收来自外部请求的端口。在这个例子中,它是43000。
容器端口:Docker容器内部正在监听的端口。在这个例子中,它是80,因为NGINX通常默认监听80端口。

docker ps -a
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                   NAMES
9d3c04f57a68   nginx     "/docker-entrypoint.…"   4 seconds ago    Up 3 seconds    0.0.0.0:43000->80/tcp   test2
b04895f870e5   nginx     "/docker-entrypoint.…"   17 seconds ago   Up 15 seconds   0.0.0.0:49170->80/tcp   test1

浏览器访问:http://192.168.80.10:43000    、http://192.168.80.10:49170

#查看容器的输出和日志信息
docker logs 容器的ID/名称


#Docker 的网络模式:
●Host:容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。

●Container:创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围。

●None:该模式关闭了容器的网络功能。

●Bridge:默认为该模式,此模式会为每一个容器分配、设置IP等,并将容器连接到一个docker0虚拟网桥,
通过docker0网桥以及iptables nat 表配置与宿主机通信。

●自定义网络

安装Docker时,它会自动创建三个网络,bridge(创建容器默认连接到此网络)、 none 、host

docker网络_第3张图片

docker network ls     或  docker network list            #查看docker网络列表

docker网络_第4张图片
NETWORK ID     NAME      DRIVER    SCOPE
2b4359d229c6   bridge    bridge    local
0fa580365d39   host      host      local
cc13aa84a223   none      null      local

NAME: 是Docker网络的名称。在这里,你列出了三个网络,它们的名称分别是bridge、host和none。

NETWORK ID: 每个Docker网络都有一个唯一的网络ID。

DRIVER: 这是Docker使用的网络驱动程序。在这里,bridge表示使用的是桥接网络,host表示使用的是主机网络,而none表示没有网络。

SCOPE: 表示网络的作用范围。local表示该网络仅在本地主机上可用。

#使用docker run创建Docker容器时,可以用 --net 或 --network 选项指定容器的网络模式
●host模式:使用 --net=host 指定。
●none模式:使用 --net=none 指定。
●container模式:使用 --net=container:NAME_or_ID 指定。
●bridge模式:使用 --net=bridge 指定,默认设置,可省略。

#网络模式详解:
1.host模式
主机模式(Host): 在主机模式下,容器与主机共享同一个网络命名空间,直接使用主机的网络栈。
这使得容器可以使用主机的 IP 地址和端口,从而不需要进行额外的端口映射。

docker run -itd --name test1 --network host nginx:1.22.0 /bin/bash
#进入容器要开启nginx的服务

2.container模式
在理解了host模式后,这个模式也就好理解了。
这个模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。 
新创建的容器不会创建自己的网卡,配置自己的IP,
而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,
其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信。

docker run -itd --name test1 --network host nginx:1.22.0 /bin/bash        #--name 选项可以给容器创建一个自定义名称

docker ps -a
CONTAINER ID   IMAGE      COMMAND       CREATED      STATUS       PORTS     NAMES
3ed82355f811   nginx:latest   "/bin/bash"   5 days ago   Up 6 hours             test1

docker inspect -f '{{.State.Pid}}' test1        #查看容器进程号
25945

ls -l /proc/25495/ns                    #查看容器的进程、网络、文件系统等命名空间编号
lrwxrwxrwx 1 root root 0 1月   7 11:29 ipc -> ipc:[4026532572]
lrwxrwxrwx 1 root root 0 1月   7 11:29 mnt -> mnt:[4026532569]
lrwxrwxrwx 1 root root 0 1月   7 11:27 net -> net:[4026532575]
lrwxrwxrwx 1 root root 0 1月   7 11:29 pid -> pid:[4026532573]
lrwxrwxrwx 1 root root 0 1月   7 12:22 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 1月   7 11:29 uts -> uts:[4026532570]

docker run -itd --name test2 --net=container:test1 nginx:1.22.0 /bin/bash
docker ps -a
CONTAINER ID   IMAGE      COMMAND       CREATED          STATUS          PORTS     NAMES
ff96bc43dd27   nginx:latest   "/bin/bash"   48 seconds ago   Up 46 seconds             test2
3ed82355f811   nginx:latest   "/bin/bash"   58 minutes ago   Up 58 minutes             test1

docker inspect -f '{{.State.Pid}}' ff96bc43dd27
27123

ls -l /proc/27123/ns            #查看可以发现两个容器的 net namespace 编号相同
lrwxrwxrwx 1 root root 0 1月   7 12:27 ipc -> ipc:[4026532692]
lrwxrwxrwx 1 root root 0 1月   7 12:27 mnt -> mnt:[4026532690]
lrwxrwxrwx 1 root root 0 1月   7 12:27 net -> net:[4026532575]
lrwxrwxrwx 1 root root 0 1月   7 12:27 pid -> pid:[4026532693]
lrwxrwxrwx 1 root root 0 1月   7 12:27 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 1月   7 12:27 uts -> uts:[4026532691]


3.none模式
使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。 
也就是说,这个Docker容器没有网卡、IP、路由等信息。
这种网络模式下容器只有lo回环网络,没有其他网卡。这种类型的网络没有办法联网,
封闭的网络能很好的保证容器的安全性。

docker run -itd --name test3 --network none nginx:1.22.0 /bin/bash

4.bridge模式
bridge模式是docker的默认网络模式,不用--net参数,就是bridge模式。
Docker 网络实现原理
桥接模式是一种网络模式,它在 Docker 中的工作方式可以分为以下几个步骤:

虚拟网络桥创建: 当您启动 Docker 守护进程时,Docker 创建一个虚拟网络桥(通常称为 docker0),
它是一个虚拟的网络设备,类似于物理网络设备的交换机。

分配唯一的 IP 地址: 每次您运行一个容器时,Docker 分配一个唯一的 IP 地址给该容器。
这个 IP 地址是在桥接模式网络的子网中。

连接容器到桥接网络: 当容器启动时,Docker 将容器的虚拟网络接口(veth pair)连接到虚拟网络桥上。
其中一个端点位于容器内,而另一个端点位于主机上。

容器与主机通信: 通过桥接模式,容器可以直接与主机通信。这意味着容器可以访问主机上运行的服务,
而主机也可以通过容器的 IP 地址访问容器内的服务。

容器之间的通信: 如果有多个容器在相同的桥接网络上运行,它们可以通过各自的 IP 地址直接通信。
Docker 会自动在桥接网络上设置路由,使得容器之间可以直接交流。

NAT(网络地址转换): 默认情况下,Docker 使用 Network Address Translation(NAT)技术,
将容器的私有 IP 地址映射到主机上的公共 IP 地址。这样,容器可以与外部网络通信,
而外部网络看到的是主机的 IP 地址。

使用 docker run -p 时,docker实际是在iptables做了DNAT规则,实现端口转发功能。
可以使用iptables -t nat -vnL 查看。


5.自定义网络
#直接使用bridge模式,是无法支持指定IP运行docker的,例如执行以下命令就会报错
docker run -itd --name test3 --network bridge --ip 172.17.0.10 nginx:latest /bin/bash

//创建自定义网络
#可以先自定义网络,再使用指定IP运行docker
docker network create --subnet=172.18.0.0/16 --opt "com.docker.network.bridge.name"="docker1"  mynetwork
----------------------------------------------------------------------------------------------------------


#docker1 为执行 ifconfig -a 命令时,显示的网卡名,如果不使用 --opt 参数指定此名称,
那你在使用 ifconfig -a 命令查看网络信息时,看到的是类似 br-110eb56a0b22 这样的名字,这显然不怎么好记。

#mynetwork 为执行 docker network list 命令时,显示的bridge网络模式名称。
----------------------------------------------------------------------------------------------------------
docker run -itd --name test4 --net mynetwork --ip 172.18.0.10 nginx:latest /bin/bash

进入虚拟机访问172.18.0.10


数据卷(容器与宿主机之间数据共享) 

数据卷是一个供容器使用的特殊目录,位于容器中。
可将宿主机的目录挂载到数据卷上,对数据卷的修改操作立刻可见,
并且更新数据不会影响镜像,从而实现数据在宿主机与容器之间的迁移。
数据卷的使用类似于Linux下对目录进行的mount操作。 

想要将容器中的数据持久化,可以将宿主机目录挂载到容器中。
一般只建议在创建容器时进行挂载,不建议启动容器后再挂载。
因为启动容器后再挂载的话,需要修改配置文件,且不一定能挂载成功。

docker run -v 数据卷              #在容器内创建数据卷
 ​
docker run -v 宿主机目录:数据卷    #将宿主机目录挂载到容器中
#注意:宿主机本地目录的路径必须是使用绝对路径。如果路径不存在,Docker会自动创建相应的路径。
#挂载后的目录默认可读可写

[root@docker1 ~]# docker run -itd --name test1 -v /opt/test1:/opt/test1 centos:7 /bin/bash

创建一个容器卷,和宿主机的的目录挂载,目录自带读写权限。

docker网络_第5张图片

 #如果希望挂载后的目录为只读目录,可以在挂载时加:ro参数
 docker run -v 宿主机目录:数据卷:ro    #将宿主机目录挂载到容器中,只可读
 
[root@docker1 ~]# docker run -itd --name test2 -v /opt/test1:/opt/test:ro centos:7 /bin/bash
[root@docker1 test1]# docker exec -it test2 bash
[root@99ad964433e5 /]# cd /opt/
[root@99ad964433e5 opt]# ls
test
[root@99ad964433e5 opt]# cd test/
[root@99ad964433e5 test]# echo 123 > 123
bash: 123: Read-only file system

#进入容器之后发现是只读模式

数据卷容器(容器与容器之间数据共享)
有时时候,容器之间共享一些数据,最简单的方法就是使用数据卷容器。
数据卷容器是一个普通的容器,专门提供数据卷给其他容器挂载使用。 

[root@docker1 test1]# docker run -itd --name co1 -v /opt/data1 -v /opt/data2 centos:7 /bin/bash
#创建挂载卷容器

[root@docker1 opt]#  docker run -itd --volumes-from co1 --name co2 centos:7 /bin/bash
#创建容器使用挂载卷

docker网络_第6张图片

容容器互联(使用centos镜像)
  容器互联是通过容器的名称在容器间建立一条专门的网络通信隧道。
  简单点说,就是会在源容器和接收容器之问建立一条隧道,接收容器可以看到源容器指定的信息。

#老版本:
[root@docker1 opt]# docker run -itd -P --name c1 centos:7 /bin/bash
-P:随机指定一个端口,和宿主机映射  

[root@docker1 opt]# docker run -itd -P --name c2 --link c1:c2 centos:7 /bin/bash

#进入容器:
yum install -y net-tools   #下载网络工具
ifconfig                   #查看IP和c2中显示的一致

#新版本:
docker network create --subnet=172.18.0.0/16 --opt "com.docker.network.bridge.name"="docker1"  mynetwork
#创建一个网段

[root@docker1 opt]# docker run -itd -P --name c11 --network=mynetwork centos:7 /bin/bash
9228697e81c5d43099485f7b151ae2838632c6e634f9688fd8f0c29bab8a0e6c

[root@docker1 opt]# docker run -itd -P --name c12 --network=mynetwork centos:7 /bin/bash
35d102685b3a1f8e6e0694b0f9f50b31bf42349ae6c0a2ee147186bb53078176
#创建两个容器,指定网段

#进入容器ping c11 c12

docker网络_第7张图片

你可能感兴趣的:(docker)