Quarkus云原生微服务开发实战
上QQ阅读APP看书,第一时间看更新

1.3 了解容器编排技术

容器化技术的出现,为微服务架构应用的部署提供了更加简单可靠的解决方案。每个容器在运行时通常只有一个进程。每个容器的功能相对独立。在使用容器来运行应用时,一般都需要多个容器来协同工作。最典型的例子是使用数据库的应用。数据库服务器和应用分别运行在各自独立的容器中,两者之间存在依赖关系。应用的容器在运行时需要访问数据库的容器。在管理多个相互关联的容器时需要用到容器编排技术。

1.3.1 使用Docker进行简单的编排

最简单的容器编排实现是使用Docker。首先创建一个自定义的网络。不同的容器可以通过该网络来交互。下面的命令创建了名为my-app的网络。

接着使用docker run命令来启动PostgreSQL容器。在启动时,通过参数--network来指定上一个命令中创建的网络名称。

最后启动应用的容器。启动时的环境变量DB_HOST表示数据库服务器的地址,它的值db来自PostgreSQL容器的名称。同一个网络上的容器可以使用容器名称来作为访问的主机名。

直接使用Docker命令的劣势在于docker run命令一般都很长,没办法有效管理。另外,启动PostgreSQL容器时的环境变量POSTGRES_PASSWORD的值与启动应用容器时的环境变量DB_PASSWORD的值必须是相同的。这两个值在命令中重复出现,会导致修改起来比较麻烦。

1.3.2 使用Docker Compose进行编排

Docker Compose是Docker提供的容器管理工具。相对于其他编排工具,Docker Compose使用简单,适合于本地开发使用。Docker Compose可以同时启动多个容器,并定义容器之间的关联关系。

还是同样的使用数据库应用的例子。Docker Compose可以同时启动两个容器,并定义其中的关联。Docker Compose使用YAML文件来描述需要启动的服务。下面代码中的docker-com-pose.yaml文件用来启动应用和PostgreSQL服务器。在services中定义了两个服务。

· 服务db使用PostgreSQL的镜像,并在environment中声明了所需的环境变量。

· 服务app使用应用的镜像,ports的作用是暴露端口。

服务app也有同样的环境变量,其中DB_HOST的值是db,是PostgreSQL服务的名称。这是因为Docker Compose使用服务名称作为容器的主机名。两个容器出现在同一个网络中,因此服务app可以访问到PostgreSQL服务器。服务app的depends_on声明了服务app对db的依赖关系。这样可以保证正确的容器启动顺序。

使用docker-compose up命令可以运行docker-compose.yaml文件描述的全部容器。

Docker Compose虽然可以解决很大一部分容器编排的问题,但是在功能上存在一定的局限性。Docker Compose一般在开发和测试中使用,生产环境上则需要使用更加成熟的容器编排技术。

1.3.3 Kubernetes介绍

Kubernetes是一个可移植和可扩展的开源平台,用来管理容器化的工作负载和服务,可以促进声明式的配置和自动化。Google在2014年开源了Kubernetes项目,目前是容器编排领域事实上的标准。绝大多数云平台都提供了Kubernetes的支持。

Kubernetes集群中有两类资源,分别是协调集群工作的控制平面(Control Plane),以及实际运行应用的工作节点(Worker Node)。Kubernetes集群由很多不同的组件组成,这些组件运行在不同的集群节点上。节点可以是物理机器或虚拟主机。这些组件可以分成两类,分别是控制平面组件和工作节点组件。图1-4给出了Kubernetes集群的示意图。

表1-1给出了Kubernetes的核心组件的说明。所有这些组件都在图1-4中出现。每个组件都说明了其作用。

·图1-4 Kubernetes集群

表1-1 Kubernetes核心组件说明

除了这些核心组件之外,还可以安装一些附加组件来提供额外的功能。表1-2给出了一些常用的附加组件。

表1-2 Kubernetes的附加组件

(续)

在实际的集群中,控制平面和工作节点通常部署在不同的机器上。包含控制平面组件的机器称为集群的主控节点(Master),包含工作节点组件的机器称为工作节点(Worker)。生产环境的集群中应该至少有1个主控节点和3个工作节点。

Kubernetes提供了开放API来对集群进行管理。与Kubernetes集群交互最常用的方式是使用Kubernetes自带的命令行工具kubectl。当需要在应用中访问Kubernetes时,可以使用不同编程语言的客户端库。

Kubernetes使用声明式的资源管理。作为使用者,只需要声明资源的期望状态。Kubernetes会确保资源的最终状态与期望的状态保持一致。Kubernetes定义了很多种资源,代表不同的实体。只需要按照资源的规范要求编写描述文件,并通过kubectl工具应用到Kubernetes集群上即可。一般使用YAML格式来描述资源。

以在Kubernetes上部署应用为例,对应的资源类型是Deployment。在Deployment的声明中可以指定部署应用的容器镜像和运行时的配置,还可以指定实例的期望数量。当某个实例出现错误而终止时,Kubernetes会启动新的实例,确保总实例的数量符合Deployment资源中声明的预期值。