如何设置和运行Docker数据卷

时间:2020-03-05 15:25:27  来源:igfitidea点击:

在本教程中,我们将在整个使用Docker卷中行走,这可以被视为Docker Ecosystem提供的灵活方式来管理和处理包含在内的内部的数据以及它们之间的共享方式。

请不要那个,对于演示我将使用Docker for Mac的版本如下所示,但我认为,在基于云的平台和我的工作文件夹中,Linux,Windows甚至新版Docker的指令/命令仍然是相同的在终端将是dockercolumes。

>>  ~ docker --version
Docker version 1.12.3, build 6b644ec

介绍

通过介绍,我会说读者可能会问的基本问题,就是为什么我们应该使用卷,Docker容器提供光线OS级虚拟化,这意味着Docker容器我可以运行整个操作系统合作,为什么卷很重要;好吧,事实上,带来这种机制背后有很多原因;最重要的是,首先是令人疑虑的分离,这意味着能够将数据存储分离,这种松散耦合允许我们甚至删除我们的容器后,即使在删除是非常好的和频繁使用情况,秒之一,卷允许我们在本机顶部运行的主机和Docker容器之间共享数据,其中三分之一,它允许我们在容器之间共享数据。

创建Docker卷

事实上,有几种方法可以创建Docker卷;主要是在Docker创建生命周期内,或者单独。

在Docker创建中添加卷

当我们使用命令Docker创建和启动Docker容器时,我们可以通过添加Argument -V和指定卷的文件夹路径来指定要连接到创建的容器的卷。

让我们创建一个Docker镜像(NodeJS镜像)并设置一个示例节点Web应用程序来解决本文:

  • 设置一个简单的NodeJS应用程序
>>  DockerVolumes ls
Dockerfile   node_modules package.json server.js
//Dockerfile
>>  DockerVolumes cat Dockerfile
FROM node:latest
# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
# Install app dependencies
COPY package.json /usr/src/app/
RUN npm install
# Bundle app source
COPY . /usr/src/app
EXPOSE 3000
CMD [ "node", "server.js" ]
//server.js
>>  DockerVolumes cat server.js
var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send("What's up docker volume!");
});
app.listen(3000, function () {
console.log('Server listening on port 3000!');
});
  • 构建我们的Docker镜像并使用-T标志标记
>>  DockerVolumes docker build -t theitroad/nodewebapp .
Sending build context to Docker daemon  5.12 kB
Step 1 : FROM node:latest
---> f5eca816b45d
Step 2 : RUN mkdir -p /usr/src/app
---> Using cache
---> 26654b09fdc4
Step 3 : WORKDIR /usr/src/app
---> Using cache
---> 37845a9e9171
Step 4 : COPY package.json /usr/src/app/
---> 6c56590fbccb
Removing intermediate container bdb0b1c0881b
Step 5 : RUN npm install
---> Running in 47e7726adb89
…
…
Removing intermediate container bc82f32eef88
Successfully built 7d558c342dfb
  • 让我们使用我们的上一个构建图像运行一个卷的容器,节点我们将公共端口3001将公钥3001绑定到我们节点服务器的私有(在我们的容器中)端口3000:
>>  DockerVolumes docker run -p 3001:3000 -d --name nodewebapp -v /nodewebapp theitroad/nodewebapp
602f318d57d5e03b353b15a4c644f90a9918e46590ddff0fb776fa09cf32c51a
  • 我们可以使用curl测试我们的节点Web
>>  ~ curl localhost:3001
What's up docker volume!
  • 检查我们的容器以检查我们创建的卷,这样做,运行
>>  DockerVolumes docker inspect nodewebapp
[
{
"Id": "602f318d57d5e03b353b15a4c644f90a9918e46590ddff0fb776fa09cf32c51a",
"Created": "2015-12-04T10:17:50.65018429Z",
"Path": "node",
"Args": [
"server.js"
……
"Mounts": [
{
"Name": "cadf05a38efc5c2445f5f7b848c16c3fa2c15e1a036a9b4cad40acc1a9e74371",
"Source": "/var/lib/docker/volumes/cadf05a38efc5c2445f5f7b848c16c3fa2c15e1a036a9b4cad40acc1a9e74371/_data",
"Destination": "/nodewebapp",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""

在安装阵列中,我们有"源"字段,该字段是链接到容器内的"目标"字段内的创建卷的主机中的文件夹。

  • 我们还可以使用卷ID检查创建的Docker卷:
>>  DockerVolumes docker volume inspect cadf05a38efc5c2445f5f7b848c16c3fa2c15e1a036a9b4cad40acc1a9e74371
[
{
"Name": "cadf05a38efc5c2445f5f7b848c16c3fa2c15e1a036a9b4cad40acc1a9e74371",
"Driver": "local",
"Mountpoint": "/var/lib/docker/volumes/cadf05a38efc5c2445f5f7b848c16c3fa2c15e1a036a9b4cad40acc1a9e74371/_data",
"Labels": null,
"Scope": "local"
}
]

说明:

另一种在Docker创建中创建卷的方法是通过将卷添加到dockerfile,如:

VOLUME ["/foo", "/var/bar", "/etc/baz"]

使用主机文件夹作为卷

Docker Volume的最开发人员面向的最佳功能之一是使用主机文件夹作为卷的可能性;通过这样做,例如,开发人员可以将他/她的工作空间绑定到Docker卷并使用该卷运行一个容器,因此工作空间中所做的任何更改都会自动反映在相关卷上,从开发人员常备点中是一个很酷的功能。
所以,让我们尝试一下,我将使用上面创建的Node Web应用程序的文件夹链接到Docker卷。

请注意,我已更改了一点我的dockerfile,以便我的工作目录将Docker卷和包。
json要使用nodemon,以便在任何更改后重新启动节点服务器,现在我的文件看起来像这样:

//Dockerfile
>>  DockerVolumes cat Dockerfile
FROM node:latest
RUN npm i -g nodemon
WORKDIR /nodewebapp
EXPOSE 3000
CMD [ "npm", "run", "dev" ]
//package.json
>>  DockerVolumes cat package.json
{
"name": "DockerVolumes",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev" : "npm i && nodemon server.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"express": "^4.14.0"
}
}

重建图像OniToroad/nodeWebApp并运行容器

>>  DockerVolumes docker run -p 3002:3000 -d --name nodewebapp2 -v /Users/deep/Code/docker-volume/theitroad/DockerVolumes:/nodewebapp theitroad/nodewebapp
9ab92d3b8b585244408da79f9b8b1755e20fa9b32bdfdb147b0fc7ac64d06e0d

并使用CURL尝试节点应用程序,并注意在服务器中进行更改时。
JS例如在"/"端点中更改日志消息将自动反映:

>>  ~ curl localhost:3002
What's up docker volume!
>>  ~ curl localhost:3002
What's up docker volume update server .js !

说明:

  • 这里要采取的一个注意是,我们需要提供主机目录的绝对路径绑定为卷。
  • 其他事情是,默认情况下,乘法卷在读写模式下安装,可以通过在卷路径之后指定:模式来更改此行为,例如:RO,如下面的只读模式:
>>  DockerVolumes docker run -p 3002:3000 -d --name nodewebapp2 -v /Users/deep/Code/docker-volume/theitroad/DockerVolumes:/nodewebapp:ro theitroad/nodewebapp
9ab92d3b8b585244408da79f9b8b1755e20fa9b32bdfdb147b0fc7ac64d06e0d
  • 第三次要注意的是,我们无法使用dockerfile安装一个主机文件夹,因为任何Docker图像必须是可移植的,所以与任何主机分开。
  • 第四件事,同样,要将主机文件夹安装为Docker卷,我们可以通过提供文件的路径而不是文件夹路径来安装文件。

Docker卷作为容器

作为容器之间的共享/持久性数据的复杂机制,Docker之间的数据提供卷作为容器。

我要从Docker Hub中拿起图像,以将卷作为容器说明,例如让官方Redis镜像。
要使用此镜像的文件夹/rediSdbstore创建名为RedisdB的卷,请运行以下命令,命令末尾的redis表示docker图像的名称:

>>  ~ docker create -v /redisdbstore --name redisDB redis
Unable to find image 'redis:latest' locally
latest: Pulling from library/redis
386a066cd84a: Already exists
769149e3a45c: Pull complete
1f43b3c0854a: Pull complete
70e928127ad8: Pull complete
9ad9c0058d76: Pull complete
bc845722f255: Pull complete
105d1e8cd76a: Pull complete
Digest: sha256:c2ce5403bddabd407c0c63f67566fcab6facef90877de58f05587cdf244a28a8
Status: Downloaded newer image for redis:latest
95f01cea2cd94376de471667fa6e643cb46bf93064de007d92b20a2658ee0134

因此,我们可以使用--from-flumes参数将创建的卷/redisdbstore挂载在另一个容器中:

>>  ~ docker run -d --volumes-from redisDB --name nodeWebAppWithRedisDB1 theitroad/nodewebapp
3ea2f024ede0c106dd2db034534977634011d164f453aa77b11c34fb3f033303

说明:

  • 可以使用几次 - volumes-从使用不同的容器卷
  • 例如,它可以通过将来自父卷的卷作为redisdb安装卷作为redisdb,我们可以使用nodewebappwithedisdb1来创建下面说明的nodewebappwithedisdb2:
>>  ~ docker run -d --name nodeWebAppWithRedisDB2 --volumes-from nodeWebAppWithRedisDB1 theitroad/nodewebapp
06af9b81d5bb65076e643615e933c1088852d6466d488a34bc2247a746eead3b

删除卷

正如我上面提到的那样,卷与容器分开,删除容器不会删除其添加的卷。

使用容器删除卷

删除IT容器中卷的最简单方法是使用-v选项:

>>  ~ docker rm –v container_id

删除其名称/id的卷

>>  ~ docker volume rm –v volume_id

删除悬空卷

如果我们删除容器而不指定Option -v的odery卷最终悬挂到本地磁盘中的悬挂卷,则可以使用以下方式删除它们:

>>  ~ docker volume rm `docker volume ls -q -f dangling=true`