How to set up kubernetes for Spring and MySql

9/11/2019

i follow this tutorial https://medium.com/better-programming/kubernetes-a-detailed-example-of-deployment-of-a-stateful-application-de3de33c8632

I create mysql pod and backend pod, but when application get error com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
pod mysql: running
pod backend: CrashLoopBackOff

Dockerfile

FROM openjdk:14-ea-8-jdk-alpine3.10
ADD target/credit-0.0.1-SNAPSHOT.jar .
EXPOSE 8200
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom", "-Dspring.profiles.active=container","-jar","/credit-0.0.1-SNAPSHOT.jar"]

credit-deployment.yml

# Define 'Service' to expose backend application deployment
apiVersion: v1
kind: Service
metadata:
  name: to-do-app-backend  
spec:
  selector:  # backend application pod lables should match these
    app: to-do-app
    tier: backend
  ports:
  - protocol: "TCP"
    port: 80
    targetPort: 8080
  type: LoadBalancer   # use NodePort, if you are not running Kubernetes on cloud
---
# Configure 'Deployment' of backend application
apiVersion: apps/v1
kind: Deployment
metadata:
  name: to-do-app-backend
  labels: 
    app: to-do-app
    tier: backend
spec:
  replicas: 2    # Number of replicas of back-end application to be deployed
  selector:
    matchLabels: # backend application pod labels should match these
      app: to-do-app
      tier: backend
  template:
    metadata:
      labels: # Must macth 'Service' and 'Deployment' labels
        app: to-do-app
        tier: backend  
    spec:                 
      containers: 
      - name: to-do-app-backend 
        image: gitim21/credit_repo:1.0  # docker image of backend application
        env:   # Setting Enviornmental Variables
          - name: DB_HOST   # Setting Database host address from configMap
            valueFrom: 
              configMapKeyRef:
                name: db-conf  # name of configMap
                key: host
          - name: DB_NAME  # Setting Database name from configMap
            valueFrom:
              configMapKeyRef:
                name: db-conf 
                key: name
          - name: DB_USERNAME  # Setting Database username from Secret
            valueFrom:
              secretKeyRef:
                name: db-credentials # Secret Name
                key: username
          - name: DB_PASSWORD # Setting Database password from Secret
            valueFrom:
              secretKeyRef:
                name: db-credentials
                key: password     
        ports:
        - containerPort: 8080

application.yml

spring:
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    hikari:
      idle-timeout: 10000
    platform: mysql
    username: ${DB_USERNAME}
    password: ${DB_PASSWORD}
    url: jdbc:mysql://${DB_HOST}/${DB_NAME}
  jpa:
    hibernate:
      naming:
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

I placed the application.yml file in the application folder "resources"

EDIT

Name:               mysql-64c7df597c-s4gbt
Namespace:          default
Priority:           0
PriorityClassName:  <none>
Node:               minikube/192.168.8.160
Start Time:         Thu, 12 Sep 2019 17:50:18 +0200
Labels:             app=mysql
                    pod-template-hash=64c7df597c
                    tier=database
Annotations:        <none>
Status:             Running
IP:                 172.17.0.5
Controlled By:      ReplicaSet/mysql-64c7df597c
Containers:
  mysql:
    Container ID:  docker://514d3f5af76f5e7ac11f6bf6e36b44ee4012819dc1cef581829a6b5b2ce7c09e
    Image:         mysql:5.7
    Image ID:      docker-pullable://mysql@sha256:1a121f2e7590f949b9ede7809395f209dd9910e331e8372e6682ba4bebcc020b
    Port:          3306/TCP
    Host Port:     0/TCP
    Args:
      --ignore-db-dir=lost+found
    State:          Running
      Started:      Thu, 12 Sep 2019 17:50:19 +0200
    Ready:          True
    Restart Count:  0
    Environment:
      MYSQL_ROOT_PASSWORD:  <set to the key 'password' in secret 'db-root-credentials'>  Optional: false
      MYSQL_USER:           <set to the key 'username' in secret 'db-credentials'>       Optional: false
      MYSQL_PASSWORD:       <set to the key 'password' in secret 'db-credentials'>       Optional: false
      MYSQL_DATABASE:       <set to the key 'name' of config map 'db-conf'>              Optional: false
    Mounts:
      /var/lib/mysql from mysql-persistent-storage (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-rgsmp (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  mysql-persistent-storage:
    Type:       PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
    ClaimName:  mysql-pv-claim
    ReadOnly:   false
  default-token-rgsmp:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-rgsmp
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  49m   default-scheduler  Successfully assigned default/mysql-64c7df597c-s4gbt to minikube
  Normal  Pulled     49m   kubelet, minikube  Container image "mysql:5.7" already present on machine
  Normal  Created    49m   kubelet, minikube  Created container mysql
  Normal  Started    49m   kubelet, minikube  Started container mysql
Name:               to-do-app-backend-8669b5467-hrr9q
Namespace:          default
Priority:           0
PriorityClassName:  <none>
Node:               minikube/192.168.8.160
Start Time:         Thu, 12 Sep 2019 18:27:45 +0200
Labels:             app=to-do-app
                    pod-template-hash=8669b5467
                    tier=backend
Annotations:        <none>
Status:             Running
IP:                 172.17.0.7
Controlled By:      ReplicaSet/to-do-app-backend-8669b5467
Containers:
  to-do-app-backend:
    Container ID:   docker://1eb8453939710aed7a93cddbd5046f49be3382858aa17d5943195207eaeb3065
    Image:          gitim21/credit_repo:1.0
    Image ID:       docker-pullable://gitim21/credit_repo@sha256:1fb2991394fc59f37068164c72263749d64cb5c9fe741021f476a65589f40876
    Port:           8080/TCP
    Host Port:      0/TCP
    State:          Waiting
      Reason:       CrashLoopBackOff
    Last State:     Terminated
      Reason:       Error
      Exit Code:    1
      Started:      Thu, 12 Sep 2019 18:51:25 +0200
      Finished:     Thu, 12 Sep 2019 18:51:36 +0200
    Ready:          False
    Restart Count:  9
    Environment:
      DB_HOST:      <set to the key 'host' of config map 'db-conf'>         Optional: false
      DB_NAME:      <set to the key 'name' of config map 'db-conf'>         Optional: false
      DB_USERNAME:  <set to the key 'username' in secret 'db-credentials'>  Optional: false
      DB_PASSWORD:  <set to the key 'password' in secret 'db-credentials'>  Optional: false
      DB_PORT:      <set to the key 'port' in secret 'db-credentials'>      Optional: false
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-rgsmp (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             False
  ContainersReady   False
  PodScheduled      True
Volumes:
  default-token-rgsmp:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-rgsmp
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type     Reason     Age                  From               Message
  ----     ------     ----                 ----               -------
  Normal   Scheduled  25m                  default-scheduler  Successfully assigned default/to-do-app-backend-8669b5467-hrr9q to minikube
  Normal   Pulled     23m (x5 over 25m)    kubelet, minikube  Container image "gitim21/credit_repo:1.0" already present on machine
  Normal   Created    23m (x5 over 25m)    kubelet, minikube  Created container to-do-app-backend
  Normal   Started    23m (x5 over 25m)    kubelet, minikube  Started container to-do-app-backend
  Warning  BackOff    50s (x104 over 25m)  kubelet, minikube  Back-off restarting failed container
-- Gitim
docker
kubernetes
mysql

1 Answer

9/12/2019

First and foremost make sure that you fillfull all requirements that are described in article. During creating deployments objects like (eg. pods, services ) environment variables are injected from the configMaps and secrets that are created earlier. This deployment uses the image kubernetesdemo/to-do-app-backend which is created in step one. Make sure you've created configmap and secrets before, otherwise delete created during deployment objects, create configMap, secret and then run deployment config file once again.

Another possibility if get:

com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure

error it means that the DB isn't reachable at all. This can have one or more of the following causes:

  1. IP address or hostname in JDBC URL is wrong.
  2. Hostname in JDBC URL is not recognized by local DNS server.
  3. Port number is missing or wrong in JDBC URL. 4. DB server is down.
  4. DB server doesn't accept TCP/IP connections.
  5. DB server has run out of connections.
  6. Something in between Java and DB is blocking connections, e.g. a firewall or proxy.

I assume that if your mysql pod is running your DB server is running and point 4. DB server is down. is wrong.

To solve the one or the other, follow the following advices:

Verify and test them with ping. Refresh DNS or use IP address in JDBC URL instead. Check if it is based on my.cnf of MySQL DB. Start the DB once again. Check if mysqld is started without the --skip-networking option. Restart the DB and fix your code accordingly that it closes connections in finally. Disable firewall and/or configure firewall/proxy to allow/forward the port.

Similar error you can find here: communication-error.

-- MaggieO
Source: StackOverflow