I have deployed MySQL in my Kubernetes cluster. It works like fine. But I am not aware of how to access or connect MySQL service to other applications. I found that MySQL deployment is not browser-supported.
when I call the MySQL server on the browser using IP:nodeport, I found the following error
J���
5.7.37����!bo.;�ÿÿ�ÿÁ����������rBPvNbCJ�mysql_native_password�!��ÿ„#08S01Got packets out of order
I can access MySQL server through Kubernetes dashboard's pod shell using MySQL user and password
You can try deploying the MySQL client on Kubernetes and connect using it.
MySQL client like : Adminer, phpMyadmin etc
Adminer example :
apiVersion: apps/v1
kind: Deployment
metadata:
name: adminer
labels:
app: adminer
spec:
selector:
matchLabels:
app: adminer
template:
metadata:
labels:
app: adminer
spec:
containers:
- name: adminer
image: adminer:4.6.3
ports:
- containerPort: 8080
env:
- name: ADMINER_DESIGN
value: "pappu687"
---
apiVersion: v1
kind: Service
metadata:
name: adminer-svc
spec:
selector:
app: adminer
ports:
- protocol: TCP
port: 8080
targetPort: 8080
You can expose this deployment with service type Nodeport or Port forwarding.
kubectl port-forward svc/adminer-svc 8080:8080
Open the localhost:8080
Once the service is exposed you can access the UI in the browser and from there you can access the MySQL database over the service name.
Read more about adminer : https://www.adminer.org/
Related
Hi I've deployed single MySQL db instance in Azure via the YAML file in Azure Kubernetes service. I can get into the container via CLI when I'm inside my cluster. I would like to connect with db instance via external client like MySQL Workbench or Sqlelectron or others, outside the cluster. As I found out it's possible via correctly exposing DB instance by Service configuration.
My deployment of single instance MySQL DB instance is:
apiVersion: v1
kind: Service
metadata:
name: mysql-db-testing-service
namespace: testing
spec:
type: ClusterIP
ports:
- port: 3306
#targetPort: 3306
selector:
app: mysql-db-testing
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-db-testing
namespace: testing
spec:
selector:
matchLabels:
app: mysql-db-testing
replicas: 1
strategy:
type: Recreate
template:
metadata:
labels:
app: mysql-db-testing
spec:
containers:
- name: mysql-db-container-testing
image: mysql:8.0.31
env:
- name: MYSQL_ROOT_PASSWORD
value: test12345
ports:
- containerPort: 3306
name: mysql-port
volumeMounts:
- mountPath: "/var/lib/mysql"
name: mysql-persistent-storage
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: azure-managed-disk-pvc-mysql-testing
nodeSelector:
env: preprod
As I've mentioned I can get to the container via CLI:
Console output regarding the working pod with db looks like:
Console output regarding the service:
Is there something missing in my deployment YAML file or maybe there are missing some fields? How can I expose db to the outside world? I would be grateful for help.
You are using ClusterIP service(line 7). The kubernetes ClusterIP service is not made to allow you to access a pod outside of the cluster. ClusterIP just provide a way to have a not changing IP for other internal services to access your pod.
You should use instead Loadbalanacer.
Cf https://stackoverflow.com/a/48281728/8398523 for differences
You have used the type: ClusterIP so it won't expose the MYSQL outside the cluster ideally, your Microservices running in the cluster will be able to access it however you can not use it externally.
To expose the service we generally have to use the type: LoadBalancer. It will directly expose your MySQL service internet and from your local workbench, you can connect to DB running on K8s.
If you really don't want to expose the MySQL service directly to internet you can deploy the adminer.
So traffic will flow like
internet > adminer > internal communication > MySQL service > MySQL POD
YAML file to deploy and get the UI output directly in the browser, it will ask of MySQL DB username, password, Host (mysql-db-testing-service.testing.svc.cluster.local) to connect
apiVersion: apps/v1
kind: Deployment
metadata:
name: adminer
labels:
app: adminer
spec:
selector:
matchLabels:
app: adminer
template:
metadata:
labels:
app: adminer
spec:
containers:
- name: adminer
image: adminer:4.6.3
ports:
- containerPort: 8080
env:
- name: ADMINER_DESIGN
value: "pappu687"
---
apiVersion: v1
kind: Service
metadata:
name: adminer-svc
spec:
type: ClusterIP(Internally to cluster)/LoadBalancer (Expose to internet)
selector:
app: adminer
ports:
- protocol: TCP
port: 8080
targetPort: 8080
Port-forward for local access or use service type: LoadBalancer
kubectl port-forward svc/adminer-svc 8080:8080
Open localhost:8080 in browser
I deployed a MySQL pod with the example from the kubernetes website: https://kubernetes.io/docs/tasks/run-application/run-single-instance-stateful-application/
I can access the pod from the pod network but not from outside the cluster, how can I achieve this? I would want to access the service via MySQL Workbench for easier editing of the Database.
I already tried to setup a NodePort service like this:
apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
ports:
- port: 3306
targetPort: 3006
nodePort: 30003
selector:
app: mysql
type: NodePort
with the goal to access the service at :30003 but that does not work.
apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
ports:
- port: 3306
targetPort: 3006
nodePort: 30003
selector:
app: mysql
type: NodePort
the targetPort is 3006 instead of 3306, it was a typo.
I deployed a mysql service in Kubernetes and created a database(db1) and a custom user('foo'#'localhost' identified by 'bar') with all privileges. I can verify it.
but somehow my Flask application cannot connect to it. So, I turned on the debug mode and got
sqlalchemy.exc.OperationalError
sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (2003, "Can't connect to MySQL server on 'localhost' ([Errno 99] Address not available)")
(Background on this error at: http://sqlalche.me/e/13/e3q8)
This never happens in Linux machines. This is my DATABASE_URL mysql+pymysql://foo:bar#localhost:3306/db1
Is there anything I am doing wrong? I am new to kubernetes, I don't even know how to go about debugging it. Please let me know if I am not providing enough information.
Thank you.
[EDITED]
mysql-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
labels:
app: mysql
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql:5.6
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "123"
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-volumeclaim
mysql-service.yaml
apiVersion: v1
kind: Service
metadata:
name: mysql
labels:
app: mysql
spec:
type: ClusterIP
ports:
- port: 3306
selector:
app: mysql
I am a newbie on Kubernetes and try to generate 2 pods including front-end application and back-end mysql. First I make a yaml file which contains both application and mysql server like below,
apiVersion: v1
kind: Pod
metadata:
name: blog-system
spec:
containers:
- name: blog-app
image: blog-app:latest
imagePullPolicy: Never
ports:
- containerPort: 8080
args: ["-t", "-i"]
link: blog-mysql
- name: blog-mysql
image: mysql:latest
env:
- name: MYSQL_ROOT_PASSWORD
value: password
- name: MYSQL_PASSWORD
value: password
- name: MYSQL_DATABASE
value: test
ports:
- containerPort: 3306
The mysql jdbc url of front-end application is jdbc:mysql://localhost:3306/test. And pod generation is successful. The application and mysql are connected without errors. And this time I seperate application pod and mysql pod into 2 yaml files.
== pod-app.yaml
apiVersion: v1
kind: Pod
metadata:
name: blog-app
spec:
selector:
app: blog-mysql
containers:
- name: blog-app
image: app:latest
imagePullPolicy: Never
ports:
- containerPort: 8080
args: ["-t", "-i"]
link: blog-mysql
== pod-db.yaml
apiVersion: v1
kind: Pod
metadata:
name: blog-mysql
labels:
app: blog-mysql
spec:
containers:
- name: blog-mysql
image: mysql:latest
env:
- name: MYSQL_ROOT_PASSWORD
value: password
- name: MYSQL_PASSWORD
value: password
- name: MYSQL_DATABASE
value: test
ports:
- containerPort: 3306
But the front-end application can not connect to mysql pod. It throws the connection exceptions. I am afraid the mysql jdbc url has some incorrect values or the yaml value has inappropriate values. I hope any advices.
In the working case since same pod has two containers they are able to talk using localhost but in the second case since you have two pods you can not use localhost anymore. In this case you need to use the pod IP of the mysql pod in the frontend application. But problem with using POD IP is that it may change. Better is to expose mysql pod as service and use service name instead of IP in the frontend application. Check this guide
For this you need to write service for exposing the db pod.
There are 4 types of services.
ClusterIP
NodePort
LoadBalancer
ExternalName
Now you need only inside the cluster then use ClusterIP
For reference use following yaml file.
kind: Service
apiVersion: v1
metadata:
name: mysql-svc
spec:
type: ClusterIP
ports:
- port: 3306
targetPort: 3306
selector:
app: blog-mysql
Now you will be access this pod using mysql-svc:3306
Refer this in blog-app yaml with
env:
- name: MYSQL_URL
value: mysql-svc
- name: MYSQL_PORT
value: 3306
For more info use Url :https://kubernetes.io/docs/concepts/services-networking/service/
Pods created will have dns configured in the following manner
pod_name.namespace.svc.cluster.local
In your case assuming these pods are in default namespace your jdbc connection string will be
jdbc:mysql://blog-mysql.default.svc.cluster.local:3306/test
Refer: https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pods
Like Arghya Sadhu and Sachin Arote suggested you can always create a service and deployment. Service and deployment helps you in the cases where you have more than one replicas of pods and service takes care of the load-balancing.
I have created mysql k8s container and nodejs k8s container under same namespace.I can't able to connect mysql db.(sequalize)
I have tried to connect using '''http://mysql.e-commerce.svc.cluster.local:3306'''.But i got "SequelizeHostNotFoundError" error.
Here is my service and deployment yaml files.
kind: Service
metadata:
labels:
app: mysql
name: mysql
namespace: e-commerce
spec:
type: NodePort
ports:
- port: 3306
targetPort: 3306
nodePort: 30306
selector:
app: mysql
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: mysql
namespace: e-commerce
spec:
replicas: 1
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql:5.6
name: mysql-container
env:
- 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```
From the ClusterIP worked for me or better way to go with the host name of the local cluster service ex. db-mysql.default.svc.cluster.local. This way if you cluster restarts and your IP changes, then you got it covered.
You are trying to access database with http protocol, leave it or change with mysql://ip:3306. Some clients won't accept DNS name for databases so you can check ClusterIP of service and try that IP too.
As mentioned by community member FL3SH you can change your spec.type to clusterIP.
You can reproduce this task using stable helm chart wordpress/mysql.
For newly created pods:
mysql-mariadb-0
mysql-wordpress
and services:
mysql-mariadb
mysql-wordpress
After successfully deployment you can verify if your service is working from the mysql-wordpress pod by running:
kubectl exec -it mysql-wordpress-7cb4958654-tqxm6 -- /bin/bash
In addition, you can install additional tools like nslooukp, telnet:
apt-get update && apt-get install dnsutils telnet
Services and connectivity with db you can test by running f.e. those commands:
nslookup mysql-mariadb
telnet mysql-mariadb 3306
mysql -uroot -hmysql-mariadb -p<your_db_password>
example output:
nslookup mysql-mariadb
Server: 10.125.0.10
Address: 10.125.0.10#53
Non-authoritative answer:
Name: mysql-mariadb.default.svc.cluster.local
Address: 10.125.0.76
mysql -u root -hmysql-mariadb -p<your_db_password>
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 2068
Server version: 10.1.40-MariaDB Source distribution
You should be able to connect using service name or using ip address.
Inside this helm chart you can find also template for statefulset in order to create mysql pods.
Update
From the second pod f.e. ubuntu run this example - Node.js Mysql, install nodes.js and create connection to the database demo_db_connection.js
example:
var mysql = require('mysql');
var con = mysql.createConnection({
host: "mysql-mariadb",
user: "root",
password: "yourpassword"
});
con.connect(function(err) {
if (err) throw err;
console.log("Connected!");
});
run it:
root#ubuntu:~/test# node demo_db_connection.js
Connected!
Try with:
kind: Service
metadata:
labels:
app: mysql
name: mysql
namespace: e-commerce
spec:
clusterIP: None
type: ClusterIP
ports:
- port: 3306
targetPort: 3306
selector:
app: mysql
with the same connection string.