• 【博客472】k8s中如何使用shared memory


    k8s中如何使用shared memory

    场景:

    需要在训练任务的pod内有两个服务,他们之间通过共享内存方式来交换数据,以获取更高的效率

    问题:

    注意:/dev/shm即为共享内存的大小

    kvm或者物理机器上,用户可以使用的共享内存为:

    root@pve:~# df -h
    Filesystem            Size  Used Avail Use% Mounted on
    tmpfs                  48G   154M   24G  1% /dev/shm
    ...
    ...
    
    • 1
    • 2
    • 3
    • 4
    • 5

    但在kubernetes上,Pod里无法使用超过 64MB的shared memory。如下是集群上一个pod的信息,可以看到,/dev/shm的大小是 64MB,通过dd往共享内存写数据时,写到64MB的时候就会报“No space left on device”。

    $ kubectl run centos --rm -it --image centos:7 bash
    [root@centos-7df8445565-dvpnt /]# df -h|grep shm
    Filesystem      Size  Used Avail Use% Mounted on
    shm              64M     0   64M   0% /dev/shm
    [root@centos-7df8445565-dvpnt /]# dd if=/dev/zero of=/dev/shm/test      bs=1024 count=102400
    dd: error writing '/dev/shm/test': No space left on device
    65537+0 records in
    65536+0 records out
    67108864 bytes (67 MB) copied, 0.161447 s, 416 MB/s
    [root@centos-7df8445565-dvpnt /]# ls -l -h
    total 64M
    -rw-r--r-- 1 root root 64M Nov 14 14:33 test
    [root@centos-7df8445565-dvpnt /]# df -h|grep shm
    Filesystem      Size  Used Avail Use% Mounted on
    shm              64M   64M     0 100% /dev/shm
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    为什么是64M

    kubernetes创建的Pod,其共享内存默认64MB,且不可更改。
    因为kubernetes本身是没有设置share memory的大小的,64MB其实是docker 默认的共享内存的大小。

    docker环境下如何支持更大的shared memory

    docker run 的时候,可以通过–shm-size来设置共享内存的大小。

    $ docker run  --rm centos:7 df -h |grep shm
    shm              64M     0   64M   0% /dev/shm
    $ docker run  --rm --shm-size 128M centos:7 df -h |grep shm
    shm             128M     0  128M   0% /dev/shm
    
    • 1
    • 2
    • 3
    • 4

    k8s环境下如何支持更大的shared memory

    kubernetes empty dir:

    emptyDir volume在一些场景下非常有用,例如在Pod的不同container之间需要共享数据,
    可以将同一个emptyDir挂载到两个container中来达到共享的目的。
    
    此时,emtpyDir实际是一个宿主机上的目录,本质上还是磁盘(比如通过sidecar的方式来收集日志)。
    
    kubernetes提供来一种特殊的emptyDir:medium为memory的临时存储。
    用户可以将memory介质的emptyDir挂到任何目录,然后将这个目录当作一个高性能的文件系统来使用。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    可以将memory介质的empty dir,挂载到 /dev/shm 下,解决共享内存 /dev/shm 不够用的问题

    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: xxx
      namespace: default
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: xxx
      template:
        metadata:
          labels:
            app: xxx
        spec:
          containers:
          - args:
            - infinity
            command:
            - sleep
            image: centos:7
            name: centos
            volumeMounts:
            - mountPath: /dev/shm
              name: cache-volume
          volumes:
          - emptyDir:
              medium: Memory
              sizeLimit: 128Mi
            name: cache-volume
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    k8s环境下使用更大的shared memory可能发生的问题

    使用empty dir的缺点:

    1、影响kubernetes调度,因为empty dir并不涉及node的resources,
    这样会造成Pod“偷偷”使用了node的内存,但是调度器并不知晓;
    
    2、用户不能及时感知到内存不可用
    
    • 1
    • 2
    • 3
    • 4

    共享内存受cgroup限制吗

    由于普通的内存是受cgroup限制的,那么自然会有一个问题:共享内存受cgroup限制吗?
    
    如果受限制,那么只要给Pod设置memroy limit就可以了,至于用户将内存是用于共享内存,
    还是用于普通用途,kubernetes层面并不需要台关心:因为共享内存并不是一个“独立”的内存,
    只是包含在memory limit里进行调度,因此也不会影响调度。
    
    • 1
    • 2
    • 3
    • 4
    • 5

    需要显示设置sizeLimit

    kubelet的eviction manager会监控pod的emptyDir卷使用的空间大小,当使用空间超过该值时,会将该Pod驱逐

    可以使用sizeLimit的大小

    1、当 Pod 并没有设置memory limit时,此时 shm大小为node的Allocateable Memory大小
    
    2、当Pod 设置了memory limit 但未设置sizeLimit时,shm 大小为Pod 的memory Limit
    
    3、当Pod的medium emptyDir设置sizeLimit时,shm大小为sizeLimit
    
    • 1
    • 2
    • 3
    • 4
    • 5

    如何防止pod由于使用共享内存而偷用了node的内存,没被调度器发现

    pod的memory request中需要把自己要使用内存的和pod挂载的shm大小一起算进来

  • 相关阅读:
    微服务实战系列之云原生
    MATLAB环境下使用二维高分辨时频分析方法提取波状分量
    LINUX漏洞复现篇之ShellShock漏洞
    物流路由线路配载前端算法逻辑实现方案
    十年测试老鸟聊聊移动端兼容性测试
    iNeuOS工业互联网操作系统,增加2154个视图建模(WEB组态)行业矢量图元、大屏背景及相关图元
    第3章-指标体系与数据可视化-3.2-描述性统计分析与绘图
    进程间的信号
    java maven pom application 生产prod/开发dev/测试test
    Vue:内置组件:KeepAlive(缓存组件实例)
  • 原文地址:https://blog.csdn.net/qq_43684922/article/details/126650483