Containerization
How to use Docker, Kubernetes, and Helm Charts to deploy your VLINGO XOOM platform services.
The following shows how to set up a Reactive, scalable, event-driven application based for VLINGO XOOM, being deployed on Kubernetes and packaged by Helm Chart.

Quick start with VLINGO XOOM

First, we need a project structure that allows us to start building our application. That's when XOOM Designer comes to play. It saves a lot of effort providing a web/graphical user interface to generate initial development resources such as application files, directory structure, Dockerfile and much more. Once it is installed, you can use the project generator wizard running the following command:
1
$ ./xoom gui
Copied!
This command will open your preferred browser. Just fill in the wizard steps so the project will be generated and ready to start the development.

Building the Docker image

If you choose either Docker or Kubernetes on the deployment step, a Dockerfile will be placed in the root folder:
1
FROM adoptopenjdk/openjdk11-openj9:jdk-11.0.1.13-alpine-slim
2
COPY target/xoom-example-*.jar xoom-example.jar
3
EXPOSE 8080
4
CMD java -Dcom.sun.management.jmxremote -noverify ${JAVA_OPTS} -jar xoom-example.jar
Copied!
That means the image is ready to be built along with the executable jar. Both tasks are performed through a single Starter CLI command:
1
$ ./xoom docker package
Copied!
Now, let's tag and publish this local image into Docker Hub.
1
$ ./xoom docker push
Copied!
You can find more information on xoom docker push and other containerization shortcut commands here.

Alternative Without VLINGO XOOM

The previous steps are pretty similar for a VLINGO XOOM service or application without VLINGO XOOM. The executable jar, including the dependency jars, can be generated with the following plugin configuration:
1
<plugin>
2
<groupId>org.codehaus.mojo</groupId>
3
<artifactId>exec-maven-plugin</artifactId>
4
<version>1.6.0</version>
5
<executions>
6
<execution>
7
<goals>
8
<goal>java</goal>
9
</goals>
10
</execution>
11
</executions>
12
<configuration>
13
<mainClass>io.vlingo.xoom.app.infra.Bootstrap</mainClass>
14
</configuration>
15
</plugin>
16
<plugin>
17
<artifactId>maven-assembly-plugin</artifactId>
18
<executions>
19
<execution>
20
<phase>package</phase>
21
<goals>
22
<goal>single</goal>
23
</goals>
24
</execution>
25
</executions>
26
<configuration>
27
<finalName>vlingo-xoom-app</finalName>
28
<descriptors>
29
<descriptor>assembly.xml</descriptor>
30
</descriptors>
31
<archive>
32
<manifest>
33
<addClasspath>true</addClasspath>
34
<mainClass>io.vlingo.xoom.app.infra.Bootstrap</mainClass>
35
<classpathPrefix>dependency-jars/</classpathPrefix>
36
</manifest>
37
</archive>
38
</configuration>
39
</plugin>
Copied!
The Dockerfile requires the jar with dependencies:
1
FROM adoptopenjdk/openjdk11-openj9:jdk-11.0.1.13-alpine-slim
2
COPY target/vlingo-xoom-app-withdeps.jar vlingo-xoom-app.jar
3
EXPOSE 8082
4
CMD java -Dcom.sun.management.jmxremote -noverify ${JAVA_OPTS} -jar vlingo-xoom-app.jar
Copied!
Now, besides the application itself, the Docker image is ready to be built and published:
1
$ ./mvn clean package && docker build ./ -t vlingo-xoom-app:latest
2
$ ./docker tag vlingo-xoom-app:latest [publisher]/vlingo-xoom-app:latest
3
$ ./docker push [publisher]/vlingo-xoom-app
Copied!

Kubernetes Deployment

Kubernetes is the chosen tool for container orchestration. In this scenario, it will run a single node cluster serving the VLINGO XOOM application. Whereas kubeadm is installed, the cluster initialization is showed below:
1
$ ./sudo kubeadm init --pod-network-cidr=192.168.0.0/16
Copied!
Secondly, the settings folder should be mapped:
1
$ ./mkdir -p $HOME/.kube
2
$ ./sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
3
$ ./sudo chown $(id -u):$(id -g) $HOME/.kube/config
Copied!
Kubernetes supports multiple networking model implementations. For now, we choose Calico. Its network policy configuration file can be added using kubectl, the command line tool for controlling Kubernetes clusters:
1
$ ./kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
Copied!
Considering the single node cluster is the option for this example, the last step is to prepare the master node by removing taints which, in short, prevents a deployable unit (Pods) to run on it.
1
$ ./kubectl taint nodes --all node-role.kubernetes.io/master-
Copied!

Management and Deployment With Helm Chart

At this point, we need to tell Kubernetes what is the application desired state and how we want to expose our services, number of replicas, allocated resources... The simpler way is through Helm, a special tool for Kubernetes application management. It simplifies installation, upgrade, scaling and other common tasks. Getting started, let's create a chart, which is a collection of files inside of a directory. This is how it's made:
1
$ ./helm create xoom-example
Copied!
The output looks like the following structure:
1
xoom-example/
2
Chart.yaml # A YAML file containing information about the chart
3
LICENSE # OPTIONAL: A plain text file containing the license for the chart
4
README.md # OPTIONAL: A human-readable README file
5
values.yaml # The default configuration values for this chart
6
values.schema.json # OPTIONAL: A JSON Schema for imposing a structure on the values.yaml file
7
charts/ # A directory containing any charts upon which this chart depends.
8
crds/ # Custom Resource Definitions
9
templates/ # A directory of templates that, when combined with values,
10
# will generate valid Kubernetes manifest files.
11
templates/NOTES.txt # OPTIONAL: A plain text file containing short usage notes
Copied!
In this basic scenario, all we need to do is editing values.yaml , informing the Docker image repository, service type / port and number of replicas:
1
# Default values for xoom-example.
2
# This is a YAML-formatted file.
3
# Declare variables to be passed into your templates.
4
5
replicaCount: 3
6
7
image:
8
repository: [publisher]/xoom-example
9
10
...
11
12
service:
13
type: ClusterIP
14
port: 8080
Copied!
Using lint, we can check if the chart is well-formed after the addition:
1
$ ./helm lint xoom-example
2
3
==> Linting xoom-example
4
[INFO] Chart.yaml: icon is recommended
5
6
1 chart(s) linted, 0 chart(s) failed
7
Copied!
With template command, we can see all files that Helm will generate and install into Kubernetes:
1
# Source: xoom-example/templates/serviceaccount.yaml
2
apiVersion: v1
3
kind: ServiceAccount
4
metadata:
5
name: RELEASE-NAME-xoom-example
6
labels:
7
helm.sh/chart: xoom-example-0.1.0
8
app.kubernetes.io/name: xoom-example
9
app.kubernetes.io/instance: RELEASE-NAME
10
app.kubernetes.io/version: "1.16.0"
11
app.kubernetes.io/managed-by: Helm
12
---
13
# Source: xoom-example/templates/service.yaml
14
apiVersion: v1
15
kind: Service
16
metadata:
17
name: RELEASE-NAME-xoom-example
18
labels:
19
helm.sh/chart: xoom-example-0.1.0
20
app.kubernetes.io/name: xoom-example
21
app.kubernetes.io/instance: RELEASE-NAME
22
app.kubernetes.io/version: "1.16.0"
23
app.kubernetes.io/managed-by: Helm
24
spec:
25
type: ClusterIP
26
ports:
27
- port: 8080
28
targetPort: http
29
protocol: TCP
30
name: http
31
selector:
32
app.kubernetes.io/name: xoom-example
33
app.kubernetes.io/instance: RELEASE-NAME
34
---
35
# Source: xoom-example/templates/deployment.yaml
36
apiVersion: apps/v1
37
kind: Deployment
38
metadata:
39
name: RELEASE-NAME-xoom-example
40
labels:
41
helm.sh/chart: xoom-example-0.1.0
42
app.kubernetes.io/name: xoom-example
43
app.kubernetes.io/instance: RELEASE-NAME
44
app.kubernetes.io/version: "1.16.0"
45
app.kubernetes.io/managed-by: Helm
46
spec:
47
replicas: 3
48
selector:
49
matchLabels:
50
app.kubernetes.io/name: xoom-example
51
app.kubernetes.io/instance: RELEASE-NAME
52
template:
53
metadata:
54
labels:
55
app.kubernetes.io/name: xoom-example
56
app.kubernetes.io/instance: RELEASE-NAME
57
spec:
58
serviceAccountName: RELEASE-NAME-xoom-example
59
securityContext:
60
{}
61
containers:
62
- name: xoom-example
63
securityContext:
64
{}
65
image: "xoom-example:1.16.0"
66
imagePullPolicy: IfNotPresent
67
ports:
68
- name: http
69
containerPort: 8080
70
protocol: TCP
71
livenessProbe:
72
httpGet:
73
path: /
74
port: http
75
readinessProbe:
76
httpGet:
77
path: /
78
port: http
79
resources:
80
{}
81
---
82
# Source: xoom-example/templates/tests/test-connection.yaml
83
apiVersion: v1
84
kind: Pod
85
metadata:
86
name: "RELEASE-NAME-xoom-example-test-connection"
87
labels:
88
helm.sh/chart: xoom-example-0.1.0
89
app.kubernetes.io/name: xoom-example
90
app.kubernetes.io/instance: RELEASE-NAME
91
app.kubernetes.io/version: "1.16.0"
92
app.kubernetes.io/managed-by: Helm
93
annotations:
94
"helm.sh/hook": test-success
95
spec:
96
containers:
97
- name: wget
98
image: busybox
99
command: ['wget']
100
args: ['RELEASE-NAME-xoom-example:8080']
101
restartPolicy: Never
102
Copied!
We finish the deployment step executing the install command:
1
$ ./helm install xoom-example
Copied!
A new Pod is created by Kubernetes to hold the xoom-example app. You should check if it's running fine:
1
$ ./kubectl get pods
2
3
NAME READY STATUS RESTARTS AGE
4
xoom-example-765bf4c7b4-26z48 1/1 Running 0 64s
Copied!
Also, it is recommended to check the application logs:
1
$ ./kubectl logs xoom-example-765bf4c7b4-26z48
Copied!
Helm also supports a packaging and versioning mechanism, that is, a set of commands that allows us to package the Chart structure and files to make it collaborative. First, an index.yaml file should be created based on a Git repository, that will be the chart repository:
1
$ ./helm repo index chart-repo/ --url https://<username>.github.io/chart-repo
Copied!
Next, the remote repository is added:
1
$ ./helm repo add chart-repo https://<username>.github.io/chart-repo
Copied!
At last, enable the chart installation from the repository:
1
$ ./helm install my-repo/hello-world --name=hello-world
Copied!

More information

Find a complete code example on GitHub, built on a DDD microservices architecture, combining Kubernetes, Helm Chart and VLINGO XOOM.
Last modified 6mo ago