当前软件的部署方式都在朝着云原生化的方式向去迁移。采用云原生架构也会带来一些复杂度,这些复杂度主要是因为引入了一些新的云原生组件,需要部署、维护这些组件,但这部分复杂度作为 Go 开发者通常不需要关注。但是,如果将我们的服务部署在云原生组件上,会带来很多好处。
采用云原生架构去部署服务,会涉及到很多新的组件,并且进入一个新的领域,完全掌握,你需要学习很多知识。本课程不是一门云原生课程,所以本节课不会详细介绍云原生架构中的组件、原理、实战等内容。但本课程,后面会采用云原生化的方式去部署 miniblog 服务,所以,这里会介绍云原生相关的基础知识和部署架构,方便你理解后面的内容。更重要的是,期望通过简短的介绍以及下一节课的实战操作,带你走进云原生的大门。
云原生简介
云原生包含的概念很多,对于一个应用开发者来说,主要关注点是如何开发应用,以及如何部署应用。所以,这里我在介绍云原生架构的时候,会主要介绍应用层的云原生架构设计,以及系统资源层的云原生架构设计。
在设计云原生架构时,应用生命周期管理层的云原生技术,我们主要侧重在使用层面,所以这里我就不详细介绍应用生命周期管理层的云原生架构了。后面的云原生架构鸟瞰图中会提到它,你可以看看。
另外,在介绍云原生时,也总是绕不开云原生计算基金会。接下来,我们就先来简单了解下 CNCF 基金会。
CNCF(云原生计算基金会)简介
CNCF(Cloud Native Computing Foundation,云原生计算基金会),2015年由谷歌牵头成立,目前已有一百多个企业与机构作为成员,包括亚马逊、微软、思科、红帽等巨头。CNCF 致力于培育和维护一个厂商中立的开源社区生态,用以推广云原生技术。
CNCF 目前托管了非常多的开源项目,其中有很多我们耳熟能详的,例如 Kubernetes、Prometheus、Envoy、Istio、Etcd 等。更多的项目,你可以参考 CNCF 公布的Cloud Native Landscape,它给出了云原生生态的参考体系,如下图所示:
什么是云原生?
CNCF官方在2018年发布了云原生v1.0,并给出了定义:
“云原生技术有利于各组织在公有云、私有云和混合云等新型动态环境中,构建和运行可弹性扩展的应用。云原生的代表技术包括容器、服务网格、微服务、不可变基础设施和声明式 API。 这些技术能够构建容错性好、易于管理和便于观察的松耦合系统。结合可靠的自动化手段,云原生技术使工程师能够轻松地对系统作出频繁和可预测的重大变更。”
简单点说,云原生(Cloud Native)是一种构建和运行应用程序的方法,是一套技术体系和方法论。云原生中包含了3个概念,分别是技术体系、方法论和云原生应用。整个云原生技术栈是围绕着 Kubernetes 来构建的,具体包括了以下核心技术栈:
这里来介绍下这些核心技术栈的基本内容:
容器: Kubernetes 的底层计算引擎,提供容器化的计算资源。
微服务: 一种软件架构思想,用来构建云原生应用。
服务网格: 建立在 Kubernetes 之上,作为服务间通信的底座,提供强大的服务治理功能。
声明式 API :一种新的软件开发模式,通过描述期望的应用状态,来使系统更加健壮。
不可变基础设施: 一种新的软件部署模式,应用实例一旦被创建,便只能重建不能更新,是现代运维的基础。
容器、服务网格和微服务,相信你已经很明白这些概念。这里再补充介绍下不可变基础设施和声明式 API。
不可变基础设施(Immutable Infrastructure)的构想,是由 Chad Fowler 于 2013 年提出的。具体来说就是:一个应用程序的实例,一旦被创建,就会进入只读的状态,后面如果想变更这个应用程序的实例,只能重新创建一个新的实例。通过这种模式,可以确保应用程序实例的一致性,这使得落地 DevOps 更加容易,并可以有效减少运维人员管理配置的负担。
声明式 API 是指我们通过工具描述期望的应用状态,并由工具保障应用一直处在我们期望的状态。
Kubernetes 的 API 设计,就是一种典型的声明式 API。例如,我们在创建 Deployment 时,在 Kubernetes YAML 文件中声明应用的副本数为2
,即设置replicas: 2
,Deployment Controller 就会确保应用的副本数一直为2
。也就是说,如果当前副本数大于2
,Deployment Controller 会删除多余的副本;如果当前副本数小于2
,会创建新的副本。
声明式设计是一种设计理念,同时也是一种工作模式,它使得你的系统更加健壮。分布式系统环境可能会出现各种不确定的故障,面对这些组件故障,如果使用声明式 API ,你只需要查看对应组件的 API 服务器状态,再确定需要执行的操作即可。
什么是云原生应用?
上面,我介绍了什么是云原生,接下来再介绍下什么是云原生应用。
整体来看,云原生应用是指生而为云的应用,应用程序从设计之初就考虑到了云的环境,可以在云上以最佳姿势运行,充分利用和发挥云平台提供的各种能力。具体来看,云原生应用具有以下三大特点:
从应用生命周期管理维度来看,使用 DevOps 和 CI/CD 的方式,进行开发和交付。
从应用维度来看,以微服务原则进行划分设计。
从系统资源维度来看,采用 Docker + Kubernetes 的方式来部署。
看完上面的介绍,你应该已经对云原生和云原生应用有了一定的理解,接下来我就介绍一种云原生架构实现。因为云原生内容很多,所以这里的介绍只是起到抛砖引玉的作用,让你对云原生架构有初步的理解。至于在具体业务中如何设计云原生架构,你还需要根据业务、团队和技术栈等因素综合考虑。
一个经典的云原生部署架构
下图,是一个经典的云原生架构部署架构:
上面的云原生部署架构中,分为 2 个 核心部署:
橙色部分:是业务开发人员需要关注的。研发人员构建 Docker 镜像、编写 Kubernetes 资源定义文件,并部署在 Kubernetes 集群中。通常我们需要以 Deployment 的形式部署我们的应用。还需要通过 ConfigMap 来挂载应用的配置。最后通过 Service 来访问应用。
非橙色部分:这部分是运维/云原生组件开发人员需要关注的。运维/云原生组件开发人员负责开发、部署并维护整个 Kubernetes 集群和其他云原生组件。
Go 开发人员只需要将应用构建成镜像、编写 Deployment、ConfigMap、Service 等 Kubernetes 资源定义文件,并通过 kubectl create -f xxx.yaml
这种命令部署到 Kubernetes 集群中,即可享受以 Kubernetes 为底座的整个云原生技术架构带来的能力:自动伸缩、服务发现、健康检查、CI/CD、制品管理、监控告警、日志、审计、配置管理、调用链追踪等能力。
上面的架构图中,物理机/虚拟机提供了最底层的计算资源,例如:网络、磁盘、存储等。上层通过 Docker 容器引擎来对这些资源进行进一步的虚拟化,以达到更细的资源划分、更高效的资源使用率、更快的启动速度等优势。
在往上,我们通过 Kubernetes 集群来调度和管理由 Docker 提供的计算资源。Kubernetes 集群具有很多能力,例如:服务发现和负载均衡、自动部署和回滚、自我修复、自动装箱、密钥和配置管理、高扩展性等。应用部署在 Kubernetes 集群中,就会天然具备这些能力。
在往上,我们通过负载均衡和网关来访问部署在 Kubernetes 集群中的应用。网关可以提供诸如:安全策略、路由策略、流量管理、统计分析、API 管理等功能。在企业中,一些小的团队、项目也可以选择不通过 API 网关来访问,以规避维护网关组件带来的成本。
Kubernetes 的 Service 也具有负载均衡的能力,对于一些小规模的团队和业务,也可以直接通过 Kubernetes 的 Service 来访问集群中的应用。
Docker + Kubernetes 作为整个云原生架构中的底座,可以基于这个底座构建更多的云原生服务,例如:配置中心、镜像仓库、日志查询系统、监控告警系统、审计系统等。这些云原生服务,可以提供对业务应用高效的生命周期管理。
如何学习云原生技术?
云原生很多技术栈都是使用 Go 语言来构建的,学习了 Go 语言,你就具备了学习云原生技术栈的基本能力。在云原生时代中,学习云原生技术对你今后的职业发展具有非常大的帮助。所以作为一名 Go 开发人员,强烈推荐你来学习一些云原生技术。
云原生架构技术栈很多,其中有一些技术栈比较核心,将这些核心技术栈分类,通常可以分为:微服务、Docker、Kubernetes、Serverless、监控告警、日志、调用链追踪、消息队列。
如何学习这些技术栈呢?在我看来可以分为 3 步:学习基础知识 -> 学习相关的开源项目 -> 实战。这里,针对每一个类别,我给出一些资料供你参考学习:
微服务:《微服务设计》;
Kubernetes:《Kubernetes权威指南:从Docker到Kubernetes实践全接触》(第4版)、《基于Kubernetes的容器云平台实战》 ;
Serverless:我们可以通过学习 Knative 来学习 Serverless。Knative 参考文档为 Knative Documentation;
监控告警:监控告警业界的事实标准是 Prometheus,所以我们可以通过 Prometheus Documentation 来学习监控告警以及 Prometheus;
调用链追踪:调用链追踪业界的用的最多的是 Jaeger,所以我们可以通过 Jaeger Documentation 来学习调用链追踪以及 Jaeger;
消息队列:我们可以通过学习 Kafka 来学习消息队列。Kafka 参考文档为:《Apache Kafka实战》;
上面列的是我觉得可以优先学习的技术栈,当然如果你有精力,还可以学习其他云原生技术,例如:Istio、Etcd、服务发现等。
学习完这些技术的基本知识之后,你就可以网上找一些优秀的实战文档,来进一步加深对这些技术的理解和掌握。
小结
当前应用部署最好的方式是采用云原生化的方式去部署(容器化部署),云原生部署架构中涉及很多技术栈,但其中有一些技术栈比较核心,可以通过这些技术栈的学习和实战,来打开云原生世界的大门。本节课就通过介绍云原生、云原生部署架构以及如何学习云原生技术,期望以此带你走进云原生世界的大门,开启更广阔的 Go 研发生涯。