本期详细解读云原生,本文从云原生概念、业务、开发、实践以及发展方向做了做一下浅谈,附高清版2022通信院发布的“云原生产品目录”

一直都对云原生未来的发展可能充满好奇,也算是在这里得到了一些答案吧!

去年最大的感受是云原生和不同行业的结合适配度更高了,这必然要面临解决个性化业务需求的问题,对技术应该也是很大的考验吧!

今天通过了一晚上的学习,做了一些准备,浅谈一下云原生,希望我们共同进步,有问题的地方希望大家留言补充,一起进步。

云原生本身涉及到的层面非常复杂也非常广泛,技术和业务打好配合确实相当重要,具备宏观战略意识的人才能看到云原生带来的本质问题,通过一些目前现有的知识,了解到,云原生转型依然存在一些痛点,但是看的出来大家还是很有信心的,而且一切都在朝着更好的方向发展!

云原生作为一种新的平台,在平台上构建面未来的各种创新服务,万千企业都可以相互学习、相互借鉴,小步快跑,共同前进,面对不确定的未来不断创新。尤其是将云原生与行业知识结合起来的行业领导者,通过在行业中分享与跨行业分享,真正将云原生技术推广到千行百业,进入到应用的星辰大海,也就建立了中国数字化升级的创新之路。

 云原生(Cloud Native)的概念,由来自Pivotal的MattStine于2013年首次提出,被一直延续使用至今。这个概念是Matt Stine根据其多年的架构和咨询经验总结出来的一个思想集合,并得到了社区的不断完善,内容非常多,包括DevOps、持续交付(Continuous Delivery)、微服务(MicroServices)、敏捷基础设施(Agile Infrastructure)和12要素(TheTwelve-Factor App)等几大主题,不但包括根据业务能力对公司进行文化、组织架构的重组与建设,也包括方法论与原则,还有具体的操作工具。采用基于云原生的技术和管理方法,可以更好地把业务生于“云”或迁移到云平台,从而享受“云”的高效和持续的服务能力。

一.云原生的定义

云原生(Cloud Native)是一种构建和运行应用程序的方法,是一套技术体系和方法论。Cloud Native是一个组合词,Cloud+Native。Cloud是适应范围为云平台,Native表示应用程序从设计之初即考虑到云的环境,原生为云而设计,在云上以最佳姿势运行,充分利用和发挥云平台的弹性+分布式优势。

1、原生云的历史

2013年,Pivotal公司的Matt Stine于首次提出原生云(CloudNative)的概念,用于区分为云而设计的应用和云上部属传统应用。

2015年,Matt Stine在《迁移到云原生架构》一书中定义了符合原生云架构的几个特征:12因素、微服务、自敏捷架构、基于API协作、抗脆弱性;

2015年云原生计算基金会(CNCF)成立,CNCF作为一个厂商中立的基金会,致力于云原生应用推广和普及。

2017年,Matt Stine将原生云架构归纳为模块化、可观察、可部署、可测试、可替换、可处理6特质;而Pivotal最新官网对云原生概括为4个要点:DevOps+持续交付+微服务+容器。

2、CNCF对云原生的定义

CNCF(Cloud Native Computing Foundation)于 2015 年 7 月成立,隶属于 Linux 基金会,初衷围绕“云原生”服务云计算。CNCF作为一个厂商中立的基金会,致力于Github上的快速成长的开源技术的推广,如Kubernetes、Prometheus、Envoy等,帮助开发人员更快更好的构建出色的产品。

原生计算基金会(CNCF)成立,是云计算的一个里程碑,标志着云计算的建设关注点从基础设施的建设向应用的云架构转变。CNCF对云原生的定义是个不断优化的过程。目前CNCF对于原生云的定义为:

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

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

CNCF对云原生的描述,前半部分是给出了云原生的定义,并给出目前云原生最佳的技术实践。后半部分指出构建云原生应用的目标。

CNCF还给出了构建云原生的相关技术栈,已经基金会相关的孵化项目信息。

3、云原生的关键技术

CNCF在定义中给出了云原生的关键技术,容器、服务网格、微服务、不可变基础设施和声明式API,是目前云原生应用的最佳实践。

 云原生技术栈

二.云原生的发展趋势

1、运维继续下沉,服务网格将成为主流,Serverless逐步推广

云计算的一个发展方向就是运维下沉,将和业务无关的管理功能和运维工作尽量下沉到基础设施中,应用可以聚焦在业务能力的开发和运营。这个趋势演化的过程,影响了云计算的发展方向。从一开始的虚拟化,到IaaS,到PaaS都是将应用系统的部分运维职责交给平台运维的过程。

云计算经过十几年的发展,从一开始讨论什么是云计算,到争论云计算是否是旧瓶装新酒,再到讨论如何建设云基础能力,到如何建设云平台上的应用,随着业界对云计算技术的不断探索,我们对云计算的理解和期望在日益提升。当前,大部分的企业已经确实体会到了云计算带来的竞争优势,并已经建成企业内部的私有云基础能力,或是将数据中心迁移到公有云上。应用如何使用好云计算基础设施,使云计算发挥最大能力,是目前云计算技术中最重要的议题。基于云计算平台设计的应用,业界称之为云原生应用。

 

 运维职能下移

三.综述

云原生技术是目前技术阶段,企业IT系统的最优模式的集合。企业通过遵循云原生的技术和设计模式,可以充分发挥云计算平台的优势的同时,可以最大限度的减少对开发效率的影响,实现稳定而高效的系统。技术是不断发展的,云原生技术也是一个不断更新迭代的过程,相应的开发习惯和方法也会跟着改变。

实现思路

我们通过“Kubernetes 云原生”化来实现我们的目标:

Kubernetes 是业界通用的,用于自动部署,扩展和管理容器化应用程序的开源编排系统。简单地说,它能够系统化地打包、运行、管理你的服务,在这里是 Bytedoc 数据库服务。这使得我们能够结合已有的运维经验和业界通用服务交付/管理解决方案,提供更好的、更高质量的数据库服务,以发挥 Bytedoc 3.0 十足的"弹性"能力

在 ByteDoc 1.0 时期,大多数数据库服务实例是直接部署到虚拟机上的,资源的分配受限于虚拟机规格的划分,无法灵活地、按需要分配机器资源,导致大部分的机器资源空闲出来,无法得到有效利用;同时,因为计算与存储的资源绑定,在 1.0 的自研部署平台中,实现容器化部署十分困难,虚拟机部署的方案就一直保留下来。

直到 ByteDoc 3.0 的出现,将数据下沉存储层,交付服务时,更多关注计算层方面的资源分配,使得容器化部署模式可行。结合 Kubernetes 对容器部署与管理的解决方案,我们将容器大部分自动化管理操作交由给 Kubernetes 控制器管理,专注于 ByteDoc 3.0 服务编排过程,如集群部署、从库扩容等,以充分发挥 3.0 的"弹性"能力。

云原生实践

服务云原生化,实际上是一个“迁移”的过程,将原有服务打包、运行、管理能力,以 Kubernetes 提供的解决方案为标准,重现出来。

在 Kubernetes 中,我们把 ByteDoc 3.0 集群定义为一种定制资源(CustomResource)。提供数据库服务,实际上就是创建了一种资源;和 K8s 内置的工作负载资源一样,定制资源也需要一个控制器来进行管理,通常把这类控制器称作 Operator。

所以,ByteDoc 3.0 云原生实践的关键是构建 ByteDoc Operator。

Kubernetes 基本概念

容器化部署

前面说到,Kubernetes 是一个容器编排系统,主要的职责是管理容器生命周期,所以实际的应用程序应该提前打包成一个容器镜像,以便于交付给 K8s 来使用。

Pod

https://kubernetes.io/zh/docs/concepts/workloads/pods/

我们打包好的容器最后会运行在 Pod 中,由 Pod 管理起来。

Pod 是 K8s 中内置的最基本的资源之一,也是最小部署的计算单元,可以类比于一些共享机器资源的容器组。

如果一个 Pod (内的容器)因异常导致退出,通常情况下,这个 Pod 会被删除销毁,高级 workload 会新建一个全新的 Pod 来代替它,而不是“重启”该 Pod。

高级 workload

通常情况下,我们构建的 Operator 不会去直接创建 Pod;而是使用 K8s 提供的高级 workload 资源,他们会帮我们把 Pod 创建出来,并提供一些基本的资源管理能力。

Deployment:

  • 维护一组给定数量的、完全相同的 Pod,通常用于无状态服务。

StatefulSet:

  • 同样维护一组 Pod,特别的是,每个 Pod 都有稳定的网络标示;在此情景下,如果一个 Pod 被销毁重建,在外部使用者看来,该 Pod 是进行“重启”了,所以通常用于有状态的服务。

如何与 K8s 交互

Kubernetes  控制面的核心是  API 服务器。API 服务器负责提供 HTTP API,以供用户、集群中的不同部分和集群外部组件相互通信。

一般而言,我们与 K8s 交互是通过“声明式”,而非“动作命令式”。

# sample.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  minReadySeconds: 6
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

ByteDoc 3.0 在 Kubernetes 上的架构

 

 (ByteDoc 经典架构,由三部分组成)

mongos:

  • 代理层,负责转发、简单处理用户请求;

  • 需要感知 Config Server,从中获取 Shard 的拓扑;

config server:

  • 复制集模式,区分主从;

  • 存储集群元信息,包括每个 shard 内实例的地址;

shard:

  • 复制集模式,区分主从;

  • server 层,处理用户请求;

 

  • mongos - deployment,对应无状态的服务

  • config server/shard - statefulset,对应有状态的服务

对于 mongo 的复制集,复制集成员需要用一个网络标示(host、dns、服务发现、headless service 等)注册进配置中,才能与其他复制集成员进行通信;所以在这里,我们使用 StatefulSet 提供的稳定的网络标示作为成员名称,保证数据库实例(对应的 pod)故障恢复后,以同样的身份加入到复制集中,正常地提供服务。

联邦模式

多机房场景下的架构

实际上,上述 ByteDoc 3.0 集群是在单机房下的架构,在线上生产环境中,还要考虑多机房容灾的场景;在多机房场景下,我们希望一个 3 副本的集群,每个计算实例是分别部署在不同的机房,但是这些副本又是需要在同一个复制集中的,在参考了几种跨 K8s 方案后,我们采取了下面的多机房架构:

有哪些候选的跨 K8s 的方案?

  1. 社区提供的 Federation V1 方案(deprecated,后续改进为 V2 方案)

    主要提供两个主要能力来支持管理多个集群:跨集群同步资源 & 跨集群服务发现

  2. 云原生 SRE 团队提供的通用 operator 方案

...
spec:
    charts:
    - name: nginx
      chart: charts/nginx
      values: '"replicaCount": "{{ .replica_count | default 1 }}"'
    cluster:
    - placement:
      - names:
        - cluster-sample
    execJobs:
    - name: ls
      command:
      - ls
      - "-l"
      mustBefore:
      - chart.nginx
    var:
      replica_count: '2'
  • 定义一系列的 chart、K8s 集群、执行任务、变量

  • 通过通用 operator 在多个 K8s 集群上完成资源部署、任务执行

  1. MongoDB 官方提供的跨 K8s 方案

  • 通过 mongodb 额外的 k8s-agent 完成跨 K8s 集群场景下,复制集与集群的构建

  • 代码未开源

为什么选择了现在这种方案?

我们当前的方案实际上和社区的 Federation 方案比较相似,通过以下的能力搭建完整的 ByteDoc 3.0 集群:

  • 资源复制:operator 连接 worker K8s,创建基本相同的资源

  • 服务发现:分具体的网络场景,如果使用 overlay 网络,可以使用社区支持的无头服务(headless service);如果是走 underlay 网络,则需要额外的服务发现能力

  • 组建 ByteDoc 集群:将实例组建为集群的核心逻辑,比较复杂,不太容易通过任务的形式实现

因此,我们选择这种 Meta Operator 的方案,通过 worker K8s 创建资源,后续 Operator 完成集群的搭建工作。

达到期望状态

spec:
  global:
    chartVersion: "1.0.0.0"
    bytedocVersion: "3.0"
    image: "example_image"
  mongos:
    replicaCount: 2
    resources:
      limits:
        cpu: "4"
        memory: 2Gi
      requests:
        cpu: "1"
        memory: 1Gi
  shard:
    shardsCount: 1
    replicaCount: 4
    ...
  config:
    replicaCount: 3
    ...
  placement:
    - name: vdc1
      vdc: "vdc1"

那么 ByteDoc Operator 到底执行了什么逻辑呢?Operator 其实也满足 K8s 控制器的设计理念,也就是,每个资源对象有一个期望状态,operator 需要把资源对象调整至期望状态,这个调整过程称为 Reconcile。

再仔细探究一下,ByteDoc 集群分为 3 个组件,只要 Mongos、config server、shard 三个组件都达到期望状态,最后将组件“连接”起来,整个集群也达到期望状态了;

所以我们可以将整个集群的 Reconcile,分解为对若干个模块 Reconcile,当每个小的模块都达到期望状态,整个集群也达到了期望状态,bytedoc operator 大致是基于这样的设计理念。

状态管理 - Status

https://kubernetes.io/zh/docs/concepts/overview/working-with-objects/kubernetes-objects/#object-spec-and-status

Status 顾名思义就是用来存储一个资源对象当前状态的,可以充当状态机或小型存储使用。可以用来实现:

  • 一次性操作的完成情况:如初始化是否完成

  • 镜像/服务版本

  • 组件 status

  • 集群升级进度控制

  • 备份进度控制

  • 资源变更是否完成

    • 通常记录在字段 observedGeneration

    • 当我们对集群 CR 做变更时,metadata 中的 generation 计数会 +1,operator 需要在达到这次变更的期望状态时,设置相等的observedGeneration 计数,以方便查询 CR 变更已完成。

  • 等等

status:
  replica_set:
    ll2022-shard-0:
      inline:
        added_as_shard: true
        initialized: true
        read_only_ready: true
        ready: 3
        size: 3
        status: ready
      placement:
        vdc1:
          ready: 3
          size: 3
          status: ready
          vdc: vdc1
    ...

资源模板化管理 - Helm

上面说到,ByteDoc 每个组件实际上用了 K8s 内置的资源来管理的,一般情况下,我们不需要从头编写整个 CR 的 yaml 文件,更多的是调整一个固定模板里的动态参数,比如 mongos 的实例数,CPU、Mem 资源限制等。

从此出发,工程实现上就有两种方向:

  • 将 yaml 模板硬编码到代码中,通过变量替换,生成目标的资源文件;

  • 将 yaml 模板以文件的形式存放,通过字符替换,生成目标的资源文件;

模板渲染与资源发布

我们采用的是第二种方法的一个较为优雅的版本,用 Helm (code)管理内置资源文件的渲染和发布 在 operator 镜像中,我们按照 helm 的标准,维护了一系列 charts 文件。

由于云原生全栈云的建设并非一蹴而就,而是意味着全新IT的重塑,包括开发模式、系统架构、部署模式、基础设施、组织文化等一系列的自动化、敏捷化演进和迭代,因此我们建议传统企业在构建云原生全栈云时,实施“三步走”策略。

第一步,建立全栈云平台,构建平台服务能力。可以先建设一个标准的、小规模但功能齐全的全栈云,初步实现一个平台、四种能力、试点应用。

第二步,丰富中台业务能力,打造一体化运维体系。从局部试点到全局应用,在平台基础之上扩展更多的业务能力,扩大应用规模,提升管理水平。

第三步,丰富完善自身能力,优势能力持续推广。最后依托完善的平台能力,进一步实现对内的深入推广,对外的同业赋能。

首先,为了抓住商业机会,业务需要快速迭代,不断试错,因此,企业需要依赖拥有持续交付的能力,这些不仅包括技术需求还包括产品的需求,如何能拥有持续交付的能力,大而全的架构因为效率低下,显然是不合适的。于是演变出微服务架构来满足需求,通过把系统划分出一个个独立的个体,每个个体服务的设计依赖需要通过12要素的原则来规范完成。同样,如果系统被分成了几十个甚至几百个服务组件,则需要借助DevOps才能很好地满足业务协作和发布等流程。最后,DevOps的有效实施需要依赖一定的土壤,即敏捷的基础设施服务,现实只有云计算的模式才能满足整体要求。通过上述梳理,我们总结出面向云原生应用的3个不同层次的特点。

高可用设计(Design for Availability),依据应用业务需求,高可用分为不同级别,比如不同区域、不同机房(跨城或同城)、不同机柜、不同服务器和不同进程的高可用,云原生应用应该根据业务的可用性要求设计不同级别的架构支持。

可扩展设计(Design for Scale),所有应用的设计是无状态的,使得业务天生具有扩展性,在业务流量高峰和低峰时期,依赖云的特性自动弹性扩容,满足业务需求。

快速失败设计(Design for Failure),即包括系统间依赖的调用随时可能会失败,也包括硬件基础设施服务随时可能宕机,还有后端有状态服务的系统能力可能有瓶颈,总之在发生异常时能够快速失败,然后快速恢复,以保证业务永远在线,不能让业务半死不活地僵持着。

通过上面的基本描述及云原生应用的组成或特点,与容器技术相比可以得知,容器的特性天生就是按这些原则进行设计的。随着互联网业务的架构不断演进,从单体应用到分布式应用,甚至微服务架构应用中,12要素较好地为构建互联网化应用提供了统一的方法论和标准化,具有强大的生命力,每一条原则都是应用开发的珠玑。当然,在实践过程中,每一个原则也不是一成不变的,随着新的理念和技术出现,原有的因素会得到延伸和发展,会出现新的原则和应用,这套理论也适用于任意语言和后端服务(数据库、消息队列、缓存等)开发的应用程序,因此也作为云原生架构应用的基本指导原则之一.

在数字经济背景下,传统企业的IT团队面临着更多元的业务需求、更敏捷的迭代速度、更复杂的IT 研发运维管理等一系列挑战,而传统基础设施已不能完全满足企业日益增长的敏态IT挑战。

为更好地应对上述挑战,越来越多的企业开始拥抱开箱即用、自主可控的一站式“全栈云原生”平台,快速优化现有资源配置,最大限度地提高开发人员的生产力、减轻运维人员的工作负担,推动企业IT和业务应用的敏捷迭代和高效演进,以实现数字化转型“弯道超车”。

最后,祝愿大家都能够依据自身企业的实际情况,探寻出最适合自己的云原生转型路径,向更敏捷、更可靠、更高效的云原生全栈云进阶。

附: 《云原生产品目录》

点击下载3M超高清原图

https://download.csdn.net/download/weixin_43044226/85816124

为解决云原生用户选型困境,全面拉齐行业认知,推动云原生产业蓬勃发展,中国信通院面向基础设施服务商、云计算服务商、软件服务商等单位,开展本次“云原生产品目录”征集活动。目前,产品目录已经完成前期收集和整理,并于6月17日“云原生产业大会”正式发布。

本次发布的《云原生产品目录》共收录云原生技术服务产品及解决方案251个,涉及容器、微服务、服务网格、无服务器、云原生存储、云原生数据、云原生安全,以及云原生融合服务等多个类别。

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

珍儿2022

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值