I have a java app that needs to connect to a MySQL instance running inside a Kubernetes cluster. The MySQL instance comes up just fine and I can log into the container from the shell. The configuration looks like:
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
spec:
selector:
matchLabels:
app: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:latest
env:
# Use secret in real usage
- name: MYSQL_ROOT_PASSWORD
value: password
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pv-claim
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv-volume
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
type: NodePort
selector:
app: mysql
ports:
- protocol: TCP
port: 3306
nodePort: 30000
targetPort: 3306
My java application is build using Docker and I can run it just fine on localhost; I'm wondering how I can pass in the db.url when running the application container?
The YML for the application is as follows:
apiVersion: apps/v1
kind: Deployment
metadata:
name: directory-deployment
spec:
replicas: 1
selector:
matchLabels:
app: directory
template:
metadata:
labels:
app: directory
spec:
containers:
- name: directory-container
image: directory:latest
imagePullPolicy: Always
ports:
- containerPort: 8080
env:
- name: SPRING_DATASOURCE_URL
value: jdbc:mysql://${DB_HOST}/temp?useSSL=false
---
apiVersion: v1
kind: Service
metadata:
name: directory-service
spec:
selector:
app: directory
ports:
- protocol: TCP
port: 8080
targetPort: 8080
type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: directory-deployment
spec:
selector:
matchLabels:
app: directory-mysql
replicas: 1
template:
metadata:
labels:
app: directory-mysql
spec:
containers:
- name: directory
image: directory:latest
ports:
- containerPort: 8080
env: # Setting Enviornmental Variables
- name: DB_HOST # Setting Database host address from configMap
valueFrom :
configMapKeyRef :
name : db-config
key : host
- name: DB_NAME # Setting Database name from configMap
valueFrom :
configMapKeyRef :
name : db-config
key : dbName
- name: DB_USERNAME # Setting Database username from Secret
valueFrom :
secretKeyRef :
name : mysql-secrets
key : username
- name: DB_PASSWORD # Setting Database password from Secret
valueFrom :
secretKeyRef :
name : mysql-secrets
key : password
---
apiVersion: v1 # Kubernetes API version
kind: Service # Kubernetes resource kind we are creating
metadata: # Metadata of the resource kind we are creating
name: directory
spec:
selector:
app: mysql
ports:
- protocol: "TCP"
port: 8080 # The port that the service is running on in the cluster
targetPort: 8080 # The port exposed by the service
type: NodePort # type of the service.
What I'm looking to do is to pass in the correct db.url to the application container to connect to the MySQL pod.
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
directory NodePort 10.101.234.92 <none> 8080:30561/TCP 5m11s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 38m
mysql NodePort 10.96.238.113 <none> 3306:30000/TCP 32m
kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
directory-deployment 0/1 1 0 5m18s
mysql 1/1 1 1 34m
As I launch the service; the JDBC connector is trying to use jdbc:mysql://mysql/temp but as you can see, it won't connect
java -jar ./target/Test.jar
[main] INFO org.eclipse.jetty.util.log - Logging initialized @56ms
[main] INFO org.test.db.DatabaseConfig - DB url: jdbc:mysql://mysql:3306
[main] INFO org.test.db.DatabaseConfig - Loaded the db file correctly!!!
[main] INFO org.test.db.DatabaseConfig - DB url: jdbc:mysql://mysql:3306
[main] ERROR org.test.handlers.Directory - The database does now exist!!!!
Exception in thread "main" com.google.inject.ProvisionException: Unable to provision, see the following errors:
1) [Guice/ErrorInjectingConstructor]: RuntimeException: Cannot connect to DB; Communications link failure