Kubernetes 实战-微服务

微服务

在 《Kubernetes In Action》的开始,先要了解 k8s 的需求来自于哪里,为什么我们需要 k8s。

引用维基百科解释:

微服务 (Microservices) 是一种软件架构风格,它是以专注于单一责任与功能的小型功能区块 (Small Building Blocks) 为基础,利用模块化的方式组合出复杂的大型应用程序,各功能区块使用与语言无关 (Language-Independent/Language agnostic) 的 API 集相互通信。

说一说我的理解,在项目早期,都是单体应用,随着功能越来越多,项目越来越大,虽然保证了部署运维的方便,但对于组内同学并不友好,新同学往往要在一坨代码中找自己想要的一点,本地修改提交跑 CI 也是以项目为单位的执行(前段时间 B 站不小心泄露的 Golang 代码就是这种)。当后续升级产品时,因为是以项目为最小粒度,哪怕无关代码,也要被迫进行代码升级,服务重启等操作,带来了额外的风险。

在 2014年,Martin Fowler 与 James Lewis 共同提出了微服务的概念,把单体应用改为通过接口产生的远程方法调用,将项目拆分,一个项目保证只做一件事情,独立部署和维护。

优点:

  • 高度可维护和可测试
  • 松散耦合
  • 可独立部署
  • 围绕业务能力进行组织

缺点:

  • 服务数量大幅增加,部署维护困难
  • 服务间依赖管理
  • 服务故障处理

容器

那么我们提到了项目演进,在同一时间,容器技术的标准化统一也间接促成了微服务的推广(我猜的),Docker 在 2013.03.13 发布第一个版本,容器化技术让我们产品发布形态有了新的选择,开发直接将容器镜像发布,运维同学通过镜像进行产品上线,确保了环境的统一,无须纠结环境配置相关问题(不用吵架了)。

当我们产品发布采用容器化上线后,我们面临一些其他的问题了:

  • 微服务追求的是将服务解耦,拆分为多个服务,那么最终发布形态对应的也是多个镜像,运维同学管理这些镜像之间的关系难度增加。
  • 同时当镜像运行在不同的物理节点上,对计算资源和网络资源的要求是一致的,运维同学需要做到让镜像无感知。
  • 当产品要进行升级时,镜像之间的依赖关系,故障切换等操作紧靠现有容器功能实现困难。

这么一看,与之前单体应用比也没好哪里去。于是有了各种容器编排系统,比如 Swarm,Mesos等等,但都不是很好用且各家一个标准,这时候老大哥谷歌发话了,我来把我们内部用了很多年要淘汰的东西拿出来给大家解决问题吧,于是有了 Kubernetes。

Kubernetes 功能上提供了解决微服务引入的问题,并更好的配合微服务去提供稳定高可用的统一容器化环境,具体如何解决的我们后续可以通过了解 Pod,ConfigMap,ReplicaSet 等功能去详细了解。

总结

可能是因为我考虑问题都是从运维角度去看的,网上的一些文章讲的带来的好处反而没看太清,可能作为 2C 产品,追求敏捷开发,产品不断快速迭代的目标比较适合,但是如果本身作为一个追求稳定可靠的 2B 产品来说,引入 k8s 带来的好处和维护 k8s 带来的成本真的要仔细的从产品层面考虑清楚,这里感觉跟具体的技术关系不大,而是说从产品面向的客户对象考虑,客户想要的是一个什么产品,而 k8s 作为一个还在不断(频繁)迭代的产品来说(可以去看看 release notes 的更新速度),后续若出现某些 API 不兼容等情况,如何去应对,感觉还是个灾难。

参考链接

在学习过程中,通过阅读 cch123 的博客对微服务有了更深的了解,这里列一下相关的系列博客链接:

  1. 微服务的灾难-通用语言

  2. 微服务的灾难-技术栈

  3. 微服务的灾难-拆分

  4. 微服务的灾难-依赖地狱

  5. 微服务的灾难-最终一致

  6. 微服务的灾难-康威定律和 KPI 冲突