Serverless 可观测性的过去、现在与未来

alicloudnative阅读(2015)评论(0)

头图.png

作者 | 孔德慧(夏莞)
来源 | 阿里巴巴云原生公众号

背景

1. Serverless 将成为下一个十年云的默认编程范式

随着 Serverless 概念的进一步普及,开发者逐渐从观望状态进入尝试阶段,越来越多的企业用户开始将业务迁移到 Serverless 平台。在阿里集团内部,淘宝、飞猪、闲鱼、高德、语雀等核心功能稳步落地,在阿里集团外部,新浪微博、世纪联华、石墨文档、TPLink、蓝墨云班课等各行各业的企业也纷纷解锁 Serverless 使用的不同场景。Serverless 正在成为成为下一个十年云的默认编程范式。

更多案例请参考 函数计算用户案例

Serverless 降本增效免运维的特性为开发者带来了实打实的好处:基于函数计算的 Serverless 方案为蓝墨节省了 60% 左右的 IT 成本,为石墨文档节约了 58% 的服务器成本;提升码隆科技的开发效率,实现两周内功能上线;平稳支撑负载的波峰波谷相差 5 倍以上的新浪微博,每天轻松处理数十亿请求。

2. 可观测性成为 Serverless 发展的绊脚石?

随着 Serverless 的深入使用,开发者逐渐发现 Serverless 架构下的问题定位比传统应用更加困难,主要原因如下:

  • 组件分布化:Serverless 架构的应用往往粘合多个云服务,请求需要流经多款云产品,一旦端到端延时变长或表现不符合预期,问题定位十分复杂,需要依次去各个产品侧逐步排查。
  • 调度黑盒化:Serverless 平台承担着请求调度、资源分配的责任,实时弹性扩容会带来不可避免的冷启动,Serverless 的资源伸缩是无需开发者参与也不受开发者控制的。冷启动会影响端对端延时,这次请求有没有遇到冷启动,冷启动的时间都消耗在哪些步骤,有没有可优化的空间都是开发者急于知道的问题。
  • 执行环境黑盒化:开发者习惯于在自己的机器上执行自己的代码,出了问题登录机器查看异常现场,查看执行环境的 CPU/内存/IO 情况。面对 Serverless 应用,机器不是自己的,登也登不上,看也看不了,开发者眼前一片漆黑。
  • 产品非标化:在 Serverless 场景下,开发者无法控制执行环境,无法安装探针,无法使用开源的三方监控平台,调查问题的方式不得不发生改变,传统的调查问题经验无法施展,非常不顺手。

函数计算是阿里云的 Serverless 产品,在过去的一年,函数计算团队为了更好地回答以上问题做了很多努力。

本文主要介绍函数计算在可观测性上的尝试与函数计算可观测性现状。

Serverless 下可观测性

可观测性是通过外部表现判断系统内部状态的衡量方式。
–维基百科

在应用开发中,可观测性帮助我们判断系统内部的健康状况。在系统平稳运行时,帮助我们评估风险,预测可能出现的问题。当系统出现问题时,帮助我们快速定位问题,及时止损。

一个好的可观测性系统要帮助用户尽可能快地发现问题、定位问题并且端到端地解决问题。

在 Serverless 这种免运维的平台体系中,可观测性是开发者的眼睛,没有可观测,何谈高可用?

1. 可观测性 1.0

1.png
图1 -可观测性基础

可观测性主要包含三个部分:日志、指标、链路追踪。

和几乎所有 FaaS 产品一样,函数计算(FC)在商业化之初就支持了函数日志和指标的查看。

  • 函数日志

用户在 FC 配置 SLS 的 Project 和 Logstore,FC 将函数打到 stdout 的日志转存到用户的 Logstore 中。用户可以通过 SLS 控制台查看函数日志,并借助 SLS 的能力对日志进行分析和聚合。

  • 基本指标

FC 将指标日志推送到云监控,通过云监控提供函数调用数/错误数/函数延时/函数内存等基本指标。

函数日志和基本指标是应用的听诊器,虽然朴素简陋,却也能帮助用户发现问题,定位问题。

即使出现开发者无法排查的问题,在用户量不那么大的年代,开发同学可以为用户提供贴身服务,结合后台日志帮用户定位问题。

函数日志和指标使用详细信息请参考配置并查看函数日志/监控指标

2. 可观测性 2.0 – 云原生的可观测

随着 Serverless 的发展,越来越多的场景在 Serverless 落地,使用规模越来越大,产品架构越来越复杂,应用听诊器的可观测性 1.0 已经不能满足各行各业开发者的监控诉求。这种近乎黑盒的执行环境给开发者带来了强烈的距离感与不信任感。开发者需要掌控自己的应用,想要知道每一个请求在函数计算经历了怎样的历程,想要看看端到端的延时长是不是因为冷启动,想要查看函数实例的执行环境,想要在请求出现异常时第一时间定位问题,想要复用熟悉的开源观测平台。

在面对这些需求时,团队内部也经过了长时间的激烈讨论,一部分同学认为我们应该支持这些需求,另一部分同学则认为这些需求某种程度上与 Serverless 本质相违背,Serverless 就是要屏蔽底层的计算资源,用户不需要关心底层计算资源的情况。另一方面我们暴露了这些指标有什么用呢,用户就算看到了有冷启动,看到了系统时间消耗,看到了底层实例的 CPU,用户又不能有任何实质操作,这些指标真的意义吗?这两种观点争论不休,而我,是坚定的反对者。

后来团队搬到了 EFC,每天都要等待着那不知什么时候会来的电梯(输入你要去的楼层,去对应的电梯安静地等待,看不到电梯目前所在楼层),电梯告诉我们,你就在这里等哦,我肯定会来的,但是我现在到了哪层,我什么时候下来你大可不必知道,你知道了也没用,我的这个调度肯定是最优的,你要相信专业电梯的调度算法。可是,我怎么能相信你呢?

于开发者而言,函数计算也是那不知什么时候会来的电梯吧,我们和开发者说您的请求我们一定会稳定执行的,您的执行环境一定很健康,请求过多我们会自动扩容的,但是当前实例的监控指标,我什么时候扩容您大可不必知道,我们的调度肯定是最优的,您要相信专业研发团队的调度算法。同样的,开发者又怎么相信我们呢?

Serverless 的可观测性不单单要帮助开发者排查问题,也要逐步揭开 Serverless 那层神秘的面纱,赢取开发者对 Serverless 的信任。

于是有了函数计算可观测性 2.0,我们希望可观测性 2.0 可以成为应用的心电图。

2.png
图 2 – 函数计算可观测性现状

  • 为了回答请求在函数计算的生命历程,串联分布式系统的上下游服务,拥抱开源可观测能力,我们集成了 OpenTracing,支持链路追踪。
  • 为了暴露系统状态,提供应用级别监控,我们集成了 ARMS(Java),内置了 APM 能力。
  • 为了加快端到端定位问题的速度,我们支持了请求级别指标(FCInsights),发布了监控中心,问题发现/调查一站式解决。
  • 为了兼容开发者已有的用户体验,我们拥抱开源,集成 OpenTracing,支持 Grafana Dashboard;我们支持三方监控平台,实现代码几乎零改造接入APM 监控系统。
  • 为了兼容传统开发者的可观测体验,支持探针安装,我们拓展了编程模型,支持函数 LifeCycle,为集成三方监控提供可能。

3.png
图 3 – 函数计算兼容开源可观测能力

相比于自己发明创造 FaaS 可观测性新体验,函数计算兼容开源可观测能力,集成 Jaeger,支持 Grafana 大盘,也支持以非常小的改动接入 New Relic 等优秀三方监控平台。函数计算是首家兼容开源、拥抱容器生态和云原生开发者的 FaaS 提供商,可观测体验的平滑迁移支撑应用在容器和 Serverless 平台的平滑迁移

1)集成 OpenTracing,支持链路追踪

FC 与链路追踪服务集成,为开发者提供了完整的调用链路还原、调用量统计、链路拓扑分析、冷启动定位等工具。帮助开发者快速分析和诊断分布式架构下的性能瓶颈。

FC 链路追踪具有以下特点:

  • 拥抱开源:完全兼容 OpenTracing 协议,没有附加学习成本。
  • 主动记录:上报请求在函数计算中消耗的端对端时间。
  • 调度透明:暴露代码准备时间与实例启动时间,是首个暴露冷启动延时与具体时间消耗的 FaaS 产品。
  • 承上启下:串起上下游应用,既可以通过 span context 与上游应用连接,又将 span context 传入函数,连接下游服务。

4.png
图 4 – 链路追踪链路示例

5.gif
图 5 – 链路追踪综合能力详情

2)集成 ARMS,内置 APM 能力

FC 无缝对接 ARMS 应用监控,开发者只需为函数新增一个环境变量即可开启 APM 应用监控功能,ARMS 探针以对代码无入侵的方式监测应用性能,提供应用级别的可观测性,包括函数实例的 CPU、内存指标、Java 虚拟机指标、代码 Profiling 信息、SQL 查询等函数实例的指标。

6.gif
图 6 – ARMS 示例

3)发布监控中心(Insights),问题发现调查一站式解决

FC 支持请求级别指标,通过为用户每个请求多打一条指标日志的方式为请求装上摄像头。通过请求级别指标,用户可以清楚地看到请求的执行时间、使用内存,是否异常、错误类型、冷启动情况,traceID 等信息。也可以基于请求级别指标串联起所有的可观测性能力。

监控中心则是 FC 可观测性能力的集大成者,监控中心集成了 Metrics、Logs、Tracing的能力,可以在一个站点完成预览指标、查看日志、分析链路的能力,争取做到问题发现调查一站式解决。

监控中心具有如下特点:

  • 多维度:支持 Region、Service、Function、Qualifier、Request 多维度的指标,展示各个维度下的调用数和错误分布。
  • 多层次:集成 Metrics、Logs、Tracing 的能力,全方位多层次对应用进行监控。
  • 全链路:结合指标、日志、链路等信息,层层递进,抽丝剥茧,真正做到可以在一个站点发现问题,定位问题并解决问题。

7.gif
图 7 – 监控中心示例

4)扩展编程模型,集成三方监控

函数实例的生命周期完全由平台控制,用户无法控制实例的启动与回收,也不感知实例的暂停与重启,这就使得在函数计算上执行除主线程外的背景线程格外困难。监控探针就是诸多重要的背景线程的一种。

FC 扩展了编程模型,发布 RuntimeLifeCycle 功能,Runtime LifeCycle 会监听函数实例生命周期事件,允许函数实例在暂停和回收前回调用户的函数逻辑。这一功能的发布使 FC 集成三方 APM 监控成为可能。用户只需要在实例暂停前将采集的指标发出去、在实例回收前将内存中的数据清理掉就可以在 APM 平台上实时地查看监控指标了。

8.gif
图 8 – Tingyun APM 示例

9.gif
图 9 – NewRelic APM 示例

3. 总结

函数计算可观测性经历了 1.0-> 2.0 的发展,从闭门造车的可观测发展成开源的可观测,从平台的可观测发展为开发者的可观测,从 FaaS Only 的可观测演进成了云原生的可观测。

作为首家兼容开源可观测、拥抱容器生态和云原生开发者的 FaaS 提供商,函数计算也将更有实力实现开发者业务的平滑迁移。

未来规划

FC 可观测性相比于一年前前进了一小步,从黑盒的可观测演进成了微弱烛光的可观测,但距离 “Serverless 应用白盒化” 的目标还有着很长的路要走。我们希望能够兼容开发者的监控体验,支撑着用户平滑地放心地将业务迁到 Serverless 上来。

接下来我们会继续投入做以下事情:

  • 完善监控中心,支持报警配置,预警异常指标。
  • 提供实例级别指标,做到代码问题可定位,环境现场可追溯。
  • 集成开源项目,集成 Prometheus,Opentelemetry,配置 Grafana 大盘。
  • 丰富指标内容,目前还有一些指标是不好透出的,没有暴露的,我们要逐步都暴露出来。

希望函数计算的可观测性成为一盏灯,照亮每一个 Serverless 应用。

广告时间:欢迎加入云原生Serverless 团队(函数计算,Serverless工作流,Serverless应用引擎),以公共云、集团、开源社区三位一体的方式打造业界领先的Serverless 产品体系。职位需求见 JD,招聘长期有效,有兴趣的同学可以发送简历至 dehui.kdh@alibaba-inc.com。

云原生的 WebAssembly 能取代 Docker 吗?

KubeSphere阅读(2204)评论(0)

WebAssembly 是一个可移植、体积小、加载快并且兼容 Web 的全新格式。由于 WebAssembly 具有很高的安全性,可移植性,效率和轻量级功能,因此它是应用程序安全沙箱方案的理想选择。现如今 WebAssembly 已受到容器,功能计算以及物联网和边缘计算社区的广泛关注。究竟 WebAssembly 是怎样的一种技术,能否取代 Docker,就请阅读本文。

本文是整理自 KubeSphere 2020 年度 meetup 中 Second State CEO Michael Yuan 的分享。

大家下午好,我是 Second State 的 CEO Michael Yuan,我们公司的主要研发在台北和美国,然后在北京望京有个办公室。今天非常开心来到 KubeSphere 2020 Meetup,我给大家分享的主题是云原生的 WebAssembly 能取代 Docker 吗?

背景

这是一个著名的 Twitter,是 Docker 的创始人 Solomon Hykes 在 2019 年 3 月份发布的。他说如果2008年的时候,WASM(WebAssembly)和 WASI(WebAssembly System Interface, WASM系统接口)这两个东西已经存在了的话,他就没有必要创立 Docker 了。他认为 WebAssembly 是计算的未来。这条推特在社区里造成很大影响,引发了很多人的的疑问。因为很多人认为,WebAssembly 可以在浏览器里取代 JavaScript,是用来玩游戏的。为什么突然成为在服务端能够取代 Docker 的东西呢?也就在这一年多后,包括我们公司在内,很多人在这里面做了很多 research。

WebAssembly 在服务端的位置

在服务端,我们一般可以把容器、虚拟机或者说运行环境分成三个不同的抽象的层次。

1.在最底层是硬件的 Hypervisor VM,或者说像 AWS Firecracker,这种叫做 microVMs,能够直接跟硬件打交道。

2.再上面一层叫做 Application containers,在这种 vm 上面你可以做像 Docker 这样的 application container。application container 仍然是在操作系统这个层级,是需要把整个操作系统调进来的。

3.再上面一层叫做 High level language VMs ,这是从 Jvm 开始的。然后把 WebAssembly 在操作系统这个层级上面给抽象出来了。这是 WebAssembly 在服务端的位置。

如果 WebAssembly 能够做成一个像 JVM 的 language VM,我们在今天也许能够实现 Java 二十几年前提出的梦想:在不同的操作系统上,在不同的硬件和软件的平台上,能够给开发者提供一个安全并高抽象性的运行环境。

WebAssembly 和 Docker 的对比

WebAssembly 跟 Docker 之间到底是什么关系,为什么说 WebAssembly 有可能会取代 Docker 呢?这里列举了 WebAssembly 相对于Docker 的一些优势。

1. 在冷启动上,WebAssembly 比 Docker 快 100 倍

大家如果做 serverless 或者做容器服务,有一个诟病很多的问题就是冷启动慢。AWS 有预留实例(reserve instance),如果要 keep hot,就违背了无服务器的初衷。用 serverless,我想要的是按毫秒付费,结果我现在先要把东西给 reserve 起来,变成了按天付费。WebAssembly 有一个很大的优势,就是不用启动整个操作系统,所以它在冷启动的时候性能超过 docker 100倍。

2. 在执行时间上,WebAssembly 比 Docker 快 10%-50%

WebAssembly 是一个非常简单的虚拟机,没有操作系统那套东西,所以它在运行时性能也比 Docker 快 10%-50%。

3. WebAssembly 占用的空间更小

WebAssembly 的应用一般在 1MB 以下,而 Docker 镜像经常就能够达到一两百 MB。

4. WebAssembly 有一个现代的安全模型

WebAssembly 安全策略是“Capability-based Security”,一种基于给定资源的安全性控制策略。们可以有针对性地为每一个独立的模块实例提供不同的操作系统接口 / 资源权限。这些操作系统接口或资源权限可以在每个模块进行实例化时被调用者主动指定

5. WebAssembly 使软件更具有可组合性

目前有一个 serverless 应用架构叫做 JAMStack,一个 JavaScript 应用后面可能会有 100 个甚至 1000 个 serverless 函数。我们需要把这些 serverless 函数组合在一起。如果我们用容器来做的话,其实是一件非常重的事。因为要从网络或者操作系统层次来做。但是使用 WebAssembly 可以通过“nanoprocess”,在有安全控制的情况下,将这些函数组合在一起。

6. WebAssembly 无缝支持服务器应用程序框架

如 Node.js,比如 Python

以上就是 WebAssembly 的优势所在。

WebAssembly 和 Rust

讲到 WebAssembly,不能不讲的就是 Rust。 Rust 已经连续 5 年在 Stack Overflow 上成为开发者最受欢迎的语言,大有取代 C 语言的趋势。

因为 WebAssembly 与 LLVM 相接,所以前端可以支持 20 种语言,但是对有 runtime 的语言比如 Python 和 Java 不能很好地支持,对 C++、Rust 等语言支持较好。所以我们觉得 WebAssembly 和 Rust 是天生一对,就像 Java 和 JVM 一样。

Rust 提高了开发者的效率和内存的安全。WebAssembly 提高了运行时的安全与跨平台的执行。而且他们同时都是高性能的和轻量级的。

WebAssembly System Interface(WASI)

WASI 类似于 Java 的 JNI。WebAssembly 之前一直是一个浏览器里的技术,今年要把它放到服务器端,如果要访问文件系统、线程、命令、服务器上的标准库等等,那么就必须通过 WASI。

另外比如说 serverless 的一个主要应用场景是 AI 推理,那么就需要在 WebAssembly 的 runtime 里能够用 GPU、ASIC、TensorFlow 等,这些都是通过 WASI 加入进来的。

WebAssembly 和 Kubernetes 结合

WebAssembly 在浏览器里普及率高,但在服务器端普及率低,这是因为在服务器端它的调度能力不强,缺乏 DevOps 的解决方案。目前是需要自身去管理进程,管理资源分配。所以能够把 WebAssembly 和 Kubernetes 结合起来,是一个非常前沿的领域。

其中一种方法是把 WebAssembly 做成 OCI(open container interface) compliant,另一种方法是在 containerd 里面写 shim API。

现在有不同的人涉足这个领域,包括我们自己,但是目前还是一个比较早期的项目阶段。也希望大家能够关注这个项目,跟我们讨论更好的做法。

上图中的这个链接,是阿里云做的,采用的第二种方法。

上文讲到 Docker 的创始人发布的推特在社区造成了很大影响,引发了很多 Docker 粉丝的不满。为了平息大家的怨言,他又发布了一条推特。事实上一年半之后,我们发现情况完全不是这样的,他应该把 Docker 这个字改成 Kubernetes。

WebAssembly 会取代 Docker 吗?

即便 WebAssembly 能够取代 Docker,也不会很快。Docker 有自己的生态,而且与 WebAssembly 不在同一个抽象的层级,所以不是一个新的 runtime 能够很快就取代的。

但是 WebAssembly 在有些方面会有很大的应用,包括需要有高性能的和轻量级的,比如微服务、JAMStack、边缘计算等。

这是我们的网站,https://www.secondstate.io,欢迎大家一起交流!

 

关于 KubeSphere

KubeSphere (https://kubesphere.io)是在 Kubernetes 之上构建的开源容器混合云,提供全栈的 IT 自动化运维的能力,简化企业的 DevOps 工作流。

KubeSphere 已被 Aqara 智能家居、本来生活、新浪、华夏银行、四川航空、国药集团、微众银行、紫金保险、中通、中国人保寿险、中国太平保险、中移金科、Radore、ZaloPay 等海内外数千家企业采用。KubeSphere 提供了开发者友好的向导式操作界面和丰富的企业级功能,包括多云与多集群管理、Kubernetes 资源管理、DevOps (CI/CD)、应用生命周期管理、微服务治理 (Service Mesh)、多租户管理、监控日志、告警通知、审计事件、存储与网络管理、GPU support 等功能,帮助企业快速构建一个强大和功能丰富的容器云平台。

 ✨ GitHub:https://github.com/kubesphere
 💻 官网(中国站):https://kubesphere.com.cn
 👨‍💻‍ 微信群:请搜索添加群助手微信号 kubesphere

中国唯一入选 Forrester 领导者象限,阿里云 Serverless 全球领先

alicloudnative阅读(1942)评论(0)

3 月 26 日消息,权威咨询机构 Forrester 发布 2021 年第一季度 FaaS 平台评估报告,阿里云函数计算凭借在产品能力、安全性、战略愿景和市场规模等方面的优势脱颖而出,产品能力位列全球第一,这也是首次有中国云厂商进入 FaaS 领导者象限

1.jpg

图:《The Forrester Wave™: Function-As-A-Service Platforms, Q12021》报告

TheForrester Wave™ 首次升级,评测标准更苛刻。作为业界公认最严苛的厂商综合能力评估模型之一,Forrester Wave 报告在全球范围内受到高度认可。本次发布的《TheForrester Wave™: Function-As-A-Service Platforms, Q1 2021》是去年《The Forrester New WaveTM: Function-As-A- Service Platforms, Q1 2020》的全新升级,测评维度更加丰富,标准更加严苛。该报告从开发者体验、产品功能、技术领先性、战略布局以及市场规模等 40 个评估标准出发,历时半年,对全球最有影响力的九大云厂商进行测评。

Forrester 对阿里云的评价是:

“阿里云函数计算通过拥抱容器生态和开源标准来加速 Web 应用、内容处理等工作负载。在 2020 年,我们认为阿里云函数计算是一个具备强劲实力的平台。在 2021 年,函数计算对容器生态、OpenTracing、OpenTelemetry、Grafana、Jaeger 等开源标准的支持,使其能力进一步提升。函数计算支持流行 Web 框架、围绕内容的工作负载、1 毫秒计费粒度以及对运行时的投入。我们现在将阿里云函数计算视为 FaaS 市场的领导者。”

作为未来十年云计算的重要趋势之一,Serverless 已经展示出不俗的潜力。Forrester 认为,Serverless 计算的兴起,让 FaaS(Function As A Service)成为继 IaaS、PaaS、SaaS 之后一种新的云计算能力提供方式。预计 2021 年,将会有大量主流企业的核心应用,从原来的主机架构迁移到 Serverless。

虽然 Serverless 技术首先是由 AWS 提出的,但中国云计算企业在 Serverless 发展中提前卡位,迅速跨入先行者行列。阿里云是国内最早提供 Serverless 计算服务的云厂商,早在 2017 年就推出了国内第一款具备毫秒级弹性伸缩能力的 FaaS 产品——函数计算 Function Compute,后续不断完善功能,更在业界首创了预付费模式,单价降低 70%,更易于资源管理,负载平稳时成本会更低。

目前,阿里云函数计算已集成了 30 款云产品,支持预留实例、单实例多并发,还提供了容器镜像、性能实例、链路追踪、异步配置等产品能力。阿里云拥有云厂商中最完整的 Serverless 产品矩阵,以全部满分成绩获得可信云函数即服务认证,可帮助开发者快速构建稳定、自动伸缩的在线应用或小程序。去年 10 月,阿里巴巴开源首个 Serverless 开发者平台 Serverless Devs,这也是业内首个支持主流 Serverless 服务/框架的云原生全生命周期管理的平台。

2.png

图:阿里云 Serverless 产品家族

此外,函数计算 FC 和 Serverless Devs 已实现和阿里云云效的全面打通,开发者可以通过云效持续交付流水线自动化部署应用到函数计算 FC、Serverless 应用引擎 SAE、Serverless Kubernetes 服务 ASK,还可以在云效上搭建从“需求->开发->测试->发布->运维->运营”的端到端 Serverless 应用研发运维体系。

目前,淘宝、支付宝、钉钉等已经将 Serverless 应用于生产业务,阿里云上的 Serverless 产品更是帮助数万家企业客户成功落地 Serverless,覆盖前端全栈、小程序、新零售、游戏互娱、在线教育等行业或场景。例如,世纪联华全面迁移到函数计算 2.0,抗住了超过去年 230% 的业务峰值,研发效率交付提效超过 30%,弹性资源成本减少 40% 以上;口袋奇兵基于函数计算,通过单实例多并发、预留实例优化,节省了 40% 的 IT 投入成本,大幅提升资源利用率。

去年 9 月,阿里巴巴成立了云原生技术委员会,全面拥抱云原生,重点围绕容器、Serverless、服务网格等技术,构建更适合云架构的应用与服务。2020 双11 期间,阿里电商核心系统更是实现了全面云原生化,底层硬核技术升级带来了澎湃动力和极致效能:每万笔峰值交易的IT成本较四年前下降了 80%,规模化应用交付效率提升了一倍之多,这也是全球最大规模的云原生实践。

经过 10 多年的技术实践,阿里云已拥有国内规模最大的云原生产品家族和开源生态,提供云原生裸金属服务器、云原生数据库、容器服务、微服务等超过 100 款创新产品。在 Gartner 发布的 2020 年公共云容器报告中,阿里云排名全球第一。

戳链接:https://www.aliyun.com/product/fc,了解阿里云函数计算!

对于 Serverless, DevOps, 多云及边缘可观察性的思考与实践

KubeSphere阅读(1880)评论(0)

从单体到微服务,再到 Serverless,应用在逐渐地轻量化。有人可能会有疑问,微服务都还没有顺畅的搭建起来,现在又出了 Serverless,应该怎么办?

其实两者之间并不是一个相互替代的关系。我们可以看到,现在有单体应用在跑,也有微服务的应用在跑,那么以后 Serverless 这种应用也会有一定的用途。而微服务里也可以调用 Serverless 的函数(function)。

Serverless 定义

Serverless 类似于之前大数据的概念,大家都知道,但不是特别确切了解其中的含义。

CNCF 有一个 Serverless 工作组,在 Serverless 的白皮书中进行了定义。简单来讲就是,Serverless 等于 FaaS(Function-as-a-Service) 加上 BaaS(Backend-as-a-Service)。我们可以将应用程序以函数的形式打包,然后上传到 FaaS 平台。这样我们就不用关心底层服务器的运维,因为它能自动扩展,而且是按需收费。

Serverless 有一个很重要的特征,就是事件驱动模式,即依赖于外部事件去触发它运行。

至于 Backend-as-a-Service,你可以理解成支撑 Serverless 运行的一些 API 的服务,比如对象存储或者是数据库服务。

Serverless 处理模型

下图是 Serverless 的处理模型。上文讲到,它的模式是事件触发,所以它会有事件源产生事件,然后 FaaS 的 controller 是根据这些事件去启动 function 的 instance,而且能够实时的去扩展,能够 scale 到 0,这样动态的去给用户提供服务。

函数生命周期

函数(function)是有生命周期的,也就是函数部署流水线的流程。首先提供 function 的源码和 spec,然后把源码 build 成 docker image,再把 docker image 部署到 FaaS 平台上。

涉及到函数,肯定会有函数的创建、更新、发布等操作,因篇幅关系,这里就不再赘述了。

Serverless 应用场景

对 IoT 设备数据进行分析

目前边缘计算,还有 IoT 的应用都在逐渐地兴起。 比如 IoT 中的一个传感器,它会源源不断的产生一些数据(例如传感器温度超过了 60 度),我们可以调用一个云端的函数来处理这件事情(发个通知或者做一个应用)。所以 Serverless 和 IoT 这个场景可以很好地结合起来。

AI 模型服务

AI 也在逐渐兴起。边缘或者是云端提供模型的服务,因为很多模型的推理都要占用 GPU,所以如果一直占用 instance,非常耗费资源,而且还增加了成本。但是如果用 Serverless 这种方式去提供服务,比如利用 Kubeflow 项目下的 KFServing 提供推理服务,在空闲的时候可以 scale 到 0,有流量的时候会自动 scale up 起来,所以能很好地节省成本。

其他场景见上图,因为篇幅关系不再一一展开讲述。

Serverless 优势

  • 降低成本
  • 提高资源利用率
  • 无需关系底层基础设施的运维及管理
  • 灵活可拓展
  • 提升开发效率

开源 Serverless 平台

我们针对开源的 Serverless 平台做了一个调研。下图中列出的都是开源的 Serverless 平台,可以分为两类,一类是 Knative,另一类就是非 Knative。

为什么这么分类呢?因为上文讲到,Serverless 主要就是有一个 FaaS 的功能,但 Knative 并不是一个严格意义上的 FaaS 平台,而其他开源的 Serverless 平台都属于 FaaS 平台。

下图是在 Google trend 上查询到的数据。在过去一年中, Knative 的热度基本是最高的,OpenFaaS 的热度在 FaaS 平台中是比较靠前的。而过去 5 年的数据也类似,可以说,Knative 自问世以来,热度一直居高不下。

下图是 CNCF 去年做的一个调查,调查显示,在可安装的 Serverless 平台里,Knative 是比较领先的,然后 OpenFaaS 在 FaaS 平台里是比较领先的。

Knative 的优势

大家可能会有疑问,上文说到 Knative 并不是一个严格意义上的 FaaS 平台,那么它为什么在 Serverless 领域会这么受欢迎呢?

有以下几个原因:

  1. Serverless 有几个要素,首先它是事件驱动的,所以它要对事件有很好的支撑。通过 Knative Eventing,可以对事件的管理有很好的支持,也形成了一套 cloudevent 规范,用于 Serverless 负载的交互。
  2. 我们上文讲到了,它需要把函数的源码去 build 成一个 docker 镜像,所以它也要有 build 的能力。之前这个组件叫knative build,现在叫 Tekton。然后在函数发布的时候,可以利用 Knative serving,进行部署和版本管理。也就是说 Knative 是一个平台的平台。基于 Knative,你可以去构建更多的 Serverless 平台或者 FaaS 平台。
  3. 之前大家对 Knative 比较诟病的地方,就是它比较重,因为它依赖于Istio。Knative 自身的安装,可能也就几十兆,但是装上 Istio 之后,会占用几 g 内存。然而目前它已经不再强依赖于 Istio 了,Istio 只是其中一个选项。你也可以使用别的组件,比如 ambassador、Gloo、Kong 去替代它做 API Gateway。这意味着 Knative 也在逐渐的轻量化。

service model

Serverless DevOps

函数要 build 成镜像会有一个 build 的过程,那么在 devops 里这个过程就是持续交付。然后把镜像部署到生产环境,在 devops 里面这个过程就是持续部署,所以 Serverless 和 DevOps 也有很多结合点。

Serverless CI

Serverless 的 CI 也是需要的,但是因为它是函数,不是一个完整的 source code,所以它有一些不一样的地方。但是肯定也需要代码的质量扫描、单元测试这样的工作。

Serverless CD

对于 Serverless CD,build 的过程也就是函数的创建过程,会自动的把这个函数打包成镜像,这是由 FaaS 平台去完成的工作。

如果要将函数镜像发布到生产环境,需要进行审核。

Serverless CI/CD 工具

build 的过程,我们可以依赖于 tekton 去管理流水线。但是从 kubernetes 1.20 开始,不再支持 docker 作为它默认的一个运行时了,也就是说以后 kubernetes 里可以不安装 docker daemon。

CNCF 官方的文档中,推荐了几个 build docker 镜像的工具,比如 Kaniko,img,buildah。他们各有各的优劣势,但是有一个共同点,就是不依赖于 docker daemon。你可以用 Kaniko 在 docker 里面 build 一个 docker 镜像,但是不需要连接 docker daemon。

另外一个比较新兴的工具是 Cloud Native Buildpacks,它更进一步,连 Dockerfile 都不需要了,根据源码就能检测出来,然后能够 build 出一个 docker 镜像。很多国外的公司,比如 Google、Pivotal,都在使用 Buildpacks。

Serverless/FaaS 痛点

目前有很多云厂商,而且几乎每个云厂商都有自己的函数平台。开源平台又有很多。所以大家会面临应该如何选择的问题,另外也会有厂商锁定的问题。

KubeSphere Serverless 路线图

我们做 Serverless 有一个想法,能不能做一个厂商中立的 FaaS 平台?它是一个平台的平台,你可以基于它去构建自己的 FaaS 平台。

通过 KubeSphere Serverless 平台,你可以在 kubernetes 里边去运行各个云厂商的云函数,运行开源 FaaS 平台的云函数。当然,运行云厂商的云函数有个前提,就是它的 runtime 必须是开源的。

KubeSphere Serverless 平台大概率也会开源,到时候希望社区的小伙伴能够积极的参与进来。

另外一个就是 Serverless 的应用,你可以把它想象成一个 deployment + service 的替代品。它有一个额外的能力,就是可以动态的扩展,然后它也能够 scale 到 0。简单来讲,你可以提供一个 docker 镜像,然后你就拥有了一个能够自动伸缩的 service。

多云及边缘可观察性

KubeSphere 在 3.0 版本中已经支持了多集群的管理,将会在 3.1 版本中支持边缘计算。所以这就产生了一个话题——多云及边缘计算的可观察性。

需求和挑战

  1. 多云及边缘集群的全局视图
    很多用户使用 KubeSphere 管理多集群,希望能在一个统一的界面看到各个集群使用资源的情况。目前这个功能还在开发中。
    也有社区用户反馈,KubeSphere 已经支持联邦的 federated 的这种调度,能不能在一个界面看到 federated 联邦的部署,各个集群里边,对运行的资源的占用情况,这也是一个需求。
  2. 跨集群监控指标
    workspace 可能是跨了几个集群,那么能不能在一个界面里面看到 KubeSphere 在 workspace 中跨集群的资源的使用情况?
  3. 多云及边缘集群的全局告警
    因为边缘节点的资源是比较受限的,边缘集群的监控和告警怎么解决?
  4. 网络状况各有不同
    每个集群的特点都不一样。有的集群能够连接外网,也能够被外网连接。有的集群只能访问外网,不能够被 Host 集群主动连接。

架构

针对 Member 集群的连接方式,如果是像上图中左上角这样的集群,它只能连接外网,我们就可以用 prometheus 通过 remote write,把监控数据写到 Host 集群的存储上去。

对于上图中左下角的集群,可以双向访问,可以直接查询数据,然后到 Host 集群上做一个聚合,这样就能够把多集群监控的数据展现出来了。

有的用户尤其是企业用户,在单个集群上存储的数据可能不是很多,如果只想存一两年应该怎么办呢?

还有一个方案就是可以把它存储到对象存储中。Host 集群上也可以去查对象存储里时间比较久远的监控数据。

以上是监控的解决方案,那么告警是怎么解决的呢?

各个集群可以有自定义的告警,KubeSphere 3.1 会支持这个功能。对于 Host 集群,也可以做对于全局的监控指标的告警。KubeSphere 也有一些自己研发的组件,比如 Kube-Events、Kube-Auditing,这些组件也会发出一些告警,发到 Alertmanager 中,最后通过 Notification Manager 发到云端。

对于边缘集群,它的资源比较受限,它的配置通常是两核 4 g、一核 2 g,如果去使用 prometheus 往云端发送数据,资源占用会比较多。

对于边缘节点,它的带宽较小,如果源源不断的把监控数据传输到云端,会浪费带宽。

我们的想法是,可以利用一些边缘的流失处理组件,比如 EMQ 的 Kuiper 这样的组件,然后配合我们云端下发告警的规则,能够实时的把边缘的一些设备、节点的数据进行实时的过滤。当超过了阈值,就发到云端告警。这就是对边缘节点的支持。

 

于 KubeSphere

KubeSphere (https://kubesphere.io)是在 Kubernetes 之上构建的开源容器混合云,提供全栈的 IT 自动化运维的能力,简化企业的 DevOps 工作流。

KubeSphere 已被 Aqara 智能家居、本来生活、新浪、华夏银行、四川航空、国药集团、微众银行、紫金保险、中通、中国人保寿险、中国太平保险、中移金科、Radore、ZaloPay 等海内外数千家企业采用。KubeSphere 提供了开发者友向导式操作界面和丰富的企业级功能,包括多云与多集群管理、Kubernetes 资源管理、DevOps (CI/CD)、应用生命周期管理、微服务治理 (Service Mesh)、多租户管理、监控日志、告警通知、审计事件、存储与网络管理、GPU support 等功能,帮助企业快速构建一个强大和功能丰富的容器云平台。

 ✨ GitHub:https://github.com/kubesphere
 💻 官网(中国站):https://kubesphere.com.cn
 👨‍💻‍ 微信群:请搜索添加群助手微信号 kubesphere

面对不可避免的故障,我们造了一个“上帝视角”的控制台

alicloudnative阅读(2663)评论(0)

头图.png

作者 | 肖长军(穹谷)
来源 | 阿里巴巴云原生公众号

混沌工程随着云原生的发展逐渐进入大家的视野,通过混沌工程可以很好地发现和解决在云原生化过程中的高可用问题。阿里巴巴在 2019 年开源了底层的混沌工程工具 – chaosblade,今年年初再次开源混沌工程控制台 chaosblade-box,ChaosBlade 品牌进一步升级。本文主要围绕云原生面临的高可用挑战和混沌工程机遇,详细介绍开源控制台的设计、特性和实践和未来规划,旨在帮助企业更好的了解控制台并通过其来实现混沌工程落地,解决云原生系统下高可用问题。

1.png

去年年底 AWS 和 Google 都出现了比较严重的服务故障:AWS 故障是由于处理数据流服务 kinesis 出现问题,导致很多云服务不可用;Google 故障是由于登录服务的扩容配额问题导致多服务不可用。从中可以发现,他们都存在因服务依赖不合理,导致一个服务故障影响多个服务不可用,缺少应急预案,整个故障恢复时间比较长,监控告警系统不完善等问题,Google 故障发生几十分钟后才感知故障的发生,AWS 的 CloudWatch 处于不可用的状态。故障不可避免,所有的一切时时刻刻存在着失败的风险。

2.png

尤其随着敏捷开发、DevOps、微服务、云原生架构和治理的出现,应用的交付能力大大提升,但系统的复杂度也日益增加,在业务快速迭代的同时,如何保障业务持续的高可用性和稳定性面临着很大的挑战。混沌工程通过主动注入故障的方式,提前发现系统的薄弱点,推进架构的改进,最终实现业务韧性。

3.png

打不倒我的必使我强大,建设韧性架构是混沌工程的目标。韧性架构包含两部分,一部分是韧性系统,比如具备冗余性、扩展性、降级熔断、故障隔离等,避免级联故障,构建容灾容错的韧性系统。另一部分是韧性组织,包含高效交付、故障预案、应急响应等组织协同建设。高度韧性的系统也会出现预期之外的故障,所以韧性的组织能弥补韧性系统缺失的部分,通过混沌工程构建极致的韧性架构。

4.png

常见的云原生高可用架构架构基本上是基于多可用区,或者是跨地域级的容灾架构,业务应用采用微服务架构下集群部署,中间件具备容错容灾能力等等。从底层设施到上层业务,都存在潜在的故障风险,比如机房断网、整个可用区不可用、集群宕机、中间件节点 crash 等。从可用区到集群、主机,再到细粒度的请求,故障影响的爆炸半径逐渐减小,这也是混沌工程原则中非常重要的一点 — 控制爆炸半径。控制爆炸半径的方式一般有两种:一是环境隔离,通过隔离实验的机房、集群等来控制影响面;二是基于实验工具或平台自身的场景控制能力,比如 chaosblade 实验工具,通过实验参数来控制实验粒度,比如微服务调用延迟,可以控制到单个服务接口、版本,甚至一次请求。下面我们来介绍一下 chaosblade 混沌实验工具。

5.png

Chaosblade 是一款遵循混沌实验模型的混沌实验执行工具,具有场景丰富度高、简单易用等特点,而且扩展场景也特别方便,开源不久便被加入到 CNCF Landspace 中,成为主流的一款混沌工具。chaosblade 是个直接下载解压即可使用的工具,不需要安装,它支持的调用方式包含 CLI 方式,直接执行 blade 命令,这里举个做网络屏蔽的例子:我们添加 -h 参数就可以看到非常完善的命令提示,比如要一个 9520 端口调用做网络丢包,它的演练目标是 network;它的 action 是丢包;它的 matcher 就是调用远程的一个服务端口 9520。执行成功后会返回实验结果,每一个实验场景我们都会作为一个对象,它会返回一个实验对象的 UID,此 UID 用于后续的实验管理,比如销毁、查询实验都是通过此 UID 来做的。要销毁实验,也就是恢复实验,直接执行 blade destroy 命令就可以。

6.png

Chaosblade 支持多平台、多语言环境,包含 Linux、Kubernetes、Docker 平台,以及 Java、NodeJS、C++、Golang 语言应用。共涉及 200 多个场景、3000 多个参数,为用户提供丰富的场景和实验参数控制。使用 blade -h 命令可以查看详细的使用文档,包含案例和场景、参数介绍。下面我们重点介绍一下 chaosblade 对应用服务场景的支持。

7.png

Chaosblade 支持 Java、C++、Golang、NodeJS 语言应用,其中对 Java 应用的支持能力更丰富,包含 OOM、线程池满、指定线程数、CPU 负载、codecache 满等 JVM 本身的场景,还支持很多常用组件,比如 Druid、Dubbo、Elasticsearch、HBase、HttpClient、Redis、Kafka、Lettuce、MongoDB、MySQL、PostgreSQL、RabbitMQ、RocketMQ、Servlet、Tars、gRPC 等。Java 场景更强大的一个功能是可用指定任意类和方法注入异常、延迟、篡改返回,甚至可以通过自己编写 Groovy 或 Java 脚本,实现更加复杂的实验场景来满足自身业务实验需求。还支持链路标识识别、请求数限制等能力。Golang 场景是通过编译时在任意代码行注入埋点逻辑来实现,目前支持修改变量值、修改参数值、修改返回值、异常、延迟、内存溢出和 Panic 场景。现在,已登记的试用或在使用的企业已经 40 家,其中包含一些深度合作共建的企业用户。下面我们举个例子来说明 chaosblade 故障注入的执行流程。

8.png

以云原生 Dubbo 应用调用下游 PetQueryService 服务延迟三秒故障场景为例,我们可以通过 chaosblade 自带的 blade 工具或 kubectl 以及通过编码的方式来执行。此处列举了使用 kubectl 和自身的 blade 工具执行。先看使用 kubectl 执行,通过配置 ChaosBlade 类型的 YAML 文件,使用 kubectl apply 命令来创建实验,Kubernetes 会创建一条 chaosblade 资源,后续通过 kubectl delete 命令删除此咨询即可恢复实验。创建好 chaosblade 资源后,chaosblade operator 监听 chaosblade 资源创建,查询目标容器,按需透传场景相关的实验工具,调用 blade 工具在容器内执行实验。使用 blade 执行,命令如上图,指定 K8s 下的 dubbo 应用注入延迟故障,通过 process 参数指定应用名、time 参数指定延迟时间、service 参数指定受影响的服务接口、names 参数和 container-names 分别指定 Pod 和 Container 名称,如果不清楚参数可以添加 -h 来查看命令帮助。

通过以上案例可以看出 chaosblade 工具使用简单,而且支持丰富的实验场景,我们在此工具的基础上做了 ChaosBlade 品牌升级。

9.png

我们开源了 chaosblade-box 混沌工程控制台,可实现混沌实验平台化操作,而且支持更多混沌工程实验工具的托管,比如 litmuschaos 等。品牌升级后,我们更进一步地解决了用户落地混沌工程的困难度,让用户将更多的精力放到推进系统韧性提升上,旨在通过混沌工程帮助企业解决系统云原生化过程中高可用问题。

10.png

Chaosblade-box 是一个面向多集群、多环境、多语言的云原生混沌工程平台。关键功能如下所示:

  • 实现了实验工具自动化部署,无需用户登录到每台机器部署实验工具,简化用户部署成本。
  • 支持实验工具托管,现在已支持 litmuschaos ,后续会支持更多优秀的实验工具来满足各种实验场景需求。
  • 通过提供统一的混沌实验用户界面,屏蔽底层故障注入方式,让用户在同一个平台上实现不同工具的实验。
  • 支持实验目标自动获取、实验场景管理等等。
  • 支持多个实验维度,比如主机、Kubernetes、应用,其中 Kubernetes 又包含 Container、Pod、Node 实验维度。
  • 后续会更进一步支持混沌工程闭环,实现稳态定义、实验执行、稳态评估等,协助用户构建高可用的云原生系统。

下面通过页面截图来了解一下 chaosblade-box 平台能力。

11.png

12.png

13.png

14.png

15.png

16.png

17.png

通过上述图片可以看出 chaosblade-box 平台整体功能,在托管更多工具场景的基础上,标准化实验场景和实验管控界面,简化用户操作,降低使用门槛,提供详细的白屏化日志,便于问题跟踪和排查。接下来我们看下平台技术架构图。

18.png

通过控制台页面可实现 chaosblade、litmus 等已托管的工具部署,按照社区的建立的混沌实验模型统一实验场景,根据主机、Kubernetes、应用来划分目标资源,通过目标管理器来控制,在实验创建页面,可以实现白屏化的目标资源选择。平台通过调用混沌实验执行来执行不同工具的实验场景,配合接入 prometheus 监控,可以观察实验 metric 指标,后续会提供丰富的实验报告。
_
_Chaosblade-box 的部署也非常简单,具体可以查看:https://github.com/chaosblade-io/chaosblade-box/releases_。

下面我们通过一个杀 Pod 实验场景来介绍平台的使用。

19.png

首先是部署 chaosblade-box,部署完成后,在实验列表页面创建实验,选择 Kubernetes Pod 实验维度,实验创建共分为四步,前两步资源选择和场景选择是必填项,后两步监控接入和实验名称是非必填项。在 Pods 列表中选择多个目标 Pods,然后选择杀 Pods 实验场景,对接 Prometheus Pod 监控,完成实验创建。在实验详情页面可以点击执行实验进入实验任务详情页面,查看实验详细信息。

20.png

Chaosblade-box 后续规划重点在托管更多的实验工具,实现更多工具自动化部署,同时支持更多的语言应用,添加更加复杂的调度策略和流程编排,生成实验报告,实验报告分三个阶段,一是实验基础报告,包含实验和监控的基本信息,二是实验缺陷报告,包含实验中发现的问题,三是实验高可用建设报告,根据实验中发现的问题提出解决方案建议。

具体的 Roadmap 可详见:https://github.com/chaosblade-io/chaosblade-box/wiki/Roadmap

ChaosBlade 品牌升级后,项目才刚刚开始,还有很多不完善的地方,欢迎大家下载使用,参与到项目建设中,也可登记企业使用情况到 issue 中,我们线下交流,登记地址:_https://github.com/chaosblade-io/chaosblade/issues/32_。

  • chaosblade 项目地址

https://github.com/chaosblade-io/chaosblade

  • chaosblade-box 项目地址

https://github.com/chaosblade-io/chaosblade-box

Go Mysql Driver 集成 Seata-Golang 解决分布式事务问题

alicloudnative阅读(2564)评论(0)

头图.png

作者 | 刘晓敏  GitHub ID:dk-lockdown
来源 | 阿里巴巴云原生公众号

背景

2020 年 4 月,我们开始尝试实现 go 语言的分布式事务框架 Seata-Golang。众所周知,Seata AT 模式以无业务代码侵入的特点,被广大开发者推崇。Java 版 Seata AT 模式通过对 DataSource 数据源进行代理,在 sql 语句执行时,对 sql 拦截解析,获取数据库对应数据在 sql 语句执行前后的副本,序列化后保存起来,在 TC 协调回滚时用来回滚对应数据。实现 go 版本 client 的 AT 模式时,怎样对业务开发者更友好,入侵更少,成了首要考虑的目标。

1.png

使用 go 操作数据库时,我们会使用到 go 语言的官方库 database/sql,通过 sql.Open("mysql", ${dsn}) 获取一个数据源操作对象 db。开启事务时,使用 db.Begin() 或 db.BeginTx(ctx, &sql.TxOptions{}) 获得事务操作对象 tx,执行 sql 查询使用 tx.Query;执行 sql 新增、修改、删除,使用 tx.Exec;最后使用 tx.Commit() 提交或使用 tx.Rollback() 回滚。

go 语言官方库 database/sql 提供了一个标准抽象层,通过实现不同的 driver 一套标准的抽象 API 可以操作不同的数据库。开发 Go 版本的 AT 模式,必然要兼容 database/sql。通过研究 database/sql 的 api,创建数据源操作对象,数据库有关的配置必须通过 Data Source Name (DSN) 抽象传递进去,下面是 DSN 的定义:

[username[:password]@][protocol[(address)]]/dbname[?param1=value1&...&paramN=valueN]

实现 AT 模式对数据源代理是需要和事务协调器 TC 进行交互的,如果将 AT 模式实现在 driver 层,那么和 TC 交互的一些参数必须要通过 DSN 传递到 driver,这样有些破坏它的设计。所以,最后采取了一种折中方案,在 database/sql 层之上实现 AT 模式,代理 database/sql 创建出来的数据源操作对象。数据源代理对象实现 database/sql 库定义的 Tx 接口,另外再提供一个开启事务的方法:Begin(),虽然没有完全兼容 database/sql 的 api,但是关键接口和它的定义成一样,勉强还能接受。到此,Seata-Golang 项目核心功能的开发已完成。

type Tx interface {
    Commit() error
    Rollback() error
}

转折

Seata-Golang  开源后,逐渐被一些开发者了解和接触,社区也对 Seata-Golang 发出了一些反馈的声音,不少开发者并不习惯写原生 sql,他们希望将 Seata-Golang 集成到 ORM 框架,因为当时的设计没有完全兼容 database/sql 导致集成上遇到一些困难。随着社区的热切呼唤,且得益于前期对 driver 的一些研究,念念不忘必有回响,今年 3 月突然灵感迸发:为什么参数一定要通过 DSN 传递?Seata-Golang Client 初始化后,在需要时通过 Client 端的 API config.GetATConfig() 直接获取使用不就可以了。

2.png

于是工作之余,历时 2 周开发,第一个集成 Seata-Golang 的完全兼容 database/sql 的 mysql driver 被开发出来,项目开源在 https://github.com/opentrx/mysql,现处于 beta 状态,希望社区开发者使用后能有一些反馈,可通过例子:https://github.com/opentrx/seata-go-samples,查看使用方式并进行测试。

driver 的一些细节

  • 使用该 driver 进行分布式事务操作时,不能在 dsn 中设置 interpolateParams 参数为 true

这涉及到 mysql 的两个协议:Text 协议和 Binary 协议。有关两个协议的区别,可以在文末参考文档找到资料。实现该 driver 只对 binary 协议进行了处理,开启 interpolateParams 会使用 text 协议执行 sql。

  • 使用该 driver 在需要加入全局事务组和 tc 进行交互时,需要使用 db.BeginTx(ctx context.Context, opts driver.TxOptions) 方法,并在 ctx 中加入 XID 全局事务 id 的值
ctx := context.WithValue(context.Background(), mysql.XID, c.Request.Header.Get("XID"))
tx, err := dao.BeginTx(ctx, &sql.TxOptions{
        Isolation: sql.LevelDefault,
        ReadOnly:  false,
    })

XID 传递到 driver 层,会保存在 &mysqlConn 连接对象中,在和 TC 交互时用到。

  • 使用该 driver 的分布式事务功能前需要先初始化 seata-golang client 和 mysql driver
  config.InitConf(configPath)
  client.NewRpcClient()
  mysql.InitDataResourceManager()
  mysql.RegisterResource(config.GetATConfig().DSN)

具体可参考 seata-go-samples

寄语

此项目开源到今年 4 月即满一年,通过本文中的 mysql driver,希望能降低使用门槛,让大家真正用起来,大家在选择微服务开发技术栈时也不用担心 go 语言没有分布式事务处理方案。另外,此项目还很年轻,仍有许多需要完善的地方,希望感兴趣的朋友一起参与到社区来对它进行完善!希望听到社区更多用户的反馈!
如果你有任何疑问,欢迎钉钉扫码加入交流群【钉钉群号 33069364】

作者简介

刘晓敏 (GitHubID dk-lockdown),目前就职于 h3c 成都分公司,擅长使用 Java/Go 语言,在云原生和微服务相关技术方向均有涉猎,目前专攻分布式事务。

参考资料

我在阿里实习做开源

alicloudnative阅读(1341)评论(0)

作者 | 李志信
来源 | 阿里巴巴云原生公众号

3 月 19 日,初春的杭州,依旧阴雨朦胧。透过 EFC 健身房的落地窗往外看,远处的楼宇、青山、整齐的街道和稀疏的车辆在水雾中若隐若现。

午后的小憩时光,我拿了瓶咖啡回到工位,看着刚刚提交的 PR 通过了 CI check,这是我人生中作为实习生的最后一天了。

成长的过程就是不断经历和体验的过程,一段又一段不同心境的开始和结束。我希望三个月后,那个过了 22 岁生日的年轻人会如愿顺利拿到毕业证,再次出现在这里,我想那时的他一定更熟悉 Java 了吧。

本科时光

循规蹈矩的大学生涯,大概是是四年本科和三年硕士,而我属于校园的时光,只有两年半。在外实习到现在已经整整一年了,从北京到深圳再到杭州,我也非常庆幸能拥有这样的经历。

三段不同方向的实习,从最一开始在学校里的 GoOnline 在线 IDE 项目,让我对真正落地的开发项目充满了向往;到 “互享“ 平台运维开发,让我对企业落地的日常开发运维流程有所了解;再到看点业务开发与需求上线,让我对拥有百万用户的项目和技术充满了激情;再到中间件研发,专注于云原生领域的探索和落地。
第一段实习是在北京时代复兴投资公司,期间充满了懵懂和纠结的,纠结于是选择研发还是科研,懵懂与对从没见过的花里胡哨的各种工具的胆怯,但很幸运最终习惯了自己的选择。

第二段实习是在深圳腾讯,整个过程充满了刺激和危机感,危机来源于在社会上和技术上如何站住脚跟,惊险刺激于一连串从没料到的事情。很感谢我能冷静对待遇到的各种突发情况,来自就业的压力,来自转正的压力,都不足以压垮一个有梦想的年轻人。至今依旧怀念当时带领我成长的导师 Steven

去年秋天开始在阿里集团中间件团队开始了我的第三段实习经历,相比前两次,这次实习舒服了很多。当看清前路的时候,活的还是比较滋润的,所要做的就是积累、沉淀和享受来自研发的快乐。很幸运,实习经历中遇到的导师、同事和领导们都非常 nice,都可以遇到一起聊天交心、一起吃饭喝酒的前辈们,或许对于初入社会的年轻人,是一盏盏指向未来散发光芒的灯塔。

dubbogo 社区

拿到阿里实习 offer 后还未入职西厂前,便被大 Boss 引入了 dubbogo 社区,被告知实习的任务就是推动dubbo-go 在内部的落地和 dubbo-go 3.0 的开发。这是一个有技术的组织,更是一个有人情味的地方。

时光到回到去年刚拿到 offer 的 10 月份,第一次将 dubbo-go clone 到本地,成功实现了 RPC 调用,心情是无比激动的。因为这个场景陌生中带着熟悉。第一次 bug fix,第一次贡献 feature,写源码解读,再到后面成为 dubbo committer,投入 Dubbo-go 3.0 的贡献中。专属于年轻 IT 工程师的快乐,莫非于让自己和项目一起成长。

在阿里的实习过程,2021 年的重大版本 dubbo-go 3.0 贯穿了整条时间线。从我尚未入职还在石家庄的时候,便开始一边在按摩店洗脚一边开周会接任务,到后面熟识了社区中的领导们、技术大佬们,很多次被前辈的技术和精神所感动,说社区充满了人情味毫不为过。

马上就要到了三月底,我也希望 dubbo-go 3.0 可以成为实习过程中属于我的一份期末答卷,而 3.0 版本一定不是终点,而是国内开源 RPC 框架发展的过程所在,因为有了每一个阶段的创新,才成就了在未来长河中的丰富的云原生发展史。

比起项目本身,我更爱这种技术氛围:

  • 很多技术人员可以凝聚在一起,各尽所长为了一个目标而努力;
  • 一种“有我在项目就在”的责任心;
  • 一种在贯彻于编码中的开源项目的严谨;
  • 一种聚会时可以快乐吹水和交流的默契。

1.png

就在上周六晚上,dubbogo 社区负责 dubbo-go-pixiu 项目的负责人铁城大哥,为了庆祝自己成功从阿里外围公司转到盒马,召集了社区杭州的网友们成功小聚。觥筹交错间从技术八卦到社区秘闻,无所不谈,并纷纷“讨伐”图中某位马上从杭州某 IoT 公司离职要投奔蚂蚁的大佬 ^_^。很感激在前行路上遇到的许多优秀又充满情怀的前辈!

Triple-go

实习当然不可能只有周末的风月,更多的是期间的工作经历和成长。整个实习期间个人主要负责 dubbo-go 3.0 的 Triple 协议和新路由规则实现。

开源 Triple 协议作为 dubbo-go 3.0 的重要 feature,简单来说,就是扩展 gRPC 协议,在 gRPC 的基础上引入 dubbo 的服务治理能力和扩展空间。

刚开始想的很简单,在 HTTP2 之上实现 Triple,并兼容 gRPC。但难点在于既要和 gRPC 在普通/流式/状态码上完全兼容,又要具有 dubbo 服务治理能力 — 在 dubbo-go 已有基础上扩展,还要扩展的优雅。

  • 手撕 HTTP2 

只借助数据帧层的 SDK 手撕 HTTP2 协议,首先需要解决发包逻辑的正确性。搞了一两个星期。实现了调用打通。

但自己实现的总会有问题…

除了数据帧发送正确,还要考虑滑动窗口流控、上下线、数据帧的拆包合包等等一系列流式场景下的问题。我的解决方法很直接,抓包看 grpc 怎么做的(没时间看源码了),然后按照它的逻辑去实现。

当问题一个在掉头发的过程中解决,看似美好,实则陷入死胡同 — 手撕真的比不上官方库,无论是稳定性还是速度。

  • 改官方库

一开始没有选择官方库,因为 gRPC 并不是这么做的。调研的过程中感觉困难重重,Go 语言官方库只给了少的可怜的接口,怎么自定义 Header 和 Trailer?怎么实现 stream 调用?给官方库提交 issue 后被回复:“想法不错,你自己实现个贡献出来吧”…

在这一点上,隔壁 java 的实现就舒服了很多,功能强大的 java-http2 库直接信手拈来。后来对于大型项目的贡献已经有点恐惧了,条条框框太多,跟师兄学聪明点,干脆 fork 个分支自己改,改的自己都觉得骚,但是能实现需求。

很感谢经验丰富的领导提醒我,官方库可以试试用。

  • 丝滑体验

花了两天时间换了底层网络库,体验丝滑了很多,尤其是几兆的大个儿数据包,跟社区前辈一起测了一下,最后 2-3MiB 的双向数据包单机压测可达到 1.5k qps。

当然没考虑到的问题还有很多,但沉浸在开发的快乐和成就感中真的很爽。

未来的云原生

实习期虽然只有三个多月,但到后来我越来越发现,中间件研发已经承包了我的太多快乐,我越来越发觉了对编程的热爱,对专业的敬畏,对云原生技术的信仰。

我认为任何一位 IT 工程师,无论技术深度如何,无论经验是否丰富,都应该拥有自己的技术信仰。我希望技术信仰于我而言,始于对于编程的喜爱和强烈的项目成就感,成长于与前辈的交流和源码的学习中,希望在未来将落实于在 “落地” 和 “创新” 两个词中。

我认为,任何的技术,如果不落地生产,将不具有太多意义。而将“形而上学”的架构观念,突破层层阻碍和壁垒,例如和已有服务/语言/设计理念相悖,不断推进落地,这过程是伟大的,这个过程中付出过努力的人都是站在浪潮之巅的弄潮儿。

中间件的未来是什么?sidecar 架构真正优雅落地是什么样子?Java 和 Go 以后的关系又是如何?RPC 又能被什么替代,或者是以一种新形态出现?

很多东西就像年初的股市一样扑朔迷离,但未来一定会有一个唯一的答案。未来在杭州,我在技术上又会经历什么变化,业内技术栈又会产生什么样的突破和进展。

难以想象未来三年后,我的技术栈将会变成什么样?毕竟从测试、运维、业务开发、再到基础架构,唯一不变的是变化。

最后的话

2.png

配上实习最后一天离开西厂前的纪念照 — 纪念一段人生路程的结束。祝福开源的 dubbo/dubbogo,在未来将会变得越来越强大,越来越多的开发者可以使用它们,创造云原生更大的价值。

dubbo/dubbo-go 3.0 将于近期正式发布,敬请期待!如有兴趣,可到 dubbogo 社区钉钉群 31363295 找我聊聊。

谨以此文致敬我的三段实习经历中帮助我成长的各位导师和技术前辈们,并以此纪念我即将逝去的大学生涯!

Fluid 0.5 版本发布:开启数据集缓存在线弹性扩缩容之路

alicloudnative阅读(1405)评论(0)

头图.png

作者 | 顾荣  南京大学PASALab, Fluid项目co-founder
来源 | 阿里巴巴云原生公众号

导读:为了解决大数据、AI 等数据密集型应用在云原生场景下,面临的异构数据源访问复杂、存算分离 I/O 速度慢、场景感知弱调度低效等痛点问题,南京大学PASALab、阿里巴巴、Alluxio 在 2020 年 6 月份联合发起了开源项目 Fluid。

Fluid 是云原生环境下数据密集型应用的高效支撑平台,项目自开源发布以来吸引了众多相关方向领域专家和工程师的关注,在大家的积极反馈下社区不断演进。近期 Fluid 0.5 版本正式发布,在该版本中,Fluid 主要新增改善以下三个方面内容:

  • 丰富数据集的操作功能,支持在线弹性扩缩容、元数据备份和恢复。
  • 支持多样环境配置部署,满足用户的个性化部署配置需求。
  • 新增数据缓存引擎实现,增加用户在公有云上的引擎选择。

Fluid 开源项目地址https://github.com/fluid-cloudnative/fluid

这三大主要功能的开发需求来自众多社区用户的实际生产反馈,此外 Fluid v0.5 还进行了一些 bug 修复和文档更新,欢迎使用体验 Fluid v0.5!

Fluidv0.5 下载链接https://github.com/fluid-cloudnative/fluid/releases

下文是本次新版本发布功能的进一步介绍。

丰富数据集的操作功能

在本版本中 Fluid 重点丰富了核心抽象对象 —— Dataset(数据集)的相关操作功能,从而使数据密集型应用能够更好地利用云原生提供的弹性、可观测性等基础功能,并增强了用户对数据集管理的灵活性。

1. 数据集在线弹性缓存扩缩容

这是社区用户一直期待的功能!在 Fluid v0.5 之前,如果用户想要调整数据集的缓存能力,需要以全部卸载缓存引擎再重部署的方式完成。这种方式耗时耗力,还必须考虑数据缓存全部丢失的高昂代价。因此,在新版本中,我们为数据集提供了对缓存弹性扩缩容的支持,用户可以根据自己的场景需求,以不停机方式 on-the-fly 地按需增加某数据集的缓存容量以加速数据访问(扩容)或减少某个不频繁使用的数据集的缓存容量(缩容),从而实现更加精细的弹性资源分配,提高资源利用率。Fluid 内置的控制器会根据策略选择合适的扩缩容节点,例如在缩容时会结合节点上运行任务情况和节点缓存比例作为筛选条件。

执行弹性数据集的缓存能力弹性扩缩容,用户只需运行如下命令:

kubectl scale alluxioruntimes.data.fluid.io {datasetName}  --replicas={num}

其中 datasetName 对应于数据集的名称,replicas 指定缓存节点的数目。

有关数据集手动扩缩容及其效果的演示视频:http://cloud.video.taobao.com/play/u/2987821887/p/1/e/6/t/1/302459823704.mp4

更多关于数据集手动扩缩容的操作细节,请参考 Github 上的示例文档

2. 元数据的备份与恢复

该功能增强了 Fluid 数据集元数据管理的灵活性。先前的 Fluid v0.4 已经支持将数据集的元数据(例如,文件系统 inode tree)加载至本地,并且会记录数据集的一些关键统计信息(例如,数据量大小和文件数量)。然而,一旦用户销毁本地数据集,这些元数据信息也都将丢失,重新构建数据集时需再次从底层存储系统获取。

因此,在 Fluid v0.5 中,我们新增了一个 K8s 自定义资源对象 —— DataBackup,为用户提供了声明式的 API 接口,以控制数据备份的相关行为。DataBackup 自定义资源对象构建的一个简单示例如下所示:

apiVersion: data.fluid.io/v1alpha1
kind: DataBackup
metadata:
  name: hbase-backup
spec:
  dataset: hbase
  backupPath: pvc://<pvcName>/subpath1/subpath2/

再次创建数据集时,只需新增一个指定备份文件位置的字段:

apiVersion: data.fluid.io/v1alpha1
kind: Dataset
metadata:
  name: hbase
spec:
  dataRestoreLocation:
    path: pvc://pvc-local/subpath1/
  mounts:
    - mountPoint:  https://mirrors.tuna.tsinghua.edu.cn/apache/hbase/2.2.6/

此时,Fluid 将首先从备份文件加载元数据和数据集统计信息,从而很大地提高元数据加载速度。

更多关于进行数据集元数据备份与恢复的操作细节,请参考 Github 上的示例文档

3. 数据集的可观测性优化

Fluid v0.5 还进一步增强了数据集的可观测性能力,具体包括两个部分:

1)与 Prometheus 相结合1.jpg

该特性能够支持数据集的可用性和性能指标收集,并且通过 Grafana 进行可视化展示。目前已支持 AlluxioRuntime 的实现,使用者可以方便地了解当前可缓存节点、缓存空间、现有缓存比例、远程读、短路读等性能指标。整个配置过程非常简单,达到了对于数据集监控系统“开箱即用”的效果。

具体的使用方法,请参考 Github 上的示例文档

2)新增数据集缓存命中率指标

该功能可以标识过去 1 分钟内对该数据集的全部访问中有多少访问命中了分布式缓存。该指标一方面能够帮助用户分析他们数据密集型应用中的性能瓶颈,量化查看 Fluid 在整个应用运行的工作流中起到的效果;另一方面能够帮助用户在应用性能提升和缓存资源占用间进行行权衡,做出合理的扩缩容决策。

这一指标被添加在 Fuild v0.5 的 Dataset.Status.CacheStates 的 Dataset CRD 资源状态中,具体来说包括:

  • Cache Hit Ratio:过去一分钟分布式缓存命中的访问百分比。
  • Local Hit Ratio:过去一分钟本地缓存命中的访问百分比。
  • Remote Hit Ratio:过去一分钟远程缓存命中的访问百分比。

注: 对于分布式缓存而言,数据命中有两种不同的缓存命中情况。本地缓存命中指的是访问发起者可直接在同结点访问到缓存数据。远程缓存命中指的是访问发起者需要通过网络访问其他结点上的缓存数据。

在 Fluid v0.5 中,用户可以使用以下命令方便地查看缓存命中率指标:

kubectl get dataset <dataset-name> -o wide
NAME        ...  CACHE HIT RATIO   AGE
<dataset-name> ...  86.2%           16m

支持多样环境配置部署

自 Fluid 0.4 版本发布以来,我们根据社区用户实际部署反馈的问题和需求,对 Fluid 在多样环境下的部署配置增加了更多支持。

1. 支持 Fuse 的 global 模式

在 Fluid 中,Dataset 资源对象中所定义的远程文件是可被调度的,这意味着你能够像管理 Pod 一样管理远程文件缓存到 Kubernetes 集群上的位置。执行计算的 Pod 可以通过 Fuse 客户端访问数据文件。在先前版本的 Fluid 中,Fuse 客户端总是会调度到缓存所在的节点上,但是用户不能自由控制 Fuse 的调度。

在 Fluid v0.5 中,我们为 Fuse 新增了 global 部署模式。在该模式下,Fuse 默认会全局部署到所有节点上。用户也可以通过指定 Fuse 的 nodeSelector 来影响 Fuse 的调度结果。同时,缓存会优先调度部署在执行计算 Pod 数量较多的节点上。

具体使用非常简单,可以参考 Github 上的示例文档

2. 支持 HDFS 的用户级配置

很多社区用户使用分布式缓存系统 Alluxio 作为 Fluid 数据集的缓存引擎。在数据集持久化存储于 HDFS 文件系统的情况下,要使得 Alluxio 能够正常访问底层 HDFS,Alluxio 集群需要提前获取该 HDFS 的各类配置信息。

在 Fluid v0.5 中,我们使用 Kubernetes 的原生资源为上述场景提供支持。用户首先需要将 HDFS 的相关配置文件(e.g. hdfs-site.xml 和 core-site.xml)以 ConfigMap 方式创建到 Kubernetes 环境中,接着在创建的 AlluxioRuntime 资源对象中引用上述创建的 ConfigMap 从而实现上述功能。

AlluxioRuntime 资源对象的一个示例如下所示:

apiVersion: data.fluid.io/v1alpha1
kind: AlluxioRuntime
metadata:
  name: my-hdfs
spec:
  ...
  hadoopConfig: <configmap-name>
  ...

至此,创建出的 Alluxio 集群将能够正常地访问 HDFS 集群中的数据。更多内容可参考 Github 上的示例文档

新增数据缓存引擎实现

Fluid 默认使用的分布式缓存 Runtime 是 AlluxioRuntime,为了支持不同环境用户对缓存系统的需求,在之前的版本中 Fluid 已经将分布式缓存 Runtime 接入框架做成了可插拔的架构。在 Fluid v0.5 中,来自阿里云的社区贡献者基于该框架开发了 JindoRuntime,新增了一种支撑 Fluid Dataset 数据管理和缓存的执行引擎实现。用户可以在 Fluid 中通过 JindoRuntime 使用 JindoFS 的 Cache 模式进行远端文件的访问和缓存。在 Fluid 上使用和部署 JindoRuntime 流程简单、兼容原生 K8s 环境、开箱即用。

总结

在 Fluid v0.5 中,我们对 Fluid 的功能特性与用户体验都进行了丰富和增强。

首先,Fluid v0.5 进一步增加了数据集的功能操作:

  • 提供数据集在线弹性扩缩容能力,实现更灵活、更精细的集群资源分配控制。
  • 新增 DataBackup CRD,实现了数据集文件元数据等信息的备份与恢复,帮助完成数据集缓存系统的快速重启。
  • 新增缓存命中率指标,帮助用户更好量化分析 Fluid 提供的加速效果。

其次,Fluid 支持更多环境模式和配置,满足更多真实场景的部署需求。

最后,Fluid 新增了基于 JindoFS 的分布式缓存 Runtime —— JindoRuntime,为用户在多样化部署环境中提供不同的缓存引擎选择。

我们会继续广泛关注和采纳社区建议,推动 Fluid 项目的长期发展,期待听到大家更多的反馈。

鸣谢

感谢为此版本做出贡献的社区小伙伴们,他们包括来自阿里云的王涛、腾讯云的谢远东、中国电信的仇伶玮、南京大学 PASALab 的徐之浩、候浩军、陈国旺、陈雨铨等同学。

作者简介

顾荣 博士,南京大学计算机系副研究员,Fluid 开源项目 co-founder、Alluxio 开源项目 PMC 成员,研究方向大数据处理系统,已在 TPDS、ICDE、JPDC、IPDPS、ICPP 等领域前沿期刊会议发表论文30余篇,主持国家自然科学基金面上项目/青年项目、中国博士后科学基金特别资助项目多项,研究成果落地应用于阿里巴巴、百度、字节跳动、中国石化、华泰证券等公司和开源项目 Apache Spark、Alluxio,获 2018 年度江苏省科学技术一等奖、2019 年度江苏省计算机学会青年科技奖,担任中国计算机学会系统软件专委会委员/大数据专委会通讯委员、江苏省计算机学会大数据专委会秘书长。

云原生时代下,容器安全的“四个挑战”和“两个关键”

alicloudnative阅读(2167)评论(0)

头图.png

作者 | 匡大虎
来源 | 阿里巴巴云原生公众号

云原生进程中的容器安全挑战

云原生的火热带来了企业基础设施和应用架构等技术层面的革新,在云原生的大势所趋下,越来越多的企业选择拥抱云原生,在 CNCF 2020 年度的调研报告中,已经有83% 的组织在生产环境中选择 Kubernetes,容器已经成为应用交付的标准,也是云原生时代计算资源和配套设施的交付单元。显然,容器已经成为应用交付的标准,也是云原生时代计算资源和配套设施的交付单元。

然而,由于在隔离和安全性方面存在的天然缺陷,安全一直是企业进行容器改造化进程中关注的核心问题之一。来到云原生时代,企业又将面临哪些容器安全新挑战?

  • 缺少体系化的容器安全能力建设:传统的企业应用安全模型通常基于内部架构不同的信任域来划分对应的安全边界,在信任域内的东西向服务交互被认为是安全的。而上云后企业应用需要在 IDC 和云上部署和交互,在物理安全边界消失后,如何在零信任的网络安全模型下构建企业级容器安全体系是云服务商需要解决的重要问题。
  • 更多的攻击面:基于容器技术的应用部署依赖 Linux 内核 namespaces 和 cgroups 等特性,从攻击者的角度出发,可以利用内核系统漏洞,容器运行时组件和容器应用部署配置等多个维度发起针对性的逃逸和越权攻击。K8s、Docker、Istio 等开源社区近年来也相继爆出不少的高危漏洞,这都给攻击者提供了可乘之机。
  • 缺少应用侧全生命周期的安全防护手段:容器技术在为企业应用架构提供了弹性、敏捷和动态可扩展等特性的同时,也改变了应用的部署模式。首先应用自身的生命周期被大幅缩短,一个容器应用的生命周期通常是分钟级;与此同时,随着存储网络和异构资源利用率等基础设施能力上的提升,容器应用的部署密度也越来越高,传统的面向虚机维度的安全防护策略和监控告警手段已经无法适应容器技术的需求。
  • 缺少对云上安全责任共担模型的理解:企业应用上云后的安全需要遵循责任共担模型,在企业应用架构云原生话的转型过程中,需要企业应用管理者和安全运维人员理解企业自身和云服务商之前的责任边界。这个过程中也需要云服务商面向企业应用侧输出更全面的容器安全最佳实践并提升安全能力的易用性,降低使用门槛。

构建容器安全体系的基本原则

为了应对上述企业应用在容器化进程中的安全挑战,云服务商和企业应用安全管理运维人员需要携手共建容器应用安全体系:

1.jpg

图 1 – ACK 容器服务安全责任共担模型

1. 云服务供给侧

对于云服务商,首先需要依托于云平台自身的安全能力,构建安全稳定的容器基础设施平台,并且面向容器应用从构建,部署到运行时刻的全生命周期构建对应的安全防护手段。整个安全体系的构建需要遵循如下基本原则:

1)保证容器管控平台基础设施层的默认安全

容器平台基础设施层承载了企业应用的管控服务,是保障业务应用正常运行的关键,容器平台的安全性是云服务商应该格外关注的。

  • 完备的平台安全能力:首先云服务商自身基础设施的安全性是容器平台是否安全的基础,比如 VPC 的安全配置能力,SLB 的访问控制,DDoS 能力和账号系统对云资源的访问控制能力等都是平台侧面向企业应用需要提供的基础安全能力。
  • 版本更新和漏洞应急响应机制:虚机 OS 的版本更新和漏洞补丁的安装能力也是保证基础设施安全的基本防护措施,除此之外如 K8s 等容器相关开源社区的风险漏洞,都可能成为恶意攻击者首选的攻击路径,需要厂商提供漏洞的分级响应机制并提供必要的版本升级能力。
  • 平台的安全合规性:这也是很多金融企业和政府部门应用上云的硬性前提条件。云服务商需要基于业界通用的安全合规标准,保证服务组件配置的默认安全性,同时面向平台用户和安全审计人员,提供完备的审计机制。

2)面向容器应用侧提供纵深防御能力

云服务商不仅要在自身管控侧建立完善的安全武装,同时也需要面向业务应用负载,提供适合云原生场景下容器应用的安全防护手段,帮助终端用户在应用生命周期各阶段都能有对应的安全治理方案。由于云原生具有动态弹性的基础设施,分布式的应用架构和创新的应用交付运维方式等特点,这就要求云服务商能够结合自身平台的基础安全能力,将云原生能力特性赋能于传统的安全模型中,构建面向云原生的新安全体系架构。

2. 企业安全侧

对于企业的安全管理和运维人员来说,首先需要理解云上安全的责任共担模型边界,究竟企业自身需要承担起哪些安全责任。云原生微服务架构下企业应用在 IDC 和云上进行部署和交互,传统的网络安全边界已经不复存在,企业应用侧的网络安全架构需要遵循零信任安全模型,基于认证和授权重构访问控制的信任基础。对于企业安全管理人员来说可以参考关注如下方向加固企业应用生命周期中的生产安全:

  • 保证应用制品的供应链安全

云原生的发展使得越来越多的大规模容器应用开始在企业生产环境上部署,也大大丰富了云原生应用制品的多样性,像容器镜像和 helm charts 都是常见的制品格式。对于企业来说制品供应链环节的安全性是企业应用生产安全的源头,一方面需要在应用构建阶段保证制品的安全性;另一方面需要在制品入库,分发和部署时刻建立对应的访问控制,安全扫描、审计和准入校验机制,保证制品源头的安全性。

  • 权限配置和凭证下发遵循权限最小化原则

基于统一的身份标识体系进行认证授权是在零信任安全模型下构建访问控制能力的基础。对于企业安全管理人员来说,需要利用云服务商提供的访问控制能力,结合企业内部的权限账号体系,严格遵循权限最小化原则配置对云上资源和容器侧应用资源的访问控制策略;另外严格控制资源访问凭证的下发,对于可能造成越权攻击行为的已下发凭证要及时吊销。另外要避免容器应用模板配置如特权容器这样的过大权限,确保最小化攻击面。

  • 关注应用数据和应用运行时刻安全

应用的成功部署上线并不意味着安全工作的结束。除了配置完备的资源请求审计外,安全管理运维人员还需要利用厂商提供的运行时刻监控告警和事件通知等机制,保持对容器应用运行时安全的关注,及时发现安全攻击事件和可能的安全隐患。对于企业应用自身依赖的敏感数据(比如数据库密码,应用证书私钥等)需要根据应用数据的安防等级采用对应的密钥加密机制,利用云上的密钥管理方案和落盘加密,机密计算等能力,保证数据在传输和落盘链路上的数据安全性。

  • 及时修复安全漏洞和进行版本更新

无论是虚机系统,容器镜像或是容器平台自身的安全漏洞,都有可能被恶意攻击者利用成为入侵应用内部的跳板,企业安全管理运维人员需要根据云服务商推荐的指导方案进行安全漏洞的修复和版本更新(比如 K8s 集群版本,应用镜像版本等)。此外企业要负责内部员工的安全培训工作,居安思危,提升安全防护意识也是企业安全生产的基础要务。

端到端的云原生容器安全架构

阿里云 ACK 容器服务面向广大的企业级客户,构建了完整的容器安全体系,提供了端到端的应用安全能力。在今年 Forrester IaaS 安全评测中,阿里云容器安全能力与谷歌并列满分,领先其他厂商。下图为阿里云容器服务的安全体系架构图:

2.jpg
图 2 – ACK 容器服务安全体系架构图

首先整个容器安全体系依托于阿里云强大的平台安全能力,包括物理/硬件/虚拟化以及云产品安全能力,构建了夯实的平台安全底座。

在云平台安全层之上是容器基础设施安全层,容器基础设施承载了企业容器应用的管控能力,其默认安全性是应用能够稳定运行的重要基础。首先面向集群 host 节点 OS 镜像本身阿里云操作系统团队做了很多安全加固相关工作,Alibaba Cloud Linux 2 (原 Aliyun Linux 2) 不仅是阿里云官方操作系统镜像,也是 ACK 的首选默认系统镜像。Alibaba Cloud Linux 2 在 2019 年 8 月 16 日正式通过了 CIS 组织的全部认证流程并发布对应的 CIS Aliyun Linux 2 Benchmark version 1.0.0。ACK 正在支持对基于 Alibaba Cloud Linux 操作系统的集群进行 CIS 安全加固来满足简单、快捷、稳定、安全的使用需求。除 CIS 合规外,2021 年 1 月,ACK 已经正式支持对基于 Alibaba Cloud Linux 操作系统的集群进行等保加固

在容器管控侧,阿里云容器服务基于 CIS Kubernetes 等业界安全标准基线对容器管控面组件配置进行默认的安全加固,同时遵循权限最小化原则收敛管控面系统组件和集群节点的默认权限,最小化攻击面。三月,阿里云容器服务提交的 CIS Kubernetes benchmark for ACK 正式通过 CIS 社区组织的认证审核,成为国内首家发布 CIS Kubernetes 国际安全标准基线的云服务商

统一的身份标识体系和访问控制策略模型是在零信任安全模型下构建安全架构的核心,ACK 管控侧和阿里云 RAM 账号系统打通,提供了基于统一身份模型和集群证书访问凭证的自动化运维体系,同时面对用户凭证泄露的风险,创新的提出了用户凭证吊销的方案,帮助企业安全管理人员及时吊销可能泄露的集群访问凭证,避免越权访问攻击事件。

针对密钥管理、访问控制、日志审计这些企业应用交互访问链路上关键的安全要素,ACK 容器服务也提供了对应的平台侧安全能力:

  • 访问控制:ACK 基于 K8s RBAC 策略模型提供集群内应用资源的访问控制能力,在保证非主账号或集群创建者默认无权限的安全前提下,集群管理员可以通过控制台或 OpenAPI 的方式对指定的子账号或 RAM 角色进行集群和账号维度的批量 RBAC 授权,ACK 面向企业常见授权场景,提供了四种预置的权限模板,进一步降低了用户对 RBAC 及 K8s 资源模型的学习成本。对于应用容器中通常依赖的集群访问凭证 serviceaccount,ACK 集群支持开启针对 serviceaccount 的令牌卷投影特性,支持对 sa token 配置绑定 audience 身份,并且支持过期时间的设置,进一步提升了应用对管控面 apiserver 的访问控制能力。
  • 密钥管理:针对企业客户对数据安全自主性和合规性的要求,ACK Pro 集群支持对 K8s Secret 的落盘加密能力,同时支持使用 BYOK 的云盘加密能力,保证企业核心数据安心上云;同时 ACK 集群支持将用户托管在阿里云 KMS 凭据管家中的敏感信息实时同步到应用集群中,用户在 K8s 应用中直接挂载凭据同步的指定 secret 实例即可,进一步避免了对应用敏感信息的硬编码问题。
  • 日志审计:ACK 除了支持 K8s 集群 audit 审计,controlplane 管控面组件日志等基本的管控面日志采集外,还支持对 Ingress 流量的日志审计和基于 NPD 插件的异常事件告警。以上日志审计能力均对接了阿里云 SLS 日志服务,通过 SLS 服务提供的快速检索、日志分析和丰富的 dashboard 展示能力,大大降低了对容器应用开发运维和安全审计的难度。

面向容器应用层在供应链和运行时刻的安全挑战,阿里云从容器应用的构建、部署到运行全生命周期,提供全方位覆盖的安全能力:

3.jpg
图 3 – ACK 容器服务应用全生命周期安全能力

  • 应用构建阶段

据 Prevasio 对于托管在 Docker Hub 上 400 万个容器镜像的调查统计,有 51% 的镜像存在高危漏洞;另外有 6432 个镜像被检测出包含恶意木马或挖矿程序,而光这 6432 个恶意镜像就已经被累计下载了 3 亿次。

如何应对这些潜伏于镜像制品中的安全挑战,一方面要求企业应用开发者在构建应用镜像时使用可信的基础镜像,规范化镜像构建流程, 保证镜像最小化;另一方面阿里云 ACR 容器镜像服务针对镜像构建流程中的安全风险,提供了仓库权限的访问控制,操作审计和镜像安全扫描等基础能力。其中镜像安全扫描是用户能够主动发现安全漏洞的基础手段,ACR 容器镜像服务阿里云云安全中心提供了不同版本的镜像漏洞库,在支持镜像深度扫描的同时具备漏洞库的实时更新能力,满足企业安全合规需求。在阿里云容器镜像服务企业版中还可以通过创建和管理交付链实例,将安全扫描和分发流程自由组合并内置到自动化任务中并且自动拦截包含漏洞的镜像,确保分发到仓库中镜像的安全性。

在镜像构建环节,除了及时发现镜像漏洞,如何在保证镜像在分发和部署时刻不被恶意篡改也是重要的安全防护手段,这就需要镜像的完整性校验。在阿里云容器服务企业版实例中,企业安全管理人员可以配置加签规则用指定的 KMS 密钥自动加签推送到仓库中的镜像。

  • 应用部署时刻

K8s 原生的 admission 准入机制为应用部署时刻提供了天然的校验机制。

滥用特权容器,敏感目录挂载,以 root 用户启动容器,这些常见的应用模板配置都很可能成为容器逃逸攻击的跳板。K8s 原生的 PSP 模型通过策略定义的方式约束应用容器运行时刻的安全行为。ACK 容器服务提供面向集群的策略管理功能,帮助企业安全运维人员根据不同的安全需求定制化 PSP 策略实例,同时绑定到指定的 ServiceAccount 上,对 PSP 特性的一键式开关也面向用户屏蔽了其复杂的配置门槛。此外,ACK 容器服务还支持 gatekeeper 组件的安装管理,用户可以基于 OPA 策略引擎更为丰富的场景下定制安全策略。

针对应用镜像在部署时刻的安全校验需求,谷歌在 18 年率先提出了 Binary Authorization 的产品化解决方案。ACK 容器服务也在去年初正式落地了应用部署时刻的镜像签名和验签能力。通过安装定制化的 kritis 组件,企业安全运维人员可以通过定制化的验签策略保证应用部署镜像的安全性,防止被篡改的恶意镜像部署到企业生产环境中。

4.jpg
图 4 –  一致性安全策略管理

  • 应用运行时刻

企业应用的稳定运行离不开运行时刻的安全防护手段。ACK 容器服务和云安全中心团队合作,面向容器内部入侵,容器逃逸,病毒和恶意程序,异常网络连接等常见的运行时刻攻击行为进行实时监控和告警,同时云安全中心还提供了针对告警事件的溯源和攻击分析能力。与此同时,ACK 容器服务基于业界安全基线和最佳实践,面向集群内运行应用提供了一键化的免费安全巡检能力,通过巡检任务及时暴露运行中容器应用在健康检查/资源限制/网络安全参数/安全参数等配置上不符合基线要求的危险配置,并提示用户修复建议,避免可能发生的攻击。

对于安全隔离程度要求较高的企业客户可以选择使用安全沙箱容器集群,安全沙箱容器基于轻量虚拟化技术实现,应用运行在独立的内核中,具备更好的安全隔离能力,适用于不可信应用隔离、故障隔离、性能隔离、多用户间负载隔离等多种场景。

对于金融支付,区块链等对数据计算过程中的完全性,完整性和机密性有强安全诉求的场景,可以选择部署使用 ACK-TEE 机密计算托管集群,其中机密计算基于 Intel SGX 技术,支持将重要的数据和代码防止在一个特殊的可信执行加密环境(Trusted Execution Environment,TEE)中,而不会暴露给系统其他部分。其他应用、BIOS、OS、Kernel、管理员、运维人员、云服务商、甚至除了 CPU 以外的其他硬件均无法访问机密计算平台数据,极大减少敏感数据的泄露风险。

5.jpg
图 5 – 容器应用安全配置巡检

6.jpg
图 6 – 容器应用运行时刻安全监控

安全是企业上云的首要关切

安全是企业上云的首要关切。随着云原生对计算基础设施和企业应用架构的重定义,容器作为云的新界面,也将紧跟云原生的发展大潮,向更加安全、可信的方向发展。未来,阿里云容器服务将始终以“让企业放心上云,安心用云”为目标,在容器安全领域保持世界级的竞争力,在不断夯实自身基础设施安全的基础上,为客户的应用安全保驾护航。

参考资料

使用 KubeKey 安装部署 Kubernetes 与 Kube-OVN

KubeSphere阅读(14766)评论(0)

使用 KubeKey 安装部署 k8s 与 Kube-OVN

作者简介:林瑞超,锐捷网络开发工程师, KubeSphere 社区 contributor, 关注Kube-OVN, Cilium 等容器网络相关技术

背景

KubeKey 是 KubeSphere V3.0 新增的安装方式,用户可以一键部署 Kubernetes 和 KubeSphere。Kube-OVN 是一款基于 OVS/OVN 的 Kubernetes 网络编排系统。本文将为大家介绍如何使用 KubeKey 来安装部署 Kubernetes 和 Kube-OVN。

KubeKey 简介

KubeKey 是 Kubernetes 和 KubeSphere 的新一代 Installer(安装程序),旨在更方便、快速、高效和灵活地安装 Kubernetes 与 KubeSphere。KubeKey 摒弃了原来 Ansible 带来的依赖问题,用 Go 重写,支持单独 Kubernetes 或整体安装 KubeSphere。它也是扩展和升级集群的有效工具。

Kube-OVN 简介

Kube-OVN 是一款开源企业级云原生 Kubernetes 容器网络编排系统,它通过将 OpenStack 领域成熟的网络功能平移到 Kubernetes,极大增强了 Kubernetes 容器网络的安全性、可运维性、管理性和性能。在上个月 Kube-OVN 加入了 CNCF Sandbox。

准备工作

  1. 满足 KubeKey 的安装条件
  2. 满足 Kube-OVN 的安装条件(主要是内核版本需要满足要求)

安装步骤

  1. 下载 KubeKey

如果能正常访问 GitHub/Googleapis,可以从 GitHub 发布页面下载 KubeKey 或直接使用以下命令。

curl -sfL https://get-kk.kubesphere.io | VERSION=v1.0.1 sh -

如果访问 GitHub/Googleapis 受限先执行以下命令以确保从正确的区域下载 KubeKey。

export KKZONE=cn

执行以下命令下载 KubeKey。

curl -sfL https://get-kk.kubesphere.io | VERSION=v1.0.1 sh -

下载 KubeKey 后,如果将其传至新的机器,且访问 Googleapis 同样受限,在执行以下步骤之前务必再次执行 export KKZONE=cn 命令。执行以上命令会下载最新版 KubeKey (v1.0.1),可以修改命令中的版本号下载指定版本。

为 kk 添加可执行权限:

chmod +x kk

创建示例配置文件:

./kk create cluster --with-kubernetes v1.17.9

完整的文档请参考官方文档

  1. 修改生成的 config-sample.yaml 文件, 把网络插件改成 Kube-OVN,配置如下:
apiVersion: kubekey.kubesphere.io/v1alpha1
kind: Cluster
metadata:
  name: example
spec:
  hosts:
  - {name: node1, address: 192.168.0.183, internalAddress: 192.168.0.183, port: 22, user: root, password: Qcloud@123}
  roleGroups:
    etcd:
     - node1
    master:
     - node1
    worker:
     - node1
  controlPlaneEndpoint:
    domain: lb.kubesphere.local
    address: ""
    port: 6443
  kubernetes:
    version: v1.17.9
    imageRepo: kubesphere
    clusterName: cluster.local
    masqueradeAll: false
    maxPods: 110
    nodeCidrMaskSize: 24
    proxyMode: ipvs
  network:
    plugin: kubeovn
    kubeovn:
      joinCIDR: 100.64.0.0/16  #joinCIDR地址
      enableSSL: true   #开启SSL
      enableMirror: true    #是否开启流量镜像
      pingerExternalAddress: 114.114.114.114 #ping external地址
      networkType: geneve   #网络类型, 可选geneve与vlan, 如果选择vlan, vlan网卡名称必须填写
      vlanInterfaceName: interface_name  #vlan网卡名称
      vlanID: '100'    #默认vlanID
      dpdkMode: false  #是否dpdk模式
    kubePodsCIDR: 10.233.64.0/18
    kubeServiceCIDR: 10.233.0.0/18
   registry:
    registryMirrors: []
    insecureRegistries: []
    privateRegistry: ""
  addons: []

在上面的 yaml 中 Kube-OVN 的配置可以不用填写,将使用默认的配置安装 Kube-OVN, 即配置可简化成如下:

 network:
   plugin: kubeovn
   kubePodsCIDR: 10.233.64.0/18
   kubeServiceCIDR: 10.233.0.0/18

部署

./kk create cluster -f config-sample.yaml

在安装过程中,能看到 Kube-OVN 的部署信息,看到Congratulations信息,表示集群已经安装成功了。使用 KubeKey 安装部署 k8s 与 Kube-OVN

通过kubectl get pod -A能看到 Kube-OVN 相关的 Pod 已经都正常运行使用 KubeKey 安装部署 k8s 与 Kube-OVN

查看当前的子网kubectl get subnet,能看到 join 子网与 ovn-default 子网:使用 KubeKey 安装部署 k8s 与 Kube-OVN

如何使用 Kube-OVN

在 Kube-OVN 中通过子网组织 IP,一个或多个 Namespace 可以被绑定到一个子网中,这些 Namespace 下的 Pod 将会从该子网中分配 IP,并使用子网下的网络配置。如果 Pod 绑定的 Namespace 没有绑定子网,将使用默认子网 ovn-default 为其分配 IP 地址。 在
https://github.com/alauda/kube-ovn/wiki
 上有关于 Kube-OVN 详细的使用教程,可移步 Kube-OVN 社区查看。使用 KubeKey 安装部署 k8s 与 Kube-OVN

创建自定义子网

apiVersion: kubeovn.io/v1
kind: Subnet
metadata:
  name: ls1
spec:
  protocol: IPv4
  cidrBlock: 10.100.0.0/16   #设置子网网段
  excludeIps:
  - 10.100.0.1..10.100.0.10  #设置子网排除(不使用)范围
  gateway: 10.100.0.1        #设置子网的网关地址
  namespaces:                #设置子网绑定的命名空间
  - ls1

子网的配置如上(相关字段的含义注释中有说明), kubectl apply之后再kubectl get subnet 能看到子网已经创建出来,通过kubectl get subnet ls1 -o yaml 可以查看子网的状态是否可用。使用 KubeKey 安装部署 k8s 与 Kube-OVN使用 KubeKey 安装部署 k8s 与 Kube-OVN

创建 Pod 并绑定自定义子网

我们已经创建了子网 ls1 并绑定了命名空间 ls1, 接下来我们创建一个 Pod 并绑定 ls1 命名空间:

创建命名空间 kubectl create ns ns1使用 KubeKey 安装部署 k8s 与 Kube-OVN

创建 Nginx Pod 并绑定 ls1 `kubectl run

使用 KubeKey 安装部署 k8s 与 Kube-OVN

通过上面两个步骤,Pod 已经创建出来了,并且分配的 IP 地址在排除地址范围外,通过kubectl get ip可以查看 Pod 分配到的 IP 地址与 mac 地址等信息

使用 KubeKey 安装部署 k8s 与 Kube-OVN

关于 KubeSphere

KubeSphere (https://kubesphere.io)是在 Kubernetes 之上构建的开源容器混合云,提供全栈的 IT 自动化运维的能力,简化企业的 DevOps 工作流。

KubeSphere 已被 Aqara 智能家居、本来生活、新浪、华夏银行、四川航空、国药集团、微众银行、紫金保险、中通、中国人保寿险、中国太平保险、中移金科、Radore、ZaloPay 等海内外数千家企业采用。KubeSphere 提供了开发者友好的向导式操作界面和丰富的企业级功能,包括多云与多集群管理、Kubernetes 资源管理、DevOps (CI/CD)、应用生命周期管理、微服务治理 (Service Mesh)、多租户管理、监控日志、告警通知、审计事件、存储与网络管理、GPU support 等功能,帮助企业快速构建一个强大和功能丰富的容器云平台。

 ✨ GitHub:https://github.com/kubesphere
 💻 官网(中国站):https://kubesphere.com.cn
 👨‍💻‍ 微信群:请搜索添加群助手微信号 kubesphere
微信公众号:KubeSphere云原生
关注请扫描二维码:

三步搞定 ARM64 离线部署 Kubernetess + KubeSphere

KubeSphere阅读(3586)评论(0)

背景

随着我国对信息安全的愈发重视,国产化的趋势也越来越浓,包括国产操作系统、国产 CPU 等。由于 ARM 架构国产 CPU 在维持创新可信和先进性方面的潜在优势,其应用也将会越来越广泛。

KubeSphere 作为一款深受国内外开发者所喜爱的开源容器平台,也将积极参与并探索在 ARM 架构下的应用与创新。本文将主要介绍如何在 ARM64 环境下部署 Kubernetes 和 KubeSphere。

环境准备

节点

kubeSphere 支持的操作系统包括:

  • Ubuntu 16.04, 18.04
  • Debian Buster, Stretch
  • CentOS/RHEL 7
  • SUSE Linux Enterprise Server 15
  • openEuler

这里以一台 openEuler 20.09 64bit 为例:

 

 

 

确保机器已经安装所需依赖软件(sudo curl openssl ebtables socat ipset conntrack docker)

具体环境要求参见:
https://github.com/kubesphere/kubekey/tree/release-1.0#
requirements-and-recommendations

关于多节点安装请参考 KubeSphere 官方文档

建议:可将安装了所有依赖软件的操作系统制作成系统镜像使用,避免每台机器都安装依赖软件,即可提升交付部署效率,又可避免依赖问题的发生。

提示:如使用 centos7.x、ubuntu18.04,则可以选择使用 kk 命令对机器进行初始化。解压安装包,并创建好配置文件之后(创建方法请看下文),可执行如下命令对节点进行初始化: ./kk init os -s ./dependencies -f config-example.yaml 如使用该命令遇到依赖问题,可自行安装相关依赖软件。

镜像仓库

可使用 harbor 或其他第三方镜像仓库。

提示:可使用 kk 命令自动创建测试用自签名镜像仓库。注意,请确保当前机器存在registry:2,如没有,可从解压包
kubesphere-images-v3.0.0/registry.tar 中导入,导入命令:docker load < registry.tar。创建测试用自签名镜像仓库:./kk init os -f config-example.yaml --add-images-repo注意:由 kk 启动的镜像仓库端口为443,请确保所有机器均可访问当前机器443端口。镜像数据存储到本地/mnt/registry (建议单独挂盘)。

安装包下载:

提示:该安装包仅包含 Kubernetes + KubeSphere-core 镜像,如需更多组件 arm64 镜像,可自行编译构建。

# md5: 3ad57823faf2dfe945e2fe3dcfd4ace9
curl -Ok https://kubesphere-installer.pek3b.qingstor.com/offline/v3.0.0/kubesphere-core-v3.0.0-offline-linux-arm64.tar.gz

安装步骤:

1. 创建集群配置文件

安装包解压后进入
kubesphere-core-v3.0.0-offline-linux-arm64

./kk create config

根据实际环境信息修改生成的配置文件config-sample.yaml,也可使用-f参数自定义配置文件路径。kk 详细用法可参考:
https://github.com/kubesphere/kubeey

注意填写正确的私有仓库地址privateRegistry(如已准备好私有仓库可设置为已有仓库地址,若使用 kk 创建私有仓库,则该参数设置为:dockerhub.kubekey.local)

apiVersion: kubekey.kubesphere.io/v1alpha1
kind: Cluster
metadata:
  name: sample
spec:
  hosts:
  # 注意指定节点 arch 为 arm64
  - {name: node1, address: 172.169.102.249, internalAddress: 172.169.102.249, password: Qcloud@123, arch: arm64}
  roleGroups:
    etcd:
    - node1
    master:
    - node1
    worker:
    - node1
  controlPlaneEndpoint:
    domain: lb.kubesphere.local
    address: ""
    port: 6443
  kubernetes:
    version: v1.17.9
    imageRepo: kubesphere
    clusterName: cluster.local
  network:
    plugin: calico
    kubePodsCIDR: 10.233.64.0/18
    kubeServiceCIDR: 10.233.0.0/18
  registry:
    registryMirrors: []
    insecureRegistries: []
    privateRegistry: dockerhub.kubekey.local
  addons: []

2. 导入镜像

进入
kubesphere-all-v3.0.0-offline-linux-arm64/kubesphere-images-v3.0.0
使用
offline-installation-tool.sh 将镜像导入之前准备的仓库中:

# 脚本后镜像仓库地址请填写真实仓库地址
./offline-installation-tool.sh -l images-list-v3.0.0.txt -d kubesphere-images -r dockerhub.kubekey.local

3. 执行安装

# 以上准备工作完成且再次检查配置文件无误后,执行安装。
./kk create cluster -f config-sample.yaml --with-kubesphere

查看结果

ARM64 离线部署 K8s + KubeSphere

ARM64 离线部署 K8s + KubeSphere

关于 KubeSphere

KubeSphere (https://kubesphere.io)是在 Kubernetes 之上构建的开源容器混合云,提供全栈的 IT 自动化运维的能力,简化企业的 DevOps 工作流。

KubeSphere 已被 Aqara 智能家居、本来生活、新浪、华夏银行、四川航空、国药集团、微众银行、紫金保险、中通、中国人保寿险、中国太平保险、中移金科、Radore、ZaloPay 等海内外数千家企业采用。KubeSphere 提供了开发者友好的向导式操作界面和丰富的企业级功能,包括多云与多集群管理、Kubernetes 资源管理、DevOps (CI/CD)、应用生命周期管理、微服务治理 (Service Mesh)、多租户管理、监控日志、告警通知、审计事件、存储与网络管理、GPU support 等功能,帮助企业快速构建一个强大和功能丰富的容器云平台。

 ✨ GitHub:https://github.com/kubesphere
 💻 官网(中国站):https://kubesphere.com.cn
 👨‍💻‍ 微信群:请搜索添加群助手微信号 kubesphere

在 Kubernetes Pod 中如何获取客户端的真实 IP

KubeSphere阅读(2520)评论(0)

创建一个后端服务

服务选择

这里选择 containous/whoami 作为后端服务镜像。在 Dockerhub 的介绍页面,可以看到访问其 80 端口时,会返回客户端的相关信息。在代码中,我们可以在 Http 头部中拿到这些信息。

Hostname : 6e0030e67d6a
IP : 127.0.0.1
IP : ::1
IP : 172.17.0.27
IP : fe80::42:acff:fe11:1b
GET / HTTP/1.1
Host: 0.0.0.0:32769
User-Agent: curl/7.35.0
Accept: */*

集群环境

我们使用开源工具 Kubekey 搭建了一套 Kubernetes 集群环境,使用 KubeSphere 来管理。简单介绍一下集群的状况。集群有三个节点,一个 master ,两个 worker 节点。如下图:

创建服务

  • 创建企业空间、项目

如下图所示,这里将企业空间和项目命名为 realip

  • 创建服务

这里创建无状态服务,选择 containous/whoami 镜像,使用默认端口。

  • 将服务改为 NodePort 模式

编辑服务的外网访问方式,修改为 NodePort 模式。

查看访问服务的 NodePort 端口,发现端口为 31509。

  • 访问服务

浏览器打开 Master 节点的 EIP + :31509 时,返回如下内容:

Hostname: myservice-fc55d766-9ttxt
IP: 127.0.0.1
IP: 10.233.70.42
RemoteAddr: 192.168.13.4:21708
GET / HTTP/1.1
Host: dev.chenshaowen.com:31509
User-Agent: Chrome/86.0.4240.198 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: lang=zh;
Dnt: 1
Upgrade-Insecure-Requests: 1

可以看到 RemoteAddr 是 Master 节点的 IP ,并不是访问客户端的真实 IP 地址。这里的 Host 指的是访问入口的地址,为了方便快速访问,我使用的是域名,并不影响测试结果。

直接通过 NortPort 访问获取真实 IP

在上面的访问中,获取不到客户端真实 IP 的原因是 SNAT 使得访问 SVC 的源 IP 发生了变化。将服务的 externalTrafficPolicy 改为 Local 模式可以解决这个问题。

打开服务的配置编辑页面

将服务的 externalTrafficPolicy 设置为 Local 模式。

访问服务,可以得到如下内容:

Hostname: myservice-fc55d766-9ttxt
IP: 127.0.0.1
IP: 10.233.70.42
RemoteAddr: 139.198.254.11:51326
GET / HTTP/1.1
Host: dev.chenshaowen.com:31509
User-Agent: hrome/86.0.4240.198 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cache-Control: max-age=0
Connection: keep-alive
Cookie: lang=zh;
Dnt: 1
Upgrade-Insecure-Requests: 1

Cluster 隐藏了客户端源 IP,可能导致第二跳到另一个节点,但具有良好的整体负载分布。 Local 保留客户端源 IP 并避免 LoadBalancer 和 NodePort 类型服务的第二跳,但存在潜在的不均衡流量传播风险。

下面是对比简图:

当请求落到没有服务 Pod 的节点时,将无法访问。用 curl 访问时,会一直停顿在 TCP_NODELAY , 然后提示超时:

* Trying 139.198.112.248...
* TCP_NODELAY set
* Connection failed
* connect to 139.198.112.248 port 31509 failed: Operation timed out
* Failed to connect to 139.198.112.248 port 31509: Operation timed out
* Closing connection 0

通过 LB -> Service 访问获取真实 IP

在生产环境,通常会有多个节点同时接收客户端的流量,如果仅使用 Local 模式将会导致服务可访问性变低。引入 LB 的目的是为了利用其探活的特点,仅将流量转发到存在服务 Pod 的节点上。

这里以青云的 LB 为例进行演示。在青云的控制,可以创建 LB ,添加监听器,监听 31509 端口,可以参考LB 的使用文档,在此不再赘述。

如下图可以看到,在服务的 31509 端口仅 master 节点处于活跃状态,流量也仅会导向 master 节点,符合预期。

接着继续增加副本数量到 3

遗憾的是,Pod 并没有均匀分布在三个节点,其中有两个处于 master 上。因此 LB 的后端节点也没有完全点亮。如下图:

这就需要给 deploy 加上反亲和性的描述。有两种选择。第一种是配置软策略,但不能保证全部 LB 后端点亮,均匀分配到流量。

spec:
template:
metadata:
labels:
app: myservice
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- myservice
topologyKey: kubernetes.io/hostname

另一种是配置硬策略,强制 Pod 分配在不同的节点上,但会限制副本数量,也就是 Pod 总数不能超过 Node 总数。

spec:
template:
metadata:
labels:
app: myservice
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- myservice
topologyKey: kubernetes.io/hostname

采用硬策略的配置,最终点亮全部后端,如下图:

通过 LB -> Ingress -> Service 访问获取真实 IP

如果每一个服务都占用一个 LB,成本很高,同时配置不够灵活,每次新增服务时,都需要去 LB 增加新的端口映射。

还有一种方案是 LB 将 80、443 的流量导给 Ingress Controller,然后将流量转发到 Service,接着达到 Pod 中的服务。

此时,需要 LB 能做 TCP 层的透传,或者 HTTP 层的带真实 IP 转发,将 Ingress Controller 的 externalTrafficPolicy 设置为 Local 模式,而 Service 可以不必设置为 Local 模式。

如果想要提高可访问性,同样可以参考上面配置反亲和性,保证在每个后端节点上都有 Ingress Controller 。

流量的转发路径:

LB(80/443) -> Ingress Controller(30000) -> myservice(80) -> myservice-fc55d766-xxxx(80)

首先需要勾选 LB 【获取客户端IP】的配置

接着开启项目的外网访问网关

然后添加服务的路由

最后还需要在【平台管理】-> 【集群管理】,进入集群,在系统项目 kubesphere-controls-system 中找到 realip 项目对应的网关。

编辑服务的配置文件,将 externalTrafficPolicy 改为 Local 模式即可。

访问服务,可以得到如下内容:

Hostname: myservice-7dcf6b965f-vv6md
IP: 127.0.0.1
IP: 10.233.96.152
RemoteAddr: 10.233.70.68:34334
GET / HTTP/1.1
Host: realip.dev.chenshaowen.com
User-Agent: Chrome/87.0.4280.67 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cache-Control: max-age=0
Cookie: _ga=GA1.2.896113372.1605489938; _gid=GA1.2.863456118.1605830768
Cookie: lang=zh;
Upgrade-Insecure-Requests: 1
X-Forwarded-For: 139.198.113.75
X-Forwarded-Host: realip.dev.chenshaowen.com
X-Forwarded-Port: 443
X-Forwarded-Proto: https
X-Original-Uri: /
X-Real-Ip: 139.198.113.75
X-Request-Id: 999fa36437a1180eda3160a1b9f495a4
X-Scheme: https

总结

本文介绍了三种获取真实 IP 的部署方式:

  • 直接通过 NortPort 访问获取真实 IP

受制于 Local 模式,可能会导致服务不可访问。需要保证对外提供入口的节点上,必须具有服务的负载。

  • 通过 LB -> Service 访问获取真实 IP

利用 LB 的探活能力,能够提高服务的可访问性。适用于服务较少,或者愿意每个服务一个 LB 的场景。

  • 通过 LB -> Ingress -> Service 访问获取真实 IP

通过 LB 将 80、443 端口的流量转到 Ingress Controller ,再进行服务分发。但 Ingress Controller 使用 Local 模式,就要求 LB 的每个后端节点都有 Ingress Controller 副本。适用于对外暴露服务数量较多的场景。

当然也可以组合使用,对于并不需要获取客户端真实 IP 的服务,可以继续使用 Cluster 模式。

参考

关于 KubeSphere

KubeSphere 是在 Kubernetes 之上构建的开源容器混合云,提供全栈的 IT 自动化运维的能力,简化企业的 DevOps 工作流。

KubeSphere 已被 Aqara 智能家居、本来生活、新浪、华夏银行、四川航空、国药集团、微众银行、紫金保险、中通、中国人保寿险、中国太平保险、中移金科、Radore、ZaloPay 等海内外数千家企业采用。KubeSphere 提供了开发者友好的向导式操作界面和丰富的企业级功能,包括多云与多集群管理、Kubernetes 资源管理、DevOps (CI/CD)、应用生命周期管理、微服务治理 (Service Mesh)、多租户管理、监控日志、告警通知、审计事件、存储与网络管理、GPU support 等功能,帮助企业快速构建一个强大和功能丰富的容器云平台。

 ✨ GitHub:https://github.com/kubesphere
 💻 官网(中国站):https://kubesphere.com.cn
 👨‍💻‍ 微信群:请搜索添加群助手微信号 kubesphere