作者:Frank Munz 博士
2017 年 2 月
本文介绍 Docker 及其在云中的使用。第一部分简要介绍 Docker,并鼓励将其用作 PaaS 服务。第二部分介绍 Oracle 容器云服务 (OCCS),并对 OCCS 的关键组件加以说明。
在过去三年中,Docker 取得了巨大的成功。它从 2014 年默默无闻、偏向技术性的开源技术,已经发展成为现在获得众多 Oracle 企业产品官方支持的标准化运行时环境。
Docker 的核心概念是映像和容器。Docker 映像包含软件运行所需的一切:代码、运行时(如 JVM)、驱动程序、工具、脚本、库、部署等。
Docker 容器是 Docker 映像的一个运行实例。不过,与采用类型 1 或类型 2 虚拟机管理程序的传统虚拟化不同,Docker 容器在主机操作系统的内核上运行。Docker 映像中没有单独的操作系统,如图 1 所示。
图 1
每个 Docker 容器都有自己的文件系统、自己的网络堆栈(因此有自己的 IP 地址)、自己的进程空间,以及明确的 CPU 和内存资源限制。由于 Docker 容器不必启动操作系统,因此它可以立即启动。Docker 的一个主要特性就是隔离,即分离主机操作系统的资源,有别于虚拟化,后者是在主机操作系统上提供一个来宾操作系统。
Docker 映像的文件系统是分层的,具有写时复制语义。这样可以实现继承和重用,节省磁盘上的资源,还可以实现增量映像下载。
图 2
如图 2 所示,包含 WebLogic 部署的 Docker 映像可以基于包含 WebLogic 域的映像,包含 WebLogic 域的映像可以基于 WebLogic 映像,WebLogic 映像基于 JDK 映像,JDK 映像又基于 Oracle Linux 基本映像。
Docker 与 VirtualBox 之间的另一个主要区别是大量可用的映像。公共 Docker Hub 提供了超过 10 万个含 Docker 映像的信息库。Docker Hub 包含来自官方信息库(如 NGINX、Logstash、Apache HTTP、Grafana、MySQL、Ubuntu 和 Oracle Linux)的软件和应用。
启动容器时,如果本地不存在对应的映像,Docker 将自动从公共 Docker Hub 下载。而且,您还可以创建自己的映像,并将其推送到 Docker Hub,进入公共或私有信息库。
图 3
到目前为止,Docker Hub 映像的下载次数已超过 50 亿 [4]。
目前,将单体应用切割成较小的微服务块的想法在软件开发人员中引起了广泛关注。
微服务作为进程独立部署,使用轻量级协议彼此通信,每个服务拥有自己的数据 [7]。由于遵循分散式治理方式,微服务需要大量基础设施自动化、自动化测试、全自动 CD 管道和熟练、敏捷的 DevOps 团队。
关于这种架构样式仍然存在大量讨论,但如果认为分解成微服务的应用可以简单地作为一组进程来操作,就太天真了。我们来列举几个要求,比如,微服务需要独立于主机,并在操作系统级别隔离。它必须在其资源限制内运行,必须能够扩展和收缩,失败时可以重新启动,并且必须通过软件定义的网络层被发现和连接到其他微服务。
因此,在 Docker 容器中运行微服务可以成为您实现其中大多数目标的绝佳跳板。
Docker 从两个不同维度改变了我们构建、交付和运行软件的方式:
创建一个包含所有依赖项的 Docker 映像解决了“但在我的开发机器上工作正常”的问题。关键想法就是 Docker 映像由一个源代码信息库(如 Git)的构建管道自动创建,并在开发环境中进行初始测试。然后将这个不可变映像存储在 Docker 注册表中。
如图 4 所示,这个映像将用于进一步的负载测试、集成测试、验收测试等。在每个环境中,将使用相同的映像。一些小但必需的环境特定的差异(如生产数据库的 JDBC URL)可以作为环境变量或文件提供给容器。
图 4
统计信息显示,目前所有 Docker 用例中,有 65% 正在开发中,48% 使用 Docker 进行持续集成 [5]。
Docker 改变了公有云的采用:一方面,使用 Docker 映像,史上首次出现了一个既可以在内部部署环境运行,又可以在每个主要云提供商上运行的通用包格式。Docker 容器在我的笔记本电脑上运行的方式与在 Oracle 云上运行的方式相同。
另一方面,由于 Docker 容器在每个主要的公有云上运行,因此有助于消除长久以来对公有云的偏见:供应商锁定。现在,每个主要云供应商都将 Docker 作为 PaaS 提供。
Docker 发布的速度比传统企业软件的发布周期快得多。有时,Docker 飞快的发布速度加上 Docker 项目的新颖性,会引发人们对 Docker 安全性和稳定性的担忧。
虽然 Docker 及其命令行、Docker 后台进程、其 API 以及 Docker Swarm、Docker Machine 和 Docker Compose 等工具是最近三年才发展起来的,但底层内核特性已在每个 Linux 内核中存在了近十年。
一个著名的容器技术早期采用者的例子就是 Google。Google 使用 Linux 容器的历史甚至早在 Docker 出现之前。而且,Google 在容器中运行所有内容。据估计,Google 每周要启动 20 亿个容器 [3]。
Docker 使用的底层 Linux 内核特性是 cgroup 和命名空间。2008 年,在 Google 开发人员先前完成的工作基础上,cgroup 被引入 Linux 内核 [1]。Cgroup 限制并负责管理一组操作系统进程的资源使用。
Linux 内核使用命名空间来隔离进程的系统资源。早在 2002 年就推出了第一个命名空间,即挂载命名空间。
Oracle 很早就赶上了 Docker 的潮流。第一个官方支持产品是 WebLogic。截至本文撰写时,官方支持以下 Oracle 产品:
此外,Dockerfile 还可用于为开源项目构建映像,包括:
请注意,截至本文撰写时,Docker hub 不提供 Oracle 企业软件。要在 Docker 容器中运行 Oracle 企业软件,您必须从 https://github.com/oracle/docker-images 下载预定义的构建脚本,添加产品安装程序,然后运行脚本创建您自己的本地 Docker 映像。
本文的第一部分解释了一些重要的 Docker 概念。但在生产环境中,仅仅在 Docker 容器中运行应用是不够的。
要搭建和运行一个生产环境,所涉及的因素还有很多:运行容器需要硬件;还必须安装、升级和修补 Docker 本身以及信息库和集群管理器等软件。如果多个 Docker 容器在主机之间通信,则必须创建一个网络。集群容器出现故障时应重新启动。此外,您还希望一组彼此链接的容器应该像单个容器实例那样容易部署。
例如,一个负载平衡器、几个 Web 服务器、一些 WebLogic Server 实例(包含管理服务器和受管服务器),以及一个数据库。
OCCS 是 Oracle 云版图中的新成员。它是一个 PaaS 服务,能够满足在生产环境中运行 Docker 的这些额外要求。以下段落将更详细地解释 OCCS 的重要概念。
要开始使用 Oracle 容器云服务,首先要定义一个 OCCS 服务,代表一组用于 OCCS 的主机。服务始终由一个管理节点和一个或多个工作节点组成。
管理节点安排将容器部署到工作节点。工作节点托管容器或容器堆栈。一个服务的一组工作节点稍后可以再分成池,用于构建资源组。
每个配置好的 OCCS 服务都有自己的管理员用户和密码。要设置 OCCS 服务,需要定义服务名称,然后再创建一个新的 SSH 密钥或指定一个现有的 SSH 密钥。使用此 SSH 密钥,您可以从命令行连接到服务。
图 5 显示了两种不同的 OCCS 服务。
图 5
设置工作节点时,可以指定底层计算模型、所用工作节点总数以及工作节点的数据卷大小,如图 6 所示。
图 6
定义了 OCCS 服务之后,您就可以在控制台中看到其管理节点和工作节点。图 7 显示了一个具有三个工作节点的服务,包括各节点的主机名、IP 地址、内存和存储设置。
图 7
OCCS 服务内的主机进一步划分成资源池。资源池是主机(工作节点)的集合,用于放置服务的容器。您可以创建任意数量的资源池,标记池,并为池分配资源作为工作节点。创建服务时,还要定义默认的资源池。
您还可以将主机从一个资源池移到另一个资源池。例如,您可以将默认池中最初的三个工作节点中的两个移到开发池,如图 8 所示。
图 8
OCCS 自带了几个预定义的 OCCS 容器服务。OCCS 容器服务定义了一个 Docker 服务以及运行 Docker 映像及其部署指令所必需的配置设置。
您可以从预先配置的现有服务列表中选择一个 OCCS 容器服务,也可以定义自己的服务(图 9)。
图 9
对于选定的服务,您可以选择其资源池作为目标,参见图 10 中的 (1)。此外,还可以选择多种编排设置:
图 10
启动 n 个容器时,可以选择其可用性 (2)。
调度策略 (3) 定义如何确定主机的顺序。
可以为某些主机或标记指定约束,进一步限制主机排位。
OCCS 与 Docker 容器的经典运行方式融为一体。可以通过三种不同的方式来指定如何运行服务。
您可以使用图形构建器向导构造一个命令运行服务,比如说,您对 Docker 命令行不太熟悉。使用 Builder 向导,您可以轻松指定 Docker 运行命令的参数:映像名称、要运行的默认命令、传递给容器的环境变量以及各种开关。
图 11 显示了在如 [8] 中所述的 Docker 容器中运行的 Grafana 服务的构建器向导。
图 11
另一种方法是 Docker run 选项卡。向导中的信息以纯文本的形式显示在 Docker run 选项卡中,可以在此处进行编辑,也可以从 Docker Hub 之类的地方复制粘贴一条 Docker run 命令。
图 12 以 Docker run 命令的形式显示了与上面的 Builder 向导中相同的信息。
图 12
在内部,OCCS 使用文档形式的 YAML 表示,您可以在第三个选项卡中查看和编辑,如图 13 所示。
图 13
OCCS 不仅定义和部署单个服务。您还可以将服务链接到一起,作为一个堆栈一起启动。OCCS 控制台已经自带了几个预定义的堆栈示例,如包含数据库的 Wordpress,或包含主从节点的 Redis 集群。
堆栈由 YAML 文件定义,该文件中列出所包含的服务。您可以为堆栈内的每个服务定义环境变量。
您可以在图形编辑器中用现有的 OCCS 服务组成这些堆栈,如图 14 所示。
图 14
或者,您还可以从以下 GitHub 信息库下载源代码,自己构建示例堆栈:
https://github.com/oracle/docker-images/tree/master/ContainerCloud
GitHub 信息库上的每个堆栈都附带一个 YAML 文件和一个用于生成它的 make 文件。而且,组成堆栈的每个映像都附带有一个用于生成它的 Docker 文件。
每个 Docker PaaS 的一个重要部分是服务发现。OCCS 依赖服务发现实现 Docker 容器之间的通信,并维护一个有关运行中的容器的信息(主机/端口)的服务发现数据库。在 OCCS 中启动 Docker 容器时,会自动插入一条发现新服务的 DNS 记录。
通过为运行的服务分配一个标记,可帮助发现服务。
OCCS 可以标记 Docker 映像并将其推送到信息库。映像可以推送到任意注册表中的任意信息库,而不仅仅是从中拉取映像的注册表。
Docker hub 经过预先配置,但您可以添加注册表,例如,在企业内部本地运行的注册表。
图 15
您可以使用在创建服务时定义的 SSH 密钥登录 OCCS 服务管理器。它运行一个非常受限的 VM 环境,只包括 vi、cat、rm 和 cp 等必要的工具。
要连接到服务定义的主节点,请从服务控制台获取其公共 IP 地址。然后从存储私钥文件的目录运行以下命令。
ssh -i privateKey opc@140.86.3.9
请注意,您只能使用私钥连接。您不必指定密码。截至本文撰写时,您只能连接到主节点,不能连接到工作节点。
您可以通过一键式操作在服务控制台中备份服务配置。备份包括部署、注册表、服务和堆栈的设置。可以将备份下载到本地计算机。Oracle 建议您定期备份服务以进行灾难恢复。而且,在升级到新版本的 OCCS 时,会强制要求备份。
当具有其他特性和错误修复的新版本 OCCS 可用时,用户将收到通知。然后,您可以备份现有服务,使用新的 OCCS 版本创建新服务,并从备份文件导入配置。
Oracle ACE 总监 Frank Munz 是一位软件架构师、云宣讲师及独立顾问,专注于中间件和分布式计算。
本文已经过相关 Oracle 产品团队审查,符合 Oracle 产品使用标准和实践。