├── src ├── main │ ├── resources │ │ ├── application.properties │ │ └── application.yml │ └── java │ │ └── com │ │ └── javatechie │ │ └── crud │ │ ├── repository │ │ └── OrderRepository.java │ │ ├── SpringbootCrudK8sExampleApplication.java │ │ ├── entity │ │ └── Order.java │ │ ├── service │ │ └── OrderService.java │ │ └── controller │ │ └── OrderController.java └── test │ └── java │ └── com │ └── javatechie │ └── crud │ └── SpringbootCrudK8sExampleApplicationTests.java ├── README.md ├── mysql-configMap.yaml ├── Dockerfile ├── mysql-secrets.yaml ├── app-deployment.yaml ├── pom.xml └── db-deployment.yaml /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # springboot-crud-k8s 2 | Run & Deploy Spring Boot CRUD Application With MySQL on K8S 3 | -------------------------------------------------------------------------------- /mysql-configMap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion : v1 2 | kind : ConfigMap 3 | metadata: 4 | name : db-config 5 | data: 6 | host : mysql 7 | dbName: javatechie 8 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8 2 | EXPOSE 8080 3 | ADD target/springboot-crud-k8s.jar springboot-crud-k8s.jar 4 | ENTRYPOINT ["java","-jar","/springboot-crud-k8s.jar"] -------------------------------------------------------------------------------- /mysql-secrets.yaml: -------------------------------------------------------------------------------- 1 | apiVersion : v1 2 | kind : Secret 3 | metadata: 4 | name : mysql-secrets 5 | data: 6 | username : cm9vdA== 7 | password : cm9vdA== 8 | -------------------------------------------------------------------------------- /src/main/java/com/javatechie/crud/repository/OrderRepository.java: -------------------------------------------------------------------------------- 1 | package com.javatechie.crud.repository; 2 | 3 | import com.javatechie.crud.entity.Order; 4 | import org.springframework.data.jpa.repository.JpaRepository; 5 | 6 | public interface OrderRepository extends JpaRepository { 7 | } 8 | -------------------------------------------------------------------------------- /src/test/java/com/javatechie/crud/SpringbootCrudK8sExampleApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.javatechie.crud; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class SpringbootCrudK8sExampleApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | datasource: 3 | driver-class-name: com.mysql.cj.jdbc.Driver 4 | url: jdbc:mysql://${DB_HOST}/${DB_NAME}?useSSL=false 5 | username: ${DB_USERNAME} 6 | password: ${DB_PASSWORD} 7 | hikari: 8 | initialization-fail-timeout: 0 9 | jpa: 10 | database-platform: org.hibernate.dialect.MySQL5Dialect 11 | generate-ddl: true 12 | show-sql: true 13 | hibernate: 14 | ddl-auto: update -------------------------------------------------------------------------------- /src/main/java/com/javatechie/crud/SpringbootCrudK8sExampleApplication.java: -------------------------------------------------------------------------------- 1 | package com.javatechie.crud; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringbootCrudK8sExampleApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(SpringbootCrudK8sExampleApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/javatechie/crud/entity/Order.java: -------------------------------------------------------------------------------- 1 | package com.javatechie.crud.entity; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import javax.persistence.Entity; 8 | import javax.persistence.GeneratedValue; 9 | import javax.persistence.Id; 10 | import javax.persistence.Table; 11 | 12 | @Data 13 | @AllArgsConstructor 14 | @NoArgsConstructor 15 | @Entity 16 | @Table(name = "ORDERS_TBL") 17 | public class Order { 18 | @Id 19 | @GeneratedValue 20 | private int id; 21 | private String name; 22 | private int qty; 23 | private double price; 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/javatechie/crud/service/OrderService.java: -------------------------------------------------------------------------------- 1 | package com.javatechie.crud.service; 2 | 3 | import com.javatechie.crud.entity.Order; 4 | import com.javatechie.crud.repository.OrderRepository; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | import java.util.List; 9 | 10 | @Service 11 | public class OrderService { 12 | 13 | @Autowired 14 | private OrderRepository repository; 15 | 16 | public Order addOrder(Order order){ 17 | return repository.save(order); 18 | } 19 | 20 | public List getOrders(){ 21 | return repository.findAll(); 22 | } 23 | 24 | public Order getOrderById(int id){ 25 | return repository.findById(id) 26 | .orElseThrow(()->new IllegalArgumentException("Invalid id : "+id)); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/javatechie/crud/controller/OrderController.java: -------------------------------------------------------------------------------- 1 | package com.javatechie.crud.controller; 2 | 3 | import com.javatechie.crud.entity.Order; 4 | import com.javatechie.crud.service.OrderService; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.web.bind.annotation.*; 7 | 8 | import java.util.List; 9 | 10 | @RestController 11 | @RequestMapping("/orders") 12 | public class OrderController { 13 | 14 | @Autowired 15 | private OrderService service; 16 | 17 | @PostMapping 18 | public Order addOrder(@RequestBody Order order){ 19 | return service.addOrder(order); 20 | } 21 | 22 | @GetMapping 23 | public List getOrders(){ 24 | return service.getOrders(); 25 | } 26 | 27 | @GetMapping("/{id}") 28 | public Order getOrderById(@PathVariable int id){ 29 | return service.getOrderById(id); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: springboot-crud-deployment 5 | spec: 6 | selector: 7 | matchLabels: 8 | app: springboot-k8s-mysql 9 | replicas: 3 10 | template: 11 | metadata: 12 | labels: 13 | app: springboot-k8s-mysql 14 | spec: 15 | containers: 16 | - name: springboot-crud-k8s 17 | image: springboot-crud-k8s:1.0 18 | ports: 19 | - containerPort: 8080 20 | env: # Setting Enviornmental Variables 21 | - name: DB_HOST # Setting Database host address from configMap 22 | valueFrom : 23 | configMapKeyRef : 24 | name : db-config 25 | key : host 26 | 27 | - name: DB_NAME # Setting Database name from configMap 28 | valueFrom : 29 | configMapKeyRef : 30 | name : db-config 31 | key : dbName 32 | 33 | - name: DB_USERNAME # Setting Database username from Secret 34 | valueFrom : 35 | secretKeyRef : 36 | name : mysql-secrets 37 | key : username 38 | 39 | - name: DB_PASSWORD # Setting Database password from Secret 40 | valueFrom : 41 | secretKeyRef : 42 | name : mysql-secrets 43 | key : password 44 | 45 | --- 46 | 47 | apiVersion: v1 # Kubernetes API version 48 | kind: Service # Kubernetes resource kind we are creating 49 | metadata: # Metadata of the resource kind we are creating 50 | name: springboot-crud-svc 51 | spec: 52 | selector: 53 | app: springboot-k8s-mysql 54 | ports: 55 | - protocol: "TCP" 56 | port: 8080 # The port that the service is running on in the cluster 57 | targetPort: 8080 # The port exposed by the service 58 | type: NodePort # type of the service. 59 | 60 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.6.1 9 | 10 | 11 | com.javatechie 12 | springboot-crud-k8s-example 13 | 0.0.1-SNAPSHOT 14 | springboot-crud-k8s-example 15 | Demo project for Spring Boot 16 | 17 | 1.8 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-data-jpa 23 | 24 | 25 | org.springframework.boot 26 | spring-boot-starter-web 27 | 28 | 29 | 30 | mysql 31 | mysql-connector-java 32 | runtime 33 | 34 | 35 | org.projectlombok 36 | lombok 37 | true 38 | 39 | 40 | org.springframework.boot 41 | spring-boot-starter-test 42 | test 43 | 44 | 45 | 46 | 47 | 48 | 49 | org.springframework.boot 50 | spring-boot-maven-plugin 51 | 52 | 53 | 54 | org.projectlombok 55 | lombok 56 | 57 | 58 | 59 | 60 | 61 | springboot-crud-k8s 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /db-deployment.yaml: -------------------------------------------------------------------------------- 1 | # Define a 'Persistent Voulume Claim'(PVC) for Mysql Storage, dynamically provisioned by cluster 2 | apiVersion: v1 3 | kind: PersistentVolumeClaim 4 | metadata: 5 | name: mysql-pv-claim # name of PVC essential for identifying the storage data 6 | labels: 7 | app: mysql 8 | tier: database 9 | spec: 10 | accessModes: 11 | - ReadWriteOnce #This specifies the mode of the claim that we are trying to create. 12 | resources: 13 | requests: 14 | storage: 1Gi #This will tell kubernetes about the amount of space we are trying to claim. 15 | --- 16 | # Configure 'Deployment' of mysql server 17 | apiVersion: apps/v1 18 | kind: Deployment 19 | metadata: 20 | name: mysql 21 | labels: 22 | app: mysql 23 | tier: database 24 | spec: 25 | selector: # mysql Pod Should contain same labels 26 | matchLabels: 27 | app: mysql 28 | tier: database 29 | strategy: 30 | type: Recreate 31 | template: 32 | metadata: 33 | labels: # Must match 'Service' and 'Deployment' selectors 34 | app: mysql 35 | tier: database 36 | spec: 37 | containers: 38 | - image: mysql:5.7 # image from docker-hub 39 | args: 40 | - "--ignore-db-dir=lost+found" # Workaround for https://github.com/docker-library/mysql/issues/186 41 | name: mysql 42 | env: 43 | - name: MYSQL_ROOT_PASSWORD 44 | valueFrom : 45 | secretKeyRef : 46 | name : mysql-secrets 47 | key : password 48 | 49 | - name: MYSQL_DATABASE # Setting Database Name from a 'ConfigMap' 50 | valueFrom : 51 | configMapKeyRef : 52 | name : db-config 53 | key : dbName 54 | 55 | 56 | ports: 57 | - containerPort: 3306 58 | name: mysql 59 | volumeMounts: # Mounting voulume obtained from Persistent Volume Claim 60 | - name: mysql-persistent-storage 61 | mountPath: /var/lib/mysql #This is the path in the container on which the mounting will take place. 62 | volumes: 63 | - name: mysql-persistent-storage # Obtaining 'vloume' from PVC 64 | persistentVolumeClaim: 65 | claimName: mysql-pv-claim 66 | --- 67 | # Define a 'Service' To Expose mysql to Other Services 68 | apiVersion: v1 69 | kind: Service 70 | metadata: 71 | name: mysql # DNS name 72 | labels: 73 | app: mysql 74 | tier: database 75 | spec: 76 | ports: 77 | - port: 3306 78 | targetPort: 3306 79 | selector: # mysql Pod Should contain same labels 80 | app: mysql 81 | tier: database 82 | clusterIP: None # We Use DNS, Thus ClusterIP is not relevant --------------------------------------------------------------------------------