Linux

Docker应用详细解析(二) —— 在macOS上使用Dock

2018-11-17  本文已影响43人  刀客传奇

版本记录

版本号 时间
V1.0 2018.11.17 星期六

前言

Docker是一个跨平台的轻量级虚拟机,可移植性非常高,一次部署,终生可用。Docker可以在Linux、Windows、MacOS等平台上安装使用。接下来几篇我们就一起看一下Docker相关的内容。感兴趣的可以看下面几篇文章。
1. Docker应用详细解析(一) —— 在macOS上使用Docker(一)

Mounting Volumes: Sharing Host & Container Files

您经常希望在主机和容器之间共享文件或目录。 停止和删除容器时,数据库中的数据不应消失。 在不同版本的应用程序或运行相同数据库应用程序的不同容器之间共享数据库也很方便。 当您在容器中运行时,您可能希望将配置文件提供给数据库应用程序或将数据提供给机器学习应用程序。 您将在本节中学习如何执行这些操作。

1. Persisting Databases After the Container Exits - 容器退出后保留数据库

要将数据库存储在本地主机系统上,使其保持不变并且可以被其他容器访问,您将在启动CouchDB容器时在Docker的存储目录中创建一个卷。

Docker run终端窗口中,输入以下命令:

docker run --mount source=couchdbVolume,target=/opt/couchdb/data --network emoji-net -d --name couchdb couchdb

注意:在--mount值中,不要在=符号周围或逗号后面添加空格。

第一次运行此命令时,它会在主机系统上的Docker存储目录中创建couchdbVolume,然后将容器的/ opt / couchdb / data目录的内容复制到couchdbVolume中。 然后容器安装并使用couchdbVolume来存储其数据库。

在您的EmojiJournalServer终端窗口中,在同一网络上启动EmojiJournalServer容器:

docker run --network emoji-net --name emojijournal -it -p 8090:8080 -v $PWD:/root/project -w /root/project emojijournal-run sh -c .build-ubuntu/release/EmojiJournalServer

刷新或打开localhost:8090 / client,添加表情符号,然后 - 在Docker cleanup终端窗口中 - 停止并删除两个容器:

docker rm $(docker stop $(docker ps -q))

即使您已删除创建它的CouchDB容器,该卷仍然存在。 要查看此信息,请输入以下命令:

docker volume inspect couchdbVolume

输出如下:

[
  {
    "CreatedAt": "2018-10-26T08:00:59Z",
    "Driver": "local",
    "Labels": null,
    "Mountpoint": "/var/lib/docker/volumes/couchdbVolume/_data",
    "Name": "couchdbVolume",
    "Options": null,
    "Scope": "local"
  }
]

使用Finder ▸ Go ▸ Go to Folder…菜单项以查看mountpoint目录......好吧,您可以尝试查看它 - 它不在那里! Docker的存储目录实际上存在于Docker引擎中并由其管理。 您不打算直接在主机文件系统上访问它。 您只能通过将其安装在Docker容器中来访问它。

现在,为了证明在删除CouchDB容器后表情符号数据库仍然存在:在Docker run终端窗口中重新运行CouchDB命令,在EmojiJournalServer终端窗口中运行EmojiJournalServer命令,然后刷新localhost:8090 / client - 这次,你不会丢失你的表情符号!

因为couchdbVolume已经存在,所以CouchDB容器刚刚安装它,将已经存储在那里的数据库暴露给EmojiJournalServer容器,该容器找到并加载了由前一个EmojiJournalServer容器创建的日志条目数据库。

Clean up:停止并取出容器。 关闭浏览器窗口。 删除所有未使用的网络

docker network prune

2. Sharing a Database With Another Docker Container - 与另一个Docker容器共享数据库

您为在emoji-net网络上运行的CouchDB创建了一个卷。 您已停止并删除了CouchDB容器,但卷仍然存在。 您可以将此卷重用于在默认网络上运行的CouchDB容器,从而有效地与另一个容器共享其数据库。

为了演示这一点,请将couchdbVolume安装在默认桥接网络上运行的CouchDB容器中,以便主机上的EmojiJournalServer可以访问已保存的日记条目数据库。

在默认桥接网络上启动CouchDB容器,安装couchdbVolume并发布其端口:

docker run --mount source=couchdbVolume,target=/opt/couchdb/data -p 5984:5984 -d --name couchdb couchdb

在您的EmojiJournalServer终端窗口中,在主机系统上运行EmojiJournalServer

.build/debug/EmojiJournalServer

在您的主机系统上运行的EmojiJournalServercouchdbVolume中查找并加载日记条目数据库,因此当您加载localhost:8080 / client时,您会看到来自EmojiJournalServer容器的表情符号:

在您的EmojiJournalServer终端窗口中,按Control-C停止此EmojiJournalServer。 关闭浏览器窗口。

停止并删除CouchDB容器,然后输入此命令以删除所有未使用的卷:

docker volume prune

3. Providing Local Files to a Docker Container - 将本地文件提供给Docker容器

在容器中运行EmojiJournalServer的命令具有-v $ PWD:/ root / project选项,该选项将EmojiJournalServer目录安装为容器中的/ root / project。 本节演示对主机文件的更改会影响容器的文件,反之亦然。

在您的EmojiJournalServer终端窗口中,在后台启动EmojiJournalServer容器:

docker run --name emojijournal -itd -p 8090:8080 -v $PWD:/root/project -w /root/project emojijournal-run sh -c .build-ubuntu/release/EmojiJournalServer

然后输入以下命令:

docker exec -it emojijournal bash

此命令创建运行bash Unix shell的交互式终端会话。 你得到一个以〜/ project#结尾的命令行提示符。 在此提示符下,输入此命令以查看容器的project目录:

ls -l

输出列出与Finder中的EmojiJournalServer文件夹相同的文件:

使用您喜欢的文本编辑器在此文件夹中创建一个新文件 - 例如,包含文本I was herekilroy.txt。在〜/ project#提示符下,再次输入ls -l,以查看您的新文件容器。 在〜/ project#提示符下输入以下命令:

rm kilroy.txt

在Finder中,文件消失。 这就是将本地目录连接到容器是多么容易 - 一个地方的变化会影响另一个!

Cleanup:停止并移除容器。

4. Choosing Between Volume & Bind Mount

您现在已经看到了两种在容器中挂载主机目录的方法:couchdbVolume是一个volume,而EmojiJournalServer目录是一个bind mount。卷和绑定装载之间的主要区别在于它位于主机文件系统上,以及是否可以通过主机文件系统直接访问它。

您将本地系统上的特定路径(如EmojiJournalServer文件夹)bind-mount到容器中的特定路径- / root / project。您可以直接与本地目录进行交互,更改将显示在容器中。同样,容器所做的更改也会显示在Finder中。

您可以通过在docker rundocker volume create命令中指定名称(如couchdbVolume)来创建volume。该卷位于Docker的存储目录中,位于本地系统的Docker引擎中。您无法直接与此目录的内容进行交互。您可以将其安装到容器中,然后可以检查其元数据或将其删除。 Docker管理卷中的读写文件。

另一个很大的区别是当您公开现有容器目录时会发生什么。

如果将本地目录绑定到现有容器目录,则本地目录中的内容会模糊容器目录的内容 - 如果将本地couchdb-config目录绑定到CouchDB容器的local.d目录,则会发生这种情况。您有效地覆盖容器目录。别担心,原始目录仍然是只读镜像!

如果将容器目录公开为volume,则会将其内容复制到主机上的卷中。当您使用CouchDB容器的/ opt / couchdb / data目录作为目标创建couchdbVolume时,会发生这种情况。

5. --mount or --volume?

您还可以使用两个不同的选项来装入卷或绑定装载本地目录。 他们做同样的事情 - 他们只是使用不同的语法。

--mount选项比--volume更新。 它使用逗号分隔的key=value对,键的顺序无关紧要。 此选项没有速记版本。

--volume标志,简写-v,有三个冒号分隔的字段:顺序很重要,但你必须记住或查找每个字段的含义。

Docker文档建议使用--mount选项而不是-v选项:它更详细,但这使得理解和记忆更容易。

以下两个命令是等效的 - 它们将当前本地目录bind-mount安装到容器中的新/ home目录:

docker run --mount type=bind,source=/`pwd`,target=/home ibmcom/kitura-ubuntu
docker run -v $PWD:/home ibmcom/kitura-ubuntu

以下两个命令是等效的 - 它们在Docker的存储目录中创建一个卷:

docker run --mount source=KituraVolume,target=/Kitura-Starter ibmcom/kitura-ubuntu

注意:type=volume是默认的。

docker run -v KituraVolume:/Kitura-Starter ibmcom/kitura-ubuntu

注意:-v选项的第一个字段是名称,而不是路径,因此Docker创建卷,而不是bind mount.

两个命令都将/ Kitura-Starter的内容复制到名为KituraVolume的卷中。 然后Kitura容器安装并使用KituraVolume。 您可以将KituraVolume安装在其他容器中,以便他们访问其内容。

您可以指定read-only访问权限:

docker run --mount source=KituraVolume,target=/Kitura-Starter,readonly --name kitura ibmcom/kitura-ubuntu
docker run -v KituraVolume:/Kitura-Starter:ro --name kitura ibmcom/kitura-ubuntu

这是来自Docker文档的--mount--volume的行为之间的另一个区别:

请注意,如果使用-v将主机上不存在的目录绑定安装到容器中存在的目录,则会将其创建为主机上的空目录,因此其空白会遮盖原始目录容器中的内容。 例如,如果您尝试使用-v $ PWD / kitura-dir:Kitura-StarterKitura-Starter目录从容器复制到本地文件系统,那么您所获得的只是文件系统中的空目录容器。

6. Copying Files Between Host & Container - 在主机和容器之间复制文件

如果您只想将正在运行的Docker容器中的文件或目录保存到本地系统,则可以复制它:

docker cp kitura:/Kitura-Starter . 

您还可以将文件或目录从本地系统复制到容器:

docker cp kilroy.txt kitura:/var/tmp 

Summary of Docker Commands - Docker命令总结

你在本教程中看到了很多Docker命令! 以下是它们的列表。 方括号中的术语(如[image])是特定名称或ID的占位符。

docker run命令:

docker run [options] [image] [command for -it options]

您在本教程中使用的docker run选项:

- --detach / -d
- --env / -e [ENV_VAR=value] 
- --interactive --tty / -it ... [command]
- --name [name]
- --network [network]
- --mount source=[volume],target=[container-dir]
- --publish / -p [host port]:[container port]
- --volume / -v [host-dir]:[container-dir]

您在本教程中使用的其他Docker命令(加上一两个您没见过的相关命令):

- docker pull [image]
- docker images or docker image ls
- docker ps -a or docker container ls -a
- docker ps -a -q -f [filter condition]
- docker exec -it [container] bash
- docker stop [container]
- docker start [container]
- docker rm $(docker ps -a -q -f status=exited)
- docker rm $(docker stop $(docker ps -q))
- docker rm [container IDs or names] 
- docker rmi [image] or docker image rm [image]
- docker container inspect [container]
- docker network create [network-name]
- docker network inspect [network-name]
- docker network ls
- docker network prune
- docker volume create [volume-name]
- docker volume inspect [volume-name]
- docker volume ls
- docker volume prune
- docker cp [container:container-path] [host-path]
- docker cp [host-path] [container:container-path] 

一些有用的方法来分离在前台运行的容器:

本教程向您介绍了Docker的一小部分功能和可能性。 它没有涉及创建自己的Docker镜像,组成Docker服务,使用Docker for CI / CD,集群和使用Docker Swarm调度容器等等。 希望本教程为您探索Docker世界提供了坚实的基础。 以下是一些可以帮助您的资源:

后记

本篇主要讲述了在macOS上使用Docker,感兴趣的给个赞或者关注~~~

上一篇下一篇

猜你喜欢

热点阅读