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

时间:2017-10-17 11:38:13

标签: java tomcat memory memory-management coreos

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

所以我想知道在docker run命令中没有指定内存限制时Docker容器的默认内存限制,这就是我运行docker容器的方式。正如本forum中所讨论的那样,答案表明它是无限的,它基于操作系统提供的内容。

但是 我想知道CoreOS如何详细决定给定容器的内存限制,我应该担心设置正在运行的容器的内存限制和CPU利用率一个带有tomcat基本映像的webapp(由于CoreOS中的内存过载问题,容器是否有可能退出?)。

对于此问题,我在互联网上找到的所有文件都没有提供与CoreOS或tomcat docker图像相关的明确答案。

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

1 个答案:

答案 0 :(得分:2)

在Docker中,默认为a container has no resource constraints。如果您没有为容器指定内存限制,the limit is unlimited。但是,内存可能受cgroup配置的限制。此外,如果您使用的是Kubernetes或其他管理系统,则可以define a default limit for a domain or namespace

Tomcat是一个在虚拟机上运行的Java Application Server。 JVM尝试根据-Xms and -Xmx arguments等参数保留一定量的内存。在TOMCAT中,可以在catalina.sh启动脚本或CATALINA_OPTSJAVA_OPTS环境变量中指定这些参数。如果未根据JVM的版本和可用内存指定内存限制Java will use a default one。有关Java 8 default limits的讨论。 Java不会使用比指定的更多的内存。如果从Tomcat调用其他非Java程序,则必须跟踪这些应用程序使用的内存。

  • Tomcat in the Docker repository未定义Java运行时的内存限制。 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使用script来计算容器限制,并使用50%的可用内存作为上限。

  • 确定应用程序所需的内存量是Tomcat tunning的一部分。您可能会发现许多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系统(包括tomcat)may fail at startup如果没有足够的内存或内存限制小于运行时所需的。 Linux和Java使用乐观的malloc,它们可能会在一段时间后失败。您必须check all of the cgroups, docker and JVM configurations