{"id":817,"date":"2020-03-30T20:00:00","date_gmt":"2020-03-30T20:00:00","guid":{"rendered":"http:\/\/bullyrooks.com\/index.php\/2020\/04\/10\/simple-spring-boot-service-to-kubernetes-application-step-20-fe28a586cdc6\/"},"modified":"2021-02-04T02:16:49","modified_gmt":"2021-02-04T02:16:49","slug":"simple-spring-boot-service-to-kubernetes-application-step-20-fe28a586cdc6","status":"publish","type":"post","link":"https:\/\/bullyrooks.com\/index.php\/2020\/03\/30\/simple-spring-boot-service-to-kubernetes-application-step-20-fe28a586cdc6\/","title":{"rendered":"Creating an Ingress in Kubernetes"},"content":{"rendered":"\n<p class=\"graf graf--p graf-after--h3 graf--trailing\" id=\"10f0\">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.<\/p>\n\n\n\n<h3 class=\"graf graf--h3 graf--leading wp-block-heading\" id=\"676b\">Current State of Our Application<\/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\/1fJU_c0QZxDuMCzwrr2ue5g.png?w=960\" alt=\"\" data-recalc-dims=\"1\"\/><\/figure>\n\n\n\n<p class=\"graf graf--p graf-after--figure\" id=\"59fa\">We\u2019re using our services as nodeports which allows us to expose an external port that will map to the internal port used by the the application. From our helm configuration our services start up on their default port (spring=8080, nginx=80) but that gets mapped to port 80 internally. So if we were inside our cluster we could talk to customer manager directly by calling its service on port 80. When we\u2019re external we have to use port 30002.<\/p>\n\n\n\n<p class=\"graf graf--p graf-after--p\" id=\"1045\">This works okay when we\u2019re running externally on our development machine, but is terrible for production. For one, keeping track of the cluster IP and making sure that each service is calling the correct port can be a maintenance nightmare.<\/p>\n\n\n\n<h3 class=\"graf graf--h3 graf-after--p wp-block-heading\" id=\"1073\">Using an&nbsp;Ingress<\/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\/1fJU_c0QZxDuMCzwrr2ue5g.png?w=960\" alt=\"\" data-recalc-dims=\"1\"\/><\/figure>\n\n\n\n<p class=\"graf graf--p graf-after--figure\" id=\"daf7\">We\u2019re going to install another component called an ingress which acts like an api gateway. This allows us to only talk to a single IP and port combination to access all components within our application. We can still access services directly via their external port (for testing, etc\u2026) but the most important part is that our front-end application won\u2019t need to know anything about where our services live and how to access them. The ingress takes care of that.<\/p>\n\n\n\n<h3 class=\"graf graf--h3 graf-after--p wp-block-heading\" id=\"1b35\">Creating an&nbsp;Ingress<\/h3>\n\n\n\n<p class=\"graf graf--p graf-after--h3\" id=\"9d41\">Create a new git repository called <code class=\"markup--code markup--p-code\">medium-ingress<\/code>. Clone that locally and in that repo create a directory called <code class=\"markup--code markup--p-code\">helm<\/code>. In here use <code class=\"markup--code markup--p-code\">helm create medium-ingress<\/code> to initialize the chart. We\u2019re going to strip out all of the files since we really only need 3.<\/p>\n\n\n\n<p class=\"graf graf--p graf-after--p\" id=\"c524\"><code class=\"markup--code markup--p-code\">templates\/ingress.yaml<\/code><\/p>\n\n\n\n<pre id=\"2948\" class=\"wp-block-code graf graf--pre graf-after--p\"><code>apiVersion: networking.k8s.io\/v1beta1\nkind: Ingress\nmetadata:\n  name: medium-ingress\n  annotations:\n    nginx.ingress.kubernetes.io\/rewrite-target: \/\nspec:\n  rules:\n    - host: medium-example.com\n      http:\n        paths:\n        - path: \/\n          backend:\n            serviceName: medium-customer-manager-service\n            servicePort: 80\n        - path: \/customer\n          backend:\n            serviceName: customer-medium-customer\n            servicePort: 80<\/code><\/pre>\n\n\n\n<p class=\"graf graf--p graf-after--pre\" id=\"439a\"><code class=\"markup--code markup--p-code\">Chart.yaml<\/code><\/p>\n\n\n\n<pre id=\"2667\" class=\"wp-block-code graf graf--pre graf-after--p\"><code>apiVersion: v1\nname: medium-ingress\ndescription: The ingress into the medium application\n\ntype: application\nversion: 0.1.0\nappVersion: 1.16.0<\/code><\/pre>\n\n\n\n<p class=\"graf graf--p graf-after--pre\" id=\"29f9\"><code class=\"markup--code markup--p-code\">values.yaml<\/code> can be left empty<\/p>\n\n\n\n<blockquote class=\"wp-block-quote graf graf--blockquote graf-after--p is-layout-flow wp-block-quote-is-layout-flow\" id=\"1a37\"><p>The important part is the ingress deployment descriptor. In here we\u2019re creating the mapping of the request path to the internal kubernetes service name and port. I just realized that my names are not very clean and I should fix that but this will get us going.<\/p><\/blockquote>\n\n\n\n<h3 class=\"graf graf--h3 graf-after--blockquote wp-block-heading\" id=\"1466\">Minikube Setup<\/h3>\n\n\n\n<p class=\"graf graf--p graf-after--h3\" id=\"fda2\">We need to do some things first before we can deploy. Ingress is a definition, but it is actually implemented within the kubernetes cluster and there are lots of implementations to choose from. We\u2019re going to use the basic ingress for minikube, but we need to install it first.<\/p>\n\n\n\n<pre id=\"d7b7\" class=\"wp-block-code graf graf--pre graf-after--p\"><code>minikube addons enable ingress<\/code><\/pre>\n\n\n\n<p class=\"graf graf--p graf-after--pre\" id=\"0597\">verify the pod is running<\/p>\n\n\n\n<pre id=\"d121\" class=\"wp-block-code graf graf--pre graf-after--p\"><code>kubectl get pods -n ingress-nginx<\/code><\/pre>\n\n\n\n<p class=\"graf graf--p graf-after--pre\" id=\"4ac7\">We also want to update our hosts file to add a mapping for <code class=\"markup--code markup--p-code\">medium-example.com<\/code> to our minikube ip (which can be retrieved via <code class=\"markup--code markup--p-code\">minikube ip<\/code>). This is partly for ease of use for us, but also important because the ingress controller uses the domain for mapping.<\/p>\n\n\n\n<pre id=\"051c\" class=\"wp-block-code graf graf--pre graf-after--p\"><code>...\n172.18.51.82 medium-example.com\n# End of section<\/code><\/pre>\n\n\n\n<h3 class=\"graf graf--h3 graf-after--pre wp-block-heading\" id=\"8e26\">Update Frontend<\/h3>\n\n\n\n<p class=\"graf graf--p graf-after--h3\" id=\"423c\">We have one more minor change to make to our react frontend. Change <code class=\"markup--code markup--p-code\">helm\/medium-customer-manager\/values.yaml<\/code> to stop calling the customer service via external port<\/p>\n\n\n\n<pre id=\"a999\" class=\"wp-block-code graf graf--pre graf-after--p\"><code>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    window.REACT_APP_CUSTOMER_HOST=''<\/code><\/pre>\n\n\n\n<p class=\"graf graf--p graf-after--pre\" id=\"3f8c\">Go ahead and commit this to kick off a build<\/p>\n\n\n\n<pre id=\"154c\" class=\"wp-block-code graf graf--pre graf-after--p\"><code>git checkout -b ingress\ngit add .\ngit commit -m \"updates for ingress\"\ngit push\ngit checkout master\ngit merge ingress\ngit push<\/code><\/pre>\n\n\n\n<h3 class=\"graf graf--h3 graf-after--pre wp-block-heading\" id=\"576c\">Deploy Ingress<\/h3>\n\n\n\n<p class=\"graf graf--p graf-after--h3\" id=\"b0ec\">use helm to install<\/p>\n\n\n\n<pre id=\"6078\" class=\"wp-block-code graf graf--pre graf-after--p\"><code>helm install ingress helm\/medium-ingress<\/code><\/pre>\n\n\n\n<p class=\"graf graf--p graf-after--pre\" id=\"594e\">and load up your page at <code class=\"markup--code markup--p-code\"><a class=\"markup--anchor markup--p-anchor\" href=\"http:\/\/medium-example.com\/.\" target=\"_blank\" rel=\"noopener\" data-href=\"http:\/\/medium-example.com\/.\">http:\/\/medium-example.com\/.<\/a><\/code><\/p>\n\n\n\n<p class=\"graf graf--p graf-after--p\" id=\"1cd5\">You can verify that its all working together in the logs as well if you review the application and ingress pod log instances.<\/p>\n\n\n\n<h3 class=\"graf graf--h3 graf-after--p wp-block-heading\" id=\"8293\">Publish the&nbsp;Chart<\/h3>\n\n\n\n<p class=\"graf graf--p graf-after--h3\" id=\"6064\">We want to version this ingress and publish it as a chart because we\u2019ll eventually pull all of these services under an umbrella chart in the future. First we need to create a pipeline.<\/p>\n\n\n\n<p class=\"graf graf--p graf-after--p\" id=\"e9d7\">In codefresh make a new build pipeline for this project called <code class=\"markup--code markup--p-code\">medium-ingress<\/code> under the <code class=\"markup--code markup--p-code\">medium <\/code>project. Make sure to add the helm repository under the environment variables setup. Then use this workflow for the pipeline:<\/p>\n\n\n\n<pre id=\"8ad5\" class=\"wp-block-code graf graf--pre graf-after--p\"><code>version: \"1.0\"\nstages:\n  - \"clone\"\n  - \"helmpublish\"<\/code><\/pre>\n\n\n\n<pre id=\"5244\" class=\"wp-block-code graf graf--pre graf-after--pre\"><code>steps:\n  Clone:\n        title: \"Cloning repository\"\n        type: \"git-clone\"\n        repo: \"<a class=\"markup--anchor markup--pre-anchor\" href=\"https:\/\/github.com\/brianrook\/medium-ingress\" target=\"_blank\" rel=\"nofollow noopener\" data-href=\"https:\/\/github.com\/brianrook\/medium-ingress\">https:\/\/github.com\/brianrook\/medium-ingress<\/a>\"\n        revision: \"master\"\n        stage: \"clone\"\n  HelmChartGetVersion:\n    title: Get Helm Chart Version\n    stage: helmpublish\n    image: codefresh\/cfstep-helm\n    working_directory: '\/codefresh\/volume\/medium-ingress'\n    environment:\n      - CHART_PATH=helm\/medium-ingress\n      - CHART_NAME=medium-ingress\n    commands:\n      - export ACTION=auth\n      - source \/opt\/bin\/release_chart\n      - helm repo add default ${{CF_CTX_CF_HELM_DEFAULT_URL}}\n      - yq .version ${CHART_PATH}\/Chart.yaml\n      - export CURRENT_CHART_VERSION=`helm search default\/${CHART_NAME} | awk 'FNR==2{print $2}' || yq .version ${CHART_PATH}\/Chart.yaml`\n      - echo $CURRENT_CHART_VERSION\n      - cf_export NEW_CHART_VERSION=`echo \"${CURRENT_CHART_VERSION}\" | awk -F. '{$NF = $NF + 1;} 1' | sed 's\/ \/.\/g'`\n      - echo $NEW_CHART_VERSION\n  HelmChartUpdate:\n    title: Update Helm Chart Version\n    stage: helmpublish\n    image: gksoftware\/yq\n    working_directory: '\/codefresh\/volume\/medium-ingress'\n    environment:\n      - CHART_PATH=helm\/medium-ingress\n      - YAML_PATH=image.tag\n    commands: \n      - echo $NEW_CHART_VERSION\n      - yq w -i ${CHART_PATH}\/Chart.yaml version ${NEW_CHART_VERSION}\n      - echo $CF_SHORT_REVISION\n      - yq w -i ${CHART_PATH}\/values.yaml ${YAML_PATH} ${{CF_SHORT_REVISION}}\n  HelmChartPush:\n      title: Push Helm Chart to Chart Repository\n      stage: helmpublish\n      image: codefresh\/cfstep-helm\n      working_directory: '\/codefresh\/volume\/medium-ingress'\n      environment:\n        - CHART_REF=helm\/medium-ingress\/\n        - ACTION=push<\/code><\/pre>\n\n\n\n<p class=\"graf graf--p graf-after--pre\" id=\"6d99\">Finally, make sure that this pipeline is triggered off push to master. Lets commit our changes and start a build<\/p>\n\n\n\n<pre id=\"3bee\" class=\"wp-block-code graf graf--pre graf-after--p\"><code>git checkout -b helm\ngit add .\ngit commit -m \"ingress helm chart\"\ngit push<\/code><\/pre>\n\n\n\n<pre id=\"be4e\" class=\"wp-block-code graf graf--pre graf-after--pre\"><code>git checkout master\ngit merge helm\ngit push\n\n<\/code><\/pre>\n\n\n\n<p class=\"graf graf--p graf-after--pre\" id=\"eb0b\">once that builds lets deploy all of our components<\/p>\n\n\n\n<pre id=\"8174\" class=\"wp-block-code graf graf--pre graf-after--p\"><code>helm repo update\nhelm install customer codefresh\/medium-customer\nhelm install cust-mgr codefresh\/medium-customer-manager\nhelm install ingress codefresh\/medium-ingress<\/code><\/pre>\n\n\n\n<p class=\"graf graf--p graf-after--pre\" id=\"5127\">And verify that everything works together.<\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"entry-summary\">\nWe\u2019ve got multiple service available for deployment now. Lets allow them to&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-20-fe28a586cdc6\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &ldquo;Creating an Ingress in Kubernetes&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":[29,79,81,102,80,50,83],"course":[40],"class_list":["post-817","post","type-post","status-publish","format-standard","hentry","category-software-development","tag-git","tag-helm","tag-helm-chart","tag-ingress","tag-kubernetes","tag-maven","tag-minikube","course-spring-with-kubernetes","entry"],"jetpack_featured_media_url":"","jetpack-related-posts":[{"id":836,"url":"https:\/\/bullyrooks.com\/index.php\/2020\/03\/30\/simple-spring-boot-service-to-kubernetes-application-step-11-636b842a3c0f\/","url_meta":{"origin":817,"position":0},"title":"Helm for Deployment","author":"Bullyrook","date":"March 30, 2020","format":false,"excerpt":"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 how to deploy our application. We can use tools like kubectl to promote these\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":817,"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":817,"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":1176,"url":"https:\/\/bullyrooks.com\/index.php\/2022\/01\/04\/cloud-kube-helm-initialization-and-chart-publishing\/","url_meta":{"origin":817,"position":3},"title":"Cloud Kube | Helm Initialization and Chart Publishing","author":"Bullyrook","date":"January 4, 2022","format":false,"excerpt":"Now that we're producing versioned docker images into our registry lets get helm setup and publish versioned charts. This will allow us to deploy fully configured services into kubernetes. Helm Init I'm assuming that helm is already installed in your development environment, so I'm not going to cover installing it.\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-25.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-25.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-25.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":1188,"url":"https:\/\/bullyrooks.com\/index.php\/2022\/01\/04\/cloud-kube-setup-cloud-hosting\/","url_meta":{"origin":817,"position":4},"title":"Cloud Kube | Setup Cloud Hosting","author":"Bullyrook","date":"January 4, 2022","format":false,"excerpt":"We've got a helm chart and associated docker image. Now we're going to setup a cloud kubernetes provider to deploy our application to. Okteto offers a very generous kubernetes hosting platform that's free for small developer projects. Setup Okteto First register on okteto by creating an account via your github\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-31.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-31.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/bullyrooks.com\/wp-content\/uploads\/2022\/01\/image-31.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":822,"url":"https:\/\/bullyrooks.com\/index.php\/2020\/03\/30\/simple-spring-boot-service-to-kubernetes-application-step-13-c3d437bb7570\/","url_meta":{"origin":817,"position":5},"title":"Automating Deployment (for CICD)","author":"Bullyrook","date":"March 30, 2020","format":false,"excerpt":"Now that we\u2019ve deployed our application, lets reduce some of the manual steps and make our deployments more reproducible with the intent of eventually making them automated for CI\/CD. Publish our Chart to the Chart Repository Normally, we would need to create a helm chart repository, however, codefresh has given\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":[]}],"_links":{"self":[{"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/posts\/817","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=817"}],"version-history":[{"count":3,"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/posts\/817\/revisions"}],"predecessor-version":[{"id":915,"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/posts\/817\/revisions\/915"}],"wp:attachment":[{"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/media?parent=817"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/categories?post=817"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/tags?post=817"},{"taxonomy":"course","embeddable":true,"href":"https:\/\/bullyrooks.com\/index.php\/wp-json\/wp\/v2\/course?post=817"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}