Kubernetes save mysql database's data inside a volume - mysql

I'm new to kubernetes (using minikube) and i want to deploy an springboot app which uses mysql to store data.
I'm running my app inside a pod with 2 containers (one for my app and one for mysql), it works fine and as expected, my data are lost once i restard the pods (with a scale --replicas=0; scale --replicas=1 for exemple).
I'm using PersistentVolumeClaim, but still the data aren't stored, i'm for sure missing something important.
Here's my configuration file:
apiVersion: apps/v1
kind: Deployment
metadata:
name: esse-deployment-1
labels:
app: esse-1
spec:
replicas: 1
selector:
matchLabels:
app: esse-1
template:
metadata:
labels:
app: esse-1
spec:
containers:
- image: mysql:5.7
name: esse-datasource
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: root
volumeMounts:
- name: mysql-persistent-storage-esse-1
mountPath: /home/esse-1/data/mysql
- image: esse-application
name: esse-app
imagePullPolicy: Never
ports:
- containerPort: 8080
env:
- name: ESSE_DATABASE_USERNAME
value: root
- name: ESSE_DATABASE_PASSWORD
value: root
- name: ESSE_APPLICATION_CONTEXT
value: /esse-1
volumes:
- name: mysql-persistent-storage-esse-1
persistentVolumeClaim:
claimName: mysql-persistent-volume-claim-esse-1
---
apiVersion: v1
kind: Service
metadata:
name: esse-service-1
labels:
app: esse-1
spec:
selector:
app: esse-1
ports:
- protocol: TCP
port: 8080
targetPort: 8080
type: NodePort
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-persistent-volume-claim-esse-1
labels:
app: esse-1
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi

You need to mount the persistent volume to the directory where mysql is actually writing the database data to (adjust mountPath for the container). This is /var/lib/mysql in this case.

Related

Unable to run wordpress example on OpenShift

I am trying to run Kubernetes Wordpress sample on OpenShift. I tried it already on Minikube and it worked. However, when I try to deploy it to OpenShift sandbox using oc (with oc apply -k ./), I get this error inside the MySQL pod:
MySQL Connection Error: (1130) Host '10.128.4.18' is not allowed to connect to this MySQL server
Warning: mysqli::mysqli(): (HY000/1130): Host '10.128.4.18' is not allowed to connect to this MySQL server in - on line 22
MySQL Connection Error: (1130) Host '10.128.4.18' is not allowed to connect to this MySQL server
Warning: mysqli::mysqli(): (HY000/1130): Host '10.128.4.18' is not allowed to connect to this MySQL
Here are my files:
kustomization.yaml:
secretGenerator:
- name: mysql-pass
literals:
- password=#MyPass1000
resources:
- mysql-deployment.yaml
- wordpress-deployment.yaml
mysql-deployment.yaml:
apiVersion: v1
kind: Service
metadata:
name: wordpress-mysql
labels:
app: wordpress
spec:
ports:
- port: 3306
selector:
app: wordpress
tier: mysql
clusterIP: None
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
labels:
app: wordpress
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress-mysql
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
tier: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
tier: mysql
spec:
containers:
- image: docker.io/library/mysql:5.6
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password
resources:
requests:
cpu: "250m"
memory: "750Mi"
limits:
cpu: "500m"
memory: "1000Mi"
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pv-claim
wordpress-deployment.yaml:
apiVersion: v1
kind: Service
metadata:
name: wordpress
labels:
app: wordpress
spec:
ports:
- port: 80
selector:
app: wordpress
tier: frontend
type: LoadBalancer
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: wp-pv-claim
labels:
app: wordpress
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
labels:
app: wordpress
spec:
selector:
matchLabels:
app: wordpress
tier: frontend
strategy:
type: Recreate
template:
metadata:
labels:
app: wordpress
tier: frontend
spec:
containers:
- image: docker.io/library/wordpress:4.8-apache
name: wordpress
env:
- name: WORDPRESS_DB_HOST
value: wordpress-mysql
- name: WORDPRESS_DB_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-pass
key: password
resources:
requests:
cpu: "250m"
memory: "250Mi"
limits:
cpu: "500m"
memory: "500Mi"
ports:
- containerPort: 80
name: wordpress
volumeMounts:
- name: wordpress-persistent-storage
mountPath: /var/www/html
volumes:
- name: wordpress-persistent-storage
persistentVolumeClaim:
claimName: wp-pv-claim
Here's the output of oc get pods:
NAME READY STATUS RESTARTS AGE
wordpress-5994c89c98-jmwpp 0/1 CrashLoopBackOff 6 (3m22s ago) 12m
wordpress-mysql-969ddcd5c-j2m46 1/1 Running 0 12m

Kubectl get pod shows ErrImageNeverPull mysql

According to this docu, i try to lunch mysql with kubernetes:
deployment.yml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: kazi-db
spec:
selector:
matchLabels:
app: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql:5.6
name: mysql
imagePullPolicy: Never
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: 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
mysql-storage.yml:
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv-volume
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 20Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
service.yml:
apiVersion: v1
kind: Service
metadata:
name: kazi-db
spec:
ports:
- port: 3306
selector:
app: mysql
db-secret.yml:
apiVersion: v1
kind: Secret
metadata:
name: kazi-db
type: kubernetes.io/basic-auth
stringData:
password: xcvas
I have registered all with kubectl apply -f ...
The problem when i call kubectl get pod
kazi-db-758b978ccc-7m29n 0/1 ErrImageNeverPull 0 4m48s
I have a docker hub with integrated kubernetes
May be thats because of 1. imagePullPolicy is set to "Never" and 2. image: mysql:5.6 does not seem to be present on the worker node where this pod got scheduled.
following are the two possible options:
Perform a manual pull of the image: mysql:5.6 on all worker nodes using
docker pull mysql:5.6
change imagePullPolicy to IfNotPresent.

How can I deploy multi wordpress in kubernetes?

I try to deploy wordpress/mysql in kubernetes.
I want mysql and wordpress to use different volumes. I'm trying to write nfs for wordpress and hostpath for mysql.
But wordpress and mysql are not connected. I don't know why. I'd appreciate your help.
here's my code:
Mysql.yaml
apiVersion: v1
kind: Pod
metadata:
name: mysql
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.7
ports:
- containerPort: 3306
protocol: TCP
env:
- name: MYSQL_ROOT_PASSWORD
value: qwer1234
volumeMounts:
- name: mysql-volume
mountPath: /var/lib/mysql
volumes:
- name: mysql-volume
persistentVolumeClaim:
claimName: mysql-pvc
---
apiVersion: v1
kind: Service
metadata:
name: mysql-svc
labels:
app: mysql
spec:
type: ClusterIP
selector:
app: mysql
ports:
- protocol: TCP
port: 3306
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
volumeName: mysql-pv
​
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
hostPath:
path: /vol/mysql
wordpress.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: wordpress
labels:
app: wordpress
spec:
replicas: 2
selector:
matchLabels:
app: wordpress
template:
metadata:
labels:
app: wordpress
spec:
containers:
- image: wordpress
name: wordpress
env:
- name: WORDPRESS_DB_HOST
value: mysql:3306
- name: WORDPRESS_DB_PASSWORD
value: P#ssw0rd
volumeMounts:
- mountPath: /nfs-volume/html
name: wordpress-pv
ports:
- protocol: TCP
containerPort: 80
volumes:
- name: wordpress-pv
persistentVolumeClaim:
claimName: wordpress-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: wordpress-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
volumeName: wordpress-pv
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: wordpress-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
nfs:
server: 192.168.201.11
path: /nfs-volume
---
apiVersion: v1
kind: Service
metadata:
name: wordpress-svc
labels:
app: wordpress
spec:
type: LoadBalancer
selector:
app: wordpress
ports:
- protocol: TCP
port: 80
you have provided the port number at last in environment variable
please try with out it
env:
- name: WORDPRESS_DB_HOST
value: mysql:3306
instead use this
env:
- name: WORDPRESS_DB_HOST
value: MySQL
you can check the example at : https://kubernetes.io/docs/tutorials/stateful-application/mysql-wordpress-persistent-volume/
if you read the documentation of Docker image they are also providing the host name without the port as value.
also in Wordpress environment you have to pass the MySQL password which you are passing wrong
- name: WORDPRESS_DB_PASSWORD
value: P#ssw0rd
instead it should be
- name: WORDPRESS_DB_PASSWORD
value: qwer1234

AWS Kubernetes Cluster - WordPress Error establishing a database connection

I am novice person to Kubernetes and trying to deploying WordPress and MySQL using the Kubernetes pod containers but its throwing the error "Error establishing a database connection" while running the Kubernetes .
Wordpress Error
Overall Kubect status
AWS Inbound Rules
mysql-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-deployment
labels:
app: mysql
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.7
ports:
- containerPort: 80
env:
- name: MYSQL_ROOT_PASSWORD
value: DEVOPS1
- name: MYSQL_USER
value: wpuser
- name: MYSQL_PASSWORD
value: DEVOPS12345
- name: MYSQL_DATABASE
value: wpdb
mysql-service.yaml
apiVersion: v1
kind: Service
metadata:
name: mysql-service
spec:
selector:
app: mysql
ports:
- protocol: TCP
port: 3306
targetPort: 3306
wordpress-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress-deployment
labels:
app: wordpress
spec:
replicas: 3
selector:
matchLabels:
app: wordpress
template:
metadata:
labels:
app: wordpress
spec:
containers:
- name: wordpress
image: wordpress
ports:
- containerPort: 80
env:
- name: WORDPRESS_DB_HOST
value: mysql-service
- name: WORDPRESS_DB_USER
value: wpuser
- name: WORDPRESS_DB_PASSWORD
value: wpdb
- name: WORDPRESS_DEBUG
value: "1"
wp-service.yaml
apiVersion: v1
kind: Service
metadata:
name: wordpress-service
spec:
type: NodePort
selector:
app: wordpress
ports:
- protocol: TCP
port: 80
targetPort: 80
Also I opened same thread on Kubernetes forum . Click Here to view it
Please change containerPort in your mysql-deployment file from 80 to 3306:
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-deployment
labels:
app: mysql
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.7
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
value: DEVOPS1
- name: MYSQL_USER
value: wpuser
- name: MYSQL_PASSWORD
value: DEVOPS12345
- name: MYSQL_DATABASE
value: wpdb
Check similar problem: wordpress-database-connection-kubernetes.

MySQL router in kubernetes as a service

I want to deploy MySQL-router in Kubernetes working as a service.
My plan..
Deploy MySQL-router inside k8 and expose MySQL-router as a service using LoadBalancer (MetalLB)
Applications running inside k8 sees mysql-router service as its database.
MySQL-router sends application data to outside InnoDB cluster.
I tried to deploy using:
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-router
namespace: mysql-router
spec:
replicas: 1
selector:
matchLabels:
app: mysql-router
template:
metadata:
labels:
app: mysql-router
version: v1
spec:
containers:
- name: mysql-router
image: mysql/mysql-router
env:
- name: MYSQL_HOST
value: "192.168.123.130"
- name: MYSQL_PORT
value: "3306"
- name: MYSQL_USER
value: "root"
- name: MYSQL_PASSWORD
value: "root#123"
imagePullPolicy: Always
ports:
- containerPort: 6446
192.168.123.130 is MySQL cluster Master IP.
apiVersion: v1
kind: Service
metadata:
name: mysql-router-service
namespace: mysql-router
labels:
app: mysql-router
spec:
selector:
app: mysql-router
ports:
- protocol: TCP
port: 6446
type: LoadBalancer
loadBalancerIP: 192.168.123.123
When I check mysql-router container logs, I see something like this:
Waiting for mysql server 192.168.123.130 (0/12)
Waiting for mysql server 192.168.123.130 (1/12)
Waiting for mysql server 192.168.123.130 (2/12)
....
After setting my external MySQL cluster info in deployment, I get following errors:
Successfully contacted mysql server at 192.168.123.130. Checking for cluster state.
Can not connect to database. Exiting.
I can not deploy mysql-router without specifying MYSQL_HOST. What am I missing here?
My ideal deployment
Of course you have to provide the MySQL Host. You could doing this with k8s DNS which setup with in the services.
MySQL Router is middleware that provides transparent routing between your application and any backend MySQL Servers. It can be used for a wide variety of use cases, such as providing high availability and scalability by effectively routing database traffic to appropriate backend MySQL Servers.
Examples
For examples below i use dynamic volume provisioning for data using openebs-hostpath And using StatefulSet for the MySQL Server.
Deployment
MySQL Router :
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-router
namespace: mysql-router
spec:
replicas: 1
selector:
matchLabels:
app: mysql-router
template:
metadata:
labels:
app: mysql-router
version: v1
spec:
containers:
- name: mysql-router
image: mysql/mysql-router
env:
- name: MYSQL_HOST
value: "mariadb-galera.galera-cluster"
- name: MYSQL_PORT
value: "3306"
- name: MYSQL_USER
value: "root"
- name: MYSQL_PASSWORD
value: "root#123"
imagePullPolicy: Always
ports:
- containerPort: 3306
MySQL Server
apiVersion: apps/v1
kind: StatefulSet
metadata:
namespace: galera-cluster
name: mariadb-galera
spec:
podManagementPolicy: OrderedReady
replicas: 1
selector:
matchLabels:
app: mariadb-galera
serviceName: mariadb-galera
template:
metadata:
labels:
app: mariadb-galera
spec:
restartPolicy: Always
securityContext:
fsGroup: 1001
runAsUser: 1001
containers:
- command:
- bash
- -ec
- |
# Bootstrap from the indicated node
NODE_ID="${MY_POD_NAME#"mariadb-galera-"}"
if [[ "$NODE_ID" -eq "0" ]]; then
export MARIADB_GALERA_CLUSTER_BOOTSTRAP=yes
export MARIADB_GALERA_FORCE_SAFETOBOOTSTRAP=no
fi
exec /opt/bitnami/scripts/mariadb-galera/entrypoint.sh /opt/bitnami/scripts/mariadb-galera/run.sh
env:
- name: MY_POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- name: BITNAMI_DEBUG
value: "false"
- name: MARIADB_GALERA_CLUSTER_NAME
value: galera
- name: MARIADB_GALERA_CLUSTER_ADDRESS
value: gcomm://mariadb-galera.galera-cluster
- name: MARIADB_ROOT_PASSWORD
value: root#123
- name: MARIADB_DATABASE
value: my_database
- name: MARIADB_GALERA_MARIABACKUP_USER
value: mariabackup
- name: MARIADB_GALERA_MARIABACKUP_PASSWORD
value: root#123
- name: MARIADB_ENABLE_LDAP
value: "no"
- name: MARIADB_ENABLE_TLS
value: "no"
image: docker.io/bitnami/mariadb-galera:10.4.13-debian-10-r23
imagePullPolicy: IfNotPresent
livenessProbe:
exec:
command:
- bash
- -ec
- |
exec mysqladmin status -uroot -p$MARIADB_ROOT_PASSWORD
failureThreshold: 3
initialDelaySeconds: 120
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
name: mariadb-galera
ports:
- containerPort: 3306
name: mysql
protocol: TCP
- containerPort: 4567
name: galera
protocol: TCP
- containerPort: 4568
name: ist
protocol: TCP
- containerPort: 4444
name: sst
protocol: TCP
readinessProbe:
exec:
command:
- bash
- -ec
- |
exec mysqladmin status -uroot -p$MARIADB_ROOT_PASSWORD
failureThreshold: 3
initialDelaySeconds: 30
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
volumeMounts:
- mountPath: /opt/bitnami/mariadb/.bootstrap
name: previous-boot
- mountPath: /bitnami/mariadb
name: data
- mountPath: /opt/bitnami/mariadb/conf
name: mariadb-galera-config
volumes:
- emptyDir: {}
name: previous-boot
- configMap:
defaultMode: 420
name: my.cnf
name: mariadb-galera-config
volumeClaimTemplates:
- apiVersion: v1
metadata:
name: data
spec:
storageClassName: openebs-hostpath
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
Services
MySQL Router Service
apiVersion: v1
kind: Service
metadata:
name: mysql-router-service
namespace: mysql-router
labels:
app: mysql-router
spec:
selector:
app: mysql-router
ports:
- protocol: TCP
port: 3306
type: LoadBalancer
loadBalancerIP: 192.168.123.123
MySQL Service
apiVersion: v1
kind: Service
metadata:
namespace: galera-cluster
name: mariadb-galera
labels:
app: mariadb-galera
spec:
type: ClusterIP
ports:
- name: mysql
port: 3306
selector:
app: mariadb-galera
---
apiVersion: v1
kind: Service
metadata:
namespace: galera-cluster
name: mariadb-galera-headless
labels:
app: mariadb-galera
spec:
type: ClusterIP
ports:
- name: galera
port: 4567
- name: ist
port: 4568
- name: sst
port: 4444
selector:
app: mariadb-galera
What you need its #1 communication from App1-x to Mysql router and #2 a VIP/LB from MysqlRoutere to external mysql instances.
Well start with #2 configuration of Mysql instances VIP. You will need a service without selector.
apiVersion: v1
kind: Service
metadata:
name: mysql-service
spec:
ports:
- name: mysql
port: 3306
protocol: TCP
targetPort: 3306
sessionAffinity: None
type: ClusterIP
---
apiVersion: v1
kind: Endpoints
metadata:
name: mysql-service
subsets:
- addresses:
- ip: 192.168.123.130
- ip: 192.168.123.131
- ip: 192.168.123.132
ports:
- name: mysql
port: 3306
protocol: TCP
You don't need LoadBalancer cuz you will connect only inside cluster. So, use ClusterIp instead.
#1 Create MysqlRouter deployment.
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-router
namespace: mysql-router
spec:
replicas: 1
selector:
matchLabels:
app: mysql-router
template:
metadata:
labels:
app: mysql-router
version: v1
spec:
containers:
- name: mysql-router
image: mysql/mysql-router
env:
- name: MYSQL_HOST
value: "mysql-service"
- name: MYSQL_PORT
value: "3306"
- name: MYSQL_USER
value: "root"
- name: MYSQL_PASSWORD
value: "root#123"
imagePullPolicy: Always
ports:
- containerPort: 6446
To connect to external MySQL instances trough VIP/ClusterIP use mysql-service service and if deployment and service is in same namespace use mysql-service as hostname or put there a CLusterIP from kubectl get service mysql-service
apiVersion: v1
kind: Service
metadata:
name: mysql-router-service
namespace: mysql-router
labels:
app: mysql-router
spec:
selector:
app: mysql-router
ports:
- name: mysql
port: 6446
protocol: TCP
targetPort: 6446
type: ClusterIP
You can connect within kubernetes cluster to mysql-router-service hostname in same namespace and outside namespace to mysql-router-service.namespace.svc or outside kubernetes cluster use NodePort or LoadBalancer.