首页 文章 精选 留言 我的

精选列表

搜索[k8s],共3940篇文章
优秀的个人博客,低调大师

云原生五大趋势预测,K8s 安卓化位列其一

作者 |李响、张磊 Kubernetes 本身并不直接产生商业价值,你不会花钱去购买 Kubernetes 。这就跟安卓一样,你不会直接掏钱去买一个安卓系统。Kubernetes 真正产生价值的地方也在于它的上层应用生态。 “未来的软件一定是生长于云上的”,这是云原生理念的最核心假设。而所谓“云原生”,实际上就是在定义一条能够让应用最大程度利用云的能力、发挥云的价值的最佳路径。因此,云原生其实是一套指导软件架构设计的思想。按照这样的思想而设计出来的软件:首先,天然就“生在云上,长在云上”;其次,能够最大化地发挥云的能力,使得我们开发的软件和“云”能够天然地集成在一起,发挥出“云”的最大价值。 云原生的概念大家并不陌生,很多企业也已经基于云原生的架构和技术理念落地相关实践。那么,这么多企业和开发者热衷和推崇的云原生,未来的发展趋势如何?如何才能顺应云原生的主流方向去发展? 我们邀请到阿里云资深技术专家、CNCF 技术监督委员会代表,etcd 作者李响和阿里云高级技术专家、CNCF 应用交付领域 co-chair 张磊分享云原生的理念、发展以及未来趋势,为大家打开新的思路和眼界。 以下内容共享给大家。 Kubernetes 项目的安卓化 云原生里有一个非常关键的项目,就是 Kubernetes。Kubernetes 的发展非常迅速,它是整个云原生体系发展的基石。今天我们来观察 Kubernetes 项目的发展特点,首先,Kubernetes 无处不在,无论是在云上,还是用户自建的数据中心里,甚至一些我们想象不到的场景里,都有 Kubernetes 的存在。 第二,所有云原生的用户使用 Kubernetes 的目的,都是为了交付和管理应用。当然这个应用是一个泛化的概念,可以是一个网站,也可以是淘宝这样非常庞大的电商主站,或者是 AI 作业、计算任务、函数、甚至虚拟机等,这些都是用户可以使用 Kubernetes 去交付和管理的应用类型。 第三,今天我们来看 Kubernetes 所处的位置,实际上是承上启下。Kubernetes 对上暴露基础设施能力的格式化数据抽象,比如 Service、Ingress、Pod、Deployment,这些都是 Kubernetes 本身原生 API 给用户暴露出来的能力。而对下,Kubernetes 提供的是基础设施能力接入的标准接口,比如说 CNI、CSI、DevicePlugin、CRD,让云能够作为一个能力提供商,以一个标准化的方式把能力接入到 Kubernetes 的体系中。 这一点其实跟安卓非常类似,安卓虽然装在你的设备里,但是它能够让你的硬件、手机、电视、汽车等都能接入到一个平台里。对上则暴露统一的一套应用管理接口,让你能够基于安卓系统来编写应用,去访问或者享受到这些基础设施能力,这也是 Kubernetes 和安卓的相似之处。 最后, Kubernetes 本身并不直接产生商业价值,你不会花钱去购买 Kubernetes。这就跟安卓一样,你不会直接掏钱去买一个安卓系统。Kubernetes 真正产生价值的地方也在于它的上层应用生态。对安卓来说,它今天已经具备了一个庞大的移动端或设备端应用的开发生态,而对于 Kubernetes 来说也是类似的,只不过现在还在于比较早的阶段。但我们已经能够看到,今天在 Kubernetes 上构建的商业层很多是垂直解决方案,是面向用户、面向应用这一侧真正能够产生商业价值的东西,而不是 Kubernetes 本身这一层。这就是为什么我说 Kubernetes 发展跟安卓很像,当然这可能也是谷歌比较擅长的一个“打法”:全力地去免费推广一个“操作系统”,真正获取商业价值的方式则是是去“收割”操作系统上层的生态价值而不是操作系统本身。 基于这些现象,我们将 Kubernetes 的发展趋势概括为以下几点: 1. 云的价值回归到应用本身 用户使用 Kubernetes 的本质目的是去交付和管理应用。从这个现象来看,如果 Kubernetes 发展下去,那么世界上所有的数据中心和基础设施上面都会有一层 Kubernetes ,自然而然用户就会开始以 Kubernetes 为基础去编写和交付以及管理其应用,就跟现在我们会以安卓这样一个操作系统为基础去编写移动应用是类似的。 这就会导致云上的大多数软件和云产品都是第三方开发的。第三方开发是指所有人都可以面向一个标准界面去开发和交付软件,这个软件本身既可以是自己的软件,也可以是一个云产品。未来,越来越多的第三方开源项目,如 MongoDB、Elasticsearch 等,都会以云原生理念去开发、部署和运维,最后直接演进成为一种云服务。 2. 云端“豌豆荚”的出现 有了 Kubernetes 这样一个标准,开发者面对的就是一个类似于操作系统的界面。由于有更多的应用是面向 Kubernetes 诞生的,或者说面向 Kubernetes 去交付的,那么就需要有一个类似于“豌豆荚”的产品,来作为云上的应用商店或者云上的应用分发系统,它的关键能力在于把应用无差别地交付给全世界任何一个 Kubernetes 上面,就跟用豌豆荚把任何一个安卓应用交付在任何一个安卓设备上的原理是一样的。 其实今天谷歌已经在做这类产品的尝试了,比如 Anthos (面向混合云的应用交付平台),虽然是一款混合云产品,但它本质上是把谷歌云的服务,比如数据库服务、大数据服务,去直接交付于任何一个基于 Kubernetes 的混合云环境里面去,其实就相当于一款云端的“豌豆荚”。 3. 基于 Kubernetes 可扩展能力的开放应用平台会取代 PaaS 成为主流 由于未来整个应用生态会面向 Kubernetes 去构建,那么基于 Kubernetes 可扩展能力的开放应用平台会逐渐取代传统 PaaS 而成为主流。基于 Kubernetes 可扩展能力去构建一个开放的应用平台,其能力是可插拔的,能够去交付和管理的应用类型是多样化的,这才更符合 Kubernetes 所构建的趋势和生态,所以一些真正高可扩展的平台层项目会大量产生。 另外,今天我们看到的 Kubernetes ,跟“理想”中的云原生应用生态之间其实还有很多路要走,这也是阿里云原生团队一直在做的事情,基于 Kubernetes 在应用层构建更丰富的应用生态,帮助用户实现多样化的需求。 应用与能力的“ Operator 化” 纵观云原生时代应用或者云的能力的发展方向,你会发现另一个趋势,就是 Operator 化。Operator 是 Kubernetes 的一个概念,是指 Kubernetes 交付的一个实体,这个实体有一个基础模型存在,这个模型分为两部分:一部分是 Kubernetes 的 API 对象(CRD),另一部分是一个控制器(Controller),如下图所示: 这里要区分两个概念,自定义和自动化。很多人会说 Operator 可以帮助我做自定义,因为很多人都会觉得 Kubernetes 内置的能力是不够用的,所以用户会利用它的可扩展能力去写一个 Controller ,从而实现跟多自定义的需求。但自定义只是 Operator 中很小的一部分价值,我们今天对应用和能力做 Operator 化的核心动力在于其实是为了实现自动化,而且只有自动化了,我们才能讲云原生。 这是因为,云原生带来的最大的红利是可以让我们最大限度、最高效地使用云的能力,二这种最高效、最大化的方式一定没办法通过人工来实现的。换句话说,只有通过自动化的方式去开发、运维应用以及与云进行交互,才能真正把云原生的价值发挥出来。 而如果要通过自动化的方式跟云进行交互,那么在云原生生态里,必须有一个类似于Controller 或者 Operator 这样的插件的存在。今天阿里巴巴在云上交付的 PolarDB、OceanBase 等,其实都有一个跟 Kubernetes 衔接的 Controller 的存在。通过 Controller 与基础设施、云进行交互,把云的能力输入到产品里面去。 在未来,会有大量的云上的应用和对应的运维能力、管理能力都会以 Kubernetes Operator 的方式交付。在这个背景下, Kubernetes 真正扮演的一个角色就是能力的接入层和标准界面。如下图所示,这是一个非常典型的用户侧 Kubernetes 集群的样子。 一个用户的 Kubernetes 只有红框里面这部分是 Kubernetes 原生提供的 API ,而大量的能力都是以插件化或者说 Operator 化的方式存在。就比如上图右边所有这些自定义的资源和能力全部来自于第三方开发,通过 Operator 这样一个标准的形态开发出来的能力来服务最终用户的。这就意味着在未来云原生的生态里面,基于 CRD Operator 的而非 Kubernetes 原生 API 的应用和能力会占到绝大多数。 随着这个趋势的不断演进,越来越多的软件和能力通过 Kubernetes Operator 去描述和定义,云产品也会开始默认以 Kubernetes 为底座,基于 Operator 进行交付。 正是因为越来越多的 Operator 的出现,这里就会逐步需要一个中心化的方式去解决 Operator 潜在的稳定性、可发现性和性能问题,也就是说在未来很可能会有一个横向的 Operator 管理平台出现,对所有基于 Kubernetes Operator 开发的应用和能力进行统一管理,从而更好、更专业地服务用户。 此外,由于未来每一个能力、每一个应用都需要去编写 Operator ,所以说对开发者友好的 Operator 编写框架也是未来一个很重要的趋势。这个编写框架可以支持不同语言,如 Go、Java、C、Rust 语言等,并且编写过程是专注于运维逻辑和应用的管理、能力的管理,而不是专注在 Kubernetes 的语义和细节上面。 最后,随着云原生生态的普及,云服务也将实现 Operator 化,并且面向多集群/混合云场景出现面向应用层的云服务标准化定义与抽象,并在云原生领域逐渐取代 IaC 项目(比如 Terraform 等)成为云服管理与消费的主流方式。 应用中间件能力进一步下沉 随着云原生以及整个生态的发展,我们看到应用中间件领域也随之发生了很多改变。从原先最开始的中心化 ESB ,到后来的胖客户端,逐步演化到今天我们经常提到的 Service Mesh 这样一种 Sidecar 化的方式。 其实今天你会发现,无论是云的能力还是基础设施的能力,都在不断丰富,很多原先只能通过中间件做的事情,现在可以很容易通过云服务来实现。应用中间件不再是能力的提供方,而是能力接入的标准界面,并且这个标准界面的构建不再基于胖客户端,而是通过非常普通的 HTTP 协议、 gRPC 协议去做,然后通过 Sidecar 方式把整个服务的接入层跟应用业务逻辑做一个解耦,这其实就是 Service Mesh 的思想。 目前 Service Mesh 只做了传统中间件里面的流量治理、路由策略、访问控制这一层的事情。而实际上, Sidecar 这个模型可以应用到所有中间件的场景里,实现中间件逻辑跟应用业务逻辑完全解耦,让应用中间件能力“下沉”,变成 Kubernetes 能力的一部分。这样应用本身会更加专一化,更多的关注业务逻辑本身。 伴随着这个趋势,在 Kubernetes 这一层还会有另外一个趋势出现,就是 Sidecar 的自动化的、规模化的运维能力会成为一个必选项。因为 Sidecar 的数量会极其庞大,应用中间件很可能会演化成 Sidecar 集群,那么这些 Sidecar 的管理和规模化的运维能力,会是集群或者云产品的一个必备选项。 下一代 DevOps 模型与体系 随着云原生生态的不断发展,云原生理念的不断普及, DevOps 的思想很可能也会发生一个本质的变化,即下一代 DevOps 模型与体系。随着 Kubernetes 的能力越来越多、越来越强大,基础设施也会变得越来越复杂,那么基于这样一个强大的基础设施去构建一个应用平台就会非常简单,并且这个应用平台最终会取代传统的PaaS平台。 我们现在之所以在用 DevOps 这一套思想,实际上是由于基础设施本身不够强大,不够标准化,不够好用,所以我们需要在业务研发侧做一套工具去黏合研发人员和基础设施。例如,基础设施提供的能力是一个虚拟机,怎么能让虚拟机变成研发侧想要的蓝绿发布或者一个渐进式的应用交付系统呢?这就需要一系列的 DevOps 的工具、 CI/CD 的流水线来完成。 但是现在的情况已经发生了变化。基于 Kubernetes 的基础设施本身的能力已经非常丰富,像蓝绿发布这些能力本身就是 Kubernetes 可以提供的能力。在这样的背景下, DevOps 的发展趋势也会发生很大的改变: 1. 关注点分离 在 Kubernetes 的背景下,“软件”不再是一个由应用 Owner 掌控的单一交付物,而是多个 Kubernetes 对象的集合,而这一堆 Kubernetes 里面的对象只有很少一部分其实才跟研发有关,所以说有很多对象会不在应用 Owner 的认知范围内,这就导致平台必须去做关注点分离,研发侧的关注点和运维侧、系统侧的关注点是完全不一样的东西。也就是研发不用再考虑运维方面的细节,比如蓝绿发布怎么做,水平扩容什么策略,只要把业务代码写完交付就好。 伴随着 Kubernetes 和基础设施越来越复杂,概念越来越多,作为平台层是不大可能让研发了解所有的概念,因此未来云原生生态一定会做抽象和分层。每一层的角色只跟属于自己的数据抽象去交互,研发侧有一套自己的声明式 API 对象,运维侧有一套自己的声明式 API 对象,每一层的关注点也是不一样的,这会是未来整个 DevOps 体系里发展的一个重要的背景。 2. Serverless 泛化 云原生本身的关注点就是应用,在这样一个背景下,Serverless 本身不再是一个独立场景,不再局限在某几个非常垂直的领域,而会变成云原生应用管理体系的一种泛化思想和天然组成部分。我从两个层面解释一下:一是在能力侧,“轻运维”“ NoOps ”以及“自助式运维能力”会成为应用运维的主流方式。云原生生态上的应用管理会体现出一种轻运维的状态,就是说应用运维不再是一个人工的、非常复杂的过程,而是一组开箱即用的、非常简单的模块化操作。无论是通过 Kubernetes 还是通过云原生能力,都是对下层基础设施的一个模块化的分装,这跟 Serverless 所提倡的 NoOps 理念非常类似。 二是在应用侧,应用描述会广泛地进行用户侧的抽象,事件驱动和 Serverless 理念被拆分和泛化,可以被应用于多样化的场景中而不仅仅是今天狭义的 Serverless 场景比如 FaaS 或者 Container Instance,未来所有的应用都可以实现 scale-to-zero 。 3. 基于 Infrastructure as Data(IaD)思想的应用层技术渐成主流 第一,基于 Infrastructure as Data(IaD)的思想会成为一个主流技术,IaD 实际就是 Kubernetes 的声明式 API ,声明式 API 的核心在于把基础设施、应用、能力以一个声明式的文件、声明式的对象去描述,那么这个文件或者对象本身就是“数据”。而 Kubernetes 或者基础设施这一层是通过数据去驱动的,这就是 Infrastructure as Data。这样的思想会延伸出很多技术和前沿的思想,比如 GitOps 、管道型 YAML 操作工具(Kustomize/kpt)等。这样的管道型应用管理会成为云原生生态里面一个非常主流的应用管理方式。 第二,声明式应用定义模型(比如 OAM),以及声明式的 CI/CD 系统和 Pipeline 会成为一个新的应用交付的模式。比如传统的 Jenkins 是一个命令式的组织方式,而随着声明式的 Pipeline 的出现,加上云原生生态、Kubernetes 的普及,基于 Infrastructure as Data 思想的流水线和下一代的 CI/CD 系统也会成为业界的主流。这跟以前的 CI/CD 和流水线有本质的区别,因为这个 CI/CD 系统里面所有的操作都是一个声明式描述。正因为是声明式描述,所有这些操作以及 CI/CD 里面的环节都可以托管到 Git 上,哪怕一个人工审核(Manual Approve)这样的动作都可以托管在 Git 里面,通过 Git 去审计和做版本管理等。 Infrastructure as Data 的出现就是告诉我们,未来云原生的系统。一切皆对象,一切皆数据。随着对象和数据越来越多,对他们的管理、审计、验证等就变得越来越复杂,那么围绕它们的策略引擎(Policy Engine)会成为一个非常重要的需求。策略引擎会成为一个非常重要的组件,未来 Kubernetes 所有的应用平台可能都需要一个策略引擎的存在,帮助用户处理不同场景下对数据的操作策略。 4. 构建于 IaD 之上的最终用户体验层 需要注意的一点是,虽然 Infrastructure as Data 会成为应用层的主流技术,但是它有一个“硬伤”,就是对最终用户并不友好。因为人的大脑比较容易去处理流程化的、规则化的事情,而不是去处理一个静态的数据,所以说在 IaD 之上会有一层面向最终用户的体验层的存在。这就意味着 Kubernetes 不会把声明式的数据直接交给最终用户,而是通过其他方式来操作这些数据,比如通过一种能够理解 Kubernetes 数据模型的动态配置语言(DSL)来完成,或者通过基于 API 对象的 CLI 或者 dashboard 来完成,也可能是通过一种以应用为中心的交互与协作流程来完成。而最终用户体验层会决定产品有没有黏性,这是云原生的这套体系有没有黏性,是不是用户友好的一个关键环节。 5. DevSecOps 随着如前所述的下一代 DevOps 体系的发展,安全会从一开始就变成应用交付的一部分。在业界大家称之为 DevSecOps ,就是从 day zero 开始就把安全策略、对安全的考量、安全配置作为应用的一部分,而不是等到应用交付出去了甚至应用已经上线了再去做事后的安全审计和管理。 底层基础设施的 Serverless 云原生化 随着云原生体系的发展,云的价值逐渐走向应用层,不断向基于声明式 API 、基于 IaD 的理念去发展,那么下层的基础设施也会发生相应的变化。第一个变化是基础设施能力声明式 API 化、自助化。今天的云是基础设施能力的集大成者,可以认为是一个无限的能力层,今天我们能想象到的基础设施上所有的能力,云都可以提供,这跟以前的基础设施完全不一样。以前云的能力很薄弱,基础设施的能力也很薄弱,所以才需要一个庞大的中间件体系和精密的 DevOps 体系来做一个“胶水层”,去弥补基础设施跟应用、研发、运维人员之间的鸿沟。 而未来,应用才是整个云原生生态的主角。应用需要使用某个能力,那么云就会提供这个能力,并且是通过一个标准化的接入层来提供,而不是直接跟基础设施打交道。云原生生态的发展会使得用户侧的视角发生很大的改变,从面向基础设施变为面向应用,从基础设施有什么用户才能用什么,变成用户要什么,基础设施就可以提供什么。以应用为中心的基础设施会是未来基础设施的一个基本形态。 这个理念跟 Serverless 理念非常类似,我们可以将它称为底层基础设施的 Serverless 原生化,这意味着基础设施会在未来也逐渐的声明式 API 化,而声明式 API 化带来的一个直接结果就是他会变成一个自助化的基础设施。 另外,由于基础设施能够实现声明式 API 化,实现自助化,那么打造更加智能化的基础设施就成为一个重要方向。因为基础设施系统的模块化能力变成了一个数据化的定义方式,那么就可以和容易的通过监控数据、历史数据来驱动基础设施的运转,也就是“自动驾驶的基础设施”。数据驱动的智能化基础设施会在未来成为可能,当然其前提是基础设施本身实现声明式 API 化和自助化。 与此同时,由于应用层本身会 Serverless 泛化,像 “scale to 0” 和 “pay as you go” 这些功能,会成为应用的一个基础的假设,导致资源层也会走向极致弹性+无限资源池的方向。作为一个智能化的基础设施,可以去做更加智能的调度与混部,从而提供极致的资源利用效能,实现成本的极低化。 与此同时,由于要实现极致的资源效能,就意味着底层一定是一个强多租架构,并且这个强多租架构是面向 Kubernetes 的,跟 Kubernetes 有一个天然的、非常融合的集成。这体现在两个方面:第一,在运行时这一层,这个基础设施会倾向走基于硬件虚拟化的容器运行时而非传统虚拟机的方向,比如 Kata Container ,并且认为神龙裸金属服务器更适合做宿主机。伴随着这套技术的发展,轻量化的 VMM(虚拟化管理技术)会成为优化容器运行时、优化整个基础设施敏捷度的一个关键技术和关键链路。 第二,强多租的控制面会针对不同租户做物理隔离,而不只是逻辑隔离,这是 Kubernetes 数据模型的要求,即租户的控制面板之间需要有强的物理隔离,这就是为什么我们讲未来的强多租架构一定会面向 Kubernetes 来构建。阿里内部也是看到了这样的趋势,在不断做一些尝试,去更好地响应未来 Serverless 原生化的基础设施的发展趋势。 另外,我们团队正在招聘2021年毕业的应届生,欢迎各位同学加入我们: 简历投递:yaowei.cyw@alibaba-inc.com 邮件标题:云原生-岗位名称 详情可点击查看:https://mp.weixin.qq.com/s/aMGMme2-p296798wlGQQfQ。 “阿里巴巴云原生关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的公众号。”

优秀的个人博客,低调大师

云原生的五大趋势,K8s安卓化位列其一

“未来的软件一定是生长于云上的”,这是云原生理念的最核心假设。而所谓“云原生”,实际上就是在定义一条能够让应用最大程度利用云的能力、发挥云的价值的最佳路径。因此,云原生其实是一套指导软件架构设计的思想。按照这样的思想而设计出来的软件:首先,天然就“生在云上,长在云上”;其次,能够最大化地发挥云的能力,使得我们开发的软件和“云”能够天然地集成在一起,发挥出“云”的最大价值。 云原生的概念大家并不陌生,很多企业也已经基于云原生的架构和技术理念落地相关实践。那么,这么多企业和开发者热衷和推崇的云原生,未来的发展趋势如何?如何才能顺应云原生的主流方向去发展?怎么在云原生时代“乘风破浪”? 我们邀请到阿里云原生资深技术专家、CNCF技术监督委员会代表,etcd作者李响和阿里云高级技术专家、CNCF 应用交付领域联席主席张磊分享云原生的理念、发展以及未来趋势,为大家打开新的思路和眼界。 以下内容共享给大家。 一、Kubernetes项目的安卓化 云原生里有一个非常关键的项目,就是Kubernetes。Kubernetes的发展非常迅速,它是整个云原生体系发展的基石。今天我们来观察Kubernetes项目的发展特点,首先,Kubernetes无处不在,无论是在云上,还是用户自建的数据中心里,甚至一些我们想象不到的场景里,都有Kubernetes的存在。 第二,所有云原生的用户使用Kubernetes的目的,都是为了交付和管理应用。当然这个应用是一个泛化的概念,可以是一个网站,也可以是淘宝这样非常庞大的电商主站,或者是AI作业、计算任务、函数,甚至虚拟机等,这些都是用户可以使用Kubernetes去交付和管理的应用类型。 第三,今天我们来看Kubernetes所处的位置,实际上是承上启下。Kubernetes对上暴露基础设施能力的格式化数据抽象,比如Service、Ingress、Pod、Deployment,这些都是Kubernetes本身原生API给用户暴露出来的能力。而对下,Kubernetes提供的是基础设施能力接入的标准接口,比如说CNI、CSI、DevicePlugin、CRD,让云能够作为一个能力提供商,以一个标准化的方式把能力接入到Kubernetes的体系中。 这一点其实跟安卓非常类似,安卓虽然装在你的设备里,但是它能够让你的硬件、手机、电视、汽车等都能接入到一个平台里。对上则暴露统一的一套应用管理接口,让你能够基于安卓系统来编写应用,去访问或者享受到这些基础设施能力,这也是Kubernetes和安卓的相似之处。 最后,Kubernetes本身并不直接产生商业价值,你不会花钱去购买Kubernetes。这就跟安卓一样,你不会直接掏钱去买一个安卓系统。而类似的,Kubernetes真正产生价值的地方也在于它的上层应用生态。对安卓来说,它今天已经具备了一个庞大的移动端或设备端应用的开发生态,而对于Kubernetes来说也是类似的,只不过现在还在于比较早的阶段。但我们已经能够看到,今天在Kubernetes上构建的商业层很多是垂直解决方案,是面向用户、面向应用这一侧真正能够产生商业价值的东西,而不是Kubernetes本身这一层。这就是为什么我说Kubernetes发展跟安卓很像,当然这可能也是谷歌比较擅长的一个“打法”:全力地去免费推广一个“操作系统”,真正获取商业价值的方式则是是去“收割”操作系统上层的生态价值而不是操作系统本身。 基于这些现象,我们将Kubernetes的发展趋势概括为以下几点: 1、云的价值回归到应用本身 用户使用Kubernetes的本质目的是去交付和管理应用。从这个现象来看,如果Kubernetes 发展下去,那么世界上所有的数据中心和基础设施上面都会有一层Kubernetes,自然而然用户就会开始以Kubernetes为基础去编写和交付以及管理其应用,就跟现在我们会以安卓这样一个操作系统为基础去编写移动应用是类似的。 这就会导致云上的大多数软件和云产品都是第三方开发的。第三方开发是指所有人都可以面向一个标准界面去开发和交付软件,这个软件本身既可以是自己的软件,也可以是一个云产品。未来,越来越多的第三方开源项目,如MongoDB、Elasticsearch等,都会以云原生理念去开发、部署和运维,最后直接演进成为一种云服务。 2、云端“豌豆荚”的出现 有了Kubernetes这样一个标准,开发者面对的就是一个类似于操作系统的界面。由于有更多的应用是面向Kubernetes诞生的,或者说面向Kubernetes去交付的,那么就需要有一个类似于“豌豆荚”的产品,来作为云上的应用商店或者云上的应用分发系统,它的关键能力在于把应用无差别地交付给全世界任何一个Kubernetes上面,就跟用豌豆荚把任何一个安卓应用交付在任何一个安卓设备上的原理是一样的。 其实今天谷歌已经在做这类产品的尝试了,比如Anthos(面向混合云的应用交付平台),虽然是一款混合云产品,但它本质上是把谷歌云的服务,比如数据库服务、大数据服务,去直接交付于任何一个基于Kubernetes的混合云环境里面去,其实就相当于一款云端的“豌豆荚”。 3、基于Kubernetes可扩展能力的开放应用平台会取代PaaS成为主流 由于未来整个应用生态会面向Kubernetes去构建,那么基于Kubernetes可扩展能力的开放应用平台会逐渐取代传统PaaS 而成为主流。基于Kubernetes可扩展能力去构建一个开放的应用平台,其能力是可插拔的,能够去交付和管理的应用类型是多样化的,这才更符合Kubernetes所构建的趋势和生态,所以一些真正高可扩展的平台层项目会大量产生。 另外,今天我们看到的Kubernetes,跟“理想”中的云原生应用生态之间其实还有很多路要走,这也是阿里云原生团队一直在做的事情,基于Kubernetes在应用层构建更丰富的应用生态,帮助用户实现多样化的需求。 二、应用与能力的“Operator化” 纵观云原生时代应用或者云的能力的发展方向,你会发现另一个趋势,就是Operator化。Operator是Kubernetes的一个概念,是指Kubernetes交付的一个实体,这个实体有一个基础模型存在,这个模型分为两部分:一部分是Kubernetes的 API 对象(CRD),另一部分是一个控制器(Controller),如下图所示。这里要区分两个概念,自定义和自动化。很多人会说 Operator 可以帮助我做自定义,因为很多人都会觉得Kubernetes内置的能力是不够用的,所以用户会利用它的可扩展能力去写一个Controller,从而实现跟多自定义的需求。但自定义只是Operator 中很小的一部分价值,我们今天对应用和能力做Operator化的核心动力在于其实是为了实现自动化,而且只有自动化了,我们才能讲云原生。 这是因为,云原生带来的最大的红利是可以让我们最大限度、最高效地使用云的能力,二这种最高效、最大化的方式一定没办法通过人工来实现的。换句话说,只有通过自动化的方式去开发、运维应用以及与云进行交互,才能真正把云原生的价值发挥出来。 而如果要通过自动化的方式跟云进行交互,那么在云原生生态里,必须有一个类似于Controller或者Operator这样的插件的存在。今天阿里巴巴在云上交付的PolarDB、OceanBase等,其实都有一个跟Kubernetes衔接的Controller的存在。通过Controller与基础设施、云进行交互,把云的能力输入到产品里面去。 在未来,会有大量的云上的应用和对应的运维能力、管理能力都会以Kubernetes Operator 的方式交付。在这个背景下,Kubernetes真正扮演的一个角色就是能力的接入层和标准界面。如下图所示,这是一个非常典型的用户侧Kubernetes集群的样子。 一个用户的Kubernetes只有红框里面这部分是Kubernetes原生提供的API,而大量的能力都是以插件化或者说Operator化的方式存在。就比如上图右边所有这些自定义的资源和能力全部来自于第三方开发,通过Operator 这样一个标准的形态开发出来的能力来服务最终用户的。这就意味着在未来云原生的生态里面,基于CRD Operator的而非Kubernetes原生API的应用和能力会占到绝大多数。 随着这个趋势的不断演进,越来越多的软件和能力通过Kubernetes Operator去描述和定义,云产品也会开始默认以Kubernetes为底座,基于Operator进行交付。 正是因为越来越多的Operator的出现,这里就会逐步需要一个中心化的方式去解决Operator潜在的稳定性、可发现性和性能问题,也就是说在未来很可能会有一个横向的Operator管理平台出现,对所有基于Kubernetes Operator开发的应用和能力进行统一管理,从而更好、更专业地服务用户。 此外,由于未来每一个能力、每一个应用都需要去编写Operator,所以说对开发者友好的Operator编写框架也是未来一个很重要的趋势。这个编写框架可以支持不同语言,如Go、Java、C、Rust语言等,并且编写过程是专注于运维逻辑和应用的管理、能力的管理,而不是专注在Kubernetes的语义和细节上面。 最后,随着云原生生态的普及,云服务也将实现Operator化,并且面向多集群/混合云场景出现面向应用层的云服务标准化定义与抽象,并在云原生领域逐渐取代IaC项目(比如 Terraform 等)成为云服管理与消费的主流方式。 三、应用中间件能力进一步下沉 随着云原生以及整个生态的发展,我们看到应用中间件领域也随之发生了很多改变。从原先最开始的中心化ESB,到后来的胖客户端,逐步演化到今天我们经常提到的Service Mesh这样一种Sidecar化的方式。 其实今天你会发现,无论是云的能力还是基础设施的能力,都在不断丰富,很多原先只能通过中间件做的事情,现在可以很容易通过云服务来实现。应用中间件不再是能力的提供方,而是能力接入的标准界面,并且这个标准界面的构建不再基于胖客户端,而是通过非常普通的HTTP协议、gRPC协议去做,然后通过Sidecar方式把整个服务的接入层跟应用业务逻辑做一个解耦,这其实就是Service Mesh的思想。 目前Service Mesh只做了传统中间件里面的流量治理、路由策略、访问控制这一层的事情。而实际上,Sidecar 这个模型可以应用到所有中间件的场景里,实现中间件逻辑跟应用业务逻辑完全解耦,让应用中间件能力“下沉”,变成Kubernetes能力的一部分。这样应用本身会更加专一化,更多的关注业务逻辑本身。 伴随着这个趋势,在Kubernetes这一层还会有另外一个趋势出现,就是Sidecar的自动化的、规模化的运维能力会成为一个必选项。因为Sidecar的数量会极其庞大,应用中间件很可能会演化成Sidecar集群,那么这些Sidecar的管理和规模化的运维能力,会是集群或者云产品的一个必备选项。 四、下一代DevOps模型与体系 随着云原生生态的不断发展,云原生理念的不断普及,DevOps的思想很可能也会发生一个本质的变化,即下一代DevOps模型与体系。随着Kubernetes的能力越来越多、越来越强大,基础设施也会变得越来越复杂,那么基于这样一个强大的基础设施去构建一个应用平台就会非常简单,并且这个应用平台最终会取代传统的PaaS平台。 我们现在之所以在用DevOps这一套思想,实际上是由于基础设施本身不够强大,不够标准化,不够好用,所以我们需要在业务研发侧做一套工具去黏合研发人员和基础设施。例如,基础设施提供的能力是一个虚拟机,怎么能让虚拟机变成研发侧想要的蓝绿发布或者一个渐进式的应用交付系统呢?这就需要一系列的DevOps的工具、CI/CD的流水线来完成。但是现在的情况已经发生了变化。基于Kubernetes的基础设施本身的能力已经非常丰富,像蓝绿发布这些能力本身就是Kubernetes可以提供的能力。在这样的背景下,DevOps的发展趋势也会发生很大的改变: 1、关注点分离 在 Kubernetes 的背景下,“软件”不再是一个由应用Owner掌控的单一交付物,而是多个Kubernetes对象的集合,而这一堆Kubernetes里面的对象只有很少一部分其实才跟研发有关,所以说有很多对象会不在应用Owner的认知范围内,这就导致平台必须去做关注点分离,研发侧的关注点和运维侧、系统侧的关注点是完全不一样的东西。也就是研发不用再考虑运维方面的细节,比如蓝绿发布怎么做,水平扩容什么策略,只要把业务代码写完交付就好。 伴随着 Kubernetes和基础设施越来越复杂,概念越来越多,作为平台层是不大可能让研发了解所有的概念,因此未来云原生生态一定会做抽象和分层。每一层的角色只跟属于自己的数据抽象去交互,研发侧有一套自己的声明式API对象,运维侧有一套自己的声明式API对象,每一层的关注点也是不一样的,这会是未来整个DevOps体系里发展的一个重要的背景。 2、Serverless 泛化 云原生本身的关注点就是应用,在这样一个背景下,Serverless本身不再是一个独立场景,不再局限在某几个非常垂直的领域,而会变成云原生应用管理体系的一种泛化思想和天然组成部分。我从两个层面解释一下:一是在能力侧,“轻运维”“NoOps”以及“自助式运维能力”会成为应用运维的主流方式。云原生生态上的应用管理会体现出一种轻运维的状态,就是说应用运维不再是一个人工的、非常复杂的过程,而是一组开箱即用的、非常简单的模块化操作。无论是通过Kubernetes还是通过云原生能力,都是对下层基础设施的一个模块化的分装,这跟Serverless所提倡的NoOps理念非常类似。 二是在应用侧,应用描述会广泛地进行用户侧的抽象,事件驱动和Serverless 理念被拆分和泛化,可以被应用于多样化的场景中而不仅仅是今天狭义的 Serverless 场景比如 FaaS 或者 Container Instance,未来所有的应用都可以实现scale-to-zero。 3、基于Infrastructure as Data(IaD)思想的应用层技术渐成主流 第一,基于Infrastructure as Data(IaD)的思想会成为一个主流技术,IaD实际就是Kubernetes的声明式API,声明式API的核心在于把基础设施、应用、能力以一个声明式的文件、声明式的对象去描述,那么这个文件或者对象本身就是“数据”。而Kubernetes或者基础设施这一层是通过数据去驱动的,这就是Infrastructure as Data。这样的思想会延伸出很多技术和前沿的思想,比如GitOps、管道型YAML操作工具(Kustomize/kpt)等。这样的管道型应用管理会成为云原生生态里面一个非常主流的应用管理方式。 第二,声明式应用定义模型(比如 OAM),以及声明式的CI/CD系统和Pipeline会成为一个新的应用交付的模式。比如传统的Jenkins是一个命令式的组织方式,而随着声明式的Pipeline的出现,加上云原生生态、Kubernetes的普及,基于Infrastructure as Data思想的流水线和下一代的CI/CD系统也会成为业界的主流。这跟以前的CI/CD和流水线有本质的区别,因为这个CI/CD系统里面所有的操作都是一个声明式描述。正因为是声明式描述,所有这些操作以及CI/CD里面的环节都可以托管到Git上,哪怕一个人工审核(Manual Approve)这样的动作都可以托管在Git里面,通过Git去审计和做版本管理等。 Infrastructure as Data的出现就是告诉我们,未来云原生的系统。一切皆对象,一切皆数据。随着对象和数据越来越多,对他们的管理、审计、验证等就变得越来越复杂,那么围绕它们的策略引擎(Policy Engine)会成为一个非常重要的需求。策略引擎会成为一个非常重要的组件,未来Kubernetes所有的应用平台可能都需要一个策略引擎的存在,帮助用户处理不同场景下对数据的操作策略。 4、构建于IaD之上的最终用户体验层 需要注意的一点是,虽然Infrastructure as Data会成为应用层的主流技术,但是它有一个“硬伤”,就是对最终用户并不友好。因为人的大脑比较容易去处理流程化的、规则化的事情,而不是去处理一个静态的数据,所以说在IaD之上会有一层面向最终用户的体验层的存在。这就意味着Kubernetes不会把声明式的数据直接交给最终用户,而是通过其他方式来操作这些数据,比如通过一种能够理解Kubernetes数据模型的动态配置语言(DSL)来完成,或者通过基于API对象的CLI或者dashboard来完成,也可能是通过一种以应用为中心的交互与协作流程来完成。而最终用户体验层会决定产品有没有黏性,这是云原生的这套体系有没有黏性,是不是用户友好的一个关键环节。 5、DevSecOps 随着如前所述的下一代DevOps体系的发展,安全会从一开始就变成应用交付的一部分。在业界大家称之为DevSecOps,就是从day zero开始就把安全策略、对安全的考量、安全配置作为应用的一部分,而不是等到应用交付出去了甚至应用已经上线了再去做事后的安全审计和管理。 五、底层基础设施的Serverless云原生化 随着云原生体系的发展,云的价值逐渐走向应用层,不断向基于声明式API、基于IaD的理念去发展,那么下层的基础设施也会发生相应的变化。第一个变化是基础设施能力声明式API化、自助化。今天的云是基础设施能力的集大成者,可以认为是一个无限的能力层,今天我们能想象到的基础设施上所有的能力,云都可以提供,这跟以前的基础设施完全不一样。以前云的能力很薄弱,基础设施的能力也很薄弱,所以才需要一个庞大的中间件体系和精密的DevOps体系来做一个“胶水层”,去弥补基础设施跟应用、研发、运维人员之间的鸿沟。 而未来,应用才是整个云原生生态的主角。应用需要使用某个能力,那么云就会提供这个能力,并且是通过一个标准化的接入层来提供,而不是直接跟基础设施打交道。云原生生态的发展会使得用户侧的视角发生很大的改变,从面向基础设施变为面向应用,从基础设施有什么用户才能用什么,变成用户要什么,基础设施就可以提供什么。以应用为中心的基础设施会是未来基础设施的一个基本形态。 这个理念跟Serverless理念非常类似,我们可以将它称为底层基础设施的Serverless原生化,这意味着基础设施会在未来也逐渐的声明式API化,而声明式API化带来的一个直接结果就是他会变成一个自助化的基础设施。 另外,由于基础设施能够实现声明式API化,实现自助化,那么打造更加智能化的基础设施就成为一个重要方向。因为基础设施系统的模块化能力变成了一个数据化的定义方式,那么就可以和容易的通过监控数据、历史数据来驱动基础设施的运转,也就是“自动驾驶的基础设施”。数据驱动的智能化基础设施会在未来成为可能,当然其前提是基础设施本身实现声明式API化和自助化。 与此同时,由于应用层本身会Serverless泛化,像“scale to 0 ”和“pay as you go”这些功能,会成为应用的一个基础的假设,导致资源层也会走向极致弹性+无限资源池的方向。作为一个智能化的基础设施,可以去做更加智能的调度与混部,从而提供极致的资源利用效能,实现成本的极低化。 与此同时,由于要实现极致的资源效能,就意味着底层一定是一个强多租架构,并且这个强多租架构是面向Kubernetes 的,跟Kubernetes有一个天然的、非常融合的集成。这体现在两个方面:第一,在运行时这一层,这个基础设施会倾向走基于硬件虚拟化的容器运行时而非传统虚拟机的方向,比如Kata Container,并且认为神龙裸金属服务器更适合做宿主机。伴随着这套技术的发展,轻量化的VMM(虚拟化管理技术)会成为优化容器运行时、优化整个基础设施敏捷度的一个关键技术和关键链路。 第二,强多租的控制面会针对不同租户做物理隔离,而不只是逻辑隔离,这是Kubernetes数据模型的要求,即租户的控制面板之间需要有强的物理隔离,这就是为什么我们讲未来的强多租架构一定会面向Kubernetes来构建。阿里内部也是看到了这样的趋势,在不断做一些尝试,去更好地响应未来Serverless原生化的基础设施的发展趋势。 云计算的下一站,就是云原生;IT架构的下一站,就是云原生架构,这是属于所有开发者最好的时代。阿里云将于7月上线《云原生架构白皮书》,助力所有的开发者、架构师和技术决策者们,共同定义云原生,拥抱云原生。

优秀的个人博客,低调大师

每日一博 | 更新应用时,如何实现 K8s 零中断滚动更新?

作者 | 子白(阿里云开发工程师)、溪恒(阿里云技术专家) <关注阿里巴巴云原生公众号,回复排查即可下载电子书> 《深入浅出 Kubernetes》一书共汇集 12 篇技术文章,帮助你一次搞懂 6 个核心原理,吃透基础理论,一次学会 6 个典型问题的华丽操作! Kubernetes集群中,业务通常采用Deployment + LoadBalancer类型Service的方式对外提供服务,其典型部署架构如图1所示。这种架构部署和运维都十分简单方便,但是在应用更新或者升级时可能会存在服务中断,引发线上问题。今天我们来详细分析下这种架构为何在更新应用时会发生服务中断以及如何避免服务中断。 图1 业务部署图 为何会发生服务中断 Deployment滚动更新时会先创建新pod,等待新pod running后再删除旧pod。 新建Pod 图2 服务中断示意图 中断原因:Pod running后被加入到Endpoint后端,容器服务监控到Endpoint变更后将Node加入到SLB后端。此时请求从SLB转发到Pod中,但是Pod业务代码还未初始化完毕,无法处理请求,导致服务中断,如图2所示。 解决方法:为pod配置就绪检测,等待业务代码初始化完毕后后再将node加入到SLB后端。 删除Pod 在删除旧pod过程中需要对多个对象(如Endpoint、ipvs/iptables、SLB)进行状态同步,并且这些同步操作是异步执行的,整体同步流程如图3所示。 图3 Deployment更新时序图 Pod pod状态变更:将Pod设置为Terminating状态,并从所有Service的Endpoints列表中删除。此时,Pod停止获得新的流量,但在Pod中运行的容器不会受到影响; 执行preStop Hook:Pod删除时会触发preStop Hook,preStop Hook支持bash脚本、TCP或HTTP请求; 发送SIGTERM 信号:向Pod中的容器发送SIGTERM信号; 等待指定的时间:terminationGracePeriodSeconds字段用于控制等待时间,默认值为30秒。该步骤与preStop Hook同时执行,因此terminationGracePeriodSeconds需要大于preStop的时间,否则会出现preStop未执行完毕,pod就被kill的情况; 发送SIGKILL信号:等待指定时间后,向pod中的容器发送SIGKILL信号,删除pod。 中断原因:上述1、2、3、4步骤同时进行,因此有可能存在Pod收到SIGTERM信号并且停止工作后,还未从Endpoints中移除的情况。此时,请求从slb转发到pod中,而Pod已经停止工作,因此会出现服务中断,如图4所示。 图4 服务中断示意图 解决方法:为pod配置preStop Hook,使Pod收到SIGTERM时sleep一段时间而不是立刻停止工作,从而确保从SLB转发的流量还可以继续被Pod处理。 iptables/ipvs 中断原因:当pod变为termintaing状态时,会从所有service的endpoint中移除该pod。kube-proxy会清理对应的iptables/ipvs条目。而容器服务watch到endpoint变化后,会调用slb openapi移除后端,此操作会耗费几秒。由于这两个操作是同时进行,因此有可能存在节点上的iptables/ipvs条目已经被清理,但是节点还未从slb移除的情况。此时,流量从slb流入,而节点上已经没有对应的iptables/ipvs规则导致服务中断,如图5所示。 图5 服务中断示意图 解决方法: Cluster 模式:Cluster模式下kube-proxy会把所有业务Pod写入Node的iptables/ipvs中,如果当前Node没有业务pod,则该请求会被转发给其他Node,因此不会存在服务中断,如6所示; 图6 Cluster模式请求转发示意图 Local模式:Local模式下,kube-proxy仅会把Node上的pod写入iptables/ipvs。当Node上只有一个pod且状态变为terminating时,iptables/ipvs会将该pod记录移除。此时请求转发到这个node时,无对应的iptables/ipvs记录,导致请求失败。这个问题可以通过原地升级来避免,即保证更新过程中Node上至少有一个Running Pod。原地升级可以保障Node的iptables/ipvs中总会有一条业务pod记录,因此不会产生服务中断,如图7所示; 图7 Local模式原地升级时请求转发示意图 ENI 模式 Service:ENI模式绕过kube-proxy,将Pod直接挂载到SLB后端,因此不存在因为iptables/ipvs导致的服务中断。 图 8 ENI模式请求转发示意图 SLB 图 9服务中断示意图 中断原因:容器服务监控到Endpoints变化后,会将Node从slb后端移除。当节点从slb后端移除后,SLB对于继续发往该节点的长连接会直接断开,导致服务中断。 解决方法:为SLB设置长链接优雅中断(依赖具体云厂商)。 如何避免服务中断 避免服务中断可以从Pod和Service两类资源入手,接下来将针对上述中断原因介绍相应的配置方法。 Pod配置 apiVersion: v1 kind: Pod metadata: name: nginx namespace: default spec: containers: - name: nginx image: nginx # 存活检测 livenessProbe: failureThreshold: 3 initialDelaySeconds: 30 periodSeconds: 30 successThreshold: 1 tcpSocket: port: 5084 timeoutSeconds: 1 # 就绪检测 readinessProbe: failureThreshold: 3 initialDelaySeconds: 30 periodSeconds: 30 successThreshold: 1 tcpSocket: port: 5084 timeoutSeconds: 1 # 优雅退出 lifecycle: preStop: exec: command: - sleep - 30 terminationGracePeriodSeconds: 60 注意:需要合理设置就绪检测(readinessProbe)的探测频率、延时时间、不健康阈值等数据,部分应用启动时间本身较长,如果设置的时间过短,会导致 POD 反复重启。 livenessProbe为存活检测,如果失败次数到达阈值(failureThreshold)后,pod会重启,具体配置见官方文档; readinessProbe为就绪检查,只有就绪检查通过后,pod才会被加入到Endpoint中。容器服务监控到Endpoint变化后才会将node挂载到slb后端; preStop时间建议设置为业务处理完所有剩余请求所需的时间,terminationGracePeriodSeconds时间建议设置为preStop的时间再加30秒以上。 Service配置 Cluster模式(externalTrafficPolicy: Cluster) apiVersion: v1 kind: Service metadata: name: nginx namespace: default spec: externalTrafficPolicy: Cluster ports: - port: 80 protocol: TCP targetPort: 80 selector: run: nginx type: LoadBalancer 容器服务会将集群中所有节点挂载到SLB的后端(使用BackendLabel标签配置后端的除外),因此会快速消耗SLB quota。SLB限制了每个ECS上能够挂载的SLB的个数,默认值为50,当quota消耗完后会导致无法创建新的监听及SLB。 Cluster模式下,如果当前节点没有业务pod会将请求转发给其他Node。在跨节点转发时需要做NAT,因此会丢失源IP。 Local模式(externalTrafficPolicy: Local) apiVersion: v1 kind: Service metadata: name: nginx namespace: default spec: externalTrafficPolicy: Local ports: - port: 80 protocol: TCP targetPort: 80 selector: run: nginx type: LoadBalancer # 需要尽可能的让每个节点在更新的过程中有至少一个的Running的Pod # 通过修改UpdateStrategy和利用nodeAffinity尽可能的保证在原地rolling update # * UpdateStrategy可以设置Max Unavailable为0,保证有新的Pod启动后才停止之前的pod # * 先对固定的几个节点打上label用来调度 # * 使用nodeAffinity+和超过相关node数量的replicas数量保证尽可能在原地建新的Pod # 例如: apiVersion: apps/v1 kind: Deployment ...... strategy: rollingUpdate: maxSurge: 50% maxUnavailable: 0% type: RollingUpdate ...... affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: deploy operator: In values: - nginx 容器服务默认会将Service对应的Pod所在的节点加入到SLB后端,因此SLB quota消耗较慢。Local模式下请求直接转发到pod所在node,不存在跨节点转发,因此可以保留源IP地址。Local模式下可以通过原地升级的方式避免服务中断,yaml文件如上。 ENI模式(阿里云特有模式) apiVersion: v1 kind: Service metadata: annotations: service.beta.kubernetes.io/backend-type: "eni" name: nginx spec: ports: - name: http port: 30080 protocol: TCP targetPort: 80 selector: app: nginx type: LoadBalancer Terway网络模式下,通过设置service.beta.kubernetes.io/backend-type: "eni" annotation可以创建ENI模式的SLB。ENI模式下,pod会直接挂载到SLB后端,不经过kube-proxy,因此不存在服务中断的问题。请求直接转发到pod,因此可以保留源IP地址。 三种svc模式对比如下表所示。 图 10 Service对比 结论 Terway 网络模式 (推荐方式) 选用ENI模式的svc + 设定Pod优雅终止 + 就绪检测。 Flannel 网络模式 如果集群中slb数量不多且不需要保留源ip:选用cluster模式 + 设定Pod优雅终止 + 就绪检测; 如果集群中slb数量较多或需要保留源ip:选用local模式 + 设定Pod优雅终止 + 就绪检测 + 原地升级(保证更新过程中每个节点上至少有一个Running Pod)。 Reference 容器生命周期钩子 Configure Liveness, Readiness and Startup Probes 通过负载均衡访问服务 Kubernetes 最佳实践:优雅的中止 Kubernetes社区相关讨论:Create ability to do zero downtime deployments when using externalTrafficPolicy: Local,Graceful Termination for External Traffic Policy Local 容器服务 kubernetes(ACK)中应用优雅上下线 课程推荐 为了更多开发者能够享受到 Serverless 带来的红利,这一次,我们集结了 10+ 位阿里巴巴 Serverless 领域技术专家,打造出最适合开发者入门的 Serverless 公开课,让你即学即用,轻松拥抱云计算的新范式——Serverless。 点击即可免费观看课程:https://developer.aliyun.com/learning/roadmap/serverless “阿里巴巴云原生关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的公众号。”

优秀的个人博客,低调大师

K8S集群入门:运行一个应用程序究竟需要多少集群?

云栖号:https://yqh.aliyun.com第一手的上云资讯,不同行业精选的上云企业案例库,基于众多成功案例萃取而成的最佳实践,助力您上云决策! 如果你使用Kubernetes作为应用程序的操作平台,那么你应该会遇到一些有关使用集群的方式的基本问题: 你应该有多少集群? 它们应该多大? 它们应该包含什么? 本文将深入讨论这些问题,并分析你所拥有的一些选择的利弊。 问题所在 作为一个软件创建者,你应该开发并运行了多个应用程序。而且,你应该在不同的环境中运行这些应用程序的多个实例——例如,你应该有开发、测试以及生产环境。那么,不同的环境和应用程序的组合,我们可以得到一个“矩阵”: 在以上例子中,有3个应用程序和3个环境,两两组合为9个应用程序实例。每个应用程序实例是一个独立的部署单位,可以独立运行。 请注意,一个应用程序实例可能由多个组件组成,如前端、后端、数据库等。在一个微服务应用程序中,一个应用程序实例将由所有微服务构成。 那么作为一个Kubernetes用户,此时会遇到一些问题: 应该在一个集群中运行所有应用程序实例吗? 或者每个应用程序实例都应该有一个单独的集群吗? 或者应该以上两者相结合? 以上这些都是行之有效的方法——Kubernetes是一个灵活的系统,它并不会直接告诉你某一条指定的使用方法。 关于集群的搭配你有以下选择: 一个大型的共享集群 许多小型的一次性集群 每个应用程序有一个集群 每个环境中有一个集群 前两种方法分别是大型集群和小型集群的极端,其规模大小关系如下: 总而言之,如果一个集群包含了大量的节点和Pod,那么它就可以被定义为大于另一个集群。例如,一个有10个节点和100Pod的集群大于有1个节点和10个Pod的集群。 厘清了概念和选项,那么我们现在开始吧! 一个大型共享集群 这个方法是指将你所有的工作负载都运行在一个集群中: 通过这种方法,我们可以像通用基础架构平台一样使用该集群——无论你需要运行什么,都可将其部署到现有的Kubernetes集群中。 Kubernetes中有一个命名空间的概念,可以 在逻辑上将集群的各个部分彼此分开。在上述情况下,你可以为每个应用程序实例创建单独的命名空间。 接下来,我们来看看这个方法的优劣势。 云栖号:https://yqh.aliyun.com第一手的上云资讯,不同行业精选的上云企业案例库,基于众多成功案例萃取而成的最佳实践,助力您上云决策! 原文发布时间:2020-02-29本文作者:Rancher本文来自:“Dockone.io”,了解相关信息可以关注“Dockone.io”

优秀的个人博客,低调大师

从认证到调度,K8s 集群上运行的小程序到底经历了什么?

作者 | 声东 阿里云售后技术专家 导读:不知道大家有没有意识到一个现实:大部分时候,我们已经不像以前一样,通过命令行,或者可视窗口来使用一个系统了。 前言 现在我们上微博、或者网购,操作的其实不是眼前这台设备,而是一个又一个集群。通常,这样的集群拥有成百上千个节点,每个节点是一台物理机或虚拟机。集群一般远离用户,坐落在数据中心。为了让这些节点互相协作,对外提供一致且高效的服务,集群需要操作系统。Kubernetes 就是这样的操作系统。 比较 Kubernetes 和单机操作系统,Kubernetes 相当于内核,它负责集群软硬件资源管理,并对外提供统一的入口,用户可以通过这个入口来使用集群,和集群沟通。 而运行在集群之上的程序,与普通程序有很大的不同。这样的程序,是“关在笼子里”的程序。它们从被制作,到被部署,再到被使用,都不寻常。我们只有深挖根源,才能理解其本质。 “关在笼子里”的程序 代码 我们使用 go 语言写了一个简单的 web 服务器程序 app.go,这个程序监听在 2580 这个端口。通过 http 协议访问这个服务的根路径,服务会返回 "This is a small app for kubernetes..." 字符串。 package main import ( "github.com/gorilla/mux" "log" "net/http" ) func about(w http.ResponseWriter, r *http.Request) { w.Write([]byte("This is a small app for kubernetes...\n")) } func main() { r := mux.NewRouter() r.HandleFunc("/", about) log.Fatal(http.ListenAndServe("0.0.0.0:2580", r)) } 使用 go build 命令编译这个程序,产生 app 可执行文件。这是一个普通的可执行文件,它在操作系统里运行,会依赖系统里的库文件。 # ldd app linux-vdso.so.1 => (0x00007ffd1f7a3000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f554fd4a000) libc.so.6 => /lib64/libc.so.6 (0x00007f554f97d000) /lib64/ld-linux-x86-64.so.2 (0x00007f554ff66000) “笼子” 为了让这个程序不依赖于操作系统自身的库文件,我们需要制作容器镜像,即隔离的运行环境。Dockerfile 是制作容器镜像的“菜谱”。我们的菜谱就只有两个步骤,下载一个 centos 的基础镜像,把 app 这个可执行文件放到镜像中 /usr/local/bin 目录中去。 FROM centos ADD app /usr/local/bin 地址 制作好的镜像存再本地,我们需要把这个镜像上传到镜像仓库里去。这里的镜像仓库,相当于应用商店。我们使用阿里云的镜像仓库,上传之后镜像地址是: registry.cn-hangzhou.aliyuncs.com/kube-easy/app:latest 镜像地址可以拆分成四个部分:仓库地址/命名空间/镜像名称:镜像版本。显然,镜像上边的镜像,在阿里云杭州镜像仓库,使用的命名空间是 kube-easy,镜像名:版本是 app:latest。至此,我们有了一个可以在 Kubernetes 集群上运行的、“关在笼子里”的小程序。 得其门而入 入口 Kubernetes 作为操作系统,和普通的操作系统一样,有 API 的概念。有了 API,集群就有了入口;有了 API,我们使用集群,才能得其门而入。Kubernetes 的 API 被实现为运行在集群节点上的组件 API Server。这个组件是典型的 web 服务器程序,通过对外暴露 http(s) 接口来提供服务。 这里我们创建一个阿里云 Kubernetes 集群。登录集群管理页面,我们可以看到 API Server 的公网入口。 API Server 内网连接端点: https://xx.xxx.xxx.xxx:6443 双向数字证书验证 阿里云 Kubernetes 集群 API Server 组件,使用基于 CA 签名的双向数字证书认证来保证客户端与 api server 之间的安全通信。这句话很绕口,对于初学者不太好理解,我们来深入解释一下。 从概念上来讲,数字证书是用来验证网络通信参与者的一个文件。这和学校颁发给学生的毕业证书类似。在学校和学生之间,学校是可信第三方 CA,而学生是通信参与者。如果社会普遍信任一个学校的声誉的话,那么这个学校颁发的毕业证书,也会得到社会认可。参与者证书和 CA 证书可以类比毕业证和学校的办学许可证。 这里我们有两类参与者,CA 和普通参与者;与此对应,我们有两种证书,CA 证书和参与者证书;另外我们还有两种关系,证书签发关系以及信任关系。这两种关系至关重要。 我们先看签发关系。如下图,我们有两张 CA 证书,三个参与者证书。 其中最上边的 CA 证书,签发了两张证书,一张是中间的 CA 证书,另一张是右边的参与者证书;中间的 CA 证书,签发了下边两张参与者证书。这六张证书以签发关系为联系,形成了树状的证书签发关系图。 然而,证书以及签发关系本身,并不能保证可信的通信可以在参与者之间进行。以上图为例,假设最右边的参与者是一个网站,最左边的参与者是一个浏览器,浏览器相信网站的数据,不是因为网站有证书,也不是因为网站的证书是 CA 签发的,而是因为浏览器相信最上边的 CA,也就是信任关系。 理解了 CA(证书),参与者(证书),签发关系,以及信任关系之后,我们回过头来看“基于 CA 签名的双向数字证书认证”。客户端和 API Server 作为通信的普通参与者,各有一张证书。而这两张证书,都是由 CA 签发,我们简单称它们为集群 CA 和客户端 CA。客户端信任集群 CA,所以它信任拥有集群 CA 签发证书的 API Server;反过来 API Server 需要信任客户端 CA,它才愿意与客户端通信。 阿里云 Kubernetes 集群,集群 CA 证书,和客户端 CA 证书,实现上其实是一张证书,所以我们有这样的关系图。 KubeConfig 文件 登录集群管理控制台,我们可以拿到 KubeConfig 文件。这个文件包括了客户端证书,集群 CA 证书,以及其他。证书使用 base64 编码,所以我们可以使用 base64 工具解码证书,并使用 openssl 查看证书文本。 首先,客户端证书的签发者 CN 是集群 id c0256a3b8e4b948bb9c21e66b0e1d9a72,而证书本身的 CN 是子账号 252771643302762862; Certificate: Data: Version: 3 (0x2) Serial Number: 787224 (0xc0318) Signature Algorithm: sha256WithRSAEncryption Issuer: O=c0256a3b8e4b948bb9c21e66b0e1d9a72, OU=default, CN=c0256a3b8e4b948bb9c21e66b0e1d9a72 Validity Not Before: Nov 29 06:03:00 2018 GMT Not After : Nov 28 06:08:39 2021 GMT Subject: O=system:users, OU=, CN=252771643302762862 其次,只有在 API Server 信任客户端 CA 证书的情况下,上边的客户端证书才能通过 API Server 的验证。kube-apiserver 进程通过 client-ca-file 这个参数指定其信任的客户端 CA 证书,其指定的证书是 /etc/kubernetes/pki/apiserver-ca.crt。这个文件实际上包含了两张客户端 CA 证书,其中一张和集群管控有关系,这里不做解释,另外一张如下,它的 CN 与客户端证书的签发者 CN 一致; Certificate: Data: Version: 3 (0x2) Serial Number: 787224 (0xc0318) Signature Algorithm: sha256WithRSAEncryption Issuer: O=c0256a3b8e4b948bb9c21e66b0e1d9a72, OU=default, CN=c0256a3b8e4b948bb9c21e66b0e1d9a72 Validity Not Before: Nov 29 06:03:00 2018 GMT Not After : Nov 28 06:08:39 2021 GMT Subject: O=system:users, OU=, CN=252771643302762862 再次,API Server 使用的证书,由 kube-apiserver 的参数 tls-cert-file 决定,这个参数指向证书 /etc/kubernetes/pki/apiserver.crt。这个证书的 CN 是 kube-apiserver,签发者是 c0256a3b8e4b948bb9c21e66b0e1d9a72,即集群 CA 证书; Certificate: Data: Version: 3 (0x2) Serial Number: 2184578451551960857 (0x1e512e86fcba3f19) Signature Algorithm: sha256WithRSAEncryption Issuer: O=c0256a3b8e4b948bb9c21e66b0e1d9a72, OU=default, CN=c0256a3b8e4b948bb9c21e66b0e1d9a72 Validity Not Before: Nov 29 03:59:00 2018 GMT Not After : Nov 29 04:14:23 2019 GMT Subject: CN=kube-apiserver 最后,客户端需要验证上边这张 API Server 的证书,因而 KubeConfig 文件里包含了其签发者,即集群 CA 证书。对比集群 CA 证书和客户端 CA 证书,发现两张证书完全一样,这符合我们的预期。 Certificate: Data: Version: 3 (0x2) Serial Number: 786974 (0xc021e) Signature Algorithm: sha256WithRSAEncryption Issuer: C=CN, ST=ZheJiang, L=HangZhou, O=Alibaba, OU=ACS, CN=root Validity Not Before: Nov 29 03:59:00 2018 GMT Not After : Nov 24 04:04:00 2038 GMT Subject: O=c0256a3b8e4b948bb9c21e66b0e1d9a72, OU=default, CN=c0256a3b8e4b948bb9c21e66b0e1d9a72 访问 理解了原理之后,我们可以做一个简单的测试:以证书作为参数,使用 curl 访问 api server,并得到预期结果。 # curl --cert ./client.crt --cacert ./ca.crt --key ./client.key https://xx.xx.xx.xxx:6443/api/ { "kind": "APIVersions", "versions": [ "v1" ], "serverAddressByClientCIDRs": [ { "clientCIDR": "0.0.0.0/0", "serverAddress": "192.168.0.222:6443" } ] } 择优而居 两种节点,一种任务 如开始所讲,Kubernetes 是管理集群多个节点的操作系统。这些节点在集群中的角色,却不必完全一样。Kubernetes 集群有两种节点:master 节点和 worker 节点。 这种角色的区分,实际上就是一种分工:master 负责整个集群的管理,其上运行的以集群管理组件为主,这些组件包括实现集群入口的 api server;而 worker 节点主要负责承载普通任务。 在 Kubernetes 集群中,任务被定义为 pod 这个概念。pod 是集群可承载任务的原子单元,pod 被翻译成容器组,其实是意译,因为一个 pod 实际上封装了多个容器化的应用。原则上来讲,被封装在一个 pod 里边的容器,应该是存在相当程度的耦合关系。 择优而居 调度算法需要解决的问题,是替 pod 选择一个舒适的“居所”,让 pod 所定义的任务可以在这个节点上顺利地完成。 为了实现“择优而居”的目标,Kubernetes 集群调度算法采用了两步走的策略: 第一步,从所有节点中排除不满足条件的节点,即预选; 第二步,给剩余的节点打分,最后得分高者胜出,即优选。 下面我们使用文章开始的时候制作的镜像,创建一个 pod,并通过日志来具体分析一下,这个 pod 怎么样被调度到某一个集群节点。 Pod 配置 首先,我们创建 pod 的配置文件,配置文件格式是 json。这个配置文件有三个地方比较关键,分别是镜像地址,命令以及容器的端口。 { "apiVersion": "v1", "kind": "Pod", "metadata": { "name": "app" }, "spec": { "containers": [ { "name": "app", "image": "registry.cn-hangzhou.aliyuncs.com/kube-easy/app:latest", "command": [ "app" ], "ports": [ { "containerPort": 2580 } ] } ] } } 日志级别 集群调度算法被实现为运行在 master 节点上的系统组件,这一点和 api server 类似。其对应的进程名是 kube-scheduler。kube-scheduler 支持多个级别的日志输出,但社区并没有提供详细的日志级别说明文档。查看调度算法对节点进行筛选、打分的过程,我们需要把日志级别提高到 10,即加入参数 --v=10。 kube-scheduler --address=127.0.0.1 --kubeconfig=/etc/kubernetes/scheduler.conf --leader-elect=true --v=10 创建 Pod 使用 curl,以证书和 pod 配置文件等作为参数,通过 POST 请求访问 api server 的接口,我们可以在集群里创建对应的 pod。 # curl -X POST -H 'Content-Type: application/json;charset=utf-8' --cert ./client.crt --cacert ./ca.crt --key ./client.key https://47.110.197.238:6443/api/v1/namespaces/default/pods -d@app.json 预选 预选是 Kubernetes 调度的第一步,这一步要做的事情,是根据预先定义的规则,把不符合条件的节点过滤掉。不同版本的 Kubernetes 所实现的预选规则有很大的不同,但基本的趋势,是预选规则会越来越丰富。 比较常见的两个预选规则是 PodFitsResourcesPred 和 PodFitsHostPortsPred。前一个规则用来判断,一个节点上的剩余资源,是不是能够满足 pod 的需求;而后一个规则,检查一个节点上某一个端口是不是已经被其他 pod 所使用了。 下图是调度算法在处理测试 pod 的时候,输出的预选规则的日志。这段日志记录了预选规则 CheckVolumeBindingPred的执行情况。某些类型的存储卷(PV),只能挂载到一个节点上,这个规则可以过滤掉不满足 pod 对 PV 需求的节点。 从 app 的编排文件里可以看到,pod 对存储卷并没有什么需求,所以这个条件并没有过滤掉节点。 优选 调度算法的第二个阶段是优选阶段。这个阶段,kube-scheduler 会根据节点可用资源及其他一些规则,给剩余节点打分。 目前,CPU 和内存是调度算法考量的两种主要资源,但考量的方式并不是简单的,剩余 CPU、内存资源越多,得分就越高。 日志记录了两种计算方式:LeastResourceAllocation 和 BalancedResourceAllocation。 前一种方式计算 pod 调度到节点之后,节点剩余 CPU 和内存占总 CPU 和内存的比例,比例越高得分就越高; 第二种方式计算节点上 CPU 和内存使用比例之差的绝对值,绝对值越大,得分越少。 这两种方式,一种倾向于选出资源使用率较低的节点,第二种希望选出两种资源使用比例接近的节点。这两种方式有一些矛盾,最终依靠一定的权重来平衡这两个因素。 除了资源之外,优选算法会考虑其他一些因素,比如 pod 与节点的亲和性,或者如果一个服务有多个相同 pod 组成的情况下,多个 pod 在不同节点上的分散程度,这是保证高可用的一种策略。 得分 最后,调度算法会给所有的得分项乘以它们的权重,然后求和得到每个节点最终的得分。因为测试集群使用的是默认调度算法,而默认调度算法把日志中出现的得分项所对应的权重,都设置成了 1,所以如果按日志里有记录得分项来计算,最终三个节点的得分应该是 29,28 和 29。 之所以会出现日志输出的得分和我们自己计算的得分不符的情况,是因为日志并没有输出所有的得分项,猜测漏掉的策略应该是 NodePreferAvoidPodsPriority,这个策略的权重是 10000,每个节点得分 10,所以才得出最终日志输出的结果。 结束语 在本文中,我们以一个简单的容器化 web 程序为例,着重分析了客户端怎么样通过 Kubernetes 集群 API Server 认证,以及容器应用怎么样被分派到合适节点这两件事情。 在分析过程中,我们弃用了一些便利的工具,比如 kubectl,或者控制台。我们用了一些更接近底层的小实验,比如拆解 KubeConfig 文件,再比如分析调度器日志来分析认证和调度算法的运作原理。希望这些对大家进一步理解 Kubernetes 集群有所帮助。 架构师成长系列直播 “阿里巴巴云原生关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术圈。”

优秀的个人博客,低调大师

蚂蚁金服万级规模 K8s 集群管理系统如何设计?

作者 | 蚂蚁金服技术专家 沧漠 关注『阿里巴巴云原生』公众号,回复关键词“1024”,可获取本文 PPT。 前言 Kubernetes 以其超前的设计理念和优秀的技术架构,在容器编排领域拔得头筹。越来越多的公司开始在生产环境部署实践 Kubernetes,在阿里巴巴和蚂蚁金服 Kubernetes 已被大规模用于生产环境。Kubernetes 的出现使得广大开发同学也能运维复杂的分布式系统,它大幅降低了容器化应用部署的门槛,但运维和管理一个生产级的高可用 Kubernetes 集群仍十分困难。本文将分享蚂蚁金服是如何有效可靠地管理大规模 Kubernetes 集群的,并会详细介绍集群管理系统核心组件的设计。 系统概览 Kubernetes 集群管理系统需要具备便捷的集群生命周期管理能力,完成集群的创建、升级和工作节点的管理。在大规模场景下

优秀的个人博客,低调大师

Rancher + VMware PKS实现全球数百站点的边缘K8S集群管理

Sovereign Systems是一家成立于2007年的技术咨询公司,帮助客户将传统数据中心技术和应用程序转换为更高效的、基于云的技术平台,以更好地应对业务挑战。曾连续3年提名CRN,并且在2012年到2016年均被评为美国增长最快的私营公司之一。 本文由Sovereign Systems的解决方案架构师Chip Zoller根据客户的使用案例撰写而成 Rancher是一个容器编排管理平台,它已经在这一领域深耕几年并且具备很多简单易用的实用功能。近几年,它经过重构已经完全拥抱Kubernetes。在本文中,我将着重介绍如何在VMware Enterprise PKS之上构建一个企业级、高可用和安全的Rancher Server安装。同时,我将回答“为什么要在PKS上使用Rancher”这一问题。此外,本文将包括整个构建流程、架构以及完整的安装指南。涉及的内容十分丰富,赶紧开始吧! 把Rancher部署在PKS上? 我知道这并不是一个普遍的搭配,特别是这两个解决方案还存在某种竞争关系。它们都能够在不同的云提供商部署Kubernetes集群,并可以在本地部署到诸如vSphere之类的堆栈。它们分别都有自己的长处和短处,但是在管理空间中两者没有重叠的地方。Enterprise PKS使用BOSH部署Kubernetes集群,并且继续将其用于生命周期的事件——扩展、修复、升级等。而Rancher则是将自己的驱动程序用于各种云PaaS解决方案,甚至使用vSphere进行本地部署来执行类似的任务。但Rancher能够导入外部配置的集群并且为其提供可见性,至今PKS还没有实现这样的功能。而在VMware 2019大会上,VMware宣布推出一款名为Tanzu Mission Control的产品,该产品在未来或许能实现Rancher现有的这些功能。但是,在那之前,Rancher依旧代表着优秀的技术,它可以管理并且聚合不同的Kubernetes集群到单一的系统中。 这个案例从何而来? 和我之前写过的很多文章一样,这篇文章也是从客户项目中衍生出来的。而且由于找不到关于这个主题的Enterprise PKS指南,我决定自己写一个。这个客户计划使用裸机、小型硬件将在边缘的Kubernetes部署到全球数百个站点。他们需要将所有集群统一到一个工具中,从而方便管理、监控以及应用程序部署。他们在主要的数据中心运行Enterprise PKS,来为其他业务需求部署Kubernetes集群。由于这些站点都与他们在世界各地的各个数据中心相连接,因此它们需要聚集在一个可以在本地运行的工具中,同时必须具有高可用性、安全性和高性能。将Enterprise PKS用于底层、专用的Kubernetes集群,然后在该集群上以HA模式在Rancher Server上分层,这样操作为我们两个方面的绝佳功能——通过NSX-T进行网络和安全性,通过BOSH进行集群生命周期维护,通过Harbor复制镜像仓库并且通过Rancher在边缘范围内对分散的Kubernetes集群在单一窗格进行统一管理。 架 构 我们先来看看架构图。 理论上说,我们在底部有一个vSphere栈,它在我们本地的SDDC中托管这个环境。接下来,我们通过PKS构建了一个3-master和3-worker的Kubernetes集群。除了许多其他系统容器(未在上图显示)之外,worker还托管Rancher pod和Nginx pod。基于以上,我们使用NSX-T提供的负载均衡器来提供两个主要虚拟的服务器:一个用于控制平面访问,另一个用于ingress访问。 然而,经过反复的试验并最终失败之后,我发现NSX-T的L7负载均衡器并不支持Rancher正常运行所需的必要请求头。具体来说,Rancher需要在HTTP请求中传递4个请求头到pod。这些请求头用于识别入站请求的来源,并确保在应用程序外部已经发生适当的TLS终止。其中一个请求头X-Forwarded-Proto,它可以告诉Rancher用于与负载均衡器进行通信的协议,但NSX-T的负载均衡器无法传递这些请求头。基于此,我们必须使用第三方ingress controller——nginx,它是目前最流行的解决方案之一,它对大部分的客户端选项提供了广泛的支持,并且可以直接发送请求头。 我们接着往下一个层次看,进入Kubernetes内部(如下图所示)。请记住,我们正在专门研究worker,但正在抽象化诸如节点之类的物理层。 外部请求通过Nginx controller中的LoadBalance服务类型进入集群。从该服务构建的端点列表中选择一个nginx controller,进而匹配ingress controller中的规则。该请求将转发到Rancher Service,最后到与该服务上的标签selector匹配的pod。 我们接下来一步一步完成安装过程,看完之后你将会有更深的理解。 安 装 请记住上文提到的架构,我们将开始将这些碎片拼在一起。一共有6个大步骤,每个步骤下都有详细的小步骤,我会详细说明。 1、 配置新的自定义PKS集群 第一步,我们将专门为Rancher制定一个plan,然后构建一个专门用于在HA模式下运行Rancher的集群。我们还将制作一个自定义的负载均衡器配置文件,以供构建中参考。 2、 使用Helm准备集群 集群构建完成之后,我们需要进行准备,以便可以使用Helm的软件包,因为我们将使用它来安装ingress controller和Rancher。 3、 生成证书和secret 这是一个企业级的部署,这意味着要使用自定义证书。所以我们需要创建那些证书并且使它们可供Kubernetes的各种API资源使用。 4、 创建并配置Ingress 既然我们无法使用NSX-T作为Ingress controller,那么我们必须配置另一种类型并适当地配置它。然后我们将使用一个NSX-T的Layer-4负载均衡器来发送流量到ingress。 5、 安装Rancher 接下来,我们使用Helm安装Rancher。 6、 配置基础架构 一切都就位之后,我们需要执行一些部署后的配置任务,然后才完成所有的步骤。 接下来,我将详细解释每一个步骤具体如何操作。 配置新的自定义PKS集群 首先我们需要做的是设置PKS基础架构,以便我们可以将Kubernetes集群部署在任意地方。需要做两件最基础的事情:创建一个新plan,创建中型负载均衡器。我们的plan需要指定3个master以使控制平面级别高可用,并且3个worker在工作负载级别高可用。在本例中,由于我们正在准备将大量集群安装到Rancher中,因此我们可能要继续进行操作,并指定一个中型负载均衡器,否则PKS会给我们一个很小的负载均衡器。这个负载均衡器将为控制平面/API访问提供虚拟服务器并将traffic发送到Rancher。 在PKS tile中,我使用以下配置创建一个新plan。 根据你自己的需求来创建plan,但记住master和worker的数量。如果想要将其放入生产环境中,我建议你增加master永久磁盘的规格。既然每个主节点都是一个包含控制平面组件和etcd的组合节点,并且Rancher将充分利用Kubernetes集群的etcd安装作为其数据存储,因此我们要确保有足够的空间。 你可以使用底部的附加组件部分来自动加载任意Kubernetes Manifest,使其可以在集群构建过程中运行。我将使用pks-dns,它可以在控制平面启动后自动为其创建DNS记录。如果你之前尚未使用过,我强烈建议你试用一下。 最后,为了让Rancher agent能够正确运行,请务必在此集群上启动“允许特权”模式。 现在,使用之前保存的plan和提交的更改,你应该能够运行一个pks plans并且显示这个新的plan。 $ pks plans Name ID Description dev-small 8A0E21A8-8072-4D80-B365-D1F502085560 1 master; 2 workers (max 4) dev-large 58375a45-17f7-4291-acf1-455bfdc8e371 1 master; 4 workers (max 8) prod-large 241118e5-69b2-4ef9-b47f-4d2ab071aff5 3 masters; 10 workers (20 max) dev-tiny 2fa824527-318d-4253-9f8e-0025863b8c8a 1 master; 1 worker (max 2); auto-adds DNS record upon completion. rancher fa824527-318d-4253-9f8e-0025863b8c8a Deploys HA configuration with 3 workers for testing Rancher HA builds. 有了这个,我们现在可以创建一个自定义负载均衡器plan。目前,实现这个方法的唯一方式是通过pks CLI工具或通过创建自定义JSON规范文件创建API。保存一下信息到名为lb-medium.json.的文件中,根据自己的需求替换“name”和”description”的值。 { "name": "lb-medium", "description": "Network profile for medium NSX-T load balancer", "parameters": { "lb_size": "medium" } } 运行以下命令来创建一个新的网络配置文件: $ pks create-network-profile lb-medium.json 再次检查,确保plan是存在的。 $ pks network-profiles Name Description lb-medium Network profile for medium NSX-T load balancer 现在使用你的plan和中型负载均衡器创建一个新的PKS集群。 $ pks create-cluster czpksrancher05 -e czpksrancher05.sovsystems.com -p rancher --network-profile lb-medium 构建集群将会花费几分钟的时间,可以趁机休息一下。你可以监视集群创建过程,以了解什么时候创建完成。 $ watch -n 5 pks cluster czpksrancher05 Every 5.0s: pks cluster czpksrancher05 Name: czpksrancher05 Plan Name: rancher UUID: 3373eb33-8c8e-4c11-a7a8-4b25fe17722d Last Action: CREATE Last Action State: in progress Last Action Description: Instance provisioning in progress Kubernetes Master Host: czpksrancher05.sovsystems.com Kubernetes Master Port: 8443 Worker Nodes: 3 Kubernetes Master IP(s): In Progress Network Profile Name: lb-medium 集群创建完成之后,如果你之前使用了我推荐的pls-dns工具,那么你的DNS记录现在也应该已经创建好了。 $ nslookup czpksrancher05 Server: 10.10.30.13 Address: 10.10.30.13#53 Name: czpksrancher05.sovsystems.com Address: 10.50.0.71 现在,所有必要的工作都完成了,我们可以访问这个集群。首先让我们先配置kubeconfig。 $ pks get-credentials czpksrancher05 然后确认我们是否具有访问权限。 $ kubectl cluster-info Kubernetes master is running at https://czpksrancher05.sovsystems.com:8443 CoreDNS is running at https://czpksrancher05.sovsystems.com:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy 使用Helm准备集群 既然现在我们已经可以访问我们的集群,我需要使用Helm来准备它。Helm是一个用chart的打包格式来将整个应用程序部署到Kubernetes的一个工具。这些chart打包了完整部署应用程序所需的各种Kubernetes manifest。网络上已经有大量的文章介绍了Helm及其入门,所以我将不再赘述。我假设你已经了解了这些,并将Helm二进制文件添加到了PATH中。我们需要在Kubernetes创建一个必要的对象,以供Tiller(Helm的服务器端组件)运行。这包括了一个ServiceAccount、ClusterRoleBinding,然后初始化Helm。 $ kubectl -n kube-system create serviceaccount tiller serviceaccount/tiller created 创建Tiller帐户的绑定作为集群管理员。当你完成安装之后,你就可以解除绑定了。通常来说,绑定service account到集群管理员角色并不是一个好主意,除非它们真的需要集群范围的访问。如果你想的话,可以限制Tiller部署到单个命名空间中。幸运的是,在Helm3中将不会有Tiller,这将进一步简化Helm chart的部署并提高了安全性。 $ kubectl create clusterrolebinding tiller --clusterrole cluster-admin --serviceaccount=kube-system:tiller clusterrolebinding.rbac.authorization.k8s.io/tiller created 接下来,使用service account初始化Helm,这将在kube-system命名空间创建一个Tiller pod。 $ helm init --service-account tiller $HELM_HOME has been configured at /home/chip/.helm. Tiller (the Helm server-side component) has been installed into your Kubernetes Cluster. 你现在应该能够检查并看到一个新的Tiller pod已经创建完成并且正在运行。 $ kubectl -n kube-system get po -l app=helm NAME READY STATUS RESTARTS AGE tiller-deploy-5d6cc99fc-sv6z6 1/1 Running 0 5m25s helm version要能确保客户端的helm二进制文件能够与新创建的Tiller pod通信。 $ helm version Client: &version.Version{SemVer:"v2.14.3", GitCommit:"0e7f3b6637f7af8fcfddb3d2941fcc7cbebb0085", GitTreeState:"clean"} Server: &version.Version{SemVer:"v2.14.3", GitCommit:"0e7f3b6637f7af8fcfddb3d2941fcc7cbebb0085", GitTreeState:"clean"} 第二个步骤就完成,接下来我们需要做一些证书工作。 生成证书和secret 现在,我们不得不创建我们的自定义证书并使它们可供Kubernetes使用。在本例中,我使用由内部企业证书颁发机构(CA)签名的证书,但是你可以只使用由第三方根签名的通用证书。Rancher可以使用以上两种证书,也可以使用自签名证书。由于这是一个企业级部署,我们需要一个已经建立的信任链,因此我们将使用企业CA。 创建证书的过程可能会有所不同,因此我无法一一列出所有情况,我只会简单介绍与本例所需证书创建和生成过程相同的证书。但是无论如何,我们都需要一个主机名,通过它可以访问集群中运行的Rancher应用程序。不要将之前我们在创建PKS集群时使用的外部主机名混淆,它们时两个单独的地址,并且作用也不一样。我将这个Rancher安装命名为“czrancherblog”,以便正确地生成并签名我的证书。 通过Internet的魔力,我们可以快速完成生成过程,直到获得证书,secret和根CA证书文件。 确保运行kubectl的系统可以访问这些文件,然后继续。 我们将为Rancher创建一个新的命名空间,在命名空间内,我们需要创建2个secret:一个用于签署我们的主机证书的根CA证书,以及实际生成的证书及其对应的私钥。 $ kubectl create ns cattle-system namespace/cattle-system created 在创建第一个secret之前,确保根CA证书命名为cacerts.pem,必须准确地使用这个名字,否则Rancher pod将启动失败。 $ kubectl -n cattle-system create secret generic tls-ca --from-file=cacerts.pem secret/tls-ca created 接下来,创建TLS secret,该secret将保存czrancherblog站点的主机证书。此外,在下一步创建的nginx ingress controllerPod也会需要这个secret,以便正确认证客户请求。 $ kubectl -n cattle-system create secret tls czrancherblog-secret --cert=czrancherblog.cer --key=czrancherblog.key secret/czrancherblog-secret created 验证已经创建的两个secret $ kubectl -n cattle-system get secret NAME TYPE DATA AGE czrancherblog-secret kubernetes.io/tls 2 2m7s default-token-4b7xj kubernetes.io/service-account-token 3 5m1s tls-ca Opaque 1 3m26s 你会注意到,创建了这些secret,实际上只是创建两种不同类型的secret而已。tls-ca这个secret是Opaque类型的secret,而czrancherblog-secret是一个TLS secret。如果你两相比较,你会注意到tls-ca secret会在数据部分为cacerts.pem列出一个base64-encoded 证书。而czrancherblog-secret将会列出其中的两个,每个文件分配一个。你同时还会注意到无论你提供哪种输入文件,都已经为tls.crt和tls.key列出它们的值(经过base64编码以使它们模糊之后)。 现在我们已经完成证书的生成了,现在应该到nginx ingress的部分。 创建和配置Ingress 既然secret和命名空间都已经创建,现在让我们来安装nginx-ingress controller。如上文所提到的,尽管Enterprise PKS可以并且将使用NSX-T作为现成的Ingress controller,但是Rancher有些特殊需求是这一controller无法满足的。因此在这一情况下,我们将使用其他的controller。Nginx有一个被广泛使用并且技术成熟的ingress controller,恰好符合我们的需求。请注意在本例中,我使用的是kubernetes/ingress-nginx,而不是nginxinc/Kubernetes-ingress。尽管它们有些许差异,但其实在本例中两者都能使用。 在您的终端上,运行以下Helm命令以从稳定版本中安装kubernetes / ingress-nginx controller: helm install stable/nginx-ingress --name nginx --namespace cattle-system --set controller.kind=DaemonSet 在这个命令中,我们让Helm把nginx对象放入cattle-system命名空间中,并且将pod作为DaemonSet而不是Deployment来运行。我们希望每个Kubernetes节点都有一个controller,进而节点故障不会消除通往Rancher Pod的入口数据路径。Rancher将完成类似的任务,但将使用具有pod反关联规则的deployment(这与vSphere DRS的工作原理相似)。 命令完成之后,你将会从Helm获得一连串的返回,包括所有它创建的对象。需要指出的是,几个API对象是ConfigMap,它存储nginx controller的配置以及服务。 ==> v1/Service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-nginx-ingress-controllern LoadBalancer 10.100.200.48 <pending> 80:32013/TCP,443:32051/TCP 0s nginx-nginx-ingress-default-backend ClusterIP 10.100.200.45 <none> 80/TCP 0s 第一个称为nginx-nginx-ingress-controller的类型为LoadBalancer。从应用程序的角度来看,这实际上将是Rancher集群的切入点。如果你看到External-IP栏,你将会注意到它最初只报告了<pending>状态。这时候需要给你的Kubernetes集群一些时间来拉取镜像,然后再次检查命名空间的服务。 # kubectl -n cattle-system get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-nginx-ingress-controller LoadBalancer 10.100.200.48 10.50.0.79,100.64.128.125 80:32013/TCP,443:32051/TCP 6m35s nginx-nginx-ingress-default-backend ClusterIP 10.100.200.45 <none> 80/TCP 6m35s 这一次,你将会发现它分配了两个IP,因为NSX容器插件(NCP)注意到该对象的创建,并已与NSX-T进行通信,以使用为此集群指定的中型负载均衡器为我们创建新的虚拟服务器。 如果你跳到NSX-T管理器界面中的Server Pool选项卡,并找到此处引用的选项卡,那么可以检查Pool Member选项卡,并查看它已自动添加了该服务引用的端点。 Name栏被截断了,但是IP栏依旧可见。让我们再次检查一下Kubernetes。 $ kubectl -n cattle-system get po -o wide -L app NAME READY IP NODE APP nginx-nginx-ingress-controller-wjn2x 1/1 10.11.54.2 9aa90453-2aff-4655-a366-0ea8e366de4a nginx-ingress nginx-nginx-ingress-controller-wkgms 1/1 10.11.54.3 f35d32a0-4dd3-42e4-995b-5daffe36dfee nginx-ingress nginx-nginx-ingress-controller-wpbtp 1/1 10.11.54.4 e832528a-899c-4018-8d12-a54790aa4e15 nginx-ingress nginx-nginx-ingress-default-backend-8fc6b98c6-6r2jh 1/1 10.11.54.5 f35d32a0-4dd3-42e4-995b-5daffe36dfee nginx-ingress 输出的内容被稍微修改了一点点,去除了不必要的栏,但除了正在运行的节点之外,你还可以清晰地看到pod、它们的状态以及IP地址。 有了新虚拟服务器的IP地址,我们接下来需要创建一个DNS记录,可以与我们的Rancher HA安装的主机名对应。我决定将其命名为“czrancherblog”,因此我将在DNS中创建一个A记录,将在czrancherblog指向10.50.0.79。 $ nslookup czrancherblog Server: 10.10.30.13 Address: 10.10.30.13#53 Name: czrancherblog.sovsystems.com Address: 10.50.0.79 这一阶段的最后一步是在Kubernetes上创建ingress controller。尽管我们已经有LoadBalancer这一服务类型,我们依旧需要ingress资源来路由流量到Rancher service。但该服务尚不存在,但很快就可以创建。 使用以下代码创建一个新的manifest,命名为ingress.yaml,并且使用kubectl create -f ingress.yaml对其进行应用: apiVersion: extensions/v1beta1 kind: Ingress metadata: annotations: kubernetes.io/ingress.class: nginx namespace: cattle-system name: rancher-ingress spec: rules: - host: czrancherblog.sovsystems.com http: paths: - backend: serviceName: rancher servicePort: 80 tls: - hosts: - czrancherblog.sovsystems.com secretName: czrancherblog-secret 现在我来解释一下这个manifest。首先,我们的类型是Ingress,接下来我们有一个注释。这一行实际上在做两件事:指示NCP不要告诉NSX-T创建和配置任何对象,并告诉Nginx controller将流量路由到端口80上尚未创建的名为rancher的服务。最后,当来自主机值为czrancherblog.sovsystems.com的请求中的任何流量进入系统时,它使用我们创建的包含证书及密钥的TLS secret应用到controller上。 尽管我们希望不会出错,但是我们仍然要将该地址放入网络浏览器中,以查看返回的内容。 我们将获得一些重要的信息。首先,非常明显的大字“503 Service Temporarily Unavailable”,考虑到目前尚无流量经过nginx controller,这样的返回结果是符合期望的。其次, 在地址栏我们看到了一个绿色锁的图标,这意味着我们创建的包含证书的TLS secret已经被接受并且应用于主机规则。 到目前为止,都在向预想的方向进行,让我们进行下一步。 安装Rancher 终于到了期待已久的一刻——安装Rancher。现在我们一切都准备好了,开始安装吧! 添加Rancher stable仓库到Helm,然后进行更新并拉取最新chart。 $ helm repo add rancher-stable https://releases.rancher.com/server-charts/stable "rancher-stable" has been added to your repositories $ helm repo list NAME URL stable https://kubernetes-charts.storage.googleapis.com local http://127.0.0.1:8879/charts rancher-stable https://releases.rancher.com/server-charts/stable $ helm repo update Hang tight while we grab the latest from your chart repositories... ...Skip local chart repository ...Successfully got an update from the "rancher-stable" chart repository ...Successfully got an update from the "stable" chart repository Update Complete. 为什么在安装nginx ingress之前我们不需要添加一个仓库呢?因为那个chart实际上来自由谷歌托管的默认”stable”仓库,因此没有自定义仓库可以添加。对于Rancher,我们必须添加stable或latest仓库以访问其管理的chart。 如果你已经成功更新了,那么赶紧激活Rancher吧。从stable repo中安装最新的chart,并检查输出。 $ helm install rancher-stable/rancher --name rancher --namespace cattle-system --set hostname=czrancherblog.sovsystems.com --set ingress.tls.source=secret --set privateCA=true NAME: rancher LAST DEPLOYED: Sun Sep 8 18:11:18 2019 NAMESPACE: cattle-system STATUS: DEPLOYED RESOURCES: ==> v1/ClusterRoleBinding NAME AGE rancher 1s ==> v1/Deployment NAME READY UP-TO-DATE AVAILABLE AGE rancher 0/3 0 0 1s ==> v1/Pod(related) NAME READY STATUS RESTARTS AGE rancher-6b774d9468-2svww 0/1 ContainerCreating 0 0s rancher-6b774d9468-5n8n7 0/1 Pending 0 0s rancher-6b774d9468-dsq4t 0/1 Pending 0 0s ==> v1/Service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE rancher ClusterIP 10.100.200.15 <none> 80/TCP 1s ==> v1/ServiceAccount NAME SECRETS AGE rancher 1 1s ==> v1beta1/Ingress NAME HOSTS ADDRESS PORTS AGE rancher czrancherblog.sovsystems.com 80, 443 1s NOTES: Rancher Server has been installed. NOTE: Rancher may take several minutes to fully initialize. Please standby while Certificates are being issued and Ingress comes up. Check out our docs at https://rancher.com/docs/rancher/v2.x/en/ Browse to https://czrancherblog.sovsystems.com Happy Containering! 很好,现在chart为我们部署了大量的Kubernetes对象。然而,注意一下最后一个对象,它是另一个ingress。我们不需要它,所以直接将其删除。 $ kubectl -n cattle-system delete ing rancher ingress.extensions "rancher" deleted 检查pod以确保它们现在正在运行。 $ kubectl -n cattle-system get po -l app=rancher NAME READY STATUS RESTARTS AGE rancher-6b774d9468-2svww 1/1 Running 2 5m32s rancher-6b774d9468-5n8n7 1/1 Running 2 5m32s rancher-6b774d9468-dsq4t 1/1 Running 0 5m32s 非常棒,一切都起来了。如果你在RESTARTS列中看到的值不是零,也不要惊慌,Kubernetes最终会与其controller和监控循环保持一致,因此只要采取适当的措施,就可以使得实际状态达到所需状态为止。 现在,这些工作都完成之后,让我们再次检查我们的网页,看看发生了什么。 正如我们所希望的那样,我们现在进入我们的Rancher集群了!让我们设置初始密码以及在下一页面中设置server URL。如果不进行设置,它将自动填充我们的主机名。 这一步骤就算完成啦,接下来让我们进入最后一步。 配置基础架构 既然我们已经让一切都起来了并且正在运行,让我们做些事情。 首先,你可能已经注意到你的“local”集群卡在Provisioning的状态,正在等待设置主机名。通常这几分钟之后就会自动解决,但在本例中,则需要执行几个简单的步骤。 最快的修复步骤是点击最右边的设置按钮来编辑这个集群。 现在不做任何更改,直接点击保存。 然后回到主页,它应该已经起来了。 再次进入集群,确保你的节点正在汇报状态。 接下来,我们需要在主机之间分配我们的基础PKS Kubernetes节点。如果你的plan包括多个可用空间,你可能已经完成这一步了。但如果你像我一样,没有多个可用空间,你将需要某种方法来确保你的master和你的worker分布在ESXi主机上。如果你听说过我的Optimize-VMwarePKS项目,我强烈建议你使用它,该项目可以自动为你处理master,但我们依旧需要手动把worker分开。请记住,我们不仅需要API和控制平面的高可用,我们也需要Rancher 数据平面的高可用。这意味着任何管理程序的故障都不会影响我们应用程序的可访问性。 你使用-ProcessDRSRules标志运行Optimize-VMware-PKS之后,它应该检测到该集群的master并创建DRS反关联性规则。现在,你需要为worker节点手动创建一个新的节点。 为worker创建一个新的反关联规则,并添加所有规则。由于BOSH会使用UUID而不是实际名称来部署它们,因此在列表中找到它们十分困难,但是你可以在vSphere VM和模板清单视图中找到它们(如果你使用-ProcessDRSRules标志运行Optimize-VMware-PKS),或者你可以在引用部署后,从BOSH CLI获取名称。 $ bosh -d service-instance_3373eb33-8c8e-4c11-a7a8-4b25fe17722d vms Using environment 'czpcfbosh.sovsystems.com' as client 'ops_manager' Task 55540. Done Deployment 'service-instance_3373eb33-8c8e-4c11-a7a8-4b25fe17722d' Instance Process State AZ IPs VM CID VM Type Active master/00be5bab-649d-4226-a535-b2a8b15582ee running AZ1 10.50.8.3 vm-a8a0c53e-3358-46a9-b0ff-2996e8c94c26 medium.disk true master/1ac3d2df-6a94-48d9-89e7-867c1f18bc1b running AZ1 10.50.8.2 vm-a6e54e16-e216-4ae3-8a99-db9100cf40c8 medium.disk true master/c866e776-aba3-49c5-afe0-8bf7a128829e running AZ1 10.50.8.4 vm-33eea584-ff26-45ed-bce3-0630fe74f88a medium.disk true worker/113d6856-6b4e-43ef-92ad-1fb5b610d28d running AZ1 10.50.8.6 vm-5508aaec-4253-4458-b2de-26675a1f049f medium.disk true worker/c0d00231-4afb-4a4a-9a38-668281d9411e running AZ1 10.50.8.5 vm-e4dfc491-d69f-4404-8ab9-81d2f1f4bd0d medium.disk true worker/ff67a937-8fea-4c13-8917-3d92533eaade running AZ1 10.50.8.7 vm-dcc29000-16c2-4f5a-b8f4-a5420f425400 medium.disk true 6 vms Succeeded 无论你选择哪种方法,只要能保证规则创建即可。 现在你已经有了master和worker的反关联规则,那么请确保你在多个方面都具备高可用性。如果你愿意进行测试,那么让工作节点(或与此相关的主节点)发生故障,或删除Rancher Pod,然后查看Kubernetes创建的新pod。此时,Rancher应该还保持工作状态。 结 语 你已经看到了我们如何从零开始创建了一个具备高可用性以及完整功能的Rancher Server,并且你也应该采取了一些措施确保将其安全地分布在底层架构上。你需要牢记一个重要的考虑因素:当在Enterprise PKS上运行Rancher的时候,与Kubernetes命名空间有关。当在Kubernetes上安装Rancher时,通过创建CRD和其他对象,Rancher从平台的角度将与Kubernetes深度集成。当用户创建一个新项目或导入一个新集群时,Kubernetes将会在后台创建一个新的命名空间。在其他Kubernetes环境中,这样的操作流程会非常完美,但在Enterprise PKS中,一个新的命名空间则意味着新的Tier-1 router、新的逻辑网段、新的pod IP块等。在PKS没有预先设置好的情况下,如果大量导入集群和创建项目,那么这些命名空间很快会耗尽诸如pod IP块之类的NSX-T对象。如果你正在考虑在生产环境中采用这样的架构,那么需要牢记这一点。现在,无法告诉NCP忽略这些命名空间创建命令,因此它不会在NSX-T内部生成对象。

优秀的个人博客,低调大师

CNCF 发布 K8s 项目历程报告,35k 贡献者有你吗?

云原生计算基金会 CNCF 首次发布了Kubernetes 项目历程报告。 Kubernetes 托管于 CNCF,它是目前使用最广泛的容器编排平台,通常被称为“云端 Linux”,CNCF 介绍此报告旨在客观地评估 Kubernetes 项目的状态以及 CNCF 如何影响 Kubernetes 的发展和增长。 Kubernetes 项目的首次 commit 发生在 2014 年 6 月 6 日,自 2016 年 3 月 10 日加入 CNCF,到目前为止,Kubernetes 共有 35k contributor 做了 110 万次贡献、148k 次 commit 与 83k PR,并且有超过2000 家公司参与贡献开源。 数据显示,目前在参与贡献的公司中,排名前两位的是 Google 和 Red Hat。三年前 Kubernetes 加入 CNCF 之前,两家公司所做贡献占了所有贡献的 83%,目前占比为 35%,这是整个生态在发展的原因,因为有越来越多人参与进来贡献,稀释了份额,但两家公司的贡献量仍然在不断增加。 值得注意的是,国内的华为贡献量排在第 4 位。 公司的累计贡献量 公司贡献占比 贡献者方面,从 Kubernetes 项目诞生开始,就有大约 20 名积极参与的开发人员参与贡献,而今天已经有超过 3000 位活跃贡献者,自创立以来增加超过 14000%。 这些贡献者来自数十个国家,其贡献的地理多样性随着时间的推移而不断扩大。在 Kubernetes 的整个生命周期中,11 个国家里平均有超过10 个贡献者。下图显示了按时间划分的贡献数量以及按国家/地区划分的贡献者的百分比。 我们可以看到,中国在这些贡献数据中有不错的成绩。 Kubernetes 是历史上发展得极快的开源软件项目,并且它的发展速度越来越快,从下边这些增长数据可以看得出来这一点。 CNCF 还表示,这是首次发布该系列报告,其将专注于已毕业项目,所以接下来应该会陆续有其它 CNCF 项目历程报告出炉。 报告详情查看:https://www.cncf.io/cncf-kubernetes-project-journey

优秀的个人博客,低调大师

云原生生态周报 Vol. 15 | K8s 安全审计报告发布

业界要闻 CNCF 公布 Kubernetes的安全审计报告,报告收集了社区对 Kubernetes、CoreDNS、Envoy、Prometheus 等项目的安全问题反馈,包含从一般弱点到关键漏洞。报告帮项目维护人员解决已识别的漏洞,并给出了一系列最佳实践。 技术监督委员会(TOC)已投票决定将 rkt 项目归档。尽管rkt 在2014年12月创建后最初很受欢迎,并在2017年3月贡献给CNCF,但其采纳程度已严重下降,很多用户已经从rkt转向了如containerd、CRI-O等其它项目。 上游重要进展 Kubernetes 项目 支持readonly的接口指定不同的网卡 https://github.com/kubernetes/enhancements/issues/1208 在Kubectl中进行pod问题定位分析: https

优秀的个人博客,低调大师

K8S从懵圈到熟练:读懂这一篇,集群节点不下线

排查完全陌生的问题,完全不熟悉的系统组件,是售后工程师的一大工作乐趣,当然也是挑战。今天借这篇文章,跟大家分析一例这样的问题。排查过程中,需要理解一些自己完全陌生的组件,比如systemd和dbus。但是排查问题的思路和方法基本上还是可以复用了,希望对大家有所帮助。 问题一直在发生 I'm NotReady 阿里云有自己的Kubernetes容器集群产品。随着Kubernetes集群出货量的剧增,线上用户零星的发现,集群会非常低概率地出现节点NotReady情况。据我们观察,这个问题差不多每个月,就会有一两个客户遇到。在节点NotReady之后,集群Master没有办法对这个节点做任何控制,比如下发新的Pod,再比如抓取节点上正在运行Pod的实时信息。 需要知道的Kubernetes知识 这里我稍微补充一点Kubernetes集群的基本知识

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册