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.

Deploy MySQL DB using Helm

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

Enable TLS in STRICT Mode for Istio before testing connection

Istio has some connectivity issues with Mysql, and we have two options to resolve this problem according to this site:

  1. Enable Mutual TLS in STRICT Mode
  2. 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

Test DB connection

  1. Run an Ubuntu pod that you can use as a client:
   kubectl run -i --tty ubuntu --image=ubuntu:16.04 --restart=Never -- bash -il
  1. Install the mysql client:
   apt-get update && apt-get install mysql-client -y
  1. Connect using the mysql cli, then provide your password:
   mysql -h mysql-server -p

Creating DB Products

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');

Deploying the Spring-boot app

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

Testing the app

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"}]
⚠️ **GitHub.com Fallback** ⚠️