万字长文深入理解Docker镜像分层原理、容器数据卷、网络通信架构(Docker系列第2章,共3章)

镜像分层的简单直观体现

在执行docker pull时,会发现多个Pull complete 字样,就能体现分层,如果是一个文件,只会有一个Pull complete 。

docker pull redis
Using default tag: latest
latest: Pulling from library/redis
a2abf6c4d29d: Already exists 
c7a4e4382001: Pull complete 
4044b9ba67c9: Pull complete 
c8388a79482f: Pull complete 
413c8bb60be2: Pull complete 
1abfd3011519: Pull complete 
Digest: sha256:db485f2e245b5b3329fdc7eff4eb00f913e09d8feb9ca720788059fdc2ed8339
Status: Downloaded newer image for redis:latest
docker.io/library/redis:latest

文件系统

  • 概念:文件系统是计算机系统中用于组织和管理数据存储的一种方式。它定义了数据如何存储、命名、访问和修改的方式。
  • 举例:如Windows自带的NTFS、FAT32、EXFAT,和Linux中的EXT3、EXT4这种的。
  • FAT32:有着很好的兼容性,但是不支持单个大于4GB的文件,U盘空间充足却放不下大文件,就是这个原因。可以格式化后换一个文件系统解决。
  • NTFS:NTFS是Windows操作系统中最常用的文件系统之一,它支持大容量硬盘和大文件,提供了较好的安全性、稳定性和恢复能力。
  • EXFAT:为了解决FAT32不支持单个大于4GB的文件而诞生。

操作系统的引导

  • 概括:操作系统的引导(Bootstrapping)是指在计算机启动时,通过加载操作系统的核心组件和必要的驱动程序,使得计算机能够进入操作系统的运行状态。引导过程通常包括以下几个步骤:
  1. 加电自检(Power-On Self-Test,POST):计算机启动时,会执行自检程序,检查硬件是否正常。如果自检过程中发现硬件故障,计算机可能会发出警报或者停止启动。
  2. BIOS/UEFI初始化:计算机启动后,会加载基本输入/输出系统(Basic Input/Output System,BIOS)或统一可扩展固件接口(Unified Extensible Firmware Interface,UEFI),进行硬件初始化和系统设置。
  3. 引导加载程序(Bootloader)启动:BIOS/UEFI会寻找引导加载程序,一般位于硬盘的引导扇区(Boot Sector)或其他可引导的介质(如USB闪存驱动器)。引导加载程序的主要任务是加载操作系统的内核镜像到内存中,并执行操作系统的初始化。
  4. 内核初始化:一旦操作系统的内核镜像被加载到内存中,引导加载程序将控制权转交给操作系统内核。内核开始初始化系统的各个部分,包括设备驱动程序、文件系统等。
  5. 用户空间初始化:内核完成初始化后,操作系统开始启动用户空间的进程,包括系统服务和用户登录界面。

联合文件系统UnionFileSystem

联合文件系统(UFS),是一种分层的高性能文件系统,支持对文件系统的修改作为一次提交来层层叠加。
docker用它作为镜像的存储方式,使得容器在运行时只需存储修改过的部分,而不是整个文件系统,从而节省存储空间并提高效率。

为什么docker用UFS

  • 共享和复用:UFS 允许多个容器共享相同的基础镜像层,这样可以节省存储空间,并减少容器的创建和启动时间。当多个容器共享相同的文件系统层时,这些层中的文件和资源只需存储一次,而不是每个容器都存储一份。这和代码是一样的,封装的方法拆分的越小,可复用性就会更好。
  • 写时复制(Copy-on-Write):UFS 允许容器在运行时进行读写操作,同时保留了镜像的不可变性。当容器对文件系统进行修改时,UFS 会将修改的内容写入新的层中,而不会直接修改原始镜像层,这样可以确保容器之间的隔离性,并且不会影响其他容器或原始镜像。
  • 快速启动和部署:由于 UFS 允许容器共享文件系统层并利用写时复制机制,因此容器的创建和启动速度非常快。Docker 可以快速地在现有镜像的基础上创建新的容器实例,并立即启动运行,这对于实现快速部署和横向扩展至关重要。
  • 轻量级:UFS 提供了一种轻量级的文件系统封装方式,它不需要完整地复制整个文件系统,而是在需要修改文件时才进行复制和修改,这样可以节省存储空间并减少资源消耗,下文会讲。

深入理解Docker镜像分层加载原理

  • 简易概括:在BootFS(宿主机提供)的基础上,利用UFS封装RootFS,使用镜像层的数据,叠加出一个可写的容器层。
    所以说,docker pull下来的CentOS、Ubuntu发行版,才很小,一个原因是省掉了BootFS,另一个原因是抛弃了很多非核心的组件,如vim等。


  • BootFS:引导文件系统(boot filesystem)是指用于引导操作系统的文件系统。这个文件系统通常包含了引导加载程序(boot loader)所需的文件,例如引导配置文件、内核以及其他引导所需的文件,docker用宿主机的内核,出处就是这里。

  • RootFS:在 Linux 中,rootfs(root file system)是指操作系统启动后的根文件系统,它包含了整个文件系统的目录结构和文件,提供了用户空间程序运行所需的基本文件和资源,例如根目录下的几个目录。

  • 镜像层:只读的,包含了应用程序运行所需的所有文件和依赖项。

  • 容器层:可写的,当容器启动时,一个新的容器层被加载到容器的顶部,用来支撑数据变化的存储。

上下层级关系是这样的:
docker的UFS管理了最上面的3层,利用写时复制(Copy-on-Write)的机制,当容器需要修改文件时,UFS 会在容器层中进行写操作,而不会直接修改镜像层中的文件。这样可以保证镜像的不可变性,同时允许容器进行灵活的读写操作。
新的容器又可以commit成一个新的镜像,这个新的镜像基础上,又可以堆叠更多的容器,层层累加。

              --容器层-------镜像层----------------RootFS----------
----------------BootFS----------------

容器数据卷

  • 极简概括:容器数据卷,容器卷、数据卷、一个概念,将宿主机中的目录或文件挂载到容器中,从而让容器和宿主机共同读写这块的数据。并且在容器销毁时,容器卷的数据不会丢失。
  • 用法:docker run --name name1 [-it/-d] -v /宿主机绝对路径:/容器内绝对路径 --privileged=true 镜像id [/bin/bash]
  • 备注:-v是volume的首字母,挂载目录默认是读写权限,但是目录本身容器内部删不掉(极少需要删除),如果宿主机没有这个目录,只要权限充足,它会自动创建。
  • 适用场景:
    • 数据备份:当容器被误删,或者容器内的组件因故障无法运行时,容器卷的数据保留的好好的,这算是一种容灾。
    • 数据互通:容器内的组件,和容器外的系统,可以共享这块数据的读写,实时的,这对开发者、运维人员很友好。
    • 同步日志和数据:很多组件,应用、日志、数据是可以分开的,所以就可以把日志,数据,放进多个数据卷。
  • 优点:
    • 上文的适用场景,就是两个优点。
    • 易于备份:通过使用容器卷,可以轻松地备份和恢复数据,而不需要备份整个容器。
  • 缺点:
    • 复杂化:对于新手,或者刚接触新服务器的运维人员,多容器下的容器卷管理,使得运维工作错综复杂。
    • 高可用问题:MySQL不推荐在docker中,其中一个就是数据的高可用问题,MySQL减少保障故障时数据丢失问题和维护高可用带来的性能问题,使用了3种不同的redo log刷盘机制作为保障,但是又加了一个容器卷环节,多了一个环节,就有可能在这上面出故障,尤其是MySQL这种需要环境极度稳定的组件。

使用容器卷记得添加–privileged=true

使容器具有完全可控的权限,防止出现Permission denied的错误。
注意是等号,不是空格,有个d。

容器数据卷实操

对数据同步的测试

docker run --name=zs_ubuntu --privileged=true -it -v /test:/test b3797fa08f5b /bin/bash
进入ubuntu容器后
cd /test
touch a
开启另一个宿主机终端
touch b
容器和宿主机互相ls,发现都有a、b两个文件

使用inspect命令查看挂载相关配置

docker inspect 容器id
找到Mounts段,
"Mounts": [{"Type": "bind","Source": "/test","Destination": "/test","Mode": "","RW": true,"Propagation": "rprivate"}
],Type: 指定了数据卷的类型,这里是bind,表示这是一个绑定挂载,即将宿主机上的一个目录挂载到容器内部。
Source: 指定了数据卷的来源,这里是/test,表示宿主机上的目录路径。
Destination: 指定了数据卷在容器内的挂载目标路径,这里也是/test,表示容器内部的路径。
Mode: 这个字段可以用来指定挂载的权限模式,但在这个配置中为空,表示使用默认权限。
RW: 表示是否以读写模式挂载,这里是true,表示挂载为读写模式。
Propagation: 指定了挂载点的传播属性,这里是rprivate,表示挂载点将会被私有化传播,即只会影响到当前容器的进程,不会传播到其他容器。

故障情况下,容器卷内容的情况

停止容器
docker stop ea03c5ef1025
在宿主机内,创建文件
touch /test/c
开启
docker start ea03c5ef1025
进入容器
docker exec -it ea03c5ef1025 /bin/bash
此时发现c依旧存在
ls /test宿主机误删容器(强制)
docker rm -f ea03c5ef1025
发现a、b、c3个文件都在。
ls /
重新创建新的容器
docker run --name=zs_ubuntu --privileged=true -it -v /test:/test b3797fa08f5b /bin/bash
进入容器后,发现a、b、c 3个文件都在。
ls /

容器数据卷的rw与ro两种读写权限

rw:默认值,双方各有读写权限。

执-v命令时,默认是读写权限,以下两个命令是相等的。
docker run --name=zs_ubuntu --privileged=true -it -v /test:/test b3797fa08f5b /bin/bash
docker run --name=zs_ubuntu --privileged=true -it -v /test:/test:rw b3797fa08f5b /bin/bash

ro:宿主机的文件可以同步给容器,但容器无法更改。

某些情况下,需要将宿主机映射的目录,让容器只有只读权限,read only,可以这样做:
docker run --name=zs_ubuntu --privileged=true -it -v /test:/test:ro b3797fa08f5b /bin/bash进入容器,测试容器内写入
touch /test/d
touch: cannot touch 'd': Read-only file system进入宿主机终端,测试文件写入:
touch /test/d
宿主机成功写入进入容器,查看容器是否同步,发现已经同步
ls /test/d
a  b  c  d

容器数据卷的继承

卷的继承需要“–volumes-from 父容器卷” 来声明,具有父子关系的容器卷还是互相共享关系,父子间并没有强关联,意味着父容器停了或被删除,不影响子容器。

请空容器,方便测试。
docker rm -f 4432fa5f2d07
并删除/test下所有文件
rm -f /test/*
启动一个父容器
docker run --name parent --privileged=true -it -v /test:/test b3797fa08f5b /bin/bash
启动一个子容器
docker run --name son --privileged=true -it --volumes-from parent b3797fa08f5b /bin/bash
宿主机查看正在运行的容器实例
docker ps -a
CONTAINER ID   IMAGE          COMMAND       CREATED         STATUS         PORTS     NAMES
5ff477d6b3ec   b3797fa08f5b   "/bin/bash"   5 minutes ago   Up 4 minutes             son
a4da63aca520   b3797fa08f5b   "/bin/bash"   6 minutes ago   Up 6 minutes             parent宿主机创建a文件
touch /test/a
两个容器上查看,发现a文件都存在。
touch /test

父级故障模拟,测试父子关联性,结果得出父子间没有强关联性。

在宿主机上停止父级容器
docker stop a4da63aca520
在宿主机上创建文件
touch /test/b
在son容器上执行ls,发现有a、b两个文件
ls /test
a b在宿主机上删除父级容器
docker rm a4da63aca520
在宿主机上创建文件
touch /test/c
在son容器上执行ls,发现有a、b、c两个文件
ls /test
a b c

容器卷的多样化共享

多容用一卷:

强制删除所有容器,能不用则不用。
docker rm -f $(docker ps -aq)
删除宿主机下,容器卷目录所有文件
rm -f /test/*开3个终端,创建3个容器
docker run --name one --privileged=true -it -v /test:/test b3797fa08f5b /bin/bash
docker run --name two --privileged=true -it -v /test:/test b3797fa08f5b /bin/bash
docker run --name three --privileged=true -it -v /test:/test b3797fa08f5b /bin/bash查看是否开启成功
docker ps
CONTAINER ID   IMAGE          COMMAND       CREATED          STATUS          PORTS     NAMES
8ed7a2356d5c   b3797fa08f5b   "/bin/bash"   17 seconds ago   Up 10 seconds             three
ff2b2a92d984   b3797fa08f5b   "/bin/bash"   26 seconds ago   Up 25 seconds             two
220539fdf650   b3797fa08f5b   "/bin/bash"   54 seconds ago   Up 53 seconds             one宿主机创建a文件
touch /test/a三个容器分别执行ls /test,发现都有a
ls /teset
a

一容用多卷:

强制删除所有容器,能不用则不用。
docker rm -f $(docker ps -aq)
删除宿主机下,容器卷目录所有文件
rm -f /test/*
并额外创建2个目录
touch /test2 /test3
如下
ll / | grep test
drwxr-xr-x.   2 root root    6 412 03:07 test
drwxr-xr-x    2 root root    6 412 03:07 test2
drwxr-xr-x    2 root root    6 412 03:07 test3创建一个容器,并映射3个目录
docker run --name test --privileged=true -it -v /test:/test -v /test2:/test2 -v /test3:/test3 b3797fa08f5b /bin/bash
发现容器内也有3个目录
ll / | grep test
drwxr-xr-x.   2 root root    6 Apr 11 19:07 test/
drwxr-xr-x    2 root root    6 Apr 11 19:07 test2/
drwxr-xr-x    2 root root    6 Apr 11 19:07 test3/容器内执行
touch /test/a /test2/a /test3/a
宿主机查看,发现文件依然共享
ls /test /test2 /test3
/test:
a/test2:
a/test3:
a

网卡相关

安装docker后,执行ifconfig,会看到以下内容:

  • ens33(老版本的叫eth0)是配置宿主机网络用的。
  • lo是本地回环地址,用于本地主机内部通信的虚拟网络接口。
  • docker就是安装docker时虚拟出来的网卡,用于docker容器间和宿主机的通信:
    • flags=4099<UP,BROADCAST,MULTICAST> mtu 1500: 这部分显示了网络接口的名称(docker0)、标志和 MTU(最大传输单元)值(1500)。
    • inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255: 这部分显示了网络接口的 IPv4 地址(172.17.0.1)、子网掩码(255.255.0.0)和广播地址(172.17.255.255)。这个地址范围是 Docker 桥接网络的默认范围。
    • inet6 fe80::42:37ff:fef9:25d7 prefixlen 64 scopeid 0x20: 这部分显示了网络接口的 IPv6 地址。
    • ether 02:42:37:f9:25:d7 txqueuelen 0 (Ethernet): 这部分显示了网络接口的 MAC 地址和一些其他信息。
    • RX packets 4197 bytes 250537 (244.6 KiB): 这部分显示了接收到的数据包和字节数。
    • TX packets 4317 bytes 14144344 (13.4 MiB): 这部分显示了发送的数据包和字节数。。
ifconfigdocker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255inet6 fe80::42:37ff:fef9:25d7  prefixlen 64  scopeid 0x20<link>ether 02:42:37:f9:25:d7  txqueuelen 0  (Ethernet)RX packets 4197  bytes 250537 (244.6 KiB)RX errors 0  dropped 0  overruns 0  frame 0TX packets 4317  bytes 14144344 (13.4 MiB)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500inet 192.168.0.180  netmask 255.255.255.0  broadcast 192.168.0.255inet6 fe80::2545:6607:f0f7:64cb  prefixlen 64  scopeid 0x20<link>ether 00:0c:29:39:be:95  txqueuelen 1000  (Ethernet)RX packets 20615  bytes 15431772 (14.7 MiB)RX errors 0  dropped 0  overruns 0  frame 0TX packets 10726  bytes 954390 (932.0 KiB)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536inet 127.0.0.1  netmask 255.0.0.0inet6 ::1  prefixlen 128  scopeid 0x10<host>loop  txqueuelen 1000  (Local Loopback)RX packets 32  bytes 2592 (2.5 KiB)RX errors 0  dropped 0  overruns 0  frame 0TX packets 32  bytes 2592 (2.5 KiB)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

执行ip a,也会看到类似的内容:

  • <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default: 这部分显示了网络接口的名称(docker0)、状态(DOWN)、标志(NO-CARRIER、BROADCAST、MULTICAST、UP)、MTU(最大传输单元)值(1500)以及队列规则(qdisc)等信息。
  • link/ether 02:42:37:f9:25:d7 brd ff:ff:ff:ff:ff:ff: 这部分显示了网络接口的 MAC 地址和广播地址。
  • inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 valid_lft forever preferred_lft forever: 这部分显示了网络接口的 IPv4 地址(172.17.0.1)、子网掩码(/16),以及广播地址。valid_lft和 `preferred_lft 分别表示地址的有效生存时间和首选生存时间,设置为 forever 表示永久有效。
  • inet6 fe80::42:37ff:fef9:25d7/64 scope link valid_lft forever preferred_lft forever: 这部分显示了网络接口的 IPv6 地址和范围。
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000link/ether 00:0c:29:39:be:95 brd ff:ff:ff:ff:ff:ffinet 192.168.0.180/24 brd 192.168.0.255 scope global noprefixroute ens33valid_lft forever preferred_lft foreverinet6 fe80::2545:6607:f0f7:64cb/64 scope link noprefixroute valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:37:f9:25:d7 brd ff:ff:ff:ff:ff:ffinet 172.17.0.1/16 brd 172.17.255.255 scope global docker0valid_lft forever preferred_lft foreverinet6 fe80::42:37ff:fef9:25d7/64 scope link valid_lft forever preferred_lft forever

Docker网络

docker网络顾名思义,为什么要去研究它?

  • 控制容器间通信:只有容器不通信,好比买了个手机不联网,技能无法充分发挥。
  • 降低对网络的运维成本:容器IP变动时(增加、减少容器数量等因素),可以通过服务名进行通信,保证通信不受影响。

Docker网络相关命令

在docker run时,可以使用docker run --network bridge …去指定驱动程序。

docker network lsNETWORK ID     NAME      DRIVER    SCOPE
f4481eb7078e   bridge    bridge    local
c10b6f388063   host      host      local
21c306a93cbb   none      null      local
  • NETWORK ID:网络唯一标识。
  • NAME:起个名。
  • DRIVER:Docker 网络所使用的驱动程序,一些常见的网络驱动程序包括:
    • bridge(桥接 默认值): 默认的 Docker 网络驱动程序,使用docker0网卡连接容器到宿主机的网络。
    • host(主机): 让容器直接使用宿主机的网络命名空间,与宿主机共享网络栈,使用这个,docker run -p就没有意义了。
    • overlay(覆盖): 允许在多个 Docker 宿主机上创建连接的容器网络,用于容器在不同宿主机间通信。
    • macvlan(MACVLAN): 允许容器拥有自己的 MAC 地址,并直接与物理网络相连。
    • none(无): 禁用容器的网络,使容器无法进行网络通信,很少用。
    • container(容器):新创建的容器不会创建自己的网卡,而是和一个指定容器共享IP和端口,很少用,容易端口冲突,且对容器有依赖性。
  • SCOPE:定义网络范围的作用域
    • local(本地 默认值): 这表示网络只在当前 Docker 宿主机上可见和可用,不会跨越宿主机边界。
    • global(全局): 这表示网络在所有 Docker 宿主机上都可见和可用,可以跨越宿主机边界。
    • swarm(集群): 这表示网络是 Docker Swarm 集群中的一部分,可以在整个 Swarm 集群中使用。

Docker对网络配置的增删改查操作:

执行网络联机的命令行帮助,会得到以下内容,无外乎就是增删改查
docker network --help
Usage:  docker network COMMANDManage networksCommands:connect     Connect a container to a networkcreate      Create a networkdisconnect  Disconnect a container from a networkinspect     Display detailed information on one or more networksls          List networksprune       Remove all unused networksrm          Remove one or more networksRun 'docker network COMMAND --help' for more information on a command.增:
docker network create test_net
7b7c0cbc15c65a5ef4a0e1ad5e7d997ec04afb322afc9e67845c8735ccf1fb06
docker network ls
NETWORK ID     NAME       DRIVER    SCOPE
f4481eb7078e   bridge     bridge    local
c10b6f388063   host       host      local
21c306a93cbb   none       null      local
7b7c0cbc15c6   test_net   bridge    local删:
docker network rm test_net
^[[Atest_net
docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
f4481eb7078e   bridge    bridge    local
c10b6f388063   host      host      local
21c306a93cbb   none      null      local改:极少操作。查:
docker inspect f4481eb7078e
返回一个json。

Docker网络通信架构

  • docker0:虚拟出来一块网卡,让容器之间、宿主机、进行通信。docker0是虚拟出来的硬件,bridge是通信的方式。
  • veth:veth(Virtual Ethernet)是Linux系统中一种虚拟网络设备,常用于 Docker 容器之间和容器与宿主机之间的通信,当创建一个Docker容器时,Docker会为容器分配一个唯一的网络命名空间,并为该容器创建一个veth pair设备。容器内的veth设备称为 eth0(或其他指定的网络接口名),而与之配对的宿主机端的veth设备可以在宿主机上看到,通常以 vethXXX 这样的形式命名。通过这种方式,容器可以通过自己的网络接口与宿主机上的其他容器或外部网络进行通信。Docker 使用 Linux 的网络命名空间和 veth 设备来隔离容器的网络栈,同时通过网络桥接(如 docker0)实现容器与宿主机网络的连接和通信。
  • eth0:这是每个容器实例或宿主机自身的内部网卡。
  • 注意:容器内的eth0和veth总是成双成对的出现。
  • 通信方式:无论是容器与容器之间,容器与宿主机之间,都需要通过docker0的bridge方式通信。

上一张经典的图:
在这里插入图片描述

开两个Nginx证明一下是否是多出来两个veth:

关闭宿主机nginx服务,nginx设置开启了服务
service nginx stop
起两个nginx容器
docker run -d -p 80:80 nginx
docker run -d -p 8080:80 nginx
确定容器是否真的跑起来
docker ps
CONTAINER ID   IMAGE     COMMAND                   CREATED         STATUS         PORTS                                   NAMES
bf6321d659c4   nginx     "/docker-entrypoint.…"   2 minutes ago   Up 2 minutes   0.0.0.0:8080->80/tcp, :::8080->80/tcp   funny_williams
859b85ccf760   nginx     "/docker-entrypoint.…"   2 minutes ago   Up 2 minutes   0.0.0.0:80->80/tcp, :::80->80/tcp       brave_vaughan确定配置是否成功,或用curl访问也行
netstat -nlp | grep 80
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      22982/docker-proxy  
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      22838/docker-proxy  
tcp6       0      0 :::8080                 :::*                    LISTEN      22988/docker-proxy  
tcp6       0      0 :::80                   :::*                    LISTEN      22844/docker-proxy  
unix  2      [ ACC ]     STREAM     LISTENING     50191    6480/abrtd           /var/run/abrt/abrt.socket重点来了,然后再执行ifconfig,会发现多出来两个veth开头的网卡:
ifconfigveth7c2861b: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500inet6 fe80::e881:5aff:fe82:55ca  prefixlen 64  scopeid 0x20<link>ether ea:81:5a:82:55:ca  txqueuelen 0  (Ethernet)RX packets 35  bytes 4797 (4.6 KiB)RX errors 0  dropped 0  overruns 0  frame 0TX packets 52  bytes 7096 (6.9 KiB)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0veth8ed54b8: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500inet6 fe80::1cb3:6eff:fe84:1563  prefixlen 64  scopeid 0x20<link>ether 1e:b3:6e:84:15:63  txqueuelen 0  (Ethernet)RX packets 31  bytes 4017 (3.9 KiB)RX errors 0  dropped 0  overruns 0  frame 0TX packets 37  bytes 4395 (4.2 KiB)TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0同理,可以使用ip a命令
ip addr14: veth7c2861b@if13: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default link/ether ea:81:5a:82:55:ca brd ff:ff:ff:ff:ff:ff link-netnsid 0inet6 fe80::e881:5aff:fe82:55ca/64 scope link valid_lft forever preferred_lft forever
18: veth8ed54b8@if17: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default link/ether 1e:b3:6e:84:15:63 brd ff:ff:ff:ff:ff:ff link-netnsid 1inet6 fe80::1cb3:6eff:fe84:1563/64 scope link valid_lft forever preferred_lft forever想要验证,与eth0是否是成对出现的,但是nginx镜像缺少ip 或者ifconfig命令,apt-get update命令报错,导致无法验证。
实际上宿主机上看的veth7c2861b@if13和veth8ed54b8@if17中的if13与if17,都是与容器当中的网卡编号对应的。

当使用docker inspect 容器id时,就能看到该容器网络相关的信息。

docker inspect 6dc7f1d29a17 | tail -n 21"Networks": {"bridge": {"IPAMConfig": null,"Links": null,"Aliases": null,"MacAddress": "","NetworkID": "f4481eb7078ebf9be90119f8a99f5869354ed14d9b093924da43bf1ba19b36a0","EndpointID": "","Gateway": "","IPAddress": "","IPPrefixLen": 0,"IPv6Gateway": "","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"DriverOpts": null,"DNSNames": null}}

对于这个json,做个介绍:

  • “IPAMConfig”: 这是用于管理IP地址的配置,通常在Docker网络模式为bridge时使用。
  • “Links”: 这里是容器与其他容器之间链接的信息,但在这个例子中为null,表示没有其他容器链接到这个容器。
  • “Aliases”: 这是容器的网络别名,也是null,表示没有设置别名。
  • “MacAddress”: 这是容器的MAC地址,通常由Docker自动生成。
  • “NetworkID”: 这是网络的唯一标识符,用于区分不同的Docker网络。
  • “EndpointID”: 这是容器端点的唯一标识符,用于标识容器在网络中的位置。
  • “Gateway”: 这是网络的网关地址,通常由Docker提供。
  • “IPAddress”: 这是容器分配的IP地址。
  • “IPPrefixLen”: 这是容器IP地址的前缀长度,通常是一个整数。
  • “IPv6Gateway”: 这是IPv6网络的网关地址。
  • “GlobalIPv6Address”: 这是容器的全局IPv6地址。
  • “GlobalIPv6PrefixLen”: 这是容器的全局IPv6地址的前缀长度。
  • “DriverOpts”: 这是网络驱动的选项配置,通常在特定网络驱动中使用。
  • “DNSNames”: 这是容器的DNS名称列表,用于解析容器内部的 DNS 查询。

不同容器配置不同的Docker网络

  • 为了分门别类,方便管理。
  • 有了它,可以避免IP变动引起的故障,为docker容器编排做准备。
创建网络
docker network create zs_test
ee465a9eccd7d758e3b4a4281539352d8169364f860091928f3296129c6ac384并查看
docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
f4481eb7078e   bridge    bridge    local
c10b6f388063   host      host      local
21c306a93cbb   none      null      local
ee465a9eccd7   zs_test   bridge    local开两个终端分别执行
docker run --name centos01 --network zs_test -it 5d0da3dc9764 /bin/bash
docker run --name centos02 --network zs_test -it 5d0da3dc9764 /bin/bash然后再任意终端上ping另一个容器的name参数
ping centos02
PING centos02 (172.23.0.3) 56(84) bytes of data.
64 bytes from centos02.zs_test (172.23.0.3): icmp_seq=1 ttl=64 time=0.082 ms
64 bytes from centos02.zs_test (172.23.0.3): icmp_seq=2 ttl=64 time=0.095 ms
64 bytes from centos02.zs_test (172.23.0.3): icmp_seq=3 ttl=64 time=0.090 ms使用name参数,可以避免IP变动情况的发生。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/816397.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法中的复杂度(先做个铺垫)

文章目录 定义与分类时间复杂度概念大O的渐进表示法举例情况注意内涵 空间复杂度最优解 定义与分类 复杂度&#xff1a;衡量算法效率的标准时间效率&#xff1a;衡量这个算法的运行速度&#xff0c;也就是我们常说的时间复杂度空间效率&#xff1a;衡量这个算法所需要的额外空…

分布式结构化数据表Bigtable

文章目录 设计动机与目标数据模型行列时间戳 系统架构主服务器Chubby作用子表服务器SSTable结构子表实际组成子表地址组成子表数据存储及读/写操作数据压缩 性能优化局部性群组&#xff08;Locality groups&#xff09;压缩布隆过滤器 Bigtable是Google开发的基于GFS和Chubby的…

云计算:Linux 部署 OVN 集群

目录 一、实验 1.环境 2.Linux 部署 OVN 集群&#xff08;中心端&#xff09; 3.Linux 部署 OVN 集群&#xff08;业务端1&#xff09; 4.Linux 部署 OVN 集群&#xff08;业务端2&#xff09; 4.OVN 中心端 连接数据库 5.OVN 业务端1 加⼊控制器 6.OVN 业务端2 加⼊控…

强大的压缩和解压缩工具 Keka for Mac

Keka for Mac是一款功能强大的压缩和解压缩工具&#xff0c;专为Mac用户设计。它支持多种压缩格式&#xff0c;包括7z、Zip、Tar、Gzip和Bzip2等&#xff0c;无论是发送电子邮件、备份文件还是节省磁盘空间&#xff0c;Keka都能轻松满足用户需求。 这款软件的操作简单直观&…

Tesserocr 的安装步骤

Tesserocr 的安装 OCR&#xff0c;即 Optical Character Recognition&#xff0c;光学字符识别。是指通过扫描字符&#xff0c;然后通过其形状将其翻译成电子文本的过程。那么对于图形验证码来说&#xff0c;它都是一些不规则的字符&#xff0c;但是这些字符确实是由字符稍加扭…

数据结构与算法——20.B-树

这篇文章我们来讲解一下数据结构中非常重要的B-树。 目录 1.B树的相关介绍 1.1、B树的介绍 1.2、B树的特点 2.B树的节点类 3.小结 1.B树的相关介绍 1.1、B树的介绍 在介绍B树之前&#xff0c;我们回顾一下我们学的树。 首先是二叉树&#xff0c;这个不用多说&#xff…

Linux的文件操作中的静态库的制作

Linux操作系统支持的函数库分为&#xff1a; 静态库&#xff0c;libxxx.a&#xff0c;在编译时就将库编译进可执行程序中。 优点&#xff1a;程序的运行环境中不需要外部的函数库。 缺点&#xff1a;可执行程序大 &#xff08;因为需要 编译&#xff09; 动态库&#xff0c…

Spring Cloud学习笔记:Eureka集群搭建样例

这是本人学习的总结&#xff0c;主要学习资料如下 - 马士兵教育 1、项目架构2、Dependency3、项目启动类4、application.yml5、启动项目 1、项目架构 因为这是单机模拟集群搭建&#xff0c;为了方便管理就都放在了一个项目中。这次准备搭建三个项目server1, server2, server3 …

常见的垃圾回收算法

文章目录 1. 标记清除算法2. 复制算法3. 标记整理算法4. 分代垃圾回收算法 1. 标记清除算法 核心思想&#xff1a; 标记阶段&#xff0c;将所有存活的对象进行标记。Java中使用可达性分析算法&#xff0c;从GC Root开始通过引用链遍历出所有存活对象。清除阶段&#xff0c;从…

webrtc中的Track,MediaChannel,MediaStream

文章目录 Track,MediaChannel,MediaStream的关系MediaStream的创建流程创建VideoChannel的堆栈创建VideoStream的堆栈 sdp中媒体参数信息的映射sdp中媒体信息参数设置体系参数设置流程参数映射体系 Track,MediaChannel,MediaStream的关系 Audio/Video track&#xff0c;MediaC…

[每周一更]-第93期:探索大型生成式聊天工具:从ChatGPT到未来

随着人工智能技术的不断进步&#xff0c;生成式聊天工具正逐渐成为人们日常生活中的一部分。这些工具利用深度学习技术和大规模语言模型的强大能力&#xff0c;能够与用户进行自然、流畅的对话&#xff0c;为我们提供了更加智能和个性化的交流体验。 ChatGPT&#xff1a;开启生…

基于RT-Thread(RTT)的BMP280气压计驱动(I2C通信)

前言 本文基于RTT操作系统使用STM32F401RET6驱动BMP280气压计模块&#xff0c;使用I2C协议通信 一、新建工程 二、添加软件包 三、添加这个包 四、打开CubeMX 五、配置时钟源&#xff0c;使用外部晶振 六、配置串行下载口 七、打开I2C&#xff0c;我这里使用的是I2C2&#x…

LabVIEW直流稳定电源自动化校准系统

LabVIEW直流稳定电源自动化校准系统 直流稳定电源正向着智能化、高精度、多通道、宽量程的方向发展。基于LabVIEW开发环境&#xff0c;设计并实现了一种直流稳定电源自动化校准系统&#xff0c;以提升校准过程的整体效能&#xff0c;实现自动化设备替代人工进行电源校准工作。…

【opencv】示例-stiching.cpp 图像拼接

#include "opencv2/imgcodecs.hpp" // 导入opencv图像编码功能库 #include "opencv2/highgui.hpp" // 导入opencv高层用户界面功能库 #include "opencv2/stitching.hpp" // 导入opencv图像拼接功能库#include <iostream> // 导入输入输出…

PyQt5

Qt是基于C实现的GUI,而PyQt就是用python调用Qt. PyQt中有很多的功能模块,开发最常用的模块功能主要有3个 1) QtCore:包含核心的非GHI的功能,主要和时间,文件与文件夹,各种数据,流,URLs,进程与线程一起使用 2) QtGUi:包含窗口系统,事件处理,2D图像,基本绘画,字体和文字类 3)…

详解构造函数

前言 希望这篇文章是有意义的&#xff0c;能够帮助初学者理清构造函数的概念&#xff0c;关系及误区。首先定义一个日期类&#xff0c;借助日期类讲解构造函数。 class Date {public:void Init(int year, int month, int day) //初始化数据的方法{_year year;_month month…

Ubuntu快捷安装MySQL

更新包列表 sudo apt update 安装mysql sudo apt install mysql-server 启动mysql // 启动mysql sudo service mysql start// 关闭mysql sudo service mysql stop// 重启mysql sudo service mysql restart 连接mysql // 初始安装无密码&#xff0c;直接连接即可&#xf…

【opencv】示例-train_HOG.cpp 训练和测试基于支持向量机(SVM)的行人检测器

#include "opencv2/imgproc.hpp" // 包含OpenCV图像处理头文件 #include "opencv2/highgui.hpp" // 包含OpenCV高层GUI&#xff08;图形用户界面&#xff09;头文件 #include "opencv2/ml.hpp" // 包含OpenCV机器学习模块头文件 #includ…

数据结构初阶:二叉树(二)

二叉树链式结构的实现 前置说明 在学习二叉树的基本操作前&#xff0c;需先要创建一棵二叉树&#xff0c;然后才能学习其相关的基本操作。由于现在对二叉树结构掌握还不够深入&#xff0c;为了降低学习成本&#xff0c;此处手动快速创建一棵简单的二叉树&#xff0c;快速进入二…

二、Flask会话技术和模板语言

Cookie Session # views.py: 路由 视图函数 import datetimefrom flask import Blueprint, render_template, request, redirect, session from .models import *# 蓝图 blue Blueprint(user, __name__)# 首页 可以写两个路由&#xff0c;都是访问同一个函数 blue.route(/) b…