想要改进这个备忘单吗?参见[贡献](#贡献)部分!
目录
- [为何选择Docker](#why-docker)
- [先决条件](#先决条件)
- [安装](#装置)
- [容器](#容器)
- [图片](#images)
- [网络](#networks)
- [注册表和存储库](#register - repository)
- [Dockerfile](#dockerfile)
- [图层](#层)
- [链接](#links)
- [卷](#卷)
- [公开端口](#exposing-ports)
- [最佳实践](#best-practices)
- [安全](#security)
- [提示](#tips)
- [贡献](#贡献)
为何选择Docker
“使用Docker,开发人员可以使用任何工具链以任何语言构建任何应用程序。”Dockerized“应用程序完全可移植,可以在任何地方运行 - 同事的OS X和Windows笔记本电脑,在云中运行Ubuntu的QA服务器以及运行的生产数据中心VM红帽。
开发人员可以从Docker Hub上提供的13,000多个应用程序之一开始快速上手。Docker管理和跟踪变更和依赖关系,使系统管理员更容易理解开发人员构建的应用程序是如何工作的。使用Docker Hub,开发人员可以通过公共或私有存储库自动化他们的构建管道并与协作者共享工件。
Docker可以帮助开发人员更快地构建和发布更高质量的应用程序。“ - [什么是Docker](https://www.docker.com/what-docker#copy1)
先决条件
我在[Docker插件]中使用[Oh My Zsh](https://github.com/robbyrussell/oh-my-zsh)(https://github.com/robbyrussell/oh-my-zsh/wiki/Plugins #docker)用于自动完成docker命令。因人而异。
Linux
3.10.x内核是Docker的[最低要求](https://docs.docker.com/engine/installation/binaries/#check-kernel-dependencies)。
苹果系统
10.8“Mountain Lion”或更新版本是必需的。
安装
Linux
Docker提供的快速简便的安装脚本:
curl -sSL https://get.docker.com/ | sh
如果您不愿意运行随机shell脚本,请参阅[安装](https://docs.docker.com/engine/installation/linux/)分发说明。
如果您是一个完整的Docker新手,那么现在应该按照[系列教程](https://docs.docker.com/engine/getstarted/)进行操作。
苹果系统
下载并安装[Docker Community Edition](https://www.docker.com/community-edition)。如果你有Homebrew-Cask,只需输入brew cask install docker
即可。或者下载并安装[Docker Toolbox](https://docs.docker.com/toolbox/overview/)。[Docker For Mac](https://docs.docker.com/docker-for-mac/)很不错,但它还不如VirtualBox安装完成。[参见比较](https://docs.docker.com/docker-for-mac/docker-toolbox/)。
注意 Docker Toolbox是传统的。您应该使用Docker Community Edition,请参阅(Docker Toolbox)[https://docs.docker.com/toolbox/overview/]
安装Docker Community Edition后,单击Launchpad中的docker图标。然后启动一个容器:
docker run hello-world
就是这样,你有一个正在运行的Docker容器。
如果你是一个完整的Docker新手,你现在应该遵循[系列教程](https://docs.docker.com/engine/getstarted/)。
容器
[您基本的孤立Docker过程](http://etherealmind.com/basics-docker-containers-hypervisors-coreos/)。容器是虚拟机,因为线程是进程的。或者你可以把它们想象成类固醇的chroots。
生命周期
- [
docker create
](https://docs.docker.com/engine/reference/commandline/create)创建一个容器,但不启动它。 - [
docker rename
](https://docs.docker.com/engine/reference/commandline/rename/)允许重命名容器。 - [
docker run
](https://docs.docker.com/engine/reference/commandline/run)在一次操作中创建并启动容器。 - [
docker rm
](https://docs.docker.com/engine/reference/commandline/rm)删除容器。 - [
docker update
](https://docs.docker.com/engine/reference/commandline/update/)更新容器的资源限制。
通常,如果你运行一个没有选项的容器,它会立即启动和停止,如果你想让它保持运行你可以使用命令docker run -td container_id
这将使用将分配伪TTY的选项-t
会话和-d
将自动分离容器(在后台和打印容器ID中运行容器)。
如果你想要一个瞬态容器,docker run --rm
将在它停止后删除容器。
如果要将主机上的目录映射到docker容器,docker run -v $ HOSTDIR:$ DOCKERDIR
。另请参阅[Volumes](https://github.com/wsargent/docker-cheat-sheet/#volumes)。
如果要删除与容器关联的卷,则删除容器必须包含``v开关,如
docker rm -v`。
还有一个[日志驱动程序](https://docs.docker.com/engine/admin/logging/overview/)可用于docker 1.10中的各个容器。要使用自定义日志驱动程序(即syslog)运行docker,请使用docker run --log-driver = syslog
。
另一个有用的选项是docker run --name yourname docker_image
,因为当你在run命令中指定--name
时,这将允许你通过使用你在创建它时指定的名称调用容器来启动和停止容器。 。
开始和停止
- [
docker start
](https://docs.docker.com/engine/reference/commandline/start)启动一个容器,使其运行。 - [
docker stop
](https://docs.docker.com/engine/reference/commandline/stop)停止正在运行的容器。 - [
docker restart
](https://docs.docker.com/engine/reference/commandline/restart)停止并启动容器。 - [
docker pause
](https://docs.docker.com/engine/reference/commandline/pause/)暂停正在运行的容器,将其“冻结”到位。 - [
docker unpause
](https://docs.docker.com/engine/reference/commandline/unpause/)将取消暂停正在运行的容器。 - [
docker wait
](https://docs.docker.com/engine/reference/commandline/wait)阻塞,直到运行容器停止。 - [
docker kill
](https://docs.docker.com/engine/reference/commandline/kill)将SIGKILL发送到正在运行的容器。 - [
docker attach
](https://docs.docker.com/engine/reference/commandline/attach)将连接到正在运行的容器。
如果要将容器与[主机进程管理器](https://docs.docker.com/engine/admin/host_integration/)集成,请使用-r = false
启动守护程序,然后使用docker start -a
。
如果要通过主机公开容器端口,请参阅[公开端口](#exposing-ports)部分。
重新启动崩溃的docker实例的策略[在此处](http://container42.com/2014/09/30/docker-restart-policies/)。
CPU约束
您可以使用所有CPU的百分比或使用特定内核来限制CPU。
例如,您可以告诉[cpu-shares
](https://docs.docker.com/engine/reference/run/#/cpu-share-constraint)设置。设置有点奇怪 - 1024表示100%的CPU,因此如果您希望容器占据所有CPU核心的50%,则应指定512.请参阅https://goldmann.pl/blog/2014/09 / 11 /资源管理在docker / #_ cpu更多:
docker run -ti --c 512 agileek/cpuset-test
您也可以使用[cpuset-cpus
](https://docs.docker.com/engine/reference/run/#/cpuset-constraint)来使用某些CPU内核。有关详细信息和一些不错的视频,请参阅https://agileek.github.io/docker/2014/08/06/docker-cpuset/:
docker run -ti --cpuset-cpus=0,4,6 agileek/cpuset-test
请注意,Docker仍然可以**看到容器内的所有CPU - 它只是没有使用所有这些CPU。有关详细信息,请参阅https://github.com/docker/docker/issues/20770。
内存约束
您还可以在Docker上设置[内存约束](https://docs.docker.com/engine/reference/run/#/user-memory-constraints):
docker run -it -m 300M ubuntu:14.04 /bin/bash
能力
可以使用cap-add
和cap-drop
来设置Linux功能。有关详细信息,请参阅https://docs.docker.com/engine/reference/run/#/runtime-privilege-and-linux-capabilities。这应该用于提高安全性。
要安装基于FUSE的文件系统,您需要结合使用--cap-add和--device:
docker run --rm -it --cap-add SYS_ADMIN --device /dev/fuse sshfs
授予访问单个设备的权限:
docker run -it --device=/dev/ttyUSB0 debian bash
授予访问所有设备的权限:
docker run -it --privileged -v /dev/bus/usb:/dev/bus/usb debian bash
有关特权容器的更多信息[这里](
https://docs.docker.com/engine/reference/run/#/runtime-privilege-and-linux-capabilities)
信息
- [
docker ps
](https://docs.docker.com/engine/reference/commandline/ps)显示正在运行的容器。 - [
docker logs
](https://docs.docker.com/engine/reference/commandline/logs)从容器中获取日志。(您可以使用自定义日志驱动程序,但日志仅适用于1.10中的json-file
和journald
)。 - [
docker inspect
](https://docs.docker.com/engine/reference/commandline/inspect)查看容器上的所有信息(包括IP地址)。 - [
docker events
](https://docs.docker.com/engine/reference/commandline/events)从容器中获取事件。 - [
docker port
](https://docs.docker.com/engine/reference/commandline/port)显示面向公众的容器端口。 - [
docker top
](https://docs.docker.com/engine/reference/commandline/top)显示容器中正在运行的进程。 - [
docker stats
](https://docs.docker.com/engine/reference/commandline/stats)显示容器的资源使用情况统计信息。 - [
docker diff
](https://docs.docker.com/engine/reference/commandline/diff)显示容器FS中已更改的文件。
docker ps -a
显示了运行和停止的容器。
docker stats --all
显示了一个正在运行的容器列表。
进出口
- [
docker cp
](https://docs.docker.com/engine/reference/commandline/cp)在容器和本地文件系统之间复制文件或文件夹。 - [
docker export
](https://docs.docker.com/engine/reference/commandline/export)将容器文件系统转换为tarball存档流到STDOUT。
执行命令
- [
docker exec
](https://docs.docker.com/engine/reference/commandline/exec)在容器中执行命令。
要输入正在运行的容器,请将新的shell进程附加到名为foo的正在运行的容器中,使用:docker exec -it foo / bin / bash
。
图片
图像只是[泊坞容器的模板](https://docs.docker.com/engine/understanding-docker/#how-does-a-docker-image-work)。
生命周期
- [
docker images
](https://docs.docker.com/engine/reference/commandline/images)显示所有图像。 - [
docker import
](https://docs.docker.com/engine/reference/commandline/import)从tarball创建图像。 - [
docker build
](https://docs.docker.com/engine/reference/commandline/build)从Dockerfile创建图像。 - [
docker commit
](https://docs.docker.com/engine/reference/commandline/commit)从容器创建图像,如果它正在运行则临时暂停。 - [
docker rmi
](https://docs.docker.com/engine/reference/commandline/rmi)删除图像。 - [
docker load
](https://docs.docker.com/engine/reference/commandline/load)将来自tar档案的图像作为STDIN加载,包括图像和标签(截至0.7)。 - [
docker save
](https://docs.docker.com/engine/reference/commandline/save)将图像保存到STDOUT的tar存档流中,包含所有父图层,标签和版本(截至0.7)。
信息
- [
docker history
](https://docs.docker.com/engine/reference/commandline/history)显示图像历史。 - [
docker tag
](https://docs.docker.com/engine/reference/commandline/tag)将图像标记为名称(本地或注册表)。
检查Docker版本
非常重要的是,您始终可以随时了解当前正在运行的Docker当前版本。这非常有用,因为您可以了解哪些功能与您运行的功能兼容。这一点也很重要,因为您知道在尝试获取模板容器时从docker商店运行的容器。那就说看看如何知道我们目前运行的docker版本
- ['docker version'](https://docs.docker.com/engine/reference/commandline/version/)检查你运行的docker版本
- [泊坞版[OPTIONS]]
获取服务器版本
$ docker version --format'{{。Server.Version}}'
1.8.0
转储原始JSON数据
$ docker version --format'{{json。}}'
{ “客户”:{ “版本”: “1.8.0”, “ApiVersion”: “1.20”, “GitCommit”: “f5bae0a”, “GoVersion”: “go1.4.2”, “OS”: “LINUX”, “拱”:“是”}
打扫干净
虽然您可以使用docker rmi
命令删除特定图像,但有一个名为[docker-gc](https://github.com/spotify/docker-gc)的工具可以安全地清理不再使用的图像任何容器。
加载/保存图像
从文件加载图像:
docker load < my_image.tar.gz
保存现有图片:
docker save my_image:my_tag | gzip > my_image.tar.gz
导入/导出容器
从文件导入容器作为图像:
cat my_container.tar.gz | docker import - my_image:my_tag
导出现有容器:
docker export my_container | gzip > my_container.tar.gz
加载已保存图像和将导出的容器作为图像导入之间的区别
使用load
命令加载图像会创建一个包含其历史记录的新图像。
使用import
命令将容器导入为图像会创建一个新图像,不包括历史记录,与加载图像相比,图像尺寸更小。
Networks
Docker有[网络](https://docs.docker.com/engine/userguide/networking/)功能。关于它的知之甚少,所以这是扩大备忘单的好地方。有一条说明说,这是一种配置docker容器以便在不使用端口的情况下相互通信的好方法。有关详细信息,请参阅[使用网络](https://docs.docker.com/engine/userguide/networking/work-with-networks/)。
生命周期
- [
docker network create
](https://docs.docker.com/engine/reference/commandline/network_create/) - [
docker network rm
](https://docs.docker.com/engine/reference/commandline/network_rm/)
信息
- [
docker network ls
](https://docs.docker.com/engine/reference/commandline/network_ls/) - [
docker network inspect
](https://docs.docker.com/engine/reference/commandline/network_inspect/)
连接
- [
docker network connect
](https://docs.docker.com/engine/reference/commandline/network_connect/) - [
docker network disconnect
](https://docs.docker.com/engine/reference/commandline/network_disconnect/)
您可以指定[容器的特定IP地址](https://blog.jessfraz.com/post/ips-for-all-the-things/):
#使用您的ip块的子网和网关创建一个新的桥接网络
$ docker network create --subnet 203.0.113.0/24 --gateway 203.0.113.254 iptastic
#在该块中运行具有特定ip的nginx容器
$ docker run --rm -it --net iptastic --ip 203.0.113.2 nginx
#从任何其他地方卷曲ip(假设这是一个公共ip块duh)
$ curl 203.0.113.2
Registry and Repository
存储库是托管标记图像集合,它们共同为容器创建文件系统。
注册表是* host * - 存储存储库的服务器,并为[管理存储库的上载和下载]提供HTTP API(https://docs.docker.com/engine/tutorials/dockerrepos/)。
Docker.com将自己的[索引](https://hub.docker.com/)托管到包含大量存储库的中央注册表。话虽如此,中央码头注册表[没有很好地验证图像](https://titanous.com/posts/docker-insecurity),如果你担心安全问题应该避免。
- [
docker login
](https://docs.docker.com/engine/reference/commandline/login)登录注册表。 - [
docker logout
](https://docs.docker.com/engine/reference/commandline/logout)从注册表注销。 - [
docker search
](https://docs.docker.com/engine/reference/commandline/search)搜索注册表中的图像。 - [
docker pull
](https://docs.docker.com/engine/reference/commandline/pull)将图像从注册表拉到本地计算机。 - [
docker push
](https://docs.docker.com/engine/reference/commandline/push)将图像从本地计算机推送到注册表。
运行本地注册表
您可以使用[docker distribution](https://github.com/docker/distribution)项目并查看[本地部署](https://github.com/docker/docker.github)来运行本地注册表。 io / blob / master / registry / deploying.md)说明。
另请参阅[邮件列表](https://groups.google.com/a/dockerproject.org/forum/#!forum/distribution)。
Dockerfile
[配置文件](https://docs.docker.com/engine/reference/builder/)。在它上面运行docker build
时设置一个Docker容器。绝对优于docker commit
。
以下是一些常用的文本编辑器及其语法高亮模块,您可以使用它们来创建Dockerfiles:
*如果您使用[jEdit](http://jedit.org),我已经为[Dockerfile](https://github.com/wsargent/jedit-docker-mode)提供了一个语法高亮模块,您可以使用它。
- [Sublime Text 2](https://packagecontrol.io/packages/Dockerfile%20Syntax%20Highlighting)
- [Atom](https://atom.io/packages/language-docker)
- [Vim](https://github.com/ekalinin/Dockerfile.vim)
- [Emacs](https://github.com/spotify/dockerfile-mode)
- [TextMate](https://github.com/docker/docker/tree/master/contrib/syntax/textmate)
- [VS Code](https://github.com/Microsoft/vscode-docker)
*另见[Docker符合IDE](https://domeide.github.io/)
说明
- [.dockerignore](https://docs.docker.com/engine/reference/builder/#dockerignore-file)
- [FROM](https://docs.docker.com/engine/reference/builder/#from)为后续指令设置基本图像。
- [MAINTAINER(已弃用 - 改为使用LABEL)](https://docs.docker.com/engine/reference/builder/#maintainer-deprecated)设置生成图像的“作者”字段。
- [RUN](https://docs.docker.com/engine/reference/builder/#run)在当前图像之上的新图层中执行任何命令并提交结果。
- [CMD](https://docs.docker.com/engine/reference/builder/#cmd)为执行容器提供默认值。
- [EXPOSE](https://docs.docker.com/engine/reference/builder/#expose)通知Docker容器在运行时侦听指定的网络端口。注意:实际上并不能使端口可访问。
- [ENV](https://docs.docker.com/engine/reference/builder/#env)设置环境变量。
- [ADD](https://docs.docker.com/engine/reference/builder/#add)将新文件,目录或远程文件复制到容器中。使缓存无效。避免使用
ADD
并使用COPY
代替。 - [COPY](https://docs.docker.com/engine/reference/builder/#copy)将新文件或目录复制到容器中。请注意,这仅以root身份复制,因此无论USER / WORKDIR设置如何,都必须手动chown。请参阅https://github.com/moby/moby/issues/30110
- [ENTRYPOINT](https://docs.docker.com/engine/reference/builder/#entrypoint)配置将作为可执行文件运行的容器。
- [VOLUME](https://docs.docker.com/engine/reference/builder/#volume)为外部安装的卷或其他容器创建安装点。
- [USER](https://docs.docker.com/engine/reference/builder/#user)设置以下RUN / CMD / ENTRYPOINT命令的用户名。
- [WORKDIR](https://docs.docker.com/engine/reference/builder/#workdir)设置工作目录。
- [ARG](https://docs.docker.com/engine/reference/builder/#arg)定义了构建时变量。
- [ONBUILD](https://docs.docker.com/engine/reference/builder/#onbuild)在图像用作另一个构建的基础时添加触发器指令。
- [STOPSIGNAL](https://docs.docker.com/engine/reference/builder/#stopsignal)设置将发送到容器退出的系统调用信号。
- [LABEL](https://docs.docker.com/engine/userguide/labels-custom-metadata/)将键/值元数据应用于您的图像,容器或守护进程。
教程
- [Flux7的Dockerfile教程](http://flux7.com/blogs/docker/docker-tutorial-series-part-3-automation-is-the-word-using-dockerfile/)
例子
- [示例](https://docs.docker.com/engine/reference/builder/#dockerfile-examples)
- [编写Dockerfiles的最佳实践](https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/)
- [Michael Crosby](http://crosbymichael.com/)还有更多[Dockerfiles最佳实践](http://crosbymichael.com/dockerfile-best-practices.html)/ [take 2](http:// crosbymichael.com/dockerfile-best-practices-take-2.html)。
- [构建良好的Docker镜像](http://jonathan.bergknoff.com/journal/building-good-docker-images)/ [构建更好的Docker镜像](http://jonathan.bergknoff.com/journal/building-好搬运工图像)
- [使用元数据管理容器配置](https://speakerdeck.com/garethr/managing-container-configuration-with-metadata)
- [如何编写出色的Dockerfiles](https://rock-it.pl/how-to-write-excellent-dockerfiles/)
图层
Docker中的版本化文件系统基于层。它们就像[文件系统的git提交或更改集](https://docs.docker.com/engine/userguide/storagedriver/imagesandcontainers/)。
链接
链接是Docker容器如何相互通信[通过TCP / IP端口](https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/)。[链接到Redis](https://docs.docker.com/engine/examples/running_redis_service/)和[Atlassian](https://blogs.atlassian.com/2013/11/docker-all-the-things- at-atlassian-automation-and-wiring /)展示了工作实例。您还可以解析[按主机名链接](https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/#/updating-the-etchosts-file)。
[用户自定义网络](https://docs.docker.com/engine/userguide/networking/#user-defined-networks)在某种程度上忽略了这一点。
注意:如果您希望容器仅通过链接相互通信,请使用-icc = false
启动docker守护程序以禁用进程间通信。
如果你有一个名为CONTAINER的容器(由docker run --name CONTAINER
指定),并且在Dockerfile中,它有一个暴露的端口:
EXPOSE 1337
然后,如果我们创建另一个名为LINKED的容器,如下所示:
docker run -d --link CONTAINER:ALIAS --name LINKED user / wordpress
然后,CONTAINER的公开端口和别名将在LINKED中显示以下环境变量:
$ ALIAS_PORT_1337_TCP_PORT
$ ALIAS_PORT_1337_TCP_ADDR
你可以通过这种方式连接它。
要删除链接,请使用docker rm --link
。
通常,docker服务之间的链接是“服务发现”的一个子集,如果您计划在生产中大规模使用Docker,这是一个很大的问题。更多信息(https://www.digitalocean.com/community/tutorials/the-docker-ecosystem-service-discovery-and-distributed-configuration-stores):请阅读[服务发现和分布式配置存储泊坞生态系统] 。
卷
Docker卷是[自由浮动文件系统](https://docs.docker.com/engine/tutorials/dockervolumes/)。它们不必连接到特定容器。您应该使用从[仅数据容器](https://medium.com/@ramangupta/why-docker-data-containers-are-good-589b3c6c749e)安装的卷来实现可移植性。
生命周期
- [
docker volume create
](https://docs.docker.com/engine/reference/commandline/volume_create/) - [
docker volume rm
](https://docs.docker.com/engine/reference/commandline/volume_rm/)
信息
- [
docker volume ls
](https://docs.docker.com/engine/reference/commandline/volume_ls/) - [
docker volume inspect
](https://docs.docker.com/engine/reference/commandline/volume_inspect/)
在无法使用链接(仅限TCP / IP)的情况下,卷很有用。例如,如果您需要通过在文件系统上保留内容来进行两个docker实例的通信。
你可以使用docker run --volumes-from
一次将它们安装在几个docker容器中。
因为卷是隔离的文件系统,所以它们通常用于存储瞬态容器之间的计算状态。也就是说,您可以从配方中运行无状态和瞬态容器,将其吹走,然后从最后一个容器中取出瞬态容器的第二个实例。
有关详细信息,请参阅[高级卷](http://crosbymichael.com/advanced-docker-volumes.html)。Container42 [也很有用](http://container42.com/2014/11/03/docker-indepth-volumes/)。
您可以[将MacOS主机目录映射为docker卷](https://docs.docker.com/engine/tutorials/dockervolumes/#mount-a-host-directory-as-a-data-volume):
docker run -v / Users / wsargent / myapp / src:/ src
如果你[感到勇敢],你可以使用远程NFS卷(https://docs.docker.com/engine/tutorials/dockervolumes/#/mount-a-shared-storage-volume-as-a-data-volume )。
您也可以考虑运行仅数据容器[如此处](http://container42.com/2013/12/16/persistent-volumes-with-docker-container-as-volume-pattern/)以提供一些数据可移植性。
[请注意,您可以将文件装载为卷。](#volumes-can-be-files)
暴露端口
通过主机容器公开传入端口[fiddly但可行](https://docs.docker.com/engine/reference/run/#expose-incoming-ports)。
这是通过使用-p
将容器端口映射到主机端口(仅使用localhost接口)来完成的:
docker run -p 127.0.0.1:$HOSTPORT:$CONTAINERPORT --name CONTAINER -t someimage
您可以通过使用[EXPOSE](https://docs.docker.com/engine/reference/builder/#expose)告诉Docker容器在运行时侦听指定的网络端口:
EXPOSE <CONTAINERPORT>
请注意,EXPOSE不会公开端口本身 - 只有-p
才会这样做。要在localhost的端口上公开容器的端口:
iptables -t nat -A DOCKER -p tcp --dport <LOCALHOSTPORT> -j DNAT --to-destination <CONTAINERIP>:<PORT>
如果您在Virtualbox中运行Docker,则需要使用[forwarded_port](https://docs.vagrantup.com/v2/networking/forwarded_ports.html)转发端口。像这样在Vagrantfile中定义一系列端口,以便您可以动态映射它们:
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
...
(49000..49900).each do |port|
config.vm.network :forwarded_port, :host => port, :guest => port
end
...
end
如果您忘记了将端口映射到主机容器上的内容,请使用docker port
来显示它:
docker port CONTAINER $CONTAINERPORT
最佳实践
这是Docker最佳实践和战争故事的发源地:
- [在自动化测试中使用Docker的兔子洞](http://gregoryszorc.com/blog/2014/10/16/the-rabbit-hole-of-using-docker-in-automated-tests/)
- [Bridget Kromhout](https://twitter.com/bridgetkromhout)有一篇关于[在生产中运行Docker]的有用博客文章(http://sysadvent.blogspot.co.uk/2014/12/day-1-docker -in-production-reality-not.html)在Dramafever。
- Lyst还有一个最佳实践[博客文章](http://developers.lyst.com/devops/2014/12/08/docker/)。
- [使用Docker构建开发环境](https://tersesystems.com/2013/11/20/building-a-development-environment-with-docker/)
- [Docker容器中的话语](https://samsaffron.com/archive/2013/11/07/discourse-in-a-docker-container)
安全
这是有关Docker的安全提示的地方。Docker [安全](https://docs.docker.com/engine/security/security/)页面详细介绍。
首先要做的事:Docker以root身份运行。如果你在docker
组中,你实际上[有root权限](http://reventlov.com/advisories/using-the-docker-command-to-root-the-host)。如果将docker unix套接字暴露给容器,则表示您正在为容器提供[对主机的root访问权限](https://www.lvh.io/posts/dont-expose-the-docker-socket-not-even-到-A-container.html)。
Docker不应该是你唯一的防守。你应该保护并加强它。
要了解容器暴露的内容,请阅读[了解和强化Linux容器](https://www.nccgroup.trust/globalassets/our-research/us/whitepapers/2016/april/ncc_group_understanding_hardening_linux_containers-1-1。 pdf)由[Aaron Grattafiori](https://twitter.com/dyn___)。这是一个完整而全面的容器问题指南,包含大量链接和脚注,可以提供更多有用的内容。如果您过去已经加固过容器,但以下安全提示非常有用,但不能替代理解。
安全提示
为了最大的安全性,您希望在虚拟机中运行Docker。这直接来自Docker安全团队负责人 - [幻灯片](http://www.slideshare.net/jpetazzo/linux-containers-lxc-docker-and-security)/ [notes](http:// www。 projectatomic.io/blog/2014/08/is-it-safe-a-look-at-docker-and-security-from-linuxcon/)。然后,使用AppArmor / seccomp / SELinux / grsec等运行[限制容器权限](http://linux-audit.com/docker-security-best-practices-for-your-vessel-and-containers/)。有关详细信息,请参阅[Docker 1.10安全功能](https://blog.docker.com/2016/02/docker-engine-1-10-security/)。
Docker图像ID是[敏感信息](https://medium.com/@quayio/your-docker-image-ids-are-secrets-and-its-time-you-treated-them-that-way-f55e9f14c1a4)不应该暴露在外面的世界。像密码一样对待它们。
请参阅[ThomasSjögren]的[Docker Security Cheat Sheet](https://github.com/konstruktoid/Docker/blob/master/Security/CheatSheet.adoc)(https://github.com/konstruktoid):好一些关于容器硬化的东西。
查看[docker bench安全脚本](https://github.com/docker/docker-bench-security),下载[白皮书](https://blog.docker.com/2015/05/understanding- docker-security-and-best-practices /)并订阅[邮件列表](https://www.docker.com/docker-security)(遗憾的是Docker没有唯一的邮件列表,只有dev / user) 。
您应该首先使用编译有grsecurity / pax的不稳定补丁的内核,例如[Alpine Linux](https://en.wikipedia.org/wiki/Alpine_Linux)。如果你在生产中使用grsecurity,你应该为[稳定补丁](https://grsecurity.net/announce.php)提供[商业支持](https://grsecurity.net/business_support.php),同样的就像你为RedHat做的那样。这是每月200美元,这对你的开支预算来说没什么。
从docker 1.11开始,您可以轻松限制在容器内运行的活动进程数,以防止使用fork炸弹。这需要一个linux内核> = 4.3,CGROUP_PIDS = y才能进入内核配置。
docker run --pids-limit = 64
也可用,因为docker 1.11能够阻止进程获得新权限。从3.5版开始,此功能一直在linux内核中。您可以在[this](http://www.projectatomic.io/blog/2016/03/no-new-privs-docker/)博客文章中阅读更多相关信息。
docker run --security-opt = no-new-privileges
来自[Docker Security备忘单](http://container-solutions.com/content/uploads/2015/06/15.06.15_DockerCheatSheet_A2.pdf)(它是PDF格式,因此难以使用,因此在下面复制)[容器解决方案](http://container-solutions.com/is-docker-safe-for-production/):
关闭进程间通信:
docker -d --icc = false --iptables
将容器设置为只读:
docker run --read-only
使用hashsum验证图像:
docker pull debian @ sha256:a25306f3850e1bd44541976aa7b5fd0a29be
将卷设置为只读:
docker run -v $(pwd)/ secrets:/ secrets:ro debian
在Dockerfile中定义并运行用户,这样就不会在容器内以root身份运行:
RUN groupadd -r user && useradd -r -g user user
USER用户
用户名空间
还有[用户名称空间](https://s3hh.wordpress.com/2013/07/19/creating-and-using-containers-without-privilege/)的工作 - 它在1.10但默认情况下未启用。
要在Ubuntu 15.10中启用用户命名空间(“重新映射用户”),[请关注博客示例](https://raesene.github.io/blog/2016/02/04/Docker-User-Namespaces/)。
安全视频
- [安全使用Docker](https://youtu.be/04LOuMgNj9U)
- [使用Docker保护您的应用程序](https://youtu.be/KmxOXmPhZbk)
- [容器安全:容器实际上包含?](https://youtu.be/a9lE9Urr6AQ)
- [Linux容器:未来还是幻想?](https://www.youtube.com/watch?v=iN6QbszB1R8)
安全路线图
Docker路线图谈论[seccomp支持](https://github.com/docker/docker/blob/master/ROADMAP.md#11-security)。
有一个名为[bane](https://github.com/jfrazelle/bane)的AppArmor策略生成器,他们正在[安全配置文件]上工作(https://github.com/docker/docker/issues/17142 )。
提示
资料来源:
- [5分钟内15个Docker技巧](http://sssslide.com/speakerdeck.com/bmorearty/15-docker-tips-in-5-minutes)
- [CodeFresh Everyday Hacks Docker](https://codefresh.io/blog/everyday-hacks-docker/)
修剪
新的[数据管理命令](https://github.com/docker/docker/pull/26108)从Docker 1.13开始登陆:
*docker system prune
*docker volume prune
*docker network prune
*docker container prune
*docker image prune
df
docker system df
提供了不同docker对象当前使用的空间的摘要。
Heredoc Docker容器
docker build -t htop - << EOF
来自高山
RUN apk - 无缓存添加htop
EOF
Last Ids
别名dl ='docker ps -l -q'
docker run ubuntu echo hello world
docker commit $(dl)helloworld
使用命令提交(需要Dockerfile)
docker commit -run ='{“Cmd”:[“postgres”,“ - tattoo -many -opts”]}'$(dl)postgres
获取IP地址
docker inspect $(dl)| grep -wm1 IPAddress | cut -d'“' - f 4
或安装[jq](https://stedolan.github.io/jq/):
docker inspect $(dl)| jq -r'。[0] .NetworkSettings.IPAddress'
或使用[go template](https://docs.docker.com/engine/reference/commandline/inspect):
docker inspect -f'{{.NetworkSettings.IPAddress}}'<container_name>
或者,当您想要传递构建参数时,从Dockerfile构建图像时:
DOCKER_HOST_IP =`ifconfig | grep -E“([0-9] {1,3} \。){3} [0-9] {1,3}”| grep -v 127.0.0.1 | awk'{print $ 2}'| cut -f2 -d:| 头-n1`
echo DOCKER_HOST_IP = $ DOCKER_HOST_IP
码头工人
--build-arg ARTIFACTORY_ADDRESS = $ DOCKER_HOST_IP
-t sometag \
一些目录/
获取端口映射
docker inspect -f'{{range $ p,$ conf:= .NetworkSettings.Ports}} {{$ p}} - > {{(index $ conf 0).HostPort}} {{end}}'<containername>
按正则表达式查找容器
for $ in $(docker ps -a | grep“REGEXP_PATTERN”| cut -f1 -d“”); 回声$ i; DONE
获取环境设置
docker run --rm ubuntu env
杀死正在运行的容器
docker kill $(docker ps -q)
删除所有容器(强制!!运行或停止容器)
docker rm -f $(docker ps -qa)
删除旧容器
docker ps -a | grep'周前'| awk'{print $ 1}'| xargs docker rm
删除已停止的容器
docker rm -v $(docker ps -a -q -f status = exited)
停止后删除容器
docker stop $(docker ps -aq)&& docker rm -v $(docker ps -aq)
删除悬空图像
docker rmi $(docker images -q -f dangling = true)
删除所有图像
docker rmi $(docker images -q)
删除悬空卷
截至Docker 1.9:
docker volume rm $(docker volume ls -q -f dangling = true)
在1.9.0中,过滤器dangling = false
确实not工作 - 它被忽略并列出所有卷。
显示图像依赖关系
docker images -viz | dot -Tpng -o docker.png
减少Docker容器
- 在RUN层清洁APT
这应该在与其他apt命令相同的层中完成。
否则,前面的图层仍会保留原始信息,您的图像仍然很胖。
运行{apt commands} \
&& apt-get clean \
&& rm -rf / var / lib / apt / lists / * / tmp / * / var / tmp / *
- 展平图像
ID = $(docker run -d image-name / bin / bash)
docker export $ ID | docker import - flat-image-name
- 备份
ID = $(docker run -d image-name / bin / bash)
(docker export $ ID | gzip -c> image.tgz)
gzip -dc image.tgz | docker import - flat-image-name
监视运行容器的系统资源利用率
要检查单个容器的CPU,内存和网络I / O使用情况,您可以使用:
docker stats <container>
对于id列出的所有容器:
docker stats $(docker ps -q)
对于按名称列出的所有容器:
docker stats $(docker ps --format'{{。Names}}')
对于按图像列出的所有容器:
docker ps -a -f ancestor = ubuntu
删除所有未标记的图像
docker rmi $(docker images | grep“^”| awk'{split($ 0,a,“”); print a [3]}')
通过正则表达式删除容器
docker ps -a | grep wildfly | awk'{print $ 1}'| xargs docker rm -f
删除所有已退出的容器
docker rm -f $(docker ps -a | grep退出| awk'{print $ 1}')
卷可以是文件
请注意,您可以将文件作为卷装入。例如,您可以注入如下配置文件:
#从容器中复制文件
docker run --rm httpd cat /usr/local/apache2/conf/httpd.conf> httpd.conf
#编辑文件
vim httpd.conf
#start容器,配置已修改
docker run --rm -ti -v“$ PWD / httpd.conf:/usr/local/apache2/conf/httpd.conf:ro”-p“80:80”httpd