本文发布于Cylon的收藏册,转载请著名原文链接~
项目设计
需求:外部分析器工具连接到运行在 kubernetes 集群上 Java pod 的 JVM,通过 jprofiler 暴露其接口,可以直接连接至这个 java pod
问题解决
Jprofiler 如何在 kubernetes 集群中运行:
- 方法1:打包至业务Pod容器内
- 缺点:需要侵入业务Pod内,不方便
- 方法2:使用 Init Container 将 JProfiler 安装复制到 Init Container 和将在 Pod 中启动的其他容器之间共享的卷
- 方法3:使用 sidecar 方式 共享业务Pod与 sidecar 共享名称空间
- 缺点:涉及到容器共享进程空间,与 jprofiler-agent 机制问题,所以需要共享 /tmp 目录
JProfiler finds JVMs via the “Attach API” that is part of the JDK. Have a look at the
$TMP/hsperfdata_$USER
directory, which is created by the hot spot JVM. It should contain PID files for all running JVMs. If not, delete the directory and restart all JVMs.
使用 Init Container 实施步骤
先决条件
假设已存在 Java 应用程序 deployment,我们还需要一个 JProfiler 镜像。如果您没有 JProfiler 镜像,这里有一个可用于构建映像的Dockerfile示例
FROM centos:7
# Switch to root
USER 0
ENV \
JPROFILER_DISTRO="jprofiler_linux_10_1_1.tar.gz" \
STAGING_DIR="/jprofiler-staging" \
HOME="/jprofiler"
LABEL \
io.k8s.display-name="JProfiler from ${JPROFILER_DISTRO}"
RUN yum -y update \
&& yum -y install ca-certificates curl \
&& mkdir -p ${HOME} ${STAGING_DIR} \
&& cd ${STAGING_DIR} \
# curl is expected to be available; wget would work, too
# Add User-Agent header to pretend to be a browser and avoid getting HTTP 404 response
&& curl -v -OL "https://download-keycdn.ej-technologies.com/jprofiler/${JPROFILER_DISTRO}" -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36" \
&& tar -xzf ${JPROFILER_DISTRO} \
&& rm -f ${JPROFILER_DISTRO} \
# Eliminate the version-specific directory
&& cp -R */* ${HOME} \
&& rm -Rf ${STAGING_DIR} \
&& chmod -R 0775 ${HOME} \
&& yum clean all
# chown and switch user as needed
WORKDIR ${HOME}
与业务Pod配置
更改应用程序的部署配置如下:
- 如果尚未定义,请在 “spec.template.spec” 下添加 “volumes” 部分并定义一个新卷:
volumes:
- name: jprofiler-share-tmp
emptyDir: {}
如果尚未定义,请在“spec.template.spec” 下添加 “initContainers”(Kubernetes 1.6+),并使用 JProfiler 的镜像定义 Init Container 将 Init container 中的文件复制到共享目录
initContainers:
- name: jprofiler-init
image: <JPROFILER_IMAGE:TAG>
command: ["/bin/sh", "-c", "cp -R /jprofiler/ /tmp/"]
volumeMounts:
- name: jprofiler
mountPath: "/tmp/jprofiler"
将 jprofiler-agent 添加到 JVM 启动参数。
-agentpath:/jprofiler/bin/linux-x64/libjprofilerti.so=port=8849
完整的Deployment 示例
apiVersion: apps/v1
kind: Deployment
metadata:
name: jprofiler-test
spec:
replicas: 1
selector:
matchLabels:
app: jprofiler
template:
metadata:
labels:
app: jprofiler
spec:
volumes:
- name: jprofiler-share-tmp
emptyDir: {}
shareProcessNamespace: true
initContainers:
- name: jprofiler-init
image: jprofiler:14_0
command: ["/bin/sh", "-c", "cp -R /jprofiler/ /tmp/"]
volumeMounts:
- name: jprofiler-share-tmp
mountPath: "/tmp"
containers:
- name: sprintboot-test
image:javaweb:3
imagePullPolicy: IfNotPresent
volumeMounts:
- name: jprofiler-share-tmp
mountPath: /tmp
env:
- name: JAVA_OPTS
# nowait 表示启动时不需要手动确认,如果不加会stuck到 jprofiler,使得业务容器不能启动
# -agentpath 必须加到java参数后,而不是 java -jar xxx -agentpath 这样
value: "-agentpath:/tmp/jprofiler/jprofiler14.0/bin/linux-x64/libjprofilerti.so=port=8849,nowait"
command:
- "java"
- "-jar"
- demo-0.0.1-SNAPSHOT.jar
args:
- --server.port=8085
本文发布于Cylon的收藏册,转载请著名原文链接~
链接:https://www.oomkill.com/2023/12/stackstorm-rules/
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」 许可协议进行许可。