关键词:kubernetes docker 共享内存 机器学习 shm
很多机器学习框架需要使用shm进行多进程并发训练的通讯。
这就意味着需要一个很大的shm设置。
docker本身是可以设置shm的大小的。
docker run --rm -it --shm-size 1G ubuntu:20.04
然而,kubernetes为了通用性考虑,并没有提供这个参数的设置能力。
思路一:通过volume挂载的方式
即在宿主机的/dev/shm中创建一个目录,并挂载到pod中container的/dev/shm中。
这样就可以得到一个和宿主机一样大的共享内存了。
操作如下:
- 创建目录,并赋权777
$ sudo mkdir /dev/shm/0460ea97-de1c-42b4-8cd5-783cfb0768f2
$ sudo chmod 777 /dev/shm/0460ea97-de1c-42b4-8cd5-783cfb0768f2 -R
- 在kubernetes的配置中,添加响应的目录挂载;将创建好的目录
/dev/shm/0460ea97-de1c-42b4-8cd5-783cfb0768f2
挂载到container的/dev/shm
上。
$ cat pod.yml
apiVersion: v1
kind: Pod
metadata:
name: pod02
labels:
app: pod02
spec:
securityContext:
fsGroup: 0
containers:
- name: pod02
image: ubuntu:20.04
args:
- until [ -f /run/ready ]; do echo waiting for setup; sleep 5; done
command:
- sh
- -c
ports:
- containerPort: 8888
name: pod02
volumeMounts:
- name: shm-volume
mountPath: /dev/shm
nodeSelector:
nuwa.storage.nid: s002
volumes:
- name: shm-volume
hostPath:
path: /dev/shm/0460ea97-de1c-42b4-8cd5-783cfb0768f2
- 创建kubernetes对象
$ kubectl apply -f pod.yml
pod/pod02 created
- 进入容器,查看共享内存的大小。
$ kubectl exec -it pod02 -- bash
root@pod02:/# free -h
total used free shared buff/cache available
Mem: 31Gi 7.7Gi 479Mi 39Mi 23Gi 23Gi
Swap: 0B 0B 0B
root@pod02:/# df -h
Filesystem Size Used Avail Use% Mounted on
overlay 227G 147G 70G 68% /
tmpfs 64M 0 64M 0% /dev
tmpfs 16G 0 16G 0% /sys/fs/cgroup
tmpfs 16G 0 16G 0% /dev/shm
/dev/mapper/ubuntu--vg-ubuntu--lv 227G 147G 70G 68% /etc/hosts
tmpfs 32G 12K 32G 1% /run/secrets/kubernetes.io/serviceaccount
tmpfs 16G 0 16G 0% /proc/acpi
tmpfs 16G 0 16G 0% /proc/scsi
tmpfs 16G 0 16G 0% /sys/firmware
root@pod02:/# exit
exit
$
思路二:修改docker的daemon.json
docker可以给定一个default-shm-size作为全局的配置,用于所有的container创建。
所以,可以通过这个功能,将全局的共享内存大小改变,这样就可以保证,所有的docker容器都使用足够大的共享内存了。
- 注意: 只有在配置修改后创建的container才会应用这个参数,即使重启。已经创建的container需要自行修改配置文件。
操作如下:
- 修改/etc/docker/daemon.json,添加default-shm-size
$ cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://xxxxxxxxx.mirror.aliyuncs.com"],
"dns" : [ "8.8.8.8", "8.8.4.4" ],
"exec-opts": ["native.cgroupdriver=systemd"],
"default-shm-size": "1G"
}
$
- 停止docker服务,重新加载配置,并启动docker服务
$ systemctl stop docker
$ systemctl daemon-reload
$ systemctl start docker
- 新创建容器并查看
$ docker run --rm -it ubuntu:20.04
root@7470a576ae61:/# df -h
Filesystem Size Used Avail Use% Mounted on
overlay 3.6T 1.9T 1.6T 54% /
tmpfs 64M 0 64M 0% /dev
tmpfs 32G 0 32G 0% /sys/fs/cgroup
/dev/sdc1 3.6T 1.9T 1.6T 54% /etc/hosts
shm 1G 0 1G 0% /dev/shm
tmpfs 32G 0 32G 0% /proc/scsi
tmpfs 32G 0 32G 0% /sys/firmware
root@7470a576ae61:/# exit
exit
$
两种方案的异同
虽然两种方案都可以达到目的,但还是存在一定的差异的。
- 思路一
- 优点:
可以灵活控制,可以让需要共享内存的container挂载共享内存。对共享内存没有特殊需求的container,不进行挂载即可。
- 缺点:
大小不可控制,直接与宿主机共享大小,如果耍流氓式的使用,会导致宿主机故障。
内容在宿主机上可见。
容器销毁后,文件依旧占用,需要自行清理。
- 优点:
- 思路二
- 优点:
可以控制大小
内容在宿主机上不可见
容器销毁后,文件自动销毁,无需关心 - 缺点:
所有的容器都会分配shm,无论是否需要。
- 优点: