Docker技术入门与实战 第二版-学习笔记-7-数据管理(volume)

时间:2022-10-21 08:28:45

Docker 数据管理

为什么要进行数据管理呢?因为当我们在使用container时,可能会在里面创建一些数据或文件,但是当我们停掉或删除这个容器时,这些数据或文件也会同样被删除,这是我们并不想看见的事情,所以我们要进行数据管理,实现持久化存储

在容器中管理数据主要有两种方式:

  • 数据卷(Data volumes)
  • 数据卷容器(Data volume containers)

一.如果使用的是-v参数的方法指定挂载的数据卷

其实本质都是在运行docker run命令时,使用-v参数将主机的某个目录作为容器的数据卷。使用-v挂载数据卷时有两种情况:

  • 挂载的是本机的某个指定目录到容器的某个目录上(链接的方式)
  • 使用的是docker自己管理的数据卷volume(存放在/var/lib/docker/volumes下)

1.第一种情况比如:

docker run -it -v $(pwd)/hostDirectory:/containerDirectory ubuntu;14.04

这种情况挂载的就是本机的某个目录到了容器的某个目录上

这种情况下需要注意下面的几点内容:

  • 本地的目录必须是全路径,即以/或者~/开头的路径,如~/.bash_history:/.bash_history,否则会被当成第二种情况被处理
  • 如果指定的本地目录在本地不存在时,docker会在本地自动创建该目录
  • 如果指定的容器目录在容器中不存在时,docker会在容器中自动创建该目录
  • 如果指定的容器目录中已经有内容的话,这些内容都会被本地目录中的内容覆盖掉

2.第二种情况就是比如下面的一个例子:

userdeMacBook-Pro:~ user$ docker run -d -P --name web -v /webapp training/webapp python app.py

其并没有指定要连接本地的什么目录,所以docker就会自动创建一个匿名的volume,并将其挂载到容器中的/webapp目录上,从其返回的挂载信息可见:

         "Mounts": [
{
"Type": "volume",
"Name": "2e8085436ec33315c8c034a87097df301e9ce1c04a9a9f5ce007344c6cef3105",
"Source": "/var/lib/docker/volumes/2e8085436ec33315c8c034a87097df301e9ce1c04a9a9f5ce007344c6cef3105/_data",
"Destination": "/webapp",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],

可见其匿名生成了一个2e8085436ec33315c8c034a87097df301e9ce1c04a9a9f5ce007344c6cef3105/_data目录,将其挂载到了容器的/webapp目录上

除了docker自动帮我们创建volume外,我们还可以自己创建并查看相应的信息:

userdeMBP:~ user$ docker volume create myVolume
myVolume
userdeMBP:~ user$ docker volume ls
DRIVER VOLUME NAME
local 6dcce8fa7b5bed65b8bdf8cb91603cfa4e993439ec20e921a6742808b6478637
local 49bfc006ae2ebc343cdf59c0af674d7e16f70466f2e9a186ac34e61deb0cb027
local 71a809c56c488bc15078d7b715ddda461eef698643bec14fe53237e66c12eb62
local 933a418456d65bafb6f77989ea120a2da8dd62c7efccd2828d2e716e3111c530
local myVolume
userdeMBP:~ user$ docker volume inspect myVolume
[
{
"CreatedAt": "2018-12-18T09:23:22Z",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/myVolume/_data",
"Name": "myVolume",
"Options": {},
"Scope": "local"
}
]

然后就能够使用这个数据卷,将其挂载到相应的容器中:

docker run -it -v myVolume:/mydata ubuntu:14.04

需要注意的内容是:

如果volume是空的,容器目录非空,那么docker会将容器目录里面的内容拷贝到volume中

如果volume中已经有内容,不管容器中有没有内容,都会将容器中的内容覆盖

二.使用的是Dockerfile

1.

当然,除了使用-v参数外,还能够在Dockerfile中使用VOLUME挂载数据卷

#Dockerfile
VOLUME /mydata

这样docker也会创建一个匿名的volume,然后将其挂载到相应容器的/mydata目录上,这样,如果/mydata中是有数据的,将会拷贝到匿名volume中

它的效果和docker run -it -v /mydata imageName是一样的

因为Dockerfile的方法每一次运行时都会自动生成一个匿名的volume,如果你想要在不同的容器之间共享数据的话,还是要使用上面自己创建一个myVolume,然后将其挂载的方法:

docker run -it -v myVolume:/mydata ubuntu:14.04

2.

⚠️需要注意的一点:

在Dockerfile的VOLUME指令后面是不能对该volume进行任何更改的,比如:

FROM debian:wheezy
RUN useradd foo
VOLUME /data
RUN touch /data/x //生成新文件夹
RUN chown -R foo:foo /data //更改权限

上面执行的结果与你预期是不符的,我们本来希望touch命令在镜像的文件系统上运行,但是实际上它是在一个临时容器的Volume上运行,所以应该做的是:

FROM debian:wheezy
RUN useradd foo
RUN mkdir /data && touch /data/x
RUN chown -R foo:foo /data
VOLUME /data

3.当我们的镜像是通过Dockerfile生成的,如果在Dockerfile中使用的本地目录下的代码需要更改时,为了不用每次更改都要重新运行build去生成一个新的镜像,方法就是将将代码所在的相应目录挂在到数据卷上,比如:

COPY . /mydata  #把当前的目录拷贝到 skeleton
WORKDIR /mydata

解决办法就是运行镜像时,写成:

docker run -d -p : -v $(pwd):/mydata ubuntu:14.04

使用-v $(pwd):/mydata,这样$(pwd)中的数据就会与容器/mydata中的数据同步,这样修改时,会自动刷新数据

下面是比较详细的讲解

1) 数据卷

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

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

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

创建一个数据卷

在用 docker run命令的时候,使用 -v 标记来创建一个数据卷并挂载到容器里。

在一次 run 中多次使用可以挂载多个数据卷。

userdeMacBook-Pro:~ user$ docker run -d -P --name web -v /webapp training/webapp python app.py
Unable to find image 'training/webapp:latest' locally
latest: Pulling from training/webapp
e190868d63f8: Pull complete
909cd34c6fd7: Pull complete
0b9bfabab7c1: Pull complete
a3ed95caeb02: Pull complete
10bbbc0fc0ff: Pull complete
fca59b508e9f: Pull complete
e7ae2541b15b: Pull complete
9dd97ef58ce9: Pull complete
a4c1b0cb7af7: Pull complete
Digest: sha256:06e9c1983bd6d5db5fba376ccd63bfa529e8d02f23d5079b8f74a616308fb11d
Status: Downloaded newer image for training/webapp:latest
1ad71e9d38081c38dcd355fd7a438cd9f94503e8bc28e99a48c0738b51e7efef

注意:也可以在 Dockerfile 中使用 VOLUME来添加一个或者多个新的卷到由该镜 像创建的任意容器。

删除数据卷

数据卷是被设计用来持久化数据的,它的生命周期独立于容器,Docker不会在容器 被删除后自动删除数据卷,并且也不存在垃圾回收这样的机制来处理没有任何容器引用的数据卷。

如果需要在删除容器的同时移除数据卷。可以在删除容器的时候使用 docker rm -v 这个命令。

挂载一个主机目录作为数据卷

使用 -v 标记也可以指定挂载一个本地主机的目录到容器中去

docker run -d -P --name web -v /src/webapp:/opt/webapp training/webapp python app.py

上面的命令加载主机的 /src/webapp目录到容器的 /opt/webapp目录。

这个功能在进行测试的时候十分方便,比如用户可以放置一些程序到本地目录/src/webapp中,来查看容器是否正常工作。

本地目录的路径必须是绝对路径,如果目录不存在 Docker 会自动为你创建它。

⚠️Dockerfile 中不支持这种用法,这是因为 Dockerfile 是为了移植和分享用 的。然而,不同操作系统的路径格式不一样,所以目前还不能支持。

Docker 挂载数据卷的默认权限是读写,用户也可以通过 :ro 指定为只读。

docker run -d -P --name web -v /src/webapp:/opt/webapp:ro training/webapp python app.py

查看数据卷的具体信息

查看的是上面运行的docker run -d -P --name web -v /webapp training/webapp python app.py命令生成的volume

userdeMacBook-Pro:~ user$ docker inspect web
[
{
"Id": "1ad71e9d38081c38dcd355fd7a438cd9f94503e8bc28e99a48c0738b51e7efef",
"Created": "2018-12-15T09:34:23.600548467Z",
"Path": "python",
"Args": [
"app.py"
], ... "Mounts": [
{
"Type": "volume",
"Name": "2e8085436ec33315c8c034a87097df301e9ce1c04a9a9f5ce007344c6cef3105",
"Source": "/var/lib/docker/volumes/2e8085436ec33315c8c034a87097df301e9ce1c04a9a9f5ce007344c6cef3105/_data",
"Destination": "/webapp",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
], ...

在输出的内容中找到其中和数据卷相关的部分,可以看到所有的数据卷都是创建在主机的 /var/lib/docker/volumes/下面的

挂载一个本地主机文件作为数据卷——不推荐

-v 标记也可以从主机挂载单个文件到容器中:

docker run --rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash
这样就可以记录在容器输入过的命令了

⚠️如果直接挂载一个文件,很多文件编辑工具,包括 vi 或者sed --in-place ,可能会造成文件 inode 的改变,从 Docker 1.1 .0起,这会导致报错误信息。

所以最简单的办法就直接挂载文件的父目录。

2) 数据卷容器——实现持续更新数据在容器间共享

数据卷容器,其实就是一个正常的容器,专门用来提供数据卷供其它容器挂载的。

首先,创建一个名为 dbdata 的数据卷容器:

docker run -d -v /dbdata --name dbdata training/postgres echo Data-only container for postgres

然后其他的容器就能够使用--volumes-from来挂载dbdata容器中的数据卷/dbdata :

$docker run -d --volumes-from dbdata --name db1 training/postgres
$docker run -d --volumes-from dbdata --name db2 training/postgres

一个容器可以使用超过一个的 --volumes-from参数来指定从多个容器挂载不同的数据卷

也可以挂载其他已经挂载了数据卷容器的容器来实现级联挂载数据卷:

docker run -d --name db3 --volumes-from db1 training/postgres

⚠️:使用--volumes-from参数所挂载数据卷的容器自己不需要保持在运行状态

如果删除了挂载的容器(包括 dbdata、db1 和 db2),数据卷并不会被自动删除。

所以如果想要删除一个数据卷,必须在删除最后一个还挂载着它的容器时使用docker rm -v命令来指定同时要删除的数据卷

3)利用数据卷容器来备份、恢复、迁移数据卷

备份

首先使用 --volumes-from标记来创建一个加载 dbdata 容器卷的容器,并从主机挂载当前目录到容器的 /backup 目录,如:

docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata

容器启动后,使用了 tar命令来将 /dbdata 卷备份为容器中的/backup/backup.tar 文件,同时也就会在主机当前目录下生成名为 backup.tar的文件。

恢复

如果要恢复数据到一个容器,首先创建一个带有空数据卷的容器 dbdata2:

docker run -v /dbdata --name dbdata2 ubuntu /bin/bash

然后创建另一个容器busybox,挂载 dbdata2 容器卷中的数据卷,也指定将数据卷中的内容挂载到容器中的/backup下,这样该容器的/backup下就有了backup.tar文件,然后使用untar解压备份文件/backup/backup.tar到挂载的容器卷中:

docker run --volumes-from dbdata2 -v $(pwd):/backup busybox tar xvf /backup/backup.tar

为了查看/验证恢复的数据,可以再启动一个容器busybox挂载同样的容器卷,然后运行ls /dbdata来查看:

docker run --volumes-from dbdata2 busybox /bin/ls /dbdata

4)学习docker volume命令的使用

1> 首先查看该命令的使用方式

userdeMBP:~ user$ 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 all unused local volumes 移除所有现在并没有在使用的数据卷
rm Remove one or more volumes 移除指定的一个或多个数据卷 Run 'docker volume COMMAND --help' for more information on a command.

2> 列举查看本地现有的volume

userdeMBP:~ user$ docker volume ls //查看之前生成的数据卷,都是匿名数据卷
DRIVER VOLUME NAME
local 2e8085436ec33315c8c034a87097df301e9ce1c04a9a9f5ce007344c6cef3105
local 4f059cc319550b606b40d1198866fcc8822267a9d6631c8f44a24619d4fe312e
local 6dcce8fa7b5bed65b8bdf8cb91603cfa4e993439ec20e921a6742808b6478637
local 49bfc006ae2ebc343cdf59c0af674d7e16f70466f2e9a186ac34e61deb0cb027
local 71a809c56c488bc15078d7b715ddda461eef698643bec14fe53237e66c12eb62
local 933a418456d65bafb6f77989ea120a2da8dd62c7efccd2828d2e716e3111c530
local a49c6e5e7497f3d1bfcb11159a5144030e03fd7cba21e3bd6ac9b12cc6e8ea76

3> 详细查看其中某一个volume的信息:

userdeMBP:~ user$ docker volume inspect 2e8085436ec33315c8c034a87097df301e9ce1c04a9a9f5ce007344c6cef3105 //详细查看其中某一个数据卷的信息
[
{
"CreatedAt": "2018-12-15T09:34:23Z",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/2e8085436ec33315c8c034a87097df301e9ce1c04a9a9f5ce007344c6cef3105/_data",
"Name": "2e8085436ec33315c8c034a87097df301e9ce1c04a9a9f5ce007344c6cef3105",
"Options": null,
"Scope": "local"
}
]

4> 将其中不在使用的本地数据卷给删除

userdeMBP:~ user$ 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: //这是被删除掉的数据卷
a49c6e5e7497f3d1bfcb11159a5144030e03fd7cba21e3bd6ac9b12cc6e8ea76
2e8085436ec33315c8c034a87097df301e9ce1c04a9a9f5ce007344c6cef3105
4f059cc319550b606b40d1198866fcc8822267a9d6631c8f44a24619d4fe312e Total reclaimed space: .23kB
userdeMBP:~ user$ docker volume ls //这些是还剩下的数据卷
DRIVER VOLUME NAME
local 6dcce8fa7b5bed65b8bdf8cb91603cfa4e993439ec20e921a6742808b6478637
local 49bfc006ae2ebc343cdf59c0af674d7e16f70466f2e9a186ac34e61deb0cb027
local 71a809c56c488bc15078d7b715ddda461eef698643bec14fe53237e66c12eb62
local 933a418456d65bafb6f77989ea120a2da8dd62c7efccd2828d2e716e3111c530

5>自己手动创建一个非匿名的volume

userdeMBP:~ user$ docker volume create myVolume 然后可以创建一个非匿名的数据卷myVolume
myVolume
userdeMBP:~ user$ docker volume ls
DRIVER VOLUME NAME
local 6dcce8fa7b5bed65b8bdf8cb91603cfa4e993439ec20e921a6742808b6478637
local 49bfc006ae2ebc343cdf59c0af674d7e16f70466f2e9a186ac34e61deb0cb027
local 71a809c56c488bc15078d7b715ddda461eef698643bec14fe53237e66c12eb62
local 933a418456d65bafb6f77989ea120a2da8dd62c7efccd2828d2e716e3111c530
local myVolume
userdeMBP:~ user$ docker volume inspect myVolume
[
{
"CreatedAt": "2018-12-18T09:23:22Z",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/myVolume/_data",
"Name": "myVolume",
"Options": {},
"Scope": "local"
}
]

6)删除容器

userdeMBP:~ user$ docker volume inspect 6dcce8fa7b5bed65b8bdf8cb91603cfa4e993439ec20e921a6742808b6478637
[
{
"CreatedAt": "2018-12-15T07:28:50Z",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/6dcce8fa7b5bed65b8bdf8cb91603cfa4e993439ec20e921a6742808b6478637/_data",
"Name": "6dcce8fa7b5bed65b8bdf8cb91603cfa4e993439ec20e921a6742808b6478637",
"Options": null,
"Scope": "local"
}
]
userdeMBP:~ user$ docker volume rm 6dcce8fa7b5bed65b8bdf8cb91603cfa4e993439ec20e921a6742808b6478637
Error response from daemon: remove 6dcce8fa7b5bed65b8bdf8cb91603cfa4e993439ec20e921a6742808b6478637: volume is in use - [b4a512f0230fa598e7e40171e0597ea6db0740105449314a1a3767dcaa4a0edb]
userdeMBP:~ user$ docker inspect b4a512f0230fa598e7e40171e0597ea6db0740105449314a1a3767dcaa4a0edb //该容器正在运行,所以其挂载的数据卷是不能被删除的
[
{
"Id": "b4a512f0230fa598e7e40171e0597ea6db0740105449314a1a3767dcaa4a0edb",
"Created": "2018-12-15T07:28:26.800359991Z",
"Path": "/entrypoint.sh",
"Args": [
"/etc/docker/registry/config.yml"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": ,
"ExitCode": ,
"Error": "",
... userdeMBP:~ user$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2084e92eea8c ubuntu:14.04 "/bin/bash" hours ago Up hours boring_jackson
b4a512f0230f registry "/entrypoint.sh /etc…" days ago Up hours 0.0.0.0:->/tcp registry userdeMBP:~ user$ docker volume rm myVolume //然后删除一个没有使用的数据卷就成功了
myVolume

5)现在我们进行一个例子小实验:

1> 首先创建一个mysql1容器,生成mysql数据卷挂载在该容器的/var/lib/mysql目录上

userdeMBP:~ user$ docker run -d -v mysql:/var/lib/mysql --name mysql1 -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql
Unable to find image 'mysql:latest' locally
latest: Pulling from library/mysql
a5a6f2f73cd8: Already exists
936836019e67: Pull complete
283fa4c95fb4: Pull complete
1f212fb371f9: Pull complete
e2ae0d063e89: Pull complete
5ed0ae805b65: Pull complete
0283dc49ef4e: Pull complete
a7e1170b4fdb: Pull complete
88918a9e4742: Pull complete
241282fa67c2: Pull complete
b0fecf619210: Pull complete
bebf9f901dcc: Pull complete
Digest: sha256:b7f7479f0a2e7a3f4ce008329572f3497075dc000d8b89bac3134b0fb0288de8
Status: Downloaded newer image for mysql:latest
71f78959d2a823e55a723cde747ee833f52138bf04f0f8ec33189ea902bb2356

2>查看生成的mysql数据卷

userdeMBP:~ user$ docker volume ls //现在可见生成了一个mysql数据卷
DRIVER VOLUME NAME
local 6dcce8fa7b5bed65b8bdf8cb91603cfa4e993439ec20e921a6742808b6478637
local 49bfc006ae2ebc343cdf59c0af674d7e16f70466f2e9a186ac34e61deb0cb027
local 71a809c56c488bc15078d7b715ddda461eef698643bec14fe53237e66c12eb62
local 933a418456d65bafb6f77989ea120a2da8dd62c7efccd2828d2e716e3111c530
local mysql
userdeMBP:~ user$ docker volume inspect mysql //查看该数据卷的详细内容
[
{
"CreatedAt": "2018-12-18T10:21:16Z",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/mysql/_data",
"Name": "mysql",
"Options": null,
"Scope": "local"
}
]

3> 然后对朝该数据卷中写入数据

userdeMBP:~ user$ docker exec -it mysql1 /bin/bash
root@71f78959d2a8:/# mysql -u root
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is
Server version: 8.0. MySQL Community Server - GPL Copyright (c) , , Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
rows in set (0.00 sec) mysql> create database docker; //生成一个新的数据库
Query OK, row affected (0.08 sec) mysql> show databases;
+--------------------+
| Database |
+--------------------+
| docker |
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
rows in set (0.01 sec) mysql> exit
Bye
root@71f78959d2a8:/# exit
exit
userdeMBP:~ user$ docker rm -f mysql1 //然后移除mysql1这个容器
mysql1

4> 然后重新打开一个mysql2容器,挂载之前生成的mysql数据卷,以验证数据是否成功共享:

userdeMBP:~ user$ docker run -d -v mysql:/var/lib/mysql --name mysql2 -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql
6f242e6fc8341f2b809f2d54bef294e718658a3db8c595dfc84955b5b4b0f7a8 userdeMBP:~ user$ docker exec -it mysql2 /bin/bash
root@6f242e6fc834:/# mysql -u root
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is
Server version: 8.0. MySQL Community Server - GPL Copyright (c) , , Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show databases; //然后查看数据库,是可以看见之前在容器mysql1上生成的docker数据库的,可见数据成功共享了
+--------------------+
| Database |
+--------------------+
| docker |
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
rows in set (0.01 sec) mysql>

Docker技术入门与实战 第二版-学习笔记-7-数据管理(volume)的更多相关文章

  1. Docker技术入门与实战 第二版-学习笔记-10-Docker Machine 项目-2-driver

    1>使用的driver 1〉generic 使用带有SSH的现有VM/主机创建机器. 如果你使用的是机器不直接支持的provider,或者希望导入现有主机以允许Docker Machine进行管 ...

  2. Docker技术入门与实战 第二版-学习笔记-8-网络功能network-3-容器访问控制和自定义网桥

    1)容器访问控制 容器的访问控制,主要通过 Linux 上的 iptables防火墙来进行管理和实现. iptables是 Linux 上默认的防火墙软件,在大部分发行版中都自带. 容器访问外部网络 ...

  3. Docker技术入门与实战 第二版-学习笔记-10-Docker Machine 项目-1-cli

    Docker Machine 是 Docker 官方编排(Orchestration)项目之一,负责在多种平台上快速安装 Docker 环境 Docker Machine是一种工具,它允许你在虚拟主机 ...

  4. Docker技术入门与实战 第二版-学习笔记-5-容器-命令及限制内存与cpu资源

    1.启动容器 启动容器有两种方式: 基于镜像新建一个容器并启动 将在终止状态(stopped)的容器重新启动 1)新建并启动——docker run 比如在启动ubuntu:14.04容器,并输出“H ...

  5. Docker技术入门与实战 第二版-学习笔记-3-Dockerfile 指令详解

    前面已经讲解了FROM.RUN指令,还提及了COPY.ADD,接下来学习其他的指令 5.Dockerfile 指令详解 1> COPY 复制文件 格式: COPY  <源路径> .. ...

  6. Docker技术入门与实战 第二版-学习笔记-8-网络功能network-1-单个host上的容器网络

    Docker 中的网络功能介绍 Docker 允许通过外部访问容器或容器互联的方式来提供网络服务 1) 外部访问容器 容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -p或 -P参数 ...

  7. Docker技术入门与实战 第二版-学习笔记-6-仓库

    仓库(Repository)是集中存放镜像的地方 一个容易混淆的概念是注册服务器(Registry). 实际上注册服务器是管理仓库的具体服务器,每个服务器上可以有多个仓库,而每个仓库下面有多个镜像. ...

  8. Docker技术入门与实战 第二版-学习笔记-2-镜像构建

    3.利用 commit 理解镜像构成 在之前的例子中,我们所使用的都是来自于 Docker Hub 的镜像. 直接使用这些镜像是可以满足一定的需求,而当这些镜像无法直接满足需求时,我们就需要定制这些镜 ...

  9. Docker技术入门与实战 第二版-学习笔记-10-Docker Machine 项目-3-Command-line completion命令补全

    Command-line completion https://docs.docker.com/machine/completion/ Installing Command Completion——实 ...

随机推荐

  1. Linq查询

    //Linq查询 List<A1> a1 = new List<A1>(); a1.Add(, Name = , Gender = true }); a1.Add(, Name ...

  2. &lbrack;Jobdu&rsqb; 题目1497:面积最大的全1子矩阵

    题目描述: 在一个M * N的矩阵中,所有的元素只有0和1,从这个矩阵中找出一个面积最大的全1子矩阵,所谓最大是指元素1的个数最多. 输入: 输入可能包含多个测试样例.对于每个测试案例,输入的第一行是 ...

  3. Unix文件 I&sol;O&lpar;不带缓冲区的&rpar;上

    简介 Unix系统大多数文件i/o只需要:open.read.write.lseek.close这几个函数.但是某些时候我们也需要fcntl.ioctl.sync等函数配合使用.这些函数都是不带缓冲区 ...

  4. Android IPC机制全解析&lt&semi;二&gt&semi;

    在AIDL文件中并不是所有的数据类型都可以使用,AIDL支持的数据类型如下: 基本数据类型(int.long.char.boolean.double等) String和CharSequence Lis ...

  5. python虚拟环境virtualenv简介

    参考网站: https://realpython.com/python-virtual-environments-a-primer/ 一. 创建一个新的虚拟环境 # Python 2: $ virtu ...

  6. table中强制不换行

    总是一些文章说要强制换行,很少提到说如何不换行. 一般都会使用word-break: keep-all;使得强制不换行. HTML <!DOCTYPE html PUBLIC "-// ...

  7. ios开发 ad hoc怎么用

    简单的说就是这样 ad hoc 方式是苹果用来给未上线的app做测试用的,首先你要在苹果开发平台上申请一个ad hoc的证书,再在profile中生成一个ad hoc 的profile文件(只需要在生 ...

  8. HDFS入门

    HDFS入门 欢迎关注我的个人博客:http://www.cnblogs.com/yjd_hycf_space 更多大数据以及编程相关的精彩文章 为什么我们需要HDFS 文件系统由三部分组成:与文件管 ...

  9. Linux系统——公网定制化yum仓库部署

    1)搭建公网源yum仓库 安装wget aliyun源 # wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel ...

  10. Fragment 简介 基础知识 总结 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...