据云原生计算基金会 CNCF 发布的第六次年度调查,96% 的企业正在使用或评估 Kubernetes,国内外很多企业更是将所有的应用都容器化,Docker 和 Kubernetes 等云原生技术已经是众多企业的事实标准。
云原生其实是“以应用为中心”的,包含一整套围绕应用程序的设计、开发、部署、运行、维护的流程,技术栈,文化理念等,而国内九成以上的程序员是从事应用程序开发,比如从事前端、后端、移动端等。那云原生应用又与传统应用有哪些区别与优势?又需要程序员在其中扮演什么角色?云原生时代,程序员应该掌握哪些云原生知识?
1、什么是云原生应用
云原生应用程序通常来说遵循十二要素应用程序的方法论,基于容器的基础架构和侧重于微服务的体系结构,充分利用云计算的优势,提高开发效率,提升业务敏捷度、弹性、可用性、资源利用率,从而达到企业的降本增效。
相比于传统开发方式和传统应用,云原生的开发方式和云原生应用的优势和特点体现在:
- 快速开发、迭代且独立:基于微服务构建的应用程序以及与生产部署集成的测试系统,开发团队之间可以更快、更频繁、更独立地更新、修复和发布应用程序。
- 自动化、可扩展:每一项服务都是高可用的,不会因为某个基础设施的故障而导致应用无法使用;平台自动化可轻松构建和运行易于管理的应用,消除因人为错误造成的停机;
- 伸缩性:云原生应用的每个服务可以独立根据业务负载弹性伸缩,而云计算资源通常是按量付费的,这让云原生应用能够自动高峰期扩展,在低谷期收缩,在复杂业务场景都能正常运行的同时还可以降低成本;
- 开放且灵活:云原生应用程序通常广泛采用开源技术,独立的团队之间也可以使用不同的编程语言与技术栈,同时企业可以构建无需修改便可支持跨公有云、私有云、混合云的应用;
而程序员所要做的就是充分利用云原生的优势如何把现有的应用平滑迁移到云原生环境中,因此对程序员来说,关于云原生应用比较简单而具体的表述是:如何将软件项目拆分为多个分布式的微服务,整个项目基于容器来构建、发布、运行;使用 Kubernetes 来编排与调度这些容器;使用 DevOps 和 GitOps 工作流来管理和自动化部署,以及使用 Prometheus、ELK 等对应用的运行状况进行监控等。
2、程序员需要掌握的云原生技术
因此,云原生时代程序员基本需要掌握四个方面的技术技能:微服务、容器化、GitOps 与 Kubernetes 基础以及服务 API 接口化与服务治理,还需要了解云原生应用的方法论:十二要素应用程序。
首先是要能够根据业务,将项目抽象、解耦,将公共功能通过分解为更小的、模块化的独立服务来简化代码复杂性,这些服务提供直接构建到应用程序的监控、指标和弹性。构建微服务的模块要做到一个服务只完成一个任务,程序之间能够提供一个通用的接口来协同工作。
采用微服务的好处是,应用程序可以相互独立开发(自由选择技术)与部署,模块化强、可替代性强、可持续开发与持续交付,能够缩短软件发布时间,可根据业务负载独立伸缩等。而要想让微服务架构能够正常运行,各个服务之间必须通过消息、REST等机制实现的显示接口相互通信,而通过在应用中构建一层服务网格可以简化服务间通信。
3、如何开始学习
对程序员来说,最简单且最容易入手且最应该先去掌握的,当然是实战性比较强的容器化、 Kubernetes 基础和 GitOps 了。至于微服务、服务治理以及十二要素应用程序这些偏方法论的知识,则都可以建立在 Docker 和 Kubernetes 的基础上。
对于云原生应用程序来说,容器不仅只是项目的代码打包和部署的单位(容器化),也是模块、服务复用的单位(微服务),同时也是应用伸缩以及资源分配的单位( Kubernetes 编排容器),所以容器以及容器化对云原生开发非常基础且重要。
而云原生中最为重要的产品还是号称云计算时代的操作系统 Kubernetes ,云原生应用众多优势的体现都与 Kubernetes 的编排调度息息相关,因此尽管程序员最主要的工作还是云原生应用开发,而 Kubernetes 的集群管理好像也是运维工程师的职责,但是程序员还是需要了解一些 Kubernetes 的基础。
而GitOps则是一种实现持续交付的模型,它的核心思想是将应用程序及其基础架构配置(如应用所需要的CPU、内存、存储、网络、权限等配置)存放在Git的版本控制库中,通过版本控制库的变更,来实现应用和基础架构的变更。
在这个过程中,程序需要掌握如何将应用打包成容器并通过 GitOps 流水线的方式一键自动发布到线上的容器服务集群(比如腾讯云的容器服务TKE、弹性容器服务 EKS 或微信云托管)上。
关于 Docker 和 Kubernetes 的学习,尽管官方技术文档是一个不错的入门教程,但是仍然存在很多新手不可避免的一些“坑”,让原本简单且有意思的动手变得艰难,有的人甚至连安装配置环境就阻力重重。
尽管 Docker 和 Kubernetes 官方技术文档是一个不错的入门教程,但是仍然存在很多新手不可避免的一些“坑”,让原本简单且有意思的动手变得艰难,有的人甚至连安装配置环境就阻力重重。
为此腾讯云【燎原社】推出了一套学习门槛更低、步骤性更强、内容更为详细且更加适合国内用户学习的云原生技术工坊,旨在帮助更多对云原生技术感兴趣的开发者快速且系统的掌握Docker与Kubernetes。作为一款入门课程,对初学者非常友好,不仅免费,还配有专门的学习交流群,群内学员打卡分享,氛围超棒!
详情可戳链接: 腾讯云燎原社技术工坊
无论是容器的构建,还是 GitOps ,还是十二要素应用程序,相信只需要经过短暂十几天业余的学习,程序员就应该可以感受到云原生开发方式相比传统方式全新的畅快体验。
4、十二要素应用程序方法论
十二要素应用程序是一套原则,一种软件工程的方法论,从源代码管理、架构体系、应用形态、开发部署等方面引导团队快速适应并构建优雅、可维护、易扩展的云原生应用,后由 Kevin Hoffman 并增加了三个额外的要素,是如何构建云原生应用程序非常值得参考的意见。
关于十二要素应用程序方法论的详细表述,可以参考12factor;而关于十五要素的具体表述,可以参考[Beyond the
Twelve-Factor App](https://hackweek-1251009918.c...)
关于十二要素应用程序的核心思想,在O'reilly出品的《云原生Java》这本书里,有一个比较提炼式的解读:
- 使用声明的方式来搭建自动化环境,最大限度地减少新加入项目的开发人员的时间和成本;
- 与底层操作系统之间建立清晰的约定,在执行环境之间提供最大的可移植性;
- 适合部署在现代的云平台上,无须提供服务器和系统管理工具;
- 最大程度减少开发环境与生产环境之间的区别,通过持续部署获得最大的灵活性;
- 可以在不对工具、架构或开发实践带来重大变动的前提下,进行水平扩展。
十二要素应用程序涵盖了所有现代应用程序的常见问题,是构建云原生应用程序的一些约束意见:
因素 | 说明 |
---|---|
基准代码 | 一份使用版本控制系统管理的基准代码,多份部署 |
依赖 | 显示声明依赖关系,通过依赖清单,确切地声明所有依赖项 |
配置 | 在环境中存储配置,与代码分离,如数据库、证书、每份部署特有的配置等 |
后端服务 | 将程序运行所需要的,通过网络调用的各种服务,如数据库、消息/队列系统,缓存系统等当做附加资源 |
构建、发布、运行 | 严格分离构建、发布和运行的代码版本 |
进程 | 以一个或多个无状态进程运行应用,任何需要持久化的数据都要存储在后端服务 |
端口绑定 | 通过端口绑定提供服务,请求统一发送至公共域名而后路由至绑定了端口的网络进程 |
并发 | 通过进程模型进行扩展,将不同的工作分配给不同的 进程类型 |
易处理 | 应用的进程可以快速启动和优雅终止,这既有利于应用的弹性伸缩,也能迅速部署不断变化的代码或配置 |
开发 /生产环境一致 | 尽可能保证开发环境、预发环境和线上环境的一致性 |
日志 | 日志应该是事件流的汇总,将所有运行中进程和后端服务的输出流按照时间顺序收集起来 |
管理进程 | 把后台管理任务当作一次性进程运行 |
这里有一份计算机顶级名校 CMU 的十二要素应用程序打分表,打分越高说明越符合云原生应用程序的约束(表格内1,2,3为评分):
12要素 | 评分 |
---|---|
基准代码 | 1. 使用电子邮件发送不同名称的代码zip 2. 频繁地提交代码更新到代码控制系统(项目代码使用的同一个代码仓库) 3. 应用程序拆分成独立的部分,每个部分都是一个应用,都有自有的仓库 |
依赖 | 1. 手动下载代码依赖,比如下载 jar 到 lib 文件夹; 2. 使用软件包管理器(如mvn、npm),或 curl 来下载管理依赖 3. 使用容器镜像制品管理仓库如 Artifactory 来管理 DevOps 流水线 |
配置 | 1. 在代码中硬编码URL、密码,使用if(Mode.PROD)来管理代码分支 2. 使用配置文件,不同环境使用多种配置文件 3. 使用配置服务(Spring Cloud Config、Zookeeper) |
后端服务 | 1. 供应商特定的连接库,硬编码连接字符串 2. 连接参数存储在配置文件中 3. 动态发现资源,独立地更新后端服务 |
构建、发布和运行 | 1. 开发从本地构建和部署代码,生产环境由手动推送 2. 使用构建/发布工具(如Jenkins,TravisCI),清晰地分离构建和部署阶段 3. 有一键点击就可发布的流水线,每个发布都用版本控制并保存用于回滚,没有人工干预 |
进程 | 1. 粘滞会话,将应用程序的数据、状态写入到本地文件系统 2. 应用的进程不依赖本地存储的数据 3. 无状态,将会话数据存储在数据存储中(redis),缓存中间事务的步骤 |
端口绑定 | 1. 应用程序不提供对外的服务 2. 单机模式,但监听特定的端口来提供服务 3. Web服务器是应用程序的一部分(node,netty),应用通过HTTP提供服务 |
并发 | 1. 必须顺序运行的阻塞式任务 2. 非阻塞式IO服务器(node、netty)3. 水平扩展,小型、独立的微服务 |
易处理 | 1. 需要开发人员来协调重启服务 2. 应用能够快速启动 3. 应用程序能优雅终止,且低于1秒快速重启,存储状态能快速恢复 |
开发环境与线上环境等价 | 1. 开发人员对线上环境不了解,开发环境和线上环境不同 2. 开发时用轻量级的产品来替代线上环境里比较复杂的产品 3. 开发环境与线上环境是等价的 |
日志 | 1. 通过代码如 System.out.print() 来输出日志 2. 将日志文件写入到web服务器 3. 将日志当作流式数据来处理(ELK) |
管理进程 | 1. 数据迁移时,手动修改数据库的条目 2. 将应用的迁移脚本存储在仓库中 3. 使用框架的工具链 |
Kevin Hoffman在十二要素之上新增了如下三个要素,也就是说理想情况下,云原生应用应该具备这15个特征:
- API优先原则
微服务架构的应用使用公开API来作为服务的对外接口;在应用的设计阶段,应该首先设计 API 并确定 API 的细节。 - 遥测数据
云原生应用需要收集一系列遥测数据,包括应用性能指标、运行状态和日志等;云平台可以用性能指标来进行自动水平扩展 - 认证与授权
云原生应用应该是安全的,可以使用基于角色的访问控制(RBAC)来保护 API
腾讯云【燎原社】还推出了为期3天的线下【云原生技术实战营】,腾讯云技术专家团队会面对面倾囊相授一线云原生实战经验,手把手教你业务容器化改造的“最佳实践”,参与者不仅可以和社区各领域程序员一起进步,还能与腾讯资深架构师、产品持续交流。
详情可戳链接:腾讯云燎原社云原生技术实战营
5、书籍推荐
一般来说,程序员更聚焦于云原生应用的开发以及相应的软件工程方法,下列推荐书籍也主要聚焦于微服务、Docker、Kubernetes的基础,以及如何基于Java生态构建云原生应用:
- 《微服务:灵活的软件架构》
- 《Docker实战(第2版)》(Docker in Action),清华大学出版社
- 《深入剖析Kubernetes》(其实这是一本入门的书籍)
- 《云原生Java》