Kun

Kun

IT学徒、技术民工、斜杠青年,机器人爱好者、摄影爱好 PS、PR、LR、达芬奇潜在学习者


共 212 篇文章


​ 其实本章原来名为k8s,后来感觉云的概念/应用太多了,远远不止一个k8s,所以就以云为开始

云原生的定义

云原生(Cloud Native)这个词汇由来已久,以致于何时出现已无据可考。云原生开始大规模出现在受众视线中,与 Pivotal 提出的云原生应用的理念有着莫大的关系。我们现在谈到云原生,更多的指的是一种文化,而不具象为哪些技术体系。

早在 2015 年 Pivotal 公司的 Matt Stine 写了一本叫做 迁移到云原生应用架构 的小册子,其中探讨了云原生应用架构的几个主要特征:

  • 符合 12 因素应用
  • 面向微服务架构
  • 自服务敏捷架构
  • 基于 API 的协作
  • 抗脆弱性

到了 2015 年 Google 主导成立了云原生计算基金会(CNCF),起初 CNCF 对云原生(Cloud Native)的定义包含以下三个方面:

  • 应用容器化
  • 面向微服务架构
  • 应用支持容器的编排调度

到了 2018 年,随着近几年来云原生生态的不断壮大,所有主流云计算供应商都加入了该基金会,且从 Cloud Native Landscape 中可以看出云原生有意蚕食原先非云原生应用的部分。CNCF 基金会中的会员以及容纳的项目越来越多,该定义已经限制了云原生生态的发展,CNCF 为云原生进行了重新定位。

以下是 CNCF 对云原生的重新定义(中英对照)

云原生技术有利于各组织在公有云、私有云和混合云等新型动态环境中,构建和运行可弹性扩展的应用。云原生的代表技术包括容器、服务网格、微服务、不可变基础设施和声明式 API。

这些技术能够构建容错性好、易于管理和便于观察的松耦合系统。结合可靠的自动化手段,云原生技术使工程师能够轻松地对系统作出频繁和可预测的重大变更。

云原生计算基金会(CNCF)致力于培育和维护一个厂商中立的开源生态系统,来推广云原生技术。我们通过将最前沿的模式民主化,让这些创新为大众所用。

设计理念

云原生系统的设计理念如下:

  • 面向分布式设计(Distribution):容器、微服务、API 驱动的开发;
  • 面向配置设计(Configuration):一个镜像,多个环境配置;
  • 面向韧性设计(Resistancy):故障容忍和自愈;
  • 面向弹性设计(Elasticity):弹性扩展和对环境变化(负载)做出响应;
  • 面向交付设计(Delivery):自动拉起,缩短交付时间;
  • 面向性能设计(Performance):响应式,并发和资源高效利用;
  • 面向自动化设计(Automation):自动化的 DevOps;
  • 面向诊断性设计(Diagnosability):集群级别的日志、metric 和追踪;
  • 面向安全性设计(Security):安全端点、API Gateway、端到端加密;

容器

容器最初是通过开发者工具而流行,可以使用它来做隔离的开发测试环境和持续集成环境,这些都是因为容器轻量级,易于配置和使用带来的优势,docker 和 docker-compose 这样的工具极大的方便的了应用开发环境的搭建,开发者就像是化学家一样在其中小心翼翼的进行各种调试和开发。

随着容器的在开发者中的普及,已经大家对 CI 流程的熟悉,容器周边的各种工具蓬勃发展,俨然形成了一个小生态,在 2016 年达到顶峰,

容器生态涵盖了容器应用中从镜像仓库、服务编排、安全管理、持续集成与发布、存储和网络管理等各个方面,随着在单主机中运行容器的成熟,集群管理和容器编排成为容器技术亟待解决的问题。譬如化学家在实验室中研究出来的新产品,如何推向市场,进行大规模生产,成了新的议题。

在单机上运行容器,无法发挥它的最大效能,只有形成集群,才能最大程度发挥容器的良好隔离、资源分配与编排管理的优势,而对于容器的编排管理,Swarm、Mesos 和 Kubernetes 的大战已经基本宣告结束,Kubernetes 成为了无可争议的赢家。

随着 Kubernetes 的日趋成熟,“Kubernetes is becoming boring”,基于该 “操作系统” 之上构建的适用于不同场景的应用将成为新的发展方向,就像我们将石油开采出来后,提炼出汽油、柴油、沥青等等,所有的材料都将找到自己的用途,Kubernetes 也是,毕竟我们谁也不是为了部署和管理容器而用 Kubernetes,承载其上的应用才是价值之所在

技术名词概念

超分

CPU“超分”是公有云(阿里云、华为云等)应用虚拟化技术时的一个必然现象,即:当设备满载或接近满载时,一台物理机被VMVare、ESXi等虚拟化系统平台自动划分成多个虚拟机,以求最大限度利用资源。

“超分”是虚拟化平台的优势,能够将可分配给客户机器的内存总合大于实际可用的物理内存总数。因为物理机中的客户机不可能都处于高负荷的状态,所以适当的超分有助于资源的充分利用。

当一台物理机被分割为N虚拟机时,每台虚拟机的计算性能缩减到了1/N的性能,这就产生了不少用户:测试时很快,实际渲染时却很慢,而且费用也很高,甚至不同机器费用高低不一”的现象;带来的后果是用户测试时感觉费用很低或速度很快,实际渲染却发现速度慢,实际支付的渲染费用高。但这不是欺诈行为,而是VMVare等虚拟化平台默认开启的功能。

适当超分会有助于资源的充分利用,但当平台用户量过多时, CPU超分率数值过大可能会严重影响物理机性能,导致业务性能卡顿,影响用户渲染、服务体验。

隔离技术与故障域

故障域指的是当一个区域出现故障以后,它的受影响范围。例如在设计双活数据中心的时候,我们要设置故障域,那个故障域是A站点,哪个是B站点。A站点出现断电,受影响的最大范围只限于本站点,那么A站点就是一个故障域。当然,硬件层面的故障域还可以分得更细:比如一个数据中心内部,不同楼层是不同的故障域;同一个楼层,不同的机架也是不同的故障域。在故障域这个问题上,关键是看故障的类型如何定义

而隔离技术就是限制故障域的。当然,应用级别的隔离术比硬件的隔离更为细致。其中包括

1.线程隔离

线程隔离主要指的是线程池隔离。根据前端的请求不同,把需求转发到不同的线程池中。

2.进程隔离

我们知道,交易和论坛都是电商系统很重要的两部分。在以前,一个电商系统如果不被拆分的情况下,交易请求和论坛请求都会访问同一个应用(一个或多个实例)。当系统拆分以后,论坛系统和交易系统是不同的应用,这样不仅做到了进程隔离,也提高了整体性能

3.集群隔离

集群隔离指的是,当电商系统某一个功能模块,单实例应用无法满足需求的时候,需要部署多个服务形成服务集群。

4.机房隔离

机房隔离是为了满足应用高可用的要求。每个机房的前端,可以通过DNS/负载均衡进行分流。或者在客户端的请求中,指明机房的分组标签。机房隔离是比较传统的隔离技术。

5.读写隔离

读写隔离又称读写分离。读写分为通常指的是数据库,如传统的RDBMS:Oracle DB、MySQL/Maria DB,以及缓存如:redis(key-value)、memcached(key-value)等。读写分离除了可以提高性能,还有一个好处是,当主集群出现问题的时候,如果没法写入数据,但用户客户从备集群读取数据。

6.动静隔离

大家都有网购的经历。网购的页面,有的是静态页面,有的是动态页面。例如:服装的图片是静态的,而附件界面是动态的。为了保证性能,电商通常将动态内容与静态资源分离,而一般静态资源放在CDN上

7.爬虫隔离

网络爬虫,大家可以理解为在网络上爬行的一直蜘蛛,互联网就比作一张大网,而爬虫便是在这张网上爬来爬去的蜘蛛咯,如果它遇到资源,那么它就会抓取下来。比如它在抓取一个网页,在这个网中他发现了一条道路,其实就是指向网页的超链接,那么它就可以爬到另一张网上来获取数据。这样,整个连在一起的大网对这之蜘蛛来说触手可及.

在用户浏览网页的过程中,我们可能会看到许多好看的图片,我们会看到几张的图片以及百度搜索框,这个过程其实就是用户输入网址之后,经过 DNS 服务器,找到服务器主机,向服务器发出一个请求,服务器经过解析之后,发送给用户的浏览器 HTML、JS、CSS 等文件,浏览器解析出来,用户便可以看到形形色色的图片了.

根据统计,很多网站的流程和正常流量访问比率可高达5:1,这种情况下,可以将爬虫路由到单独的集群

8.热点隔离

抢购、秒杀、开门红等业务,都属于热点。对于这种系统,应该造成独立的系统进行隔离,底层使用配置较高的硬件服务器、更好的网络带宽,并且加入多级缓存。

9.资源隔离

资源隔离是比较好理解发的。如CPU、内存、IO的隔离。这同样属于传统硬件隔离范畴。基本原则是,按照业务特点,业务区域。如CPU密集型的应用,底层服务器多配置主频高的处理器,大内存访问的应用,配置内存高的服务器。另外,对于到多数I/O访问量高的应用,通常使用SSD磁盘

以一个电商的架构为例

从最外端的Web UI开始,这是一个用node.js写的微服务。用于对外提供访问,接受用户的请求。接下来是CoolStore的GW,其实就是这套微服务的API Gateway,Spring boot书写。指向到CoolStore的GW的Hystrix和Turbine负责微服务的熔断。

接下来的六个微服务,从左右往右:Rating Service、Review Service、Inventory Service、Catelog Service、Cart Service、Pricing Service。则是我们网购的时候,调用后端的微服务。其实也就是网购具体的应用。

  • Catelog Service,也就是目录服务 - JBoss 的Java应用程序,为零售产品提供产品和价格.
  • Cart Service,也就是购物车服务 - 在每个客户管理购物车的JDK上运行的Spring Boot应用程序
  • Inventory Service,也就是库存服务 - 在JBoss EAP 7和PostgreSQL上运行的Java EE应用程序,为零售产品提供库存和可用性数据
  • Pricing Service,也就是定价服务 - JBoss BRMS产品定价业务规则应用
  • Review Service,也就是审查服务 - 在JDK上运行的WildFly Swarm服务,用于撰写和显示产品评论
  • Rating Service,也就是评级服务 - 在JDK上运行的Vert.x服务用于评级产品
  • Coolstore API网关 - 在JDK上运行的Spring Boot + Camel应用程序作为后端服务的API网关。
  • Web UI - 在Node.js容器中运行的基于AngularJS和PatternFly的前端。也就是客户访问电商的界面展示。

Rating Service、Review Service、Inventory Service、Catelog Service这四个微服务,都有自己的数据库。这其实正是符合微服务的share as little as possible原则。即说微服务应该尽量设计成边界清晰不重叠,数据独享不共享。实现所谓的“高内聚、低耦合”。这样有助于实现独立可部署

在这个案例中,前文提到的:线程隔离、进程隔离、集群隔离、读写隔离、爬虫隔离、机房隔离、热点隔离、资源隔离都已经可以实现。而动静隔离只要前面增加CDN即可。

线程隔离:客户端发起不同的请求,CoolStore的网关根据请求的类型,查分发送到不同的微服务。如有的用户是浏览购物记录,有的是查价格,有的看评论等等。

进程隔离:各个后台微服务之间,就是进程隔离。

集群隔离:每个后台的微服务都是一个service,每个service都可以有多个Pod,也就是多个应用实例,组成应用集群。

读写隔离:将微服务后端的数据库按照读写分离的方式部署到容器中即可。

爬虫隔离:可以将其作为微服务进行部署。

机房隔离:PaaS架构搭建的时候,可以跨机房。对不同机房的物理服务器打label即可。这样部署容器的时候,就可以将一个应用不同的容器实例跨机房。

热点隔离:电商里,web-ui、评论等容易出现热点的微服务,可以通过打标签的方式,部署到配置高的服务器上。

资源隔离:与机房隔离类似,通过对服务器打标签,在部署微服务的时候,可以将不同的服务部署到不同的物理服务器上,实现资源隔离。

所以说,微服务很适合互联网架构,而容器很适合微服务。在容器化的微服务中,API网关是个很重要的角色。在微服务中,API网关很多时候需要引入hystrix这个熔断器。

容灾与容错

容灾:是指系统冗余部署,当一处由于意外停止工作,整个系统应用还可以正常工作。

容错:是指在运行中出现错误(如上下游故障或概率性失败)仍可正常提供服务。

可用性:描述的是系统可提供服务的时间长短。用公式来说就是A=MTBF/(MTBF+MTTR),即正常工作时间/(正常工作时间+故障时间)。

可靠性:描述的是系统指定时间单位内无故障的次数。比如:一年365天,以天为单位来衡量。有天发生了故障,哪怕只有1秒,这天算不可靠。其他没有故障的是可靠的。

稳定性:这个业界没有明确的定义,我的理解是:在受到各种干扰时仍然能够提供符合预期的服务的能力。

从要求的严格程度上:可用性<可靠性<稳定性。

可用性和可靠性更侧重于容灾,而对稳定性同时包含容灾和容错。

服务容错的难点在于存在未知和不可预测。所以对服务容错要处理两个问题:发现和解决。

虚拟化

VNC与noVNC

VNC (Virtual Network Console)是虚拟网络控制台的缩写,分为server端和client端两部分,分别部署完成后在server端简单的配置即可使用,基于TCP的通信。noVNC项目是通过取消VNC Client的安装,直接通过浏览器访问noVNC,然后由noVNC间接访问VNC server来达到client web化。从上面部署方式看到,VNC server仍然保留且没有任何修改,处理的始终是TCP流量,但是浏览器和noVNC之间是在http基础上使用WebSocket交互,由于VNC server 无法处理websocket流量,因此引入了 websockify ,noVNC的姐妹项目,负责把WebSocket流量转换为普通的TCP流,使VNC server正常工作。noVNC其实是一个HTML形式的APP,websockify并充当了一个mini web server的角色,当浏览器访问时,会通过网络加载运行noVNC。

noVNC 作为一个高性能,开源的项目,被集成到众多公司,项目的控制面板功能当中,例如VMware 的VM console, PVE 等,当然你也可以集成到任何个人的web项目中,来增加基于web的远程控制的功能。

安装vnc server

vncserver是用来实现远程桌面连接的,比如说你由两台机器PC1:192.168.1.101和PC2:192.168.1.102,如果你想在PC1上访问PC2的桌面,就需要在PC2上安装vncserver,然后在PC1上通过vncviewer或noVNC访问PC2。下面以tigervnc-server为例来介绍一下vncserver的安装和使用。

安装

yum -y install tigervnc-server

安装完后,查看vncserver的配置文件:

[root@mycentos liushaolin]# rpm -qc tigervnc-server
/etc/sysconfig/vncservers

启动vnc server

vncserver
或
vncserver :n

这里的n就是sessionnumber,不指定的话默认为1,第一次启动时会提示输入密码,以后也可以使用vncpasswd命令修改密码。VNC的默认端口号是5900,而远程桌面连接端口号则是5900+n。如果使用“vncserver :1”命令启动VNC Server,那么端口应该是5901。

vncserver -list[root@mycentos liushaolin]# vncserver -list

TigerVNC server sessions:

X DISPLAY #	PROCESS ID
:1		5918
:3		7726

安装noVNC

$git clone https://github.com/kanaka/noVNC
$cd noVNC
$./utils/launch.sh --vnc localhost:5901

启动launch脚本,会输出如下信息:

WebSocket server settings:
  - Listen on :6080
  - Flash security policy server
  - Web server. Web root: /root/noVNC
  - No SSL/TLS support (no cert file)
  - proxying from :6080 to localhost:5901


Navigate to this URL:

    http://localhost:6080/vnc.html?host=localhost&port=6080

这时,访问http://localhost:6080/vnc.html?host=localhost&port=6080http://localhost:6080/vnc.html,然后输入Host地址,端口号,密码,token,其中密码和token有的话需要输入,然后连接即可。当然你可以从PC1的浏览器中输入PC2的IP地址访问。

https://vosamo.github.io/2016/07/noVNC%E7%9A%84%E4%BD%BF%E7%94%A8%E4%B9%8B%E4%B8%80/

https://github.com/novnc/noVNC

服务发现

假设我们写的代码会调用 REST API 或者 Thrift API 的服务。为了完成一次请求,代码需要知道服务实例的网络位置(IP 地址和端口)。

运行在物理硬件上的传统应用中,服务实例的网络位置是相对固定的,代码能从一个偶尔更新的配置文件中读取网络位置。

对于基于云端的、现代化的微服务应用而言,这却是一大难题。将容器应用部署到集群时,其服务地址是由集群系统动态分配的。那么,当我们需要访问这个服务时,如何确定它的地址呢?这时就需要服务发现(Service Discovery)了

服务分服务提供者(Service Provider)和服务消费者(Service Consumer),如果要提供海量服务能力,单一的服务实例显然是不够的,如果要提供成千上万种服务,则需要有一个地方记录服务名到服务实例列表的映射,所以,有必要引入一个新的角色:服务中介,服务中介维护一个服务注册表(Service Registry),可以把注册表理解为服务字典,key是服务名,value是服务提供实例列表;服务注册表是联系服务提供者和服务消费者的桥梁,它维护服务提供者的最新网络位置等信息,也是服务发现最核心的部分。

服务发现有两大模式:客户端发现模式和服务端发现模式。

客户端发现模式

使用客户端发现模式时,客户端决定相应服务实例的网络位置,并且对请求实现负载均衡。客户端查询服务注册表,后者是一个可用服务实例的数据库;然后使用负载均衡算法从中选择一个实例,并发出请求。

服务实例的网络位置在启动时被记录到服务注册表,等实例终止时被删除。服务实例的注册信息通常使用心跳机制来定期刷新。

客户端发现模式优缺点兼有。

  • 这一模式相对直接,除了服务注册外,其它部分无需变动。此外,由于客户端知晓可用的服务实例,能针对特定应用实现智能负载均衡,比如使用哈希一致性。
  • 这种模式的一大缺点就是客户端与服务注册绑定,要针对服务端用到的每个编程语言和框架,实现客户端的服务发现逻辑。

服务端发现模式

客户端通过负载均衡器向某个服务提出请求,负载均衡器查询服务注册表,并将请求转发到可用的服务实例。

Kubernetes 和 Marathon 这样的部署环境会在每个集群上运行一个代理,将代理用作服务端发现的负载均衡器。客户端使用主机 IP 地址和分配的端口通过代理将请求路由出去,向服务发送请求。代理将请求透明地转发到集群中可用的服务实例。

服务端发现模式兼具优缺点。

  • 它最大的优点是客户端无需关注发现的细节,只需要简单地向负载均衡器发送请求,这减少了编程语言框架需要完成的发现逻辑。并且如上文所述,某些部署环境免费提供这一功能。
  • 这种模式也有缺点。除非负载均衡器由部署环境提供,否则会成为一个需要配置和管理的高可用系统组件。

对比客户端发现模式,使用服务端发现模式的客户端本地不保存服务实例列表,客户端不做负载均衡,这个负载均衡器既承担了服务发现的角色,又承担了网关的角色,所以经常叫API网关服务器

因为负载均衡器是中心式的,所以它也必须是一个集群,单个实例不足以支撑高并发访问,针对负载均衡器本身的服务发现和负载均衡通常借助DNS。

Http服务器,Nginx、Nginx Plus就是此类服务端发现模式的负载均衡器。

优点

  • 服务发现对于服务消费者是透明的,服务消费者与注册表解耦,服务发现功能的更新对客户端无感知。
  • 服务消费者只需要向负载均衡器发送请求,不需要为每种服务消费者的编程语言和框架,开发服务发现逻辑SDK。

缺点

  • 由于所有请求都要经负载均衡器转发,所以负载均衡器有可能成为新的性能瓶颈。
  • 负载均衡器(服务网关)是中心式的,而中心式的架构会有稳定性的隐忧。
  • 因为负载均衡器转发请求,所以RT会比客户端直连模式高。

云端IDE

传统上,软件开发是(而且在很大程度上仍然是)在个人机器上使用集成开发环境(IDE)工具,如 VSCode、JetBrains、Eclipse 等完成。虽然这种 “离线” 开发的模式在早期运作得非常好,但人们很快就注意到,这种方法并非完美。

首先,合作起来很麻烦,因为写好的代码必须上传到网上供进一步审查。这样写出来的代码的可移植性也并不总是有保证,因为有各种各样的操作系统和其他限制条件,需要它来实现最佳的功能。

正如开发者和技术记者 Owen Williams 去年 在他的博客 Charged 上写道:“在设备之间同步你的文档和照片是微不足道的…… 这样你就可以在任何地方把它们调出来,但开发者工具仍然停留在过去 —— 每台笔记本电脑或 PC 都要单独配置,使你的环境设置得恰到好处。”

随着大流行期间越来越多的分布式团队和更多的敏捷工作方式,引入能够让开发人员在任何地方保持生产力的工具变得至关重要。这为什么会有 GitpodGitHub Codespaces、Replit 等基于云端 IDE 出现。

云端IDE的优点:

使用云端 IDE 无需担心配置

由于开发环境完全在浏览器上运行,因此不再需要梳理安装页面和弄清楚需要安装哪个软件包。

硬件的选择并不重要

基于云的集成开发环境消除了(好吧,几乎是!)开始进行网络开发的障碍。在任何支持现代网络浏览器都可以运行,你甚至不需要在不同的机器上从头开始重新配置一切。

在任何地方工作和协作都很容易

这些工具具有高度可定制的工作空间,可以在团队 / 个人层面上进行优化,它们不仅促进了更好的合作,而且完全消除了 “在我的机器上可以运行 " 这种太过普遍的情况。鉴于这些主要的优点,很明显基于云的 IDE 已经获得了发展势头。

于云的 IDE 的许多缺点都与扩展问题有关,因为这些工具仍然处于成熟的早期阶段。以下是早期采用者可能会遇到的一些关键问题。

性能可能是不平衡的

由于云上的资源是由需求不稳定的消费者共享的,因此肯定有机会出现性能不一致的情况,特别是在对网络延迟、容量或整体产品的故障造成问题的情况下,更是如此。

故障的来源可能很难识别和解决

当你不知道根本原因时,很难修复一个问题,总的来说,这可能会导致此类产品的早期采用者有一个令人沮丧的体验。

大项目可能更适合使用离线 IDE

到今天为止,已经观察到一些初期问题,用户抱怨平均负载过高。对于大型开发项目,所需的数据传输和处理量将是巨大的。虽然它可能不会扼杀基于云的 IDE 的资源,但由于其实用性,在这种情况下,离线替代方案肯定是更佳选择。

供应商锁定会限制工具的可用性

另一个需要考虑的方面是当涉及到基于云端 IDE 时,工具包的可用性。大量的工具可以在本地与 IDE 配对使用。但是,对于基于云端 IDE,开发者被限制在供应商提供的集成选择上,这对于那些需要更广泛工具包的人来说可能是限制性的。

云端 IDE 需要 WiFi

最后一点往往被忽略,基于云的 IDE 在与真正强大的桌面 IDE 相媲美之前还有很长的路要走,这些 IDE 允许降低对 WiFi 等外部因素的依赖性。即使正在实施各种变通办法,其可靠性水平也远远不能与桌面 IDE 提供的离线体验相比。

云工具

腾讯HiFlow:https://hiflow.tencent.com/

云原生资源

国内云原生社区: https://cloudnative.to/

国外云原生社区:cncf

如果你觉得我的文章对你有帮助的话,希望可以推荐和交流一下。欢迎關注和 Star 本博客或者关注我的 Github