Home > Software engineering >  Can't connect to a local MySQL server using Kubernetes
Can't connect to a local MySQL server using Kubernetes

Time:01-06

I am developing an application which should store some results daily to MySQL database. MySQL server is hosted on my local machine, is outside the Kubernetes cluster, and by using the following docker command I can execute my script and store the results in the database:

docker run --network="host" <image:id>

I could not do this before I added --network="host" in my command line.

However, I would like to access my server by using Kubernetes, such that I can schedule the tasks and run multiple models. I fail to connect to my server with Kubernetes pod even though the credentials to log in to the server has not changed.

When executing the

kubectl logs <pod:name>

command I get the following error message:

sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (2003, "Can't connect to MySQL server on '127.0.0.1' ([Errno 111] Connection refused)")

From my local machine terminal I can log in to the MySQL server, so I know that the server is listening. Also, the issue is not related to the firewall, as the UFW is turned off.

I am trying to connect to the MySQL server by using the following code:

class Connector():
    def __init__(self) -> None:

        # Using kubes env
        self.config = {'USER': os.environ["SQL_SERVER_USERNAME"],
                       'PASSWORD': os.environ["SQL_SERVER_PASSWORD"],
                       'HOST': os.environ["SQL_SERVER_HOST"],
                       'DATABASE': os.environ["SQL_SERVER_DATABASE"],
                       'PORT': os.environ["SQL_SERVER_PORT"]}

    def connect(self):
            cnx = create_engine(
                f"mysql pymysql://{self.config['USER']}:{self.config['PASSWORD']}@{self.config['HOST']}:{self.config['PORT']}/{self.config['DATABASE']}")
        return cnx

Here is the Deployment yaml file:

apiVersion: v1
kind: Service
metadata:
  name: k8s-rain-clustering-service
spec:
  selector:
    app: k8s-rain-clustering
  ports:
  - protocol: "TCP"
    port: 6000
    targetPort: 5000
  type: LoadBalancer

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: k8s-rain-clustering
spec:
  selector:
    matchLabels:
      app: k8s-rain-clustering
  replicas: 1
  template:
    metadata:
      labels:
        app: k8s-rain-clustering
    spec:
      containers:
      - name: k8s-rain-clustering
        image: <my image>
        env:
          - name: SQL_SERVER_HOST
            value:  127.0.0.1
          - name: SQL_SERVER_PORT
            value:  "3306"
          - name: SQL_SERVER_USERNAME
            value:  root
          - name: SQL_SERVER_PASSWORD
            value:  root
          - name: SQL_SERVER_DATABASE
            value: coat_project
        imagePullPolicy: Always
        ports:
        - containerPort: 4025
      imagePullSecrets:
        - name: k8s-registry-secret

I suspect that I have something wrong in my yaml file, but I can not figure out what is the problem. I would be happy if somebody can assist me with this matter and point me to the right direction. Thank you in advance.

CodePudding user response:

you can't access localhost from the docker. You need to use host.docker.internal instead of 127.0.0.1 as database host like this:

        env:
          - name: SQL_SERVER_HOST
            value:  host.docker.internal

Info

CodePudding user response:

Thank you SuleymanSah, this did the trick. Besides that, I had to do a few more steps, namely:

  1. I had to allow Minikube VM to access the MySQL local server by creating the user with minikube's IP address and granting all the privileges to the desired database
  2. I had to link the minikube's IP address to the host.docker.internal by running the following commands:
minikube ssh
sudo mkdir -p /var/run/mysqld
sudo mount --bind /var/run/mysqld /var/run/mysqld
sudo sh -c "echo $(ip route show default | awk '/default/ {print $3}') host.docker.internal >> /etc/hosts"
  1. Lastly, I had to edit the yaml file to also include hostNetwork.
spec:
  selector:
    matchLabels:
      app: k8s-rain-clustering
  replicas: 1
  template:
    metadata:
      labels:
        app: k8s-rain-clustering
    spec:
      hostNetwork:  True
      containers:
      - name: k8s-rain-clustering
      ....
  • Related