select 共享内存 linux,Kubernetes中Pod间共享内存方案

二、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该如何支持这两种类型的共享内存机制呢?

5710bc875c8977a79fc763a2a9500bba.png

当然,安全性上做出了牺牲,但在非容器化之前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/v1

kind: DaemonSet

metadata:

name: demo-agent

namespace: kube-system

labels:

k8s-app: demo-agent

spec:

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: truehostIPC: 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: 100mmemory: 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方式共享内存。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值