docker存储管理及实例

2023-11-03

一、Docker存储概念

1、容器本地存储与Docke存储驱动

容器本地存储:每个容器都被自动分配了内部存储,即容器本地存储。采用的是联合文件系统。通过存储驱动进行管理。

存储驱动:控制镜像和容器在 docker 主机上的存储和管理方式。

容器本地存储空间:分层结构构成,由一个可写容器层和若干只读的镜像层组成。

联合文件系统:Docker的一种底层技术,由存储驱动(Storage Driver)实现。相应的存储驱动有aufs、overlay、overlay2、devicemapper、btrfs、zfs、vfs等。

每个Docker主机只能选择一种存储驱动,不能为每个容器选择不同的存储驱动。

(1)查看主机支持的存储驱动

[root@docker ~]# docker info
# 找到如下信息
 Storage Driver: overlay2           # 存储驱动是overlay2
  Backing Filesystem: xfs           # 底层文件系统是xfs
  Supports d_type: true             # 支持d_type
  Native Overlay Diff: true
  userxattr: false

(2)更改现有的存储驱动

可以根据需要修改现有的存储驱动

注意:
1,一个主机只能选择一个存储驱动。
2,系统版本和存储驱动的兼容问题。
3,更改存储驱动会使得现有的容器和镜像不可访问(原因:每种存储驱动存储镜像层的位置是不同的)
4,但恢复存储驱动,可以再次访问之前的镜像和容器

# 修改daemon.json文件来更改存储引擎配置
[root@docker ~]# vi /etc/docker/daemon.json 
{
  "registry-mirror":["https://registry.docker-cn.com"],
  "storage-driver":"overlay"                           <—————添加这个信息
}
# 重启docker生效
[root@docker ~]# systemctl daemon-reload
[root@docker ~]# systemctl restart docker
[root@docker ~]# docker info
# 找到如下信息
 Storage Driver: overlay                 <——————修改生效
  Backing Filesystem: xfs
  Supports d_type: true
# 更改存储驱动会使得现有的容器和镜像不可访问
[root@docker ~]# docker images
REPOSITORY   TAG       IMAGE ID   CREATED   SIZE
# 恢复存储驱动,可以再次访问之前的镜像和容器
[root@docker ~]# vi /etc/docker/daemon.json  
{
  "registry-mirror":["https://registry.docker-cn.com"]
}
[root@docker ~]# systemctl daemon-reload
[root@docker ~]# systemctl restart docker
[root@docker ~]# docker images
REPOSITORY         TAG       IMAGE ID       CREATED        SIZE
ubuntu             latest    825d55fb6340   2 weeks ago    72.8MB
centos             latest    5d0da3dc9764   7 months ago   231MB

2、容器和非持久化数据

非持久化数据:不需要保存的数据。容器本地存储中的数据属于非持久化数据。

容器创建时会创建非持久化存储,非持久化存储自动创建,从属于容器,生命周期与容器相同。删除容器也会删除全部非持久化数据。

非持久化数据存在问题:

  • 这类数据从属于容器,生命周期与容器相同,会随着容器的删除而被删除。(易丢失)
  • 当该容器不再运行时,数据不会持久保存,如果另一个进程需要,则可能很难从该容器中获取数据。(难获取)
  • 容器的可写层与运行容器的Docker主机紧密耦合,无法轻松地将数据转移到其他位置。(难转移)
  • 写入容器的可写层需要Docker存储驱动管理文件系统。存储驱动使用Linux内核提供的联合文件系统,其性能不如直接写入主机文件系统的Docker卷。(读写性能差)

3、容器和持久化数据

持久化数据:需要保存的数据。例如:日志、业务数据、客户信息等有用的数据。

外部存储:Docker通过将主机中的文件系统挂载到容器中供容器存取,从而实现持久化数据存储。

容器持久化数据存储方式:Docker目前支持卷、绑定挂载,这两种挂载类型实现容器的持久化。

卷(数据卷):Docker中进行持久化数据存储的最佳方式。本质是Docker主机文件系统中的目录或文件直接挂载到容器的文件系统中。

  • 卷和容器是解耦的,可以独立地创建并管理卷
  • 卷不与容器的生命周期绑定(容器的停止删除和卷无关)
  • 可以将任意数量的卷装入容器,多个容器也可以共享一个或多个卷(多对多关系)

4、挂载类型

往容器中挂载的外部文件系统主要有:卷、绑定挂载、tmpfs挂载。无论哪种挂载,对容器内部来说是一样的,都会显示为文件或目录。

(1)卷

  • 卷存储在主机文件系统中由Docker管理的位置,在Linux主机上该位置默认就是/var/lib/docker/volumes目录。

  • 卷是Docker持久化存储数据的最佳方式。卷支持使用卷驱动,可以让用户将数据存储在远程主机或云提供商处等。

可以以命名方式或匿名方式挂载卷:

  • 匿名卷(Anonymous Volumes):首次挂载容器未指定名称,Docker为其随机指定一个唯一名称。
  • 命名卷(Named Volumes):指定明确名称,和匿名卷其他特性相同。

卷由Docker创建并管理,卷适合以下应用场景:

  • 1, 在多个正在运行的容器之间共享数据。(数据共享)
  • 2, 当Docker主机不能保证具有特定目录结构时,卷有助于将Docker主机的配置与容器运行时解耦。(构建新目录与主机不同)
  • 3, 当需要将容器的数据存储到远程主机或云提供商处,而不是本地时。(可以远程挂载卷,公有云、灾备等场景)
  • 4, 当需要在两个Docker主机之间备份、恢复或迁移数据时。(主机间备份迁移)

(2)绑定挂载

  • 绑定挂载可以存储到主机系统的任意位置,甚至会存储到一些重要的系统文件或目录中。

特点:

  • 主机上进程或容器可以随时修改。
  • 相比卷,功能更受限、性能更高。
  • 绑定挂载运行访问敏感文件。

绑定挂载适合以下应用场景:

  • 在主机和容器之间共享配置文件
  • 在Docker主机上的开发环境和容器之间共享源代码或构建工件。
  • 当Docker主机上的目录结构保证与容器要求的绑定挂载一致时。

(3)tmpfs挂载

tmpfs挂载仅限于运行Linux操作系统的Docker主机使用,它只存储在主机的内存中,不会被写到主机的文件系统中,因此不能持久保存容器的应用数据。

在不需要将数据持久保存到主机或容器中时,tmpfs挂载最合适。

如果容器产生了非持久化数据,那么可以考虑使用tmpfs挂载避免将数据永久存储到任何位置,并且通过避免写入容器的可写层来提高容器的性能。

Top

二、Docker卷管理

docker volume是Docker卷的管理命令。

创建卷的时候主机上的Docker根目录(linux默认是/var/lib/docker)下的volumes子目录内会生成一个以卷名命名的子目录,这个子目录里面再创建一个_data的子目录作为卷的数据存储路径。

卷名必须唯一,不同的卷驱动不能使用相同的卷名。

# 语法
[root@localhost volumes]# docker volume
Usage:  docker volume COMMAND
Manage volumes
Commands:
  create      Create a volume                                            # 创建卷
  inspect     Display detailed information on one or more volumes        # 查看卷的详细信息
  ls          List volumes                                               # 列出本地docker主机上的卷
  prune       Remove all unused local volumes                            # 删除未被使用的卷
  rm          Remove one or more volumes                                 # 删除指定卷

1、创建卷

# 参数所有示例

# 语法
[root@localhost volumes]# docker volume create --help
Usage:  docker volume create [OPTIONS] [VOLUME]
Create a volume
Options:
  -d, --driver string   Specify volume driver name (default "local")     # 说明卷驱动名称(默认是'local')
      --label list      Set metadata for a volume                        # 设置卷元数据
  -o, --opt map         Set driver specific options (default map[])      # 设置驱动特殊选项


# 案例1:创建普通卷
[root@localhost volumes]# docker volume create test-vol01
test-vol01
[root@localhost volumes]# docker volume inspect test-vol01
[
    {
        "CreatedAt": "2022-04-27T17:02:27+08:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/test-vol01/_data",
        "Name": "test-vol01",
        "Options": {},
        "Scope": "local"
    }
]

# 案例2:创建tmpfs卷,大小100m,uid为1000
[root@localhost volumes]# docker volume create --driver local \
> --opt type=tmpfs \
> --opt device=tmpfs \
> --opt o=size=100m,uid=1000 \
> test-vol02
test-vol02
[root@localhost volumes]# docker volume inspect test-vol02
[
    {
        "CreatedAt": "2022-04-27T17:10:21+08:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/test-vol02/_data",
        "Name": "test-vol02",
        "Options": {
            "device": "tmpfs",
            "o": "size=100m,uid=1000",
            "type": "tmpfs"
        },
        "Scope": "local"
    }
]


# 案例3:设置元数据
[root@localhost volumes]# docker volume create --label city=wuhan test-vol03
test-vol03
[root@localhost volumes]# docker volume inspect test-vol03
[
    {
        "CreatedAt": "2022-04-27T17:07:44+08:00",
        "Driver": "local",
        "Labels": {
            "city": "wuhan"
        },
        "Mountpoint": "/var/lib/docker/volumes/test-vol03/_data",
        "Name": "test-vol03",
        "Options": {},
        "Scope": "local"
    }
]

2、查看卷列表

使用 docker volume ls 命令列出当前的卷
format关键词:

Placeholder Description
.Name Volume name
.Driver Volume driver
.Scope Volume scope (local, global)
.Mountpoint The mount point of the volume on the host
.Labels All labels assigned to the volume
.Label Value of a specific label for this volume. For example {{.Label "project.version"}}
# 语法
[root@localhost volumes]# docker volume ls --help
Usage:  docker volume ls [OPTIONS]    <—————注意选项不能写在ls之前
List volumes
Aliases:
  ls, list
Options:
  -f, --filter filter   Provide filter values (e.g. 'dangling=true')      # 条件筛选
      --format string   Pretty-print volumes using a Go template          # 内容过滤输出
  -q, --quiet           Only display volume names                         # 只打印卷名

# 案例1:普通查看
[root@localhost volumes]# docker volume ls
卷驱动     卷名称
DRIVER    VOLUME NAME
local     test-vol01
local     test-vol02
local     test-vol03

# 案例2:条件筛选
# 没有被使用的卷
[root@localhost volumes]# docker volume ls -f dangling=true
DRIVER    VOLUME NAME
local     test-vol01
local     test-vol02
local     test-vol03
# 驱动为local的卷
[root@localhost volumes]# docker volume ls -f driver=local
DRIVER    VOLUME NAME
local     test-vol01
local     test-vol02
local     test-vol03
# 根据label元数据筛选
[root@localhost volumes]# docker volume ls --filter label=city
DRIVER    VOLUME NAME
local     test-vol03
# 根据名称筛选
[root@localhost volumes]# docker volume ls -f name=03
DRIVER    VOLUME NAME
local     test-vol03
[root@localhost volumes]# docker volume ls -f name=vol
DRIVER    VOLUME NAME
local     test-vol01
local     test-vol02
local     test-vol03

# 案例3:只打印卷名
[root@localhost volumes]# docker volume ls -q
test-vol01
test-vol02
test-vol03

# 案例4:内容过滤输出
[root@localhost volumes]# docker volume ls --format "{{.Name}}: {{.Driver}}"
test-vol01: local
test-vol02: local
test-vol03: local
[root@localhost volumes]# docker volume ls --format "{{.Name}}: {{.Mountpoint}}: {{.Labels}}"
test-vol01: /var/lib/docker/volumes/test-vol01/_data: 
test-vol02: /var/lib/docker/volumes/test-vol02/_data: 
test-vol03: /var/lib/docker/volumes/test-vol03/_data: city=hb

3、查看卷详细信息

# 语法
[root@localhost ~]# docker volume inspect --help
Usage:  docker volume inspect [OPTIONS] VOLUME [VOLUME...]
Display detailed information on one or more volumes
Options:
  -f, --format string   Format the output using the given Go template

# 案例
[root@localhost ~]# docker volume create --driver local \
> --opt type=tmpfs \
> --opt device=tmpfs \
> --opt o=size=100m,uid=1000 \
> --label city=wuhan \
> --label type=tmpfs \
> test-vol
70eefb6835df2daafcc3e678395af214dae4a98241fd6886e5822bbc9e7de920
[root@localhost ~]# docker volume inspect test-vol
[
    {
        "CreatedAt": "2022-04-28T00:36:35+08:00",
        "Driver": "local",                                           # 卷驱动
        "Labels": {
            "city": "wuhan",
            "type": "tmpfs"
        },
        "Mountpoint": "/var/lib/docker/volumes/test-vol/_data",      # 卷挂载点
        "Name": "test-vol",                                          # 卷名称
        "Options": {
            "device": "tmpfs",
            "o": "size=100m,uid=1000",
            "type": "tmpfs"
        },
        "Scope": "local"                                             # 卷作用域
    }
]
[root@localhost ~]# docker volume inspect --format '{{ .Mountpoint }}' test-vol
/var/lib/docker/volumes/test-vol/_data
[root@localhost ~]# docker volume inspect --format '{{ .Options }}' test-vol
map[device:tmpfs o:size=100m,uid=1000 type:tmpfs]
[root@localhost ~]# docker volume inspect --format '{{ .Options.o }}' test-vol
size=100m,uid=1000
[root@localhost ~]# docker volume inspect --format '{{ .Labels.city }}' test-vol
hb

4、删除卷

使用 docker volume rm 删除指定卷(不能删除正在被容器使用的卷)

# 语法
[root@localhost ~]# docker volume rm --help
Usage:  docker volume rm [OPTIONS] VOLUME [VOLUME...]
Remove one or more volumes. You cannot remove a volume that is in use by a container.
Aliases:
  rm, remove
Options:
  -f, --force   Force the removal of one or more volumes   强制删除

# 案例
[root@localhost ~]# docker volume rm test-vol01
test-vol01
[root@localhost ~]# docker volume rm $(docker volume ls -q)
test-vol
test-vol02
test-vol03

使用 docker volume prune 删除未被容器或服务使用的所有卷

# 语法
[root@localhost ~]# docker volume prune --help
Usage:  docker volume prune [OPTIONS]
Remove all unused local volumes
Options:
      --filter filter   Provide filter values (e.g. 'label=<label>')
  -f, --force           Do not prompt for confirmation

# 案例
[root@localhost ~]# docker volume prune
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Volumes:
test-vol01
test-vol02
test-vol03
Total reclaimed space: 0B

Top

三、容器文件系统挂载

使用 docker run 或 docker create 命令的相关选项将外部的文件系统挂载到容器中。
早期版本:

  • 卷和绑定挂载都可以通过 -v 和 --mount 选项挂载到容器中,主要是两者的语法的细微区别
  • -v用于独立容器,--mount用于集群服务
  • tmpfs挂载可以使用 --tmpfs选项

docker 17.06或更高版本:

  • 建议所有的容器或服务,绑定挂载、卷、tmpfs都使用--mount选项。(语法清晰、定制详细)
  • --mount 选项也可以用于独立容器。

-v和--mount的区别:

  • -v语法是将选项组合在一个字段中,--mount的语法是将它们分开。
  • --mount采用键值对写法支持更多的设置选项,-v 写法更加简洁。

1、-v(--volume)选项

选项包括冒号分隔的三个字段,必须按照正确顺序排序

# 语法
[root@localhost ~]# docker run(create)
  -v, --volume=[host-src:]container-dest[:<options>]: Bind mount a volume.

第一个host-src字段表示挂载源,来自主机的文件系统,为绝对路径或名称变量。
第二个container-dest字段表示挂载目标,即容器的挂载点,可以是目录或文件路径(绝对路径)
第三个options字段可选,以逗号分隔选项列表,如:[rw|ro], [z|Z], [[r]shared|[r]slave|[r]private], and [nocopy].
   rw:读写模式??
   ro:只读模式
   nocopy:禁止自动复制到卷存储地址
   命名卷,copy是默认模式,copy模式不支持绑定挂载的卷。
   如果既没有指定rw又没有指定ro,卷挂载为读写模式。

# 案例:卷类型
[root@localhost ~]# docker volume create test-vol
test-vol
[root@localhost ~]# docker run -ti -v test-vol:/world ubuntu /bin/bash

# 案例:绑定挂载类型
[root@localhost ~]#  docker run -d \
>   -it \
>   --name devtest \
>   -v "$(pwd)"/target:/app \
>   nginx:latest
9c9bd6c4b7898f272b162683bf7370fe2fde2d04b30a361bda7443bc6a2d2bf4
[root@localhost ~]# docker ps -a
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS         PORTS     NAMES
9c9bd6c4b789   nginx:latest   "/docker-entrypoint.…"   10 seconds ago   Up 9 seconds   80/tcp    devtest
[root@localhost ~]# docker exec -ti 9c9bd6c4b789 /bin/bash
root@9c9bd6c4b789:/# ls
app  boot  docker-entrypoint.d	 etc   lib    media  opt   root  sbin  sys  usr
bin  dev   docker-entrypoint.sh  home  lib64  mnt    proc  run	 srv   tmp  var
root@9c9bd6c4b789:/# df -H
Filesystem               Size  Used Avail Use% Mounted on
overlay                   19G  5.5G   13G  30% /
tmpfs                     68M     0   68M   0% /dev
tmpfs                    1.1G     0  1.1G   0% /sys/fs/cgroup
shm                       68M     0   68M   0% /dev/shm
/dev/mapper/centos-root   19G  5.5G   13G  30% /app

2、--mount选项

绑定挂载、卷、tmpfs类型都使用--mount选项

--mount选项的参数由多个由逗号分隔的键值对组成

特殊键如下:

  • type: 指定要挂载的类型,值可以是bind(绑定挂载)、volume(卷)或tmpfs。
  • source(或src): 指定挂载源
  • destination(或dst、target):指定挂载目标,即容器中的挂载点,必须采用绝对路径的形式
  • readonly:指定只读选项,表示源以只读方式挂载到容器中。
  • 其他键:可以被多次指定,由若干键值对组成。卷和绑定挂载有不同的键。
[root@localhost ~]# docker run(create)
      --mount <键>=<值>,<键>=<值>,...                Attach a filesystem mount to the container

# 案例
[root@localhost ~]# docker run -d   --name devtest01   --mount source=myvol2,target=/app   nginx:latest
65e5132a4a64d40f688d2bcb80fe2f6d9a2fb504e092ca628b59398dd207b2a3
[root@localhost ~]# docker volume ls
DRIVER    VOLUME NAME
local     myvol2
[root@localhost ~]# docker volume inspect myvol2
[
    {
        "CreatedAt": "2022-04-28T02:45:45+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/myvol2/_data",
        "Name": "myvol2",
        "Options": null,
        "Scope": "local"
    }
]
[root@localhost ~]# docker exec -ti devtest01 /bin/bash
root@65e5132a4a64:/# cd /app/

3,tmpfs 选项

tmpfs 挂载容许两个配置选项,两个选项都不是必需的。 若是须要指定这些选项,则必须使用 --mount 标记,由于 --tmpfs 标记不支持

  • tmpfs-size
    tmpfs 挂载的大小(以字节为单位)。默认无限制。

  • tmpfs-mode
    tmpfs 的八进制文件模式。例如,700 或 0770。默认为 1777 或全局可写

示例将 tmpfs-mode 设置为 1770,所以在容器中它不是全局可读的

docker run -d \
  -it \
  --name tmptest \
  --mount type=tmpfs,destination=/app,tmpfs-mode=1770 \
  nginx:latest

Top

四、卷应用示例

1、创建一个卷并让容器挂载

# 1.创建一个卷、查看当前卷列表、查看卷详细信息
[root@localhost ~]# docker volume create test-vol
test-vol
[root@localhost ~]# docker volume ls
DRIVER    VOLUME NAME
local     test-vol
[root@localhost ~]# docker volume inspect test-vol
[
    {
        "CreatedAt": "2022-04-28T03:06:05+08:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/test-vol/_data",
        "Name": "test-vol",
        "Options": {},
        "Scope": "local"
    }
]

# 2.启动容器,将卷挂载到容器/world目录,在容器中查看根目录、退出容器
[root@localhost ~]# docker run -ti -v test-vol:/world ubuntu /bin/bash
root@e6535eebe726:/# ls
bin   dev  home  lib32  libx32  mnt  proc  run   srv  tmp  var
boot  etc  lib   lib64  media   opt  root  sbin  sys  usr  world
root@e6535eebe726:/# ls /world/
root@e6535eebe726:/# exit
exit

# 3.查看容器信息,验证卷是否正确挂载
[root@localhost ~]# docker inspect --format='{{json .Mounts}}'   e6535
[{"Type":"volume","Name":"test-vol","Source":"/var/lib/docker/volumes/test-vol/_data","Destination":"/world","Driver":"local","Mode":"z","RW":true,"Propagation":""}]

# 4.删除卷
[root@localhost ~]# docker volume rm test-vol
Error response from daemon: remove test-vol: volume is in use - [e6535eebe726069b355567be0a562131844ad04b175b2a0ee870d990f72dca95]
# 使用中的卷不能直接删除,第二次是先删除容器,再删除卷
[root@localhost ~]# docker rm e6535
e6535
[root@localhost ~]# docker volume rm test-vol
test-vol

2、启动容器时自动创建卷

启动带有卷的容器时,如果卷尚不存在,则Docker会自动创建这个卷。
示例:将myvol卷挂载到容器testnovol的/app目录下。

--mount选项实现:

[root@localhost ~]# docker run -d --name testnovol01 --mount source=myvol,target=/app nginx
beafe21868168531d1eeb69c7b29e234f0ceb60cabc60ed8e5deae0c4c99f28d
[root@localhost ~]# docker inspect --format='{{json .Mounts}}' testnovol01
[{"Type":"volume","Name":"myvol","Source":"/var/lib/docker/volumes/myvol/_data","Destination":"/app","Driver":"local","Mode":"z","RW":true,"Propagation":""}]

-v选项实现:

[root@localhost ~]# docker run -d --name testnovol02 -v myvol02:/app nginx
d7728830916fd11dec8487ea9aaf7e6f1b306b3c4c072683cf8155f430f57887
[root@localhost ~]# docker inspect --format='{{json .Mounts}}' testnovol02
[{"Type":"volume","Name":"myvol02","Source":"/var/lib/docker/volumes/myvol02/_data","Destination":"/app","Driver":"local","Mode":"z","RW":true,"Propagation":""}]

3、使用容器填充卷

容器启动时挂载已经存在并包含数据的卷,则容器不会将其挂载点目录的数据复制到该卷,而是直接使用该卷的数据

如果容器启动时挂载空白卷或自动创建新卷,而容器的挂载点目录有文件,则该挂载点的内容会复制到卷中

# 1.执行以下命令启动一个nginx容器,并使用容器的/usr/share/nginx/html目录的内容填充新的卷nginx-vol。
[root@localhost ~]# docker run -d --name=nginxtest --mount source=nginx-vol,destination=/usr/share/nginx/html nginx
3f208b4cecc9bc98c0424dc891ae39314b9dab61985e1e957b294a799589fafb
[root@localhost ~]# docker ps 
CONTAINER ID   IMAGE          COMMAND                  CREATED             STATUS             PORTS     NAMES
3f208b4cecc9   nginx          "/docker-entrypoint.…"   20 seconds ago      Up 19 seconds      80/tcp    nginxtest

# 2.执行docker volume inspect nginx-vol命令查看该卷的详细信息,其中挂载点设置如下。
[root@localhost ~]# docker volume ls
DRIVER    VOLUME NAME
local     nginx-vol
[root@localhost ~]# docker volume inspect --format='{{json .Mountpoint}}' nginx-vol
"/var/lib/docker/volumes/nginx-vol/_data"

# 3.查看主机上该卷所在目录的内容,发现容器已经填充了卷。
[root@localhost ~]# cd /var/lib/docker/volumes/nginx-vol/_data/
[root@localhost _data]# ls
50x.html  index.html
[root@localhost _data]# cat index.html 
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

# 4.启动另一个容器挂载该卷,以使用其中预先填充的内容。
[root@localhost _data]# docker run -ti --name=othercntr --mount source=nginx-vol,destination=/nginx ubuntu /bin/bash
root@a68b8352663b:/# ls /nginx/
50x.html  index.html
root@a68b8352663b:/# cd /nginx/
root@a68b8352663b:/nginx# cat 50x.html 
<!DOCTYPE html>
<html>
<head>
<title>Error</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>An error occurred.</h1>
<p>Sorry, the page you are looking for is currently unavailable.<br/>
Please try again later.</p>
<p>If you are the system administrator of this resource then you should check
the error log for details.</p>
<p><em>Faithfully yours, nginx.</em></p>
</body>
</html>

# 5.删除容器和卷
[root@localhost _data]# docker stop $(docker ps -aq)
a68b8352663b
3f208b4cecc9
d7728830916f
beafe2186816
65e5132a4a64
9c9bd6c4b789
[root@localhost _data]# docker rm $(docker ps -aq)
a68b8352663b
3f208b4cecc9
d7728830916f
beafe2186816
65e5132a4a64
9c9bd6c4b789
[root@localhost _data]# docker volume rm  $(docker volume ls -q)
myvol
myvol2
myvol02
nginx-vol

【文章福利】:C/C++Linux服务器开发/后台架构师【公开课学习】(C/C++,Linux,golang技术,内核,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg,大厂面试题 等)有需要的可以点击793599096加群领取哦~

4、使用只读卷

同一个卷可以由多个容器挂载,并且让容器执行读写操作。设置只读权限后,在容器中是无法对卷中数据修改的,可以提升安全性。

# --mount选项
[root@localhost _data]# docker run -dti --name=nginx-test --mount source=nginx-vol01,destination=/usr/share/nginx/html,readonly nginx
44bb1ee56819a71a4fafda36ab0ea05952d51b5d3c49dbfcc14a27fd2c84f740
[root@localhost _data]# docker exec -ti nginx-test /bin/bash
root@44bb1ee56819:/# cd /usr/share/nginx/html/
root@44bb1ee56819:/usr/share/nginx/html# touch sss
touch: cannot touch 'sss': Read-only file system
root@44bb1ee56819:/usr/share/nginx/html# echo 'adadadd' >> 50x.html 
bash: 50x.html: Read-only file system
[root@localhost _data]# docker inspect --format='{{json .Mounts}}'  nginx-test
[{"Type":"volume","Name":"nginx-vol01","Source":"/var/lib/docker/volumes/nginx-vol01/_data","Destination":"/usr/share/nginx/html","Driver":"local","Mode":"z","RW":false,"Propagation":""}]

# -v选项
[root@localhost _data]# docker run -dti --name=nginx-test02 -v nginx-vol02:/usr/share/nginx/html:ro nginx
5b909ace1f2533ecd637bcf5779baf8df5a90aafb9f18a21fcf1fe3573103641
[root@localhost _data]# docker exec -ti nginx-test02 /bin/bash
root@5b909ace1f25:/# cd /usr/share/nginx/html/
root@5b909ace1f25:/usr/share/nginx/html# echo 'sadad' >> index.html 
bash: index.html: Read-only file system
root@5b909ace1f25:/usr/share/nginx/html# touch asdad
touch: cannot touch 'asdad': Read-only file system
[root@localhost _data]# docker inspect --format='{{json .Mounts}}'  nginx-test02
[{"Type":"volume","Name":"nginx-vol02","Source":"/var/lib/docker/volumes/nginx-vol02/_data","Destination":"/usr/share/nginx/html","Driver":"local","Mode":"ro","RW":false,"Propagation":""}]

注意:-v 和 --mount 选项,inspect查看输出的Mounts部分的信息有差异,主要是'Mode'显示的内容不同,一个表示读写模式,一个表示selinux的标签设置。

5、使用匿名卷

定义:匿名卷没有指定明确的名称。在创建或启动容器时可以创建匿名卷。

# --mount:启动容器时不定义source
[root@localhost ~]# docker run -it --mount destination=/app ubuntu /bin/bash
root@eacbc9629f0f:/# ls
app  boot  etc   lib    lib64   media  opt   root  sbin  sys  usr
bin  dev   home  lib32  libx32  mnt    proc  run   srv   tmp  var
root@eacbc9629f0f:/# exit
exit
[root@localhost ~]# docker volume ls
DRIVER    VOLUME NAME
local     baa55a4c1cfc3aa117630efd47b2986fb9ad775be95d4f08735fc0495340ab0e
[root@localhost ~]# docker volume rm baa55a4c
Error: No such volume: baa55a4c     《————指定匿名卷必须使用完整的UUID
[root@localhost ~]# docker rm eacbc9629f0f
eacbc9629f0f
[root@localhost ~]# docker volume rm baa55a4c1cfc3aa117630efd47b2986fb9ad775be95d4f08735fc0495340ab0e
baa55a4c1cfc3aa117630efd47b2986fb9ad775be95d4f08735fc0495340ab0e

# -v:启动容器时省略第一个字段[host-src:]
[root@localhost ~]# docker run -ti -v /app ubuntu /bin/bash
root@3673f14ae07a:/# ls
app  boot  etc   lib    lib64   media  opt   root  sbin  sys  usr
bin  dev   home  lib32  libx32  mnt    proc  run   srv   tmp  var
root@3673f14ae07a:/# exit
exit
[root@localhost ~]# docker volume ls
DRIVER    VOLUME NAME
local     db8dfec8d223d5eb3662c73249a9545ee1d982f00b52ca8b1a5e6314d843495d
[root@localhost ~]# docker container prune
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Deleted Containers:
3673f14ae07a660a437d615eaca1aeb012673233010d5e7e0cbc0d30c7e601f0
Total reclaimed space: 8B
[root@localhost ~]# docker volume prune
WARNING! This will remove all local volumes not used by at least one container.
Are you sure you want to continue? [y/N] y     
Deleted Volumes:
db8dfec8d223d5eb3662c73249a9545ee1d982f00b52ca8b1a5e6314d843495d
Total reclaimed space: 0B

6、绑定挂载主机上的目录

可以通过绑定挂载将Docker主机上现有的目录挂载到容器的目录中,需要挂载的目录可以由主机的绝对路径引用。

$(pwd) 命令可以表示linux主机的当前目录,注意要用双引号包起来,否则报错。

绑定挂载的容器,不能强制删除,应该先停止后删除,否则会有警告

(1) --mount选项

# 1.准备目录,切换到新目录的父目录
[root@localhost ~]# mkdir -p source/target
[root@localhost ~]# cd source/
[root@localhost source]# pwd
/root/source
# 2.启动容器,将主机的source/target目录挂载到容器的/app目录下
[root@localhost source]# docker run -dti --name devtest --mount type=bind,source="$(pwd)/target",target=/app nginx
497a3e9b17926b428e22c8b424a5d566a2edd8cc1211bbadd6416d65cbe13b86
# 失败的案例:绑定挂载必须使用已经存在的目录:
[root@localhost source]# docker run -dti --name devtest01 --mount type=bind,source="$(pwd)/test",target=/app nginx
docker: Error response from daemon: invalid mount config for type "bind": bind source path does not exist: /root/source/test.

# 3.查看容器的信息,验证绑定挂载是否创建
[root@localhost source]# docker inspect --format='{{json .Mounts}}'  devtest
[{"Type":"bind","Source":"/root/source/target","Destination":"/app","Mode":"","RW":true,"Propagation":"rprivate"}]
# type说明挂载方式为绑定挂载,源和目标路径都是正确的,Propagation(传播)方式是:rprivate(私有的)。
# Mode:表示与selinux标签有关的选项。
  # z选项表示绑定挂载的内容在多个容器之间共享。
  # Z选项表示绑定挂载的内容是私有的。

# 4.停止并删除容器
[root@localhost source]# docker rm -f devtest
devtest

# 5.启动只读绑定挂载容器
[root@localhost source]# docker run -dti --name devtest --mount type=bind,source="$(pwd)"/target,target=/app,readonly nginx
586c51f2b909903e4a755a85685bb4b1d9a7b5f2bb226f2bcc4c2f8fae1cf270

# 6.查看容器的信息
[root@localhost source]# docker inspect --format='{{json .Mounts}}' devtest
[{"Type":"bind","Source":"/root/source/target","Destination":"/app","Mode":"","RW":false,"Propagation":"rprivate"}]
# RW为false,说明为只读模式

(2)-v选项

# 1.准备目录,切换到新目录的父目录
[root@localhost ~]# mkdir -p source/target
[root@localhost ~]# cd source/
[root@localhost source]# pwd
/root/source
# 2.启动容器,将主机的source/target目录挂载到容器的/app目录下
[root@localhost source]# docker run -dti --name devtest -v "$(pwd)/target":/app nginx
9efef939c123a1b2e7f4b053008d4699c0dc4f1f879c40ea81614f24e9acec04

# 3.查看容器的信息,验证绑定挂载是否创建
[root@localhost source]# docker inspect --format='{{json .Mounts}}' devtest
[{"Type":"bind","Source":"/root/source/target","Destination":"/app","Mode":"","RW":true,"Propagation":"rprivate"}]
# type说明挂载方式为绑定挂载,源和目标路径都是正确的,Propagation(传播)方式是:rprivate(私有的)。

# 4.停止并删除容器
[root@localhost source]# docker stop devtest
devtest
[root@localhost source]# docker rm devtest
devtest

# 5.启动只读绑定挂载容器
[root@localhost source]# docker run -dti --name devtest -v "$(pwd)/target":/app:ro nginx
c56f97fd97247eaa3fe02edeef6e298944944575d023e16a60365edb53911aa3

# 6.查看容器的信息
[root@localhost source]# docker inspect --format='{{json .Mounts}}' devtest
[{"Type":"bind","Source":"/root/source/target","Destination":"/app","Mode":"ro","RW":false,"Propagation":"rprivate"}]
# Mode为"ro",为只读模式

7、绑定挂载主机上的文件

绑定挂载文件主要用于主机与容器之间共享配置文件

配置文件置于Docker主机中,并挂载到容器,可以随时更改配置,将配置管理变简单

# 1.查看主机的时区
[root@localhost source]# date +%z
+0800

# 2.启动一个ubuntu容器查看时区
[root@localhost source]# docker run -tid --rm --name test ubuntu  /bin/bash
a688f13a3d1eb1e2d252b68df657517f3325145823c9ce2c83cdb7e0fb6c889d
[root@localhost source]# docker exec -ti test /bin/bash
root@a688f13a3d1e:/# date +%z
+0000

# 3.启动一个绑定挂载文件的容器查看时区
[root@localhost source]# docker run -tid --rm --name test01 -v /etc/localtime:/etc/localtime  ubuntu  /bin/bash
bda7b3deca99bd39985df06a0c875114c3867f7411477ccbe220dcf08260e4a6
[root@localhost source]# docker exec -ti test01 /bin/bash
root@bda7b3deca99:/# date +%z
+0800

8、绑定挂载主机上不存在的目录或文件

绑定挂载Docker主机上不存在的目录或文件--mount-v选项的表现不同

(1)-v选项:自动创建目录

# 启动容器,查看路径,并退出
[root@localhost ~]# docker run -ti --rm -v /doestnt/exist:/foo ubuntu bash
root@8fcdd361f44f:/# cd foo/
root@8fcdd361f44f:/foo# pwd
/foo
root@8fcdd361f44f:/foo# exit
exit

# 在docker主机查看新创建的路径
[root@localhost /]# ls
bin   dev      etc   lib    media  opt   root  sbin  sys  usr
boot  doestnt  home  lib64  mnt    proc  run   srv   tmp  var
[root@localhost /]# ls /doestnt/exist/

(2)--mount选项:报错

[root@localhost /]# docker run -ti --rm --mount type=bind,source=/doesnt/exist,destination=/foo ubuntu bash
docker: Error response from daemon: invalid mount config for type "bind": bind source path does not exist: /doesnt/exist.

9、绑定挂载到容器中的非空目录

如果将主机上的目录绑定挂载到容器上的非空目录,则容器挂载的目录中的现有内容会被绑定挂载(主机上的目录)所遮盖

  • 被遮盖的目录和文件不会被删除或更改,但在使用绑定挂载时不可访问
  • 无论主机上的目录是否为空,绑定挂载到容器中的非空目录都会发生被遮盖的情况
[root@localhost /]# docker run -tid --name broken-test --mount type=bind,source=/tmp,target=/etc/yum.repos.d centos
cb7c523f56bd7ae4293bb83a27074f35f9abd319c9d08a94d9b17d072ddffad1
[root@localhost /]# docker exec -ti broken-test /bin/bash
[root@cb7c523f56bd /]# cd /etc/yum.repos.d/
[root@cb7c523f56bd yum.repos.d]# ls
vmware-root      <————遮盖了容器之前的内容

10、备份、恢复和迁移数据卷

可以通过卷容器(Volume Container)实现卷的备份、恢复和迁移。

卷容器(数据卷容器):一种特殊的容器,专门用来将卷(或绑定挂载)提供给其他容器挂载。

--volumes-from 选项:创建容器时使用这个选项,可基于卷容器创建一个新的容器,并挂载卷容器提供的卷。

(1)创建卷容器

# 创建卷容器,挂载一个匿名卷
[root@localhost tmp]# docker create -v /dbdata --name dbstore busybox /bin/sh
e0bf42be22e492c1377112967dd113d6cfc6b0bd2483adef84f9f0da962c2806
[root@localhost tmp]# docker volume ls
DRIVER    VOLUME NAME
local     e3440f88e29fdb974db84419090554c2d61bd78819a86650446f3f69a5030783
[root@localhost tmp]# docker inspect --format='{{json .Mounts}}' dbstore
[{"Type":"volume","Name":"e3440f88e29fdb974db84419090554c2d61bd78819a86650446f3f69a5030783","Source":"/var/lib/docker/volumes/e3440f88e29fdb974db84419090554c2d61bd78819a86650446f3f69a5030783/_data","Destination":"/dbdata","Driver":"local","Mode":"","RW":true,"Propagation":""}]

(2)备份卷容器

[root@localhost tmp]# docker run --rm --volumes-from dbstore -v $(pwd):/backup ubuntu tar cvfP /backup/backup.tar /dbdata
/dbdata/
[root@localhost tmp]# ls
backup.tar  vmware-root
[root@localhost tmp]# du -sh *
12K	backup.tar
0	vmware-root

# 执行命令会完成一下操作:
# 1. 启动一个新的容器并从dbstore容器中挂载卷。
# 2. 将本地主机的当前目录挂载为/backup。
# 3. 传送一个命令将dbdata卷的内容打包为/backup/backup.tar文件。

(3)从备份恢复卷容器

创建备份后,可以将它恢复到同一个容器,或另一个容器。

# 1. 创建一个新卷容器
[root@localhost tmp]# docker run -v /dbdata --name dbstore2 ubuntu /bin/bash

# 2. 在新容器的数据卷中将备份文件解压
[root@localhost tmp]# docker run -tid --volumes-from dbstore2 -v $(pwd):/backup ubuntu bash -c "cd /backup && tar xvf backup.tar && /bin/bash"
e4a269b16d16e03e8e8fa4bd94940d03e7425c2671573bf570a3f42a2f2f29a2
[root@localhost tmp]# docker exec -ti e4a269b16d16 /bin/bash
root@e4a269b16d16:/# cd /backup/
root@e4a269b16d16:/backup# ls
backup.tar  dbdata  vmware-root       <————dbdata为解压出的文件夹

至此docker存储管理的学习已经完结

转自;https://www.cnblogs.com/zhengyan6/p/16224092.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

docker存储管理及实例 的相关文章

  • 锁定 ASP.NET 应用程序变量

    我在 ASP NET 应用程序中使用第三方 Web 服务 对第 3 方 Web 服务的调用必须同步 但 ASP NET 显然是多线程的 并且可能会发出多个页面请求 从而导致对第 3 方 Web 服务的同时调用 对 Web 服务的调用封装在自
  • MFC CList 支持复制分配吗?

    我在 MSVC 中查找了 CList 定义afxtempl h http www cppdoc com example mfc classdoc MFC AFXTEMPL H html并记录在MSDN http msdn microsoft
  • 如果在等待“read -s”时中断,在子进程中运行 bash 会破坏 tty 的标准输出吗?

    正如 Bakuriu 在评论中指出的那样 这基本上与BASH 输入期间按 Ctrl C 会中断当前终端 https stackoverflow com questions 31808863 bash ctrlc during input b
  • 全局使用和 .NET Standard 2.0

    我最近意识到我可以使用 C 10 功能文件范围的命名空间在 NET Standard 2 0 项目中也可以通过设置
  • C++ 将联合强制转换为其成员类型之一

    以下对我来说似乎完全符合逻辑 但不是有效的 C 联合不能隐式转换为其成员类型之一 有人知道为什么不这样做的充分理由吗 union u int i char c function f int i int main u v v i 6 f v
  • while循环中的变量初始化

    我有一个可以分块读取文件的函数 public static DataObject ReadNextFile 数据对象看起来像这样 public DataObject public string Category get set And ot
  • 为什么需要数字后缀?

    C 语言 我确信还有其他语言 需要在数字文字末尾添加后缀 这些后缀指示文字的类型 例如 5m是一个小数 5f是一个浮点数 我的问题是 这些后缀真的有必要吗 或者是否可以从上下文中推断出文字的类型 例如 代码decimal d 5 0应该推断
  • 为什么不能调用带有 auto& 参数的 const mutable lambda?

    include
  • 将错误代码映射到 C++ 中的字符串

    将错误代码从枚举映射到字符串的更有效方法是什么 在 C 中 例如 现在我正在做这样的事情 std string ErrorCodeToString enum errorCode switch errorCode case ERROR ONE
  • 如何使用 CSI.exe 脚本参数

    当你运行csi exe 安装了 Visual Studio 2015 update 2 您将得到以下语法 Microsoft R Visual C Interactive Compiler version 1 2 0 51106 Copyr
  • doxygen c++:记录由“using”声明公开的私有继承成员

    作为一个例子 我有以下课程 class A public void methodOne class B private A public Brief description using A methodOne 我还没有找到强制 doxyge
  • ALTER TABLE ... ADD CONSTRAINT 失败时将事务回滚到保存点

    有没有办法在事务中添加检查约束and如果失败回滚到以前的保存点 而不是回滚整个事务 就我而言 当 ALTER TABLE ADD CONSTRAINT 命令失败时 事务无法回滚到保存点 尝试这样做会引发 InvalidOperationEx
  • 浮点字节序?

    我正在为实时海上模拟器编写客户端和服务器 并且由于我必须通过套接字发送大量数据 因此我使用二进制数据来最大化可以发送的数据量 我已经了解整数字节顺序以及如何使用htonl and ntohl为了规避字节顺序问题 但我的应用程序与几乎所有模拟
  • 从 NumPy 数组到 Mat 的 C++ 转换 (OpenCV)

    我正在围绕 ArUco 增强现实库 基于 OpenCV 编写一个薄包装器 我试图构建的界面非常简单 Python 将图像传递给 C 代码 C 代码检测标记并将其位置和其他信息作为字典元组返回给 Python 但是 我不知道如何在 Pytho
  • 在哪里可以下载没有 Visual Studio 2010 的 C# 4.0 编译器?

    我知道 CTP VS 2010 映像 但我可以只下载 NET Framework 4 0 和 C 编译器吗 AFAIK VS 2010 CTP 仅作为 VM 映像提供 我不相信 Microsoft 发布了 VS 的安装程序 其中一个绝对不适
  • Linq.Select() 中的嵌套表达式方法调用

    I use Select i gt new T 每次手动点击数据库后将我的实体对象转换为 DTO 对象 以下是一些示例实体和 DTOS 用户实体 public partial class User public int Id get set
  • 如何将 int 作为“void *”传递给线程启动函数?

    我最初有一个用于斐波那契变量数组的全局变量 但发现这是不允许的 我需要进行基本的多线程处理并处理竞争条件 但我无法在 pthread 创建中将 int 作为 void 参数提供 我尝试过使用常量指针 但没有成功 由于某些奇怪的原因 void
  • 如果“嵌入式”SQL 2008 数据库文件不存在,如何创建它?

    我使用 C ADO Net 和在 Server Management Studio 中创建的嵌入式 MS SQL 2008 数据库文件 附加到 MS SQL 2008 Express 创建了一个数据库应用程序 有人可以向我指出一个资源 该资
  • 如何在c linux中收听特定接口上的广播?

    我目前可以通过执行以下操作来收听我编写的简单广播服务器 仅广播 hello int fd socket PF INET SOCK DGRAM 0 struct sockaddr in addr memset addr 0 sizeof ad
  • 如何提高环复杂度?

    对于具有大量决策语句 包括 if while for 语句 的方法 循环复杂度会很高 那么我们该如何改进呢 我正在处理一个大项目 我应该减少 CC gt 10 的方法的 CC 并且有很多方法都存在这个问题 下面我将列出一些例如我遇到的问题的

随机推荐

  • 【保姆级教程】手把手教你用github制作学术个人主页(学者必备)

    很多朋友到了本科生或者研究生或者博士生的高年级 有了制作个人主页的需求 今天这一期博客将以academicpages模板为例 手把手教你快速制作一个简洁能用的个人主页 1 首先你需要拥有一个github账号 2 然后我们来找模板 比如你可以
  • eclipse ide使用_开始使用Eclipse Che IDE在云端进行开发

    eclipse ide使用 在我职业生涯中经历的许多技术面试中 我注意到很少有人问到具有确定答案的问题 大多数情况下 我会被问到开放式问题 这些问题没有绝对正确的答案 但会评估我以前的经验以及我能很好地解释事情的能力 我多次被问到的一个有趣
  • kafka初探 版本0.10 java编程

    之前一直有项目用到 不过我并不负责这一块 所以了解不多 这次趁机会学习下 之前对kafka的了解其实仅限于知道它是一个分布式消息系统 这次详细了解了下 知道了一些关键概念 topic主题 broker服务 producers消息发布者 co
  • 类中数组成员变量怎么初始化,数组名与指针的区别

    使用STL标准模板库之后 编程时已经很少使用数组和指针 相反 多使用序列容器vector代替之 std vector
  • datetime.dt.day以及to_datetime函数讲解(Python时序量汇总)

    之前在别的博客记过pandas处理时间量的笔记 但是时间一长又忘了 所以决定另外写一篇记录下时序量的处理 1 关于pandas的to datetime函数的理解 参考 https blog csdn net qq 36523839 arti
  • MATLAB——数据及其运算

    MATLAB数值数据 数值数据类型的分类 1 整型 整型数据是不带小数的数 有带符号整数和无符号整数之分 表中列出了各种整型数据的取值范围和对应的转换函数 2 浮点型 浮点型数据有单精度 single 和双精度 double 之分 单精度型
  • 95-30-015-Channel-AbstractNioMessageChannel

    文章目录 1 概述 2 类图 2 1 继承关系 2 2 类图简介 3 内部类NioMessageUnsafe 3 1 read事件框架 1 概述 AbstractNioMessageChannel是底层数据为消息的NioChannel 在N
  • 动态规划入门之国王的金矿

    最近学习算法 对动态规划不太了解 使用的时候照搬转移方程式 知其然不知其所以然 今天看到一篇动态规划的教程 解释得非常通俗 原文在这里 动态规划入门教程 http blog csdn net woshioosm article detail
  • 并发编程--------JUC集合

    并发集合 一 ConcurrentHashMap 1 1 存储结构 ConcurrentHashMap是线程安全的HashMap ConcurrentHashMap在JDK1 8中是以CAS synchronized实现的线程安全 CAS
  • 不会“卷”,就会被淘汰?3招教你打破职场内卷焦虑

    内卷 这个词对大家来说都已经不新鲜了 时不时就会听到 人人皆在卷 万物皆可卷 从未出生那一刻的胎教到出生后的早教 从幼儿园开始的择校 一路 卷 到大学的名号 绩点 而职场内卷 是大家最熟悉的 战场 职场内卷是指在职场竞争中 为了争夺有限的资
  • 【目标检测】---- 正负样本匹配策略

    1 综述 无论是anchor box 还是anchor free 在训练计算类别 前背景损失时都需用到正负样本匹配 目前分为两大类 第一类 fixed label assignment 常用的主要有MaxIou ATSS focos 第二类
  • Docker loop volume VS direct LVM 选型和分析

    测试准备 测试目的 Docker在DeviceMapper这块支持两种存储模式 分别是docker默认的loop volume和Direct VLM 为了了解其中区别也是为了依据业务进行选型 所以选择了对二者进行性能测试 测试范围 性能指标
  • React 引入antd后启动项目时出现的警告信息

    Compiled with warnings Failed to parse source map webpack antd components config provider style index less URL is not su
  • windows不安装虚拟机如何使用Linux系统作为开发工具?

    哈喽 大家好 我是仲一 作为嵌入式开发程序员 常常需要在Linux环境下编译一些代码 安装虚拟机比较方便 但是 太占用内存了 性能不好的电脑开了一台虚拟机后 可能就干不了其他事情了 安装双系统也比较麻烦 常常需要重启电脑来完成系统的切换 今
  • RHCE第四次作业

    1 判新当前磁盘剩余空间是否有20G 如果小于20G 则将报警邮件发送给管理员 每天检查一次磁盘剩余空间 2 判web服务是否运行 1 查看进程的方式判断该程序是否运行 2 通过查看端口的方式判断该程序是否运行 如果没有运行 则启动该服务并
  • Leetcode刷题c++之575. 分糖果

    题目描述 定一个偶数长度的数组 其中不同的数字代表着不同种类的糖果 每一个数字代表一个糖果 你需要把这些糖果平均分给一个弟弟和一个妹妹 返回妹妹可以获得的最大糖果的种类数 示例 输入 candies 1 1 2 2 3 3 输出 3 解析
  • Python与Excel交互与处理

    一 Python与Excel交互的背景及意义 Excel是很多公司和个人在数据分析和处理中使用的工具 其可以通过公式和条件格式等功能 实现简单的数据分析和处理 但是对于复杂的数据分析和处理来说 Excel的局限性就很大 难以满足需求 而Py
  • Nginx 日志配置、日志切割、日志切割脚本

    文章目录 前言 一 access log 1 语法 2 基本用法 3 作用域 4 log format 自定义日志格式 二 error log 1 语法 2 基本用法 3 作用域 4 rewrite log 指令 三 Nginx变量 1 简
  • 地球人口承载力估计 解析和C++代码

    Description 假设地球上的新生资源按恒定速度增长 照此测算 地球上现有资源加上新生资源可供x亿人生活a年 或供y亿人生活b年 为了能够实现可持续发展 避免资源枯竭 地球最多能够养活多少亿人 Input 一行 包括四个正整数x a
  • docker存储管理及实例

    一 Docker存储概念 1 容器本地存储与Docke存储驱动 容器本地存储 每个容器都被自动分配了内部存储 即容器本地存储 采用的是联合文件系统 通过存储驱动进行管理 存储驱动 控制镜像和容器在 docker 主机上的存储和管理方式 容器