Docker数据卷与网络模式

数据卷

数据卷是一个可供一个或多个容器使用的特殊目录,它绕过UFS,可以提供很多有用的特定:

  • 数据卷可以在容器之间共享和重用
  • 对数据卷的修改会立马生效
  • 数据卷的更新,不会影响镜像
  • 数据卷默认会一直存在,即使容器被删除
  • 用容器操作数据卷,用数据卷操作容器,都是会产生相同的效果

注意

数据卷的使用,类似于Linux下对目录或文件进行mount镜像中的被指定为挂载点的目录中的文件会隐藏掉,能显示看到的挂载的数据卷。

数据卷操作

Docker volume(数据卷)是Docker中用于在容器和主机之间共享和持久化数据的机制。它使得容器之间的数据共享和容器的数据持久化成为可能。

Docker volume的主要特点包括:

  1. 数据持久性:即使容器被删除,Volume中的数据也不会丢失,因为它们存储在宿主机上。
  2. 数据共享:多个容器可以共享同一个Volume,使得数据共享变得简单方便。
  3. 类型多样:Docker支持多种类型的Volume,包括本地Volume、远程Volume以及插件支持的Volume等。

以下是一个Docker volume的示例,演示如何创建、使用和管理Volume:

示例

  1. 创建Docker Volume

使用docker volume create命令可以创建一个新的Volume:

docker volume create my-volume

这条命令会创建一个名为my-volume的新Volume。

  1. 查看Docker Volume

使用docker volume ls命令可以查看当前系统中存在的所有Docker Volume:

docker volume ls

输出中会列出所有Volume的详细信息,包括它们的名称和驱动程序。

  1. 将Volume挂载到容器

当创建容器时,可以使用-v--volume参数将Volume挂载到容器中的指定路径。例如:

docker run -d -v my-volume:/data my-image

这条命令会启动一个容器,并将my-volume挂载到容器内的/data目录。容器内的/data目录现在将共享my-volume中的数据。

  1. 查看Volume的挂载位置

有时,你可能想要知道Volume在宿主机上的具体挂载位置。可以通过docker volume inspect命令获取:

docker volume inspect my-volume

输出中会包含Volume的详细信息,包括其挂载点(Mountpoint),这就是Volume在宿主机上的实际位置。

  1. 删除Docker Volume

当不再需要某个Volume时,可以使用docker volume rm命令删除它:

docker volume rm my-volume

这条命令会删除my-volume以及其中的所有数据。请注意,如果Volume正被容器使用,则无法直接删除,需要先停止并移除相关的容器。

[root@server ~]# docker volume create my-volume  #在Linux主机中创建一个名为my-volume的数据卷
my-volume
[root@server ~]# docker volume ls  #查看主机中的数据卷
DRIVER    VOLUME NAME
local     2656990227a34c0f5e8022aa8a05a7be0c91554a28b2d71e8f4a51d73a5e36f4
local     my-volume
[root@server ~]# docker volume inspect my-volume  #查看my-volume数据卷的信息
[
    {
        "CreatedAt": "2024-03-25T11:32:05+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/my-volume/_data",
        "Name": "my-volume",
        "Options": null,
        "Scope": "local"
    }
]
[root@server _data]# docker run -d -P --name web1 -v my-volume:/data nginx:latest
34ceb2d4ea950e140ef7786863ac9fe0a79c295d4a183cb4628db4c62ff699b5
[root@server _data]# docker ps
CONTAINER ID   IMAGE          COMMAND                   CREATED          STATUS          PORTS                                     NAMES
34ceb2d4ea95   nginx:latest   "/docker-entrypoint.…"   21 seconds ago   Up 20 seconds   0.0.0.0:32769->80/tcp, :::32769->80/tcp   web1


[root@server _data]# docker exec -it web1 bash  #进入容器中
root@34ceb2d4ea95:/# ls /   #发现出现了/data目录
bin   dev                   etc   lib64  opt   run   sys  var
boot  docker-entrypoint.d   home  media  proc  sbin  tmp
data  docker-entrypoint.sh  lib   mnt    root  srv   usr
root@34ceb2d4ea95:/# cd /data
root@34ceb2d4ea95:/data# ls
root@34ceb2d4ea95:/data# touch file.txt  #创建一个file.txt文件
root@34ceb2d4ea95:/data# ls
file.txt
root@34ceb2d4ea95:/data# cd
root@34ceb2d4ea95:~# exit  #退出容器
exit
[root@server _data]# cd /var/lib/docker/volumes/my-volume/_data/  #切换到数据卷中
[root@server _data]# ls   #发现了我们在容器中创建的file.txt
file.txt
[root@server _data]#
[root@server _data]# docker inspect web1  #显示结果如下图

在这里插入图片描述

[root@server _data]# docker volume --help

Usage:  docker volume COMMAND

Manage volumes

Commands:
  create      Create a volume
  inspect     Display detailed information on one or more volumes
  ls          List volumes
  prune       Remove unused local volumes
  rm          Remove one or more volumes


[root@server _data]# docker volume rm my-volume   #数据卷正在使用,所以不能删除数据卷,需要关闭或删除容器后,再删除数据卷
Error response from daemon: remove my-volume: volume is in use - [34ceb2d4ea950e140ef7786863ac9fe0a79c295d4a183cb4628db4c62ff699b5]
  • 数据卷是被设计用来持久化数据的,它的生命周期独立于容器, Docker不会在容器被删除后自动删除数据卷, 并且也不存在垃圾回收这样的机制来处理没有任何容器引用的数据卷。如果需要在删除容器的同时移除数据卷。可以在删除容器的时候使用 docker rm -v 这个命令。
  • 无主的数据卷可能会占据很多空间,要清理请使用以下命令:
[root@server _data]# docker volume prune

查看镜像,容器,数据卷所占空间

[root@server _data]# docker system df
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          3         1         891.8MB   705.1MB (79%)
Containers      1         1         1.095kB   0B (0%)
Local Volumes   2         1         0B        0B
Build Cache     0         0         0B        0B

Docker的网络模式

当你安装docker时,它会自动创建三个网络

[root@server ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
69cf9fe45652   bridge    bridge    local
211a8fdf9c39   host      host      local
fa566b41018a   none      null      local
  • bridge此模式会为每一个容器分配,设置IP地址等,使用--net或--network=bridge指定,默认网络模式
  • host:使用宿主机的IP和端口,使用--net或--network=host指定
  • none:该模式关闭了容器的网络功能,使用--net或--network=none指定,使容器不能通信只能和自己玩
  • container:和一个指定的容器共享IP,端口,使用--net或--network=container:指定容器名指定

查看指定容器的网络模式

[root@server ~]# docker inspect linux-ubuntu | grep -i network
            "NetworkMode": "bridge",
        "NetworkSettings": {
            "Networks": {
                    "NetworkID": "69cf9fe45652f27db873a0f1dbcc7f36b7357af33884f51356c4c38f41ca5181",

bridge模式

  • DockerBridge网络模式是Docker默认网络模式。当不指定网络类型时,所创建的容器默认采用这种网络模式Bridge网络模式为每一个容器分配一个Network Namespace、IP等,并将容器的网络连接到一个网桥(默认为docker0)上。

  • Bridge网络模式下,同一个宿主机上所有容器默认会在同一个网段(默认网段为172.17.0.0/16)下,并且相互之间可以通信以及访问外部网络(前提是宿主机可以访问外部网络)。这种网络模式提供了容器之间的自动DNS解析,使得容器化应用程序可以轻松地相互通信,同时提高了安全性。

  • Bridge网络模式是基于Linux bridge虚拟网络实现Docker引擎在创建一个Bridge网络时,会创建一个新的虚拟网桥(命名为docker0),然后将主机上的所有Docker容器虚拟网卡接口连接到这个虚拟网桥上。每个容器虚拟网卡接口都包含一个MAC地址和一个唯一的IP地址,这些信息用于标识和路由容器之间的数据包。

  • 此外,DockerBridge网络驱动会自动在宿主机上安装好防火墙规则隔离不同网桥之间的直接通信,以确保安全性。Bridge网络适用于同一个Docker daemon宿主机下的容器。对于不同主机之间的通信,可以在操作系统层面设置路由规则,或者使用overlay网络等其他网络模式。

  • 主机可以和容器通信,容器之间也可以相互通信

  • 安装docker时会自动创建一个docker0网桥,运行容器时,你可以使用选项指定容器应连接到哪个
    网络,否则Docker守护程序默认将容器连接到docker0虚拟网桥,通过docker0网桥以及Iptables nat表配置与宿主机通信。

  • Docker 随机分配一个本地未占用的私有网段(在 RFC1918 中定义)中的一个地址给docker0 接口此后启动的容器内的网口也会自动分配一个同一网段的地址docker0的IP地址则为容器的默认网关在主机上创建一对虚拟网卡vethpair设备Docker将veth pair设备的端放在新创建的容器中并命名为eth0(容器的网卡)另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网桥中(bridge模式示意图如下图所示)

  • 在这里插入图片描述

[root@docker-node1 ~]# nmcli connection
NAME     UUID                                  TYPE      DEVICE
eth0     3fe4f788-e5f3-4046-8a3e-6cdfb8098aab  ethernet  eth0
docker0  80889309-7f07-45a6-9f59-cd49caba864d  bridge    docker0
  • 我们可以发现docker0网卡ip地址172.17.0.1/16
[root@docker-node1 ~]# ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:3eff:fe09:bb64  prefixlen 64  scopeid 0x20<link>
        ether 02:42:3e:09:bb:64  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 15  bytes 1866 (1.8 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.25.254.100  netmask 255.255.255.0  broadcast 172.25.254.255
        inet6 fe80::4e21:e4b4:36e:6d14  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:cf:80:f2  txqueuelen 1000  (Ethernet)
        RX packets 5180  bytes 2131050 (2.0 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 3072  bytes 296398 (289.4 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
  • 当我们启动一个容器后,我们可以发现它的ip地址为172.17.0.2/16,和docker0网卡IP同一个网段
[root@docker-node1 ~]# docker run -it --name test1 --network bridge busybox
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02
          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:15 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:2042 (1.9 KiB)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
  • 我们可以发现,容器可以访问宿主机
/ # ping 172.25.254.100
PING 172.25.254.100 (172.25.254.100): 56 data bytes
64 bytes from 172.25.254.100: seq=0 ttl=64 time=0.244 ms
64 bytes from 172.25.254.100: seq=1 ttl=64 time=0.088 ms
64 bytes from 172.25.254.100: seq=2 ttl=64 time=0.105 ms
  • 我们也可以发现,容器可以访问外网
/ # ping www.baidu.com
PING www.baidu.com (183.2.172.42): 56 data bytes
64 bytes from 183.2.172.42: seq=0 ttl=127 time=37.890 ms
64 bytes from 183.2.172.42: seq=1 ttl=127 time=38.224 ms
64 bytes from 183.2.172.42: seq=2 ttl=127 time=39.000 ms
[root@server ~]# docker run -d -it --name linux-ubuntu --net=bridge ubuntu
[root@server ~]# docker inspect linux-ubuntu | grep -i network
            "NetworkMode": "bridge",
        "NetworkSettings": {
            "Networks": {
                    "NetworkID": "69cf9fe45652f27db873a0f1dbcc7f36b7357af33884f51356c4c38f41ca5181",

none模式

  • 使用none模式Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡ip路由等信息,只有lo网络接口
  • 不参与网络通信运行于此类容器中的进程仅能访问本地lo回环接口None模式示意图如下所示:

在这里插入图片描述

  • 我们可以发现,只有一个lo网卡
[root@docker-node1 ~]# docker run -it --name test1 --network none busybox
/ # ifconfig
lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

/ #
  • 不能通信
/ # ping www.baidu.com
ping: bad address 'www.baidu.com'
/ # ping 172.25.254.100
PING 172.25.254.100 (172.25.254.100): 56 data bytes
ping: sendto: Network is unreachable
[root@server ~]# docker run -d --name linux-ubuntu --network=none ubuntu
c2d71a8545314dbf2ef8d936e8c69dc34c02296ecf6c5585d40258ade4e47a80
[root@server ~]# docker inspect linux-ubuntu | grep -i network
            "NetworkMode": "none",
        "NetworkSettings": {
            "Networks": {
                    "NetworkID": "fa566b41018a2edff899c8bf0b3f275a6726582276241e912d96fc48b626693a",
[root@server ~]#

host模式

  • 如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个NetworkNamespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。Host模式示意图如下所示:
  • 在这里插入图片描述
[root@server ~]# docker run -it --name linux-ubuntu -d --net=host ubuntu
64bf40afc85615e1af24de8e5062a044e9dd8f4e9149d9b06e2015d6e2aab098
[root@server ~]# docker inspect linux-ubuntu | grep -i network
            "NetworkMode": "host",
        "NetworkSettings": {
            "Networks": {
                    "NetworkID": "211a8fdf9c39a6ebbbd74c3b88e3e682a645f2d553bb21f8d2f6005fd84582a1",
[root@server ~]#

container模式

Container模式的示例可以如下进行:

首先,我们创建一个新的容器,并默认使用Bridge模式(这也是Docker的默认网络模式)。我们将使用busybox镜像来创建一个名为bb的容器:

docker run -itd --name bb busybox

接下来,我们要创建另一个容器,这次我们将使用Nginx镜像,并通过--net container:bb参数指定它的网络模式为Container模式,让它和之前创建的bb容器共享相同的网络命名空间:

docker run -d --name nginx-container --net=container:bb nginx

这条命令会启动一个新的Nginx容器,并将其网络配置设置为与bb容器相同。现在,nginx-container和bb容器将共享相同的IP地址和端口范围,它们之间的进程可以通过lo网卡设备进行通信。
在这里插入图片描述

[root@server ~]# docker ps
CONTAINER ID   IMAGE          COMMAND                   CREATED          STATUS          PORTS                                     NAMES
630a7fa66f4c   nginx:latest   "/docker-entrypoint.…"   53 minutes ago   Up 53 minutes   0.0.0.0:32770->80/tcp, :::32770->80/tcp   web1
[root@server ~]# docker run -d --name linux-ubuntu --network=container:web1 ubu
ntu
2738e0fec3c329d77b53d08ef04b79650d08dc09cd58db735ccceb9bc2b47379
[root@server ~]# docker inspect linux-ubuntu | grep -i network
            "NetworkMode": "container:630a7fa66f4cffb7c17887295af442d8c3fd45e3c5fe9b5497f127474d2cf594",
        "NetworkSettings": {
            "Networks": {}
[root@server ~]#
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

^~^前行者~~~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值