5种Docker日志最佳实践

作者 |Jeffrey Walker

翻译|Vincent

来源| CSDN

原文|http://geek.csdn.net/news/detail/232608

在过去的几年中,容器已经成为IT领域的一个重要话题,尤其是在DevOps领域。简单地说,当从一个环境迁移到另一个环境时,容器提供了一种简单且可扩展的方法可以运行软件。

容器是通过在一个包中提供完整的运行环境实现的,其中就包括了应用程序,所有的依赖项,库,其它二进制文件以及运行时所需的配置文件。

与容器紧密结合的是微服务,它代表了开发应用程序的一种更灵活的方式。微服务体系结构将应用程序构建为一组松耦合的服务,这些服务通过处理离散业务功能的API连接起来。微服务主要为应用程序开发提供了一种“分而治之”的方法,而不是一个大型的单一代码库。

Docker在容器的基础架构领域是处于世界领先地位的,它是一个部署容器级软件应用的平台。容器的真正价值在于它们允许团队动态地启动一个完整的运行环境。Docker可以说是让企业采用微服务的最具影响力的平台。

类似于虚拟机通过向来自一个服务器的终端用户提供一个操作系统的多个实例来简化软件开发和测试,容器在应用程序和主机操作系统之间添加了一个额外的抽象层。最大的不同是,容器不需要管理程序,只运行操作系统的一个实例;总的来说,这等同于内存更少,运行时间更快。

与开发任何应用程序一样,日志记录是过程的中心部分,在出现问题时尤其有用。但是,在集装箱化应用程序的世界里,与传统应用程序相比,它是不同的。日志Docker实际上意味着不仅记录应用程序和应用程序主机操作系统,以及Docker服务。在处理多码应用程序时,有许多日志记录技术和方法可以记住。我们将在下面详细介绍前五种最佳实践。

基于应用程序的日志记录

在基于应用程序的方法中,容器内的应用程序使用日志框架来处理日志记录过程。例如,某个Java应用程序可能会使用Log4j 2来对日志文件格式化,然后发送到远程服务器,并完全绕过Docker环境和操作系统。

虽然基于应用程序的日志记录使开发人员对日志事件有了最大的控制权,但是这种方法也会在应用程序过程中产生大量的消耗。这种方法对于那些工作在传统应用程序环境中的人来说可能是有用的,因为它允许开发人员继续使用应用程序的日志框架(例如Log4j 2)而不需要向主机添加日志功能。

Logging Docker实际上意味着不仅需要记录应用程序和主机操作系统,还包括了Docker服务。

使用数据卷

容器本质上是临时的,这意味着如果容器关闭了,那么容器内的任何文件最终都会丢失。相反,容器必须将日志事件转发到集中式日志记录服务(比如Loggly),或者将日志事件存储在数据卷中。数据卷的定义为“容器内的一个标记目录,该目录用来保存持久或共享的数据”。

使用数据卷来记录事件的好处是,由于它们链接到主机上的一个目录,所以日志数据仍然存在,并且可以与其它容器共享。这种方法的优点是它减少了在容器失败或关闭时丢失数据的可能性。在这里可以找到关于在Ubuntu中设置Docker数据卷的说明。

Docker日志驱动

在Docker中进行日志记录的第三种方法是使用平台的日志驱动程序将日志事件转发给在主机上运行的syslog实例。Docker日志驱动程序直接从容器的stdout和stderr输出里面读取日志事件;这就消除了从日志文件中读取和写入的需要,最终也会稍微改善性能。

然而,使用Docker日志驱动程序也有一些缺点:

  1. 它不允许进行日志解析,只允许进行日志转发。

  2. Docker日志命令只与日志驱动程序JSON文件一起工作。

  3. 当TCP服务器不可访问时,容器就会终止。

这里可以找到为Docker配置默认日志驱动程序的说明。

容器专用日志

这种方法的主要优点是允许在Docker环境中完全地管理日志事件。由于专用的日志容器可以从其他容器收集日志事件,聚合它们,然后将事件存储或转发到第三方服务,这种方法消除了对主机的依赖。

专用日志容器的其它优点是:

  1. 自动收集、监视和分析日志事件。

  2. 在没有配置的情况下自动缩放日志事件。

  3. 通过多个日志事件、stats和Docker API数据流来检索日志。

Sidecar方法

Sidecars已经成为管理微服务架构的流行方法。Sidecar的想法来自于类似摩托车的sidecar是如何附着在摩托车上的。引用一个消息源,“Sidecar作为第二个过程在你的服务旁边运行,并通过类似于HTTP上的REST-like API 这样一个同类接口提供了’平台基础设施’的特性。”

从日志记录的角度来看,Sidecar方法的优点是每个容器都与它自己的日志容器有关(应用程序容器保存日志事件和日志容器标记,然后像Loggly那样将它们转发到日志管理系统)。

5种Docker日志最佳实践

Sidecar方法对于大型部署来说尤其有用,因为这些部署需要有更专门的日志信息和自定义标记。不过,建立Sidecar非常复杂,而且难度也很大。

【基础教程】Docker基础及应用

0x00什么是Docker?

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。

一个完整的Docker有以下几个部分组成:

dockerClient客户端

Docker Daemon守护进程

Docker Image镜像

DockerContainer容器

知乎上有人回答说:Docker(码头工人)的思想来自于集装箱,集装箱解决了什么问题?在一艘大船上,可以把货物规整的摆放起来。并且各种各样的货物被集装箱标准化了,集装箱和集装箱之间不会互相影响。那么我就不需要专门运送水果的船和专门运送化学品的船了。只要这些货物在集装箱里封装的好好的,那我就可以用一艘大船把他们都运走。这里可以看docker的logo来理解,鲸鱼拖着许多集装箱。

这就解释了另外一个应用场景:应用的分离化,假如搭建一个Web网站需要CentOS+Apache+PHP+MySQL,我们即可利用CentOS的集装箱,Apache的集装箱和PHP,MySQL的集装箱来通信实现Web应用,集装箱之间除了交换数据并没有多余的联系。

0x01Docker相关的几个概念

1. 仓库(Repositories)

docker提供一个公共仓库,可以用dockersearch 命令去查找所需要的镜像,用docker pull 命令从仓库中拉取需要的镜像到本地。

https://hub.docker.com/explore/

【基础教程】Docker基础及应用

2.镜像(Images)

Docker的镜像类似虚拟机的快照,但更轻量,非常非常轻量。

创建Docker镜像有几种方式,多数是在一个现有镜像基础上创建新镜像,因为几乎你需要的任何东西都有了公共镜像,包括所有主流Linux发行版,你应该不会找不到你需要的镜像。不过,就算你想从头构建一个镜像,也有好几种方法。

要创建一个镜像,你可以拿一个镜像,对它进行修改来创建它的子镜像。实现前述目的的方式有两种:在一个文件中指定一个基础镜像及需要完成的修改;或通过“运行”一个镜像,对其进行修改并提交。不同方式各有优点,不过一般会使用文件来指定所做的变化。

镜像拥有唯一ID,以及一个供人阅读的名字和标签对。镜像可以命名为类似ubuntu:latest、ubuntu:precise、django:1.6、django:1.7等等。

用docker images 列出本地的镜像,dpcler search查找镜像列表。

【基础教程】Docker基础及应用

3.容器(Container)

你可以从镜像中创建容器,这等同于从快照中创建虚拟机,不过更轻量。应用是由容器运行的。

举个例子,你可以下载一个Ubuntu的镜像(有个叫docker registry的镜像公共仓库),通过安装Gunicorn和Django应用及其依赖项来完成对它的修改,然后从该镜像中创建一个容器,在它启动后运行你的应用。

容器与虚拟机一样,是隔离的。它们也拥有一个唯一ID和唯一的供人阅读的名字。容器对外公开服务是必要的,因此Docker允许公开容器的特定端口。

【基础教程】Docker基础及应用

与虚拟机相比,容器有一个很大的差异,它们被设计用来运行单进程,无法很好地模拟一个完整的环境Docker。容器和虚拟机的第二个巨大差异是:当你停止一个虚拟机时,可能除了一些临时文件,没有文件会被删除;当你停止一个Docker容器,对初始状态(创建容器所用的镜像的状态)做的所有变化都会丢失。

容器是设计来运行一个应用的,而非一台机器。你可能会把容器当虚拟机用,但如我们所见,你将失去很多的灵活性,因为Docker提供了用于分离应用与数据的工具,使得你可以快捷地更新运行中的代码/系统,而不影响数据。

仓库、镜像、容器的关系

【基础教程】Docker基础及应用

4.数据卷

数据卷让你可以不受容器生命周期影响进行数据持久化。它们表现为容器内的空间,但实际保存在容器之外,从而允许你在不影响数据的情况下销毁、重建、修改、丢弃容器。Docker允许你定义应用部分和数据部分,并提供工具让你可以将它们分开。使用Docker时必须做出的最大思维变化之一就是:容器应该是短暂和一次性的。

卷是针对容器的,你可以使用同一个镜像创建多个容器并定义不同的卷。卷保存在运行Docker的宿主文件系统上,你可以指定卷存放的目录,或让Docker保存在默认位置。保存在其他类型文件系统上的都不是一个卷。

【基础教程】Docker基础及应用

5.链接

链接是Docker的另一个重要部分。

容器启动时,将被分配一个随机的私有IP,其它容器可以使用这个IP地址与其进行通讯。这点非常重要,原因有二:一是它提供了容器间相互通信的渠道,二是容器将共享一个本地网络。在同一台机器上为两个客户启动两个elasticsearch容器,但保留集群名称为默认设置,结果这两台elasticsearch服务器立马变成了一个自主集群。注:限制容器间通讯是可行的,请阅读Docker的高级网络文档做进一步了解。

要开启容器间通讯,Docker允许你在创建一个新容器时引用其它现存容器,在你刚创建的容器里被引用的容器将获得一个(你指定的)别名。我们就说,这两个容器链接在了一起。

因此,如果DB容器已经在运行,我可以创建web服务器容器,并在创建时引用这个DB容器,给它一个别名,比如dbapp。在这个新建的web服务器容器里,我可以在任何时候使用主机名dbapp与DB容器进行通讯。

Docker更进一步,要求你声明容器在被链接时要开放哪些端口给其他容器,否则将没有端口可用。

0x02Docker的应用场景

关于docker的应用场景,http://dockone.io/article/126给出了详细的介绍。

【基础教程】Docker基础及应用

1. 简化配置

虚拟机的最大好处是能在你的硬件设施上运行各种配置不一样的平台(软件、系统),Docker在降低额外开销的情况下提供了同样的功能。它能让你将运行环境和配置放在代码中然后部署,同一个Docker的配置可以在不同的环境中使用,这样就降低了硬件要求和应用环境之间耦合度。

2. 代码流水线(Code Pipeline)管理

前一个场景对于管理代码的流水线起到了很大的帮助。代码从开发者的机器到最终在生产环境上的部署,需要经过很多的中间环境。而每一个中间环境都有自己微小的差别,Docker给应用提供了一个从开发到上线均一致的环境,让代码的流水线变得简单不少。

3. 提高开发效率

不同的开发环境中,我们都想把两件事做好。一是我们想让开发环境尽量贴近生产环境,二是我们想快速搭建开发环境。

理想状态中,要达到第一个目标,我们需要将每一个服务都跑在独立的虚拟机中以便监控生产环境中服务的运行状态。然而,我们却不想每次都需要网络连接,每次重新编译的时候远程连接上去特别麻烦。这就是Docker做的特别好的地方,开发环境的机器通常内存比较小,之前使用虚拟的时候,我们经常需要为开发环境的机器加内存,而现在Docker可以轻易的让几十个服务在Docker中跑起来。

4. 隔离应用

有很多种原因会让你选择在一个机器上运行不同的应用,比如之前提到的提高开发效率的场景等。

我们经常需要考虑两点,一是因为要降低成本而进行服务器整合,二是将一个整体式的应用拆分成松耦合的单个服务。

5. 整合服务器

正如通过虚拟机来整合多个应用,Docker隔离应用的能力使得Docker可以整合多个服务器以降低成本。由于没有多个操作系统的内存占用,以及能在多个实例之间共享没有使用的内存,Docker可以比虚拟机提供更好的服务器整合解决方案。

6. 调试能力

Docker提供了很多的工具,这些工具不一定只是针对容器,但是却适用于容器。它们提供了很多的功能,包括可以为容器设置检查点、设置版本和查看两个容器之间的差别,这些特性可以帮助调试Bug。

7. 多租户环境

另外一个Docker有意思的使用场景是在多租户的应用中,它可以避免关键应用的重写。这种多租户的基本代码非常复杂,很难处理,重新规划这样一个应用不但消耗时间,也浪费金钱。

使用Docker,可以为每一个租户的应用层的多个实例创建隔离的环境,这不仅简单而且成本低廉,当然这一切得益于Docker环境的启动速度和其高效的diff命令。

8. 快速部署

在虚拟机之前,引入新的硬件资源需要消耗几天的时间。虚拟化技术(Virtualization)将这个时间缩短到了分钟级别。而Docker通过为进程仅仅创建一个容器而无需启动一个操作系统,再次将这个过程缩短到了秒级。

你可以在数据中心创建销毁资源而无需担心重新启动带来的开销。通常数据中心的资源利用率只有30%,通过使用Docker并进行有效的资源分配可以提高资源的利用率。

0x03安全人员的常用场景

快速搭建各种漏洞环境

实例1:快速搭建webgoat环境

docker pull webgoat/webgoat-8.0docker run -p 8080:8080 -itwebgoat/webgoat-8.0 /home/webgoat/start.sh

【基础教程】Docker基础及应用

访问网址:http://IP:8080/WebGoat/login.mvc即可。

DVWA等开源漏洞平台也可以如上步骤轻松搭建。

实例2:搭建Zabbix漏洞环境

在平时的工作和学习中经常会遇到需要本地复现某个漏洞的情况,很多时候,搭建漏洞环境就会耗去我们较长的时间,其间可能会遇到各种各样的问题,要去修改、调试,直至真正搭建成功,过程还是比较崎岖的。docker完美的解决了这一问题。

以 Zabbix v2.2.x, 3.0.0-3.0.3 jsrpc 参数 profileIdx2 SQL 注入漏洞为例:

可以先使用docker search zabbix命令查找仓库中有哪些zabbix镜像,在镜像列表中选择一个 拉取到本地。

【基础教程】Docker基础及应用

Step1、拉取镜像到本地

docker pull medicean/vulapps:z_zabbix_1

Step2、启动环境

docker run -d -p 8888:80medicean/vulapps:z_zabbix_1

-p 8888:80 前面的 8888代表物理机的端口,可随意指定。

如果获取速度慢,推荐使用 中科大 Docker Mirrors

【基础教程】Docker基础及应用

在同网段访问该主机的8888端口即可看到zabbix服务已经成功启动

【基础教程】Docker基础及应用

如果不适用docker呢?

通常情况下,我们如果选择在一台centos7上安装zabbix,会经历以下过程

Step1.安装依赖包

yum -y install wget net-snmp-devel OpenIPMI-devel httpdopenssl-devel java lrzsz fping-devel libcurl-devel perl-DBI pcre-devel libxml2libxml2-devel mysql-devel gcc php php-bcmath php-gd php-xml php-mbstringphp-ldap php-mysql.x86_64 php-pear php-xmlrpc net-tools wget vim-enhanced

经历了大约10分钟的等待,依赖包全部安装完成。期间可能会出现

Cannot find a valid baseurl for repo:base/7/x86_64的报错信息,可以通过修改DNS来解决,不赘述。

Step2.关闭防火墙

systemctl stop firewalld.servicesystemctl disable firewalld.service

关闭selinux

vi /etc/selinux/config

修改SELINUX选项为disabled

重启x系统 reboot

等待ing…..

Step3. 搭建zabbix所需要的lamp环境

下载最新的yum源,

wget -P/etc/yum.repos.d http://mirrors.aliyun.com/repo/Centos-7.repo

【基础教程】Docker基础及应用

开始安装lamp环境

yum -y install mariadbmariadb-server php php-mysql httpd

【基础教程】Docker基础及应用

配置mysql数据库

systemctl enable mariadb.servicesystemctl start mariadb.service

【基础教程】Docker基础及应用

初始化mysql数据库,并配置root用户密码mysql_secure_installation

【基础教程】Docker基础及应用

【基础教程】Docker基础及应用

Enter current passwdord for root处,直接敲回车键即可

为root用户配置密码,并刷新相关权限。(密码设为123456,只为实验用,生产环境自定义)

Remove anonymous users? 删除匿名用户?

Disallow root login remotely? 禁止root远程登陆

Remove test database and access to it? 删除测试数据库并且和访问它

Reload privilege tables now? 重新载入特权表

0x04Docker的安装

由于Docker是一门较新的技术,所以对系统的要求也是比较新的,Docker需要在内核版本至少在3.0以后的版本中运行。

笔者环境是系统环境为CentOS Linux release 7.3.1611(Core) 内核版本3.10.0-514.el7.x86_64

centos7安装docker

1、Docker 软件包已经包括在默认的 CentOS-Extras 软件源里。因此想要安装 docker,只需要运行下面的 yum 命令:

yum install docker

2、安装完成后,使用下面的命令来启动docker 服务,并将其设置为开机启动:

service docker startchkconfig docker on

4、下载官方的 CentOS 镜像到本地

docker pull centos

5、确认 CentOS 镜像已经被获取:

docker images centos

6、运行一个 Docker 容器:

docker run -it centos /bin/bash

0x05Docker常用命令

基础命令

启动docker服务service docker start

设置开机自动启动 chkconfig docker on

docker服务对应版本查看docker version

Docker环境查看docker info

查看docker的所有命令docker

Docker命令帮助docker <command> –help 查看docker命令的帮助信息

查看docker状态ps -ef | grep docker

镜像

查找镜像 docker search <image name >

查看镜像列表 docker images

查看镜像的历史版本 docker history <image name>

 

创建镜像 docker pull <image name>

删除一个或多个镜像docker rmi <image name>

 

保存镜像docker save image name > /tmp/image.tar

加载镜像 docker load < /tmp/image/image.tar

 

容器

新建容器 docker create container name

交互式启动容器 docker run -it < containername> /bin/bash

 

显示容器状态 docker stats < container name/id>

启动容器 docker start <container name/id>

重启容器 docker restart < container name/id>

停止容器 docker stop < container name/id >

杀死容器 docker kill < container name/id>

删除容器 docker rm < container name/id>

重命名容器 docker rename < container name/id>

备份容器docker commit< container name/id > pro_test1

列出所有容器docker ps -a

列出最近一次启动的容器docker ps -l

列出所有当前正在运行的容器docker ps

0x06Dockerfile

Docker 可以通过 Dockerfile 的内容来自动构建镜像。

Dockerfile一般包含下面几个部分:

基础镜像:以哪个镜像作为基础进行制作,用法是FROM 基础镜像名称

维护者信息:需要写下该Dockerfile编写人的姓名或邮箱,用法是MANITAINER 名字/邮箱

镜像操作命令:对基础镜像要进行的改造命令,比如安装新的软件,进行哪些特殊配置等,常见的是RUN 命令

容器启动命令:当基于该镜像的容器启动时需要执行哪些命令,常见的是CMD 命令或ENTRYPOINT

Dockerfile 的基本语法结构

Dockerfile 是一个包含创建镜像所有命令的文本文件,通过docker build命令可以根据 Dockerfile 的内容构建镜像,先介绍下 Dockerfile 的基本语法结构。

Dockerfile 有以下指令选项:

  • FROM
  • MAINTAINER
  • RUN
  • CMD
  • EXPOSE
  • ENV
  • ADD
  • COPY
  • ENTRYPOINT
  • VOLUME
  • USER
  • WORKDIR
  • ONBUILD

1.FROM

用法:FROM <image>

  • FROM指定构建镜像的基础源镜像,如果本地没有指定的镜像,则会自动从 Docker 的公共库 pull 镜像下来。
  • FROM必须是 Dockerfile 中非注释行的第一个指令,即一个 Dockerfile 从FROM语句开始。
  • FROM可以在一个 Dockerfile 中出现多次,如果有需求在一个 Dockerfile 中创建多个镜像。
  • 如果FROM语句没有指定镜像标签,则默认使用latest标签。

2 MAINTAINER

指定创建镜像的用户。用法:MAINTAINER <name>

3.RUN

RUN命令将在当前image中执行任意合法命令并提交执行结果。命令执行提交后,就会自动执行Dockerfile中的下一个指令。有两种使用方式:

  • RUN
  • RUN “executable”, “param1”, “param2”

每条RUN指令将在当前镜像基础上执行指定命令,并提交为新的镜像,后续的RUN都在之前RUN提交后的镜像为基础,镜像是分层的,可以通过一个镜像的任何一个历史提交点来创建,类似源码的版本控制。

exec 方式会被解析为一个 JSON 数组,所以必须使用双引号而不是单引号。exec 方式不会调用一个命令 shell,所以也就不会继承相应的变量,如:

RUN [ "echo", "$HOME" ]

这种方式是不会达到输出 HOME 变量的,正确的方式应该是这样的

RUN [ "sh", "-c", "echo", "$HOME" ]

RUN产生的缓存在下一次构建的时候是不会失效的,会被重用,可以使用–no-cache选项,即docker build –no-cache,如此便不会缓存。

4 CMD

CMD有三种使用方式:

  • CMD “executable”,”param1″,”param2″
  • CMD “param1″,”param2”
  • CMD command param1 param2 (shell form)

CMD指定在 Dockerfile 中只能使用一次,如果有多个,则只有最后一个会生效。

CMD的目的是为了在启动容器时提供一个默认的命令执行选项。如果用户启动容器时指定了运行的命令,则会覆盖掉CMD指定的命令。

CMD会在启动容器的时候执行,build 时不执行,而RUN只是在构建镜像的时候执行,后续镜像构建完成之后,启动容器就与RUN无关了。

5 EXPOSE

用法:EXPOSE <port> [<port>…]

告诉 Docker 服务端容器对外映射的本地端口,需要在 docker run 的时候使用-p或者-P选项生效。

6 ENV

ENV <key> <value> # 只能设置一个变量

ENV <key>=<value> …# 允许一次设置多个变量

指定一个环境变量,会被后续RUN指令使用,并在容器运行时保留。

例子:

ENV myName="John Doe" myDog=Rex The Dog   myCat=fluffy

等同于

ENV myName John DoeENV myDog Rex The DogENV myCat fluffy

ENV设置的环境变量,可以使用 docker inspect命令来查看。同时还可以使用docker run –env <key>=<value>来修改环境变量

7 ADD

用法:ADD <src>… <dest>

ADD 将文件从路径 <src> 复制添加到容器内部路径 <dest>。

<src> 必须是想对于源文件夹的一个文件或目录,也可以是一个远程的url,<dest> 是目标容器中的绝对路径。

所有的新文件和文件夹都会创建UID 和 GID。事实上如果<src> 是一个远程文件URL,那么目标文件的权限将会是600。

支持通过Go的正则模糊匹配,具体规则可参见 Go filepath.Match

ADD hom* /mydir/    # adds all files starting with "hom"ADD hom?.txt /mydir/  # ? is replaced with any single character

路径必须是绝对路径,如果不存在,会自动创建对应目录;路径必须是 Dockerfile 所在路径的相对路径,如果是一个目录,只会复制目录下的内容,而目录本身则不会被复制。

8 COPY

用法:COPY <src><dest>

COPY 将文件从路径 <src> 复制添加到容器内部路径 <dest>。

COPY复制新文件或者目录从 并且添加到容器指定路径中 。用法同ADD,唯一的不同是不能指定远程文件 URLS。

9 ENTRYPOINT

  • ENTRYPOINT “executable”, “param1″,”param2”
  • ENTRYPOINT command param1 param2 (shell form)

配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖,而CMD是可以被覆盖的。如果需要覆盖,则可以使用docker run –entrypoint选项。

每个 Dockerfile 中只能有一个ENTRYPOINT,当指定多个时,只有最后一个生效。

Exec form ENTRYPOINT 例子

通过ENTRYPOINT使用 exec form 方式设置稳定的默认命令和选项,而使用CMD添加默认之外经常被改动的选项。

FROM ubuntuENTRYPOINT ["top", "-b"]CMD ["-c"]

通过 Dockerfile 使用ENTRYPOINT展示前台运行 Apache 服务

FROM debian:stableRUN apt-get update && apt-get install -y --force-yes apache2EXPOSE 80 443VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"]ENTRYPOINT ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]

Shell form ENTRYPOINT 例子

这种方式会在/bin/sh -c中执行,会忽略任何CMD或者docker run命令行选项,为了确保docker stop能够停止长时间运行ENTRYPOINT的容器,确保执行的时候使用exec选项。

FROM ubuntuENTRYPOINT exec top -b

如果在ENTRYPOINT忘记使用exec选项,则可以使用CMD补上:

FROM ubuntuENTRYPOINT top -bCMD --ignored-param1 # --ignored-param2 ... --ignored-param3 ... 依此类推

10 VOLUME

用法:VOLUME [“/data”]

创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等。

11 USER

USER daemon

USER 用来切换运行属主身份的。Docker 默认是使用 root,但若不需要,建议切换使用者身分,毕竟 root 权限太大了,使用上有安全的风险,后续的RUN、CMD、ENTRYPOINT也会使用指定用户。

12 WORKDIR

用法:WORKDIR /path/to/workdir

WORKDIR 用来切换工作目录的。Docker 默认的工作目录是/,只有 RUN 能执行cd命令切换目录,而且还只作用在当下下的 RUN,也就是说每一个 RUN 都是独立进行的。如果想让其他指令在指定的目录下执行,就得靠 WORKDIR。WORKDIR 动作的目录改变是持久的,不用每个指令前都使用一次。

为后续的RUN、CMD、ENTRYPOINT指令配置工作目录。可以使用多个WORKDIR指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。

WORKDIR。

WORKDIR /a

WORKDIR b

WORKDIR c

RUN pwd

最终路径是/a/b/c。

WORKDIR指令可以在ENV设置变量之后调用环境变量:

ENV DIRPATH /path

WORKDIR $DIRPATH/$DIRNAME

最终路径则为 /path/$DIRNAME。

13 ONBUILD

用法:ONBUILD [INSTRUCTION]

ONBUILD 的作用就是让指令延迟執行,延迟到下一个使用 FROM 的 Dockerfile 在建立 image 时执行,只限延迟一次。

ONBUILD 的使用情景是在建立镜像时取得最新的源码 (搭配 RUN) 与限定系统框架。

例如,Dockerfile 使用如下的内容创建了镜像 image-A:

[...]ONBUILD ADD . /app/srcONBUILD RUN /usr/local/bin/python-build --dir /app/src[...]

如果基于 image-A 创建新的镜像时,新的 Dockerfile 中使用 FROM image-A 指定基础镜像时,会自动执行 ONBUILD 指令内容,等价于在后面添加了两条指令。

# Automatically run the followingADD . /app/srcRUN /usr/local/bin/python-build --dir /app/src

使用ONBUILD指令的镜像,推荐在标签中注明,例如 ruby:1.9-onbuild。

创建dockerfile文件实例

【基础教程】Docker基础及应用

vim编辑Dockerfile文件

【基础教程】Docker基础及应用

上面的Dockerfile非常简单,创建了一个包含apache的镜像。

FROM指定基础镜像,如果镜像名称中没有制定TAG,默认为latest。

MAINTAINER写明了作者信息

RUN命令默认使用/bin/sh Shell执行,默认为root权限。如果命令过长需要换行,需要在行末尾加。

CMD命令也是默认在/bin/sh中执行,并且默认只能有一条,如果是多条CMD命令则只有最后一条执行。用户也可以在docker run命令创建容器时指定新的CMD命令来覆盖Dockerfile里的CMD。

这个Dockerfile已经可以使用docker build创建新镜像了,先构建一个版本yishuyu:1:

【基础教程】Docker基础及应用

使用docker images命令查看镜像

【基础教程】Docker基础及应用

使用该镜像创建容器web1,将容器中的端口80映射到本地80端口:

【基础教程】Docker基础及应用

查看最近启动的容器

【基础教程】Docker基础及应用

访问该台机器8080端口,即可看到apache首页

【基础教程】Docker基础及应用

CMD如果只有一个命令,那如果我们需要运行多个服务怎么办呢?最好的办法是分别在不同的容器中运行,通过link进行连接。如果一定要在一个容器中运行多个服务可以考虑用Supervisord来进行进程管理,方式就是将多个启动命令放入到一个启动脚本中。

首先安装Supervisord,添加下面内容到Dockerfile:

RUN easy_install supervisorRUN mkdir -p /var/log/supervisor

拷贝配置文件到指定的目录:

COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf

其中supervisord.conf文件需要放在/home/yishuyu/yishuyu下,文件内容如下:

[supervisord]nodaemon=true[program:apache2]command=/bin/bash -c "source /etc/apache2/envvars && exec /usr/sbin/apache2ctl -D FOREGROUND"

如果有多个服务需要启动可以在文件后继续添加[program:xxx],比如如果有ssh服务,可以增加[program:ssh]。

修改CMD命令,启动Supervisord:

CMD ["/usr/bin/supervisord"]

在上述基本的架构下,我们根据需求可以增加新的内容到Dockerfile中。后续的扩展操作都需要放置在Dockerfile的镜像操作部分。

# Version 0.2FROM centosMAINTAINER yishuyu@163.com  #作者信息RUN yum -y install apache2   #安装apacheRUN easy_install supervisor  #安装SupervisordRUN mkdir -p /var/log/supervisor  #建立supervisor目录VOLUME ["/var/log/apche2"]  #将apache访问的日志数据存储到宿主机可以访问的数据卷中ADD html.tar /var/www  #向镜像中增加文件COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf  #拷贝配置文件到指定的目录WORKDIR /var/www/html  #指定后续命令的执行目录ENV HOSTNAME shiyanloutest  #使用ENV设置一些apache启动的环境变量ENV APACHE_RUN_USER www-dataENV APACHE_RUN_GROUP www-dataENV APACHE_LOG_DIR /var/log/apche2ENV APACHE_PID_FILE /var/run/apache2.pidENV APACHE_RUN_DIR /var/run/apache2ENV APACHE_LOCK_DIR /var/lock/apche2EXPOSE 80  #设置对外连接端口号CMD ["/usr/bin/supervisord"]  #启动Supervisord

 

0x06参考链接

http://dockone.io/article/126

https://lug.ustc.edu.cn/wiki/mirrors/help/docker

https://github.com/Medicean/VulApps/tree/master/z/zabbix/1

http://www.jkeabc.com/176978.html

http://www.linuxidc.com/Linux/2014-12/110034.htm

【基础教程】Docker基础及应用

 

Docker实战命令

输入docker –help可以查看Docker的子命令。

总结一下常用命令:

其中< >括起来的参数为必选,[]括起来为可选。

·docker version查看docker的版本号,包括客户端、服务端、依赖的Go等

·docker info查看系统(docker)层面信息,包括管理的images, containers数等

·docker search <image>在docker index中搜索image

·docker pull <image>从docker registry server中下拉image

·docker push <image|repository>推送一个image或repository到registry

·docker push <image|repository>:TAG同上,指定tag

·docker inspect <image|container>查看image或container的底层信息

·docker imagesTODOfilter out the intermediate image layers (intermediate image layers 是什么)

·docker images -a列出所有的images

·docker ps默认显示正在运行中的container

·docker ps -l显示最后一次创建的container,包括未运行的

Docker实战命令

·docker ps -a显示所有的container,包括未运行的

·docker logs <container>查看container的日志,也就是执行命令的一些输出

·docker rm <container…>删除一个或多个container

·docker rm `docker ps -a -q` 删除所有的container

·docker ps -a -q | xargsdocker rm同上, 删除所有的container

·docker rmi <image…>删除一个或多个image

·docker start/stop/restart <container>开启/停止/重启container

·docker start -i <container>启动一个container并进入交互模式

·docker attach <container>attach一个运行中的container

·docker run <image> <command>使用image创建container并执行相应命令,然后停止

·docker run -i -t <image> /bin/bash使用image创建container并进入交互模式, login shell是/bin/bash

·docker run -i -t -p <host_port:contain_port>将container的端口映射到宿主机的端口

·docker commit <container> [repo:tag]将一个container固化为一个新的image,后面的repo:tag可选

·docker build <path>寻找path路径下名为的Dockerfile的配置文件,使用此配置生成新的image

·docker build -t repo[:tag]同上,可以指定repo和可选的tag

·docker build – < <dockerfile>使用指定的dockerfile配置文件,docker以stdin方式获取内容,使用此配置生成新的image

·docker port <container> <container port>查看本地哪个端口映射到container的指定端口,或者用docker ps也可以看到。

 

Docker 入门教程

2013年发布至今,Docker一直广受瞩目,被认为可能会改变软件行业。

但是,许多人并不清楚 Docker 到底是什么,要解决什么问题,好处又在哪里?本文就来详细解释,帮助大家理解它,还带有简单易懂的实例,教你如何将它用于日常开发。

Docker 入门教程

一、环境配置的难题

软件开发最大的麻烦事之一,就是环境配置。用户计算机的环境都不相同,你怎么知道自家的软件,能在那些机器跑起来?

用户必须保证两件事:操作系统的设置,各种库和组件的安装。只有它们都正确,软件才能运行。举例来说,安装一个 Python 应用,计算机必须有 Python 引擎,还必须有各种依赖,可能还要配置环境变量。

如果某些老旧的模块与当前环境不兼容,那就麻烦了。开发者常常会说:”它在我的机器可以跑了”(It works on my machine),言下之意就是,其他机器很可能跑不了。

环境配置如此麻烦,换一台机器,就要重来一次,旷日费时。很多人想到,能不能从根本上解决问题,软件可以带环境安装?也就是说,安装的时候,把原始环境一模一样地复制过来。

二、虚拟机

虚拟机(virtual machine)就是带环境安装的一种解决方案。它可以在一种操作系统里面运行另一种操作系统,比如在 Windows 系统里面运行 Linux 系统。应用程序对此毫无感知,因为虚拟机看上去跟真实系统一模一样,而对于底层系统来说,虚拟机就是一个普通文件,不需要了就删掉,对其他部分毫无影响。

虽然用户可以通过虚拟机还原软件的原始环境。但是,这个方案有几个缺点。

(1)资源占用多

虚拟机会独占一部分内存和硬盘空间。它运行的时候,其他程序就不能使用这些资源了。哪怕虚拟机里面的应用程序,真正使用的内存只有 1MB,虚拟机依然需要几百 MB 的内存才能运行。

(2)冗余步骤多

虚拟机是完整的操作系统,一些系统级别的操作步骤,往往无法跳过,比如用户登录。

(3)启动慢

启动操作系统需要多久,启动虚拟机就需要多久。可能要等几分钟,应用程序才能真正运行。

三、Linux 容器

由于虚拟机存在这些缺点,Linux 发展出了另一种虚拟化技术:Linux 容器(Linux Containers,缩写为 LXC)。

Linux 容器不是模拟一个完整的操作系统,而是对进程进行隔离。或者说,在正常进程的外面套了一个保护层。对于容器里面的进程来说,它接触到的各种资源都是虚拟的,从而实现与底层系统的隔离。

由于容器是进程级别的,相比虚拟机有很多优势。

(1)启动快

容器里面的应用,直接就是底层系统的一个进程,而不是虚拟机内部的进程。所以,启动容器相当于启动本机的一个进程,而不是启动一个操作系统,速度就快很多。

(2)资源占用少

容器只占用需要的资源,不占用那些没有用到的资源;虚拟机由于是完整的操作系统,不可避免要占用所有资源。另外,多个容器可以共享资源,虚拟机都是独享资源。

(3)体积小

容器只要包含用到的组件即可,而虚拟机是整个操作系统的打包,所以容器文件比虚拟机文件要小很多。

总之,容器有点像轻量级的虚拟机,能够提供虚拟化的环境,但是成本开销小得多。

四、Docker 是什么?

Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口。它是目前最流行的 Linux 容器解决方案。

Docker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了 Docker,就不用担心环境问题。

总体来说,Docker 的接口相当简单,用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。

五、Docker 的用途

Docker 的主要用途,目前有三大类。

(1)提供一次性的环境。比如,本地测试他人的软件、持续集成的时候提供单元测试和构建的环境。

(2)提供弹性的云服务。因为 Docker 容器可以随开随关,很适合动态扩容和缩容。

(3)组建微服务架构。通过多个容器,一台机器可以跑多个服务,因此在本机就可以模拟出微服务架构。

六、Docker 的安装

Docker 是一个开源的商业产品,有两个版本:社区版(Community Edition,缩写为 CE)和企业版(Enterprise Edition,缩写为 EE)。企业版包含了一些收费服务,个人开发者一般用不到。下面的介绍都针对社区版。

Docker CE 的安装请参考官方文档:https://docs.docker.com/install/。

  • Mac

  • Windows

  • Ubuntu

  • Debian

  • CentOS

  • Fedora

  • 其他 Linux 发行版

安装完成后,运行下面的命令,验证是否安装成功。

$ docker version# 或者$ docker info

Docker 需要用户具有 sudo 权限,为了避免每次命令都输入sudo,可以把用户加入 Docker 用户组(官方文档)。

$ sudo usermod -aG docker $USER

Docker 是服务器—-客户端架构。命令行运行 docker 命令的时候,需要本机有 Docker 服务。如果这项服务没有启动,可以用下面的命令启动(官方文档)。

# service 命令的用法$ sudo service docker start# systemctl 命令的用法$ sudo systemctl start docker

七、image 文件

Docker 把应用程序及其依赖,打包在 image 文件里面。只有通过这个文件,才能生成 Docker 容器。image 文件可以看作是容器的模板。Docker 根据 image 文件生成容器的实例。同一个 image 文件,可以生成多个同时运行的容器实例。

image 是二进制文件。实际开发中,一个 image 文件往往通过继承另一个 image 文件,加上一些个性化设置而生成。举例来说,你可以在 Ubuntu 的 image 基础上,往里面加入 Apache 服务器,形成你的 image。

# 列出本机的所有 image 文件。$ docker image ls# 删除 image 文件$ docker image rm [imageName]

image 文件是通用的,一台机器的 image 文件拷贝到另一台机器,照样可以使用。一般来说,为了节省时间,我们应该尽量使用别人制作好的 image 文件,而不是自己制作。即使要定制,也应该基于别人的 image 文件进行加工,而不是从零开始制作。

为了方便共享,image 文件制作完成后,可以上传到网上的仓库。Docker 的官方仓库Docker Hub是最重要、最常用的 image 仓库。此外,出售自己制作的 image 文件也是可以的。

八、实例:hello world

下面,我们通过最简单的 image 文件 “hello world”,感受一下 Docker。

首先,运行下面的命令,将 image 文件从仓库抓取到本地。

$ docker image pull library/hello-world

上面代码中,docker image pull 是抓取 image 文件的命令。library/hello-world 是 image 文件在仓库里面的位置,其中 library 是 image 文件所在的组,hello-world 是 image 文件的名字。

由于 Docker 官方提供的 image 文件,都放在 library 组里面,所以它的是默认组,可以省略。因此,上面的命令可以写成下面这样。

$ docker image pull hello-world

抓取成功以后,就可以在本机看到这个 image 文件了。

$ docker image ls

现在,运行这个 image 文件。

$ docker container run hello-world

docker container run 命令会从 image 文件,生成一个正在运行的容器实例。

注意,docker container run 命令具有自动抓取 image 文件的功能。如果发现本地没有指定的 image 文件,就会从仓库自动抓取。因此,前面的 docker image pull 命令并不是必需的步骤。

如果运行成功,你会在屏幕上读到下面的输出。

$ docker container run hello-world

Hello from Docker!

This message shows that your installation appears to be working correctly

…. …

输出这段提示以后,hello world 就会停止运行,容器自动终止。

有些容器不会自动终止,因为提供的是服务。比如,安装运行 Ubuntu 的 image,就可以在命令行体验 Ubuntu 系统。

$ docker container run -it ubuntu bash

对于那些不会自动终止的容器,必须使用 docker container kill 命令手动终止。

$ docker container kill [containID]

九、容器文件

image 文件生成的容器实例,本身也是一个文件,称为容器文件。也就是说,一旦容器生成,就会同时存在两个文件: image 文件和容器文件。而且关闭容器并不会删除容器文件,只是容器停止运行而已。

# 列出本机正在运行的容器$ docker container ls -l# 列出本机所有容器,包括终止运行的容器$ docker container ls --all

上面命令的输出结果之中,包括容器的 ID。很多地方都需要提供这个 ID,比如上一节终止容器运行的 docker container kill 命令。

终止运行的容器文件,依然会占据硬盘空间,可以使用 docker container rm 命令删除。

$ docker container rm [containerID]

运行上面的命令之后,再使用 docker container ls –all 命令,就会发现被删除的容器文件已经消失了。

十、Dockerfile 文件

学会使用 image 文件以后,接下来的问题就是,如何可以生成 image 文件?如果你要推广自己的软件,势必要自己制作 image 文件。

这就需要用到 Dockerfile 文件。它是一个文本文件,用来配置 image。Docker 根据该文件生成二进制的 image 文件。

下面通过一个实例,演示如何编写 Dockerfile 文件。

十一、实例:制作自己的 Docker 容器

下面我以koa-demos项目为例,介绍怎么写 Dockerfile 文件,实现让用户在 Docker 容器里面运行 Koa 框架。

作为准备工作,请先下载源码。

$ git clone https://github.com/ruanyf/koa-demos.git

$ cd koa-demos

11.1 编写 Dockerfile 文件

首先,在项目的根目录下,新建一个文本文件.dockerignore,写入下面的内容。

.git node_modules npm-debug.log

上面代码表示,这三个路径要排除,不要打包进入 image 文件。如果你没有路径要排除,这个文件可以不新建。

然后,在项目的根目录下,新建一个文本文件 Dockerfile,写入下面的内容。

FROM node:8.4

COPY . /app

WORKDIR /app

RUN npm install –registry=https://registry.npm.taobao.org

EXPOSE 3000

上面代码一共五行,含义如下。

  • FROM node:8.4:该 image 文件继承官方的 node image,冒号表示标签,这里标签是8.4,即8.4版本的 node。

  • COPY . /app:将当前目录下的所有文件(除了.dockerignore排除的路径),都拷贝进入 image 文件的/app目录。

  • WORKDIR /app:指定接下来的工作路径为/app。

  • RUN npm install:在/app目录下,运行npm install命令安装依赖。注意,安装后所有的依赖,都将打包进入 image 文件。

  • EXPOSE 3000:将容器 3000 端口暴露出来, 允许外部连接这个端口。

11.2 创建 image 文件

有了 Dockerfile 文件以后,就可以使用 docker image build 命令创建 image 文件了。

$ docker image build -t koa-demo .

# 或者

$ docker image build -t koa-demo:0.0.1 .

上面代码中,-t 参数用来指定 image 文件的名字,后面还可以用冒号指定标签。如果不指定,默认的标签就是 latest。最后的那个点表示 Dockerfile 文件所在的路径,上例是当前路径,所以是一个点。

如果运行成功,就可以看到新生成的 image 文件 koa-demo 了。

$ docker image ls

11.3 生成容器

docker container run 命令会从 image 文件生成容器。

$ docker container run -p 8000:3000 -it koa-demo /bin/bash

# 或者

$ docker container run -p 8000:3000 -it koa-demo:0.0.1 /bin/bash

上面命令的各个参数含义如下:

  • -p参数:容器的 3000 端口映射到本机的 8000 端口。

  • -it参数:容器的 Shell 映射到当前的 Shell,然后你在本机窗口输入的命令,就会传入容器。

  • koa-demo:0.0.1:image 文件的名字(如果有标签,还需要提供标签,默认是 latest 标签)。

  • /bin/bash:容器启动以后,内部第一个执行的命令。这里是启动 Bash,保证用户可以使用 Shell。

如果一切正常,运行上面的命令以后,就会返回一个命令行提示符。

root@66d80f4aaf1e:/app#

这表示你已经在容器里面了,返回的提示符就是容器内部的 Shell 提示符。执行下面的命令。

root@66d80f4aaf1e:/app# node demos/01.js

这时,Koa 框架已经运行起来了。打开本机的浏览器,访问 http://127.0.0.1:8000,网页显示”Not Found”,这是因为这个demo没有写路由。

这个例子中,Node 进程运行在 Docker 容器的虚拟环境里面,进程接触到的文件系统和网络接口都是虚拟的,与本机的文件系统和网络接口是隔离的,因此需要定义容器与物理机的端口映射(map)。

现在,在容器的命令行,按下 Ctrl + c 停止 Node 进程,然后按下 Ctrl + d (或者输入 exit)退出容器。此外,也可以用 docker container kill 终止容器运行。

# 在本机的另一个终端窗口,查出容器的 ID

$ docker container ls

# 停止指定的容器运行

$ docker container kill [containerID]

容器停止运行之后,并不会消失,用下面的命令删除容器文件。

# 查出容器的 ID$ docker container ls --all# 删除指定的容器文件$ docker container rm [containerID]

也可以使用 docker container run 命令的 –rm 参数,在容器终止运行后自动删除容器文件。

$ docker container run –rm -p 8000:3000 -it koa-demo /bin/bash

11.4 CMD 命令

上一节的例子里面,容器启动以后,需要手动输入命令 node demos/01.js。我们可以把这个命令写在 Dockerfile 里面,这样容器启动以后,这个命令就已经执行了,不用再手动输入了。

FROM node:8.4

COPY . /app

WORKDIR /app

RUN npm install –registry=https://registry.npm.taobao.org

EXPOSE 3000

CMD node demos/01.js

上面的 Dockerfile 里面,多了最后一行 CMD node demos/01.js,它表示容器启动后自动执行 node demos/01.js。

你可能会问,RUN 命令与 CMD 命令的区别在哪里?简单说,RUN 命令在 image 文件的构建阶段执行,执行结果都会打包进入 image 文件;CMD 命令则是在容器启动后执行。另外,一个 Dockerfile 可以包含多个 RUN 命令,但是只能有一个 CMD 命令。

注意,指定了 CMD 命令以后,docker container run 命令就不能附加命令了(比如前面的 /bin/bash),否则它会覆盖 CMD 命令。现在,启动容器可以使用下面的命令。

$ docker container run –rm -p 8000:3000 -it koa-demo:0.0.1

11.5 发布 image 文件

容器运行成功后,就确认了 image 文件的有效性。这时,我们就可以考虑把 image 文件分享到网上,让其他人使用。

首先,去hub.docker.com或cloud.docker.com注册一个账户。然后,用下面的命令登录。

$ docker login

接着,为本地的 image 标注用户名和版本。

$ docker image tag [imageName] [username]/[repository]:[tag]

# 实例

$ docker image tag koa-demos:0.0.1 ruanyf/koa-demos:0.0.1

也可以不标注用户名,重新构建一下 image 文件。

$ docker image build -t [username]/[repository]:[tag] .

最后,发布 image 文件。

$ docker image push [username]/[repository]:[tag]

发布成功以后,登录 hub.docker.com,就可以看到已经发布的 image 文件。

十二、其他有用的命令

docker 的主要用法就是上面这些,此外还有几个命令,也非常有用。

(1)docker container start

前面的 docker container run 命令是新建容器,每运行一次,就会新建一个容器。同样的命令运行两次,就会生成两个一模一样的容器文件。如果希望重复使用容器,就要使用 docker container start 命令,它用来启动已经生成、已经停止运行的容器文件。

$ docker container start [containerID]

(2)docker container stop

前面的 docker container kill 命令终止容器运行,相当于向容器里面的主进程发出 SIGKILL 信号。而 docker container stop 命令也是用来终止容器运行,相当于向容器里面的主进程发出 SIGTERM 信号,然后过一段时间再发出 SIGKILL 信号。

$ docker container stop [containerID]

这两个信号的差别是,应用程序收到 SIGTERM 信号以后,可以自行进行收尾清理工作,但也可以不理会这个信号。如果收到 SIGKILL 信号,就会强行立即终止,那些正在进行中的操作会全部丢失。

(3)docker container logs

docker container logs 命令用来查看 docker 容器的输出,即容器里面 Shell 的标准输出。如果 docker run 命令运行容器的时候,没有使用 -it 参数,就要用这个命令查看输出。

$ docker container logs [containerID]

(4)docker container exec

docker container exec 命令用于进入一个正在运行的 docker 容器。如果 docker run 命令运行容器的时候,没有使用 -it 参数,就要用这个命令进入容器。一旦进入了容器,就可以在容器的 Shell 执行命令了。

$ docker container exec -it [containerID] /bin/bash

(5)docker container cp

docker container cp 命令用于从正在运行的 Docker 容器里面,将文件拷贝到本机。下面是拷贝到当前目录的写法。

$ docker container cp [containID]:[/path/to/file] .

  • 来源:阮一峰的网络日志

  • 原文:http://t.cn/RRhT0D2

  • 题图:来自谷歌图片搜索

  • 版权:本文版权归原作者所有

Docker 入门教程

今日思想

Knowledge will give you power, but character respect.

知识给你力量,品格给你别人的尊敬。

——李小龙

Docker 入门教程

更多精彩热文:

Docker 入门教程

Docker 入门教程

Docker 入门教程

docker概述与原理

 

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中。谢谢刘磊为我们准备了这一系列的内容,非常赞!

 

 

Docker是一个开源的引擎,可以轻松而又快速的为任何应用创建一个轻量级的、可移植的、自给自足的容器。开发者在笔记本上编译测试通过的容器可以批量地在生产环境中部署,包括VMs(虚拟机)、baremetal、OpenStack集群和其他的基础应用平台。

1
Docker系统有两个程序:服务端和客户端

其中docker服务端是一个服务进程,管理着所有的容器。docker客户端则扮演着docker服务端的远程控制器,可以用来控制docker的服务端进程。大部分情况下,docker服务端和客户端运行在一台机器上。

2
Docker通常适用如下场景:

·web应用的自动化打包和发布;

·自动化测试和持续集成、发布;

·在服务型环境中部署和调整数据库或其他的后台应用;

·从头编译或者扩展现有的OpenShift或CloudFoundry平台来搭建自己的PaaS环境。

3
查看docker版本

docker概述与原理

4
Dockr架构

docker概述与原理

Docker采用Client/Server架构模式。DockerDaemon是docker的核心守护进程,也就是Server端,Server端可以部署在远程,也可以部署在本地,客户端向服务器发送请求,服务端负责构建、运行和分发容器。客户端和服务器可以运行在同一个Host上,客户端可以通过socket或RESTAPI与远程的服务器通信.

dockerCLI实现容器和镜像的管理,为用户提供统一的操作界面,这个客户端提供一个只读的镜像,然后通过镜像可以创建一个或者多个容器(container),这些容器可以只是一个RFS(RootFileSystem),也可以是一个包含了用户应用的RFS。容器在dockerClient中只是一个进程,两个进程是互不可见的,从而实现容器之间的个隔离。

用户不能与server直接交互,但可以通过与容器这个桥梁来交互,由于是操作系统级别的虚拟技术,中间的损耗几乎可以不计。

docker概述与原理

5
docker容器和虚拟化实现原理

docker概述与原理

左图是虚拟机的工作原理图,着重体现在硬件层面进行虚拟化,实现对硬件资源进行抽象,对性能的损耗比较大,而且还会占用大量的内存资源

有图是Docker的工作原理图,属于OS级别的虚拟化,kernel通过创建多个镜像来隔离不同的app进程,由于kernel是是共享,本身linuximage也不大,性能损耗几乎可以不计,而且内存占用也不大,大大节约了设备成本