This article shows you how to deploy a containerized microservice on a Kubernetes platform using Jenkins.
The article covers:
Microservices structure an application into several modular services
Containers are a good way to develop and deploy microservices, and the platforms for running containers are a good way to manage microservice-based applications
Docker is an open-source platform that is used to create, deploy, and run applications by using containers
Kubernetes is an open-source system for automating deployment, scaling, and the operations of application containers across clusters of hosts
This is a continuation of the Talend Community Knowledge Base article, Continuous Integration and Continuous Deployment of data services, routes, and microservices.
Sources for the project are available in the attached Zip file.
Install the software and configure the servers:
Create three VMs and install Ubuntu Linux 18.04.
Name the servers ciserver, adminserver, and executionserver respectively.
In the /etc/hosts file, map the domain name of the server to the given IP address.
sudo vi /etc/hosts
## Execution server settings ##
## Admin server settings ##
## CI server settings ##
On the ciserver, install the following:
Latest patches for Talend CommandLine and Studio
On the adminserver, install the following:
Talend Administration Center
Install Git and create a repository, for example, CI_ESB_DEMOS
On the executionserver, install the following:
Microk8s (single node Kubernetes cluster with Docker and built-in registry)
Steps in this article require minimal knowledge of Docker and Kubernetes.
Steps in this article can be executed on any Linux OS.
For information on installing Talend Software modules on the adminserver, see Talend Data Services Platform Installation Guide for Linux on the Talend Help Center.
For information on installing Docker and Kubernetes on Ubuntu, see the Microk8s documentation.
Containerization of Talend microservices
Fabric8 Maven plugin (f8-m-p)
The fabric8-maven-plugin (f8-m-p) supports multiple configuration models to create Docker images and Kubernetes resources descriptors for Java applications. This tutorial leverages two popular models:
Resource Fragments (external configuration files)
For more information on configuration models, see the Maven fabric8-maven-plugin documentation, and scroll down to the 1.3. Configuration section.
Building Docker images using XML Configuration
f8-m-p provides an XML-based configuration for creating Docker files or to include external Docker files and assemble the Java build into a Docker image.
With Talend Studio, the Docker profile build and push goals are invoked during the Maven deploy phase.
Build artifacts (Talend Jobs) and assemble the build into a Docker image. The Docker image name can be specified with the <name> tag.
Push uploads the image to a registry.
Generating Kubernetes resources using XML Configuration
Using XML Configuration, you can create Kubernetes API objects, such as labels, secrets, and services.
Generating Kubernetes resources using Resource Fragments
Resource fragment models allow expert users to use plain configuration files, such as YAML. A YAML file specifies a skeleton and allows you to create complex Kubernetes / OpenShift API objects. F8-m-p can resolve a Maven XML configuration, pick up the resource files, and further enrich the configuration into a single kubernetes.yml and openshift.yml file.
The flowchart shows you how f8-m-p generates Kubernetes resource descriptors.
Objectives and logical architecture
Configure Jenkins for Docker and Kubernetes integration
Create a pipeline Job that builds a microservice as a Docker image, then publishes it to the Docker registry
Change Talend Studio plug-in
Create a new Maven profile with XML Configuration
Use Resource Fragments or external resources (YAML files)
Create a pipeline Job that builds a microservice as a Docker image, generates Kubernetes resources, and finally deploys the service to a Kubernetes engine
Verify the deployment using Kubectl commands and from Kubernetes dashboard
Configuring Jenkins for Docker and Kubernetes integration
Jenkins needs additional tools and configurations to generate Docker images and a Kubernetes deployment. To accomplish this, you will do the following:
Use Manage Plugins to install additional plug-ins for Docker
Configure System parameters, for example, Docker registry and Kubeconfig
Configure Credentials, for example, Docker
In the Manage Jenkins view, select Manage Plugins.
Select the Available tab.
Select and install the Docker plug-in.
Install the core plugins as described in the Continuous Integration and Continuous Deployment of data services, routes, and microservices article of this series.
In the Manage Jenkins view, click Configure System and configure your system variables and Docker registry settings.
Configure the KUBECONFIG environment variable that allows Jenkins to communicate with a Kubernetes cluster on a remote server.
Log in to the executionserver.
Copy the kubelet.config file of the Microk8s Kubernetes instance.
Note: In Microk8s the kubelet.config file is located at /snap/microk8s/current/microk8s-resources.
In Minikube the config file is located at ~/.kube/config.
Log in to the CI server as Jenkins user.
Copy the kubelet.config file from the Jenkins home folder, for example, /var/lib/jenkins.
Navigate to Pipeline Model Definition to configure the Docker registry URL and credentials.
Note: Follow the steps in the Git credentials section of the Continuous Integration and Continuous Deployment of data services, routes, and microservices article of this series, and configure your Docker registry credentials.
Configure the PATH+extra environmental variable, as described in the Continuous Integration and Continuous Deployment of data services, routes, and microservices article of this series.
Creating a Jenkins Job: build a microservice Docker image and publish to Docker registry
Click New Item, enter the name of the pipeline, for example, Pipeline_DemoRestRoute_Docker, then click Pipeline and click OK.
In the Description field, provide the purpose of this pipeline.
Click Build Triggers, select Poll SCM, for example, every night.
Click Pipeline, then select pipeline script from the Definition drop-down menu. Copy the contents of the groovy script, Pipeline_k8s_deploy.groovy, attached to this article, into the script area.
Value of DOCKER_HOST environment variable is set with the URL of the Docker daemon which is running on the execution server.
Maven profile used, for example, -pdocker.
Docker CLI options, for example, -Ddocker.push.username.
Save the file, then click Build now.
Verify the run in the Blue Ocean pipeline.
After successful execution, the pipeline status turns to green.
Verify that the image is created in the Docker registry.
Log in to the executionserver and verify the image, using the following command:
Run the container msdemorestroute, using the following command:
docker run -p 8065:8065 msdemorestroute
Test the microservice, by typing the following URL into your browser.
Configuring Talend Studio for generating Kubernetes resources
Create a new Maven profile, called k8s, with the XML Configuration model to store Docker images and Kubernetes resource objects. The k8s profile should execute resource, push, and deploy goals during the Maven deploy phase.
Resource creates Kubernetes and OpenShift resource descriptors leveraging XML Configuration and resource fragments models.
Push uploads the image specified in the <name> tag to a registry.
Deploy applies Kubernetes resource descriptors to the cluster and deploys the containerized microservice.
Creating a new Maven profile k8s
Connect to Talend Studio remote Project.
Click File > Edit project properties to open the Project Settings dialog box.
Select Build > Maven > Default from the navigation menu on the left, to open the Project POM settings.
Note: Backup the original POM settings before making any changes.
Search for the Maven profile ID, docker, in the Project POM settings.
Append the new profile, k8s, in the profile_k8s.xml file attached to this article, after the docker profile.
Including external files or Resource Fragments
In this article, external descriptors are stored in a Git repository, for example, CI_ESB_DEMOS. Jenkins can check out the Kubernetes resources along with the Talend project.
Create two files for resources, Deployment.yml and Service.yml. Both files in the ZIP file attached to this article.
Notice the mapping to the external resources file with XML element <resourceDir>, in the k8s profile shown below:
Review the contents of the deployment.yml file.
Review the contents of the service.yml file.
Creating a Jenkins pipeline: build a microservice Docker image and deploy to a Kubernetes engine
Click New Item, enter the name of the pipeline, for example, Pipeline_Microservice_DemoRestRoute_Docker_k8s, click Pipeline, then select the pipeline you created in the previous step. Click OK.
Update the Description of the pipeline.
Click Pipeline, then select pipeline script from the Definition drop-down menu. Copy the contents of the groovy script, Pipeline_docker_register_deploy.groovy, attached to this article, into the script area.
Click Build now and run the pipeline.
Click the pipeline and observe the generated artifacts.
Testing the containerized microservice on the Kubernetes platform
Using Kubernetes dashboard
Log in to the executionserver.
In Microk8s, install the Kubernetes dashboard, by entering the following command:
microk8s.enable dns dashboard
Get the ClusterIP and Port of the kubernetes-dashboard service, by issuing the below command:
kubectl get svc --all-namespaces
To see the dashboard; type the following URL into your browser, then accept any security exceptions, and skip the security settings
From the dashboard, navigate to the Overview screen, then review the status of Deployments, Pods, Replica sets, Services, and Secrets.
Using Kubectl commands
Log in to the executionserver.
Verify the status of your Deployments, by using the kubectl command along with a label, in this case, -l environment, as shown below:
kubectl get deployments -l environment -o wide
Verify the response from the kubectl command, and observe the Selector, in this case, environment=dev.
Get the ClusterIP and Port, by entering the following command:
kubectl get svc -l environment=dev
Open a browser window on the executionserver and call the microservice with Cluster-IP, as shown below:
Get the pod or container IP, by entering the following command:
kubectl get pods -l environment=dev -o wide
From a browser window on the executionserver, call the microservice with Container-IP and ContainerPort, as shown below:
Configuring Liveness and Readiness probes
Talend microservices supports JMX and Spring Actuator that enables you to monitor the health of the service using the context path, /health. In a containerized environment health checks help you to identify the health of the Container or Pod and determine when to restart the Container.
Using the Pod IP and port 8080 check the health of the service.
On the Overview screen, click Deployments, select the ellipsis to the right of msdemorestroute. In the Scale a Deployment dialog box set the Desired number of pods to 0. Click OK.
Notice that the running Pod or the Container is undeployed and the count changes to 0.
From the Overview screen, click Deployments > View/edit YAML, and change the initialdelayseconds to 1, then click Update.
From the Overview screen, click Deployments, and set Scale a Deployment to 1. Click Update. After the update, notice that the health of Deployments and Pods has changed to red.
The Container status changed to red, and the Readiness Probe failed because the Container is still in Creation mode, because the configuration of initialdelayseconds that is set to 1.
The next health check is done again after a delay of 10 secs.
Now if the Container is up, the status turns green.
Frequently Asked Questions
Question: Why use two configuration models to generate resource descriptors?
Answer: The XML Configuration model allows for type-safe configuration with IDE support. However, it only allows you to configure a subset of possible Kubernetes resource descriptors. For example, the XML Configuration model doesn't allow you to configure the resource descriptors for all API objects, such as, Deployments and Selectors.
Question: Can I build a Docker image using external Docker files?
Answer: Yes. In the <image> element you can refer to external Docker files with the elements dockerFile and dockerFileDir.
Question: Can I create or configure a Secret for sensitive information like credentials?
Answer: Yes. The <secret> element can be configured using XML Configuration or Resource Fragments.
Question: Can I add labels with XML Configuration?
Answer: Yes. Use the <resources> element to add labels, for example:
The <all> element allows you to create a label on all resource objects, such as Pods, Services, Deployments, and Replicasets.
The name and value of the labels can be passed dynamically from the Jenkins Job, labels such as environment = dev and module = xyz.
Question: Which additional features are brought in by Enrichers?
Answer: Enrichers are used to create and customize Kubernetes and OpenShift resource objects. They are looked up automatically from the plug-in dependencies and the add more features to the generated skeleton. For example, it adds health checks for spring boot microservices if the spring-boot JAR is present as a dependency.
Question: Can I include or exclude a set of Enrichers?
Answer: Yes. The element <enrichers> excludes labels from fmp-project and adds default labels like artifactId, groupid, version, and provider.
Question: How are the health checks performed on a containerized microservice?
Answer: Enricher f8-healthcheck-spring-boot generates resource descriptors for performing Kubernetes Liveness and Readiness probes on spring-boot containers.
In this article, you leveraged Talend Studio and the f8-m-p plug-in to create Maven profiles for Docker and k8s. You created a Docker image and generated Kubernetes resources for a microservice, then with a Jenkins pipeline script, you published the microservice container to a Docker registry and deployed Kubernetes resources to a Kubernetes engine. Finally, you tested the microservice with Container IP, Cluster IP, and verified Liveness and Readiness probes.