技术

并发的成本 基础设施优化 hashicorp raft源码学习 docker 架构 mosn细节 与微服务框架整合 Java动态代理 编程范式 并发通信模型 《网络是怎样连接的》笔记 go细节 codereview mat使用 jvm 线程实现 go打包机制 go interface及反射 如何学习Kubernetes 《编译原理之美》笔记——后端部分 《编译原理之美》笔记——前端部分 Pilot MCP协议分析 go gc 内存管理玩法汇总 软件机制 istio流量管理 Pilot源码分析 golang io 学习Spring mosn源码浅析 MOSN简介 《datacenter as a computer》笔记 学习JVM Tomcat源码分析 Linux可观测性 MVCC 学习存储 学计算 Gotty源码分析 kubernetes operator kaggle泰坦尼克问题实践 kubernetes自动扩容缩容 神经网络模型优化 直觉上理解机器学习 knative入门 如何学习机器学习 神经网络系列笔记 TIDB源码分析 《阿里巴巴云原生实践15讲》笔记 Alibaba Java诊断工具Arthas TIDB存储——TIKV 《Apache Kafka源码分析》——简介 netty中的线程池 guava cache 源码分析 Springboot 启动过程分析 Spring 创建Bean的年代变迁 Linux内存管理 自定义CNI IPAM 扩展Kubernetes 副本一致性 spring redis 源码分析 kafka实践 spring kafka 源码分析 Linux进程调度 让kafka支持优先级队列 Codis源码分析 Redis源码分析 C语言学习 《趣谈Linux操作系统》笔记 docker和k8s安全机制 jvm crash分析 Prometheus 学习 Kubernetes监控 Kubernetes 控制器模型 容器日志采集 容器狂占cpu怎么办? 容器狂打日志怎么办? Kubernetes资源调度——scheduler 时序性数据库介绍及对比 influxdb入门 maven的基本概念 《Apache Kafka源码分析》——server Kubernetes objects之编排对象 源码分析体会 自动化mock AIOps说的啥 《数据结构与算法之美》——算法新解 Kubernetes源码分析——controller mananger Kubernetes源码分析——apiserver Kubernetes源码分析——kubelet Kubernetes介绍 ansible学习 Kubernetes源码分析——从kubectl开始 jib源码分析之Step实现 kubernetes实践 jib源码分析之细节 线程排队 跨主机容器通信 jib源码分析及应用 为容器选择一个合适的entrypoint kubernetes yaml配置 marathon-client 源码分析 《持续交付36讲》笔记 mybatis学习 程序猿应该知道的 无锁数据结构和算法 CNI 为什么很多业务程序猿觉得数据结构和算法没用? 串一串一致性协议 当我在说PaaS时,我在说什么 《数据结构与算法之美》——数据结构笔记 swagger PouchContainer技术分享体会 harbor学习 用groovy 来动态化你的代码 《深入剖析kubernetes》笔记 精简代码的利器——lombok 学习 编程语言的动态性 rxjava3——背压 rxjava2——线程切换 spring cloud 初识 《深入拆解java 虚拟机》笔记 《how tomcat works》笔记 hystrix 学习 rxjava1——概念 Redis 学习 TIDB 学习 分布式计算系统的那些套路 Storm 学习 AQS1——论文学习 Unsafe Spark Stream 学习 linux vfs轮廓 mysql 批量操作优化 《自己动手写docker》笔记 java8 实践 中本聪比特币白皮书 细读 区块链泛谈 比特币 大杂烩 总纲——如何学习分布式系统 hbase 泛谈 forkjoin 泛谈 看不见摸不着的cdn是啥 《jdk8 in action》笔记 程序猿视角看网络 bgp初识 mesos 的一些tips mesos 集成 calico calico学习 AQS2——粗略的代码分析 我们能用反射做什么 web 跨域问题 《clean code》笔记 硬件对软件设计的影响 《Elasticsearch权威指南》笔记 mockito简介及源码分析 2017软件开发小结—— 从做功能到做系统 《Apache Kafka源码分析》——clients dns隐藏的一个坑 《mysql技术内幕》笔记2 《mysql技术内幕》笔记1 log4j学习 为什么netty比较难懂? 回溯法 apollo client源码分析及看待面向对象设计 学习并发 从一个marathon的问题开始的 docker 环境(主要运行java项目)常见问题 Scala的一些梗 OpenTSDB 入门 spring事务小结 事务一致性 javascript应用在哪里 《netty in action》读书笔记 netty对http2协议的解析 ssl证书是什么东西 http那些事 苹果APNs推送框架pushy apple 推送那些事儿 编写java框架的几大利器 java内存模型 java exception Linux IO学习 network channel network byte buffer 测试环境docker化实践 netty(七)netty在框架中的使用套路 Nginx简单使用 《Linux内核设计的艺术》小结 Go并发机制及语言层工具 mesos深入 Macvlan Linux网络源代码学习——数据包的发送与接收 《docker源码分析》小结 docker中涉及到的一些linux知识 hystrix学习 Linux网络源代码学习——整体介绍 zookeeper三重奏 数据库的一些知识 Spark 泛谈 链式处理的那些套路 netty(六)netty回顾 Thrift基本原理与实践(二) Thrift基本原理与实践(一) 回调 异步执行抽象——Executor与Future Docker0.1.0源码分析 java gc Jedis源码分析 Redis概述 机器学习泛谈 Linux网络命令操作 JTA与TCC 换个角度看待设计模式 Scala初识 向Hadoop学习NIO的使用 以新的角度看数据结构 并发控制相关的硬件与内核支持 systemd 简介 那些有用的sql语句 异构数据库表在线同步 quartz 源码分析 基于docker搭建测试环境(二) spring aop 实现原理简述 自己动手写spring(八) 支持AOP 自己动手写spring(七) 类结构设计调整 分析log日志 自己动手写spring(六) 支持FactoryBean 自己动手写spring(九) 总结 自己动手写spring(五) bean的生命周期管理 自己动手写spring(四) 整合xml与注解方式 自己动手写spring(三) 支持注解方式 自己动手写spring(二) 创建一个bean工厂 自己动手写spring(一) 使用digester varnish 简单使用 关于docker image的那点事儿 基于docker搭建测试环境 分布式配置系统 JVM内存与执行 git spring rmi和thrift maven/ant/gradle使用 再看tcp mesos简介 缓存系统 java nio的多线程扩展 《Concurrency Models》笔记 回头看Spring IOC IntelliJ IDEA使用 Java泛型 vagrant 使用 Go常用的一些库 Python初学 Goroutine 调度模型 虚拟网络 《程序员的自我修养》小结 VPN(Virtual Private Network) Kubernetes存储 Kubernetes 其它特性 访问Kubernetes上的Service Kubernetes副本管理 Kubernetes pod 组件 使用etcd + confd + nginx做动态负载均衡 如何通过fleet unit files 来构建灵活的服务 CoreOS 安装 CoreOS 使用 Go学习 JVM类加载 硬币和扑克牌问题 LRU实现 virtualbox 使用 ThreadLocal小结 docker快速入门

标签


《阿里巴巴云原生实践15讲》笔记

2019年08月04日

简介

王坚:计算像是一口井,井里有着最珍贵的水资源。随着大家对计算需求的增大,要有人想办法把井水变为自来水,让它顺畅地流入寻常百姓家。这个过程看似简单,实际上需要建水厂、铺管道、做水龙头、装水表等一系列环节的精密配合。更重要的是人们对新理念的接纳,因为第一口自来水从水龙头里流出之前,没有人相信。

解读容器 2019:把“以应用为中心”进行到底云原生的本质是一系列最佳实践的结合;更详细的说,云原生为实践者指定了一条低心智负担的、能够以可扩展、可复制的方式最大化地利用云的能力、发挥云的价值的最佳路径。这种思想,以一言以蔽之,就是“以应用为中心”。正是因为以应用为中心,云原生技术体系才会无限强调让基础设施能更好的配合应用、以更高效方式为应用“输送”基础设施能力,而不是反其道而行之。而相应的, Kubernetes 、Docker、Operator 等在云原生生态中起到了关键作用的开源项目,就是让这种思想落地的技术手段。

解读容器 2019:把“以应用为中心”进行到底这篇文章读多少遍都不多

云原生的“上下文”是什么?阿里2015年前全部使用内部基础设施 ==> 2015-2018 活动期间 向阿里云申请“机房”(一批服务器)双十一后归还(机器资源成本下降50%); 部分业务上云 ==> 全面上云 ==> 云原生

全面上云

在Cloud Native 时代之前,多数公司随着业务的发展,或多或少都会打造出自有、封闭的技术体系,如果是自建机房/采购物理机称为Hosting,如果是采购云厂商的资源自己搭,称之为Cloud Hosting。这一方面造成巨大的投入,使得公司的技术人才力量没有完全专注的投入到业务上,另一方面也造成了这个行业人才流动的困难。尽管很多的开源产品在一定程度上有助于解决这个问题,但还不足以体系化

对于云厂商而言,会提供越来越多开放、主流的技术栈的技术产品, 从而让客户有更为丰富和自主的选择权,也会做到让这些技术产品的互通性更好。PS:感觉是不满足于 开源产品的零敲碎打,是整个开发体系的“输出”。当然,云化的产品肯定架设在“弹性”的基础设施之上,弹性从“物理层”领域发展到“服务层”。租2台机器搭建redis 不如直接给你一个自由扩展的redis。

上云架构未来演进:云原生

基础设施和业务的边界应该在哪里?真正的判断标准是业务关注的边界而非架构边界,基础设施应无须业务持续关注和维护。例如,使用了容器服务,是否能让业务无须关注底层资源?也未必,取决于资源的弹性能力是否有充分的支持(否则业务仍需时刻关注流量和资源压力),也取决于可观测性(否则问题的排查仍需关注底层环境)的能力。

  1. 节点托管的 K8s 服务
  2. Service Mesh 化
  3. 应用和基础设施全面解耦
  4. 应用交付的标准化:OAM

解耦前

解耦后

通过上云,最大化的使阿里巴巴的业务使用云的技术,通过技术架构的演进使业务更好的聚焦于自身的发展而无须关于通用底层技术,使业务研发效率提升,迭代速度更快是技术人的真正目标。PS:笔者的感受就是,有一阵鼓吹DevOps,代码上线之前评估流量、压测、上下游服务是否受得了等。从另一个视角看,我负责开发一个服务,那么除了我这个服务,其它所有的一切计算、存储、上下游服务对我来说都是基础设施,都可以假定是可用的。

云原生如何落地

蚂蚁金服 Service Mesh 深度实践

当我们回顾云计算的发展历程,会看到基础架构经历了从物理机到虚拟机,从虚 拟机再到容器的演进过程。在这大势之下,应用架构也在同步演进,从单体过渡到多层,再到当下的微服务。在变化的背后,有一股持续的动力,它来自于三个不变的追求:

  1. 提高资源利用率
  2. 优化开发运维体验
  3. 以及更好地支持业务发展。

对话阿里云叔同:释放云价值,让容器成为“普适”技术云原生正在通过方法论、工具集和理念重塑整个软件技术栈和生命周期

  1. 过去我们常以虚拟化作为云平台和与客户交互的界面,为企业带来灵活性的同时也带来一定的管理复杂度;
  2. 容器的出现,在虚拟化的基础上向上封装了一层,逐步成为云平台和与客户交互的新界面之一,应用的构建、分发和交付得以在这个层面上实现标准化,大幅降低了企业 IT 实施和运维成本,提升了业务创新的效率。从技术发展的维度看,开源让云计算变得越来越标准化,容器已经成为应用分发和交付的标准,可以将应用与底层运行环境解耦;3. Kubernetes成为资源调度和编排的标准,屏蔽了底层架构的差异性,帮助应用平滑运行在不同的基础设施上;
  3. 在此基础上建立的上层应用抽象如微服务和服务网格,逐步形成应用架构现代化演进的标准,开发者只需要关注自身的业务逻辑,无需关注底层实现

把阿里巴巴的核心系统搬到云上,架构上的挑战与演进是什么?全面上云也不只是将机器搬到云上,更重要的是 replatforming,集团的技术栈和云产品融合,应用通过神龙服务器 + 容器和 K8s 上云,数据库接入 PolarDB,中间件采用云中间件和消息产品,负载均衡采用云 SLB 产品等。

  1. 自研神龙服务器
  2. 存储方面,走向了全面云化存储,也即全面存储计算分离。盘古

Kubernetes的价值

docker 让镜像和容器融合在一起,docker run 扣动扳机,实现镜像到 容器的转变。但docker run 仍然有太多要表述的,比如docker run的各种参数: 资源、网络、存储等,“一个容器一个服务”本身也不够反应应用的复杂性(或者 说还需要额外的信息 描述容器之间的关系,比如--link)。

我们学习linux的时候,知道linux 提供了一种抽象:一切皆文件。没有人会质疑基本单元为何是文件不是磁盘块?linux 还提供了一种抽象叫“进程”,没有人会好奇为何 linux 不让你直接操纵cpu 和 内存。一个复杂的系统,最终会在某个层面收敛起来,就好像一个web系统,搞到最后就是一系列object 的crud。类似的,如果我们要实现一个“集群操作系统”,容器的粒度未免太小。也就是说,镜像和容器之间仍然有鸿沟要去填平?kubernetes 叫pod,marathon叫Application,中文名统一叫“应用”。在这里,应用是一组容器的有机组 合,同时也包括了应用运行所需的网络、存储的需求的描述。而像这样一个“描述” 应用的 YAML 文件,放在 etcd 里存起来,然后通过控制器模型驱动整个基础设施的 状态不断地向用户声明的状态逼近,就是 Kubernetes 的核心工作原理了。“有了 Pod 和容 器设计模式,我们的应用基础设施才能够与应用(而不是容器)进行交互和响应的能力,实现了“云”与“应用”的直接对接。而有了声明式 API,我们的应用基础而设施才能真正同下层资源、调度、编排、网络、存储等云的细节与逻辑解耦”。PS:笔者最近在团队管理上也有一些困惑, 其实,你直接告诉小伙伴怎么做并不是一个很好的方式,他们不自由,你也很心累。比较好的方式是做好目标管理,由他们自己不断去填平目标与现实的鸿沟。

阿里巴巴落地 Kubernetes 可以分为三个阶段:

  1. 首先通过 Kubernetes 提供资源 供给,但是不过多干扰运维流程,这系统容器是富容器,将镜像标准化与轻量级虚拟 化能力带给了上面的 PaaS 平台。
  2. 通过 Kubernetes controller 的形式改造PaaS 平台的运维流程,给 PaaS 带来更强的面向终态的自动化能力。
  3. 把运行 环境等传统重模式改成原生容器与 pod 的轻量模式,同时将 PaaS 能力完全移交给 Kubernetes controller,从而形成一个完全云原生的架构体系。

演进中的挑战

  1. Kubernetes 本身的管理,节点发布回滚策略,按规则要求灰度发布;将环境进行镜像切分,分为模拟环境和生产环境;并且在监控侧下足功夫,将 Kubernetes 变得更白盒化和透明化,及早发现问题、预防问题、解决问题。
  2. Kubernetes 的多租户管理

  3. 在web级集群中动态调整Pod资源限制 https://github.com/openkruise
  4. 大规模k8s集群下的巡检 k8s集群运维通过巡检走向AIOPS

Service Mesh

“下沉”的应用基础设施能力与 Service Mesh在过去,我们编写一个应用所需要的基础设施能力,比如,数据库、分布式锁、服务注册 / 发现、消息服务等等,往往是通过引入一个中间件库来解决的。过更确切的说,中间件体系的出现,并不单单是要让“专业的人做专业的事”,而更多是因为在过去,基础设施的能力既不强大、也不标准

不过,基础设施本身的演进过程,实际上也伴随着云计算和开源社区的迅速崛起。时至今日,以云为中心、以开源社区为依托的现代基础设施体系,已经彻底的打破了原先企业级基础设施能力良莠不齐、或者只能由全世界几家巨头提供的情况。

这个变化,正是云原生技术改变传统应用中间件格局的开始。更确切的说,原先通过应用中间件提供和封装的各种基础设施能力,现在全都被 Kubernetes 项目从应用层“拽”到了基础设施层也就是 Kubernetes 本身当中。而值得注意的是,Kubernetes 本身其实也不是这些能力的直接提供者, Kubernetes 项目扮演的角色,是通过声明式 API 和控制器模式把更底层的基础设施能力对用户“暴露”出去。这些能力,或者来自于“云”(比如 PolarDB 数据库服务);或者来自于生态开源项目(比如 Prometheus 和 CoreDNS)。

这也是为什么 CNCF 能够基于 Kubernetes 这样一个种子迅速构建起来一个数百个开源项目组成的庞大生态的根本原因:Kubernetes 从来就不是一个简单的平台或者资源管理项目,它是一个分量十足的“接入层”,是云原生时代真正意义上的“操作系统”。PS:操作系统帮你简化访问内存、cpu、文件、外设的问题,k8s帮你简化 访问所有外界服务的问题。

可是,为什么只有 Kubernetes 能做到这一点呢?这是因为, Kubernetes 是第一个真正尝试以“应用为中心“的基础设施开源项目。以应用为中心,使得 Kubernetes 从第一天开始,就把声明式 API 、而不是调度和资源管理作为自己的立身之本。声明式 API 最大的价值在于“把简单留给用户,把复杂留给自己”。通过声明式 API,Kubernetes 的使用者永远都只需要关心和声明应用的终态,而不是底层基础设施比如云盘或者 Nginx 的配置方法和实现细节。

应用基础设施能力“下沉”,实际上伴随着整个云原生技术体系和 Kubernetes 项目的发展始终。比如, Kubernetes 最早提供的应用副本管理、服务发现和分布式协同能力,其实就是把构建分布式应用最迫切的几个需求,通过 Replication Controller,kube-proxy 体系和 etcd “下沉”到了基础设施当中。而 Service Mesh ,其实就更进一步,把传统中间件里至关重要的“服务与服务间流量治理”部分也“下沉”了下来。当然,这也就意味着 Service Mesh 实际上并不一定依赖于 Sidecar :只要能无感知的拦截下来服务与服务之间的流量即可(比如 API Gateway 和 lookaside 模式)

随着底层基础设施能力的日趋完善和强大,越来越多的能力都会被以各种各样的方式“下沉”下来。而在这个过程中,CRD + Operator 的出现,更是起到了关键的推进作用。 CRD + Operator,实际上把 Kubernetes 声明式 API 驱动对外暴露了出来,从而使得任何一个基础设施“能力”的开发者,都可以轻松的把这个“能力”植入到 Kubernetes 当中。

“声明式基础设施”的基础,就是让越来越多的“复杂”下沉到基础设施里,无论是插件化、接口化的 Kubernetes “民主化”的努力,还是容器设计模式,或者 Mesh 体系,这些所有让人兴奋的技术演进,最终的结果都是让 Kubernetes 本身变得越来越复杂。而声明式 API 的好处就在于,它能够在基础设施本身的复杂度以指数级攀升的同时,至少保证使用者的交互界面复杂度仍然以线性程度上升。否则的话,如今的 Kubernetes 恐怕早就已经重蹈了 OpenStack 的灾难而被人抛弃。

  linux kubernetes
描述 单机操作系统 不只是集群操作系统管理一堆物理机
在应用和外界定义了一条线
作用 简化对硬件cpu、内存、外设的访问 简化对所有外部资源的访问
访问接口 系统调用 api
扩展方式 驱动 CRD/Operator

“复杂”,是任何一个基础设施项目天生的特质而不是缺点。今天的 Linux Kernel 一定比 1991 年的第一版复杂不止几个数量级;今天的 Linux Kernel 开发人员也一定没办法像十年前那样对每一个 Module 都了如指掌。这是基础设施项目演进的必然结果。但是,基础设施本身的复杂度,并不意味着基础设施的所有使用者都应该承担所有这些复杂度本身。这就好比我们每一个人其实都在“使用” Linux Kernel,但我们并不会抱怨“Linux Kernel 实在是太复杂了”:很多时候,我们甚至并不知道 Linux Kernel 的存在。

前的 Kubernetes 体系覆盖的三类技术群体:

  1. 基础设施工程师,在公司里,他们往往称作“Kubernetes 团队”或者“容器团队”。他们负责部署、维护 Kubernetes 及容器项目、进行二次开发、研发新的功能和插件以暴露更多的基础设施能力。声明式 API 设计、CRD Operator 体系,就是为了方便基础设施工程师接入和构建新基础设施能力而设计的。
  2. 运维工程师
  3. 业务研发工程师

很多公司和组织落地 Kubernetes 的时候实际上采用了“ PaaS 化”的思路,即:在 Kubernetes 之上再构建一个 PaaS 系统,通过 PaaS API(或者 UI)把 Kubernetes 跟业务运维和业务研发隔离开来。但这种做法从本质上来说,其实跟 Kubernetes “以应用为中心”的设计是不一致的。在现代云原生技术体系当中,“运维能力”可以直接通过声明式 API 和控制器模型成为 Kubernetes 基础设施的一部分。所以在大多数情况下,其实并不需要一个运维 PaaS 的存在。

在下一代“以应用为中心”的基础设施当中,业务研发通过声明式 API 定义的不再是具体的运维配置(比如:副本数是 10 个),而是“我的应用期望的最大延时是 X ms”。接下来的事情,就全部会交给 Kubernetes 这样的应用基础设施来保证实际状态与期望状态的一致,这其中,副本数的设置只是后续所有自动化操作中的一个环节。只有让 Kubernetes 允许研发通过他自己的视角来定义应用,而不是定义 Kubernetes API 对象,才能从根本上的解决 Kubernetes 的使用者“错位”带来的各种问题。

在底层基础设施层逐渐 Serverless 化(PS:通过api操控),在 2019 年 4 月,Google Cloud 发布了 Cloud Run 服务,第一次把 Serverless Application 的概念呈现给大众。2019 年 9 月,CNCF 宣布成立应用交付领域小组,宣布将“应用交付”作为云原生生态的第一等公民。 2019 年 10 月,Microsoft 发布了基于 Sidecar 的应用中间件项目 Dapr ,把“面向 localhost 编程”变成了现实。而在 2019 年 10 月,阿里巴巴则联合 Microsoft 共同发布了 Open Application Mode(OAM)项目,第一次对“以应用为中心”的基础设施和构建规范进行了完整的阐述。在这场革命的终态,任何一个符合“以应用为中心“规范的软件,将能够从研发而不是基础设施的视角自描述出自己的所有属性,以及自己运行所需要所有的运维能力和外部依赖。这样的应用才能做到天生就是 Serverless Application

从 Serverless Infrastructure 到 Serverless Application,我们已经看到云原生技术栈正在迅速朝“应用”为中心聚拢和收敛。我们相信在不久的未来,一个应用要在世界上任何一个地方运行起来,唯一要做的,就是声明“我是什么”,“我要什么”。在这个时候,所有的基础设施概念包括 Kubernetes、Istio、Knative 都会“消失不见”:就跟 Linux Kernel 一样。

Serverless

相 比容器技术,Serverless 可以将资源管理的粒度更加细化,使开发者更快上手云原 生,并且倡导事件驱动模型支持业务发展。从而帮助用户解决了资源管理复杂、低频业务资源占用等问题;实现面向资源使用,以取代面向资源分配的模式。

Serverless 的喧哗与骚动(一):Serverless 行业发展简史

向阿里学习什么?

  1. 一切问题 都可以变着法儿用技术问题去解决。
  2. 就一个故障恢复,想不透的只能空口抱怨,若是想透了, 拉一个部门这个活儿都干不完。