How to connect MySQL running on Kubernetes
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
To connect to MySQL running on Kubernetes, you need a MySQL Deployment or StatefulSet, a Service to expose it, and the correct connection string using the Service's DNS name. Within the cluster, pods connect via mysql-service.namespace.svc.cluster.local:3306. For external access, use kubectl port-forward, a NodePort Service, or a LoadBalancer Service. Store credentials in a Kubernetes Secret and mount them as environment variables.
Deploying MySQL on Kubernetes
Secret for Credentials
Deployment and Service
PersistentVolumeClaim
Connecting from Inside the Cluster
Pods within the same Kubernetes cluster connect using the Service's DNS name:
Full DNS Name
Format: <service-name>.<namespace>.svc.cluster.local
If the application is in a different namespace:
Connecting from Outside the Cluster
Method 1: kubectl port-forward (Development)
This is for development only — the tunnel stops when you close the terminal.
Method 2: NodePort Service
Method 3: LoadBalancer Service (Cloud)
Using a StatefulSet (Production)
For production MySQL deployments, use a StatefulSet with stable network identities:
StatefulSet pods get predictable DNS names: mysql-0.mysql.default.svc.cluster.local.
Running a MySQL Client Pod
Common Pitfalls
- No PersistentVolumeClaim: Without persistent storage, MySQL data is lost when the pod restarts. Always attach a PVC with
ReadWriteOnceaccess mode for MySQL's data directory (/var/lib/mysql). - Using Deployment instead of StatefulSet: Deployments do not guarantee stable network identities or ordered startup/shutdown. For production MySQL, use a StatefulSet which provides stable pod names and persistent volume binding.
- Exposing MySQL externally without security: Using
LoadBalancerorNodePortexposes MySQL to the internet. Always restrict access with network policies, firewall rules, or VPN. Never expose root credentials on a public endpoint. - Hardcoding passwords in YAML: Store MySQL credentials in Kubernetes Secrets, not in plain text in Deployment manifests. Reference secrets with
secretKeyRefin environment variables. - DNS resolution failures: If the application pod cannot resolve
mysql-service, check that the Service exists in the same namespace or use the full DNS name. Runkubectl get svcto verify the Service is created andkubectl execinto the app pod to test DNS withnslookup mysql-service.
Summary
- Deploy MySQL as a Deployment or StatefulSet with a PVC for persistent storage
- Create a
ClusterIPService for internal cluster access - Connect from within the cluster using
mysql-service:3306(or full DNS name for cross-namespace) - Use
kubectl port-forwardfor development access from outside the cluster - Use
NodePortorLoadBalancerfor external access (with proper security) - Store credentials in Kubernetes Secrets and reference them in pod environment variables
Related reading
- How to connect to minikube services from outside
- how to control access for pods/exec only in kubernetes rbac without pods create binded?
- How to control Flink jobs to be distributed/load-balanced properly amongst task-managers in a cluster?
- How to copy file from container in a pod in a specific namespace?
- How to connect to local clickhouse db form container?
- how to connect to localhost9092 from docker container using docker-compose and not using docker bridge
- How to connect to Cassandra inside a Pylons app?
- How to connect to MySQL from the command line

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.