整理了一些使用k8s的理由和优势!
拥抱微服务
微服务架构将巨大单体式应用分解为多个服务,每个服务通过 RPC 或者API 进行通信,具备了各个自服务容易开发、维护的优点,另外子服务还具备独立部署、快速扩展等优点。Kubernetes 对微服务本身有很好的支持,应用本身通过Deployment
进行部署,各个服务运行在 Pod
中,Pod
之间服务通过 Service
具备的服务发现实现相互间的通信。同时微服务架构也恰好是云原生应用的一种体现。
容器编排
Kubernetes 帮助使用者通过简单易用的 API 高效地管理成千上万个运行在容器中的微服务。Kubernetes 在 1.6 版本中已经支持 5000 个节点,这也说明 Kubernetes具备大规模集群的编排管理能力。同时,Kubernetes 还具备包括监控、日志、包管理等各种完善而专业的工具链,这将大大减轻运维和开发人员的负担。
服务注册发现
微服务的实践过程中存在各种服务依赖关系,因此服务的注册发现十分重要。Kubernetes 对服务进行抽象,通过抽象的服务层动态地解析到对应的容器服务。Kubernetes 同时提供了 DNS 和环境变量两种方式,帮助实现服务的注册和发现,Kubernetes 早期版本中使用的环境变量方式实现,现在 Kubernetes 则默认使用 DNS,通过使用 DNS 将服务名称解析为服务的 IP 地址,然后 Proxy
转到对应的 Pod
。
主机资源利用率
Kubernetes 对主机的资源利用率,也是一种提升,基本上物理机,ECS,EC2,主机的利用率通常都在30%左右,极大的浪费了资源。使用 Kubernetes 后,可以根据主机资源使用情况,自动的调度 Pod
运行到那台机器上。可以极大的提高主机的资源利用率。
弹性扩容
例如我们新上线的应用,因不同的业务场景,初次上线的时候不太确定给多少资源,默认就给应用 4G 内存,在 Kubernetes 中我们可以根据内存的使用率,来定义是否启动一个新的 Pod,以及 Pod 最少多少个,最多多少个。
应用横向扩展
例如我们应用在在访问资源高峰期,应用需要进行添加机器,如果在 ECS、EC2 等机器,就需要再安装服务呀,配置负载之类的,在容器中就简单多了,直接修改ReplicaSet
,修改节点数量,就会根据镜像自动启动新服务。
容器调度和服务编排
- 镜像仓库
解决Docker镜像存储和访问 - 资源调度
决定Docker镜像可分发到哪些机器
这些解决后,就该考虑如何在集群中创建容器,即容器调度。
容器创建后如何运作才能对外提供服务,即容器调度。
1 容器调度
当服务需要发布的时候,该选择哪些机器部署容器。
若集群机器规模上百台,要发布的服务上百个,就不能靠人肉运维,需要有专门容器调度系统,所以很多基于Docker的容器调度系统,比如Swarm、Mesos。Kubernetes。
它们能解决哪些问题呢?
主机过滤
解决容器创建时什么样的机器可以使用:
-
存活过滤
必须选择存活的节点,因为主机也有可能下线、故障态。 -
硬件过滤
比如Web集群往往用作计算节点,它的CPU一般配置比较高
大数据集群往往用作数据存储,它的磁盘一般配置比较高
以上都是针对主机层次的过滤方式。
调度策略
为解决容器创建时选择哪些主机最合适,一般通过给主机打分。
比如Swarm
包含两种类似策略:spread
和binpack
,都会根据每台主机的可用CPU、内存以及正在运行的容器的数量来给每台主机打分:
spread
策略
会选择一个资源使用最少的节点,以使容器尽可能的分布在不同的主机上运行。好处:可以使每台主机的负载都比较平均,而且如果有一台主机有故障,受影响的容器也最少binpack
策略
正好相反,会选择一个资源使用最多的节点,好让容器尽可能的运行在少数机器上,节省资源的同时也避免了主机使用资源的碎片化
适用场景
各主机配置基本相同,使用也较简单,一台主机上只创建一个容器。每次创建容器时,直接从尚未创建过容器的主机中,随机选择一台。
某些在线、离线业务混布场景,为达到主机资源使用率最高,需综合考量容器中的任务特点:
- 在线业务主要使用CPU
- 离线业务主要使用磁盘和I/O
这两种业务的容器大部分情况下适合混跑在一起。
还有一种业务场景,主机资源都充足,每个容器只要划定所用资源限制,理论上跑在一起是没问题。但有时会出现对每个资源的抢占,比如都是CPU密集型或者I/O密集型的业务就不适合容器混布一台主机。
2 服务编排
服务依赖
若服务A调度的前提是先有服务B,容器调度时,就要考虑服务间这种依赖关系。
所以Docker提供Docker Compose。允许用户通过一个单独的docker-compose.yaml
定义一组相互关联的容器组成一个项目,以项目形式管理应用。
比如要实现一个Web项目,要创建:
- Web容器比如Tomcat容器
- 数据库容器比如MySQL容器
- 负载均衡容器比如Nginx容器等
就可以通过docker-compose.yaml
配置这个Web项目里包含的三个容器的创建。
服务发现
容器调度完成后,就可以启动了。但此时容器还不能对外服务,服务消费者并不知道这个新的节点,必须具备服务发现机制,使得新容器节点能够加入到线上服务。
常用的服务发现机制:
基于Nginx的服务发现
针对提供HTTP服务的。
当有新容器节点时,修改Nginx的节点list
配置,然后利用Nginx的reload
,重新读取配置,加载新节点。
基于注册中心的服务发现
针对提供RPC服务的。
当有新的容器节点时,需要调用注册中心提供的服务注册接口。使用这种方式时,如果服务部署在多个IDC,就要求容器节点分IDC进行注册,以便实现同IDC内就近访问。以微博的业务为例,微博服务除了部署在内部的两个IDC,还在阿里云上也有部署,这样的话,内部机房上创建的容器节点就应该加入到内部IDC分组,而云上的节点应该加入到阿里云的IDC。
弹性扩容
大部分互联网业务的访问呈现出访问时间的规律性。在高峰期,增加容器的数量,确保服务稳定性;低峰期减少容器数量,减少服务使用的资源成本。可以根据容器的CPU负载,设置一个扩缩容的容器数量或比例。比如可以设定容器的CPU使用率不超过50%,一旦超过这个使用率就扩一倍节点。