<p>What do I have to put into a container to get the agent to run? Just libjprofilerti.so on its own doesn't work, I get</p>

<pre><code>Could not find agent.jar. The agentpath parameter must point to
libjprofilerti.so in an unmodified JProfiler installation. 
</code></pre>

<p>which sounds like obvious nonsense to me - surely I can't have to install over 137.5 MB of files, 99% of which will be irrelevant, in each container in which I want to profile something?</p>

<p>-agentpath:/path/to/libjprofilerti.so=nowait</p>

<p>An approach is to use <a href="https://kubernetes.io/docs/concepts/workloads/pods/init-containers/" rel="nofollow noreferrer">Init Container</a>. </p>

<p>The idea is to have an image for JProfiler separate from the application's image. Use the JProfiler image for an Init Container; the Init Container copies the JProfiler installation to a volume shared between that Init Container and the other Containers that will be started in the Pod. This way, the JVM can reference at startup time the JProfiler agent from the shared volume.</p>

<p>It goes something like this (more details are in this <a href="https://apisimulator.io/connect-jprofiler-to-jvm-kubernetes-pod/" rel="nofollow noreferrer">blog article</a>):</p>

<ul>
<li>Define a new volume:</li>
</ul>

<pre><code>volumes:
  - name: jprofiler
    emptyDir: {}
</code></pre>

<ul>
<li>Add an Init Container:</li>
</ul>

<pre><code>initContainers:
  - name: jprofiler-init
    image: &lt;JPROFILER_IMAGE:TAG&gt;
    command: ["/bin/sh", "-c", "cp -R /jprofiler/ /tmp/"]
    volumeMounts:
      - name: jprofiler
        mountPath: "/tmp/jprofiler"
</code></pre>

<p>Replace <code>/jprofiler/</code> above with the correct path to the installation directory in the JProfiler's image. Notice that the copy command will create <code>/tmp/jprofiler</code> directory under which the JProfiler installation will go - that is used as mount path.</p>

<ul>
<li>Define volume mount:</li>
</ul>

<pre><code>volumeMounts:
  - name: jprofiler
    mountPath: /jprofiler
</code></pre>

<ul>
<li>Add to the JVM startup arguments JProfiler as an agent:</li>
</ul>

<pre><code>-agentpath:/jprofiler/bin/linux-x64/libjprofilerti.so=port=8849
</code></pre>

<p>Notice that there isn't a "nowait" argument. That will cause the JVM to block at startup and wait for a JProfiler GUI to connect. The reason is that with this configuration the profiling agent will receive its profiling settings from the JProfiler GUI.</p>

<p>Change the application deployment to start with only one replica. Alternatively, start with zero replicas and scale to one when ready to start profiling.</p>

<p>To connect from the JProfiler's GUI to the remote JVM:</p>

<ul>
<li>Find out the name of the pod (e.g. <code>kubectl -n &lt;namespace&gt; get pods</code>) and set up port forwarding to it:</li>
</ul>

<pre><code>kubectl -n &lt;namespace&gt; &lt;pod-name&gt; port-forward 8849:8849
</code></pre>

<ul>
<li>Start JProfiler up locally and point it to 127.0.0.1, port 8849.</li>
</ul>

<p>Change the local port 8849 (the number to the left of <code>:</code>) if it isn't available; then, point JProfiler to that different port.</p>
