Docker 容器是一种打包格式,可通过标准格式打包应用的所有代码和依赖关系,确保应用能够快速、可靠地在计算环境下运行。Docker 容器是一种广受欢迎的轻量级、可执行的独立容器,其中包含应用运行所需的一切要素,包括库、系统工具、代码和运行时。此外,Docker 还是一个软件平台,支持开发人员快速构建、测试和部署容器化应用。
容器即服务 (CaaS) 或容器服务是一种用于管理容器生命周期的托管式云技术服务。它可以帮助您编排(启动、停止、扩展)容器运行时,简化、加速并实现应用开发与部署生命周期自动化。
在过去几年里,Docker 和容器服务得到了快速采用,取得了巨大的成功。如今,Docker 这一开源技术已从 2013 年的几乎无人知晓发展成了一种标准化运行时环境,已正式支持众多 Oracle 企业级产品。
一个软件容器平台,旨在利用容器技术开发、交付和运行应用。Docker 有两个版本,即企业版和社区版。
与提供硬件虚拟化的 VM 不同,容器通过抽象“用户空间”来提供轻量级、操作系统级的虚拟化。容器与其他容器共享主机系统的内核。在主机操作系统上运行的容器是一个标准软件单元,可以打包代码及其所有依赖项,因此应用可以从一个环境快速、可靠地运行到另一个环境。容器是非持久化的,并且由映像运行。
构建并运行容器的开源主机软件。作为客户端/服务器应用,Docker 引擎支持各种 Windows 服务器和 Linux 操作系统(包括 Oracle Linux、CentOS、Debian、Fedora、RHEL、SUSE 和 Ubuntu)上的容器。
要作为容器运行的软件集合,包含一组指令来创建可在 Docker 平台上运行的容器。映像是不可变的,如需更改则需要构建新的映像。
Docker 注册表用于存储和下载映像。Docker 注册表是一个无状态且可扩展的服务器端应用,用于存储和分发 Docker 映像。
Docker 是一个面向 DevOps 和开发人员而设计的开放应用开发框架。使用 Docker,开发人员能够以轻量级、可移植、自给自足,可在几乎所有环境下运行的容器形式,轻松构建、打包、传输和运行应用;能够对应用及其所有依赖关系打包,统一进行部署。得益于预构建、自治的应用容器,开发人员可以专注于应用代码及代码使用,而不必担心底层操作系统或部署系统。
此外,开发人员还可以充分利用数千个可在 Docker 容器中运行的开源容器应用。而对于 DevOps 团队,Docker 可提供持续集成支持和开发工具链,降低在系统架构中部署和管理应用时的约束和复杂性。最后,随着容器编排云技术服务的问世,如今所有开发人员都可以在自己的本地开发环境下开发容器化应用,随后将容器化应用迁移至云技术服务(例如托管式 Kubernetes 服务)并在基于云技术服务的生产环境下运行。
任何开发人员都可以打包容器。在软件行业,通常按照专业(如前端、后端或介于两者之间)来区分开发人员。虽然您通常会看到后端开发人员负责打包容器,但事实上,熟悉 CaaS 基本概念的任何人都可以在软件开发周期内做到这一点。在准备打包应用的依赖项之前,请查看 developer.oracle.com 并了解一些可用于构建应用或程序的工具。
Linux 容器早在 2008 年就已出现,但是直到 2013 年 Docker 容器问世,它才广为人知。随着 Docker 容器的到来,越来越多的人开始开发和部署容器化应用。然而,随着容器化应用数量的不断增长(有时要在多台服务器上部署数百个容器),容器操作变得越来越复杂。如何协调、扩展、管理和调度数以百计的容器?Kubernetes 可助一臂之力。Kubernetes 是一个开源编排系统,让您可以运行 Docker 容器和工作负载。当您需要扩展跨多台服务器部署的多个容器时,它可以为您降低操作复杂性。使用 Kubernetes 引擎,您可以自动化编排容器生命周期,将应用容器分布在整个托管式基础设施中。最后,Kubernetes 还可以快速按需扩展或收缩资源,持续供应、调度、删除和监视容器的运行状况。
Docker 的核心概念是映像和容器。其中,Docker 映像包含运行软件所需的一切要素:代码、运行时(例如 Java 虚拟机 (JVM)、驱动程序、工具、脚本、库和部署等)。
Docker 容器则是 Docker 映像的运行实例。但与基于类型 1 或类型 2 虚拟机管理程序的传统虚拟化不同,Docker 容器在主机操作系统的内核上运行。最后,Docker 映像中没有单独的操作系统(参见图 1)。
每一个 Docker 容器都拥有自己的文件系统、网络体系(因此也拥有自己的 IP 地址)、进程空间以及面向 CPU 和内存定义的资源限制。同时,它不需要引导操作系统,可以即时启动。简而言之,Docker 的宗旨是隔离,即隔离主机操作系统的资源,虚拟化则是在主机操作系统上提供访客操作系统。
Docker 映像的文件系统采用分层结构,具有写时复制语义。这不仅有助于继承和重用以及节约磁盘资源,还支持增量式映像下载。
如图 2 所示,具有 WebLogic 部署的 Docker 映像基于具有 Oracle WebLogic Server 域的映像运行,该映像之下依次是 WebLogic 映像、Java Development Kit (JDK) 映像和 Oracle Linux 基础映像。
Docker 映像易于构建,其简单性和可移植性深受开发人员喜爱。然而,管理数千个 Docker 映像是一项极具挑战的任务。Docker Registry 可以解决这一问题。Registry 是一种存储和分发 Docker 映像的标准方法,是一个获得了宽松式 Apache 许可的开源存储库。
Docker Registry 还可以优化其存储库中存储的 Docker 映像的访问控制和安全性。它可以管理映像分发,还可以与应用开发工作流集成。在实际应用中,开发人员可以构建自己的 Docker Registry,也可以使用托管式 Docker Registry 服务,例如 Docker Hub、Oracle Container Registry 和 Azure Container Registry 等。
Docker Hub 就是 Docker 托管的一个注册表,它存储了来自软件供应商、开源项目和社区的 100000 多个容器映像,还包含了许多来自 NGINX、Logstash、Apache HTTP、Grafana、MySQL、Ubuntu 和 Oracle Linux 等官方存储库的软件和应用。
当启动容器时,如果本地映像不可用,Docker 就会默认自动从公共 Docker Hub 中拉取相应的映像。当然,您也可以创建自己的映像并将映像推送到 Docker Hub 的公共或私有存储库中。
如今,将单体应用分割为较小的微服务块这一理念已引起了软件开发人员的广泛关注。
微服务作为进程独立部署,使用轻量级协议相互通信,且每一项服务都拥有自己的数据。由于采用非集中式治理方法,微服务的实现离不开高水平的基础设施自动化、自动化测试、全自动 CD 管道以及熟练、敏捷的 DevOps 团队。
对于微服务这种架构,尽管目前仍有许多不同声音,但有一个共识,那就是在被分解为微服务后,应用无法以一组进程的形式运行。微服务的实现需要满足众多条件,例如它需要独立于主机,在操作系统层面进行隔离,需要在其资源限制内运行,必须支持按需伸缩,必须能在发生故障后重新启动,必须通过软件定义网络层连接至其他微服务。
在 Docker 容器中运行微服务可为实现这些目标奠定一个良好的基础。
Docker 在两个维度上改变了软件的构建、交付和运行方式:
以下是关于这两个维度的详细介绍。
包含所有依赖关系的 Docker 映像可解决“开发环境下正常但生产环境下出错”的问题,其关键在于构建管道可以自动基于源代码库(如 Git)创建 Docker 映像,在开发环境下进行初步测试,然后在 Docker 注册表中存储该不可变映像。
如图 4 所示,您可以使用同一映像进行进一步的负载测试、集成测试、验收测试等。换言之,您在每一个环境下使用的都是同一个映像。而对于细微但必要的环境特定差异(例如生产数据库的 JDBC URL),您可以将其作为环境变量或文件纳入到容器中。
有统计数据显示,当前 65% 的 Docker 使用场景都位于开发环境中,而 48% 的使用场景都使用 Docker 进行持续集成。
Docker 改变了公有云技术的采用方式。一方面,Docker 映像这种前所未有的通用软件包格式可以在本地环境和所有主流的云技术提供商环境下运行。例如,Docker 容器可以像在 Oracle Cloud 上一样在笔记本电脑上运行。
另一方面,Docker 容器可以在所有主流的公有云上运行,这消除了长期以来关于公有云技术的一个偏见,即供应商依赖。如今,所有主流的云技术提供商均可提供 Docker as PaaS 服务。
Docker 的发布节奏比传统企业软件快得多,这种快节奏以及 Docker 项目的新颖性有时甚至引起了人们对 Docker 安全性和稳定性的担忧。
事实上,尽管 Docker 及其命令行、Docker daemon、API 以及 Docker Swarm、Docker Machine 和 Docker Compose 等工具快速发展只是近三年的事情,近十年来每一个 Linux 内核中都能看到 Docker 的底层内核特性。
Google 就是一个典型的容器技术早期采用者。早在 Docker 出现之前,Google 就一直在使用 Linux 容器,甚至在容器中运行所有一切。据估计,Google 每周推出数十亿个容器。
Docker 使用的底层 Linux 内核特性包括 Cgroup 和命名空间。2008 年,在 Google 开发人员以往工作的基础上,Linux 内核引入了 Cgroup 1。Cgroup 可以限制并说明一组操作系统进程的资源用量。
命名空间则可隔离各个进程之间的系统资源。2002 年,Linux 引入了第一个命名空间(即 mount 命名空间)。2
本文的第一部分介绍了关于 Docker 的一些重要概念。但在生产环境下,除了在 Docker 容器中运行应用,您还需要解决很多问题。
您需要准备硬件来运行容器,从而设置和操作生产环境;需要安装、升级和修补 Docker 等软件以及存储库和集群管理器;需要创建一个网络,以便多个 Docker 容器跨主机通信;需要能够在集群化容器发生故障后将它们重新启动。此外,一系列互连的容器应当像一个逻辑应用实例一样易于部署,例如一个负载均衡器、多个 Web 服务器、多个带管理服务器的 Oracle WebLogic Server 实例、一个托管式服务器和一个数据库。最后,要想规模化地管理容器化应用,Kubernetes 或 Docker Swarm 之类的容器编排系统也必不可少,而部署、管理和运行 Kubernetes 之类的编排系统也是一项耗时且充满挑战的任务。
为了更轻松、高效地创建容器化应用,很多云技术提供商提供了容器云技术服务或容器即服务 (CaaS),以帮助开发人员和运营团队理顺和管理容器生命周期。这些编排服务通常由 Kubernetes 构建,支持 DevOps 团队更轻松、规模化地管理和运行容器化应用。例如,Oracle Container Engine for Kubernetes 和 Azure Kubernetes Service 就是两个常用的、典型的托管式容器编排云技术服务。
Oracle Container Engine for Kubernetes 是一个全托管式、可扩展、高度可用且可在云端部署容器化应用的服务。如果您的开发团队希望可靠地构建、部署和管理云原生应用,请使用 Container Engine for Kubernetes(有时缩写为 OKE)。
任何开发人员都可以打包容器。在软件行业,通常按照专业(如前端、后端或介于两者之间)来区分开发人员。虽然您通常会看到后端开发人员负责打包容器,但事实上,熟悉 CaaS 基本概念的任何人都可以在软件开发周期内做到这一点。在准备打包应用的依赖项之前,请查看 developer.oracle.com 并了解一些可用于构建应用或程序的工具。
下面是获取或为 Oracle 产品构建 Docker 映像的来源。其中,面向 Docker 映像的 Oracle GitHub 存储库包含为 Oracle 商用产品和 Oracle 赞助的开源项目构建 Docker 映像的 Dockerfile 和示例。
注:为免疑义,本网页所用以下术语专指以下含义: