Kubernetes
MySQL
database access
networking
cloud computing

How to access mysql outside my kubernetes cluster?

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

Accessing MySQL from outside a Kubernetes cluster is possible, but the safe answer depends on whether you need temporary admin access, controlled internal-network access, or public internet exposure. In most cases, you should avoid exposing MySQL broadly and instead choose the narrowest access path that satisfies the operational need.

Start With the Safest Option: Port Forwarding

If the goal is occasional admin access from your workstation, kubectl port-forward is usually the simplest and safest choice.

bash
kubectl port-forward svc/mysql 3306:3306 -n database

Then connect locally:

bash
mysql -h 127.0.0.1 -P 3306 -u app_user -p

This approach avoids creating a permanently exposed database endpoint. It is excellent for debugging, migrations, or short-lived maintenance sessions.

Use a Service Type That Matches the Network Boundary

If you need repeatable access from outside the cluster, expose the Service explicitly.

For cloud environments, LoadBalancer is the most common direct path.

yaml
1apiVersion: v1
2kind: Service
3metadata:
4  name: mysql-external
5spec:
6  type: LoadBalancer
7  selector:
8    app: mysql
9  ports:
10    - port: 3306
11      targetPort: 3306

This can provision an external address, but it also increases risk. A database endpoint should rarely be open without strict network controls.

NodePort is another option, but it is usually a lower-level escape hatch rather than the cleanest production design.

Prefer Private Connectivity Over Public Exposure

The best production pattern is often not "expose MySQL to the internet." It is "make the client part of the trusted network."

Examples include:

  • VPN access into the cluster network
  • a bastion host inside the private network
  • cloud-private networking between services
  • a database proxy with authentication and IP restrictions

These patterns reduce the blast radius and keep raw MySQL traffic off the public internet.

Ingress Is Usually Not the Default Answer

Ingress is mainly an HTTP and HTTPS routing tool. MySQL speaks a TCP database protocol, not ordinary web traffic.

Some ingress controllers can proxy arbitrary TCP services, but that is controller-specific configuration, not the usual first answer. If your only goal is exposing port 3306, a Service or private-network path is usually clearer.

Lock Down Security Before You Test Connectivity

However you expose the service, secure it deliberately.

That means at minimum:

  • strong MySQL authentication
  • least-privilege database users
  • network restrictions to trusted source IPs or ranges
  • TLS if traffic leaves a trusted internal boundary
  • secret management for credentials

If the database is reachable from outside the cluster and you have not locked these down, the networking step was incomplete.

Verify the Service and Endpoint Chain

Before blaming MySQL client access, confirm the Kubernetes path:

bash
kubectl get svc -n database
kubectl get endpoints -n database
kubectl get pods -n database -o wide

A surprising number of "external access" problems are really one of these:

  • the Service selector does not match the Pods
  • the container is not listening on the expected interface or port
  • the cloud load balancer has not finished provisioning
  • firewalls or security groups still block the traffic

Common Pitfalls

The most common mistake is exposing MySQL publicly when the real need was only occasional admin access, which kubectl port-forward could have handled safely.

Another mistake is assuming Ingress is the universal answer, even for raw TCP database traffic.

A third issue is opening the network path without restricting source IPs or database permissions.

Finally, if connectivity fails, check the Kubernetes Service, endpoints, and cloud firewall path before changing MySQL itself.

Summary

  • Use kubectl port-forward for temporary admin access whenever possible.
  • Use LoadBalancer or NodePort only when you truly need an externally reachable Service.
  • Prefer private-network access patterns over public exposure for production databases.
  • Ingress is usually not the default solution for MySQL because it is primarily an HTTP tool.
  • Secure the network path, credentials, and MySQL permissions together.
  • Debug the full Service-to-Pod-to-firewall chain before assuming the database is the problem.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track 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.

Practice system design

All Rights Reserved.