我有一个Kubernetes部署,它基于anapsix/alpine-java映像部署Java应用程序.容器中没有其他任何东西可以用于Java应用程序和容器开销.
我希望最大化Java进程在docker容器中可以使用的内存量,并最小化将保留但从未使用过的ram数量.
例如,我有:
如何安全地最大化在两个节点上运行的pod的数量,而由于内存限制,从不让Kubernetes终止我的POD?
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: my-deployment
spec:
replicas: 1
template:
metadata:
labels:
app: my-deployment
spec:
containers:
- name: my-deployment
image: myreg:5000/my-deployment:0.0.1-SNAPSHOT
ports:
- containerPort: 8080
name: http
resources:
requests:
memory: 1024Mi
limits:
memory: 1024Mi
Run Code Online (Sandbox Code Playgroud)
Java 8 update 131+有一个标志-XX:+ UseCGroupMemoryLimitForHeap来使用来自Kubernetes部署的Docker限制.
我的Docker实验向我展示了Kubernetes正在发生的事情
如果我在Docker中运行以下代码:
docker run -m 1024m anapsix/alpine-java:8_server-jre_unlimited java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XshowSettings:vm -version
Run Code Online (Sandbox Code Playgroud)
我明白了:
VM settings:
Max. Heap Size (Estimated): 228.00M
Run Code Online (Sandbox Code Playgroud)
这个值很低是因为Java默认情况下将-XX:MaxRAMFraction设置为4并且我得到了大约1/4的ram分配...
如果我在Docker中使用-XX:MaxRAMFraction = 2运行相同的命令:
docker run -m 1024m anapsix/alpine-java:8_server-jre_unlimited java -XX:+UnlockExperimentalVMOptions …Run Code Online (Sandbox Code Playgroud) 我正在运行包含JVM(java8u31)的Docker容器。这些容器被部署为Kubernetes集群中的Pod。我经常得到Pod的OOM,而Kubernetes杀死Pod并重新启动它。我是Kubernetes的新手,在寻找这些OOM的根本原因时遇到了问题。
这是JVM参数
-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -Xms700M -Xmx1000M -XX:MaxRAM=1536M -XX:MaxMetaspaceSize=250M
Run Code Online (Sandbox Code Playgroud)这些容器被部署为有状态集,以下是资源分配
resources:
requests:
memory: "1.5G"
cpu: 1
limits:
memory: "1.5G"
cpu: 1
Run Code Online (Sandbox Code Playgroud)
因此分配给容器的总内存与MaxRam匹配
如果我使用-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/etc/opt/jmx/java_pid%p.hprof该方法无济于事,因为一旦有OOM,吊舱就会被杀死,重新创建并启动,因此吊舱中的所有物品都会丢失
获取线程或HEAP转储的唯一方法是SSH到Pod中,这也是我无法接受的,因为Pod是在OOM之后重新创建的,所以在OOM时我没有占用内存。我在OOM之后进行SSH,这没有太大帮助。
我还使用visualVM,jHat对代码进行了概要分析,但是找不到大量的内存占用空间,这可能导致JVM中运行的线程消耗过多内存或可能导致泄漏的结论。
感谢您提供任何帮助来解决Kubernetes抛出的OOM。