第 3 章 配置 Java 应用程序
要启用 Cryostat 收集、存储和分析 Java Flight Recorder (JFR)数据,有关 Java 虚拟机(JVM)上运行的目标应用程序的数据,您必须配置应用程序,以便 Cryostat 可以检测并连接到它们。
您可以使用以下方法配置应用程序:
- Cryostat 代理
您可以使用 Cryostat 代理组件检测和连接,后者作为 Java Instrumentation Agent 实现,并充当 JVM 上运行的应用程序的插件。
Cryostat 代理提供了一个 HTTP API,Cryostat 服务器可用作应用程序 JMX 端口的替代选择。通过将正确配置的 Cryostat 代理附加到您部署的工作负载应用程序中,您可以使用完整的 Cryostat 功能集,而无需目标应用程序公开 JMX 端口。
注意在 Red Hat build of Cryostat 2.4 之前,Cryostat 代理提供了一个只读 HTTP API,它只支持有限的 JFR 操作。
与 JMX 端口相比,Cryostat 代理的 HTTP API 可以提供以下优点:
- 由于 API 面区域减少,安全性更高
- 由于 Cryostat 代理的双角色作为 Cryostat 发现插件,部署灵活性
如需更多信息 ,请参阅使用 Cryostat 代理。
- 远程 Java 管理扩展(JMX)连接
您可以配置目标应用程序以允许 Java 管理扩展(JMX)连接。这种类型的配置使用 OpenShift Service 检测和 JMX 进行连接。
JMX 是 JVM 上的标准功能,您可以使用它监控和管理 JVM 上运行的目标应用程序。要使 Cryostat 使用 JMX,您必须在启动 JVM 时启用和配置 JMX,因为 Cryostat 需要目标应用程序来公开 JMX 端口。
Cryostat 通过此 JMX 端口与目标应用程序通信,以启动和停止 JFR 记录并通过网络拉取 JFR 数据,启用 Cryostat 存储和分析这个 JFR 数据。远程监控需要安全性,以确保未授权的人员无法访问应用程序。Cryostat 会提示您输入您的凭证,然后 Cryostat 可以访问任何应用程序的 JFR 记录。
如需更多信息,请参阅使用 JMX 连接配置应用程序。
- Cryostat 代理和 JMX 混合
您可以将目标应用程序配置为使用混合方法,其中使用 Cryostat 代理和 JMX。使用此方法,您可以使用 Cryostat 代理来检测目标应用程序和 JMX 来公开 JFR 数据到 Cryostat,从而获得更大的灵活性。
例如,您可以使用代理来检测应用程序,而无需依赖特定的端口号,并使用 JMX 连接根据需要启动和停止 JFR flight 记录。
如果 Cryostat 代理检测到也会在应用程序上配置 JMX,代理会将自身发布到带有代理 HTTP API 定义和 JMX URL 定义的 Cryostat 服务器。在这种情况下,您可以使用您喜欢的任何配置选项。
如需更多信息,请参阅使用 Cryostat 代理和 JMX 连接配置应用程序。
3.1. 使用 Cryostat 代理 复制链接链接已复制到粘贴板!
Cryostat 代理作为 Java Instrumentation Agent 实施,该代理充当 JVM 上运行的应用程序的插件。Cryostat 代理提供了一个 HTTP API,它提供比 JMX 端口更大的部署灵活性,因为代理的双角色作为发现插件。您可以将目标应用程序配置为使用代理的 HTTP API 来通过 Cryostat 检测和连接。
3.1.1. Cryostat 代理功能 复制链接链接已复制到粘贴板!
Red Hat build of Cryostat 提供了 Cryostat 代理的不同发行版,并支持部署和使用代理的不同方法。请考虑以下信息,以帮助您确定 Cryostat 代理部署的类型以及最适合您的需求的用例。
3.1.1.1. 代理 JAR 文件发布 复制链接链接已复制到粘贴板!
Red Hat build of Cryostat 3.0 分发了 Cryostat 代理的 JAR 文件的两个不同变体:
一个一体化的"shaded" JAR 文件,该文件是自包含的,包括代理代码及其所有依赖项
此"shaded" JAR 文件提供了在现有应用程序中包括的最方便的 Cryostat 代理形式,因为您只需要包含一个额外的代理 JAR 文件。这是类似代理和工具的常见分发模式。在 Cryostat 2.4 之前,"shaded" JAR 文件是 Cryostat 代理的唯一可用发行版。"shaded" JAR 文件名采用 cry
ostat-agent-0.4.X.redhat-xxxxx-shaded.jar,其中0.4.X和xxxxx分别代表代理版本和构建号。包含没有依赖项的代理代码的标准 JAR 文件
如果您知道代理和工作负载应用程序之间存在依赖关系冲突,则这种类型的 JAR 文件很有用。如果您打算应用自己的策略,以提供每个依赖项的正确版本以满足代理和应用程序的要求,您可以使用独立 JAR 文件。标准 JAR 文件名采用 cry
ostat-agent-0.4 格式。X.redhat-xxxxx.jar,其中0.4.X和xxxxx分别代表代理版本和构建号。
如果要使用 Cryostat 代理,则一体化"shaded" JAR 文件是部署代理的首选方法。除非打算应用自己的策略来解决代理和工作负载应用之间的任何依赖关系冲突,否则请不要使用标准 JAR 文件。
agent JAR 文件可从 Red Hat Maven Repository 下载。
3.1.1.2. JVM 的静态或动态附件 复制链接链接已复制到粘贴板!
根据您的要求,Cryostat 代理可以使用静态或动态方法附加到 JVM。
JVM 的静态附件
您可以启用工作负载应用的 JVM,在 JVM 启动时加载和初始化 Cryostat 代理。这个静态附加方法要求您将应用程序配置为将路径为 Cryostat 代理的 JAR 文件(例如, )。在 Cryostat 代理的基本初始化完成后,您的工作负载应用程序的正常启动过程会正常开始。
-javaagent:/deployment/app/lib/cryostat-agent-shaded.jar
根据您的工作负载应用程序,静态附加方法可能需要设置一个或多个环境变量,或者在 argLine 参数中添加参数。然而,在某些情况下,您可能需要重新配置、重建并重新部署应用程序。静态附加还需要重启应用程序 JVM,这可能会导致应用程序停机。
在 Cryostat 3.0 之前,通过 -javaagent JVM 标志进行静态附加是启用 Cryostat 代理在目标应用程序上附加和运行的唯一方法。
如需更多信息,请参阅使用 Cryostat 代理配置应用程序。
JVM 的动态附加
从 Cryostat 3.0 开始,Cryostat 代理可以动态地附加正在运行的应用程序 JVM,而无需应用程序重启。这个动态附加功能有以下要求:
-
您必须确保代理的 JAR 文件被复制到 JVM 的文件系统中(例如,使用
oc cp命令)。 -
您必须能够在同一主机上或同一应用程序(例如,使用
oc exec命令)将代理作为单独的进程运行。
动态附加功能支持临时一次性性能分析或故障排除工作流,您可能不需要在每次 JVM 启动时附加代理。动态附加还适合于无法或不想为附加代理的唯一目的重新配置应用程序的情况。由于代理可以在不需要应用重启的情况下附加到正在运行的 JVM,因此这也意味着没有应用停机时间。
如需更多信息,请参阅 启动 Cryostat 代理作为对 JVM 的动态附加的独立进程。
3.1.1.3. 将代理的 JAR 文件包含到工作负载应用程序中的选项 复制链接链接已复制到粘贴板!
根据您的要求,您可以以不同的方式将 Cryostat 代理的 JAR 文件包含在工作负载应用程序中:
-
对于正在运行的 JVM 的动态一次性连接,您可以使用
oc cp命令将代理的 JAR 文件复制到 JVM 的文件系统中。 对于在启动时对 JVM 的静态附件,您可以使用以下选项之一:
-
最简单的选项是将 JAR 文件添加到
pom.xml或build.gradle文件中的应用依赖项中。您的构建工具(Maven 或 Gradle)会下载 JAR 文件,以包含在您的应用构建输出中。 -
您可以使用 Maven 插件(如
maven-dependency-plugin)提供对应用构建输出中下载和包含 JAR 文件的更精细的控制。 -
您可以创建一个包含 JAR 文件的 PersistentVolume 存储卷。然后,重新配置应用程序的
Deployment/DeploymentConfig以挂载 PersistentVolume 和 use-javaagent:/path/to/persistentvolume/cryostat-agent-shaded.jar。完成此任务的确切方法取决于您在 OpenShift 集群中启用的 PersistentVolume 供应商类型。
-
最简单的选项是将 JAR 文件添加到
当 Cryostat 代理成功添加到应用程序容器中并载入后,应用程序的 stdout 和 控制台日志 会开始显示 Cryostat 代理中的日志消息。
3.1.1.4. 代理配置属性 复制链接链接已复制到粘贴板!
您可以通过以下两种方式之一为 Cryostat 代理指定配置属性:
-
在应用上使用 JVM 系统属性标志(例如,
-Dcryostat.agent.api.writes-enabled=true)。 -
通过将所有字母大写字母组成并将任何标点替换为下划线(例如,
CRYOSTAT_AGENT_API_WRITES_ENABLED=true)来使用环境变量。
所需的代理属性
您必须配置以下属性,以便 Cryostat 代理能够成功运行:
|
|
这将指定 Cryostat 代理向(即内部 OpenShift Service 对象)公告自己(如 |
|
|
这将指定 Cryostat 代理实例或应用程序本身的 URL 位置。Cryostat 使用此 URL 执行健康检查并从代理请求数据。您可以使用 OpenShift/Kubernetes Downward API 将此属性设置为如 |
|
|
这指定了一个标头值,Cryostat 代理可以在对 Cryostat 服务器的 API 请求中包含(例如, 注意
此属性优先于 |
|
|
这指定了与 注意
如果您为 有效的授权类型如下:
此属性默认设置为 |
|
|
这指定了与 注意
如果您为 请考虑以下指南:
默认情况下,此属性设置为 |
可选代理属性
根据您的设置要求,您还可以配置以下代理属性:
|
|
这表明 Cryostat 代理是否允许写操作。这默认设置为 注意
即使此属性设置为 |
|
| 这将指定代理用来绑定其 HTTP API 的 HTTP 端口号(默认为 9977)。如果这与应用程序或其他工具代理使用的现有端口冲突,您必须指定不同的端口号。 |
|
|
这指定了一个标签,用于标识此 Cryostat 代理实例附加到哪个应用程序(默认情况下,cry |
前面的列表只描述了 Cryostat 代理的可用配置属性的子集。有关代理属性的完整列表,请参阅 代理属性。
3.1.2. 使用 Cryostat 代理配置应用程序 复制链接链接已复制到粘贴板!
您可以使用 Cryostat 代理(作为 Java Instrumentation Agent 实施)来配置目标应用程序,以便 Cryostat 可以检测应用程序,收集数据,并将数据发送到 Cryostat 以进行分析。您还可以选择启用 Cryostat 代理,以接受来自 Cryostat 服务器的请求,以启动、停止和删除 JFR 记录。
如果要使用静态附加功能,这个过程是相关的,它允许工作负载应用程序的 JVM 在 JVM 启动时加载和初始化 Cryostat 代理。如果您希望 Cryostat 代理一次附加到运行的 JVM,请参阅 启动 Cryostat 代理作为动态附加的独立进程到 JVM。
如 Agent JAR 文件分发 中所述,红帽提供了两个不同版本的 Cryostat 代理,可以是一体化"shaded" JAR 文件或作为标准 JAR 文件。all-in-one "shaded" JAR 文件是部署 Cryostat 代理的首选方法。除非打算应用自己的策略来解决代理和工作负载应用之间的任何依赖关系冲突,否则请不要使用标准 JAR 文件。
以下流程描述了如何安装 Cryostat 3.0 代理的"shaded" JAR 文件分发。可以从 Red Hat Maven 存储库 下载最新的"shaded" JAR 文件。"shaded" JAR 文件名采用 cry ostat-agent-0.4.X.redhat-xxxxx-shaded.jar,其中 0.4.X 和 xxxxx 分别代表代理版本和构建号。有关 Cryostat 代理的最新版本和构建号的详情,请参考 Red Hat Maven 存储库。
如在 工作负载应用程序中包含代理的 JAR 文件的 Options 所述,Cryostat 3.0 代理支持不同的选项,用于将代理的 JAR 文件包含在工作负载应用程序中。以下流程描述了如何将 "shaded" JAR 文件添加到 pom.xml 或 build.gradle 文件中的应用程序依赖项中。
先决条件
- 登录到您的 Cryostat web 控制台。
- 安装了 JDK 版本 11 或更高版本。
流程
安装 Cryostat 代理。根据您的应用程序构建选择以下选项之一:
使用 Maven:
使用 Cryostat 代理 JAR 文件信息更新应用程序
pom.xml文件。pom.xml 示例
<project> ... <repositories> <repository> <id>redhat-maven-repository</id> <url>https://maven.repository.redhat.com/earlyaccess/all/</url> </repository> </repositories> ... <build> <plugins> <plugin> <artifactId>maven-dependency-plugin</artifactId> <version>3.3.0</version> <executions> <execution> <phase>prepare-package</phase> <goals> <goal>copy</goal> </goals> <configuration> <artifactItems> <artifactItem> <groupId>io.cryostat</groupId> <artifactId>cryostat-agent</artifactId> <version>0.4.X.redhat-xxxxx</version> <classifier>shaded</classifier> </artifactItem> </artifactItems> <stripVersion>true</stripVersion> </configuration> </execution> </executions> </plugin> </plugins> ... </build> ... </project>注意在前面的示例中,将
0.4.X.redhat-xxxxx替换为 Cryostat 代理的最新版本和构建号。有关 Cryostat 代理的最新版本和构建号的详情,请参考 Red Hat Maven 存储库。下次构建应用程序时,Cryostat 代理 JAR 文件位于
target/dependency/cryostat-agent-shaded.jar。使用 Gradle:
更新
build.gradle文件。build.gradle文件示例repositories { … maven { url "https://maven.repository.redhat.com/earlyaccess/all/" credentials { username "myusername" password "mytoken" } } }如何将代理 JAR 文件打包到应用中取决于用于构建的 Gradle 插件。例如,如果您使用 Jib 插件,请按如下所示更新
build.gradle文件:build.gradle文件示例plugins { id 'java' id 'application' id 'com.google.cloud.tools.jib' version '3.3.1' id 'com.ryandens.javaagent-jib' version '0.5.0' } … dependencies { … javaagent 'io.cryostat:cryostat-agent:0.4.X.redhat-xxxxx:shaded'注意在前面的示例中,将
0.4.X.redhat-xxxxx替换为 Cryostat 代理的最新版本和构建号。有关 Cryostat 代理的最新版本和构建号的详情,请参考 Red Hat Maven 存储库。
更新 Docker 文件。以下示例使用
JAVA_OPTS环境变量传递相关的 JVM 信息。Example
... COPY target/dependency/cryostat-agent-shaded.jar /deployments/app/ ... ENV JAVA_OPTS="-javaagent:/deployments/app/cryostat-agent-shaded.jar"重建特定于应用程序的容器镜像。
docker build -t docker.io/myorg/myapp:latest -f src/main/docker/Dockerfile要提供您需要配置 Cryostat 代理的 JVM 系统属性或环境变量,请推送更新的镜像,然后修改应用程序部署。
Example
apiVersion: apps/v1 kind: Deployment ... spec: ... template: ... spec: containers: - name: sample-app image: docker.io/myorg/myapp:latest env: - name: CRYOSTAT_AGENT_APP_NAME value: "myapp" # Replace this with the Kubernetes DNS record # for the Cryostat Service - name: CRYOSTAT_AGENT_BASEURI value: "http://cryostat.mynamespace.mycluster.svc:4180" - name: POD_IP valueFrom: fieldRef: fieldPath: status.podIP - name: CRYOSTAT_AGENT_CALLBACK value: "http://$(POD_IP):9977"1 # Replace "abcd1234" with a plain-text authentication token - name: CRYOSTAT_AGENT_AUTHORIZATION2 value: "Bearer abcd1234" - name: CRYOSTAT_AGENT_API_WRITES_ENABLED3 value: true ports: - containerPort: 9977 protocol: TCP resources: {} restartPolicy: Always status: {}-
<1>: 端口号
9977是代理为服务 Cryostat 请求的内部 Web 服务器公开的默认 HTTP 端口。如果与安装代理的目标应用程序冲突,您可以更改此端口号。 -
<2>:
CRYOSTAT_AGENT_AUTHORIZATION值显示代理在 API 请求中包含的凭证,以公告其自身存在或推送 JFR 数据。您还可以为此目的创建一个 Kubernetes服务帐户,并将abcd1234替换为与服务帐户关联的纯文本身份验证令牌。 -
<3>:默认情况下
CRYOSTAT_AGENT_API_WRITES_ENABLED变量设为false。如果您希望 Cryostat 代理接受来自 Cryostat 服务器的请求以启动、停止或删除 JFR flight 记录,您必须将此变量设置为true。
-
<1>: 端口号
3.1.2.1. 将 Cryostat 代理配置为信任 Cryostat 服务器 复制链接链接已复制到粘贴板!
当您将 Cryostat 代理与启用了 cert-manager 集成的 Cryostat 实例搭配使用时,Cryostat 代理会通过安全 HTTPS 连接与 Cryostat 通信。在这种情况下,Cryostat Operator 使用 cert-manager 来生成自签名证书颁发机构(CA)证书,该证书存储在 secret 中。您必须将 Cryostat 代理配置为信任此 CA 证书。
流程
创建一个 Cryostat CR,为您的 Cryostat 实例和目标应用程序定义命名空间。
例如,如果要在
cryostat命名空间中创建 Cryostat CR,该 CR 配置为连接到apps命名空间中的目标应用程序,请输入以下详情:apiVersion: operator.cryostat.io/v1beta2 kind: Cryostat metadata: name: cryostat-sample namespace: cryostat spec: enableCertManager: true targetNamespaces: - apps在 Cryostat 可用时,要获取目标应用程序命名空间中的 CA 证书 secret,请输入以下命令:
$ oc project apps $ oc get secret "cryostat-ca-$(echo -n 'cryostat/cryostat-sample' | sha256sum | cut -d ' ' -f 1)"在前面的示例中,将
apps替换为您的目标应用程序的命名空间,并将cryostat/cryostat-sample替换为 Cryostat 实例的命名空间和名称。另外,请确保 Cryostat 实例的命名空间和名称用正斜杠(/)分隔。前面的命令会生成类似如下的输出:
如上例所示,secret 名称包含一个哈希后缀,以防止与集群中的其他 Cryostat 实例冲突。
通过创建 init 容器将证书导入到信任存储中,将 Cryostat 代理配置为信任 Cryostat 的 CA 证书。
注意此步骤假设您在
apps命名空间中有一个名为my-app的目标应用程序,该应用程序安装了 Cryostat 代理,否则会正确配置。在以下示例中,将任何出现
my-app和apps替换为目标应用程序的名称和命名空间。使用在第 2 步中 获取的 secret 名称,为部署中的 Cryostat CA secret 创建卷。
例如:
$ oc set volumes deploy/my-app --add --name=cryostat-ca --secret-name=cryostat-ca-30268177e44252b3f9b7d9bf3a6db48f3a1cd3656700a6830952afc4456c0048前面的命令会生成类似如下的输出:
deployment.apps/my-app volume updated创建一个
emptyDir卷,以在 init 容器和应用程序容器间共享信任存储:例如:
$ oc set volumes deploy/my-app --add --name=truststore -m /var/run/secrets/io.cryostat/truststore前面的命令会生成类似如下的输出:
deployment.apps/my-app volume updated向目标应用程序的部署 YAML 文件中添加一个 init 容器。
例如:
initContainers: - name: pem-to-truststore image: registry.access.redhat.com/ubi8/openjdk-11-runtime:latest command: - /bin/bash args: - -c - >- keytool -import -file /var/run/secrets/io.cryostat/cryostat-ca/tls.crt -keystore /var/run/secrets/io.cryostat/truststore/truststore.jks -trustcacerts -noprompt -storepass <my password> volumeMounts: - mountPath: /var/run/secrets/io.cryostat/cryostat-ca name: cryostat-ca - mountPath: /var/run/secrets/io.cryostat/truststore name: truststore在前面的示例中,将 &
lt;mypassword> 替换为您要使用的密码。在应用程序中定义
javax.ssl.trustStoreJava 系统属性。例如:
env: - name: JAVA_OPTS_APPEND value: |- # … -Djavax.net.ssl.trustStore=/var/run/secrets/io.cryostat/truststore/truststore.jks -Djavax.net.ssl.trustStorePassword=<my password>在前面的示例中,将
<mypassword> 替换为您在上一步中指定的密码。注意如何设置 Java 系统属性取决于应用程序的构建方式以及您使用的基础镜像。前面的示例假设您使用通过 OpenJDK UBI 镜像构建的应用程序。
3.1.3. 启动 Cryostat 代理作为到 JVM 动态附加的独立进程 复制链接链接已复制到粘贴板!
如果您希望 Cryostat 代理动态附加到已在运行的应用程序 JVM,您可以将代理作为独立 Java 进程启动。
只有在您想要使用动态附加功能时,这个过程才相关,这允许 Cryostat 代理附加到临时一次性运行的 JVM。如果您希望工作负载的 JVM 在 JVM 启动时加载和初始化 Cryostat 代理,请参阅使用 Cryostat 代理配置应用程序。
先决条件
使用
oc cp命令将代理的 JAR 文件复制到 JVM 的文件系统。注意可以从 Red Hat Maven 存储库 下载最新的"shaded" JAR 文件。"shaded" JAR 文件名采用 cry
ostat-agent-0.4.X.redhat-xxxxx-shaded.jar,其中0.4.X和xxxxx分别代表代理版本和构建号。
流程
输入以下命令:
$ java -jar target/<agent_jar_file> <pid>在前面的命令中,将 < ;agent_jar_file > 替换为代理的 JAR 文件名,并将 <pid > 替换为您要附加到的 JVM 的进程 ID (PID)。
例如:
$ java -jar target/cryostat-agent-0.4.1.redhat-00001-shaded.jar 1234注意前面的示例仅显示了说明,可能不会反映"shaded" JAR 文件的最新可用版本和构建。
运行上述命令时,代理进程使用其附加提供程序来查找指定的 PID。如果找到指定的 PID,代理进程会附加到此 PID,并尝试将代理的 JAR 文件加载到此 JVM 中,然后引导到正常的代理启动进程。
基于 PID 值的代理启动行为
根据 PID 值,请考虑以下代理启动行为准则:
- 如果您指定了无效的 PID,代理将无法成功启动。
-
如果您将通配符星号(
*)指定为 PID 值,代理的 JAR 文件将尝试引导到它找到的每个 JVM。 -
如果将
0指定为 PID 值,或者没有指定任何 PID 值,代理会检查是否只有一个 candidate JVM 可用。如果只有一个 JVM 可用,代理会尝试引导到此 JVM。如果多个 JVM 或没有 JVM 可用,代理将无法成功启动。
late-binding 配置选项
当将 Cryostat 代理作为独立进程启动时,您也可以使用命令行选项在代理启动程序中指定额外的 late-binding 配置选项。
例如:
$ java -jar target/cryostat-agent-0.4.1.redhat-00001-shaded.jar \
-Dcryostat.agent.baseuri=<cryostat_server_url> \
-Dcryostat.agent.callback=<cryostat_agent_url> \
-Dcryostat.agent.authorization=Bearer <authorization_value> \
--smartTrigger=[ProcessCpuLoad>0.2]~profile \
@/deployment/app/moreAgentArgs \
1234
有关可用选项及其行为的信息,请运行 java -jar target/ <filename>.jar -h help 命令,其中 & lt;filename > 代表您复制的"shaded"代理 JAR 文件的名称。
如上例中所示,当将 Cryostat 代理作为独立进程启动时,请确保在 the-jar < path_to_jarfile> 参数后 为任何 late- binding 配置选项指定 -D 标志。-D 标志的位置在此非常重要:
-
如果您在 <
path_to_jarfile>参数之前为系统属性指定标志,则在独立启动程序 JVM 进程上设置此属性。当将代理作为独立进程启动时,这可能会导致意外的问题。-D -
如果您在 /jar <
path_to_jarfile> 参数后为系统属性指定标志,则这些属性将作为参数传递到代理启动程序。当启动程序将代理引导到主机 JVM 中时,代理会在代理启动时将这些属性应用到 JVM。-D
如上例所示,请确保将任何所需的代理属性(如 cryostat.agent.baseuri、cryostat.agent.callback )和 cryostat.agent.authorization 指定为代理启动程序的配置选项。有关配置属性的更多信息,请参阅 代理配置属性。