OpenKruise v0(1)

阿里巴巴集团内部拥有着百万级的容器数量连同上面承载的上千个业务,因此,sidecar 容器的管理与升级也就成为了亟待完善的主题。因此,我们总结了内部许多 sidecar 容器的通用化需求,并将其沉淀到 OpenKruise 上面,最终抽象为 SidecarSet 作为管理和升级种类繁多 sidecar 容器的利器。

OpenKruise SidecarSet

==========================================================================================

SidecarSet 是 OpenKruise 中针对 sidecar 抽象出来的概念,负责注入和升级 Kubernetes 集群中的 sidecar 容器,是 OpenKruise 的核心 workload 之一。它提供了非常丰富的功能,用户使用 SidecarSet 可以非常方便实现 sidecar 容器的管理。主要特性如下:

  • 配置单独管理:为每一个 sidecar 容器配置单独的 SidecarSet 配置,方便管理。

  • 自动注入:在新建、扩容、重建 pod 的场景中,实现 sidecar 容器的自动注入。

  • 原地升级:支持不重建 pod 的方式完成 sidecar 容器的原地升级,不影响业务主容器,并包含丰富的灰度发布策略

注意:针对 Pod 中包含多个容器的模式,其中对外提供主要业务逻辑能力的容器称之为 主容器,其它一些如日志采集、安全、代理等辅助能力的容器称之为 Sidecar 容器。例如:一个对外提供 web 能力的 pod,nginx 容器提供主要的 web server 能力即为主容器,logtail 容器负责采集、上报 nginx 日志即为 Sidecar 容器。本文中的 SidecarSet 资源抽象也是为解决 Sidecar 容器的一些问题。

1. Sidecar logging architectures


应用日志可以让你了解应用内部的运行状况,日志对调试问题和监控集群活动非常有用。应用容器化后,最简单且最广泛采用的日志记录方式就是写入标准输出和标准错误。

但是,在当前分布式系统、大规模集群的时代下,上述方案还不足以达到生产环境的标准。首先,对于分布式系统而言,日志都是分散在单个容器里面,没有一个统一汇总的地方。其次,如果发生容器崩溃、Pod 被驱逐等场景,会出现日志丢失的情况。因此,需要一种更加可靠,独立于容器生命周期的日志解决方案。

Sidecar logging architectures 是将 logging agent 放到一个独立的 sidecar 容器中,通过共享日志目录的方式,实现容器日志的采集,然后存储到日志平台的后端存储。

1.png

阿里巴巴以及蚂蚁集团内部同样也是基于这种架构实现了容器的日志采集,下面我将介 绍OpenKruise SidecarSet 如何助力 Sidecar 日志架构在 Kubernetes 集群中的大规模落地实践

2. 自动注入


OpenKruise SidecarSet 基于 Kubernetes AdmissionWebhook 机制实现了 sidecar 容器的自动注入,因此只要将 sidecar 配置到 SidecarSet 中,不管用户用 CloneSet、Deployment、StatefulSet 等任何方式部署,扩出来的 Pod 中都会注入定义好的 sidecar 容器

2.png

Sidecar 容器的所有者只需要配置自身的 SidecarSet,就可以在业务无感知的情况下完成 sidecar 容器的注入,这种方式极大的降低了 sidecar 容器使用的门槛,也方便了 sidecar 所有者的管理工作。为了满足 sidecar 注入的多种场景,SidecarSet 除 containers 之外还扩展了如下字段:

sidecarset.yaml

apiVersion: apps.kruise.io/v1alpha1

kind: SidecarSet

metadata:

name: test-sidecarset

spec:

通过selector选择pod

selector:

matchLabels:

app: web-server

指定 namespace 生效

namespace: ns-1

container definition

containers:

  • name: logtail

image: logtail:1.0.0

共享指定卷

volumeMounts:

  • name: web-log

mountPath: /var/log/web

共享所有卷

shareVolumePolicy: disabled

环境变量共享

transferEnv:

  • sourceContainerName: web-server

TZ代表时区,例如:web-server容器中存在环境变量 TZ=Asia/Shanghai

envName: TZ

volumes:

  • name: web-log

emptyDir: {}

  • Pod 选择器

  • 支持 selector 来选择要注入的 Pod,如示例中将选择 labels[app] = web-server 的 pod,将 logtail 容器注入进去,也可以在所有的 pod 中添加一个 labels[inject/logtail] = true 的方式,来实现全局性的 sidecar 注入。

  • namespace:sidecarSet 默认是全局生效的,如果只想对某一个 namespace 生效,则配置该参数。

  • 数据卷共享

  • 共享指定卷:通过 volumeMounts 和 volumes 可以完成与主容器的特定卷的共享,如示例中通过共享 web-log volume 来达到日志采集的效果。

  • 共享所有卷:通过 shareVolumePolicy = enabled | disabled 来控制是否挂载 pod 主容器的所有卷卷,常用于日志收集等 sidecar,配置为 enabled 后会把应用容器中所有挂载点注入 sidecar 同一路经下(sidecar 中本身就有声明的数据卷和挂载点除外)。

  • 环境变量共享:可以通过 transferEnv 从其它容器中获取环境变量,会把名为 sourceContainerName 容器中名为 envName 的环境变量拷贝到本 sidecar 容器,如示例中日志 sidecar 容器共享了主容器的时区 TZ,这在海外环境中尤其常见。

注意:Kubernetes 社区对于已经创建的 Pod 不允许修改 container 数量,所以上述注入能力只能发生在 Pod 创建阶段,对于已经创建的 Pod 需要通过重建的方式来注入。

3. 原地升级


SidecarSet 不仅实现 sidecar 容器的注入,而且复用了 OpenKruise 中原地升级的特性,实现了在不重启 Pod 和主容器的前提下单独升级 sidecar 容器的能力。由于这种升级方式基本上能做到业务方无感知的程度,所以 sidecar 容器的升级已不再是上下交困的难题,从而极大解放了 sidecar 的所有者,提升了 sidecar 版本迭代的速度。

3.png

注意:Kubernetes 社区对于已经创建的 Pod 只允许修改 container.image 字段,因此对于 sidecar 容器的修改包含除 container.image 的其它字段,则需要通过 Pod 重建的方式,不能直接原地升级。

为了满足一些复杂的 sidecar 升级场景,SidecarSet 除了原地升级以外,还提供了非常丰富的灰度发布策略。

4. 灰度发布


灰度发布应该算是日常发布中最常见的一种手段,它能够比较平滑的完成 sidecar 容器的发布,尤其是在大规模集群的场景下,强烈建议使用这种方式。下面是首批暂停后续基于最大不可用滚动发布的例子,假设一个有 1000 个 pod 需要发布:

apiVersion: apps.kruise.io/v1alpha1

kind: SidecarSet

metadata:

name: sidecarset

spec:

updateStrategy:

type: RollingUpdate

partition: 980

maxUnavailable: 10%

上述配置首先发布(1000 - 980)= 20 个 pod 之后就会暂停发布,业务可以观察一段时间发现 sidecar 容器正常后,调整重新 update SidecarSet 配置:

apiVersion: apps.kruise.io/v1alpha1

kind: SidecarSet

metadata:

name: sidecarset

spec:

updateStrategy:

type: RollingUpdate

maxUnavailable: 10%

这样调整后,对于余下的 980 个 pod,将会按照最大不可用的数量(10% * 1000 = 100)的顺序进行发布,直到所有的 pod 都发布完成。

Partition 的语义是保留旧版本 Pod 的数量或百分比,默认为 0。这里的 partition 不表示任何 order 序号。如果在发布过程中设置了 partition:

  • 如果是数字,控制器会将 (replicas - partition) 数量的 Pod 更新到最新版本。

  • 如果是百分比,控制器会将 (replicas * (100% - partition)) 数量的 Pod 更新到最新版本。

MaxUnavailable 是发布过程中保证的,同一时间下最大不可用的 Pod 数量,默认值为 1。用户可以将其设置为绝对值或百分比(百分比会被控制器按照 selected pod 做基数来计算出一个背后的绝对值)。

注意:maxUnavailable 和 partition 两个值是没有必然关联。举例:

  • 当 {matched pod}=100,partition=50,maxUnavailable=10,控制器会发布 50 个 Pod 到新版本,但是发布窗口为 10,即同一时间只会发布 10 个 Pod,每发布好一个 Pod 才会再找一个发布,直到 50 个发布完成。

  • 当 {matched pod}=100,partition=80,maxUnavailable=30,控制器会发布 20 个 Pod 到新版本,因为满足 maxUnavailable 数量,所以这 20 个 Pod 会同时发布。

5. 金丝雀发布


对于有金丝雀发布需求的业务,可以通过 strategy.selector 来实现。方式:对于需要率先金丝雀灰度的 pod 打上固定的 labels[canary.release] = true,再通过 strategy.selector.matchLabels 来选中该 pod。

apiVersion: apps.kruise.io/v1alpha1

kind: SidecarSet

metadata:

name: sidecarset

spec:

updateStrategy:

type: RollingUpdate

selector:

matchLabels:

  • canary.release: true

maxUnavailable: 10%

上述配置只会发布打上金丝雀 labels 的容器,在完成金丝雀验证之后,通过将 updateStrategy.selector 配置去掉,就会继续通过最大不可用来滚动发布。

6. 打散发布


SidecarSet 对于 pod 的升级顺序,默认按照如下规则:

  • 对升级的 pod 集合,保证多次升级的顺序一致

  • 选择优先顺序是(越小优先级越高):unscheduled < scheduled, pending < unknown < running, not-ready < ready, newer pods < older pods。

除了上述默认发布顺序之外,scatter 打散策略允许用户自定义将符合某些标签的 Pod 打散到整个发布过程中。比如,对于像 logtail 这种全局性的 sidecar container,一个集群当中很可能注入了几十个业务 pod,因此可以使用基于 应用名 的方式来打散 logtail 的方式进行发布,实现不同应用间打散灰度发布的效果,并且这种方式可以同最大不可用一起使用。

apiVersion: apps.kruise.io/v1alpha1

kind: SidecarSet

metadata:

name: sidecarset

spec:

updateStrategy:

type: RollingUpdate

配置pod labels,假设所有的pod都包含labels[app_name]

scatterStrategy:

  • key: app_name

value: nginx

  • key: app_name

value: web-server

  • key: app_name

value: api-gateway

maxUnavailable: 10%

注意:当前版本必须要列举所有的应用名称,我们将在下个版本支持只配置 label key 的智能打散方式。

7. 实践


阿里巴巴以及蚂蚁集团内部已经大规模的使用 SidecarSet 来管理 sidecar 容器,下面我将通过日志采集 Logtail sidecar 来作为一个示例。

  1. 基于 sidecarSet.yaml 配置文件创建 SidecarSet 资源。

sidecarset.yaml

apiVersion: apps.kruise.io/v1alpha1

kind: SidecarSet

metadata:

name: logtail-sidecarset

spec:

selector:

matchLabels:

app: nginx

updateStrategy:

type: RollingUpdate

maxUnavailable: 10%

containers:

  • name: logtail

image: log-service/logtail:0.16.16

when recevie sigterm, logtail will delay 10 seconds and then stop

command:

  • sh

  • -c

  • /usr/local/ilogtail/run_logtail.sh 10

livenessProbe:

exec:

command:

  • /etc/init.d/ilogtaild

  • status

resources:

limits:

memory: 512Mi

requests:

cpu: 10m

memory: 30Mi

share this volume

volumeMounts:

  • name: nginx-log

mountPath: /var/log/nginx

transferEnv:

  • sourceContainerName: nginx

envName: TZ

volumes:

  • name: nginx-log

emptyDir: {}

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。**

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-rTWKw0p0-1715864105467)]

[外链图片转存中…(img-m8KKujkv-1715864105467)]

[外链图片转存中…(img-YT6tUX5W-1715864105468)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

  • 24
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值