Deploying sample Spring Boot app and MySQL DB on Kubernetes - dpsp-summit/wiki GitHub Wiki
In this tutorial we are going to deploy both a sample application and a database to a Kubernetes cluster.
The sample application is Products from this repository The database is going to be MySQL will be created using a Helm template.
We are going to use helm to deploy a sample mysql pod:
helm install --name mysql-server --set mysqlRootPassword=my-password stable/mysql
Note: The name and password that we are defining here are going to be used by our spring application later, so keep that in mind if you decide to change the values.
After that we can check if the deployment and service were created:
kubectl get svc,deployment
We should see something similar to this:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 100.64.0.1 <none> 443/TCP 14d
service/mysql-server ClusterIP 100.67.125.198 <none> 3306/TCP 23h
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deployment.extensions/mysql-server 1 1 1 1 23h
Istio has some connectivity issues with Mysql, and we have two options to resolve this problem according to this site:
- Enable Mutual TLS in STRICT Mode
- Disable Mutual TLS
For this tutorial we are going to use mutual TLS in STRICT mode.
Create a file named tls_strict.yaml with the following content:
apiVersion: "authentication.istio.io/v1alpha1"
kind: "Policy"
metadata:
name: mysql-mtls-authn
spec:
targets:
- name: mysql-server # The name of *your* K8s Service
peers:
- mtls:
mode: STRICT
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: mysql-mtls-dr
spec:
host: mysql-server # The name of *your* K8s Service
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
Apply the configurations:
kubectl apply -f tls_strict.yaml
- Run an Ubuntu pod that you can use as a client:
kubectl run -i --tty ubuntu --image=ubuntu:16.04 --restart=Never -- bash -il
- Install the mysql client:
apt-get update && apt-get install mysql-client -y
- Connect using the mysql cli, then provide your password:
mysql -h mysql-server -p
Once connected to the DB, we create Products the schema:
create schema products;
use products;
Create the products table:
CREATE TABLE IF NOT EXISTS products (
id INT AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB;
And insert some sample data:
INSERT INTO products VALUES (1, 'Produto 1');
INSERT INTO products VALUES (2, 'Produto 2');
INSERT INTO products VALUES (3, 'Produto 3');
INSERT INTO products VALUES (4, 'Produto 4');
INSERT INTO products VALUES (5, 'Produto 5');
Now that we have our database ready, we need to deploy the Products App. The code for our application is in this repository.
Create a file named products.yaml for the products deployment and service:
kind: Deployment
apiVersion: apps/v1
metadata:
name: products
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: products
template:
metadata:
labels:
app: products
spec:
containers:
- name: products
image: fbereche/products-api:4.0.0
env:
- name: DB_SERVER
value: mysql-server
- name: DB_USERNAME
value: root
- name: DB_PASSWORD
value: my-password
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: products-service
spec:
selector:
app: products
type: LoadBalancer
ports:
- protocol: TCP
port: 80
targetPort: 8080
Note: Remember to put the same values used when configuring the mysql instance on DB_SERVER and DB_PASSWORD.
Execute the creation:
kubectl create -f products.yaml
After deploying the products service, we should see a new Load Balancer being created on the AWS console. Similar to this:
afd0aa50ea0fd11e9b53a02f515ffc3f-1489305742.us-west-2.elb.amazonaws.com
We can confirm this is the same URL shown for our products-service on Kubernetes:
kubectl get svc
The result should show something similar to this:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 100.64.0.1 <none> 443/TCP 14d
mysql-server ClusterIP 100.67.125.198 <none> 3306/TCP 22h
products-service LoadBalancer 100.65.111.242 afd0aa50ea0fd11e9b53a02f515ffc3f-1489305742.us-west-2.elb.amazonaws.com 80:31808/TCP 22h
It will take a few minutes to transition from OutOfService to InService. After it is ready, we can do a GET to the following URL:
afd0aa50ea0fd11e9b53a02f515ffc3f-1489305742.us-west-2.elb.amazonaws.com/products
We should get the following information:
[{"id":1,"name":"Produto 1"},{"id":2,"name":"Produto 2"},{"id":3,"name":"Produto 3"},{"id":4,"name":"Produto 4"},{"id":5,"name":"Produto 5"}]