docker删除映像_可执行映像-如何对开发机器进行Docker化

docker删除映像

 

每个开发人员都知道不兼容软件的痛苦。 当在需要不同版本的Java运行时的多个项目上工作时,尤其是在OsX上,问题Swift出现。 Ruby有其自己的版本管理器是有原因的。 我的两位同事花了数小时来用Homebrew软件包调试其OpenSSL和Python版本的不兼容性。 我们可以使用容器解决这些问题吗? 答案是:“是的,我们可以!”

容器的主要目标是交付软件。 新成立的Open Containers项目提供以下定义:

标准容器的目标是以一种可自我描述和可移植的格式封装软件组件及其所有依赖项,以便任何兼容的运行时都可以在没有额外依赖项的情况下运行该组件,而不管底层机器和容器的内容如何。

此定义未声明有关所分发软件的种类的任何信息。 这是有目的的,因为容器在设计上是内容不可知的。 您要交付的内容以及应如何使用完全取决于您自己。 在本文中,我提出了服务映像和可执行映像之间的区别。 我还将提倡使用可执行映像。

可执行映像比服务映像更不常见,但是是混合映像中非常有用的补充。 他们将解决软件不兼容等问题。 以官方的Docker Maven映像为例,我们将研究什么是可执行映像,它们如何工作以及如何自己创建它们。 Dockerfiles的ENTRYPOINT指令在可执行映像中起着核心作用。

服务映像与可执行映像

传统上,集装箱图像用于长时间运行的进程:那些在服务器上运行的服务 ,而不是因为它们包含影响主机。 我们称这些服务图像 。 Web服务器,负载平衡器和数据库是服务映像的很好示例。 这些容器可以轻松地与虚拟机进行比较。

容器映像也可以用于短暂的过程:容器化的可执行文件,意在在计算机上运行。 这些容器执行单个任务, 寿命短 ,使用后通常可以将其删除。 我们称这些可执行映像 。 示例包括编译器(Golang)或构建工具(Maven),演示文稿软件(我喜欢以Markdown格式破解一个简单的演示文稿,并让RevealJS Docker镜像为之服务)和浏览器(一个新的内置浏览器,用于跟踪该钓鱼链接)。 真正的可执行映像传播者是Docker自己的Jessie Frazelle 。 要获得灵感,请务必阅读她的博客或在DockerCon 2015上查看此演示文稿

服务映像和可执行映像之间的区别不是一成不变的。 根据定义,所有图像都是可执行的,因为它们的工作是运行一个进程。 在容器中运行演示文稿或浏览器是本地工具的完美示例,因此我将这些可执行图像称为。 即使它们是长期运行的过程。 话虽如此,我希望您同意分类是有意义的。 这更多是关于图像的意图,而不是有关过程是长寿还是短寿。

可执行映像的优点

那么可执行映像的优点是什么? 他们如何解决我先前描述的问题?

试验可执行映像的一个原因是,它们是使用Docker入门的好方法。 这些实验可能非常有用,并且不会影响您的生产环境。 这也很有趣!

另一个原因是易于安装。 我知道,我们有像apt-get,yum,macports和homebrew这样的软件包管理器。 至少在大多数情况下,它们通常工作正常……通常……除非您真的需要它们。 事实是,这些工具擅长于一件事:管理依赖项。 他们不太擅长管理单个软件包的两个版本,包括其依赖关系树。 容器在设计上没有依赖项:所有依赖项都烘焙到映像中。 通过运行docker run命令可以隐含安装本身。 万一在您的系统上找不到该映像,Docker将自动下载(拉出)它。 通过使用软件封装依赖性,容器映像是分发软件的可靠方法。 测试容器映像还会测试依赖项是否与主要功能一起使用。 为了每一个。

容器化的可执行文件就是这样:容器化。 换句话说:沙盒。 这降低了运行不完全受信任的软件的风险,并消除了许多程序漏洞。 一个示例是在浏览器中跟踪一条钓鱼链接。 在干净的文件系统中启动新的浏览器,以使其更加安全。 另一个错误是几个月前发生的错误 ,其中Valve的Steam删除了所有用户文件,包括连接的驱动器! Docker的沙箱并不完美,但绝对可以避免清除家庭照片库。

因为包含了过程及其依赖项,所以运行同一软件的不同版本非常容易! 通常,从Java / Maven项目开始时,您需要安装正确版本的Java Development Kit(JDK)和Maven。 使用Docker,我们可以跳过这一点。 团队成员之一可以将JDK和Maven安装在可执行映像中。 这样,任何人都可以签出源代码,并直接进行编译和测试。 您可以将基于不同JDK版本的另一个图像用于另一个项目。 您甚至可以同时编译这些项目! 而且您不必担心$ JAVA_HOME环境变量。

Maven图像

构建服务映像是为了以特定方式运行服务。 它可能需要有关其环境的信息,例如数据库的地址,但仅此而已。 可执行映像是专门用于与系统交互的工具。 有多种技术可以完成此任务。 我们将看一下Maven编译器映像以检查这些技术。 请注意,这些技术是通用的,如果您不喜欢Java,请多多包涵。

将文件作为卷传递以进行配置

假设我们有一个包含Java源代码的Maven项目。 它在项目根目录中至少包含一个pom.xml文件和一个/ src / main / java目录。 出于本文的目的,您可以采用自己喜欢的任何Maven项目。 如果您没有Maven项目,则可以在Spring Boot中下载一个(选择Maven Project作为Type)。 使用命令行cd进入项目目录(包含pom.xml文件),我们可以执行以下操作:

user:project$  docker run --rm \
               -v $(pwd):/project \
               -w /project \
               maven:3.3.3-jdk-8 mvn install

此命令执行以下操作:

  • docker run创建maven:3.3.3-jdk-8映像的容器实例。 它在容器内部执行命令mvn install。 原则上,这不会影响您的系统;
  • -v $(pwd):/ project将当前目录作为/ project挂载到容器中。 这使容器可以在系统上的当前目录中读写。
  • -w / project将/ project设置为工作目录,该目录又指向项目目录。 这意味着mvn命令将在项目目录中有效执行;
  • --rm在执行后删除容器。 甩掉包袱!

结果与直接在主机上从项目目录运行mvn install相同,而无需实际安装Java或Maven。 我们最终在项目中的目标目录中包含已编译的Java应用程序。

我们可以通过运行maven clean命令来清理项目:

user:project$  docker run --rm \
               -v $(pwd):/project \
               -w /project \
               maven:3.3.3-jdk-8 mvn clean

使用入口点传递参数

Maven映像的功能是运行mvn [args]。 因此,您可能不得不在docker命令中指定mvn,这是多余的。 为了解决这个问题,Docker提供了一个入口点。 入口点命令密切相关。 两者都可以在Dockerfile中指定。 指令分别是ENTRYPOINT和CMD。 这些指令作为元数据应用于容器映像,可以在docker run命令中覆盖这些指令。 然后我们可以执行mvn clean install,如下所示:

user:project$ docker run --rm \
              -v $(pwd):/project \
              -w /project \
              --entrypoint mvn \
              maven:3.3.3-jdk-8 clean install

入口点和命令串联在一起并执行。 好处是分离关注点。 对于可执行的容器映像,请使用入口点作为常量部分,并使用命令作为变量部分。

如果将入口点合并到容器映像中,则分隔将变得更加优雅。 为此,请在具有以下内容的其他目录中创建一个Dockerfile:

FROM maven:3.3.3-jdk-8
WORKDIR /project
ENTRYPOINT ["mvn"]
CMD ["-h"]

在这里我们还添加了工作目录,因此我们的新映像期望将Maven项目挂载为/ project。 该Dockerfile以exec形式定义了一个入口点和命令,可以用括号表示法识别,并且在shell形式之上是首选的。 使用“ docker build -t my_mvn”构建映像。 在包含Dockerfile的目录中,我们可以选择将先前的执行命令简化为:

user:project$ docker run --rm \
              -v $(pwd):/project \
              my_mvn clean install

干净安装当然可以是任何其他mvn参数。 如果您忘记包含命令,由于Dockerfile中的默认-h命令,将显示maven帮助。

入口点的另一个好用法是定义一个帮助程序脚本。 例如,如果您需要运行一些命令才能正确启动实际服务,则可以使用帮助程序脚本来解决。 或者,这样的脚本可以检查是否提供了所有必需的运行时配置,例如链接或环境变量。 该命令本身成为启动脚本的参数,但由脚本透明执行。 有关此信息和一个简单示例的更多信息,请参阅Docker文档中的Dockerfile最佳实践

为可执行映像创建别名

您也可以为可执行映像创建别名。 这样,您可以像输入常规程序一样键入简短的指令。 在您的〜/ .profile中,包括

mvn() {
  docker run --rm \
    -v $(pwd):/project \
    my_mvn $*
}

我们需要传递参数,因此我们使用函数而不是别名。 运行源〜/ .profile加载更改后,我们可以简单地使用

user:project$ mvn clean install

使用卷缓存Maven本地存储库

当前方法的缺点是现在在每次运行期间都会下载Maven工件。 本地Maven安装始终包含一个存储所有工件的存储库目录。 当前的方法很干净,但不实用。 让我们将Maven存储库添加为一个卷。 创建一个目录,例如/usr/tmp/.m2并运行

user:project$ docker run --rm \
             -v $(pwd):/project \
             -v /usr/tmp/.m2:/root/.m2 \
             my_mvn install

现在,主机上的目录/usr/tmp/.m2充满了maven下载的工件。 每次我们以这种方式启动maven容器映像时,我们都会引用该目录,因此maven可以重新使用这些工件。 运行两次mvn install来查看区别。

我们只是使Maven构建更快。 但是,我们现在必须通过在Docker主机上管理目录来为此付费。 本文的最后一步是让Docker管理该卷。 首先,创建一个命名数据容器:

user:project$ docker run --name maven_data \
              -v /root/.m2 \
              maven:3.3.3-jdk-8 echo 'data for maven'

该容器在打印“ maven数据”后退出,但创建了一个卷。 实际使用的映像并不重要:在这种情况下,maven:3.3.3-jdk-8很方便,因为已经下载了该文件,而my_mvn却不那么方便,这是因为回显之前会存在入口点声明。 注意-v /root/.m2中没有冒号:我们不再引用主机上的目录。 相反,Docker在主机上的自己的数据目录中创建一个目录。 无需在名称和命令中使用“数据”,但可以明确表明这是一个数据容器,现在将在运行docker ps时反映出来。 我们可以使用--volumes-from引用该容器的卷,而不必关心Docker将实际目录保存在何处。 这样做会将卷安装到/root/.m2下的引用容器中。 此技术对于在容器之间共享数据也很有用。 让我们在〜/ .profile中执行此操作:

mvn() {
  docker run --rm \
    -v $(pwd):/project \
    --volumes-from maven_data \
    my_mvn $*
}

现在,当我们运行mvn时,maven主目录将被映射到该卷。 Maven容器本身将被删除,但是该卷将保留在本地缓存下载的资源库中。 如果要清洁系统,请使用以下方法删除数据容器

docker rm -v maven_data

-v指示删除与容器关联的卷,以防万一

a)卷由Docker管理

b)没有其他容器引用该卷

请注意:如果您忘记使用-v选项,则最终将得到孤立卷目录。

结论

可执行容器映像是Docker的强大应用程序。 它们对于分发软件或以确定的方式在您的计算机上运行软件很有用。 而且,它们是开始尝试使用Docker的一种有趣方式。 希望您能从启发中开始尝试并使用本文中介绍的技术。

翻译自: https://www.infoq.com/articles/docker-executable-images/?topicPageSponsorship=c1246725-b0a7-43a6-9ef9-68102c8d48e1

docker删除映像

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值