容器化适用于 Kubernetes 的 Java 应用程序

本文介绍如何容器化 Java 应用程序以在 Kubernetes 上进行部署。 有关容器内存、JVM 堆内存、垃圾回收器(DC)和 vCPU 核心的指南,请参阅 容器化 Java 应用程序

为 Kubernetes 节点池确定合适的 VM SKU

确定可用于群集的 Kubernetes 节点池或池是否适合要使用的容器内存和 vCPU 核心。 如果节点池可以托管应用程序,请继续操作。 否则,请预配一个适合容器内存量和目标 vCPU 内核数量的节点池。

请记住,VM SKU 的成本与核心数和内存量成正比。 确定一个容器实例的 vCPU 和内存的起点后,请确定仅通过水平缩放是否能够满足应用程序的需求。 对于可靠且始终可用的系统,必须至少提供两个副本。 根据需要纵向扩展和横向扩展。

设置 CPU 请求和限制

如果必须限制 CPU,请确保在部署文件中对 limitsrequests 应用相同的值。 JVM 不会动态调整其运行时,例如 GC 和其他线程池。 JVM 读取仅在启动期间可用的处理器数。

提示

为 CPU 请求和 CPU 限制设置相同的值。

containers:
- image: myimage
  name: myapp
  resources:
    limits:
      cpu: "2"
    requests:
      cpu: "2"

了解 JVM 可用的处理器

当 OpenJDK 中的 HotSpot JVM 确定它在容器中运行时,它使用 cpu_quotacpu_period 等值来确定其可用的处理器数。 一般情况下,任何不超过 1000m 毫核的值都可视为单处理器的机器。 1001m2000m 之间的任何值都标识为双处理器计算机,依此类推。 此信息可通过 API Runtime.getRuntime(.availableProcessors()获取。 一些并发 GC 也可能使用此值来配置其线程。 其他 API、库和框架也可能使用此信息来配置线程池。

Kubernetes CPU 配额与进程在 CPU 中花费的时间量有关,而不是进程可用的 CPU 数。 多线程运行时(如 JVM)仍可能同时使用多个处理器,同时有多个线程。 即使容器限制为一个 vCPU,JVM 也可能指示看到两个或多个可用的处理器。

若要通知 JVM 应在 Kubernetes 环境中看到的确切处理器数,请使用以下 JVM 标志:

-XX:ActiveProcessorCount=N

设置内存请求和限制

将内存限制设置为之前确定的量。 请确保内存限制号是容器内存,而不是 JVM 堆内存值。

提示

将内存请求设置为等于内存限制。

containers:
  - name: myimage
    image: myapp
    resources:
      limits:
        memory: "4Gi"
      requests:
        memory: "4Gi"

在部署文件中设置 JVM 参数

请记住将 JVM 堆内存设置为之前确定的内存量。 建议将此值作为环境变量传递,以便轻松更改该值,而无需重新生成容器映像。

containers:
  - name: myimage
    image: myapp
    env:
    - name: JAVA_OPTS
      value: "-XX:+UseParallelGC -XX:MaxRAMPercentage=75"

后续步骤