Caching Microservices with Hazelcast in Kubernetes

duration 25 minutes

Prerequisites:

Use Hazelcast Caching in Open Liberty and Spring Boot based Microservices and deploy to Kubernetes

What you’ll learn

You will learn how to use Hazelcast distributed caching with Spring Boot, bundle with openliberty and deploy to a local Kubernetes cluster. You will then create a Kubernetes Service which load balance between containers and verify that you can share data between Microservices.

The microservice you will deploy is called hazelcast-caching. The hazelcast-caching microservice simply helps you put a data and read it back. As Kubernetes Service will send the request to different pod each time you initiate the request, the data will be served by shared hazelcast cluster between hazelcast-caching pods.

You will use a local single-node Kubernetes cluster. However, you can deploy this application on any kubernetes distributions such as IBM Cloud Private.

What is Hazelcast?

Hazelcast is an open source In-Memory Data Grid (IMDG). It provides elastically scalable distributed In-Memory computing, widely recognized as the fastest and most scalable approach to application performance.

Hazelcast is designed to scale up to hundreds and thousands of members. Simply add new members and they will automatically discover the cluster and will linearly increase both memory and processing capacity

Why Spring Boot?

Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can "just run". To learn more about Spring Boot. http://spring.io/projects/spring-boot

Additional prerequisites

Before you begin, you need a containerization software for building containers. Kubernetes supports various container runtimes. You will use Docker in this guide. For Docker installation instructions, refer to the official Docker documentation.

Use Docker Desktop, where a local Kubernetes environment is pre-installed and enabled. If you do not see the Kubernetes tab, then upgrade to the latest version of Docker Desktop.

Complete the setup for your operating system:

After you complete the Docker setup instructions for your operating system, ensure that Kubernetes (not Swarm) is selected as the orchestrator in Docker Preferences.

Use Docker Desktop, where a local Kubernetes environment is pre-installed and enabled. If you do not see the Kubernetes tab, then upgrade to the latest version of Docker Desktop.

Complete the setup for your operating system:

After you complete the Docker setup instructions for your operating system, ensure that Kubernetes (not Swarm) is selected as the orchestrator in Docker Preferences.

You will use Minikube as a single-node Kubernetes cluster that runs locally in a virtual machine. Make sure you have kubectl installed. If you need to install kubectl, see the kubectl installation instructions. For Minikube installation instructions, see the Minikube documentation.

Getting started

The fastest way to work through this guide is to clone the Git repository and use the projects that are provided inside:

git clone https://github.com/openliberty/guide-caching-microservices-hazelcast.git
cd guide-caching-microservices-hazelcast

The start directory contains the starting project that you will build upon.

The finish directory contains the finished project that you will build.

Before you begin, make sure you have all the necessary prerequisites.

Starting and preparing your cluster for deployment

Start your Kubernetes cluster.

Start your Docker Desktop environment.

Ensure that Kubernetes is running on Docker Desktop and that the context is set to docker-desktop.

Run the following command from a command-line session:

minikube start

Next, validate that you have a healthy Kubernetes environment by running the following command from the active command-line session.

kubectl get nodes

This command should return a Ready status for the master node.

You do not need to do any other step.

Run the following command to configure the Docker CLI to use Minikube’s Docker daemon. After you run this command, you will be able to interact with Minikube’s Docker daemon and build new images directly to it from your host machine:

eval $(minikube docker-env)

Use Hazelcast Caching in Spring Boot Application

The microservice in the start directory has in-process cache which is not accessible between microservices.

Firstly, you need to configure Hazelcast to be used in Spring Boot Application. replace Application.java with the following java class.

package io.openliberty.guides.hazelcast;

import com.hazelcast.config.Config;
import com.hazelcast.config.JoinConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class Application {

    private static Config config;

    @Bean
    public Config hazelcastConfig() {
        Config config = new Config();
        config.setProperty( "hazelcast.logging.type", "slf4j" );
        JoinConfig joinConfig = config.getNetworkConfig().getJoin();
        joinConfig.getMulticastConfig().setEnabled(false);
        joinConfig.getKubernetesConfig().setEnabled(true);
        return config;
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

This configuration will tell Spring Boot what kind of configuration is needed when each hazelcast member is started.

Now it is time to use Hazelcast in the hazelcast-caching microservice. if you check the source code of CommandController.java, you would notice that ConcurrentHashMap is used for backing key value store. In order to make this cache distributed, replace CommandController.java with Hazelcast version.

package io.openliberty.guides.hazelcast;

import com.hazelcast.core.HazelcastInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.ConcurrentMap;

@RestController
public class CommandController {

    @Value("#{environment.MY_POD_NAME}")
    private String podName;

    @Autowired
    HazelcastInstance hazelcastInstance;

    private ConcurrentMap<String,String> retrieveMap() {
        return hazelcastInstance.getMap("map");
    }

    @RequestMapping("/put")
    public CommandResponse put(@RequestParam(value = "key") String key, @RequestParam(value = "value") String value) {
        retrieveMap().put(key, value);
        return new CommandResponse(value,podName);
    }

    @RequestMapping("/get")
    public CommandResponse get(@RequestParam(value = "key") String key) {
        String value = retrieveMap().get(key);
        return new CommandResponse(value,podName);
    }


}

You would notice that getting hazelcast member is Autowired by Spring Boot and made available to the CommandController and there is no change in /put and /get endpoints.

Building and containerizing microservice

The first step of deploying to Kubernetes is to build your microservices and containerize them with Docker.

The starting Java project, which you can find in the start directory, is a spring boot based microservice. It is called hazelcast-caching which has two simple endpoints, /put and /get. This guide uses boost-maven-plugin to bundle spring boot app and openliberty together and build docker image for the deployment. Boost plugin does not require you to create your own Dockerfile but instead opionated docker image.

If you wanna learn more about boost maven plugin, you can visit the project website. https://github.com/OpenLiberty/boost/tree/master/boost-maven

If you want to create your own Dockerfile then you can always use dockerfile-maven plugin. please refer to https://openliberty.io/guides/kubernetes-intro.html#starting-and-preparing-your-cluster-for-deployment

To build hazelcast-caching microservice, run the following command in the start folder. This will build the docker image and push it to docker registry provided by minikube

mvn package

Execute following command to see available docker images

docker images

Verify that the hazelcast-caching:latest is listed among them, for example:

WINDOWS | MAC

REPOSITORY                                 TAG                 IMAGE ID            CREATED             SIZE
hazelcast-caching                          latest              ee0fb6a53f68        11 seconds ago      595MB
<none>                                     <none>              991f5e8961a5        13 seconds ago      595MB
open-liberty                               springBoot2         1da856d69fac        3 weeks ago         546MB
k8s.gcr.io/kube-proxy-amd64                v1.10.0             bfc21aadc7d3        11 months ago       97MB
k8s.gcr.io/kube-apiserver-amd64            v1.10.0             af20925d51a3        11 months ago       225MB
k8s.gcr.io/kube-scheduler-amd64            v1.10.0             704ba848e69a        11 months ago       50.4MB
k8s.gcr.io/kube-controller-manager-amd64   v1.10.0             ad86dbed1555        11 months ago       148MB
k8s.gcr.io/etcd-amd64                      3.1.12              52920ad46f5b        11 months ago       193MB
k8s.gcr.io/kube-addon-manager              v8.6                9c16409588eb        12 months ago       78.4MB
k8s.gcr.io/k8s-dns-dnsmasq-nanny-amd64     1.14.8              c2ce1ffb51ed        13 months ago       41MB
k8s.gcr.io/k8s-dns-sidecar-amd64           1.14.8              6f7f2dc7fab5        13 months ago       42.2MB
k8s.gcr.io/k8s-dns-kube-dns-amd64          1.14.8              80cc5ea4b547        13 months ago       50.5MB
k8s.gcr.io/pause-amd64                     3.1                 da86e6ba6ca1        14 months ago       742kB
k8s.gcr.io/kubernetes-dashboard-amd64      v1.8.1              e94d2f21bc0c        14 months ago       121MB
gcr.io/k8s-minikube/storage-provisioner    v1.8.0              4689081edb10        15 months ago       80.8MB
gcr.io/k8s-minikube/storage-provisioner    v1.8.1              4689081edb10        15 months ago       80.8MB
k8s.gcr.io/pause-amd64                     3.0                 99e59f495ffa        2 years ago         747kB

LINUX

REPOSITORY                                 TAG                 IMAGE ID            CREATED             SIZE
hazelcast-caching                          latest              ee0fb6a53f68        11 seconds ago      595MB
<none>                                     <none>              991f5e8961a5        13 seconds ago      595MB
open-liberty                               springBoot2         1da856d69fac        3 weeks ago         546MB
k8s.gcr.io/kube-proxy-amd64                v1.10.0             bfc21aadc7d3        11 months ago       97MB
k8s.gcr.io/kube-apiserver-amd64            v1.10.0             af20925d51a3        11 months ago       225MB
k8s.gcr.io/kube-scheduler-amd64            v1.10.0             704ba848e69a        11 months ago       50.4MB
k8s.gcr.io/kube-controller-manager-amd64   v1.10.0             ad86dbed1555        11 months ago       148MB
k8s.gcr.io/etcd-amd64                      3.1.12              52920ad46f5b        11 months ago       193MB
k8s.gcr.io/kube-addon-manager              v8.6                9c16409588eb        12 months ago       78.4MB
k8s.gcr.io/k8s-dns-dnsmasq-nanny-amd64     1.14.8              c2ce1ffb51ed        13 months ago       41MB
k8s.gcr.io/k8s-dns-sidecar-amd64           1.14.8              6f7f2dc7fab5        13 months ago       42.2MB
k8s.gcr.io/k8s-dns-kube-dns-amd64          1.14.8              80cc5ea4b547        13 months ago       50.5MB
k8s.gcr.io/pause-amd64                     3.1                 da86e6ba6ca1        14 months ago       742kB
k8s.gcr.io/kubernetes-dashboard-amd64      v1.8.1              e94d2f21bc0c        14 months ago       121MB
gcr.io/k8s-minikube/storage-provisioner    v1.8.0              4689081edb10        15 months ago       80.8MB
gcr.io/k8s-minikube/storage-provisioner    v1.8.1              4689081edb10        15 months ago       80.8MB
k8s.gcr.io/pause-amd64                     3.0                 99e59f495ffa        2 years ago         747kB

If you don’t see the hazelcast-caching:latest image, 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 and not your host’s as described in the previous section.

Deploying the microservices

Now that your Docker images are built, deploy them using a Kubernetes resource definition. To deploy the hazelcast-caching microservice, first create the kubernetes.yaml file in the start directory:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: hazelcast-caching-statefulset
  labels:
    app: hazelcast-caching
spec:
  replicas: 2
  serviceName: hazelcast-caching-service
  selector:
    matchLabels:
      app: hazelcast-caching
  template:
    metadata:
      labels:
        app: hazelcast-caching
    spec:
      containers:
        - name: hazelcast-caching-container
          image: hazelcast-caching:latest
          imagePullPolicy: IfNotPresent
          ports:
            - name: openliberty
              containerPort: 9080
          env:
            - name: MY_POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name

---
apiVersion: v1
kind: Service
metadata:
  name: hazelcast-caching-service
spec:
  type: NodePort
  selector:
    app: hazelcast-caching
  ports:
    - protocol: TCP
      port: 9080
      targetPort: 9080
      nodePort: 31000

This file defines two Kubernetes resources: one statefulset and one service. StatefulSet is preferred solution for Hazelcast because it enables controlled scale out/in of your microservices for easy data distribution. To learn more about StatefulSet, you can visit Kubernetes documentation https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/

By default, we create 2 replicas of hazelcast-caching microservice behind the hazelcast-caching-service which forwards requests to one of the pods available in the kubernetes cluster.

MY_POD_NAME is an environment variable made available to the pods so that each microservice knows which pod they are in. This is going to be used in this guide in order to show which pod is responding to the http request.

As a second step, we will create rbac.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: default-cluster
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: view
subjects:
  - kind: ServiceAccount
    name: default
    namespace: default

Role Based Access Controller(RBAC) configuration is used to give access to Kubernetes Master API from pods which runs microservices. Hazelcast requires a read access to autodiscover other hazelcast members and form hazelcast cluster.

Run the following commands to deploy the resources as defined in kubernetes.yaml and rbac.yaml in the specified order:

kubectl apply -f rbac.yaml
kubectl apply -f kubernetes.yaml

run the following command to check the status of your pods:

kubectl get pods

You’ll see an output similar to the following if all the pods are healthy and running:

NAME                              READY     STATUS    RESTARTS   AGE
hazelcast-caching-statefulset-0   1/1       Running   0          20m
hazelcast-caching-statefulset-1   1/1       Running   0          20m

You should also check if hazelcast cluster is formed by checking one of the pod’s log file:

kubectl logs hazelcast-caching-statefulset-1
Members {size:2, ver:2} [
        Member [172.17.0.4]:5701 - 71009ef7-ee18-45f0-8a8f-e9321931e9ce this
        Member [172.17.0.5]:5701 - 99222e16-93e5-4453-ac9e-cdf3e80069c6
]

Next you will make requests to your services.

WINDOWS | MAC

The default hostname for Docker Desktop is localhost.

LINUX

The default hostname for minikube is 192.168.99.100. Otherwise it can be found using the minikube ip command.

Open your favorite terminal and send http get requests in a loop via curl command. This request asks for the value of key=1 and prints value and which pod has replied to the request. You might need to wait up to 30 sec before microservices accepts traffic.

while true; do curl 192.168.99.100:31000/get?key=1;echo; sleep 2; done

You should see an output like below. The value is null because we have not put any data yet. podname shows that which kubernetes pod replied to the request.

{"value":null,"podName":"hazelcast-caching-statefulset-1"}
{"value":null,"podName":"hazelcast-caching-statefulset-1"}
{"value":null,"podName":"hazelcast-caching-statefulset-0"}
{"value":null,"podName":"hazelcast-caching-statefulset-1"}
{"value":null,"podName":"hazelcast-caching-statefulset-0"}

Break the current loop and put some data into hazelcast-caching microservice.

curl "http://192.168.99.100:31000/put?key=1&value=hazelcast_springboot_openliberty"

Although request has been executed by one specific kubernetes pod, by querying the data in a loop will show data the data is actually shared by multiple pods. To see this, execute following command again.

while true; do curl 192.168.99.100:31000/get?key=1;echo; sleep 2; done

As you can see both pods are returning the same data.

{"value":"hazelcast_springboot_openliberty","podName":"hazelcast-caching-statefulset-1"}
{"value":"hazelcast_springboot_openliberty","podName":"hazelcast-caching-statefulset-0"}
{"value":"hazelcast_springboot_openliberty","podName":"hazelcast-caching-statefulset-1"}
{"value":"hazelcast_springboot_openliberty","podName":"hazelcast-caching-statefulset-0"}
{"value":"hazelcast_springboot_openliberty","podName":"hazelcast-caching-statefulset-1"}

Scaling with Hazelcast

Scale the cluster with one more pod and see that you still retrieve the shared data.

kubectl scale statefulset hazelcast-caching-statefulset --replicas=3

Run following command to see the latest status of the pods

kubectl get pods

As you can see, a new pod hazelcast-caching-statefulset-2 has joined to the cluster.

NAME                              READY     STATUS    RESTARTS   AGE
hazelcast-caching-statefulset-0   1/1       Running   0          8m
hazelcast-caching-statefulset-1   1/1       Running   0          8m
hazelcast-caching-statefulset-2   1/1       Running   0          31s

Run the following command again to see the output

while true; do curl 192.168.99.100:31000/get?key=1;echo; sleep 2; done

As you can see, hazelcast-caching-statefulset-2 is returning correct data.

{"value":"hazelcast_springboot_openliberty","podName":"hazelcast-caching-statefulset-1"}
{"value":"hazelcast_springboot_openliberty","podName":"hazelcast-caching-statefulset-2"}
{"value":"hazelcast_springboot_openliberty","podName":"hazelcast-caching-statefulset-0"}

Testing microservices that are running on Kubernetes

Create a HazelcastCachingIT class.
src/test/java/it/io/openliberty/guides/hazelcast/HazelcastCachingIT.java

HazelcastCachingIT.java

 1/*
 2 * Copyright 2014-2016 the original author or authors.
 3 *
 4 * Licensed under the Apache License, Version 2.0 (the "License");
 5 * you may not use this file except in compliance with the License.
 6 * You may obtain a copy of the License at
 7 *
 8 *      http://www.apache.org/licenses/LICENSE-2.0
 9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package it.io.openliberty.guides.hazelcast;
17
18import io.openliberty.guides.hazelcast.CommandResponse;
19import org.junit.Assert;
20import org.junit.BeforeClass;
21import org.junit.Test;
22import org.springframework.http.HttpStatus;
23import org.springframework.http.ResponseEntity;
24import org.springframework.web.client.RestTemplate;
25
26
27public class HazelcastCachingIT {
28
29    private static String clusterUrl;
30
31
32    @BeforeClass
33    public static void oneTimeSetup() {
34        String clusterIp = System.getProperty("cluster.ip");
35        String nodePort = System.getProperty("cluster.port");
36        clusterUrl = "http://" + clusterIp + ":" + nodePort ;
37    }
38
39
40    @Test(timeout = 60000)
41    public void testHazelcastCache()
42            throws Exception {
43
44
45        String key = "1";
46        String value = "hazelcast-springboot-openliberty";
47
48        String put_url = String.format(clusterUrl +"/put?key=%s&value=%s", key, value);
49        RestTemplate rest = new RestTemplate();
50
51        ResponseEntity<CommandResponse> putResponse = rest.getForEntity(put_url, CommandResponse.class);
52        Assert.assertTrue(putResponse.getStatusCode() == HttpStatus.OK);
53
54        String firstPod = putResponse.getBody().getPodName();
55
56        //GET call to see data is coming from another pod
57        String get_url = String.format(clusterUrl+"/get?key=%s", key);
58
59        while (true) { // it will try every second until it timeouts in 60 seconds
60            ResponseEntity<CommandResponse> getResponse = rest.getForEntity(get_url, CommandResponse.class);
61            String secondPod = getResponse.getBody().getPodName();
62            if (!secondPod.equals(firstPod)) break; // we get the response from different pod so SUCCESS!!
63            Thread.sleep(1000);
64        }
65    }
66
67}

The testHazelcastCache test makes sure that the /put endpoint is handled by one pod and /get methods returns the same data from the other kubernetes pod.

It first puts a key/value pair to hazelcast-caching microservice and keeps podname in the firstpod variable. In the second part, tests submits multiple /get requests until to see that podname is different then the pod which initially handled /put request.

In order to run integration tests, you must have a running hazelcast-caching microservices in minikube environment. As you have gone through all previous steps, you already have it.

The default properties defined in the pom.xml are:

Property Description

cluster.ip

IP or hostname for your cluster, 192.168.99.100 by default, which is appropriate when using Minikube.

cluster.port

Port of the Kubernetes Service wrapping the hazelcast-caching pods, hazelcast-caching-service by default.

Navigate back to the start directory.

LINUX | MAC

Run the integration tests against a cluster running at the default Minikube IP address:

mvn verify

WINDOWS

Run the integration tests against a cluster running with a hostname of localhost:

mvn verify -Dcluster.ip=localhost

Run the integration tests against an external IP address and port, you can use cluster.ip and cluster.port based kubernetes service on your kubernetes cluster.

mvn verify -Dcluster.ip=192.168.99.100 -Dcluster.port=31000

If the tests pass, you’ll see a similar output to the following:

[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running it.io.openliberty.guides.hazelcast.HazelcastCachingIT
14:52:17.881 [Time-limited test] DEBUG org.springframework.web.client.RestTemplate - Created GET request for "http://192.168.99.100:31000/put?key=1&value=hazelcast-springboot-openliberty"
14:52:17.916 [Time-limited test] DEBUG org.springframework.web.client.RestTemplate - Setting request Accept header to [application/json, application/*+json]
14:52:17.989 [Time-limited test] DEBUG org.springframework.web.client.RestTemplate - GET request for "http://192.168.99.100:31000/put?key=1&value=hazelcast-springboot-openliberty" resulted in 200 (OK)
14:52:17.991 [Time-limited test] DEBUG org.springframework.web.client.RestTemplate - Reading [class io.openliberty.guides.hazelcast.CommandResponse] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@48e08f49]
14:52:18.007 [Time-limited test] DEBUG org.springframework.web.client.RestTemplate - Created GET request for "http://192.168.99.100:31000/get?key=1"
14:52:18.007 [Time-limited test] DEBUG org.springframework.web.client.RestTemplate - Setting request Accept header to [application/json, application/*+json]
14:52:18.048 [Time-limited test] DEBUG org.springframework.web.client.RestTemplate - GET request for "http://192.168.99.100:31000/get?key=1" resulted in 200 (OK)
14:52:18.048 [Time-limited test] DEBUG org.springframework.web.client.RestTemplate - Reading [class io.openliberty.guides.hazelcast.CommandResponse] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@48e08f49]
14:52:19.051 [Time-limited test] DEBUG org.springframework.web.client.RestTemplate - Created GET request for "http://192.168.99.100:31000/get?key=1"
14:52:19.052 [Time-limited test] DEBUG org.springframework.web.client.RestTemplate - Setting request Accept header to [application/json, application/*+json]
14:52:19.060 [Time-limited test] DEBUG org.springframework.web.client.RestTemplate - GET request for "http://192.168.99.100:31000/get?key=1" resulted in 200 (OK)
14:52:19.060 [Time-limited test] DEBUG org.springframework.web.client.RestTemplate - Reading [class io.openliberty.guides.hazelcast.CommandResponse] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@48e08f49]
14:52:20.069 [Time-limited test] DEBUG org.springframework.web.client.RestTemplate - Created GET request for "http://192.168.99.100:31000/get?key=1"
14:52:20.069 [Time-limited test] DEBUG org.springframework.web.client.RestTemplate - Setting request Accept header to [application/json, application/*+json]
14:52:20.122 [Time-limited test] DEBUG org.springframework.web.client.RestTemplate - GET request for "http://192.168.99.100:31000/get?key=1" resulted in 200 (OK)
14:52:20.122 [Time-limited test] DEBUG org.springframework.web.client.RestTemplate - Reading [class io.openliberty.guides.hazelcast.CommandResponse] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@48e08f49]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.714 s - in it.io.openliberty.guides.hazelcast.HazelcastCachingIT
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO]
[INFO] --- spring-boot-maven-plugin:2.1.3.RELEASE:stop (post-integration-test) @ hazelcast-caching ---
[INFO]
[INFO] --- maven-failsafe-plugin:2.21.0:verify (default) @ hazelcast-caching ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 12.470 s
[INFO] Finished at: 2019-03-04T14:52:20-05:00
[INFO] ------------------------------------------------------------------------

== Tearing down the environment

When you no longer need your deployed microservices, you can delete all Kubernetes resources by running the kubectl delete command: You might need to wait up to 30 seconds as stateful sets kills pods one at a time.

kubectl delete -f kubernetes.yaml

Nothing more needs to be done for Docker Desktop.

Perform the following steps to return your environment to a clean state.

  1. Point the Docker daemon back to your local machine:

    eval $(minikube docker-env -u)
  2. Stop your Minikube cluster:

    minikube stop
  3. Delete your cluster:

    minikube delete

== Great work! You’re done!

You have just created a Spring Boot application, bundled it with openliberty and deployed to Kubernetes. You then added Hazelcast caching to the hazelcast-caching,tested with a simple curl command. You also scaled out the microservices and saw that data is shared between microservices As a last step, you ran integration tests against hazelcast-caching that was deployed in a Kubernetes cluster.

== Contribute to this guide

Is something missing or broken? Raise an issue, or send us a pull request.

Great work! You're done!

What did you think of this guide?

Extreme Dislike Dislike Like Extreme Like

What could make this guide better?

Raise an issue to share feedback

Create a pull request to contribute to this guide

Need help?

Ask a question on Stack Overflow

Like Open Liberty? Star our repo on GitHub.

Star

Guide license