【QCon】精华内容上线92%,全面覆盖“人工智能+”的典型案例!>>> 了解详情
写点什么

如何在 Kubernetes 中 Pod 间共享内存以实现高性能通信?

  • 2020-05-16
  • 本文字数:3446 字

    阅读完需:约 11 分钟

如何在Kubernetes中Pod间共享内存以实现高性能通信?

一些公共服务组件在追求性能过程中,与业务耦合太紧,造成在制作基础镜像时,都会把这些基础组件都打包进去,因此当业务镜像启动后,容器里面一大堆进程,这让 Kubernetes 对 Pod 的管理存在很大隐患。为了让业务容器瘦身,更是为了基础组件自身的管理更独立和方便,将基础组件从业务镜像中剥离并 DaemonSet 容器化部署。然而一些基础组件 Agent 与业务 Pod 之间通过共享内存的方式进行通信,同一 Node 中跨 Pod 的共享内存方案是首先要解决的问题。

为什么要将公共基础组件 Agent 进行 DaemonSet 部署

自研的公共基础组件,比如服务路由组件、安全组件等,通常以进程方式部署在 Node 上并同时为 Node 上所有的业务提供服务,微服务及容器化之后,服务数量成百上千的增长,如果以 sidecar 或者打包到业务 Image 中继续 Per Pod Per Agent 的方式部署, 那么基础组件的 Server 端的压力可能也会成百上千的增长,风险是很大的。因此,我们希望能以 DaemonSet 方式部署这些组件的 Agents。


先说说 Kubernetes 大行其道的今天,如果不将这些基础组件从业务 Pod 中剥离,存在哪些问题:


  • 业务容器中存在一大堆进程,我们在为 Pod 申请资源(cpu/mem request and limit)时,不仅要考虑业务应用本身的资源消耗,还要考虑这些基础组件的资源消耗。而且一旦某些 Agent 有 Bug,比如内存泄漏,这将导致 Pod 牵连被重建,甚至 Cgroup OOM 在 kill 进程时,可能将业务进程 kill 了。

  • 违背了 Kubernetes&微服务的部署最佳实践:Per Process Per Contaienr,并且业务进程在前台运行,使其与容器共生死,不然这将导致 Kubernetes 无法根据业务进程状态关联到容器状态,进而进行高可用管理。

  • 一个 Node 上运行 10 个 Pod,那么就会有 x10 的基础组件数量在 Node 上。没有容器化之前,一个 Node 只要部署一个组件进程即可,容器化之后,集群中组件 Agents 数量要几十倍的增长,如果业务进行了微服务拆分,这个指数会更大,这些基础组件服务端是否能承受比以往高几十倍上百倍的通信请求,这是未知的。

  • 如果你要全网升级某个基础组件 Agent,那你可能会疯掉,你需要重新打所有业务镜像,然后全网业务要进行灰度升级。因为一个 Agent 的升级,导致你不得不重建业务 Pod。你可能会说,基础组件 Agents 都会有自己的热升级方案,我们通过它们的方案升级就好了呀,那你将引入很大麻烦:Agents 的热升级因为无法被 Kubernetes 感知,将引发 Kubernetes 中集群中的数据不一致问题,那就真的要回到虚拟机或者物理机部署的玩法了。当然,这样的需求,我们也想过通过 Operator 也实现,但代价太大了,而且很不 CloudNative!


将基础组件 Agents 从业务 Pod 中剥离,以上的问题都能解决了,架构上的解耦带来的好处无需多言。而且我们可以通过 Kubernetes 管理这些基础组件 Agents 了,享受其自愈、滚动升级等好处。

Linux 共享内存机制

然而,理想很美好,现实很残酷。首先要解决的问题是,有些组件 Agent 与业务 Pod 之间是通过共享内存通信的,这跟 Kubernetes&微服务的最佳实践背道而驰。


大家都知道,Kubernetes 单个 Pod 内是共享 IPC 的,并且可以通过挂载 Medium 为 Memory 的 EmptyDir Volume 共享同一块内存 Volume。


首先我们来了解一下 Linux 共享内存的两种机制:


  • POSIX 共享内存(shm_open()、shm_unlink())

  • System V 共享内存(shmget()、shmat()、shmdt())


其中,System V 共享内存历史悠久,一般的 UNIX 系统上都有这套机制;而 POSIX 共享内存机制接口更加方便易用,一般是结合内存映射 mmap 使用。


mmap 和 System V 共享内存的主要区别在于:


  • sysv shm 是持久化的,除非被一个进程明确的删除,否则它始终存在于内存里,直到系统关机

  • mmap 映射的内存在不是持久化的,如果进程关闭,映射随即失效,除非事先已经映射到了一个文件上

  • /dev/shm 是 Linux 下 sysv 共享内存的默认挂载点


POSIX 共享内存是基于 tmpfs 来实现的。实际上,更进一步,不仅 PSM(POSIX shared memory),而且 SSM(System V shared memory)在内核也是基于 tmpfs 实现的。


从这里可以看到 tmpfs 主要有两个作用:


  • 用于 SYSV 共享内存,还有匿名内存映射;这部分由内核管理,用户不可见

  • 用于 POSIX 共享内存,由用户负责 mount,而且一般 mount 到/dev/shm ;依赖于 CONFIG_TMPFS


虽然 System V 与 POSIX 共享内存都是通过 tmpfs 实现,但是受的限制却不相同。 也就是说/proc/sys/kernel/shmmax 只会影响 SYS V 共享内存,/dev/shm 只会影响 Posix 共享内存 。实际上,System V 与 Posix 共享内存本来就是使用的两个不同的 tmpfs 实例(instance)。


SYS V 共享内存能够使用的内存空间只受/proc/sys/kernel/shmmax 限制;而用户通过挂载的/dev/shm,默认为物理内存的 1/2。


概括一下:

POSIX 共享内存与 SYS V 共享内存在内核都是通过 tmpfs 实现,但对应两个不同的 tmpfs 实例,相互独立。

通过/proc/sys/kernel/shmmax 可以限制 SYS V 共享内存的最大值,通过/dev/shm 可以限制 POSIX 共享内存的最大值(所有之和)。

同一 Node 上跨 Pod 的共享内存方案

基础组件 Agents DaemonSet 部署后,Agents 和业务 Pod 分别在同一个 Node 上不同的 Pod,那么 Kubernetes 该如何支持这两种类型的共享内存机制呢?



当然,安全性上做出了牺牲,但在非容器化之前 IPC 的隔离也是没有的,所以这一点是可以接受的。

灰度上线

对于集群中的存量业务,之前都是将 Agents 与业务打包在同一个 docker image,因此需要有灰度上线方案,以保证存量业务不受影响。


  • 首先创建好对应的 Kubernetes ClusterRole, SA, ClusterRoleBinding, PSP Object。关于 PSP 的内容,请参考官方文档介绍 pod-security-policy。

  • 在集群中任意选择部分 Node,给 Node 打上 Label(AgentsDaemonSet:YES)和 Taint(AgentsDaemonSet=YES:NoSchedule)。


$ kubectl label node $nodeName AgentsDaemonSet=YES$ kubectl taint node $nodeName AgentsDaemonSet=YES:NoSchedule
复制代码


  • 部署 Agent 对应的 DaemonSet(注意 DaemonSet 需要加上对应的 NodeSelector 和 Toleration, Critical Pod Annotations), Sample as follows:


apiVersion: apps/v1kind: DaemonSetmetadata:  name: demo-agent  namespace: kube-system  labels:    k8s-app: demo-agentspec:  selector:    matchLabels:      name: demo-agent  template:    metadata:      annotations:        scheduler.alpha.kubernetes.io/critical-pod: ""      labels:        name: demo-agent    spec:      tolerations:      - key: "AgentsDaemonSet"        operator: "Equal"        value: "YES"        effect: "NoSchedule"      hostNetwork: true      hostIPC: true      nodeSelector:        AgentsDaemonSet: "YES"      containers:      - name: demo-agent        image: demo_agent:1.0        volumeMounts:        - mountPath: /dev/shm          name: shm        resources:          limits:            cpu: 200m            memory: 200Mi          requests:            cpu: 100m            memory: 100Mi      volumes:      - name: shm        hostPath:          path: /dev/shm          type: Directory
复制代码


  • 在该 Node 上部署不包含基础组件 Agent 的业务 Pod,检查所有基础组件和业务是否正常工作,如果正常,再分批次选择剩余 Nodes,加上 Label(AgentsDaemonSet:YES)和 Taint(AgentsDaemonSet=YES:NoSchedule),DaemonSet Controller 会自动在这些 Nodes 创建这些 DaemonSet Agents Pod。如此逐批次完成集群中基础组件 Agents 的灰度上线。

总结

在高并发业务下,尤其还是以 C/C++代码实现的基础组件,经常会使用共享内存通信机制来追求高性能,本文给出了 Kubernetes Pod 间 Posix/SystemV 共享内存方式的折中方案,以牺牲一定的安全性为代价,请知悉。当然,如果微服务/容器化改造后,基础服务的 Server 端确定不会有压力,那么建议以 SideCar Container 方式将基础服务的 Agents 与业务 Container 部署在同一 Pod 中,利用 Pod 的共享 IPC 特性及 Memory Medium EmptyDir Volume 方式共享内存。


作者介绍


王涛,腾讯云高级工程师,西安电子科大硕士毕业,持续深耕云计算领域七年,目前在腾讯基于 TKE(Tencent Kubernetes Engine)构建 DevOps 平台,帮助集团自研业务上云,曾在华为、唯品会、vivo 从事企业私有云平台的建设工作,2014 年开始专注于 Kubernetes/Docker 等容器技术栈在 DevOps、AI Platform 方向的应用,积累了大量生产经验。


2020-05-16 17:151092

评论

发布
暂无评论
发现更多内容

本地MQTT协议消息服务远程连接教程介绍

EquatorCoco

Linux 本地化 mqtt 协议解析

外包的鄙视链,背后原因是什么

老张

外包 竞争力 核心竞争力

Screen Recorder by Omi Mac(Omi录屏专家‬)v1.3.5激活版

影影绰绰一往直前

预训练模型在迁移学习中的应用

百度开发者中心

深度学习 大模型 LLM

CodeWhisperer--手把手教你使用一个十分强大的工具

亚马逊云科技 (Amazon Web Services)

Python 人工智能 云上探索实验室 Amazon CodeWhisperer Amazon Cloud9

StoneDB顺利通过中科院软件所 2023 开源之夏 结项审核

StoneDB

MySQL 数据库 HTAP StoneDB

万界星空科技云MES管理系统和ERP的对接

万界星空科技

数字化转型 mes 云mes 万界星空科技 万界星空科技mes

平凯星辰 TiDB 获评 “2023 中国金融科技守正创新扬帆计划” 十佳优秀实践奖

编程猫

助力开发者健康长效增长 OPPO 开启应用和服务生态新篇章

Geek_2d6073

更快更省更好用!天翼云云原生一体机iStack打通物云最后一公里!

天翼云开发者社区

云计算 云原生

Ghost Buster Pro for Mac直装激活版下载

影影绰绰一往直前

LED显示屏防护等级知识讲解

Dylan

LED显示屏 户外LED显示屏 led显示屏厂家 等级

【Linux 基础入门 + Java项目部署】

百度搜索:蓝易云

Java 云计算 Linux 运维 云服务器

Aiseesoft Video Repair for Mac(视频修复软件) 1.0.12永久激活版

mac

苹果mac Windows软件 视频修复软件 AIseesoft Video RepAIr

赛车竞速游戏:art of rally拉力赛车 for Mac 1.5.0中文版

繁星

赛车竞速游戏 Art of Rally

代码混淆的原理是什么?常见代码混淆方法介绍

雪奈椰子

苹果Mac动态壁纸:Dynamic Wallpaper 16.7中文版

繁星

动态壁纸 Dynamic Wallpaper

华秋这场技术研讨邀请了哪些重磅嘉宾?

华秋电子

任福继院士:基于交叉学科的研究将成主流,算力平台和计算人才是自主创新关键

Geek_2d6073

从商业增长到自然增长,OPPO广告联盟为开发者开辟增长新路径

Geek_2d6073

最新前端技术趋势——菜鸟必看

秃头小帅oi

前端

云主机CPU和内存配比:优化资源分配的关键

天翼云开发者社区

云计算 cpu 云主机

华为云GaussDB助力工商银行、华夏银行斩获“十佳卓越实践奖”

华为云开发者联盟

数据库 后端 华为云 华为云GaussDB 华为云开发者联盟

Mybatis和其他主流框架的整合使用

不在线第一只蜗牛

开源 mybatis 项目开发

Flyingbee PDF to PowerPoint for Mac(飞蜂pdf转ppt工具)v5.3.8激活版

影影绰绰一往直前

更快更省更好用!天翼云云原生一体机iStack打通物云最后一公里!

Geek_2d6073

KiCon Asia 2023完美落幕,助力Kicad生态繁荣,华秋在行动

华秋电子

kicad

使用 PPO 算法进行 RLHF 的 N 步实现细节

EquatorCoco

算法 ppo算法

巴适得板!这次我们和四川一起加“数”前行!

天翼云开发者社区

云计算 大数据

Apache环境php安装扩展swoole。

百度搜索:蓝易云

Apache 云计算 Linux swoole 云服务器

Gitlab配置mirrorRepository 镜像仓库

javaNice

Java gitlab

如何在Kubernetes中Pod间共享内存以实现高性能通信?_文化 & 方法_Rancher_InfoQ精选文章