Skip to content

Commit 1605d15

Browse files
committed
feat(traits): gitops trait
We enable the possibility to issue a PR on a given repository with the Integration recently built, and allow the deployment with a GitOps approach Closes #6137
1 parent 9b52a9a commit 1605d15

File tree

25 files changed

+2534
-465
lines changed

25 files changed

+2534
-465
lines changed

docs/modules/ROOT/nav.adoc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,10 @@
2323
* xref:running/running.adoc[Run an Integration]
2424
** xref:running/running-cli.adoc[kamel run CLI]
2525
** xref:running/build-from-git.adoc[Git hosted Integrations]
26+
** xref:running/gitops.adoc[GitOps]
2627
** xref:running/self-managed.adoc[Self managed Integrations]
2728
** xref:running/synthetic.adoc[Synthetic Integrations]
28-
** xref:running/promoting.adoc[Promote an Integration]
29+
** xref:running/promoting.adoc[kamel promote CLI]
2930
** xref:running/dry-build.adoc[Dry build]
3031
* xref:pipes/pipes.adoc[Run an Pipe]
3132
** xref:pipes/bind-cli.adoc[kamel bind CLI]
@@ -54,6 +55,7 @@
5455
** xref:traits:deployer.adoc[Deployer]
5556
** xref:traits:deployment.adoc[Deployment]
5657
** xref:traits:environment.adoc[Environment]
58+
** xref:traits:gitops.adoc[Gitops]
5759
** xref:traits:health.adoc[Health]
5860
** xref:traits:ingress.adoc[Ingress]
5961
** xref:traits:init-containers.adoc[Init Containers]

docs/modules/ROOT/pages/running/build-from-git.adoc

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,18 +60,14 @@ metadata:
6060
spec:
6161
git:
6262
url: https://github.com/michalvavrik/sample.git
63-
branch: feature/xyz # Use specific branch
63+
# branch: feature/xyz # Use specific branch
6464
# tag: v1.2.3 # Or use specific tag
6565
# commit: f2b9bd064a62263ab53b3bfe6ac2b71e68dba45b # Or use specific commit
6666
```
6767

6868
== Rebuild
6969

70-
In order to trigger a rebuild of an Integration you will need to `kamel reset` or to wipe off the Integration `status` as it normally happens for any other regular Integration.
71-
72-
== GitOps
73-
74-
The possibility to build directly from the Git repo will give you more flexibility to close the loop between your CICD which is taking care to build an application and to deploy it.
70+
In order to trigger a rebuild of an Integration you will need to `kamel rebuild` or to wipe off the Integration `status` as it normally happens for any other regular Integration.
7571

7672
== Future developments
7773

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
[[gitops]]
2+
= Camel GitOps
3+
4+
Once your build is complete, you can configure the operator to run an opinionated GitOps strategy. Camel K has a built-in feature which allow the operator to push a branch on a given Git repository with the latest Integration candidate release built. In order to set the context, this would be the scenario:
5+
6+
1. The dev operator builds the application from Git source
7+
2. The dev operator push the container image
8+
3. The operator creates a branch into a Git repo with the Integration custom resource pinned with the container image just built
9+
4. (Optional) there could be a gateway such as a Pull Request to control the changes pushed are good to go
10+
5. A CICD tool (eg, ArgoCD) will be watching the repo and be notified when a change Integration is ready for a given environment (eg, production)
11+
6. The production operator will immediately start the Integration as it was a self managed Integration (it directly holds the container image) which does not require any build
12+
13+
The feature is based on Kustomize and can be entirely configured via `gitops` trait.
14+
15+
NOTE: the work described here is influenced by https://developers.redhat.com/e-books/path-gitops["The Path to GitOps"] book.
16+
17+
== GitOps overlays
18+
19+
The operator can create a Kustomize based overlay structure in order to simplify the creation of a **GitOps based deployment** process. Let's pretend we want to create a GitOps pipeline for two environments, as an example, *staging* and *production*. We need to configure the trait with the following configuration:
20+
21+
```yaml
22+
apiVersion: camel.apache.org/v1
23+
kind: Integration
24+
metadata:
25+
name: sample
26+
spec:
27+
...
28+
traits:
29+
camel:
30+
properties:
31+
- my-env=dev
32+
container:
33+
requestMemory: 256Mi
34+
gitops:
35+
url: https://github.com/my-org/my-camel-apps.git
36+
secret: my-gh-token
37+
branchPush: cicd-listener
38+
overlays:
39+
- staging
40+
- production
41+
```
42+
43+
NOTE: There are more options to configure on the `gitops` trait. Feel free to have a look and learn on the trait documentation page directly.
44+
45+
As soon as the build of the Integration is completed, the operator will prepare the commit with the overlays. The structure would be like the following directory tree:
46+
47+
```
48+
/integrations/
49+
└── sample
50+
├── base
51+
│   ├── integration.yaml
52+
│   └── kustomization.yaml
53+
├── overlays
54+
│   ├── production
55+
│   │   ├── kustomization.yaml
56+
│   │   └── patch-integration.yaml
57+
│   └── staging
58+
│   ├── kustomization.yaml
59+
│   └── patch-integration.yaml
60+
└── routes
61+
└── XYZ.java
62+
63+
```
64+
65+
The above structure could be used directly with `kubectl` (eg, `kubectl apply -k /tmp/integrations/sample/overlays/production`) or any CICD capable of running a similar deployment strategy.
66+
67+
The important thing to notice is that the **base** Integration is adding the container image that we've just built and any other trait which is required for the application to run correctly (and without the need to be rebuilt) on another environment:
68+
69+
```yaml
70+
apiVersion: camel.apache.org/v1
71+
kind: Integration
72+
metadata:
73+
name: test
74+
spec:
75+
...
76+
traits:
77+
camel:
78+
runtimeVersion: 3.15.3
79+
properties:
80+
- my-env=dev
81+
container:
82+
image: 10.110.254.179/camel-k/camel-k-kit-d4taqhk20aus73c0o74g@sha256:9d95d940291be22743c24fe5f2c973752e0e3953989d84936c57d81e6f179914
83+
requestMemory: 256Mi
84+
jvm:
85+
classpath: dependencies/*:dependencies/app/*:dependencies/lib/boot/*:dependencies/lib/main/*:dependencies/quarkus/*
86+
```
87+
88+
What's cool is that each `patch-integration.yaml` (hence, each overlay) can be configured with different trait configuration (for example, resources configuration, replicas, ...). The tool will create a first empty configuration for those traits that are configuring deployment aspects, but won't override any existing overlay, so that you can change them directly in the git repository without the risk the operator to override them. Every new build, it will only change the `container.image` and any other configuration which is not explicitly defined in the overlay.
89+
90+
For example, your "production" overlay patch may be in this case:
91+
92+
```yaml
93+
apiVersion: camel.apache.org/v1
94+
kind: Integration
95+
metadata:
96+
name: test
97+
spec:
98+
traits:
99+
camel:
100+
properties:
101+
- my-env=prod
102+
container:
103+
requestMemory: 2Gi
104+
```
105+
106+
At next build, the patch won't change. So, you can safely trust your CICD that will release correctly, just refreshing the container image with the newest candidate release image.
107+
108+
=== Manual gateway
109+
110+
As you're pushing the changes on a branch, you may want to use the branch and create Pull Request, Merge Request or any other merging strategy used by the git implementation of your choice. This is a clever way to introduce a gateway and have some approval methodology that has to be reviewed by a human operator. As git does not mandate a standard approach for this feature, you will need to implement a strategy on your own. If you're using GitHub, you may, for example have GitHub Action to automate the creation of a PR each time a new commit happen on a given branch.
111+
112+
=== Running Camel with ArgoCD
113+
114+
argo-cd.readthedocs.io[ArgoCD] is one of the most popular CICD choices around. Once you have stored the project in a Git repository, if you're using a CICD technology like ArgoCD you can run your *production* pipeline as:
115+
116+
```
117+
argocd app create my-ck-it-prod --repo https://git-server/repo/integrations/sample.git --path overlays/production --dest-server https://kubernetes.default.svc --dest-namespace prod
118+
```
119+
120+
From this moment onward any change can be performed on the repository and it will be automatically refreshed by the CICD pipeline accordingly.
121+
122+
NOTE: any other CICD technology can be adopted using the Git repository as source.
123+
124+
=== Separated cluster
125+
126+
The GitOps feature makes it possible to have a physical separated cluster for each environment. You may have a build only cluster only which is the one where the operator performs the build of the Camel applications. Then you have a testing environment where your QA team is validating the application and finally a separated cluster for running production workloads. All automated and in sync without the need to rebuild the application. They have to use the same container registry or you need to adopt some registry synchronization tooling to maintain in sync the repository.
127+
128+
=== Single repository for multiple Camel applications
129+
130+
You can have a single repository that will contain all your Integrations. If you have noticed, the Integrations will be added to an `integrations` root directory (you can configure it if you need). This is on purpose, as you may want a single repo with all your Kubernetes resources and some CICD just watching at them. So, the `integrations` will contain all your Integrations built and ready to run.
131+
132+
NOTE: this is the approach suggested in https://developers.redhat.com/e-books/path-gitops["The Path to GitOps"] book.
133+
134+
=== Push to the same repository you've used to build
135+
136+
If you're building application from Git and you want to push the changes back to the same, then, you don't need to configure the Git repository for `gitops` trait. If nothing is specified, the trait will get the configuration from `.spec.git` Integration. This approach may be good when you want to have a single repository containing all aspects of an application. In this case we suggest to use a directory named `ci` or `cicd` as a convention to store your GitOps configuration.
137+
138+
=== Chain of GitOps environments
139+
140+
By default, the `gitops` trait will delete the trait configuration when creating the overlays. This is done in order to avoid a circular infinite push loop. In general, you don't need the trait in your overlays, unless you have some more complex GitOps chaining methodology. If you have a cascading GitOps mechanisms, you can include the configuration in the `patch-integration.yaml`. We can imagine a build which trigger a QA execution. And then, the QA execution may trigger a Production overlay execution. You can use the patch in each different step and configure the `gitops` trait accordingly.
141+
142+
The above description would turn into something like:
143+
144+
```yaml
145+
apiVersion: camel.apache.org/v1
146+
kind: Integration
147+
metadata:
148+
name: sample
149+
spec:
150+
...
151+
traits:
152+
camel:
153+
properties:
154+
- my-env=dev
155+
...
156+
gitops:
157+
url: https://github.com/my-org/my-camel-apps.git
158+
secret: my-gh-token
159+
branchPush: cicd-listener-test
160+
overlays:
161+
- testing
162+
```
163+
164+
Then, once the operator has built and pushed the change on the GitOps repo, you can configure your "testing" `patch-integration.yaml` overlay adding the `gitops` trait:
165+
166+
```yaml
167+
apiVersion: camel.apache.org/v1
168+
kind: Integration
169+
metadata:
170+
name: test
171+
spec:
172+
traits:
173+
camel:
174+
properties:
175+
- my-env=test
176+
gitops:
177+
url: https://github.com/my-org/my-camel-apps.git
178+
secret: my-gh-token
179+
branchPush: cicd-listener-prod
180+
overlays:
181+
- production
182+
```
183+
184+
When the "testing" pipeline executes, it will push further a "production" overlay that can be the final stage of your process. With this strategy you can create a chain of pipelines each of them controlling the next step (ideally with some gateway to control the flow).
185+
186+
=== Predetermined configuration
187+
188+
The operator will add a patch configuration for any of the following trait configuration found in the source base Integration:
189+
190+
* Affinity configuration
191+
* Camel properties
192+
* Container resources
193+
* Environment variables
194+
* JVM options
195+
* Mount configuration
196+
* Toleration configuration
197+
198+
These are the traits that are executed at deployment time. However, you can add any trait you want. Only mind that the "build" traits or in general traits executed in any phase before "Deploy", won't take any effect.
199+
200+
NOTE: feel free to ask to add any further configuration you require.

docs/modules/ROOT/pages/running/promoting.adoc

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -57,18 +57,14 @@ Please notice that the Integration running in test is not altered in any way and
5757
[[traits]]
5858
== Moving traits
5959

60-
NOTE: this feature is available starting from version 2.5
61-
6260
When you use the `promote` subcommand, you're also keeping the status of any configured trait along with the new promoted Integration. The tool is in fact in charge to recover the trait configuration of the source Integration and port it over to the new Integration promoted.
6361

6462
This is particularly nice when you have certain traits which are requiring the scan the source code (for instance, Service trait). In this way, when you promote the new Integration, the traits will be automatically configured to copy any parameter, replicating the very exact behavior between the source and destination environment.
6563

6664
With this approach, you won't need to worry any longer about any trait which was requiring the source to be attached in order to automatically scan for features.
6765

6866
[[gitops]]
69-
== GitOps
70-
71-
NOTE: this feature is available starting from version 2.6
67+
== Make your own GitOps
7268

7369
The promote has also the possibility to create a Kustomize based overlay structure in order to simplify the creation of a **GitOps based deployment** process. Let's pretend we want to create a GitOps pipeline for two environments, as an example, *staging* and *production*. For each environment we can call the export command:
7470

@@ -120,18 +116,6 @@ The CLI has a predetermined set of configuration (traits) which are typically su
120116

121117
The above structure could be used directly with `kubectl` (eg, `kubectl apply -k /tmp/integrations/promote-server/overlays/production`). For this reason it can be used *as is* to feed a Git repository and referenced in any CICD pipeline.
122118

123-
=== Running Camel with ArgoCD
124-
125-
Once you have stored the project in a Git repository, if you're using a CICD technology like https://argo-cd.readthedocs.io[ArgoCD] you can run immediately your *production* pipeline as:
126-
127-
```
128-
argocd app create my-ck-it-prod --repo https://git-server/repo/promote-server.git --path overlays/production --dest-server https://kubernetes.default.svc --dest-namespace prod
129-
```
130-
131-
From this moment onward any change can be performed on the repository and it will be automatically refreshed by the CICD pipeline accordingly.
132-
133-
NOTE: any other CICD technology can be adopted using the Git repository as source.
134-
135119
=== Predetermined configuration
136120

137121
The CLI will add a patch configuration for any of the following trait configuration found in the source base Integration:

0 commit comments

Comments
 (0)