微服务:大型单体应用被分解成小的、可独立运行的组件。
微服务彼此之间解耦,可独立开发、部署、升级、伸缩。
随着部署组件的增多和数据中心的增长,配置、管理并保持系统的正常运行越来越困难。手动去做很困难,因此有了一些自动化措施:自动调度、配置、监管和故障处理,这正是Kebernetes用武之地。
Kubernetes抽象了数据中心的硬件基础设施,使得对外暴露的只是一个巨大的资源池。让我们在部署和运行组件时,不用关注底层的服务器。使用Kubernetes部署多组件应用时,它会为每个组件都选择一个合适的服务器,部署之后它能够保证每个组件可以轻易地发现其它组件,并彼此之间实现通信。
1.1.1 从单体应用到微服务
单体应用由很多个组件组成,这些组件紧密地耦合在一起,由于它们在同一个操作系统进程中运行,所以在开发、部署、管理的时候必须以同一个实体进行。单体应用中,即使是某个组件中一个小的修改,都需要重新部署整个应用。
单体应用垂直扩展增加CPU、内存或其它系统资源;水平扩展增加更多的跑这些应用程序的服务器。
将应用拆解为多个微服务:
单体应用过大时难以做垂直扩展,可拆分为小的可独立部署的微服务组件。
每个微服务以独立的进程运行,并通过简单且定义良好的接口与其它微服务通信。
服务之间可以通过类似HTTP这样的同步协议通信,或者通过像AMQP这样的异步协议通信。这些协议能够被大多数开发者所理解,并且并不局限于某种编程语言。所以任何一个微服务,都可以用最适合的开发语言来实现。
每个微服务都是独立的进程,提供相对静态的API,所以独立开发和部署单个微服务成了可能。只要API不变或者向前兼容,改动一个微服务并不会要求其它微服务进行改动或者重新部署。
微服务的扩容:
微服务的扩容只需针对单个服务。
1.1.3 迈向持续交付:DevOps和无运维
让同一个团队参与应用的开发、部署、运维的整个生命周期。开发者、QA和运维团队彼此之间合作贯穿整个流程。这种实践被称为DevOps。
1.2 介绍容器技术
当应用组件较多时,不同组件需要不同的、可能存在冲突的依赖库版本,或者是其它的不同环境需求。分配给每个组件一个虚拟机不太理想。
用Linux容器技术隔离组件:
容器允许在同一台机器上运行很多的服务,不仅提供不同的环境给每个服务,而且将它们相互隔离。容器比虚拟机开销小很多。
一个容器里运行的进程实际上运行在宿主机的操作系统上(虚拟机有自己的操作系统),容器里的进程仍然是和其它进程隔离的。
比较虚拟机和容器:
容器轻量级,允许在相同的硬件上运行更多数量的组件;虚拟机运行自己的一组系统进程,产生了除组件进程消耗以外的额外计算资源损耗。容器仅仅是运行在宿主机上被隔离的单个进程,仅消耗应用容器消耗的资源,不会有其他进程的开销。
虚拟机各自拥有分离的操作系统,共同运行在一台机器上。虚拟机之下是宿主机的操作系统与一个管理程序,它将物理硬件资源分成较小部分的虚拟硬件资源。运行在那些虚拟机里的应用程序会执行虚拟机操作系统的系统调用,然后虚拟机内核会通过管理程序在宿主机上的物理CPU执行指令。
多个容器则会完全执行运行在宿主机上的同一个内核的系统调用,此内核是唯一一个在宿主机操作系统上执行x86指令的内核。
虚拟机提供完全隔离的环境,因为运行在自己的Linux内核上。而容器都调用同一个内核。
容器实现隔离机制介绍:
如果多个进程运行在同一个操作系统上,那容器到底是怎样隔离它们的?有两个机制可用:第一个是Linux命名空间,它使每个进程只看到它自己的系统视图(文件、进程、网络接口、主机名等);第二个是Linux控制组(cgroups),它限制了进程能使用的资源量(CPU、内存、网络带宽等)。
用Linux命名空间隔离进程:
默认情况下,每个Linux系统最初仅有一个命名空间。所有系统资源(诸如文件系统、用户ID、网络接口等)属于这一个命名空间。但是可以创建额外的命名空间,以及在它们之间组织资源。对于一个进程,可以在其中一个命名空间中运行它。进程将只能看到同一个命名空间下的资源。会存在多种类型的多个命名空间,所以一个进程不单单只属于某一个命名空间,而属于每个类型的一个命名空间。
存在以下类型的命名空间:
1)Mount(mnt)
2)Process ID(pid)
3)Network(net)
4)Inter-process communication(pid)
5)UTS
6)User ID(user)
每种命名空间被用来隔离一组特定的资源。
限制进程的可用资源:
另外的隔离性就是限制容器能使用的系统资源。这通过cgroups来实现。cgroups是一个Linux内核功能,它被用来限制一个进程或者一组进程的资源使用。一个进程的资源(CPU、内存、网络带宽等)使用量不能超出被分配的量。这种方式下,进程不能过分使用为其它进程保留的资源,这和进程运行在不同的机器上是类似的。
1.2.2 Docker
Docke利用容器技术打包应用组件。
Docker是一个打包、分发和运行应用程序的平台。它允许将应用程序和应用程序所依赖的整个环境打包在一起。既可以是一些应用程序需要的库,也可以是一个被安装的操作系统所有可用的文件。Docker使得传输这个包到一个中央仓库成为可能,然后这个包就能被分发到任何运行Docker的机器上执行。
Docker三个主要概念:
1)镜像:docker镜像里包含了打包的应用程序及其所依赖的环境。包含应用程序可用的文件系统和其它元数据。
2)镜像仓库:docker镜像仓库用于存放docker镜像,以及促进不同人和不同电脑之间共享这些镜像。
3)容器:docker容器通常是一个Linux容器,它基于docker镜像被创建。一个运行中的容器是一个运行在docker主机上的进程,但它和主机,以及所有运行在主机上的其它进程都是隔离的。这个进程也是资源受限的。
镜像层:
Docker镜像由多层构成。层使分发更高效,也有助于减少镜像的存储空间。每一层仅被存一次,当基于相同基础层的镜像被创建成两个容器时,它们就能读相同的文件。如果其中一个容器写入某些文件,另外一个是无法看见文件变更的。容器写时在基础层上加上了附加层。
1.3 Kubernetes介绍
Kubernetes是一个软件系统,它允许你在其上很容易地部署和管理容器化的应用。它依赖于Linux容器的特性来运行异构应用,而无需知道这些应用的内部详情,也不需要手动将这些应用部署到每台机器。
Kubernetes的核心功能:
整个系统由一个主节点和若干个工作节点组成。开发者把一个应用列表提交到主节点,Kubernetes会将它们部署到集群的工作节点,开发者无须关心组件被部署在哪个节点。
1.3.3 Kubernetes集群架构
在硬件级别,一个Kubernetes集群由很多节点组成,这些节点被分成以下两种类型:
1)主节点,它承载着Kubernetes控制和管理整个集群系统的控制面板。
2)工作节点,它们运行用户实际部署的应用。
控制面板:
控制面板用于控制集群并使它工作。它包含多个组件,组件可以运行在单个主节点上或者通过副本分别部署在多个主节点以确保高可用性。
控制面板包含的组件是:
1)Kubernetes API服务器,你和其它控制面板组件都要和它通信。
2)Scheduler,它调度你的应用(为应用的每个可部署组件分配一个工作节点)。
3)Controller Manager,它执行集群级别的功能,如复制组件、持续跟踪工作节点、处理节点失败等。
4)etcd,一个可靠的分布式数据库存储,它能持久化存储集群配置。
工作节点:
工作节点是运行容器化应用的机器。运行、监控和管理应用服务的任务是由以下组建完成的:
1)Docker、rtk或其它的容器类型。
2)Kubelet,它与API服务器通信,并管理它所在节点的容器。
3)Kubernetes Service Proxy(kube-proxy),它负责组件之间的负载均衡网络流量。