├── .gitignore ├── src ├── main │ ├── resources │ │ └── application.yml │ └── java │ │ └── pl │ │ └── piomin │ │ └── samples │ │ ├── controller │ │ └── SampleController.java │ │ └── DekorateIstioApplication.java └── test │ └── java │ └── pl │ └── piomin │ └── samples │ └── SampleControllerTests.java ├── k8s └── configmap.yaml ├── renovate.json ├── skaffold.yaml ├── README.md ├── .circleci └── config.yml └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | # Project exclude paths 2 | /target/ -------------------------------------------------------------------------------- /src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring.application.name: sample-springboot-dekorate-istio -------------------------------------------------------------------------------- /k8s/configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: sample-configmap 5 | data: 6 | property1: I'm ConfigMap property 7 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:base",":dependencyDashboard" 5 | ], 6 | "packageRules": [ 7 | { 8 | "matchUpdateTypes": ["minor", "patch", "pin", "digest"], 9 | "automerge": true 10 | } 11 | ], 12 | "prCreation": "not-pending" 13 | } -------------------------------------------------------------------------------- /skaffold.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skaffold/v4beta5 2 | kind: Config 3 | build: 4 | artifacts: 5 | - image: default/sample-springboot-dekorate-istio 6 | jib: 7 | args: 8 | - -DskipTests 9 | tagPolicy: 10 | customTemplate: 11 | template: "1.0" 12 | manifests: 13 | rawYaml: 14 | - target/classes/META-INF/dekorate/*.yml 15 | - k8s/*.yaml -------------------------------------------------------------------------------- /src/main/java/pl/piomin/samples/controller/SampleController.java: -------------------------------------------------------------------------------- 1 | package pl.piomin.samples.controller; 2 | 3 | import org.springframework.beans.factory.annotation.Value; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.bind.annotation.RequestMapping; 6 | import org.springframework.web.bind.annotation.RestController; 7 | 8 | @RestController 9 | @RequestMapping("/sample") 10 | public class SampleController { 11 | 12 | @Value("${propertyFromMap}") 13 | String propertyFromMap; 14 | @Value("${propertyEnv}") 15 | String propertyEnv; 16 | 17 | @GetMapping("/properties") 18 | public String getProperties() { 19 | return "propertyFromMap=" + propertyFromMap + ", propertyEnv=" + propertyEnv; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/test/java/pl/piomin/samples/SampleControllerTests.java: -------------------------------------------------------------------------------- 1 | package pl.piomin.samples; 2 | 3 | import org.junit.jupiter.api.Assertions; 4 | import org.junit.jupiter.api.Test; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.boot.test.context.SpringBootTest; 7 | import org.springframework.boot.test.web.client.TestRestTemplate; 8 | 9 | @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, 10 | properties = { 11 | "propertyFromMap=map", "propertyEnv=env" 12 | }) 13 | public class SampleControllerTests { 14 | 15 | @Autowired 16 | TestRestTemplate restTemplate; 17 | 18 | @Test 19 | void sample() { 20 | String response = restTemplate.getForObject("/sample/properties", String.class); 21 | Assertions.assertNotNull(response); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/pl/piomin/samples/DekorateIstioApplication.java: -------------------------------------------------------------------------------- 1 | package pl.piomin.samples; 2 | 3 | import io.dekorate.kubernetes.annotation.Env; 4 | import io.dekorate.kubernetes.annotation.KubernetesApplication; 5 | import io.dekorate.kubernetes.annotation.Label; 6 | import io.dekorate.kubernetes.annotation.Port; 7 | import io.dekorate.option.annotation.GarbageCollector; 8 | import io.dekorate.option.annotation.JvmOptions; 9 | import org.springframework.boot.SpringApplication; 10 | import org.springframework.boot.autoconfigure.SpringBootApplication; 11 | 12 | @SpringBootApplication 13 | @KubernetesApplication(replicas = 2, 14 | partOf = "default", 15 | envVars = { @Env(name = "propertyEnv", value = "Hello from env!"), 16 | @Env(name = "propertyFromMap", value = "property1", configmap = "sample-configmap") }, 17 | ports = @Port(name = "http", containerPort = 8080), 18 | labels = @Label(key = "version", value = "v1")) 19 | @JvmOptions(server = true, xmx = 256, gc = GarbageCollector.SerialGC) 20 | public class DekorateIstioApplication { 21 | 22 | public static void main(String[] args) { 23 | SpringApplication.run(DekorateIstioApplication.class, args); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Spring Boot on Kubernetes Advanced Demo Project [![Twitter](https://img.shields.io/twitter/follow/piotr_minkowski.svg?style=social&logo=twitter&label=Follow%20Me)](https://twitter.com/piotr_minkowski) 2 | 3 | [![CircleCI](https://circleci.com/gh/piomin/sample-springboot-dekorate-istio.svg?style=svg)](https://circleci.com/gh/piomin/sample-springboot-dekorate-istio) 4 | 5 | [![SonarCloud](https://sonarcloud.io/images/project_badges/sonarcloud-black.svg)](https://sonarcloud.io/dashboard?id=piomin_sample-springboot-dekorate-istio) 6 | [![Bugs](https://sonarcloud.io/api/project_badges/measure?project=piomin_sample-springboot-dekorate-istio&metric=bugs)](https://sonarcloud.io/dashboard?id=piomin_sample-springboot-dekorate-istio) 7 | [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=piomin_sample-springboot-dekorate-istio&metric=coverage)](https://sonarcloud.io/dashboard?id=piomin_sample-springboot-dekorate-istio) 8 | [![Lines of Code](https://sonarcloud.io/api/project_badges/measure?project=piomin_sample-springboot-dekorate-istio&metric=ncloc)](https://sonarcloud.io/dashboard?id=piomin_sample-springboot-dekorate-istio) 9 | 10 | ## Getting Started 11 | 12 | In the following article I'm demonstrating how to use Dekorate (https://dekorate.io/) with Spring Boot to automatically generate Kubernetes and Istio manifests: [Simplify development on Kubernetes with Dekorate, Skaffold and Spring Boot](https://piotrminkowski.com/2020/06/08/simplify-development-on-kubernetes-with-dekorate-skaffold-and-spring-boot/) -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | 3 | jobs: 4 | analyze: 5 | docker: 6 | - image: 'cimg/openjdk:21.0.9' 7 | steps: 8 | - checkout 9 | - run: 10 | name: Analyze on SonarCloud 11 | command: mvn verify sonar:sonar 12 | deploy-k8s: 13 | executor: machine_executor_amd64 14 | steps: 15 | - checkout 16 | - run: 17 | name: Install Kubectl 18 | command: | 19 | curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" 20 | chmod +x kubectl 21 | sudo mv ./kubectl /usr/local/bin/kubectl 22 | - run: 23 | name: Install Skaffold 24 | command: | 25 | curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64 26 | chmod +x skaffold 27 | sudo mv skaffold /usr/local/bin 28 | - run: 29 | name: Install Kind 30 | command: | 31 | [ $(uname -m) = x86_64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-linux-amd64 32 | chmod +x ./kind 33 | sudo mv ./kind /usr/local/bin/kind 34 | - run: 35 | name: Install OpenJDK 21 36 | command: | 37 | java -version 38 | sudo apt-get update && sudo apt-get install openjdk-21-jdk 39 | sudo update-alternatives --set java /usr/lib/jvm/java-21-openjdk-amd64/bin/java 40 | sudo update-alternatives --set javac /usr/lib/jvm/java-21-openjdk-amd64/bin/javac 41 | java -version 42 | export JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64 43 | - run: 44 | name: Create Kind Cluster 45 | command: | 46 | kind create cluster --name c1 47 | - run: 48 | name: Deploy to K8s 49 | command: | 50 | export JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64 51 | mvn package -DskipTests 52 | skaffold run 53 | - run: 54 | name: Delete Kind Cluster 55 | command: | 56 | kind delete cluster --name c1 57 | 58 | executors: 59 | jdk: 60 | docker: 61 | - image: 'cimg/openjdk:21.0.9' 62 | machine_executor_amd64: 63 | machine: 64 | image: ubuntu-2204:2023.10.1 65 | environment: 66 | architecture: "amd64" 67 | platform: "linux/amd64" 68 | 69 | orbs: 70 | maven: circleci/maven@2.1.1 71 | 72 | workflows: 73 | build-and-deploy: 74 | jobs: 75 | - maven/test: 76 | name: test 77 | executor: jdk 78 | - analyze: 79 | context: SonarCloud 80 | - deploy-k8s: 81 | requires: 82 | - test -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | pl.piomin.samples 8 | sample-springboot-dekorate-istio 9 | 1.0 10 | 11 | 12 | org.springframework.boot 13 | spring-boot-starter-parent 14 | 3.5.9 15 | 16 | 17 | 18 | piomin_sample-springboot-dekorate-istio 19 | piomin 20 | https://sonarcloud.io 21 | 21 22 | 23 | 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-web 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter-actuator 32 | 33 | 34 | io.dekorate 35 | kubernetes-spring-starter 36 | 4.1.7 37 | 38 | 39 | org.springframework.boot 40 | spring-boot-starter-test 41 | test 42 | 43 | 44 | 45 | 46 | 47 | 48 | org.springframework.boot 49 | spring-boot-maven-plugin 50 | 51 | 52 | 53 | build-info 54 | 55 | 56 | 57 | 58 | 59 | com.google.cloud.tools 60 | jib-maven-plugin 61 | 3.5.1 62 | 63 | 64 | eclipse-temurin:21-jdk-ubi9-minimal 65 | 66 | 67 | 68 | 69 | org.jacoco 70 | jacoco-maven-plugin 71 | 0.8.14 72 | 73 | 74 | 75 | prepare-agent 76 | 77 | 78 | 79 | report 80 | test 81 | 82 | report 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | --------------------------------------------------------------------------------