K8s 里如何优雅地使用 /dev/shm 实现容器间共享内存
- 1. 從 docker run 的 --shm-size 參數(shù)聊起
- 2. Linux 里的 /dev/shm
- 3. Docker 對(duì)共享內(nèi)存的支持
-
4. K8s 里如何設(shè)置
/dev/shm大小- 4.1 方案一:修改節(jié)點(diǎn)的 Docker 配置
- 4.2 方案二:通過(guò) Volume 掛載一個(gè)大目錄到 Pod 的 /dev/shm
- 4.3 方案三:用 K8s 的方式共享內(nèi)存
- 5. 總結(jié)
1. 從 docker run 的 --shm-size 參數(shù)聊起
今天無(wú)意見看到算法同學(xué)寫的一個(gè) docker run 命令用到了 --shm-size 參數(shù)。沒錯(cuò),接著他想將這些容器跑到 K8s 里,于是我就得開始思考 --shm-size 在 K8s 里對(duì)應(yīng)的特性是什么了。
我猜 K8s 里會(huì)有優(yōu)雅的方式來(lái)實(shí)現(xiàn)一樣的目的,最終我也找到了那個(gè)優(yōu)雅的方法。不過(guò)這個(gè)過(guò)程還是稍稍坎坷,我在在網(wǎng)上看一圈,找到的前2種方案都有點(diǎn)“丑陋”,但是給人一種“只能這樣”的錯(cuò)覺。最后看到第三條路的時(shí)候,我不禁拍了一下大腿:“我X!太帥了!”。于是乎,我想讓你們也拍一下大腿,然后就有了此文。行,且往下看。
2. Linux 里的 /dev/shm
Linux 里有一個(gè) /dev/shm 目錄,shm 代表共享內(nèi)存(Shared Memory)。如果這是你第一次聽說(shuō) shm,可能會(huì)有點(diǎn)疑惑:“這東西到底是內(nèi)存還是磁盤”。其實(shí) /dev/shm 是一個(gè)臨時(shí)文件系統(tǒng),讓你用操作磁盤中的文件一樣的方式來(lái)將讀寫內(nèi)存。換言之,你可以用文件讀寫的語(yǔ)法來(lái)操作“/dev/shm/a.txt”,但是這個(gè)文件本質(zhì)是存在內(nèi)存里的,所以讀寫速度會(huì)非??臁?/p>
有了 /dev/shm,你就可以讓一個(gè)進(jìn)程非常高效地存取一些臨時(shí)文件,或者讓多個(gè)進(jìn)程非常高效的“共享內(nèi)存”。這種“進(jìn)程間快速共享內(nèi)存”的能力對(duì)于很多機(jī)器學(xué)習(xí)框架來(lái)說(shuō)非常有用。
順口提一下,可能大伙平時(shí)接觸最多的進(jìn)程間通信(IPC)方式是 Socket 和 RPC,這類走網(wǎng)絡(luò)通信的方式可以實(shí)現(xiàn)跨主機(jī)的 IPC,應(yīng)用場(chǎng)景更廣。不過(guò)上帝給你開了一扇門,就不會(huì)多給你開一堆窗,Socket 和 RPC 的通信效率肯定就沒有“共享內(nèi)存”來(lái)得快了。(可能你心里在想 http 協(xié)議,沒錯(cuò),http 用的更多,但是一般 http 不被歸入進(jìn)程間通信方式。)
3. Docker 對(duì)共享內(nèi)存的支持
在 Linux 系統(tǒng)中,/dev/shm 的大小一般為物理內(nèi)存的一半。Docker 在啟動(dòng)容器的時(shí)候,默認(rèn)給容器設(shè)置的 /dev/shm 大小是 64M。(你品,你細(xì)品,是不是自定義容器內(nèi) shm 大小的需求就產(chǎn)生了?)
Docker 在 shm 大小的配置上提供了兩種支持:
-
docker run支持通過(guò)--shm-size=1g這種方式指定一個(gè)容器的 shm 大??; - Docker 配置
daemon.json中可以通過(guò)"shared-memory-size": "1G"配置指定容器啟動(dòng)的默認(rèn) shm 大小。
不難猜到,--shm-size 參數(shù)的優(yōu)先級(jí)會(huì)比 shared-memory-size 配置高。
4. K8s 里如何設(shè)置 /dev/shm 大小
K8s 里沒有原生提供啥直觀的 shm 配置方式。但是為了讓應(yīng)用能夠嘗到“共享內(nèi)存”的滋味,YAML 工程師還是得給出方案。
4.1 方案一:修改節(jié)點(diǎn)的 Docker 配置
Sao 操作來(lái)了,因?yàn)?Docker 支持 shared-memory-size 配置,所以直接修改節(jié)點(diǎn)的 daemon.json 配置,那不就讓所有 Pod 都能夠用起來(lái)更大的 share memory 了?
我就不演示了。反正基本滿足需求,但是冥冥之中又讓你覺得哪里不太對(duì)勁,總之吧,不優(yōu)雅。
4.2 方案二:通過(guò) Volume 掛載一個(gè)大目錄到 Pod 的 /dev/shm
不就是讓 Pod 內(nèi)的 /dev/shm 大一點(diǎn)嘛,那就掛卷呀:
apiVersion: v1
kind: Pod
metadata:
name: shared-memory-pod
spec:
containers:
- name: mycontainer
image: your_image_name
volumeMounts:
- name: shared-memory-volume
mountPath: /dev/shm
volumes:
- name: shared-memory-volume
emptyDir: {}
如果用 PVC 的方式,后端存儲(chǔ)系統(tǒng)支持限定卷大小的話,這里就能精準(zhǔn)分配 shm 的大小了??傊瑯I(yè)務(wù)能跑起來(lái)。(你是不是已經(jīng)忍不住要開噴了?忍忍。我知道,這種方式通過(guò)磁盤上的文件來(lái)實(shí)現(xiàn)“共享內(nèi)存”,功能走通了,性能不達(dá)標(biāo)。)
到這一步,我以為“方案一”挺合理的,改改 Docker 的啟動(dòng)參數(shù),似乎影響不大,沒啥大壞處,妥。
不過(guò)更進(jìn)一步,K8s 真的不支持配置 shm?這個(gè)需求聽起來(lái)合理呀,為什么沒有被實(shí)現(xiàn)呢?繼續(xù)搜一搜,我在 * 上看到了第三種玩法。
4.3 方案三:用 K8s 的方式共享內(nèi)存
且看這段配置:
apiVersion: v1
kind: Pod
metadata:
name: shared-memory-pod
spec:
volumes:
- name: dshm
emptyDir:
medium: Memory
sizeLimit: "1Gi"
containers:
- name: mycontainer
image: your_image_name
volumeMounts:
- name: dshm
mountPath: /dev/shm
行吧,破案了。之前我也不知道 emptyDir 可以配置 medium: Memory。
5. 總結(jié)
散了吧,總結(jié)啥。大周五的,早點(diǎn)回家。
總結(jié)
以上是生活随笔為你收集整理的K8s 里如何优雅地使用 /dev/shm 实现容器间共享内存的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: “轴承+互联网”走进天府之国
- 下一篇: 考研保研、夏令营推免的简历模板