CoreOS 如何为 Docker 容器分配内存?

How does CoreOS allocates memory to a Docker container?

我正在 运行ning 一个容器,其中包含一个 J2EE webapp,在 AWS(t2 介质)的 CoreOS 服务器实例上具有 tomcat docker 基础图像。最近我发现在 Docker 容器中使用 Java 超出内存限制会导致容器失败 (Resource)。阅读上述文章后,我有点担心我 运行 在我的 CoreOS 实例上使用的任何容器将来是否会面临这个问题。

所以我想知道在 docker 运行 命令上没有指定内存限制时 Docker 容器的默认内存限制是多少,这就是我的方式运行正在我的 docker 容器中。正如本 forum 中所讨论的那样,答案表明它是无限的,并且它基于 OS 给出的任何内容。

但是 我想知道 CoreOS 是如何详细决定给定容器的内存限制的,我是否应该担心设置内存限制和 CPU 容器的利用率,该容器正在 运行 使用 tomcat 基础映像连接 Web 应用程序(是否有可能由于 Core[=] 中的内存过载问题导致容器退出37=]?).

我在互联网上找到的

None 文档针对此问题提供了与核心 OS 或 tomcat docker 图像相关的明确答案。

注意 - 我正在通过 systemd 管理我的 Docker 容器。

在Docker中,默认情况下,a container has no resource constraints. If you do not specify a memory limit for your container, the limit is unlimited. However, it is possible that the memory is limited by your cgroup configuration. In addition, if you are using Kubernetes or another management system, it is possible to define a default limit for a domain or namespace

Tomcat 是在虚拟机上运行的 Java 应用程序服务器。 JVM 会根据 -Xms and -Xmx arguments. In TOMCAT, these parameters may be specified in the catalina.sh startup script or the CATALINA_OPTS and JAVA_OPTS environment variables. If you do not specify a memory limit, Java will use a default one based on the version of the JVM and the available memory. There is a discussion on 等参数尝试保留一定数量的内存。 Java 不会使用超过指定的内存。如果您从 Tomcat 调用其他非 Java 程序,您必须跟踪这些应用程序使用的内存。

  • Tomcat in the Docker repository does not define a memory limit for the Java runtime. The default tomcat catalina.sh也不限定。
  • 如果您使用该模板,Java(和 Tomcat)将使用默认值。您可以使用以下方法检查系统中的值:

    java -XX:+PrintFlagsFinal -version | grep -iE 'HeapSize|PermSize|ThreadStackSize'
    

    在您提到的页面中,他们在 dockerfile 中使用了一个 CMD:

    CMD java -XX:+PrintFlagsFinal -XX:+PrintGCDetails $JAVA_OPTIONS -jar java-container.jar
    
  • 您提到的页面使用Fabric8 dockerfile that uses an script计算容器限制并使用可用内存的 50% 作为上限。

  • 确定您的应用程序所需的内存量是 Tomcat tunning. You may find many pages 讨论此问题和另一个 Tomcat 参数的一部分,例如允许的连接数和连接器中使用的线程数等。
  • 您可以使用 -e 开关设置环境变量来定义内存限制。

    $ docker run -d --name mycontainer -p 8080:8080 -m 800M -e JAVA_OPTIONS='-Xmx300m' ...
    
  • 如果您为容器定义内存限制,则它必须大于 Java 使用的内存限制。在 Github 问题中有一个 old discussion 关于要添加多少内存的一些想法。


请注意,最近的 Java 版本考虑了可用内存和 CPU according to the docker/cgroup defined limits. Java systems (including tomcat) may fail at startup if you do not have enough memory or the memory limit is less than the required by the runtime. Linux and Java uses an optimistic mallocand they may fail after a while. You must check all of the cgroups, docker and JVM configurations