{"id":836,"date":"2020-03-30T11:00:00","date_gmt":"2020-03-30T11:00:00","guid":{"rendered":"http:\/\/bullyrooks.com\/index.php\/2020\/04\/02\/simple-spring-boot-service-to-kubernetes-application-step-11-636b842a3c0f\/"},"modified":"2021-02-04T01:56:41","modified_gmt":"2021-02-04T01:56:41","slug":"simple-spring-boot-service-to-kubernetes-application-step-11-636b842a3c0f","status":"publish","type":"post","link":"https:\/\/bullyrooks.com\/index.php\/2020\/03\/30\/simple-spring-boot-service-to-kubernetes-application-step-11-636b842a3c0f\/","title":{"rendered":"Helm for Deployment"},"content":{"rendered":"\n<p class=\"graf graf--p graf-after--h3 graf--trailing\" id=\"79ec\">We\u2019re about ready to deploy into kubernetes. However, deployment is not exactly straightforward. There are a lot of configuration files that we need to create and maintain in order to explain to the container management system <em class=\"markup--em markup--p-em\">how <\/em>to deploy our application. We can use tools like kubectl to promote these files, but it quickly becomes cumbersome. In this article we\u2019ll explain how helm will assist us with deployment.<\/p>\n\n\n\n<h3 class=\"graf graf--h3 graf--leading wp-block-heading\" id=\"0025\">Kubernetes Overview<\/h3>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2021\/02\/1qQ7oPSqKKI2ntrUwStj0MA.png?w=960\" alt=\"\" data-recalc-dims=\"1\"\/><\/figure>\n\n\n\n<p class=\"graf graf--p graf-after--figure\" id=\"eb54\">This is a very simple and over simplification of the kubernetes environment and I would say that it may even be inaccurate depending on the application and its configuration, but for our very high level discussion it will be useful.<\/p>\n\n\n\n<p class=\"graf graf--p graf-after--p\" id=\"b05a\">The pods are the actual instances of a microservice. You can configure how many instances should be available (for failover and scalability purposes). They pull the image out of the docker registry on startup.<\/p>\n\n\n\n<p class=\"graf graf--p graf-after--p\" id=\"7255\">Most applications need some sort of configuration (in our example service, the datasource) in order to be able to function correctly. Now that we\u2019re in a distributed environment (multiple service instances running simultaneously) we need to make sure that the running instances are using the same configuration. That\u2019s where configmaps come in. They store the configuration for our application and make sure that all instances are running with the same configuration.<\/p>\n\n\n\n<p class=\"graf graf--p graf-after--p\" id=\"47a2\">Finally, since we have multiple service instances we need a loadbalancer to determine which instance will handle a request. This is where the service comes in. It links all of the pods to a single endpoint. It can be configured to be available outside of the cluster and that can function as an ingress point to the cluster. This is how we\u2019ll be configuring our service.<\/p>\n\n\n\n<p class=\"graf graf--p graf-after--p\" id=\"28d9\">There are also kubenetes configuration that we\u2019re not discussing related to security and access. These are required (letting our deployment see our configmap for example) and must be deployed, but doing all of this by hand is tedious and error prone. We\u2019re going to use a tool called Helm to manage templates of our kubernetes deployment configuration and inject values into them instead. This is very similar to properties in an application context for spring.<\/p>\n\n\n\n<h3 class=\"graf graf--h3 graf-after--p wp-block-heading\" id=\"466b\">Helm Overview<\/h3>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2021\/02\/1qQ7oPSqKKI2ntrUwStj0MA.png?w=960\" alt=\"\" data-recalc-dims=\"1\"\/><\/figure>\n\n\n\n<p class=\"graf graf--p graf-after--figure\" id=\"13e7\">Again, this is a gross oversimplification. Helm is a deployment configuration management tool but functions also as a deployment tool. By defining templates for the kubernetes deployment configuration we can just use a values.yaml to inject our application\u2019s values into it. This will create a \u2018real\u2019 deployment configuration that we can push into kubernetes. Since kubernetes knows about the docker repository (from the deployment configuration) it will setup the configuration definition, pull the image, build a pod from it using the specified configuration, setup the service to front the pods and start up everything.<\/p>\n\n\n\n<p class=\"graf graf--p graf-after--p\" id=\"1b33\">The only command we have to know in order to make all of this happen is <code class=\"markup--code markup--p-code\">helm install<\/code>. We can also upgrade any changes to the docker image or configuration with <code class=\"markup--code markup--p-code\">helm upgrade<\/code> and we can revert those changes with <code class=\"markup--code markup--p-code\">helm rollback<\/code>.<\/p>\n\n\n\n<p class=\"graf graf--p graf-after--p\" id=\"183a\">Additionally, we can package the finalized deployment configuration into (what is called) a chart so that we can version our application deployment configuration. We can combine our helm charts into an umbrella chart as well, which allows us to define our entire cluster which is a very powerful tool from an operations perspective.<\/p>\n\n\n\n<p class=\"graf graf--p graf-after--p graf--trailing\" id=\"4e51\">Lets get started.<\/p>\n\n\n\n<h3 class=\"graf graf--h3 graf--leading wp-block-heading\" id=\"a34c\">Helm File Installation<\/h3>\n\n\n\n<h4 class=\"graf graf--h4 graf-after--h3 wp-block-heading\" id=\"c1d9\">Helm Install<\/h4>\n\n\n\n<p class=\"graf graf--p graf-after--h4\" id=\"0448\">Use your package manager to install helm.<\/p>\n\n\n\n<h4 class=\"graf graf--h4 graf-after--p wp-block-heading\" id=\"dd39\">Helm Template<\/h4>\n\n\n\n<p class=\"graf graf--p graf-after--h4\" id=\"8074\"><a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/paulczar\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/paulczar\">Paul Czarkowski<\/a> has done a lot of work creating a \u2018standard\u2019 <a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/github.com\/paulczar\/helm-chart-spring\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/github.com\/paulczar\/helm-chart-spring\">spring boot helm chart template project<\/a> that we\u2019ll rely heavily on. We\u2019re basically going to lift that entire structure, drop it into our project and then change the <code class=\"markup--code markup--p-code\">values.yaml<\/code> file to reflect our application\u2019s needs.<\/p>\n\n\n\n<p class=\"graf graf--p graf-after--p\" id=\"11ad\">Create a directory for helm in <code class=\"markup--code markup--p-code\">src\/main\/helm\/medium-customer<\/code>. copy the contents of that project into the <code class=\"markup--code markup--p-code\">helm\/medium-customer<\/code> directory.<\/p>\n\n\n\n<p class=\"graf graf--p graf-after--p\" id=\"3285\">Make the following changes to <code class=\"markup--code markup--p-code\">values.yaml<\/code><\/p>\n\n\n\n<pre id=\"558f\" class=\"wp-block-preformatted graf graf--pre graf-after--p\">image:\n  repository: r.cfcr.io\/docketdynamics\/medium-customer<\/pre>\n\n\n\n<pre id=\"491d\" class=\"wp-block-code graf graf--pre graf-after--pre\"><code>spring:\n<em class=\"markup--em markup--pre-em\">## Uncomment if you want to activate a specfic spring profile\n  # profile: kubernetes\n  ## Ensures that Spring trusts Kubernetes certificate for use with\n  ## service discovery, configuration, etc.\n<\/em>trustKubernetesCertificates: true\n<em class=\"markup--em markup--pre-em\">## customized parameters\/config for your spring app.\n  ## by default will be rendered to `\/config\/application.yml`\n<\/em>config:\n<em class=\"markup--em markup--pre-em\">## Currently only supports file\n<\/em>type: file\n<em class=\"markup--em markup--pre-em\">## Contents of config in YAML\n<\/em>content: |-\n      server:\n        tomcat:\n          accesslog:\n            enabled: true\n            pattern: '%h %l %u %t \\\"%r\\\" %s %b zipkin:&#91;%{X-B3-TraceId}i, %{X-B3-SpanId}i, %{X-B3-ParentSpanId}i]'\n    spring:\n      application:\n        name: customer\n      jackson:\n        deserialization:\n          FAIL_ON_UNKNOWN_PROPERTIES: false\n      datasource:\n        hikari:\n          connectionTimeout: 20000\n          maximumPoolSize: 2\n        url: jdbc:postgresql:\/\/ec2***.amazonaws.com:5432\/df***oe<\/code><\/pre>\n\n\n\n<p class=\"graf graf--p graf-after--pre\" id=\"da40\">Also update the chart.yaml<\/p>\n\n\n\n<pre id=\"394b\" class=\"wp-block-code graf graf--pre graf-after--p\"><code>apiVersion: v1\nappVersion: 0.0.1\ndescription: A Helm chart for Kubernetes\nname: medium-customer\nversion: 0.0.1\nmaintainers:\n  - name: brook\n    email: brook@test.com<\/code><\/pre>\n\n\n\n<p class=\"graf graf--p graf-after--pre\" id=\"648b\"><strong class=\"markup--strong markup--p-strong\">Build and Commit<\/strong><\/p>\n\n\n\n<p class=\"graf graf--p graf-after--p\" id=\"e1f5\">We can\u2019t test this yet until we have a cluster working. Let\u2019s go ahead and commit these changes for now.<\/p>\n\n\n\n<pre id=\"880a\" class=\"wp-block-code graf graf--pre graf-after--p\"><code>git checkout -b helm\nmvn clean install\ngit add .\ngit commit -m \"helm chart create\"\ngit push --set-upstream origin helm\ngit checkout master\ngit merge helm\ngit push<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<div class=\"entry-summary\">\nWe\u2019re about ready to deploy into kubernetes. However, deployment is not exactly&hellip;\n<\/div>\n<div class=\"link-more\"><a href=\"https:\/\/bullyrooks.com\/index.php\/2020\/03\/30\/simple-spring-boot-service-to-kubernetes-application-step-11-636b842a3c0f\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &ldquo;Helm for Deployment&rdquo;<\/span>&hellip;<\/a><\/div>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[41],"tags":[5,29,79,81,80,50],"course":[40],"class_list":["post-836","post","type-post","status-publish","format-standard","hentry","category-software-development","tag-docker","tag-git","tag-helm","tag-helm-chart","tag-kubernetes","tag-maven","course-spring-with-kubernetes","entry"],"jetpack_featured_media_url":"","jetpack-related-posts":[{"id":816,"url":"https:\/\/bullyrooks.com\/index.php\/2020\/03\/30\/simple-spring-boot-service-to-kubernetes-application-step-12-c6423261a93a\/","url_meta":{"origin":836,"position":0},"title":"Setting up a Kubernetes Cluster","author":"Bullyrook","date":"March 30, 2020","format":false,"excerpt":"Finally, we\u2019re going to be able to deploy our application. We need to get access to a cluster first. Install Tooling We\u2019re going to need more tools in order to get started. Use your OS package management tool to install these tools: Kubectl (Interact with a k8s instance)Minikube (Run a\u2026","rel":"","context":"In &quot;Software Development&quot;","block_context":{"text":"Software Development","link":"https:\/\/bullyrooks.com\/index.php\/category\/software-development\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":823,"url":"https:\/\/bullyrooks.com\/index.php\/2020\/03\/30\/simple-spring-boot-service-to-kubernetes-application-step-21-6986a29db37a\/","url_meta":{"origin":836,"position":1},"title":"Simplify Deployment","author":"Bullyrook","date":"March 30, 2020","format":false,"excerpt":"Now that we have multiple components lets simplify our deployment so that we can deploy our complete application in one step. Create an Umbrella\u00a0Chart Create a new git repository called medium-application. This is the repository that will house the helm umbrella chart. Create a directory called helm and run helm\u2026","rel":"","context":"In &quot;Software Development&quot;","block_context":{"text":"Software Development","link":"https:\/\/bullyrooks.com\/index.php\/category\/software-development\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":818,"url":"https:\/\/bullyrooks.com\/index.php\/2020\/03\/30\/simple-spring-boot-service-to-kubernetes-application-step-19-944a76415384\/","url_meta":{"origin":836,"position":2},"title":"Put the UI in to Helm","author":"Bullyrook","date":"March 30, 2020","format":false,"excerpt":"Lets take the docker image we just created and wrap it with helm so that we have an easy way to deploy our application. Create Helm Chart Templates We\u2019ve created helm charts before, so lets create a helm directory at the frontend root. Then run helm create in that directory\u2026","rel":"","context":"In &quot;Software Development&quot;","block_context":{"text":"Software Development","link":"https:\/\/bullyrooks.com\/index.php\/category\/software-development\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":817,"url":"https:\/\/bullyrooks.com\/index.php\/2020\/03\/30\/simple-spring-boot-service-to-kubernetes-application-step-20-fe28a586cdc6\/","url_meta":{"origin":836,"position":3},"title":"Creating an Ingress in Kubernetes","author":"Bullyrook","date":"March 30, 2020","format":false,"excerpt":"We\u2019ve got multiple service available for deployment now. Lets allow them to communicate internally and externally with the cluster. We\u2019ll do that by creating an ingress. Current State of Our Application We\u2019re using our services as nodeports which allows us to expose an external port that will map to the\u2026","rel":"","context":"In &quot;Software Development&quot;","block_context":{"text":"Software Development","link":"https:\/\/bullyrooks.com\/index.php\/category\/software-development\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1205,"url":"https:\/\/bullyrooks.com\/index.php\/2022\/01\/04\/kube-cloud-automate-kube-deploy\/","url_meta":{"origin":836,"position":4},"title":"Kube Cloud | Automate Kube Deploy","author":"Bullyrook","date":"January 4, 2022","format":false,"excerpt":"Lets improve our CD pipeline by automating deployment. Update Build Pipeline I only want main to deploy on successful build. So add these lines to the end of the main.yaml github action workflow - name: Deploy uses: WyriHaximus\/github-action-helm3@v2 with: exec: | helm repo add bullyrooks https:\/\/bullyrooks.github.io\/helm-charts\/ helm repo update helm\u2026","rel":"","context":"In &quot;Software Development&quot;","block_context":{"text":"Software Development","link":"https:\/\/bullyrooks.com\/index.php\/category\/software-development\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-36.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-36.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-36.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":1296,"url":"https:\/\/bullyrooks.com\/index.php\/2022\/02\/19\/kube-cloud-pt4-tracing\/","url_meta":{"origin":836,"position":5},"title":"Kube Cloud Pt4 | Tracing","author":"Bullyrook","date":"February 19, 2022","format":false,"excerpt":"For this portion we're going to use OpenTelemetry for tracing. OpenTelemetry projects intent is to solve all of the observability space in an opensource way. Unfortunately, at this time the logging and metrics portions are still in development, so we won't be able to use them. However the tracing piece\u2026","rel":"","context":"In &quot;General&quot;","block_context":{"text":"General","link":"https:\/\/bullyrooks.com\/index.php\/category\/general\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/02\/image-35.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/02\/image-35.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/02\/image-35.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/02\/image-35.png?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/02\/image-35.png?resize=1400%2C800&ssl=1 4x"},"classes":[]}],"_links":{"self":[{"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/posts\/836","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/comments?post=836"}],"version-history":[{"count":3,"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/posts\/836\/revisions"}],"predecessor-version":[{"id":1139,"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/posts\/836\/revisions\/1139"}],"wp:attachment":[{"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/media?parent=836"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/categories?post=836"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/tags?post=836"},{"taxonomy":"course","embeddable":true,"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/course?post=836"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}