DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Enterprise AI Trend Report: Gain insights on ethical AI, MLOps, generative AI, large language models, and much more.

2024 Cloud survey: Share your insights on microservices, containers, K8s, CI/CD, and DevOps (+ enter a $750 raffle!) for our Trend Reports.

PostgreSQL: Learn about the open-source RDBMS' advanced capabilities, core components, common commands and functions, and general DBA tasks.

AI Automation Essentials. Check out the latest Refcard on all things AI automation, including model training, data security, and more.

Related

  • Automate Application Load Balancers With AWS Load Balancer Controller and Ingress
  • Building the World's Most Resilient To-Do List Application With Node.js, K8s, and Distributed SQL
  • 7 Ways of Containerizing Your Node.js Application
  • Dynatrace Perform: Day Two

Trending

  • Types of Data Breaches in Today’s World
  • Building Safe AI: A Comprehensive Guide to Bias Mitigation, Inclusive Datasets, and Ethical Considerations
  • AI-Driven API and Microservice Architecture Design for Cloud
  • Why You Should Move From Monolith to Microservices
  1. DZone
  2. Software Design and Architecture
  3. Cloud Architecture
  4. Write Kubernetes Native Application Using Camel K: Part 1

Write Kubernetes Native Application Using Camel K: Part 1

By 
Chandra Shekhar Pandey user avatar
Chandra Shekhar Pandey
·
Oct. 01, 20 · Tutorial
Like (4)
Save
Tweet
Share
3.6K Views

Join the DZone community and get the full member experience.

Join For Free

Apache Camel K is integration framework based on ubiquitous Apache Camel.  Camel K differs from Apache Camel, as Camel K is native to Kubernetes, while Apache Camel runs almost everywhere. But why Camel K is required? The following bullet points makes Camel K more favorable in Kubernetes or an OpenShift Environment:

  • Low code and Quick deployment.
  • Cloud Native Camel on Kubernetes
  • Designed for Serverless and MicroService architecture.
  • Can be written in YAML, JAVA, XML, Groovy, Javascript, Kotlin.
  • Exchange K-Native Eventing events.

I will try to write a series of Technology blogs on Camel K. This is the first one. This article would be simple but will cover important aspects.

Camel K provides a CLI tool, kamel, which can be run from Linux/Mac shell or Windows OS. It can be download from Camel K release page. It contains a binary named kamel that you should put into system path. For example, if you’re using Linux, you can put kamel in /usr/bin.

Step 1 : Firstly we have to install Camel-k operator with command "kamel install".  This commands intall Camel-k operator and customer resources.

I have used Fedora 32 and minikube v1.9.2. So let us start actual work.

Shell
xxxxxxxxxx
1
50
 
1
# start minishift with profile camelkprofile
2
[chandrashekhar@localhost camel-k-client]$ minikube start -p camelkprofile --cpus=2 --memory='5g'
3
4
# set local docker registry to point to minikube docker registry with profile camelkprofile
5
[chandrashekhar@localhost camel-k-client]$ eval $(minikube -p camelkprofile docker-env)
6
7
# enable registry addon
8
[chandrashekhar@localhost camel-k-client]$ minikube addons enable registry -p camelkprofile
9
��  The 'registry' addon is enabled
10
11
# check kamel in system path
12
[chandrashekhar@localhost camel-k-client]$ which kamel
13
/usr/bin/kamel
14
15
# create a namespace camelk-namespace, where we will deploy our application.
16
[chandrashekhar@localhost camel-k-client]$ kubectl create ns camelk-namespace
17
namespace/camelk-namespace created
18
19
# set current namespace context to camelk-namespace with this we don't have to specify namespace for each command
20
[chandrashekhar@localhost camel-k-client]$ kubectl config set-context $(kubectl config current-context) --namespace=camelk-namespace
21
Context "camelkprofile" modified.
22
23
# currently there are no pods in namespace
24
[chandrashekhar@localhost camel-k-client]$ kubectl get pods
25
No resources found in camelk-namespace namespace.
26
27
# install camel-k operator now
28
[chandrashekhar@localhost camel-k-client]$ kamel install
29
Camel K installed in namespace camelk-namespace
30
31
# check pods now, we will find camel-k operator now
32
[chandrashekhar@localhost camel-k-client]$ kubectl get pods
33
NAME                                READY   STATUS    RESTARTS   AGE
34
camel-k-operator-7df56fc69b-qvldd   1/1     Running   0          7m29s
35
36
# at present no integration is installed
37
[chandrashekhar@localhost camel-k-client]$ kubectl get it
38
No resources found in camelk-namespace namespace.
39
40
# at present no integration platform is installed
41
[chandrashekhar@localhost camel-k-client]$ kubectl get ip
42
NAME      PHASE
43
camel-k   Ready
44
45
# following configmap are there.
46
[chandrashekhar@localhost camel-k-client]$ kubectl get configmap
47
NAME                     DATA   AGE
48
camel-k-lock             0      94s
49
camel-k-maven-settings   1      93s
50
[chandrashekhar@localhost camel-k-client]$  


Step 2 : Deploy Camel K application. 

Let us create a simple Camel  K application in Java CamelkPoc.java.

Java
xxxxxxxxxx
1
14
 
1
import org.apache.camel.builder.RouteBuilder;
2
  
3
public class CamelkPoc extends RouteBuilder {
4
    @Override
5
    public void configure() throws Exception {
6
7
        from("timer:java?period=10000")
8
        .routeId("java")
9
        .setBody()
10
            .simple("Hello Camel K from ${routeId} and {{message}}")
11
        .to("log:info");
12
    }
13
}
14


Step 3 : Now, let us run the application in dev mode. In dev mode, we should not close the original terminal. That terminal which is running the application or integration will also undeploy as soon as it's closed. In dev mode, we can change integration at runtime.

Shell
xxxxxxxxxx
1
32
 
1
[chandrashekhar@localhost kamelpoc]$ kamel run CamelkPoc.java -p message="parameter from commandline" --dev
2
3
# From different terminal run following command
4
[chandrashekhar@localhost ~]$ kubectl get pods
5
NAME                                READY   STATUS    RESTARTS   AGE
6
camel-k-operator-7df56fc69b-qvldd   1/1     Running   0          54m
7
8
# Still we see only operator pod but not application/integration pod. This could be because all dependencies of integration/application is being installed. Check operator logs to verify this.
9
[chandrashekhar@localhost ~]$ kubectl logs -f camel-k-operator-7df56fc69b-qvldd
10
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/wildfly/common/wildfly-common/1.5.4.Final-format-001/wildfly-common-1.5.4.Final-format-001.jar (307 kB at 15 kB/s)
11
[INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/eclipse/microprofile/context-propagation/microprofile-context-propagation-api/1.0.1/microprofile-context-propagation-api-1.0.1.jar
12
[INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/graalvm/sdk/graal-sdk/20.1.0/graal-sdk-20.1.0.jar (536 kB at 25 kB/s)
13
14
# Finally after few minutes
15
[chandrashekhar@localhost ~]$ kubectl get pods
16
NAME                                READY   STATUS    RESTARTS   AGE
17
camel-k-operator-7df56fc69b-qvldd   1/1     Running   0          65m
18
camelk-poc-66fd9585cf-lj4rr         1/1     Running   0          62s
19
20
# Ensure that integration and integration-platform are in Running and Ready state respectively. If not than might be integration/application is still installing.
21
[chandrashekhar@localhost ~]$ kubectl get it
22
NAME         PHASE     KIT                        REPLICAS
23
camelk-poc   Running   kit-btjjsi5pu87knpm77nmg   1
24
[chandrashekhar@localhost ~]$ kubectl get ip
25
NAME      PHASE
26
camel-k   Ready
27
[chandrashekhar@localhost ~]$ 
28
29
# Check logs of application/integration pod.
30
[chandrashekhar@localhost ~]$ kubectl logs -f camelk-poc-66fd9585cf-lj4rr
31
2020-09-20 11:58:50.050 INFO  [Camel (camel-k) thread #0 - timer://java] info - Exchange[ExchangePattern: InOnly, BodyType: String, Body: Hello Camel K from java and parameter from commandline]
32
2020-09-20 11:59:00.051 INFO  [Camel (camel-k) thread #0 - timer://java] info - Exchange[ExchangePattern: InOnly, BodyType: String, Body: Hello Camel K from java and parameter from commandline]


Step 4: Let us now make changes to code at runtime.

Shell
xxxxxxxxxx
1
13
 
1
# Edit text with "Modified" in CamelkPoc.java without stopping any integration or terminal.
2
.simple("Hello Modified Camel K from ${routeId} and {{message}}")
3
4
# We will find a new pod is created but logs of pods will be printed/logged in same terminal where we were earlier monitoring logs.
5
[chandrashekhar@localhost camel-k-client]$ kubectl get pod
6
NAME                                READY   STATUS    RESTARTS   AGE
7
camel-k-operator-7df56fc69b-qvldd   1/1     Running   0          121m
8
camelk-poc-cf8dd47b-5z65v           1/1     Running   0          98s
9
10
# Check pod logs in same terminal defined in step 3.
11
[2] 2020-09-20 12:40:26.515 INFO  [Camel (camel-k) thread #0 - timer://java] info - Exchange[ExchangePattern: InOnly, BodyType: String, Body: Hello Modified Camel K from java and parameter from commandline]
12
[2] 2020-09-20 12:40:36.515 INFO  [Camel (camel-k) thread #0 - timer://java] info - Exchange[ExchangePattern: InOnly, BodyType: String, Body: Hello Modified Camel K from java and parameter from commandline]


Step 5 Camel K Resource Visualization: This application is running in dev mode, and any changes are reflected at runtime. The user or developer is only concerned with their application. Other details like Camel-k Operator and Custom Resource are abstracted away or hidden from the user. Some of these abstract components are described below.

Camel K resource visualization

  

Integration Platform (kubectl get ip): It is a one generic configuration for all the integrations. It is having information like maven's settings.xml from where the maven artifacts are installed. If we note below commands than we find that settings.xml is mounted as configmap camel-k-maven-settings.

Shell
xxxxxxxxxx
1
20
 
1
[chandrashekhar@localhost camel-k-client]$  kubectl get ip camel-k -o yaml|grep -i -A 1 -B 1 settings.xml
2
        configMapKeyRef:
3
          key: settings.xml
4
          name: camel-k-maven-settings
5
[chandrashekhar@localhost camel-k-client]$ kubectl get configmap|grep settings
6
camel-k-maven-settings       1      80m
7
[chandrashekhar@localhost camel-k-client]$ kubectl describe configmap camel-k-maven-settings |head -n 20|tail -n 11
8
<?xml version="1.0" encoding="UTF-8"?>
9
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
10
  <localRepository></localRepository>
11
  <profiles>
12
    <profile>
13
      <id>maven-settings</id>
14
      <activation>
15
        <activeByDefault>true</activeByDefault>
16
      </activation>
17
      <repositories>
18
        <repository>
19
[chandrashekhar@localhost camel-k-client]$ 
20


Integration(kubectl get it): There is one integration for each of our application/integration installed. If we describe this integration than we will find that it contains the code(or camel route) details and also dependencies of application. 

Shell
xxxxxxxxxx
1
76
 
1
[chandrashekhar@localhost camel-k-client]$ kubectl get it
2
NAME         PHASE     KIT                        REPLICAS
3
camelk-poc   Running   kit-btjjsi5pu87knpm77nmg   1
4
5
# Describe integration and we can find code details.
6
[chandrashekhar@localhost camel-k-client]$ kubectl describe it camelk-poc |grep -A 15 Sources
7
  Sources:
8
    Content:  import org.apache.camel.builder.RouteBuilder;
9
10
public class CamelkPoc extends RouteBuilder {
11
    @Override
12
    public void configure() throws Exception {
13
14
        from("timer:java?period=10000")
15
        .routeId("java")
16
        .setBody()
17
            .simple("Hello Camel K from ${routeId} and {{message}}")
18
        .to("log:info");
19
    }
20
}
21
22
    Name:  CamelkPoc.java
23
    
24
# We can also see camel dependencies involved to run this application.    
25
[chandrashekhar@localhost camel-k-client]$ kubectl describe it camelk-poc |grep -A 5 Dependencies
26
  Dependencies:
27
    camel:log
28
    camel:timer
29
    mvn:org.apache.camel.k/camel-k-loader-java
30
    mvn:org.apache.camel.k/camel-k-runtime-main
31
  Digest:            vPcZSWphLbNfrwmlkSMZ9aNDtza8oNWjhfsL7WZYbo0I
32
[chandrashekhar@localhost camel-k-client]$ 
33
34
# Further this code and application.properties if any are also mounted as configmap.
35
[chandrashekhar@localhost camel-k-client]$ kubectl get deployment
36
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
37
camel-k-operator   1/1     1            1           98m
38
camelk-poc         1/1     1            1           33m
39
[chandrashekhar@localhost camel-k-client]$ 
40
41
[chandrashekhar@localhost camel-k-client]$ kubectl get deployment camelk-poc -o yaml|grep -A 6 -i "configMap:"
42
      - configMap:
43
          defaultMode: 420
44
          items:
45
          - key: content
46
            path: CamelkPoc.java
47
          name: camelk-poc-source-000
48
        name: i-source-000
49
      - configMap:
50
          defaultMode: 420
51
          items:
52
          - key: application.properties
53
            path: user.properties
54
          name: camelk-poc-user-properties
55
        name: user-properties
56
57
[chandrashekhar@localhost camel-k-client]$ kubectl get cm camelk-poc-source-000 -o yaml
58
apiVersion: v1
59
data:
60
  content: |
61
    import org.apache.camel.builder.RouteBuilder;
62
63
    public class CamelkPoc extends RouteBuilder {
64
        @Override
65
        public void configure() throws Exception {
66
67
            from("timer:java?period=10000")
68
            .routeId("java")
69
            .setBody()
70
                .simple("Hello Camel K from ${routeId} and {{message}}")
71
            .to("log:info");
72
        }
73
    }
74
kind: ConfigMap
75
-----
76
-----


Step 6: Finally, we can close the terminal where we executed CamelkPoc.java in --dev mode. In production mode, we are going to run without --dev mode so that simply closing the terminal doesn't uninstall our integration.

Shell
x
18
 
1
[chandrashekhar@localhost kamelpoc]$ kamel run CamelkPoc.java -p message="test parameter from commandline"
2
integration "camelk-poc" created
3
[chandrashekhar@localhost kamelpoc]$ kubectl get it
4
NAME         PHASE     KIT                        REPLICAS
5
camelk-poc   Running   kit-btjjsi5pu87knpm77nmg   1
6
[chandrashekhar@localhost kamelpoc]$ kubectl get pods
7
NAME                                READY   STATUS    RESTARTS   AGE
8
camel-k-operator-7df56fc69b-qvldd   1/1     Running   0          134m
9
camelk-poc-55df4fb589-5bxl8         1/1     Running   0          24s
10
[chandrashekhar@localhost kamelpoc]$ kubectl logs -f camelk-poc-55df4fb589-5bxl8
11
---
12
---
13
2020-09-20 12:59:21.162 INFO  [Camel (camel-k) thread #0 - timer://java] info - Exchange[ExchangePattern: InOnly, BodyType: String, Body: Hello Modified 123 Camel K from java and test parameter from commandline]
14
2020-09-20 12:59:31.139 INFO  [Camel (camel-k) thread #0 - timer://java] info - Exchange[ExchangePattern: InOnly, BodyType: String, Body: Hello Modified 123 Camel K from java and test parameter from commandline]
15
2020-09-20 12:59:41.139 INFO  [Camel (camel-k) thread #0 - timer://java] info - Exchange[ExchangePattern: InOnly, BodyType: String, Body: Hello Modified 123 Camel K from java and test parameter from commandline]
16
^C
17
[chandrashekhar@localhost kamelpoc]$ 


Thanks so much for reading. I believe this article would have provided you insights about Camel-k and how it works. Stay tune for the next article in this series.

application Kubernetes

Opinions expressed by DZone contributors are their own.

Related

  • Automate Application Load Balancers With AWS Load Balancer Controller and Ingress
  • Building the World's Most Resilient To-Do List Application With Node.js, K8s, and Distributed SQL
  • 7 Ways of Containerizing Your Node.js Application
  • Dynatrace Perform: Day Two

Partner Resources


Comments

ABOUT US

  • About DZone
  • Send feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: