分类 容器与云 下的文章

开放容器计划(OCI)和原生云计算基金会(CNCF)的代表说,Kubernetes 和容器可以在降低程序员和系统管理成本的同时加速部署进程,从被忽视的 Kubernetes 特性(比如命令空间)开始,去利用 Kubernetes 和它的相关工具运行一个原生云架构。

Kubernetes 不止是一个云容器管理器。正如 Steve Pousty,他是 Red Hat 支持的 OpenShift 的首席开发者,在 Linux 基金会开源峰会上的讲演中解释的那样,Kubernetes 提供了一个 “使用容器进行原生云计算的通用操作平台”。

Pousty 的意思是什么?先让我们复习一下基础知识。

开源容器计划(OCI)和 原生云计算基金会 (CNCF)的执行董事 Chris Aniszczyk 的解释是,“原生云计算使用开源软件栈将应用程序部署为微服务,打包每一个部分到其容器中,并且动态地编排这些容器以优化资源使用”。Kubernetes 一直在关注着原生云计算的最新要素。这将最终将导致 IT 中很大的一部分发生转变,如从服务器到虚拟机,从 构建包 buildpack 到现在的 容器

会议主持人表示,数据中心的演变将节省相当可观的成本,部分原因是它需要更少的专职员工。例如,据 Aniszczyk 说,通过使用 Kubernetes,谷歌每 10000 台机器仅需要一个网站可靠性工程师(LCTT 译注:即 SRE)。

实际上,系统管理员可以利用新的 Kubernetes 相关的工具的优势,并了解那些被低估的功能。

构建一个原生云平台

Pousty 解释说,“对于 Red Hat 来说,Kubernetes 是云 Linux 的内核。它是每个人都可以构建于其上的基础设施”。

例如,假如你在一个容器镜像中有一个应用程序。你怎么知道它是安全的呢? Red Hat 和其它的公司使用 OpenSCAP,它是基于 安全内容自动化协议 Security Content Automation Protocol (SCAP)的,是使用标准化的方式表达和操作安全数据的一个规范。OpenSCAP 项目提供了一个开源的强化指南和配置基准。选择一个合适的安全策略,然后,使用 OpenSCAP 认可的安全工具去使某些由 Kubernetes 控制的容器中的程序遵守这些定制的安全标准。

Red Hat 将使用 原子扫描 Atomic Scan 来自动处理这个过程;它借助 OpenSCAP 提供者 provider 来扫描容器镜像中已知的安全漏洞和策略配置问题。原子扫描会以只读方式加载文件系统。这些通过扫描的容器,会在一个可写入的目录存放扫描器的输出。

Pousty 指出,这种方法有几个好处,主要是,“你可以扫描一个容器镜像而不用实际运行它”。因此,如果在容器中有糟糕的代码或有缺陷的安全策略,它不会影响到你的系统。

原子扫描比手动运行 OpenSCAP 快很多。 因为容器从启用到消毁可能就在几分钟或几小时内,原子扫描允许 Kubernetes 用户在(很快的)容器生命期间保持容器安全,而不是在更缓慢的系统管理时间跨度里进行。

关于工具

帮助系统管理员和 DevOps 管理大部分 Kubernetes 操作的另一个工具是 CRI-O。这是一个基于 OCI 实现的 Kubernetes 容器运行时接口。CRI-O 是一个守护进程, Kubernetes 可以用于运行存储在 Docker 仓库中的容器镜像,Dan Walsh 解释说,他是 Red Hat 的顾问工程师和 SELinux 项目领导者。它允许你直接从 Kubernetes 中启动容器镜像,而不用花费时间和 CPU 处理时间在 Docker 引擎 上启动。并且它的镜像格式是与容器无关的。

在 Kubernetes 中, kubelet 管理 pod(容器集群)。使用 CRI-O,Kubernetes 及其 kubelet 可以管理容器的整个生命周期。这个工具也不是和 Docker 镜像捆绑在一起的。你也可以使用新的 OCI 镜像格式CoreOS 的 rkt 容器镜像。

同时,这些工具正在成为一个 Kubernetes 栈:编排系统、容器运行时接口 (CRI)和 CRI-O。Kubernetes 首席工程师 Kelsey Hightower 说,“我们实际上不需要这么多的容器运行时——无论它是 Docker 还是 rkt。只需要给我们一个到内核的 API 就行”,这个结果是这些技术人员的承诺,是推动容器比以往更快发展的强大动力。

Kubernetes 也可以加速构建容器镜像。目前为止,有三种方法来构建容器。第一种方法是通过一个 Docker 或者 CoreOS 去构建容器。第二种方法是注入定制代码到一个预构建镜像中。最后一种方法是, 资产生成管道 Asset Generation Pipeline 使用容器去编译那些 资产 asset ,然后其被包含到使用 Docker 的 多阶段构建 Multi-Stage Build 所构建的随后镜像中。

现在,还有一个 Kubernetes 原生的方法:Red Hat 的 Buildah, 这是一个脚本化的 shell 工具 用于快速、高效地构建 OCI 兼容的镜像和容器。Buildah 降低了容器环境的学习曲线,简化了创建、构建和更新镜像的难度。Pousty 说。你可以使用它和 Kubernetes 一起基于应用程序的调用来自动创建和使用容器。Buildah 也更节省系统资源,因为它不需要容器运行时守护进程。

因此,比起真实地引导一个容器和在容器内按步骤操作,Pousty 说,“挂载该文件系统,就如同它是一个常规的文件系统一样做一些正常操作,并且在最后提交”。

这意味着你可以从一个仓库中拉取一个镜像,创建它所匹配的容器,并且优化它。然后,你可以使用 Kubernetes 中的 Buildah 在你需要时去创建一个新的运行镜像。最终结果是,他说,运行 Kubernetes 管理的容器化应用程序比以往速度更快,需要的资源更少。

你所不知道的 Kubernetes 拥有的特性

你不需要在其它地方寻找工具。Kubernetes 有几个被低估的特性。

根据谷歌云全球产品经理 Allan Naim 的说法,其中一个是 Kubernetes 命名空间。Naim 在开源峰会上谈及 “Kubernetes 最佳实践”,他说,“很少有人使用命名空间,这是一个失误。”

“命名空间是将一个单个的 Kubernetes 集群分成多个虚拟集群的方法”,Naim 说。例如,“你可以认为命名空间就是 姓氏 family name ”,因此,假如说 “Simth” 用来标识一个家族,如果有个成员 Steve Smith,他的名字就是 “Steve”,但是,家族范围之外的,它就是 “Steve Smith” 或称 “来自 Chicago 的 Steve Smith”。

严格来说,“命名空间是一个逻辑分区技术,它允许一个 Kubernetes 集群被多个用户、用户团队或者一个用户的多个不能混淆的应用程序所使用。Naim 解释说,“每个用户、用户团队、或者应用程序都可以存在于它的命名空间中,与集群中的其他用户是隔离的,并且可以像你是这个集群的唯一用户一样操作它。”

Practically 说,你可以使用命名空间去构建一个企业的多个业务/技术的实体进入 Kubernetes。例如,云架构可以通过映射产品、地点、团队和成本中心为命名空间,从而定义公司的命名空间策略。

Naim 建议的另外的方法是,去使用命名空间将软件开发 流程 pipeline 划分到分离的命名空间中,如测试、质量保证、 预演 staging 和成品等常见阶段。或者命名空间也可以用于管理单独的客户。例如,你可以为每个客户、客户项目、或者客户业务单元去创建一个单独的命名空间。它可以更容易地区分项目,避免重用相同名字的资源。

然而,Kubernetes 现在还没有提供一个跨命名空间访问的控制机制。因此,Naim 建议你不要使用这种方法去对外公开程序。还要注意的是,命名空间也不是一个管理的“万能药”。例如,你不能将命名空间嵌套在另一个命名空间中。另外,也没有跨命名空间的强制安全机制。

尽管如此,小心地使用命名空间,还是很有用的。

以人为中心的建议

从谈论较深奥的技术换到项目管理。Pousty 建议,在转移到原生云和微服务架构时,在你的团队中要有一个微服务操作人员。“如果你去做微服务,你的团队最终做的就是 Ops-y。并且,不去使用已经知道这种操作的人是愚蠢的行为”,他说。“你需要一个正确的团队核心能力。我不想开发人员重新打造运维的轮子”。

而是,将你的工作流彻底地改造成一个能够使用容器和云的过程,对此,Kubernetes 是很适用的。

使用 Kubernetes 的原生云计算:领导者的课程

  • 迅速扩大的原生云生态系统。寻找可以扩展你使用容器的方法的工具。
  • 探索鲜为人知的 Kubernetes 特性,如命名空间。它们可以改善你的组织和自动化程度。
  • 确保部署到容器的开发团队有一个 Ops 人员参与。否则,冲突将不可避免。

作者简介:

Steven J. Vaughan-Nichols, Vaughan-Nichols & Associates 的 CEO

Steven J. Vaughan-Nichols,即 sjvn,是一个技术方面的作家,从 CP/M-80 还是前沿技术、PC 操作系统、300bps 是非常快的因特网连接、WordStar 是最先进的文字处理程序的那个时候开始,一直从事于商业技术的写作,而且喜欢它。他的作品已经发布在了从高科技出版物(IEEE Computer、ACM Network、 Byte)到商业出版物(eWEEK、 InformationWeek、ZDNet),从大众科技(Computer Shopper、PC Magazine、PC World)再到主流出版商(Washington Post、San Francisco Chronicle、BusinessWeek) 等媒体之上。


via: https://insights.hpe.com/articles/how-to-implement-cloud-native-computing-with-kubernetes-1710.html

作者:Steven J. Vaughan-Nichols 译者:qhwdw 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

去年,Kubernetes 项目推出了 容器运行时接口 Container Runtime Interface (CRI):这是一个插件接口,它让 kubelet(用于创建 pod 和启动容器的集群节点代理)有使用不同的兼容 OCI 的容器运行时的能力,而不需要重新编译 Kubernetes。在这项工作的基础上,CRI-O 项目(原名 OCID)准备为 Kubernetes 提供轻量级的运行时。

那么这个真正的是什么意思?

CRI-O 允许你直接从 Kubernetes 运行容器,而不需要任何不必要的代码或工具。只要容器符合 OCI 标准,CRI-O 就可以运行它,去除外来的工具,并让容器做其擅长的事情:加速你的新一代原生云程序。

在引入 CRI 之前,Kubernetes 通过“一个内部的易失性接口”与特定的容器运行时相关联。这导致了上游 Kubernetes 社区以及在编排平台之上构建解决方案的供应商的大量维护开销。

使用 CRI,Kubernetes 可以与容器运行时无关。容器运行时的提供者不需要实现 Kubernetes 已经提供的功能。这是社区的胜利,因为它让项目独立进行,同时仍然可以共同工作。

在大多数情况下,我们不认为 Kubernetes 的用户(或 Kubernetes 的发行版,如 OpenShift)真的关心容器运行时。他们希望它工作,但他们不希望考虑太多。就像你(通常)不关心机器上是否有 GNU Bash、Korn、Zsh 或其它符合 POSIX 标准 shell。你只是要一个标准的方式来运行你的脚本或程序而已。

CRI-O:Kubernetes 的轻量级容器运行时

这就是 CRI-O 提供的。该名称来自 CRI 和开放容器计划(OCI),因为 CRI-O 严格关注兼容 OCI 的运行时和容器镜像。

现在,CRI-O 支持 runc 和 Clear Container 运行时,尽管它应该支持任何遵循 OCI 的运行时。它可以从任何容器仓库中拉取镜像,并使用 容器网络接口 Container Network Interface (CNI)处理网络,以便任何兼容 CNI 的网络插件可与该项目一起使用。

当 Kubernetes 需要运行容器时,它会与 CRI-O 进行通信,CRI-O 守护程序与 runc(或另一个符合 OCI 标准的运行时)一起启动容器。当 Kubernetes 需要停止容器时,CRI-O 会来处理。这没什么令人兴奋的,它只是在幕后管理 Linux 容器,以便用户不需要担心这个关键的容器编排。

 title=

CRI-O 不是什么

值得花一点时间了解下 CRI-O 不是什么。CRI-O 的范围是与 Kubernetes 一起工作来管理和运行 OCI 容器。这不是一个面向开发人员的工具,尽管该项目确实有一些面向用户的工具进行故障排除。

例如,构建镜像超出了 CRI-O 的范围,这些留给像 Docker 的构建命令、 BuildahOpenShift 的 Source-to-Image(S2I)这样的工具。一旦构建完镜像,CRI-O 将乐意运行它,但构建镜像留给其他工具。

虽然 CRI-O 包含命令行界面 (CLI),但它主要用于测试 CRI-O,而不是真正用于在生产环境中管理容器的方法。

下一步

现在 CRI-O 1.0 发布了,我们希望看到它作为一个稳定功能在下一个 Kubernetes 版本中发布。1.0 版本将与 Kubernetes 1.7.x 系列一起使用,即将发布的 CRI-O 1.8-rc1 适合 Kubernetes 1.8.x。

我们邀请您加入我们,以促进开源 CRI-O 项目的开发,并感谢我们目前的贡献者为达成这一里程碑而提供的帮助。如果你想贡献或者关注开发,就去 CRI-O 项目的 GitHub 仓库,然后关注 CRI-O 博客


via: https://www.redhat.com/en/blog/introducing-cri-o-10

作者:Joe Brockmeier 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

IBM 的 Ken Parmelee 说:“微服务和 API 是产品,我们需要以这种方式思考。”

领导 IBM 的 API 网关和 Big Blue 开源项目的的 Ken Parmelee 对以开源方式 “进攻” API 以及如何创建微服务和使其伸缩有一些思考。

Parmelee 说:“微服务和 API 是产品,我们需要以这种方式思考这些问题。当你开始这么做,人们依赖它作为它们业务的一部分。这是你在这个领域所做的关键方面。”

他在最近的北欧 APIs 2017 平台峰会登上讲台,并挑战了一些流行的观念。

“快速失败不是一个很好的概念。你想在第一场比赛中获得一些非常棒的东西。这并不意味着你需要花费大量的时间,而是应该让它变得非常棒,然后不断的发展和改进。如果一开始真的很糟糕,人们就不会想要用你。”

他谈及包括 OpenWhisk 在内的 IBM 现代无服务器架构,这是一个 IBM 和 Apache 之间的开源伙伴关系。 云优先的基于分布式事件的编程服务是这两年多来重点关注这个领域的成果;IBM 是该领域领先的贡献者,它是 IBM 云服务的基础。它提供基础设施即服务(IaaS)、自动缩放、为多种语言提供支持、用户只需支付实际使用费用即可。这次旅程充满了挑战,因为他们发现服务器操作需要安全、并且需要轻松 —— 匿名访问、缺少使用路径、固定的 URL 格式等。

任何人都可以在 30 秒内在 https://console.bluemix.net/openwhisk/ 上尝试这些无服务器 API。“这听起来很有噱头,但这是很容易做到的。我们正在结合 Cloud Foundry 中完成的工作,并在 OpenWhisk 下的 Bluemix 中发布了它们,以提供安全性和可扩展性。”

他说:“灵活性对于微服务也是非常重要的。 当你使用 API 在现实世界中工作时,你开始需要跨云进行扩展。”这意味着从你的内部云走向公共云,并且“对你要怎么做有一个实在的概念很重要”。

在思考“任何云概念”的时候,他警告说,不是“将其放入一个 Docker 容器,并到处运行。这很棒,但需要在这些环境中有效运行。Docker 和 Kubernetes 有提供了很多帮助,但是你想要你的操作方式付诸实施。” 提前考虑 API 的使用,无论是在内部运行还是扩展到公有云并可以公开调用 - 你需要有这样的“架构观”,他补充道。

Parmelee 说:“我们都希望我们所创造的有价值,并被广泛使用。” API 越成功,将其提升到更高水平的挑战就越大。

API 是微服务或“服务间”的组成部分。

他说,API 的未来是原生云的 - 无论你从哪里开始。关键因素是可扩展性,简化后端管理,降低成本,避免厂商锁定。

你可以在下面或在 YouTube 观看他整整 23 分钟的演讲。


via: http://superuser.openstack.org/articles/deploy-multi-cloud-serverless-cloud-foundry-apis-scale/

作者:Superuser 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

Google 的 Grafeas 为容器的元数据提供了一个从镜像、构建细节到安全漏洞的通用 API。

我们运行的软件从来没有比今天更难获得。它分散在本地部署和云服务之间,由不知到有多少的开源组件构建而成,以快速的时间表交付,因此保证安全和质量变成了一个挑战。

最终的结果是软件难以审计、推断、安全化和管理。困难的不只是知道 VM 或容器是用什么构建的, 而是由谁来添加、删除或更改的。Grafeas 最初由 Google 设计,旨在使这些问题更容易解决。

什么是 Grafeas?

Grafeas 是一个定义软件组件的元数据 API 的开源项目。旨在提供一个统一的元数据模式,允许 VM、容器、JAR 文件和其他软件 工件 artifact 描述自己的运行环境以及管理它们的用户。目标是允许像在给定环境中使用的软件一样的审计,以及对该软件所做的更改的审计,并以一致和可靠的方式进行。

Grafeas提供两种格式的元数据 API —— 备注和事件:

  • 备注 note 是有关软件工件的某些方面的细节。可以是已知软件漏洞的描述,有关如何构建软件的详细信息(构建器版本、校验和等),部署历史等。
  • 事件 occurrence 是备注的实例,包含了它们创建的地方和方式的细节。例如,已知软件漏洞的详细信息可能会有描述哪个漏洞扫描程序检测到它的情况、何时被检测到的事件信息,以及该漏洞是否被解决。

备注和事件都存储在仓库中。每个备注和事件都使用标识符进行跟踪,该标识符区分它并使其唯一。

Grafeas 规范包括备注类型的几个基本模式。例如,软件包漏洞模式描述了如何存储 CVE 或漏洞描述的备注信息。现在没有接受新模式类型的正式流程,但是这已经在计划创建这样一个流程。

Grafeas 客户端和第三方支持

现在,Grafeas 主要作为规范和参考形式存在,它在 GitHub 上提供GoPythonJava 的客户端都可以用 Swagger 生成,所以其他语言的客户端也应该不难写出来。

Google 计划让 Grafeas 广泛使用的主要方式是通过 Kubernetes。 Kubernetes 的一个名为 Kritis 的策略引擎,可以根据 Grafeas 元数据对容器采取措施。

除 Google 之外的几家公司已经宣布计划将 Grafeas 的支持添加到现有产品中。例如,CoreOS 正在考察 Grafeas 如何与 Tectonic 集成,Red HatIBM 都计划在其容器产品和服务中添加 Grafeas 集成。


via: https://www.infoworld.com/article/3230462/security/what-is-grafeas-better-auditing-for-containers.html

作者:Serdar Yegulalp 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

云集成高级编排器 Cloud Integrated Advanced Orchestrator (Ciao) 是一个新的负载调度程序,用来解决当前云操作系统项目的局限性。Ciao 提供了一个轻量级,完全基于 TLS 的最小配置。它是 工作量无关的、易于更新、具有优化速度的调度程序,目前已针对 OpenStack 进行了优化。

其设计决策和创新方法在对安全性、可扩展性、可用性和可部署性的要求下进行:

  • 可扩展性: 初始设计目标是伸缩超过 5,000 个节点。因此,调度器架构用新的形式实现:

    • 在 ciao 中,决策制定是去中心化的。它基于拉取模型,允许计算节点从调度代理请求作业。调度程序总能知道启动器的容量,而不要求进行数据更新,并且将调度决策时间保持在最小。启动器异步向调度程序发送容量。
    • 持久化状态跟踪与调度程序决策制定相分离,它让调度程序保持轻量级。这种分离增加了可靠性、可扩展性和性能。结果是调度程序让出了权限并且这不是瓶颈。
  • 可用性: 虚拟机、容器和裸机集成到一个调度器中。所有的负载都被视为平等公民。为了更易于使用,网络通过一个组件间最小化的异步协议进行简化,只需要最少的配置。Ciao 还包括一个新的、简单的 UI。所有的这些功能都集成到一起来简化安装、配置、维护和操作。
  • 轻松部署: 升级应该是预期操作,而不是例外情况。这种新的去中心化状态的体系结构能够无缝升级。为了确保基础设施(例如 OpenStack)始终是最新的,它实现了持续集成/持续交付(CI/CD)模型。Ciao 的设计使得它可以立即杀死任何 Ciao 组件,更换它,并重新启动它,对可用性影响最小。
  • 安全性是必需的: 与调度程序的连接总是加密的:默认情况下 SSL 是打开的,而不是关闭的。加密是从端到端:所有外部连接都需要 HTTPS,组件之间的内部通信是基于 TLS 的。网络支持的一体化保障了租户分离。

初步结果证明是显著的:在 65 秒内启动一万个 Docker 容器和五千个虚拟机。进一步优化还在进行。


via: https://clearlinux.org/ciao

作者:ciao 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

docker

之前的文章中我们提到可以通过容器创建一个我们自定义过的镜像,那么我们是否可以直接通过基础的镜像直接自定义镜像呢?答案当然是可以的,在 Docker 中我们可以从名为 Dockerfile 的文件中读取指令并且自动构建镜像。在本文中,将介绍 Dockerfile 的基本语法以及基本知识。

1、Dockerfile 是什么?

Dockerfile 其实是一份文本文档,里面包含了用户可以用来操作镜像的一些指令。通过顺序执行这些指令,最后得到一个自定义的镜像,这有点类似于我们的 shell 脚本。

2、Dockerfile 示例

接下来先看一个 Dockerfile 示例:

FROM centos
LABEL maintainer="Locez <[email protected]>"
ENV TEST="This is a test env"
COPY nginx.repo /etc/yum.repos.d/nginx.repo
RUN yum update -y && \
        yum install -y nginx
COPY nginx.conf /etc/nginx/nginx.conf
COPY index.html /usr/share/nginx/html/index.html
COPY index_files/ /usr/share/nginx/html/index_files/
EXPOSE 80
CMD ["/usr/sbin/nginx","-g","daemon off;"]

在上面我们可以看到 Dockerfile 中的一些指令,通过名称我们也可以猜到这些指令大概是干嘛的,其中有一些对文件的操作,因此我们先来看看用于存放 Dockerfile 的这个目录的目录结构:

# tree .
.
├── Dockerfile
├── index_files
│   ├── 145049z4og8xyjhx4xy8go.jpg
│   ├── 222746e5vh38d7ey3leyps.jpg
│   ├── 88x31.png
│   ├── archlinux-splash.png
│   ├── bdshare.css
│   ├── Best-Linux-Markdown-Editors.png
│   ├── core.js
│   ├── docker-icon.jpg
│   ├── hadoop-pic1.png
│   ├── jquery_002.js
│   ├── jquery.css
│   ├── jquery.js
│   ├── MathJax.js
│   ├── pic.gif
│   ├── raspberrypiraspberry-pi-logo.jpg
│   ├── script.js
│   ├── scrollup.png
│   ├── share.js
│   ├── style.css
│   └── z_stat.js
├── index.html
├── nginx.conf
└── nginx.repo

1 directory, 24 files

构建镜像

在当前目录下执行以下命令构建镜像:

# docker build -t locez/nginx .
Sending build context to Docker daemon 1.851 MB
Step 1/10 : FROM centos
 ---> 196e0ce0c9fb
Step 2/10 : LABEL maintainer "Locez <[email protected]>"
 ---> Using cache
 ---> 9bba3042bcdb
Step 3/10 : ENV TEST "This is a test env"
 ---> Using cache
 ---> c0ffe95ea0c5
Step 4/10 : COPY nginx.repo /etc/yum.repos.d/nginx.repo
 ---> Using cache
 ---> bb6ee4c30d56
Step 5/10 : RUN yum update -y &&        yum install -y nginx
 ---> Using cache
 ---> 6d46b41099c3
Step 6/10 : COPY nginx.conf /etc/nginx/nginx.conf
 ---> Using cache
 ---> cfe908390aae
Step 7/10 : COPY index.html /usr/share/nginx/html/index.html
 ---> Using cache
 ---> 21729476079d
Step 8/10 : COPY index_files/ /usr/share/nginx/html/index_files/
 ---> Using cache
 ---> 662f06ec7b46
Step 9/10 : EXPOSE 80
 ---> Using cache
 ---> 30db5a889d0a
Step 10/10 : CMD /usr/sbin/nginx -g daemon off;
 ---> Using cache
 ---> d29b9d4036d2
Successfully built d29b9d4036d2

然后用该镜像启动容器:

# docker run -d -it --rm --name test-nginx -p 8080:80 locez/nginx
e06fd991ca1b202e08cf1578f8046355fcbba10dd9a90e11d43282f3a1e36d29

用浏览器访问 http://localhost:8080/ 即可看到部署的内容。

3 Dockerfile 指令解释

Dockerfile 支持 FROMRUNCMDLABELEXPOSEENVADDCOPYENTRYPOINTVOLUMEUSERWORKDIRARGONBUILDSHELL 等指令,这里只选择常用的几个进行讲解,可结合上面的示例进行理解。其它的请自行查阅官方文档。

3.1 FROM

FROM 指令用于指定要操作的基础镜像,因为在我们构建我们自己的镜像的时候需要一个基础镜像。 语法:

FROM <image> [AS <name>]
FROM <image>[:<tag>] [AS <name>]

其中 [AS <name>] 为指定一个名称,在一个 Dockerfile 中多次使用 FROM 时如有需要,可用 COPY --from=<name|index> 语法进行复制。

3.2 RUN

RUN 指令用于执行命令,并且是在新的一层上执行,并把执行后的结果提交,也就是生成新的一层。基于这个问题,我们在使用 RUN 指令时应该尽可能的把要执行的命令一次写完,以减少最后生成的镜像的层数。 语法:

RUN <command>
RUN ["executable", "param1", "param2"]

3.3 CMD

CMD 指令用于给容器启动时指定一个用于执行的命令,例如上例中的 nginx 启动命令。 语法:

CMD ["executable","param1","param2"]
CMD ["param1","param2"] ### 用于给 ENTRYPOINT 指令提供默认参数
CMD command param1 param2

3.4 LABEL

LABEL 指令用于为镜像指定标签,可用 docker inspect 命令查看。可用来代替被舍弃的 MAINTAINER 命令。 语法:

LABEL <key>=<value> <key>=<value> <key>=<value> ...

3.5 EXPOSE

EXPOSE 指令用于告诉 Docker 容器监听的特殊端口,但是此时端口还没有暴露给 host ,只有当在运行一个容器显式用参数 -p 或者 -P 的时候才会暴露端口。 语法:

EXPOSE <port> [<port>/<protocol>...]

3.6 ENV

ENV 指令用于设定环境变量。 语法:

ENV <key> <value>
ENV <key>=<value> ...

3.7 ADD

ADD 指令用于复制新文件,目录,远程文件到容器中。其中 <src> 可以为文件,目录,URL,若为可解压文件,在复制后会解压。 语法:

ADD <src>... <dest>
ADD ["<src>",... "<dest>"]

3.8 COPY

COPY 指令与 ADD 指令非常相似,但 COPY 比较直观且简单,它只支持本地的文件以及目录的复制,不像 ADD 指令可以远程获取文件并解压。 语法:

COPY <src>... <dest>
COPY ["<src>",... "<dest>"]

3.9 ENTRYPOINT

ENTRYPOINT 指令也跟 CMD 指令相似,用于指定容器启动时执行的命令。当使用 ENTRYPOINT 指令时,可用 CMD 命令配合,这样在启动容器时,可以对 CMD 指令写入的参数进行覆盖。 语法:

ENTRYPOINT ["executable", "param1", "param2"]

例子:

ENTRYPOINT ["top","-b"]
CMD ["-c"]

上面的 -c 参数可以在启动时覆盖 docker run -it --rm --name test top -H。 如果要覆盖 ENTRYPOINT 指令则用 --entrypoint 参数启动容器。

3.10 VOLUME

VOLUME 指令用于为容器创建一个挂载点,这个挂载点可以用来挂载 本地文件/文件夹 也可以用来挂载 数据卷。其中若在启动一个新容器时没有指定挂载目录,则会自动创建一个数据卷,当容器被销毁时,数据卷如果没有被其它容器引用则会被删除。 语法:

VOLUME ["/data1","/data2"]

3.11 USER

USER 指令用于设置执行 RUN, CMD, ENTRYPOINT 等指令的用户以及用户组。默认为 root 用户。 语法:

USER <user>[:<group>]

3.12 WORKDIR

WORKDIR 指令用于设置 RUN, CMD, ENTRYPOINT, COPY, ADD 等指令的工作目录。 语法:

WORKDIR /path/to/workdir

4 总结


本文从一个具体的例子出发,讲述了如何利用 Dockerfile 构建镜像,然后解释了 Dockerfile 文件中的指令的语法,有关更多内容可访问官方文档。

5 参考资料