docker的挂载和数据卷
我们还定义了两个 volumes,一个用于将本地的 /data/mysql 目录挂载到 MySQL 容器中的 /var/lib/mysql 目录上,另一个用于将当前目录(即 .)挂载到 Django 容器中的 /code 目录上。它们允许容器中的数据在容器停止和删除后仍然存在,并允许多个容器共享同一卷,使用数据卷可以使容器中的数据持久化,并且可以在多个容器之间共享相同的数据。MySQL 容器中的数
Docker挂载(Mount)
一种将主机文件系统上的目录或文件系统挂载到Docker容器内的方式,可以让容器访问主机上的文件系统,也可以让容器之间共享数据。
Docker支持两种挂载方式:
命名挂载
命名挂载使用预先定义的数据卷进行挂载。首先需要使用docker volume create命令创建一个数据卷,然后使用–mount或-v选项将数据卷挂载到容器中。例如:
docker volume create mydata
docker run --mount source=mydata,target=/app/data myimage:latest
上述命令创建了一个名为mydata的数据卷,并将其挂载到容器中的/app/data目录中
使用 -v 挂载时,如果宿主机上没有指定文件不会报错,会自动创建指定文件;当使用 --mount时,如果宿主机中没有这个文件会报错找不到指定文件,不会自动创建指定文件
因此上述命令等价于:
docker volume create mydata
docker run -v mydata:/app/data myimage:latest
docker创建的数据卷默认是共享卷,即:可以挂载到多个容器,并且在一个容器里面的改动,在其他容器也会有体现
docker volume create myvolume
docker run -d --name my-container -v myvolume:/data mysql
但是会报错:
2023-11-25 23:05:49 2023-11-25 15:05:49+00:00 [ERROR] [Entrypoint]: Database is uninitialized and password option is not specified
2023-11-25 23:05:49 You need to specify one of the following as an environment variable:
2023-11-25 23:05:49 - MYSQL_ROOT_PASSWORD
2023-11-25 23:05:49 - MYSQL_ALLOW_EMPTY_PASSWORD
2023-11-25 23:05:49 - MYSQL_RANDOM_ROOT_PASSWORD
这是因为 MySQL 镜像在启动时检测到数据库未初始化,并且没有设置 MySQL root 用户密码。MySQL 镜像要求在启动容器时提供 root 用户密码,以确保安全性。
你可以通过以下几种方式之一解决这个问题:
设置 root 用户密码: 在 docker run 命令中,使用 -e 选项设置环境变量 MYSQL_ROOT_PASSWORD 来指定 root 用户的密码。
docker run -d --name my-container -v myvolume:/data -e MYSQL_ROOT_PASSWORD=mysecretpassword mysql
将 mysecretpassword 替换为你想要设置的实际密码。
允许空密码: 如果你希望 root 用户没有密码,可以使用 -e 选项设置环境变量 MYSQL_ALLOW_EMPTY_PASSWORD。
docker run -d --name my-container -v myvolume:/data -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql
随机生成 root 用户密码: 如果你希望 MySQL 在每次启动时为 root 用户生成一个随机密码,可以使用 -e 选项设置环境变量 MYSQL_RANDOM_ROOT_PASSWORD。
docker run -d --name my-container -v myvolume:/data -e MYSQL_RANDOM_ROOT_PASSWORD=true mysql
创建两个容器并挂载同一个卷,就可以实现共享: docker exec -it my-container2 bash
在一个容器里面修改卷内容,另一个容器也会有体现
匿名挂载
匿名挂载是一种将主机上的目录或文件系统挂载到容器内部的方式,不需要预先定义数据卷。可以使用–mount或-v选项指定要挂载的目录或文件系统。例如:
docker run -d --name my-container3 -v D:/temp_files/docker_file:/dockerfiles -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql
将主机上的D:/temp_files/docker_file目录挂载到容器中的/docker_file目录中,然后就可以实现互通,任何一个目录的改动在另一个也会有相同的改动。
在使用挂载时,需要注意以下几点:
1.目标路径必须是容器内部的绝对路径。
2.如果要在多个容器之间共享数据,则需要使用相同的挂载路径和选项。
3.如果挂载了主机上的目录,则容器内的更改将反映在主机上,并且主机上的更改将反映在容器内。
4.如果挂载了数据卷,则数据将在容器停止和删除后仍然存在。
总之,使用挂载可以让容器访问主机上的文件系统,并可以在多个容器之间共享数据。
数据卷
Docker的数据卷是一种特殊的目录,可用于在容器和主机之间持久化和共享数据。它们允许容器中的数据在容器停止和删除后仍然存在,并允许多个容器共享同一卷,使用数据卷可以使容器中的数据持久化,并且可以在多个容器之间共享相同的数据。这使得容器更加灵活和可靠,同时也简化了容器的管理和部署。
使用数据卷有以下几个步骤:
创建数据卷:可以使用以下命令来创建数据卷:
docker volume create <volume-name>
将数据卷挂载到容器中:可以使用以下命令来挂载数据卷到容器中:
docker run -v <volume-name>:<container-path> <image-name>
其中,volume-name是数据卷的名称,container-path是容器中要挂载数据卷的路径,image-name是容器使用的镜像名称。
在容器中使用数据卷:可以在容器中的应用程序中使用挂载的数据卷。任何写入容器中挂载的路径的数据都将被持久化到数据卷中,并且在容器被删除时仍然存在。
共享数据卷:可以在多个容器之间共享数据卷。可以使用相同的数据卷名称和路径来挂载数据卷,从而使多个容器都能够访问相同的数据。
删除数据卷:可以使用以下命令来删除数据卷:
docker volume rm <volume-name>
如果数据卷当前正在被容器使用,则无法删除。要删除被容器使用的数据卷,必须先删除使用该数据卷的容器。
在Docker Compose中使用数据卷:
定义数据卷1(命名挂载)
在Docker Compose文件中,可以使用volumes关键字来定义数据卷。例如:
version: "3.9"
services:
app:
image: myapp:latest
volumes:
- mydata:/app/data
volumes:
mydata:
上述代码定义了一个名为mydata的数据卷,并将其挂载到应用程序容器中的/app/data目录中。
定义数据卷2(匿名挂载)
version: "3"
services:
db:
image: mysql
volumes:
- /data/mysql:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: my-secret-pw
web:
build: .
volumes:
- .:/code
ports:
- "8000:8000"
depends_on:
- db
environment:
DB_HOST: db
DB_NAME: mydatabase
DB_USER: root
DB_PASSWORD: my-secret-pw
定义了两个服务:一个 MySQL 服务(名为 db),一个 Django 服务(名为 web)。我们还定义了两个 volumes,一个用于将本地的 /data/mysql 目录挂载到 MySQL 容器中的 /var/lib/mysql 目录上,另一个用于将当前目录(即 .)挂载到 Django 容器中的 /code 目录上。
在使用Compose时,如果没有手动创建数据卷,则Compose将自动创建它们。在数据卷的生命周期内,数据将保留在主机的文件系统中,并可以被多个容器共享。如果需要清除数据卷,则可以使用以下命令:
在运行 Docker Compose 时,我们可以使用如下命令:
docker-compose up
Docker Compose 会自动创建并启动两个容器,并将它们连接在一起。MySQL 容器中的数据会被保存到本地的 /data/mysql 目录中,而 Django 容器中的代码会被保存到本地的当前目录中。
docker-compose down --volumes
这将清除所有Compose中定义的数据卷。
数据卷的位置
在容器中,数据卷通常被挂载到容器的文件系统中的某个目录。Docker容器中的文件系统包括只读的镜像层和可写的容器层,数据卷属于容器层,可以被多个容器共享。Docker容器中挂载数据卷的路径通常是绝对路径,可以在启动容器时通过-v或–mount参数指定。
在主机上,Docker数据卷的位置取决于数据卷类型。Docker支持多种类型的数据卷,包括:
匿名卷
匿名卷是在Docker容器内部创建的卷,没有命名和标签。在主机上,匿名卷存储在Docker的数据目录下,通常是/var/lib/docker/volumes目录。
命名卷
命名卷是具有名称和标签的数据卷,可以在创建容器时手动创建或者在Docker Compose文件中定义。在主机上,命名卷也存储在Docker的数据目录下,但是路径包括了卷的名称和标签信息。例如,如果创建了一个名为mydata的数据卷,那么该卷在主机上的位置通常是/var/lib/docker/volumes/mydata/_data
绑定挂载
绑定挂载将主机上的目录或文件系统挂载到容器中,因此在主机上,挂载的位置就是绑定的目录或文件系统的位置。
挂载和数据卷
相比挂载,数据卷的优点是由于是 Docker 统一管理的,不存在由于权限不够引发的挂载问题,也不需要在不同服务器指定不同的路径;缺点是它不太适合单配置文件的映射。
和挂载一样,数据卷的生命周期脱离了容器,删除容器之后卷还是存在的。下次构建镜像时,指定卷的名称就可以继续使用了。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)