如何在 Container-Optimized OS 中设置容器 ulimit

how to set container ulimits in Container-Optimized OS

我需要在容器上设置 ulimits。例如,docker run --ulimit memlock="-1:-1" <image>。但是,我不确定在 Compute Engine 上部署容器优化 VM 时如何执行此操作,因为它处理容器的启动。

我能够使用 --privileged、-e 等选项部署 VM 环境变量,甚至是覆盖 CMD。如何部署为容器设置 ulimits 的 VM?

creating a Container Optimized OS or in the doc for Configuring Options to Run Container时好像没有设置ulimit的文档。

目前,似乎不支持在部署容器优化的 VM 时自动设置容器的 ulimit 选项,因为文档 here and here. You can submit a feature request for that here under 'Compute'. The document on Configuring Options to Run Container 中也不包含该选项。

但是,您可以run containers on a Container-Optimized OS (COS) instance. Thereby, you can run a docker with setting ulimit like here

收到正式回复:

Unfortunately the Containers on Compute Engine feature does not currently support setting the ulimit options for containers.

A workaround would be to set ulimit inside the container. For example: gcloud beta compute instances create-with-container INSTANCE --zone=ZONE --container-image=gcr.io/google-containers/busybox --container-privileged --container-command=sh --container-arg=-c --container-arg=ulimit\ -n\ 100000

Unfortunately this method requires running the container as privileged.

Best regards,...

这个回复给了我做以下事情的灵感。创建从 docker 图像的 ENTRYPOINT 引用的包装器脚本。在此包装脚本中,在启动受 ulimit 约束的进程之前设置 ulimit。

举个简单的例子:

$HOME/example/wrapper.sh

#! /bin/bash

# set memlock to unlimited
ulimit -l unlimited

# start the elasticsearch node 
# (found this from the base images dockerfile on github)
/usr/local/bin/docker-entrypoint.sh eswrapper

$HOME/example/Dockerfile

FROM docker.elastic.co/elasticsearch/elasticsearch:6.3.2
COPY wrapper.sh .
RUN chmod 777 wrapper.sh
ENTRYPOINT ./wrapper.sh

本地镜像构建

docker image build -t gcr.io/{GCLOUD_PROJECT_ID}/example:0.0.0 $HOME/example

部署到 gcr.io

docker push gcr.io/{GCLOUD_PROJECT_ID}/example:0.0.0

通过 gcloud 创建实例

gcloud beta compute instances create-with-container example-instance-1 \
    --zone us-central1-a \
    --container-image=gcr.io/{GCLOUD_PROJECT_ID}/example:0.0.0 \
    --container-privileged \
    --service-account={DEFAULT_COMPUTE_ENGINE_SERVICE_ACC_ID}-compute@developer.gserviceaccount.com \
    --metadata=startup-script="echo 'vm.max_map_count=262144' > /etc/sysctl.conf; sysctl -p;"

注意以下几点。上面的启动脚本只需要 运行 这个镜像的容器。从您的私人 google 容器注册表中提取服务帐户是必需的。 --container-privileged 参数是必要的,因为 运行 具有特权的容器需要在其中设置 ulimits。

正在验证是否为您的进程设置了 ulimits

在虚拟机主机上,ps -e 并找到在您的包装脚本中执行的进程的 PID。在这种情况下,找到命令为 java 的 PID。对于每个 PID,cat /proc/{PID}/limits。在这种情况下,我只将 memlock 设置为无限制。可以看到确实设置为unlimited

以下我已经成功使用了

从 VM 内或从 Container Optimized OS 的启动脚本:

sudo echo "vm.max_map_count=262144" | tee -a /etc/sysctl.conf
sudo sysctl -p