微服务和云原生架构笔记1

174 阅读11分钟

系统架构设计和技术栈选型

为什么采用为服务架构?

对于这个问题主要有两种主流的观点: 1.企业应用是否需要微服务主要是看主要看企业业务的发展和规模,业务发展早期主要采用单块应用,随着业务的不断发展和扩展也随着对业务领域的不断理解,再逐步拆分解耦演化成微服务。 image.png

2.有人认为技术的进步使得微服务的门槛和成本大大降低,微服务架构是当前互联网架构的首选。因为发现采用微服务和采用单块架构的门槛和成本几乎是一样的。在这样的情况下,既然微服务更加灵活性和易于扩展的好处,为什么不直接使用微服务呢?从软件开发方法学演进的角度来看行业经历过面向过程、面向对象、面向组件、到现在面向服务、微服务发展的历程,微服务能够让我们在更高的层面抽象管理软件的复杂性,开发更大规模的系统,应对更加复杂多变的互联网需求,它是行业发展的一种必然趋势。 image.png

服务开发框架设计和实践

可编程网关设计和实践

安全框架设计和实践

微服务测试设计和实践

可运维架构设计和实践

服务容器化和Docker Compose部署

云原生架构和Kubernetes容器云部署

到底什么是云原生架构?

云原生(Cloud Native)应用定义

Kubernetes 背景和架构

Kubernetes 有哪些基本概念?

  • Kubernetes 集群(Cluster)
    这个集群有很多节点组成,而且可以按需添加更多的节点(节点可以是物理机也可以是虚拟机,每个节点都有一定量的CPU和RAM)。整个Kubernetes可以看作是一个抽象的计算机,它的CPU容量可以看成所有几点容量的总和,而且可以按需添加更多的CPU和内存。 image.png

  • 容器 Container Kubernetes是个一个容器调度平台,所以容器是Kubernetes平台的基本概念。从宿主机操作系统的视角还看,容器其实是一个一个的进程,那么从容器内部的视角来看,自己就是一个完整的操作系统,有自己的文件系统、网络、CPU等资源。 image.png

  • POD Kubernetes并没有直接调度容器,而是在外面再封装了一个Pod的概念。那么Pod(英文:豌豆荚的意思)是Kubernetes的基本调度单位。一个Pod可以跑一个或者多个容器,多个容器它们共享Pod的文件系统和网络,每个Pod有独立的IP。Pod中的容器共享Pod的IP和端口空间,并且同一个Pod中的容器可以通过localhost相互访问。大部分场景下一个Pod只跑一个容器。那么Kubernetes并没有直接调度容器,而是在外面再封装了一个Pod,一个原因是考虑一些需要辅助容器的场景,比如需要set card的场景,另外一个原因是可以替换使用不同的容器技术。 image.png

  • 副本集 ReplicaSet 一个应用发布的时候,不会只发布一个Pod实例,而是会发布多个Pod实例,这样才能实现HA高可用,副本集ReplicaSet就适合一个应用的一组Pod相对应的概念。它可以通过模板(主要是yaml或者是)来规范某个应用的容器镜像、端口、副本数量,健康检查、环境变量、数据卷挂载等等这些相关的信息。运行时 ReplicaSet 会监控POD的数量,POD多了就下线POD,少了就启动POD。之前还有一个 Replication Controller 的概念,但是这个概念已经被ReplicaSet替代了。 image.png

  • 服务 Service 由于POD是不固定的,也就是有可能会随时挂,或者重启(这个重启包括预期的和非预期的),那么重启之后或者挂了,响应的IP就会改变。如果消费者直接寻址POD的IP,那影响就会很大了。所以,Kubernetes引入Service这个抽象概念来解决这个问题,简单的讲就是屏蔽了应用的IP寻址和负载均衡这些细节,消费者可以直接通过服务名访问目标服务。Kubernetes中的Service底层机制会做负载均衡和寻址。即使应用POD的IP发生了变更,Service也会屏蔽这种变更。让消费方无感知。 image.png

  • 发布 Deployment 副本集 ReplicaSet可以认为是一种基本的发布机制。通过ReplicaSet可以实现基本的发布,也可以实现高级的发布,比如说金丝雀,蓝绿,滚动发布。但是使用ReplicaSet操作起来比较繁琐,为了简化这些高级的发布,引入了 Deployment 概念。简单讲,Deployment用来管理 ReplicaSet 的,实现蓝绿和滚动这些高级发布机制。 image.png

通过 Deployment 实现滚动发布 Rolling Update 假设应用1.0已经发布了,对应的ReplicaSet为v1.0,然后我们可以Deployment进行升级发布应用的1.1,下图蓝色版本,那么 Deployment就会创建ReplicaSet v1.1,之后Deployment会依次调度,不断的拉入蓝色版本,拉出绿色版本,知道所有的蓝色POD全部上线,绿色POD全部下线为止。这个过程中 Service抽象会屏蔽应用地址的变更,让消费方无感知。如果在发布过程中,蓝色POD有问题(比如说健康检查没通过),那么Deployment会终止并且回退发布,即使发布成功完成,后续如果有需要也可以通过Deployment回退到之前某个版本。所以Deployment是一个更灵活的发布机制。 image.png

发布和服务总结 特别强调,Deployment和Service是和微服务发布的最重要两个概念。我们发布微服务的时候所书写定义的发布描述文件(yaml)里头主要是Deployment和Service的规范。Deployment是基于ReplicaSet之上的概念。发布应用的时候Deployment会创建ReplicaSet,ReplicaSet去规范创建POD实例,并且维护和保证POD实例的数量,升级的时候会创建新的ReplicaSet调动滚动发布。 image.png

  • ConfigMap/Secret 我们知道微服务在上线的时候常常需要设置一些可变配置。这些配置针对不同环境的配置值也会不同。这些配置有些是在启动期一次要配置好的, 比如说数据库的连接。还有些配置是可以在运行期动态调整的。缓存的过期时间TTL值,或者业务中商品限购数量等等。所以微服务需要配置中心的支持,实现针对不同环境的灵活的动态配置。 Kubernetes内置了ConfigMap来做配置,开发人员把配置写在ConfigMap中,Kubernetes将ConfigMap中的配置以ENV(环境变量)的形式注入到POD中。这样POD中的应用可以以环境变量的方式去访问到配置。ConfigMap也支持持久卷Volume的形式Mount到POD中,这样POD中的应用就可以本地配置文件的方式访问配置。有些配置是涉及敏感数据的,比如用户名、密码、安全证书等。Kubernetes通过Secret概念支持敏感数据的配置。Secret可以认为是一种特殊的配置,它提供了一种更安全的存储和访问配置的机制。 image.png

  • DaemonSet 还有一种场景在微服务中也经常遇到,就是需要在每个节点上常驻一个守护进程Daemon进程(比如监控场景需要在每个机器上部署一个日志采集进程)。针对这种场景Kubernetes有一个DaemonSet概念。可以在每个work节点上部署一个守护进程POD,并且保证有且只有一个这样的POD。 image.png

  • 其它概念

    • Volume:存储卷抽象,简单可以理解为磁盘文件存储(可以是节点本地存储也可以是远程存储),挂载之后成为POD的一部分,POD销毁,Volume也被销毁。

    • PersistentVolume:持久卷。如果Volume只用节点文件的本地存储,那么下一次应用容器重启可能会换一个节点,相应的存储就不存在了,持久卷简称PV,是一种高级的存储资源抽象,可以对接各种云存储。如果使用PV挂载Volume,那么应用POD重启之后Volume上的数据不丢。

    • PersistentVolumeClaims:应用申请PV时需要填写的规范,包括磁盘大小、类型等等,简称PVC。应用通过PVC申请PV资源,然后以Volume的形式挂载在POD中。PV和PVC的引入使得Volume和具体的物理存储解耦,参照下图。

    • StatefulSet:支持有状态应用发布的机制,如果要发布MySQL或者Redis就需要这种StatefulSet。它和ReplicaSet是相对应的,ReplicaSet支持的是无状态应用的发布,而StatefulSet支持的是有状态应用的发布。

    • Job:支持跑一次的任务

    • CronJob:支持周期性跑的Job。 image.png

  • 概念补充

    • Label/Selector:Label给Kubernetes的资源大标签的机制,比如下图中展示的我们可以给这个POD打上Backend标签,标识是后端的。Selector是通过标签查询定位的机制,比如可以通过Selector查询出所有Prod环境的并且是Frontend的POD。在发布描述符文件中会使用Label/Selector。
    • Namespace:Namespace是Kubernetes中一种逻辑性的隔离机制,基于Namespace可以实现多租户、环境、项目之间的逻辑隔离。
    • Readiness Probe(就绪探针):Kubernetes支持这种就绪探针的,用于判断POD是否可以接入流量,比如通过应用的健康检查端点可以检查POD是否就绪,就绪的话就可以接入流量。
    • Liveness Probe(活跃探针):Kubernetes支持的活跃探针,用于判断POD是否存活,比如通过应用的健康检查端点可以定期检查POD是否存活。不存活就kill掉这个POD并根据配置策略决定是否要重启这个POD。实际上Readiness Probe和Liveness Probe常常是配合使用的。在发布描述符文件中可以配置。
      image.png

概念总结 image.png image.png

理解 Kubernetes 节点网络和 Pod 网络

Kubernetes网络是一个难点,其中涉及到节点网络、 Pod 网络、service 网络、overlay网络。 image.png Kubernetes最底层的网络叫节点网络。这个网络是用来保证Kubernetes的节点,包括master和worker节点之间以及worker节点之间能够正常的IP寻址和通讯的。上图当中我们假定节点网络在10.100.0.0/24这个地址空间内,这里给出了两个Worker节点,每个节点都有自己的网卡eht0。这两个节点的IP一个是10.100.0.2,一个是10.100.0.3。它们都连在同一个路由器上面,路由器是10.100.0.1,这是节点网络。

Kubernetes的第二个网络叫POD网络,它是构建在节点网络之上的。POD网络是保证Kubernetes集群当中的POD。它们之间能够正常的IP寻址和通讯。先来看一下POD的内部网络。POD是Kubernetes的最基本的调度单位,一个POD内部可以住一个或者多个容器,这些容器是共享POD的网络站的(可以理解为POD的容器共享一个虚拟网卡),比如上面这个图,PODA中容器想要访问POD外部的网络,它们都会走这个共享的veth0这个虚拟网络,容器之间可以通过localhost直接访问,同时端口空间也是共享的,也就是说这些容器不能使用同一个端口,会端口冲突。POD内部的网络站是一个叫Pause创建的。这个Pause容器的唯一目的就是为POD内其他的容器创建共享的网络站。 那么POD之间如何实现IP寻址和通讯的呢?在Kubernetes中,每个POD可以看成是带虚拟网卡的小型虚拟机。在节点网络之上,Kubernetes会创建和管理一个专门为POD寻址和访问服务的虚拟网络,我们称之为POD网络,Kubernetes主要通过两个机制来实现POD网络。首先Kubernetes会在每个节点上创建虚拟网桥(图:cbr0),并且管理这些网桥的地址空间和分配。其次Kubernetes会修改路由器的规则,使得不同Worker节点的POD之间可以相互访问。

深入理解 Service 和 Service Discovery

POD网络可以保证POD之间和包括不同节点的POD之间可以相互寻址和访问。

image.png