{"id":20465,"date":"2022-10-05T10:16:51","date_gmt":"2022-10-05T08:16:51","guid":{"rendered":"https:\/\/blog.trifork.com\/?p=20465"},"modified":"2022-10-05T10:16:51","modified_gmt":"2022-10-05T08:16:51","slug":"helm-your-way-to-kubernetes-with-spring-boot-admin","status":"publish","type":"post","link":"https:\/\/trifork.nl\/blog\/helm-your-way-to-kubernetes-with-spring-boot-admin\/","title":{"rendered":"Helm your way to Kubernetes with Spring Boot Admin"},"content":{"rendered":"\n<p>In this blog post I am experimenting with <a href=\"https:\/\/helm.sh\/\">Helm, the package manager for Kubernetes<\/a>  by packaging <a href=\"https:\/\/github.com\/codecentric\/spring-boot-admin\">codecentric&#8217;s Spring Boot Admin<\/a> for out of the box real-time insights into a suite of Spring Boot Java services deployed to Amazon Elastic Kubernetes Service (EKS).<\/p>\n\n\n\n<p><em>Spring Boot Admin<\/em> gives a nice overview of what is deployed in your <em>Kubernetes<\/em>&nbsp;&nbsp;cluster, in one or more namespaces. Behind the scenes, its magic is given by the <em>Spring Boot Actuator&#8217;s&nbsp;<\/em>endpoints.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"681\" src=\"https:\/\/trifork.nl\/articles\/wp-content\/uploads\/sites\/3\/2022\/10\/journal_endpoints_detected_event_actuator-1024x681.png\" alt=\"\" class=\"wp-image-20475\" srcset=\"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/10\/journal_endpoints_detected_event_actuator-1024x681.png 1024w, https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/10\/journal_endpoints_detected_event_actuator-300x199.png 300w, https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/10\/journal_endpoints_detected_event_actuator-768x511.png 768w, https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/10\/journal_endpoints_detected_event_actuator-1536x1021.png 1536w, https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/10\/journal_endpoints_detected_event_actuator-2048x1361.png 2048w, https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/10\/journal_endpoints_detected_event_actuator-1920x1276.png 1920w, https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/10\/journal_endpoints_detected_event_actuator-600x400.png 600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption>Applications Journal Actuator Endpoints Detected Event<br \/><\/figcaption><\/figure>\n\n\n\n<p>One of the easiest ways to install Java Spring Boot applications on Amazon Elastic Kubernetes Service (EKS) is using <a href=\"https:\/\/helm.sh\/\">Helm<\/a> as it offers:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>package management via a common <em>blue-print&nbsp;<\/em> called <em>helm chart&nbsp;<\/em>which is a collection of&nbsp; <em>yaml<\/em> files bundled together;<\/li><li>templating of dynamic configuration, think of possible Java options (<code>java -X<\/code>), service name, http port, any other configuration eligible for being externalised in order to make the<em>&nbsp;helm chart <\/em>re-usable, as well as application secrets;<\/li><li>easy override of dynamic configuration per environment and service. Example increase replica count for a stateless critical service in an environment under higher load;<\/li><li>release management by providing a history of charts installation within the EKS cluster.<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\"><em><br \/><\/em>\u279c helm-charts (main) \u2717 <strong>helm history spring-boot-admin<\/strong><br \/>REVISION        UPDATED                         STATUS          CHART                   APP VERSION     DESCRIPTION     <br \/>1               Mon May  9 11:05:36 2022        superseded      spring-boot-admin-0.0.2 2.6.6           Install complete<br \/>2               Thu May 12 13:47:23 2022        superseded      spring-boot-admin-0.0.3 2.6.7           Upgrade complete<br \/>3               Thu May 12 15:02:49 2022        deployed        spring-boot-admin-0.0.3 2.6.7           Upgrade complete<br \/>\u279c helm-charts (main) \u2717 <strong>helm rollback spring-boot-admin 1<\/strong><br \/>Rollback was a success! Happy Helming!<br \/>\u279c helm-charts (main) \u2717 <strong>helm history spring-boot-admin<\/strong>   <br \/>REVISION        UPDATED                         STATUS          CHART                   APP VERSION     DESCRIPTION     <br \/>1               Mon May  9 11:05:36 2022        superseded      spring-boot-admin-0.0.2 2.6.6           Install complete<br \/>2               Thu May 12 13:47:23 2022        superseded      spring-boot-admin-0.0.3 2.6.7           Upgrade complete<br \/>3               Thu May 12 15:02:49 2022        superseded      spring-boot-admin-0.0.3 2.6.7           Upgrade complete<br \/>4               Thu May 12 16:05:42 2022        deployed        spring-boot-admin-0.0.2 2.6.6           Rollback to 1   <br \/><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Creating the Spring Boot Admin Helm Chart<\/h2>\n\n\n\n<p>One of the reasons&nbsp;<em>Helm<\/em> is so popular is the ease of finding charts in open-sourced repositories. I even started my experiment with&nbsp;<a href=\"https:\/\/github.com\/evryfs\/helm-charts\/tree\/master\/charts\/spring-boot-admin\">this Spring Boot Admin chart<\/a>&nbsp;but then discovered that my installation use-case required a bit different Kubernetes objects to be created: <\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><em>ClusterRole<\/em> instead of a <em>Role<\/em><\/li><li><em>ClusterRoleBinding<\/em> instead of a <em>RoleBinding<\/em><\/li><li>I\u2019ve wanted to customise the <em>ServiceAccount<\/em> annotations to something in the trend: eks.amazonaws.com\/role-arn: arn:aws:iam::awsAccountId:role\/projectName\/awsEnv\/eks-spring-boot-admin<\/li><li>as well as I\u2019ve implemented slight changes to the ConfigMap and Deployment<\/li><\/ul>\n\n\n\n<p>I\u2019ve kept the container image to the one published into <a href=\"https:\/\/quay.io\/\">Red Hat&#8217;s Quay.io registry:<\/a> <em>quay.io\/evryfs\/spring-boot-admin:2.7.5&nbsp;(now),  quay.io\/evryfs\/spring-boot-admin:2.6.7&nbsp;(then)&nbsp;as:<\/em><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>I liked that the&nbsp;<a href=\"https:\/\/github.com\/evryfs\/spring-boot-admin\">maintainer<\/a>&nbsp;is actively providing new versions in alignment with&nbsp;<a href=\"https:\/\/github.com\/codecentric\/spring-boot-admin\/tags\">codecentric\u2019s Spring Boot Admin releases<\/a><\/li><li>base image is using Java 17, at the moment of writing, just like the Spring Boot applications I was scraping for insights in the Dutch Lottery assignment, as part of the proof-of-concept<\/li><li>it packaged the dependencies I was interested in: <a href=\"https:\/\/mvnrepository.com\/artifact\/org.springframework.cloud\/spring-cloud-kubernetes-fabric8-discovery\">Spring Cloud Kubernetes Discovery<\/a> and <a href=\"https:\/\/mvnrepository.com\/artifact\/de.codecentric\/spring-boot-admin-starter-server\">Spring Boot Admin Server Starter<\/a> containing both server and server UI components<\/li><li>wanted to keep it simple while researching its capabilities. It is though recommended to build &amp; publish your own container image, when you desire Spring Boot Admin UI customisations or plan deploying it to production.<\/li><\/ul>\n\n\n\n<p><em><strong>Note<\/strong><\/em>: One can <em>use&nbsp;<\/em><code>helm repo add<\/code><em>&nbsp;to expand your list of trusted helm charts repositories and&nbsp;<\/em><code>helm search repo<\/code><em>&nbsp;to search charts in those repositories.<\/em><\/p>\n\n\n\n<p><em>Updated Helm chart can be found&nbsp;&nbsp;<a href=\"https:\/\/gitlab.com\/cristinanegrean\/helm-charts\/-\/tree\/main\/spring-boot-admin\">here<\/a><\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"mce_1\">Lessons Learnt and Chart Usage<\/h2>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"mce_4\">Namespace Bound or Cluster-Wide?<\/h4>\n\n\n\n<p style=\"text-align:left\">In the Dutch Lottery assignment, I needed to scrape Spring Boot services being installed in two Kubernetes namespaces. With the initial Helm chart config value <em><strong>spring.cloud.kubernetes.discovery.all-namespaces<\/strong><\/em> set to <em><strong>true<\/strong><\/em> , the installation is discovering only services installed in one namespace: <em>gateway-private.&nbsp;<\/em>This namespace I&#8217;d use, by project convention, for all deployments of services that are not publicly exposed via Kubernetes <em>Ingress<\/em> or <em>IngressRoute<\/em>. Thus, it was not discovering any of the Spring Boot applications deployed in <em>gateway-public&nbsp;<\/em>namespace.<\/p>\n\n\n\n<p>The reason for that is: <em>Roles<\/em> in Kubernetes are scoped, either bound to a specific namespace or cluster-wide. While a namespace bound <em>Role<\/em> is a safer practice, my only solution for the Spring Boot Admin Tool to discover all the services I was interested in, while creating a <em>Role<\/em> instead of a <em>ClusterRole<\/em>, was to install the <em>Role<\/em> and <em>RoleBinding<\/em> Kubernetes RBAC API objects in both namespaces. In which case I also need to install the Kubernetes <em>ServiceAccount<\/em> in both namespaces, as &#8220;<em>User accounts<\/em>&#8221; are for humans and &#8220;<em>Service accounts<\/em>&#8221; are for processes in Kubernetes, which run in pods. &#8220;<em>User accounts<\/em>&#8221; are intended to be <em>global<\/em>. &#8220;<em>Service accounts<\/em>&#8221; are &#8220;<em>namespaced<\/em>&#8220;. As the <em>ServiceAccount<\/em> is then used in the <em>Deployment<\/em>, I end up installing the whole Helm chart in both <em>gateway-private<\/em> and <em>gateway-public<\/em> namespaces. That would look, in my terminal, something in the trend:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><br \/>\u279c helm-charts(main) \u2714 helm install --set namespace=gateway-private \\<br \/>                     --set multi.namespaced=false \\<br \/>                     spring-boot-admin-gw-private .\/spring-boot-admin --debug <br \/><\/pre>\n\n\n\n<p>followed by:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><br \/>\u279c helm-charts (main) \u2714 helm install --set namespace=gateway-public \\<br \/>                     --set multi.namespaced=false \\<br \/>                     spring-boot-admin-gw-public .\/spring-boot-admin --debug <br \/><br \/><\/pre>\n\n\n\n<p>Now I have two Spring Boot Admin Kubernetes <em>Service<\/em> objects I need to port-forward into, use separate local ports, and two Spring Boot Admin UI browser tabs, in order to see insights for all microservices. That is cumbersome, and my requirement was to collect insights from all Spring Boot Java applications in one overview.<\/p>\n\n\n\n<p>I ended up using the alternative solution, which is to create  <em>ClusterRole<\/em> and ClusterRoleBinding Kubernetes Role-based access control (RBAC)&nbsp;API objects and leveraging chart usage:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><br \/>\u279c helm-charts(main) \u2714 helm install --set namespace=gateway-private \\<br \/>                     --set multi.namespaced=true \\<br \/>                     spring-boot-admin .\/spring-boot-admin --debug <br \/><br \/><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"mce_4\">Treat your pods according to their needs<\/h4>\n\n\n\n<p style=\"text-align:left\">Containers are just processes. In Kubernetes not all containers are equal. When you launch a pod in Kubernetes, a really nice and sophisticated piece of software called &#8220;scheduler&#8221; determines which host should be chosen to run it. If you describe your pod after it is running, you&#8217;ll notice a label called <a href=\"https:\/\/kubernetes.io\/docs\/tasks\/configure-pod-container\/quality-service-pod\/\">QoS Class<\/a>.<\/p>\n\n\n\n<p>While leveraging Spring Boot Admin <a href=\"https:\/\/github.com\/evryfs\/helm-charts\/blob\/master\/charts\/spring-boot-admin\/values.yaml#L84\">helm chart<\/a>, the QoS class that gets assigned to the pod is &#8220;BestEffort&#8221;. And yes, that&#8217;s the less prioritised class. The Spring Boot Admin pod would be between the first one(s) to be evicted, when host is running low on resources. This might be perfectly fine in a development environment, in production running one replica of the Spring Boot Admin process with &#8220;QoS Class: BestEffort&#8221; means your insights on your Spring Boot applications may come and go.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"mce_4\">Discovery Based on Kubernetes Service Label<\/h4>\n\n\n\n<p>In each of the two namespaces, there is more running than just Spring Boot Java applications, so I needed to define a filter for which services to scrape, and ignore the rest.<\/p>\n\n\n\n<p>This can be done using property (see <em>ConfigMap<\/em> listing below): <em><strong>spring.cloud.kubernetes.discovery.service-labels<\/strong><\/em> , <em>a map is required here for label name and value.<\/em><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># Source: spring-boot-admin\/templates\/configmap.yaml\napiVersion: v1\nkind: ConfigMap\nmetadata:\n  name: RELEASE-NAME-config\n  labels:\n    app: RELEASE-NAME\n  namespace: gateway-private\ndata:\n  application.yml: |-\n    spring:\n      application:\n        name: admin-server\n      boot:\n        admin:\n          context-path: '\/admin'\n          ui:\n            title: 'Gateway Spring Boot Admin'\n            brand: 'Gateway Spring Boot Admin'\n      server:\n        port: 8080\n      logging:\n        level:\n          org.springframework.cloud.kubernetes: TRACE\n          de.codecentric.boot.admin.discovery.ApplicationDiscoveryListener: DEBUG\n      cloud:\n        kubernetes:\n          discovery:\n            all-namespaces: true\n            service-labels:\n              type: gateway-base\n            catalog-services-watch:\n              enabled: true\n              catalogServicesWatchDelay: 10000\n<\/pre>\n\n\n\n<p>I&#8217;ve named map key <em><strong>type<\/strong><\/em>&nbsp;and&nbsp;I added one value: <em><strong>gateway-base<\/strong><\/em>.&nbsp; However&nbsp;you&nbsp;can&nbsp;change&nbsp;these&nbsp;to&nbsp;whatever&nbsp;desired. You will do have to update as well the <em>helm chart<\/em> used to deploy your Java applications to add configured service label.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">apiVersion: v1<br \/>kind: Service<br \/>metadata:<br \/>  name: {{ template \"getApplicationFullName\" . }}<br \/>  namespace: {{ .Values.namespace }}<br \/>  labels:<br \/>    type: {{ .Values.app.type }}<\/pre>\n\n\n\n<p>Note: <em><strong>Labels<\/strong><\/em>&nbsp;are key\/value pairs that are attached to objects, such as Pods and Services, and <em>are different from Kubernetes <\/em><a href=\"https:\/\/kubernetes.io\/docs\/concepts\/services-networking\/service\/#publishing-services-service-types\"><em>service types<\/em><\/a>.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nNAME                         TYPE        TYPE\neventhub-system              ClusterIP   gateway-base\ngame-process                 ClusterIP   gateway-base\ngame-system                  ClusterIP   gateway-base\ninlane-process               ClusterIP   gateway-base\nmarketing-system             ClusterIP   gateway-base\nplayer-process               ClusterIP   gateway-base\nplayer-system                ClusterIP   gateway-base\nresponsible-gaming-system    ClusterIP   gateway-base\nsalesforce-sync-system       ClusterIP   gateway-base\nspring-boot-admin            ClusterIP\nsubscription-process         ClusterIP   gateway-base\nsubscription-sales-process   ClusterIP   gateway-base\ntraefik-ingress-private      ClusterIP  \n<\/pre><\/div>\n\n\n<p>As you can see in the <em>Wallboard<\/em> , there are no <em><strong>spring-boot-admin<\/strong><\/em><strong> <\/strong>or <em><strong>traefik-ingress-private<\/strong><\/em> services being discovered.<br \/><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"739\" src=\"https:\/\/trifork.nl\/articles\/wp-content\/uploads\/sites\/3\/2022\/10\/wallboard-1024x739.png\" alt=\"\" class=\"wp-image-20491\" srcset=\"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/10\/wallboard-1024x739.png 1024w, https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/10\/wallboard-300x216.png 300w, https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/10\/wallboard-768x554.png 768w, https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/10\/wallboard.png 1364w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption>Wallboard<br \/><\/figcaption><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"mce_4\">UI Customisations<\/h4>\n\n\n\n<p><em><strong>Note<\/strong><\/em>: It has been chosen not to expose the Spring Boot Admin UI externally. Instead one can use port forwarding inside the <em>spring-boot-admin<\/em> service to access the UI.<\/p>\n\n\n\n<p>First time, I have installed the Helm chart, I was noticing an &#8220;unspecified&#8221; label in Spring Boot Admin UI &#8220;Wallboard&#8221; (image above), but also in the &#8220;Applications&#8221; overview feature. That is when your Spring Boot Application has no &#8220;build version&#8221; in the JSON output of &#8220;\/actuator\/info&#8221; endpoint. <br \/>As the project is leveraging <a href=\"https:\/\/spring.io\/blog\/2020\/08\/14\/creating-efficient-docker-images-with-spring-boot-2-3\">Spring Boot improved image creation technique called layered jar<\/a>, including information as build version or time would result in layer recreation, which might slow down the CI &amp; CD pipeline. <br \/> <\/p>\n\n\n\n<p>So what if you would like to brand your installation of Spring Boot Admin UI a bit? Well it is possible!<br \/> Just a few examples of possible overrides in <a href=\"https:\/\/codecentric.github.io\/spring-boot-admin\/current\/\">codecentric&#8217;s Spring Boot Admin<\/a>:<br \/><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>&#8220;Page-Title&#8221; to be shown top navigation bar and overwriting property <em><strong>spring.boot.admin.ui.title<\/strong><\/em><strong> <\/strong>via&nbsp;corresponding chart template value: <code>ui.title<\/code><\/li><li>&#8220;Brand&#8221; to be shown in the navigation bar as brand image and changing default value of property <em><strong>spring.boot.admin.ui.brand<\/strong><\/em>. As this one is an image asset, <em>it makes sense to build a custom Docker image that includes the image asset<\/em>.<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-preformatted\">Below screenshot exemplifies both the \"Page-Title\" and \"Build version\" customisations in \"Applications\" screen.<\/pre>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"862\" src=\"https:\/\/trifork.nl\/articles\/wp-content\/uploads\/sites\/3\/2022\/10\/applications-1024x862.png\" alt=\"\" class=\"wp-image-20493\" srcset=\"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/10\/applications-1024x862.png 1024w, https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/10\/applications-300x253.png 300w, https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/10\/applications-768x646.png 768w, https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/10\/applications.png 1226w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption>Applications<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"mce_4\">Useful Features of the Spring Boot Admin<\/h2>\n\n\n\n<p>A former colleague wrote a Trifork <a href=\"https:\/\/blog.trifork.com\/2018\/12\/06\/managing-spring-boot-microservices-with-spring-boot-admin-on-kubernetes\/\">blog<\/a> post making a nice inventory of useful features in Spring Boot Admin. The features he describes in his article, section &#8220;The top cool features we like and use most&#8221; were relevant as well for the Dutch Lottery assignment, with the exception of the database migrations. This post is more focused on Helm and how I deployed Spring Boot Admin in EKS, nonetheless I would like to extend on that blog post with few other unmentioned useful features:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>hunt down memory (even possible leak) issues in any of your Spring Boot Java application. You can use JDK&#8217;s Flight Recorder or <a href=\"https:\/\/visualvm.github.io\/\">VisualVM <\/a> and serve it a <em>Heap Dump <\/em>you can download to your machine via Spring Boot Admin UI. As a Heap Dump contains sensitive data, you will need write, port-forward privileges in a production grade cluster, and knowledge when your Java service will be under high load, and possibly misbehaving.<\/li><li>list <em>Scheduled Tasks<\/em>, <em>Caches<\/em>, <em>Circuit Breakers<\/em>, <em>database connection pool details<\/em>, if your service integrates with any.<\/li><li>display application\u2019s <em>Request Mappings<\/em>. While I prefer Swagger UI as a Rest API Documentation Tool, not all Spring Boot Java applications abide by the &#8220;REpresentational State Transfer&#8221; as an architectural style for distributed hypermedia systems,. Nonetheless they might provide some HTTP based APIs and having a list of those endpoints might offer insights on what the service does.<\/li><li><em>Notifications<\/em> based on the &#8220;Event Journal&#8221; (see image below). In Kubernetes is pretty common for services to come and go, however if you have a scenario of a critical stateful deployment with only one replica, and you want to be notified of its lifecycle events, it&#8217;s possible to integrate Spring Boot Admin with monitoring tools like: Slack, PagerDuty, OpsGenie.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"685\" src=\"https:\/\/trifork.nl\/articles\/wp-content\/uploads\/sites\/3\/2022\/10\/journal_application_status_change_event-1024x685.png\" alt=\"\" class=\"wp-image-20486\" srcset=\"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/10\/journal_application_status_change_event-1024x685.png 1024w, https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/10\/journal_application_status_change_event-300x201.png 300w, https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/10\/journal_application_status_change_event-768x514.png 768w, https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/10\/journal_application_status_change_event-1536x1028.png 1536w, https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/10\/journal_application_status_change_event-2048x1371.png 2048w, https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/10\/journal_application_status_change_event-1912x1280.png 1912w, https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/10\/journal_application_status_change_event-600x400.png 600w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption>Applications Status Change Event<\/figcaption><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>In this blog post I am experimenting with Helm, the package manager for Kubernetes by packaging codecentric&#8217;s Spring Boot Admin for out of the box real-time insights into a suite of Spring Boot Java services deployed to Amazon Elastic Kubernetes Service (EKS).<\/p>\n","protected":false},"author":29,"featured_media":20468,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"content-type":"","footnotes":""},"categories":[428,88,473,98,10,94],"tags":[554,555,556,557],"class_list":["post-20465","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cloud-native","category-devops","category-kubernetes","category-microservices","category-development","category-spring","tag-aws-eks","tag-helm","tag-spring-boot-admin","tag-spring-cloud-kubernetes-discovery"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v24.4 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Helm your way to Kubernetes with Spring Boot Admin - Trifork Blog<\/title>\n<meta name=\"description\" content=\"Helm3, Kubernetes, AWS EKS, Java, Spring Boot Admin, Spring Cloud Kubernetes Discovery\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/trifork.nl\/blog\/helm-your-way-to-kubernetes-with-spring-boot-admin\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Helm your way to Kubernetes with Spring Boot Admin - Trifork Blog\" \/>\n<meta property=\"og:description\" content=\"Helm3, Kubernetes, AWS EKS, Java, Spring Boot Admin, Spring Cloud Kubernetes Discovery\" \/>\n<meta property=\"og:url\" content=\"https:\/\/trifork.nl\/blog\/helm-your-way-to-kubernetes-with-spring-boot-admin\/\" \/>\n<meta property=\"og:site_name\" content=\"Trifork Blog\" \/>\n<meta property=\"article:published_time\" content=\"2022-10-05T08:16:51+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/10\/spring_boot_admin.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1271\" \/>\n\t<meta property=\"og:image:height\" content=\"929\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Cristina Negrean\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Cristina Negrean\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/trifork.nl\/blog\/helm-your-way-to-kubernetes-with-spring-boot-admin\/\",\"url\":\"https:\/\/trifork.nl\/blog\/helm-your-way-to-kubernetes-with-spring-boot-admin\/\",\"name\":\"Helm your way to Kubernetes with Spring Boot Admin - Trifork Blog\",\"isPartOf\":{\"@id\":\"https:\/\/trifork.nl\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/trifork.nl\/blog\/helm-your-way-to-kubernetes-with-spring-boot-admin\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/trifork.nl\/blog\/helm-your-way-to-kubernetes-with-spring-boot-admin\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/10\/spring_boot_admin.png\",\"datePublished\":\"2022-10-05T08:16:51+00:00\",\"author\":{\"@id\":\"https:\/\/trifork.nl\/blog\/#\/schema\/person\/254aacbf72f5931b33fd835323088d73\"},\"description\":\"Helm3, Kubernetes, AWS EKS, Java, Spring Boot Admin, Spring Cloud Kubernetes Discovery\",\"breadcrumb\":{\"@id\":\"https:\/\/trifork.nl\/blog\/helm-your-way-to-kubernetes-with-spring-boot-admin\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/trifork.nl\/blog\/helm-your-way-to-kubernetes-with-spring-boot-admin\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/trifork.nl\/blog\/helm-your-way-to-kubernetes-with-spring-boot-admin\/#primaryimage\",\"url\":\"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/10\/spring_boot_admin.png\",\"contentUrl\":\"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/10\/spring_boot_admin.png\",\"width\":1271,\"height\":929},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/trifork.nl\/blog\/helm-your-way-to-kubernetes-with-spring-boot-admin\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/trifork.nl\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Helm your way to Kubernetes with Spring Boot Admin\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/trifork.nl\/blog\/#website\",\"url\":\"https:\/\/trifork.nl\/blog\/\",\"name\":\"Trifork Blog\",\"description\":\"Keep updated on the technical solutions Trifork is working on!\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/trifork.nl\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/trifork.nl\/blog\/#\/schema\/person\/254aacbf72f5931b33fd835323088d73\",\"name\":\"Cristina Negrean\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/trifork.nl\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/2caac30c15e1ac0f5b6744bb0f0e2572?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/2caac30c15e1ac0f5b6744bb0f0e2572?s=96&d=mm&r=g\",\"caption\":\"Cristina Negrean\"},\"url\":\"https:\/\/trifork.nl\/blog\/author\/cristinan\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Helm your way to Kubernetes with Spring Boot Admin - Trifork Blog","description":"Helm3, Kubernetes, AWS EKS, Java, Spring Boot Admin, Spring Cloud Kubernetes Discovery","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/trifork.nl\/blog\/helm-your-way-to-kubernetes-with-spring-boot-admin\/","og_locale":"en_US","og_type":"article","og_title":"Helm your way to Kubernetes with Spring Boot Admin - Trifork Blog","og_description":"Helm3, Kubernetes, AWS EKS, Java, Spring Boot Admin, Spring Cloud Kubernetes Discovery","og_url":"https:\/\/trifork.nl\/blog\/helm-your-way-to-kubernetes-with-spring-boot-admin\/","og_site_name":"Trifork Blog","article_published_time":"2022-10-05T08:16:51+00:00","og_image":[{"width":1271,"height":929,"url":"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/10\/spring_boot_admin.png","type":"image\/png"}],"author":"Cristina Negrean","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Cristina Negrean","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/trifork.nl\/blog\/helm-your-way-to-kubernetes-with-spring-boot-admin\/","url":"https:\/\/trifork.nl\/blog\/helm-your-way-to-kubernetes-with-spring-boot-admin\/","name":"Helm your way to Kubernetes with Spring Boot Admin - Trifork Blog","isPartOf":{"@id":"https:\/\/trifork.nl\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/trifork.nl\/blog\/helm-your-way-to-kubernetes-with-spring-boot-admin\/#primaryimage"},"image":{"@id":"https:\/\/trifork.nl\/blog\/helm-your-way-to-kubernetes-with-spring-boot-admin\/#primaryimage"},"thumbnailUrl":"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/10\/spring_boot_admin.png","datePublished":"2022-10-05T08:16:51+00:00","author":{"@id":"https:\/\/trifork.nl\/blog\/#\/schema\/person\/254aacbf72f5931b33fd835323088d73"},"description":"Helm3, Kubernetes, AWS EKS, Java, Spring Boot Admin, Spring Cloud Kubernetes Discovery","breadcrumb":{"@id":"https:\/\/trifork.nl\/blog\/helm-your-way-to-kubernetes-with-spring-boot-admin\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/trifork.nl\/blog\/helm-your-way-to-kubernetes-with-spring-boot-admin\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/trifork.nl\/blog\/helm-your-way-to-kubernetes-with-spring-boot-admin\/#primaryimage","url":"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/10\/spring_boot_admin.png","contentUrl":"https:\/\/trifork.nl\/blog\/wp-content\/uploads\/sites\/3\/2022\/10\/spring_boot_admin.png","width":1271,"height":929},{"@type":"BreadcrumbList","@id":"https:\/\/trifork.nl\/blog\/helm-your-way-to-kubernetes-with-spring-boot-admin\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/trifork.nl\/blog\/"},{"@type":"ListItem","position":2,"name":"Helm your way to Kubernetes with Spring Boot Admin"}]},{"@type":"WebSite","@id":"https:\/\/trifork.nl\/blog\/#website","url":"https:\/\/trifork.nl\/blog\/","name":"Trifork Blog","description":"Keep updated on the technical solutions Trifork is working on!","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/trifork.nl\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/trifork.nl\/blog\/#\/schema\/person\/254aacbf72f5931b33fd835323088d73","name":"Cristina Negrean","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/trifork.nl\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/2caac30c15e1ac0f5b6744bb0f0e2572?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/2caac30c15e1ac0f5b6744bb0f0e2572?s=96&d=mm&r=g","caption":"Cristina Negrean"},"url":"https:\/\/trifork.nl\/blog\/author\/cristinan\/"}]}},"_links":{"self":[{"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/posts\/20465","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/users\/29"}],"replies":[{"embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/comments?post=20465"}],"version-history":[{"count":0,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/posts\/20465\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/media\/20468"}],"wp:attachment":[{"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/media?parent=20465"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/categories?post=20465"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/trifork.nl\/blog\/wp-json\/wp\/v2\/tags?post=20465"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}