{"id":18429118,"url":"https://github.com/openliberty/guide-kubernetes-intro","last_synced_at":"2026-03-06T06:04:29.928Z","repository":{"id":37085995,"uuid":"129763550","full_name":"OpenLiberty/guide-kubernetes-intro","owner":"OpenLiberty","description":"An introductory guide on how to deploy microservices to a Kubernetes cluster and manage them with the Kubernetes CLI: https://openliberty.io/guides/kubernetes-intro.html","archived":false,"fork":false,"pushed_at":"2026-02-01T18:36:50.000Z","size":739,"stargazers_count":22,"open_issues_count":13,"forks_count":24,"subscribers_count":4,"default_branch":"prod","last_synced_at":"2026-02-27T04:27:34.875Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/OpenLiberty.png","metadata":{"files":{"readme":"README.adoc","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2018-04-16T15:16:27.000Z","updated_at":"2025-11-10T15:17:02.000Z","dependencies_parsed_at":"2023-11-24T20:29:31.949Z","dependency_job_id":"289e0cb5-ec81-4110-9653-0d2bac411126","html_url":"https://github.com/OpenLiberty/guide-kubernetes-intro","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/OpenLiberty/guide-kubernetes-intro","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenLiberty%2Fguide-kubernetes-intro","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenLiberty%2Fguide-kubernetes-intro/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenLiberty%2Fguide-kubernetes-intro/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenLiberty%2Fguide-kubernetes-intro/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OpenLiberty","download_url":"https://codeload.github.com/OpenLiberty/guide-kubernetes-intro/tar.gz/refs/heads/prod","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenLiberty%2Fguide-kubernetes-intro/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30164532,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-06T04:43:31.446Z","status":"ssl_error","status_checked_at":"2026-03-06T04:40:30.133Z","response_time":250,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-06T05:15:53.749Z","updated_at":"2026-03-06T06:04:29.879Z","avatar_url":"https://github.com/OpenLiberty.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"// INSTRUCTION: Please remove all comments that start INSTRUCTION prior to commit. Most comments should be removed, although not the copyright.\n// INSTRUCTION: The copyright statement must appear at the top of the file\n//\n// Copyright (c) 2018, 2025 IBM Corporation and others.\n// Licensed under Creative Commons Attribution-NoDerivatives\n// 4.0 International (CC BY-ND 4.0)\n//   https://creativecommons.org/licenses/by-nd/4.0/\n//\n// Contributors:\n//     IBM Corporation\n//\n:projectid: kubernetes-intro\n:page-layout: guide-multipane\n:page-duration: 25 minutes\n:page-releasedate: 2018-10-05\n:page-description: Explore how to deploy microservices to Kubernetes and manage your cluster.\n:page-tags: ['kubernetes', 'docker']\n:page-permalink: /guides/{projectid}\n:page-related-guides: ['docker', 'istio-intro']\n:common-includes: https://raw.githubusercontent.com/OpenLiberty/guides-common/prod\n:source-highlighter: prettify\n:page-seo-title: Deploying Java microservices to Kubernetes\n:page-seo-description: A getting started tutorial on how to deploy Java microservices in Docker containers to a Kubernetes cluster with examples of how to manage and scale the Kubernetes deployment.\n:guide-author: Open Liberty\n= Deploying microservices to Kubernetes\n\n[.hidden]\nNOTE: This repository contains the guide documentation source. To view the guide in published form, view it on the https://openliberty.io/guides/{projectid}.html[Open Liberty website].\n\nDeploy microservices in Open Liberty Docker containers to Kubernetes and manage them with the Kubernetes CLI, kubectl.\n\n:minikube-ip: 192.168.99.100\n:kube: Kubernetes\n:hashtag: #\n:win: WINDOWS\n:mac: MAC\n:linux: LINUX\n:system-api: http://[hostname]:31000/system/properties\n:inventory-api: http://[hostname]:32000/inventory/systems\n\n// =================================================================================================\n// What is {kube}\n// =================================================================================================\n\n== What is {kube}?\n\n{kube} is an open source container orchestrator that automates many tasks involved in deploying, managing, and scaling containerized applications.\n\nOver the years, {kube} has become a major tool in containerized environments as containers are being further leveraged for all steps of a continuous delivery pipeline.\n\n=== Why use {kube}?\n\nManaging individual containers can be challenging. A small team can easily manage a few containers for development but managing hundreds of containers can be a headache, even for a large team of experienced developers. {kube} is a tool for deployment in containerized environments. It handles scheduling, deployment, as well as mass deletion and creation of containers. It provides update rollout abilities on a large scale that would otherwise prove extremely tedious to do. Imagine that you updated a Docker image, which now needs to propagate to a dozen containers. While you could destroy and then re-create these containers, you can also run a short one-line command to have {kube} make all those updates for you. Of course, this is just a simple example. {kube} has a lot more to offer.\n\n=== Architecture\n\nDeploying an application to Kubernetes means deploying an application to a Kubernetes cluster.\n\nA typical {kube} cluster is a collection of physical or virtual machines called nodes that run containerized applications. A cluster is made up of one parent node that manages the cluster, and many worker nodes that run the actual application instances inside {kube} objects called pods.\n\nA pod is a basic building block in a {kube} cluster. It represents a single running process that encapsulates a container or in some scenarios many closely coupled containers. Pods can be replicated to scale applications and handle more traffic. From the perspective of a cluster, a set of replicated pods is still one application instance, although it might be made up of dozens of instances of itself. A single pod or a group of replicated pods are managed by {kube} objects called controllers. A controller handles replication, self-healing, rollout of updates, and general management of pods. One example of a controller that you will use in this guide is a deployment.\n\nA pod or a group of replicated pods are abstracted through {kube} objects called services that define a set of rules by which the pods can be accessed. In a basic scenario, a {kube} service exposes a node port that can be used together with the cluster IP address to access the pods encapsulated by the service.\n\nTo learn about the various Kubernetes resources that you can configure, see the https://kubernetes.io/docs/concepts/[official {kube} documentation^].\n\n// =================================================================================================\n// Introduction\n// =================================================================================================\n\n== What you'll learn\n\nYou will learn how to deploy two microservices in Open Liberty containers to a local {kube} cluster. You will then manage your deployed microservices using the `kubectl` command line interface for {kube}. The `kubectl` CLI is your primary tool for communicating with and managing your {kube} cluster.\n\nThe two microservices you will deploy are called `system` and `inventory`. The `system` microservice returns the JVM system properties of the running container and it returns the pod's name in the HTTP header making replicas easy to distinguish from each other. The `inventory` microservice adds the properties from the `system` microservice to the inventory. This process demonstrates how communication can be established between pods inside a cluster.\n\nYou will use a local single-node {kube} cluster.\n\n// =================================================================================================\n// Prerequisites\n// =================================================================================================\n[role='command']\ninclude::{common-includes}/kube-prereq.adoc[]\n\n// =================================================================================================\n// Getting Started\n// =================================================================================================\n[role='command']\ninclude::{common-includes}/gitclone.adoc[]\n\n// no \"try what you'll build\" section in this guide because it would be too long due to all setup the user will have to do.\n\n// =================================================================================================\n// Staring and preparing your cluster for deployment\n// =================================================================================================\n// Static guide instruction\nifndef::cloud-hosted[]\n[role='command']\ninclude::{common-includes}/kube-start.adoc[]\nendif::[]\n\n// =================================================================================================\n// Building and containerizing the microservices\n// =================================================================================================\n\n== Building and containerizing the microservices\n\nThe first step of deploying to {kube} is to build your microservices and containerize them with Docker.\n\nThe starting Java project, which you can find in the `start` directory, is a multi-module Maven project that's made up of the `system` and `inventory` microservices. Each microservice resides in its own directory, `start/system` and `start/inventory`. Each of these directories also contains a Dockerfile, which is necessary for building Docker images. If you're unfamiliar with Dockerfiles, check out the https://openliberty.io/guides/containerize.html[Containerizing Microservices^] guide, which covers Dockerfiles in depth.\n\nNavigate to the `start` directory and build the applications by running the following commands:\n\ninclude::{common-includes}/os-tabs.adoc[]\n\n[.tab_content.windows_section]\n--\n[role='command']\n```\ncd start\nmvnw.cmd clean package\n```\n--\n\n[.tab_content.mac_section]\n--\n[role='command']\n```\ncd start\n./mvnw clean package\n```\n--\n\n[.tab_content.linux_section]\n--\n[role='command']\n```\ncd start\n./mvnw clean package\n```\n--\n\n\n\nNext, run the `docker build` commands to build container images for your application:\n[role='command']\n```\ndocker build -t system:1.0-SNAPSHOT system/.\ndocker build -t inventory:1.0-SNAPSHOT inventory/.\n```\n\nThe `-t` flag in the `docker build` command allows the Docker image to be labeled (tagged) in the `name[:tag]` format. The tag for an image describes the specific image version. If the optional `[:tag]` tag is not specified, the `latest` tag is created by default.\n\nDuring the build, you'll see various Docker messages describing what images are being downloaded and built. When the build finishes, run the following command to list all local Docker images:\n[role='command']\n```\ndocker images\n```\n\n// Static guide instruction\nifndef::cloud-hosted[]\nVerify that the `system:1.0-SNAPSHOT` and `inventory:1.0-SNAPSHOT` images are listed among them, for example:\n\ninclude::{common-includes}/os-tabs.adoc[]\n\n[.tab_content.windows_section.mac_section]\n--\n[source, role=\"no_copy\"]\n----\nREPOSITORY                                                       TAG\ninventory                                                        1.0-SNAPSHOT\nsystem                                                           1.0-SNAPSHOT\nopenliberty/open-liberty                                         kernel-slim-java11-openj9-ubi\nk8s.gcr.io/kube-proxy-amd64                                      v1.10.3\nk8s.gcr.io/kube-scheduler-amd64                                  v1.10.3\nk8s.gcr.io/kube-controller-manager-amd64                         v1.10.3\nk8s.gcr.io/kube-apiserver-amd64                                  v1.10.3\nk8s.gcr.io/etcd-amd64                                            3.1.12\nk8s.gcr.io/k8s-dns-dnsmasq-nanny-amd64                           1.14.8\nk8s.gcr.io/k8s-dns-sidecar-amd64                                 1.14.8\nk8s.gcr.io/k8s-dns-kube-dns-amd64                                1.14.8\nk8s.gcr.io/pause-amd64                                           3.1\n----\n--\n\n[.tab_content.linux_section]\n--\n[source, role=\"no_copy\"]\n----\nREPOSITORY                                                       TAG\ninventory                                                        1.0-SNAPSHOT\nsystem                                                           1.0-SNAPSHOT\nopenliberty/open-liberty                                         kernel-slim-java11-openj9-ubi\nk8s.gcr.io/kube-proxy-amd64                                      v1.10.0\nk8s.gcr.io/kube-controller-manager-amd64                         v1.10.0\nk8s.gcr.io/kube-apiserver-amd64                                  v1.10.0\nk8s.gcr.io/kube-scheduler-amd64                                  v1.10.0\nquay.io/kubernetes-ingress-controller/nginx-ingress-controller   0.12.0\nk8s.gcr.io/etcd-amd64                                            3.1.12\nk8s.gcr.io/kube-addon-manager                                    v8.6\nk8s.gcr.io/k8s-dns-dnsmasq-nanny-amd64                           1.14.8\nk8s.gcr.io/k8s-dns-sidecar-amd64                                 1.14.8\nk8s.gcr.io/k8s-dns-kube-dns-amd64                                1.14.8\nk8s.gcr.io/pause-amd64                                           3.1\nk8s.gcr.io/kubernetes-dashboard-amd64                            v1.8.1\nk8s.gcr.io/kube-addon-manager                                    v6.5\ngcr.io/k8s-minikube/storage-provisioner                          v1.8.0\ngcr.io/k8s-minikube/storage-provisioner                          v1.8.1\nk8s.gcr.io/defaultbackend                                        1.4\nk8s.gcr.io/k8s-dns-sidecar-amd64                                 1.14.4\nk8s.gcr.io/k8s-dns-kube-dns-amd64                                1.14.4\nk8s.gcr.io/k8s-dns-dnsmasq-nanny-amd64                           1.14.4\nk8s.gcr.io/etcd-amd64                                            3.0.17\nk8s.gcr.io/pause-amd64                                           3.0\n----\n--\n\nIf you don't see the `system:1.0-SNAPSHOT` and `inventory:1.0-SNAPSHOT` images, then check the Maven build log for any potential errors. In addition, if you are using Minikube, make sure your Docker CLI is configured to use Minikube's Docker daemon instead of your host's Docker daemon.\nendif::[]\n\n// Cloud hosted guide instruction\nifdef::cloud-hosted[]\nVerify that the ***system:1.0-SNAPSHOT*** and ***inventory:1.0-SNAPSHOT*** images are listed among them, for example:\n\n```\nREPOSITORY                                TAG                       \ninventory                                 1.0-SNAPSHOT\nsystem                                    1.0-SNAPSHOT\nopenliberty/open-liberty                  kernel-slim-java11-openj9-ubi\n```\n\nIf you don't see the ***system:1.0-SNAPSHOT*** and ***inventory:1.0-SNAPSHOT*** images, then check the Maven build log for any potential errors. If the images built without errors, push them to your container registry on IBM Cloud with the following commands:\n\n```bash\ndocker tag inventory:1.0-SNAPSHOT us.icr.io/$SN_ICR_NAMESPACE/inventory:1.0-SNAPSHOT\ndocker tag system:1.0-SNAPSHOT us.icr.io/$SN_ICR_NAMESPACE/system:1.0-SNAPSHOT\ndocker push us.icr.io/$SN_ICR_NAMESPACE/inventory:1.0-SNAPSHOT\ndocker push us.icr.io/$SN_ICR_NAMESPACE/system:1.0-SNAPSHOT\n```\nendif::[]\n\n// =================================================================================================\n// Deploying the microservices\n// =================================================================================================\n\n== Deploying the microservices\n\nNow that your Docker images are built, deploy them using a Kubernetes resource definition.\n\nA Kubernetes resource definition is a yaml file that contains a description of all your deployments, services, or any other resources that you want to deploy. All resources can also be deleted from the cluster by using the same yaml file that you used to deploy them.\n\n[role=\"code_command hotspot\", subs=\"quotes\"]\n----\n#Create the Kubernetes configuration file in the `start` directory.#\n`kubernetes.yaml`\n----\n\nkubernetes.yaml\n[source, yaml, linenums, role=\"code_column hide_tags=rolling1,readinessProbe1,rolling2,readinessProbe2\"]\n----\ninclude::finish/kubernetes.yaml[]\n----\n\nThis file defines four {kube} resources. It defines two deployments and two services. A {kube} deployment is a resource that controls the creation and management of pods. A service exposes your deployment so that you can make requests to your containers. Three key items to look at when creating the deployments are the [hotspot=labels1 hotspot=labels2 hotspot=labels3 hotspot=labels4]`labels`, [hotspot=image1 hotspot=image2]`image`, and [hotspot=containerPort1 hotspot=containerPort2]`containerPort` fields. The [hotspot=labels1 hotspot=labels2 hotspot=labels3 hotspot=labels4]`labels` is a way for a {kube} service to reference specific deployments. The [hotspot=image1 hotspot=image2]`image` is the name and tag of the Docker image that you want to use for this container. Finally, the [hotspot=containerPort1 hotspot=containerPort2]`containerPort` is the port that your container exposes to access your application. For the services, the key point to understand is that they expose your deployments. The binding between deployments and services is specified by labels -- in this case the [hotspot=app1 hotspot=app2 hotspot=app3 hotspot=app4 hotspot=app5 hotspot=app6 hotspot=app7 hotspot=app8]`app` label. You will also notice the service has a type of [hotspot=NodePort1 hotspot=NodePort2]`NodePort`. This means you can access these services from outside of your cluster via a specific port. In this case, the ports are `31000` and `32000`, but port numbers can also be randomized if the [hotspot=nodePort1 hotspot=nodePort2]`nodePort` field is not used.\n\n// Cloud hosted guide instruction\nifdef::cloud-hosted[]\nUpdate the image names so that the images in your IBM Cloud container registry are used, and remove the ***nodePort*** fields so that the ports can be generated automatically:\n\n```bash\nsed -i 's=system:1.0-SNAPSHOT=us.icr.io/'\"$SN_ICR_NAMESPACE\"'/system:1.0-SNAPSHOT\\n        imagePullPolicy: Always=g' kubernetes.yaml\nsed -i 's=inventory:1.0-SNAPSHOT=us.icr.io/'\"$SN_ICR_NAMESPACE\"'/inventory:1.0-SNAPSHOT\\n        imagePullPolicy: Always=g' kubernetes.yaml\nsed -i 's=nodePort: 31000==g' kubernetes.yaml\nsed -i 's=nodePort: 32000==g' kubernetes.yaml\n```\nendif::[]\n\nRun the following commands to deploy the resources as defined in kubernetes.yaml:\n[role='command']\n```\nkubectl apply -f kubernetes.yaml\n```\n\nWhen the apps are deployed, run the following command to check the status of your pods:\n[role='command']\n```\nkubectl get pods\n```\n\nYou'll see an output similar to the following if all the pods are healthy and running:\n\n[source, role=\"no_copy\"]\n----\nNAME                                    READY     STATUS    RESTARTS   AGE\nsystem-deployment-6bd97d9bf6-4ccds      1/1       Running   0          15s\ninventory-deployment-645767664f-nbtd9   1/1       Running   0          15s\n----\n\nYou can also inspect individual pods in more detail by running the following command:\n[role='command']\n```\nkubectl describe pods\n```\n\nYou can also issue the `kubectl get` and `kubectl describe` commands on other {kube} resources, so feel free to inspect all other resources.\n\n// Static guide instruction\nifndef::cloud-hosted[]\nNext you will make requests to your services.\n\ninclude::{common-includes}/os-tabs.adoc[]\n\n[.tab_content.windows_section.mac_section]\n--\nThe default host name for Docker Desktop is `localhost`.\n--\n\n[.tab_content.linux_section]\n--\nThe default host name for minikube is {minikube-ip}. Otherwise it can be found using the `minikube ip` command.\n--\n\nThen, run the `curl` command or visit the following URLs to access your microservices, substituting the appropriate host name:\n\n* `{system-api}`\n* `{inventory-api}/system-service`\n\nThe first URL returns system properties and the name of the pod in an HTTP header called `X-Pod-Name`. To view the header, you may use the `-I` option in the `curl` when making a request to `{system-api}`. The second URL adds properties from the `system-service` endpoint to the inventory {kube} Service. Visiting `{inventory-api}/[kube-service]` in general adds to the inventory depending on whether `kube-service` is a valid {kube} service that can be accessed.\nendif::[]\n\n// Cloud-hosted guide instruction\nifdef::cloud-hosted[]\nIn this execise, you need to access the services by using the Kubernetes API. Run the following command to start a proxy to the Kubernetes API server:\n\n```bash\nkubectl proxy\n```\n\nOpen another command-line session by selecting **Terminal** \u003e **New Terminal** from the menu of the IDE. Run the following commands to store the proxy path of the ***system*** and ***inventory*** services.\n```bash\nSYSTEM_PROXY=localhost:8001/api/v1/namespaces/$SN_ICR_NAMESPACE/services/system-service/proxy\nINVENTORY_PROXY=localhost:8001/api/v1/namespaces/$SN_ICR_NAMESPACE/services/inventory-service/proxy\n```\n\nRun the following echo commands to verify the variables:\n\n```bash\necho $SYSTEM_PROXY \u0026\u0026 echo $INVENTORY_PROXY\n```\n\nThe output appears as shown in the following example:\n\n```\nlocalhost:8001/api/v1/namespaces/sn-labs-yourname/services/system-service/proxy\nlocalhost:8001/api/v1/namespaces/sn-labs-yourname/services/inventory-service/proxy\n```\n\nThen, use the following ***curl*** command to access your ***system*** microservice:\n\n```bash\ncurl -s http://$SYSTEM_PROXY/system/properties | jq\n```\n\nAlso, use the following ***curl*** command to access your ***inventory*** microservice:\n\n```bash\ncurl -s http://$INVENTORY_PROXY/inventory/systems/system-service | jq\n```\n\nThe ***http://$SYSTEM_PROXY/system/properties*** URL returns system properties and the name of the pod in an HTTP header that is called ***X-Pod-Name***. To view the header, you can use the ***-I*** option in the ***curl*** command when you make a request to the ***http://$SYSTEM_PROXY/system/properties*** URL.\n\n```bash\ncurl -I http://$SYSTEM_PROXY/system/properties\n```\n\nThe ***http://$INVENTORY_PROXY/inventory/systems/system-service*** URL adds properties from the ***system-service*** endpoint to the inventory {kube} Service. Making a request to the ***http://$INVENTORY_PROXY/inventory/systems/[kube-service]*** URL in general adds to the inventory. That result depends on whether the ***kube-service*** endpoint is a valid {kube} service that can be accessed.\nendif::[]\n\n// =================================================================================================\n// Scaling a deployment\n// ================================================================================================\n\n== Rolling update\n\nWithout continuous updates, a Kubernetes cluster is susceptible to a denial of a service attack. Rolling updates continually install Kubernetes patches without disrupting the availability of the deployed applications. Update the yaml file as follows to add the `rollingUpdate` configuration. \n\n[role=\"code_command hotspot\", subs=\"quotes\"]\n----\n#Replace the Kubernetes configuration file#\n`kubernetes.yaml`\n----\n\nkubernetes.yaml\n[source, yaml, linenums, role=\"code_column\"]\n----\ninclude::finish/kubernetes.yaml[]\n----\n\nThe [hotspot=rolling1 hotspot=rolling2]`rollingUpdate` configuration has two attributes, `maxUnavailable` and `maxSurge`. The [hotspot=maxUnavailable1 hotspot=maxUnavailable2]`maxUnavailable` attribute specifies the the maximum number of Kubernetes pods that can be unavailable during the update process. Similarly, the [hotspot=maxSurge1 hotspot=maxSurge2]`maxSurge` attribute specifies the maximum number of additional pods that can be created during the update process.\n\nThe [hotspot=readinessProbe1 hotspot=readinessProbe2]`readinessProbe` allows Kubernetes to know whether the service is ready to handle requests. The readiness health check classes for the `/health/ready` endpoint to the `inventory` and `system` services are provided for you. If you want to learn more about how to use health checks in Kubernetes, check out the https://openliberty.io/guides/kubernetes-microprofile-health.html[Kubernetes-microprofile-health^] guide. \n\nifdef::cloud-hosted[]\nUpdate the image names and remove the ***nodePort*** fields by running the following commands:\n```bash\ncd /home/project/guide-kubernetes-intro/start\nsed -i 's=system:1.0-SNAPSHOT=us.icr.io/'\"$SN_ICR_NAMESPACE\"'/system:1.0-SNAPSHOT\\n        imagePullPolicy: Always=g' kubernetes.yaml\nsed -i 's=inventory:1.0-SNAPSHOT=us.icr.io/'\"$SN_ICR_NAMESPACE\"'/inventory:1.0-SNAPSHOT\\n        imagePullPolicy: Always=g' kubernetes.yaml\nsed -i 's=nodePort: 31000==g' kubernetes.yaml\nsed -i 's=nodePort: 32000==g' kubernetes.yaml\n```\nendif::[]\n\nRun the following command to deploy the `inventory` and `system` microservices with the new configuration:\n[role='command']\n```\nkubectl apply -f kubernetes.yaml\n```\n\nRun the following command to check the status of your pods are ready and running:\n[role='command']\n```\nkubectl get pods\n```\n\n== Scaling a deployment\n\nTo use load balancing, you need to scale your deployments. When you scale a deployment, you replicate its pods, creating more running instances of your applications. Scaling is one of the primary advantages of {kube} because you can replicate your application to accommodate more traffic, and then descale your deployments to free up resources when the traffic decreases.\n\nAs an example, scale the `system` deployment to three pods by running the following command:\n[role='command']\n```\nkubectl scale deployment/system-deployment --replicas=3\n```\n\nUse the following command to verify that two new pods have been created.\n[role='command']\n```\nkubectl get pods\n```\n\n[source, role=\"no_copy\"]\n----\nNAME                                    READY     STATUS    RESTARTS   AGE\nsystem-deployment-6bd97d9bf6-4ccds      1/1       Running   0          1m\nsystem-deployment-6bd97d9bf6-jf9rs      1/1       Running   0          25s\nsystem-deployment-6bd97d9bf6-x4zth      1/1       Running   0          25s\ninventory-deployment-645767664f-nbtd9   1/1       Running   0          1m\n----\n\n// Static guide instruction\nifndef::cloud-hosted[]\nWait for your two new pods to be in the ready state, then make a `curl -I` request to, or visit the `{system-api}` URL. \nendif::[]\n\n// Cloud-hosted guide instruction\nifdef::cloud-hosted[]\nWait for your two new pods to be in the ready state, then make the following ***curl*** command:\n\n```bash\ncurl -I http://$SYSTEM_PROXY/system/properties\n```\nendif::[]\n\nNotice that the `X-Pod-Name` header has a different value when you call it multiple times. The value changes because three pods that all serve the `system` application are now running. Similarly, to descale your deployments you can use the same scale command with fewer replicas.\n\n[role='command']\n```\nkubectl scale deployment/system-deployment --replicas=1\n```\n\n== Redeploy microservices\n\nWhen you're building your application, you might want to quickly test a change. To run a quick test, you can rebuild your Docker images then delete and re-create your {kube} resources. Note that there is only one `system` pod after you redeploy because you're deleting all of the existing pods.\n\n// Static guide instruction\nifndef::cloud-hosted[]\ninclude::{common-includes}/os-tabs.adoc[]\n\n[.tab_content.windows_section]\n--\n[role='command']\n```\nkubectl delete -f kubernetes.yaml\n\nmvnw.cmd clean package\ndocker build -t system:1.0-SNAPSHOT system/.\ndocker build -t inventory:1.0-SNAPSHOT inventory/.\n\nkubectl apply -f kubernetes.yaml\n```\n--\n\n[.tab_content.mac_section]\n--\n[role='command']\n```\nkubectl delete -f kubernetes.yaml\n\n./mvnw clean package\ndocker build -t system:1.0-SNAPSHOT system/.\ndocker build -t inventory:1.0-SNAPSHOT inventory/.\n\nkubectl apply -f kubernetes.yaml\n```\n--\n\n[.tab_content.linux_section]\n--\n[role='command']\n```\nkubectl delete -f kubernetes.yaml\n\n./mvnw clean package\ndocker build -t system:1.0-SNAPSHOT system/.\ndocker build -t inventory:1.0-SNAPSHOT inventory/.\n\nkubectl apply -f kubernetes.yaml\n```\n--\nendif::[]\n\n// Cloud-hosted guide instruction\nifdef::cloud-hosted[]\n```bash\ncd /home/project/guide-kubernetes-intro/start\nkubectl delete -f kubernetes.yaml\n\n./mvnw clean package\ndocker build -t system:1.0-SNAPSHOT system/.\ndocker build -t inventory:1.0-SNAPSHOT inventory/.\ndocker tag inventory:1.0-SNAPSHOT us.icr.io/$SN_ICR_NAMESPACE/inventory:1.0-SNAPSHOT\ndocker tag system:1.0-SNAPSHOT us.icr.io/$SN_ICR_NAMESPACE/system:1.0-SNAPSHOT\ndocker push us.icr.io/$SN_ICR_NAMESPACE/inventory:1.0-SNAPSHOT\ndocker push us.icr.io/$SN_ICR_NAMESPACE/system:1.0-SNAPSHOT\n\nkubectl apply -f kubernetes.yaml\n```\nendif::[]\n\nUpdating your applications in this way is fine for development environments, but it is not suitable for production. If you want to deploy an updated image to a production cluster, you can update the container in your deployment with a new image. Once the new container is ready, {kube} automates both the creation of a new container and the decommissioning of the old one.\n\n// =================================================================================================\n// Testing microservices that are running on {kube}\n// =================================================================================================\n\n== Testing microservices that are running on {kube}\npom.xml\n[source, xml, linenums, role='code_column']\n----\ninclude::finish/inventory/pom.xml[]\n----\n\nA few tests are included for you to test the basic functionality of the microservices. If a test failure occurs, then you might have introduced a bug into the code.  To run the tests, wait for all pods to be in the ready state before proceeding further. The default properties defined in the [hotspot]`pom.xml` are:\n\n[cols=\"15, 100\", options=\"header\"]\n|===\n| *Property*                        | *Description*\n| [hotspot=system.kube.service]`system.kube.service`       | Name of the {kube} Service wrapping the `system` pods, `system-service` by default.\n| [hotspot=system.service.root]`system.service.root`       | The {kube} Service `system-service` root path, `localhost:31000` by default.\n| [hotspot=inventory.service.root]`inventory.service.root` | The {kube} Service `inventory-service` root path, `localhost:32000` by default.\n|===\n\nNavigate back to the `start` directory.\n\n// Static guide instruction\nifndef::cloud-hosted[]\ninclude::{common-includes}/os-tabs.adoc[]\n\n[.tab_content.windows_section]\n--\nRun the integration tests against a cluster running with a host name of `localhost`:\n[role='command']\n```\nmvnw.cmd failsafe:integration-test\n```\n--\n\n[.tab_content.mac_section]\n--\nRun the integration tests against a cluster running with a host name of `localhost`:\n[role='command']\n```\n./mvnw failsafe:integration-test\n```\n--\n\n[.tab_content.linux_section]\n--\nRun the integration tests with the IP address for Minikube:\n[role='command']\n```\n./mvnw failsafe:integration-test -Dsystem.service.root=$(minikube ip):31000 -Dinventory.service.root=$(minikube ip):32000\n```\n--\nendif::[]\n\n// Cloud-hosted guide instruction\nifdef::cloud-hosted[]\nUpdate the ***pom.xml*** files so that the ***system.service.root*** and ***inventory.service.root*** properties match the values to access the ***system*** and **inventory*** services.\n\n```bash\nsed -i 's=localhost:31000='\"$SYSTEM_PROXY\"'=g' inventory/pom.xml\nsed -i 's=localhost:32000='\"$INVENTORY_PROXY\"'=g' inventory/pom.xml\nsed -i 's=localhost:31000='\"$SYSTEM_PROXY\"'=g' system/pom.xml\n```\n\nRun the integration tests by using the following command:\n\n```bash\n./mvnw failsafe:integration-test\n```\nendif::[]\n\nIf the tests pass, you'll see an output similar to the following for each service respectively:\n\n[source, role=\"no_copy\"]\n----\n-------------------------------------------------------\n T E S T S\n-------------------------------------------------------\nRunning it.io.openliberty.guides.system.SystemEndpointIT\nTests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.372 s - in it.io.openliberty.guides.system.SystemEndpointIT\n\nResults:\n\nTests run: 2, Failures: 0, Errors: 0, Skipped: 0\n----\n\n[source, role=\"no_copy\"]\n----\n-------------------------------------------------------\n T E S T S\n-------------------------------------------------------\nRunning it.io.openliberty.guides.inventory.InventoryEndpointIT\nTests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.714 s - in it.io.openliberty.guides.inventory.InventoryEndpointIT\n\nResults:\n\nTests run: 4, Failures: 0, Errors: 0, Skipped: 0\n----\n\n// =================================================================================================\n// Tear Down\n// =================================================================================================\n\n== Tearing down the environment\n\n// Cloud-hosted guide instruction\nifdef::cloud-hosted[]\nPress **CTRL+C** to stop the proxy server that was started at step 6 ***Deploying the microservices***.\nendif::[]\n\nWhen you no longer need your deployed microservices, you can delete all {kube} resources by running the ***kubectl delete*** command:\n[role='command']\n```\nkubectl delete -f kubernetes.yaml\n```\n\n// Static guide only instruction\nifndef::cloud-hosted[]\n[role='command']\ninclude::{common-includes}/kube-minikube-teardown.adoc[]\nendif::[]\n\n// =================================================================================================\n// finish\n// =================================================================================================\n\n== Great work! You're done!\n\nYou have just deployed two microservices that are running in Open Liberty to {kube}. You then scaled a microservice and ran integration tests against miroservices that are running in a {kube} cluster.\n\n// Include the below from the guides-common repo to tell users how they can contribute to the guide\n\ninclude::{common-includes}/attribution.adoc[subs=\"attributes\"]\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenliberty%2Fguide-kubernetes-intro","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenliberty%2Fguide-kubernetes-intro","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenliberty%2Fguide-kubernetes-intro/lists"}