Connecting to MySQL
How a developer reaches the in-cluster Percona MySQL from their laptop using
Sequel Ace, an Auth0-backed kubeconfig, and kubectl port-forward.
The cluster MySQL is not exposed publicly. You tunnel through the Kubernetes API server, which authenticates you via Auth0 and authorises you via namespace-scoped RBAC.
Prerequisites
-
You're a member of the
k8s-cluster-dev-groupAuth0 group. Ask DevOps if you're not. -
You have access to the
persona-mysqlproject in Infisical (at least theprodenvironment, scope/cluster/). That's where the user passwords live. -
Install the tooling:
brew install kubectlbrew install int128/kubelogin/kubelogin # provides `kubectl oidc-login`brew install --cask sequel-ace -
Drop the shared kubeconfig at
~/.kube/config:curl -o ~/.kube/config \https://gitlab.com/onyourmarks/k8s/oym-k8s-cluster/-/raw/main/k8s/kubeconfig
Log in
The kubeconfig is configured to delegate authentication to Auth0 via
kubectl oidc-login. The first command you run will pop a browser:
kubectl get pods -n percona-pxc-operator
Log in with your Auth0 account. The token is cached in your macOS Keychain; you won't be prompted again until it expires.
If the command lists pods, you're in. If you get Forbidden, your Auth0
account is not in the k8s-cluster-dev-group — ask DevOps to add you.
Start the tunnel
kubectl -n percona-pxc-operator port-forward svc/persona-mysql-haproxy 3307:3306
Leave that command running. We use 3307 locally so it doesn't clash with a
MySQL you might have running on 3306 for local dev.
Sequel Ace settings
Create a new connection (Standard tab):
| Field | Value |
|---|---|
| Host | 127.0.0.1 |
| Username | persona-dev, persona-stg, or persona-prod |
| Password | from Infisical (see below) |
| Port | 3307 |
| Database | leave empty — you'll pick after connecting |
Each user is locked to its own database prefix and to data, not schema:
| User | Can access | Can do |
|---|---|---|
persona-dev | databases named dev-* | read and write rows, export dumps |
persona-stg | databases named stg-* | read and write rows, export dumps |
persona-prod | databases named prod-* | read and write rows, export dumps |
The grant is SELECT, INSERT, UPDATE, DELETE, LOCK TABLES, SHOW VIEW, CREATE TEMPORARY TABLES. CREATE, ALTER,
DROP, TRUNCATE and index changes are refused with command denied, and so is importing a dump in Sequel Ace,
because a dump starts with CREATE TABLE. Schema work and imports go through the scripts below.
Where the passwords live
Open Infisical → project persona-mysql → environment prod → folder
/cluster/. The relevant keys:
| User | Infisical key |
|---|---|
persona-dev | PERSONA_MYSQL_PASSWORD_DEV |
persona-stg | PERSONA_MYSQL_PASSWORD_STAGING |
persona-prod | PERSONA_MYSQL_PASSWORD_PROD |
Don't paste passwords into Slack, tickets, or commit them — Sequel Ace can store them in your macOS Keychain via "Add to Favorites".
Imports and schema changes
The port-forward is for looking at and fixing data. Dumps and schema changes go through the scripts in scripts/, which talk to the cluster's write node as root and know the rules of a Galera cluster:
scripts/db-copy prod-my-project stg-my-project # refresh staging from production: drops every table in staging, streams production in
scripts/db-export prod-my-project # local gzip dump, for development or before a risky change
scripts/db-import stg-my-project dump.sql.gz # stream a dump in; add --replace to drop every table first
scripts/db-shell stg-my-project # root mysql shell for ad-hoc DDL
All of them read the root password from Infisical → project persona-mysql → prod → /cluster/ → root, talk to the cluster's write node directly, rewrite ENGINE=MyISAM to InnoDB on the way in, and refuse to write while the cluster is not whole. Writing into a prod-* database with db-copy or db-import --replace needs --force. Why not just import in Sequel Ace: see MySQL (Galera).
After copying production into staging for a Craft project nothing else is needed: the project config and site URLs come from the environment, and the next deploy's craft up (or php craft project-config/apply in the pod) applies the staging config.
Production access
Only DevOps and people with a current operational need should hold the
persona-prod password. If you find yourself reaching for it for a one-off
read-only query, ask whether the same answer is available in Grafana or a
staging copy first.
Troubleshooting
Forbidden when running kubectl: your Auth0 group membership isn't
flowing through. Log out (kubectl oidc-login clean) and back in.
bind: address already in use: something is already on local 3307.
Either kill the other process or pick a different local port
(3308:3306).
Connection refused in Sequel Ace: the port-forward command stopped.
Check the terminal you started it in — it dies if the pod is rescheduled.
Restart it.
Access denied for user 'persona-dev': wrong password, or you're trying
to query a database the user doesn't have grants on (e.g. persona-dev
opening a stg-* schema).