到目前为止,我的想法是容器技术(如: docker)提供所需的隔离和操作系统级别的虚拟化。在容器中运行的应用程序受到名称空间、cgroup、apparmour/selinux和功能的限制,它们无法确定它们所处的主机环境。但这种理解似乎并不是百分之百正确。
在wiki -OS级虚拟化上
OS级虚拟化是一个操作系统范例,内核允许存在多个隔离的用户空间实例。这样的实例,称为容器(LXC、Solaris容器、Docker)、区域(Solaris容器)、虚拟专用服务器(OpenVZ)、分区、虚拟环境(VEs)、虚拟内核(DragonFly BSD)或监狱(FreeBSD监狱或chroot监狱),从运行它们的程序的角度来看,1可能看起来像真正的计算机。在普通操作系统上运行的计算机程序可以看到计算机的所有资源(连接的设备、文件和文件夹、网络共享、CPU功率、可量化的硬件功能)。但是,在容器内部运行的程序只能看到容器的内容和分配给容器的设备.。
从上面的引语来看,它似乎只增加了隔离和抽象,而不像虚拟化那样。
因为Java团队必须向JVM添加容器支持,所以它不直接查看主机env,而是将自己限制在由docker提供的隔离/抽象上。
参考资料:
Linux容器支持首先出现在JDK 10中,然后移植到8u191,
这是否意味着运行在容器环境中的C程序可以绕过限制并访问/读取主机env详细信息。 of,当它尝试(即使用此信息)做超出容器允许的任何事情时,容器引擎可能会扼杀容器本身的进程。
因此,如果我正在开发一个C/C++应用程序,它请求/查询CPU/MEM/设备等主机资源,那么通过添加容器支持在容器环境中按预期运行应用程序是我的责任吗?
发布于 2020-10-12 07:27:52
虽然我怀疑这将是一个流行的答案,但我的观点是,可能在容器环境中运行的应用程序必须提供明确指定资源限制的方法。依靠从系统查询的信息是错误的。
容器不是完全虚拟化环境,通常不会完全隐藏底层平台。虽然容器可能在网络、文件系统和用户级别上与其主机隔离,但这并不意味着它们是真正独立的。我遇到的一个典型问题是,容器无法获得它自己对系统负载平均值的贡献--只有主机的负载平均值。
没有完全虚拟化这一事实并不意味着主机不能强制执行限制--它通常可以,而且确实如此。但这意味着容器很难找到它们是什么
容器可以使用各种启发式方法。例如,它可能能够解析/proc/self/cgroup。这可能提供有用的信息,也可能不提供有用的信息,具体情况取决于执行情况。只有当主机使用控制组时,这种方法才能提供有用的信息--大多数当前的实现都是这样,但这并不意味着它是强制性的。
目前正在使用若干不同的容器框架,而且这一数量可能还会增加。很难预测将来需要使用哪些方法来验证应用程序容器。我认为,为用户提供一种控制限制的方法,比为您开发的每一个软件进行持续的维护任务要好。
发布于 2020-10-12 13:21:46
在容器环境中,构建可以运行多个副本的小型互联容器通常会更好地工作。然后,您可以将环境大小调整到工作负载,而不是将工作负载大小调整到其环境中。
一个更容易考虑的示例是处理异步任务的辅助进程。在非容器环境中,一个典型的设置是询问主机它有多少内核,然后启动那么多线程。这并不能很好地转化为容器,确切地说是因为你引用的问题。相反,通常最好是让您的工作进程是单线程,但然后启动尽可能多的副本,您需要做的工作。
特别是,如果您在云环境中运行Kubernetes,那么这样做有一些真正的优势。在Kubernetes部署中,您可以指定容器的replicas:数量,并动态地更改它,因此您根本没有绑定到硬件配置。您可以使用一个名为卧式吊舱自动分频器的Kubernetes块来根据队列长度自动设置部署计数。当工作负载变得对当前集群来说太大时,您可以使用另一个名为簇自动分频器的Kubernetes块来自动请求更多的云计算节点。在此基础上是一个基本假设,即单个容器(Kubernetes Pods)是小的、无状态的,并且在任何硬件设置上都是一样的。
您引用的JVM内存限制问题也面临着类似的问题。默认JVM行为将为堆使用25%的系统内存,但现在的问题是,如何决定在每个容器资源约束下的内存数量?不过,大多数应用程序运行时没有像这样的依赖于系统的硬内存限制;您可以讨论C程序,在达到内核强制(物理或cgroup)内存限制之前,malloc()将很好地工作。
因此,如果我正在开发一个C/C++应用程序,它请求/查询主机资源,如CPU/MEM/设备.
在像Docker这样的隔离系统中运行...it是不合适的。直接在主机上运行。
https://stackoverflow.com/questions/64312354
复制相似问题