<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jean-François Lamy</title>
    <description>The latest articles on DEV Community by Jean-François Lamy (@jflamy).</description>
    <link>https://dev.to/jflamy</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F366513%2Fd9f91d1a-898b-458f-9126-ede044663431.jpeg</url>
      <title>DEV Community: Jean-François Lamy</title>
      <link>https://dev.to/jflamy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jflamy"/>
    <language>en</language>
    <item>
      <title>Compiling Java 17 using Maven in an Azure DevOps Pipeline</title>
      <dc:creator>Jean-François Lamy</dc:creator>
      <pubDate>Wed, 29 Dec 2021 15:27:51 +0000</pubDate>
      <link>https://dev.to/jflamy/compiling-java-17-using-maven-in-an-azure-devops-pipeline-24cn</link>
      <guid>https://dev.to/jflamy/compiling-java-17-using-maven-in-an-azure-devops-pipeline-24cn</guid>
      <description>&lt;p&gt;Using ubuntu-latest machines in an Azure DevOps pipeline, there is currently no support for versions beyond 11.  So using a Maven@3 task to compile using a newer version fails.  The workaround is to use a container version of Maven.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jobs:
  # build uberjar
  - job: ${{ parameters.jobName }}
    pool:
      vmImage: ubuntu-latest
    container: maven:3.8.1-openjdk-17-slim
    variables:
      - name: JAVA_HOME_11_X64
        value: /usr/local/openjdk-17
    steps:
      - template: steps-prepare-maven.yml
      - task: Maven@3
        displayName: build ${{ parameters.moduleName }} uberJar 
        inputs:
          mavenPomFile: pom.xml
          mavenOptions: -Xmx3072m $(MavenOpts)
          javaHomeSelection: 'path'
          jdkDirectory: '/usr/local/openjdk-17'
          publishJUnitResults: true
          testResultsFiles: "**/surefire-reports/TEST-*.xml"
          effectivePomSkip: true
          goals: -P production -pl ${{ parameters.moduleName }} -am $(MavenOpts) -Dmaven.test.skip=${{ parameters.skipTests }} $(BuildGoal)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are using &lt;code&gt;openjdk-17&lt;/code&gt; &lt;em&gt;and&lt;/em&gt; explicitly using &lt;code&gt;javaHomeSelection&lt;/code&gt; and &lt;code&gt;jdkDirectory&lt;/code&gt; to set our &lt;code&gt;JAVA_HOME&lt;/code&gt; to match where the container puts the JDK.&lt;/p&gt;

&lt;p&gt;So why are we also defining the environment variable &lt;code&gt;JAVA_HOME_11_X64&lt;/code&gt;, you ask? Well, I have reusable templates that are used outside the container setting.  For example, the &lt;code&gt;steps-prepare-maven.yml&lt;/code&gt; file is a template that creates a settings.xml file using the project secrets and updates the revision based on my build parameters - I also use it on Windows jobs. Such steps use the default version, Java 11.  When running inside the container, the JAVA_HOME_11_X64 takes precedence and the Maven steps in the reusable templates work correctly.&lt;/p&gt;

&lt;p&gt;This is extracted from a template file, replace the parameters with what you need.&lt;/p&gt;

&lt;p&gt;Credit: sfragata's &lt;a href="https://github.com/microsoft/azure-pipelines-tasks/issues/14915#issuecomment-868473328"&gt;answer&lt;/a&gt; to a github issue got me started.  Then I stumbled around until I could fix my included templates using the environment variable.&lt;/p&gt;

</description>
      <category>java</category>
      <category>maven</category>
    </item>
    <item>
      <title>Interactive Java JVM Monitoring on Kubernetes - Configuring VisualVM to use JMXMP</title>
      <dc:creator>Jean-François Lamy</dc:creator>
      <pubDate>Thu, 21 May 2020 13:11:18 +0000</pubDate>
      <link>https://dev.to/jflamy/interactive-java-jvm-monitoring-on-kubernetes-part-2-configuring-visualvm-to-use-jmxmp-181d</link>
      <guid>https://dev.to/jflamy/interactive-java-jvm-monitoring-on-kubernetes-part-2-configuring-visualvm-to-use-jmxmp-181d</guid>
      <description>&lt;p&gt;This is part 2 of a 2-part series.&lt;/p&gt;

&lt;p&gt;Despite feature requests to do so and some work to create a plugin, VisualVM does not ship with JMXMP configured by default.   The following recipe has been tested with VisualVM 2.0.1.&lt;/p&gt;

&lt;p&gt;If we used Maven to enable our application, we have a copy of the required java archive (jar) in the .m2 directory.  The simple way is to add that jar to the class path using the &lt;code&gt;--cp:a&lt;/code&gt; option.   This jar would normally have to be "endorsed" to be used, but starting from the directory where it is found allows things to work.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="nf"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;C:\Dev\.m2\repository\org\glassfish\external\opendmk_jmxremote_optional_jar\1.0-b01-ea&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nf"&gt;C:\Dev\Java\visualvm_201\bin\visualvm.exe&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--cp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;opendmk_jmxremote_optional_jar-1.0-b01-ea.jar&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can also create a shortcut on your desktop to run the command.  Use the &lt;code&gt;Start In&lt;/code&gt; option to select the directory where the jmxremote jar is found.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding a remote host
&lt;/h3&gt;

&lt;p&gt;When accessing a remote host such as KubeSail, add it using the &lt;code&gt;add remote host&lt;/code&gt; option&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hlLuUXnN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://user-images.githubusercontent.com/678663/82157843-d6b23e80-9851-11ea-8444-6ab5f8299fdd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hlLuUXnN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://user-images.githubusercontent.com/678663/82157843-d6b23e80-9851-11ea-8444-6ab5f8299fdd.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Configure a connection
&lt;/h3&gt;

&lt;p&gt;Under the new host (or under Local if connecting locally), right-click and use &lt;code&gt;Add JMX Connection&lt;/code&gt;.   Use the accessible address.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If running locally, this will be localhost, and the syntax will be &lt;code&gt;service:jmx:jmxmp://localhost:1098&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;if remote, the external address obtained by querying the pod. 
In our example, that yields&lt;code&gt;service:jmx:jmxmp://54.151.2.??:300??&lt;/code&gt;  (the port is the one listed in the NodePort configuration as explained in &lt;a href="https://dev.to/jflamy/interactive-java-jvm-monitoring-on-kubernetes-part-1-exposing-jmxmp-5c3f"&gt;Part 1&lt;/a&gt;.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FV35k6_u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://user-images.githubusercontent.com/678663/82157887-24c74200-9852-11ea-8351-a6f2f6c8add0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FV35k6_u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://user-images.githubusercontent.com/678663/82157887-24c74200-9852-11ea-8351-a6f2f6c8add0.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Double-clicking on the new connection will open it, and the name of the monitored application will be shown.  You can then use the various tabs to monitor, examine or sample the application.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ns6qijmY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://user-images.githubusercontent.com/678663/82157944-9f905d00-9852-11ea-8331-318e88f14b2c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ns6qijmY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://user-images.githubusercontent.com/678663/82157944-9f905d00-9852-11ea-8331-318e88f14b2c.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>visualvm</category>
      <category>monitoring</category>
      <category>jmx</category>
    </item>
    <item>
      <title>Interactive Java JVM Monitoring on Kubernetes: Exposing JMXMP</title>
      <dc:creator>Jean-François Lamy</dc:creator>
      <pubDate>Thu, 21 May 2020 13:00:25 +0000</pubDate>
      <link>https://dev.to/jflamy/interactive-java-jvm-monitoring-on-kubernetes-part-1-exposing-jmxmp-5c3f</link>
      <guid>https://dev.to/jflamy/interactive-java-jvm-monitoring-on-kubernetes-part-1-exposing-jmxmp-5c3f</guid>
      <description>&lt;p&gt;In addition to log-based or agent-based monitoring, it is occasionally necessary to inspect interactively the behavior of a Java application, in particular its memory usage or CPU usage.  In the Java ecosystem, the free VisualVM or jconsole tools are often used. These tools also allow seeing the thread usage and drill down/filter interactively.&lt;/p&gt;

&lt;p&gt;This post explains the steps necessary to manually inspect a Java application using the JMXMP protocol in a Kubernetes cluster.&lt;br&gt;
Part 1 is about making the application to be monitored visible using JMXMP&lt;br&gt;
Part 2 discusses how to add VisualVM to the mix (similar techniques apply to other monitoring tools)&lt;/p&gt;

&lt;h2&gt;
  
  
  What about RMI?
&lt;/h2&gt;

&lt;p&gt;Exposing the default RMI protocol is extremely painful because of the way it handles ports and requires a back channel.  The general consensus is don't bother.  After wasting a couple days, I wholeheartedly agree.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enabling JMXMP monitoring
&lt;/h2&gt;

&lt;p&gt;The simplest way to enable monitoring is to create the monitoring port ourselves.  For example, in a web frontend, add the following to open port 1098 for JMXMP monitoring:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Get the MBean server for monitoring/controlling the JVM&lt;/span&gt;
    &lt;span class="nc"&gt;MBeanServer&lt;/span&gt; &lt;span class="n"&gt;mbs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ManagementFactory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPlatformMBeanServer&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Create a JMXMP connector server&lt;/span&gt;
    &lt;span class="nc"&gt;JMXServiceURL&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;JMXServiceURL&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"jmxmp"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"localhost"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1098&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="nc"&gt;JMXConnectorServer&lt;/span&gt; &lt;span class="n"&gt;cs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;JMXConnectorServerFactory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newJMXConnectorServer&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
            &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mbs&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;cs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printStackTrace&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In order for this code to compile, you will need to include a JMXMP implementation.  If using Maven, add the following to your &lt;code&gt;pom.xml&lt;/code&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;

&lt;span class="c"&gt;&amp;lt;!-- https://mvnrepository.com/artifact/org.glassfish.external/opendmk_jmxremote_optional_jar --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.glassfish.external&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;opendmk_jmxremote_optional_jar&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.0-b01-ea&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In real life, &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you will likely use an environment variable so you can configure the port number using a ConfigMap or Secret, and perhaps not start the connector if there is no such variable present.&lt;/li&gt;
&lt;li&gt;You may wish to secure the connection.   For my own purposes, I have used IP whitelisting of my development workstation in a k8s networking policy, so I have not explored this topic further.
See &lt;a href="https://interlok.adaptris.net/interlok-docs/advanced-jmx.html" rel="noopener noreferrer"&gt;https://interlok.adaptris.net/interlok-docs/advanced-jmx.html&lt;/a&gt; for examples on how to enable this.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Special considerations for building the container
&lt;/h3&gt;

&lt;p&gt;KubeSail uses IPv6 by default.  In the process of debugging this recipe, we have found it necessary to add the following Java flags to the Java entry point command of the Docker container.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nt"&gt;-Djava&lt;/span&gt;.net.preferIPv4Stack&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;span class="nt"&gt;-Dcom&lt;/span&gt;.sun.management.jmxremote.ssl&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt;
&lt;span class="nt"&gt;-Dcom&lt;/span&gt;.sun.management.jmxremote.authenticate&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;(Editor's note - We will be checking whether they are still necessary.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Exposing a port in Kubernetes for Docker Desktop
&lt;/h2&gt;

&lt;p&gt;The following instructions have been tested with the new WSL2 Docker backend which runs directly on Linux.&lt;/p&gt;

&lt;p&gt;For Docker Desktop, the simplest way to expose a port is to use a LoadBalancer service.  This avoids having to use kubectl on every session.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Service&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myapp&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myapp&lt;/span&gt;
  &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;TCP&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http&lt;/span&gt;
    &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
    &lt;span class="na"&gt;targetPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8080&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;TCP&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jmx&lt;/span&gt;
    &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1098&lt;/span&gt;
    &lt;span class="na"&gt;targetPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1098&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;LoadBalancer&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This makes it possible to open the web application on &lt;a href="http://localhost" rel="noopener noreferrer"&gt;http://localhost&lt;/a&gt; even though the container is communicating on port 8080, and also opens up the JMX monitoring channel on port 1098.   You can change the port to suit your needs, but &lt;code&gt;targetPort&lt;/code&gt; needs to match what is used by the application being monitored (see the Java above).&lt;/p&gt;

&lt;h2&gt;
  
  
  Exposing a port with KubeSail Kubernetes
&lt;/h2&gt;

&lt;p&gt;KubeSail is an affordable managed PaaS for running Kubernetes applications.  By default, only the traffic coming in through an Ingress (NGINX) is allowed to go further.  It is therefore necessary to &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;create a Network Policy that allows traffic to flow to the monitored application container&lt;/li&gt;
&lt;li&gt;expose the port for monitoring&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Creating a network policy
&lt;/h3&gt;

&lt;p&gt;The following opens the 1098 port on the application to be accessed from the outside, and limits outside access to a certain address (obviously you would use your own).&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;NetworkPolicy&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;networking.k8s.io/v1&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myapp-allow-jmx&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;podSelector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myapp&lt;/span&gt;
  &lt;span class="na"&gt;policyTypes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Ingress&lt;/span&gt;
  &lt;span class="na"&gt;ingress&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;ipBlock&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;cidr&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;208.77.188.166/32&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;TCP&lt;/span&gt;
      &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1098&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;More advanced topics are discussed on this page &lt;br&gt;
&lt;a href="https://www.magalix.com/blog/kubernetes-network-policies-101" rel="noopener noreferrer"&gt;https://www.magalix.com/blog/kubernetes-network-policies-101&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Exposing the monitoring port
&lt;/h3&gt;

&lt;p&gt;The simplest way is to use a NodePort, which makes the virtual machine open a port and expose it to the outside world.  In the case of a shared service like KubeSail, there is therefore the possibility that the chosen port is in conflict with others, and that you will need to change it. &lt;br&gt;
The last line (externalTrafficPolicy) is required to prevent Kubernetes from doing a NAT (Network Address Translation)&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Service&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jmx&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myapp&lt;/span&gt;
  &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;protocol&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;TCP&lt;/span&gt;
    &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1098&lt;/span&gt;
    &lt;span class="na"&gt;targetPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1098&lt;/span&gt;
    &lt;span class="na"&gt;nodePort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;30098&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;NodePort&lt;/span&gt;
  &lt;span class="na"&gt;externalTrafficPolicy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Local&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Getting the address of the node
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;In order to the the address of the node, you may use&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

  kubectl get pod -o wide


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F678663%2F82157544-1e37cb00-9850-11ea-86e1-da3feed3f06a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fuser-images.githubusercontent.com%2F678663%2F82157544-1e37cb00-9850-11ea-86e1-da3feed3f06a.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You may also install the &lt;code&gt;jq&lt;/code&gt; JSON query tool, and use the following one-liner&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

  kubectl get pod -o json -l 'app=myapp' | jq -r '.items[0].spec.nodeName'


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;which will output the ip address (54.151.3.??) in the example&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In order to test that all is good, you can use the command.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

  telnet 54.151.3.?? 300??


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;You will get garbage back, but with a recognizable &lt;code&gt;javax.management.remote.message.HandshakeBeginMessage&lt;/code&gt; string at the beginning.&lt;/p&gt;

</description>
      <category>java</category>
      <category>monitoring</category>
      <category>visualvm</category>
      <category>jmx</category>
    </item>
  </channel>
</rss>
