Documentation / mysql
NetworkPolicy
The chart renders a Calico projectcalico.org/v3 NetworkPolicy, so it requires
Calico, which is the network fabric the Bahriya Kubernetes Engine installs. It is
additive to your namespace’s existing policies. Where a namespace blocks
cross-namespace ingress by default, this chart adds targeted Allow rules for
MySQL pods so traffic from the right sources gets through.
The allowFrom escape hatch keeps the familiar Kubernetes NetworkPolicyPeer
input shape (ipBlock / namespaceSelector / podSelector); the chart
translates each entry into the equivalent Calico source rule.
Three allow channels, each independently toggleable:
| Channel | Always-on? | Field | Purpose |
|---|---|---|---|
| Same-namespace | yes (when enabled: true) |
(built-in) | App pods in the same namespace can reach MySQL. Required for the chart’s own phpMyAdmin client and for app workloads colocated with their database. |
| Ingress controller | opt-in | allowFromIngressController |
Kong (or other ingress controller) can route external traffic to MySQL. Required for TCPIngress and any phpMyAdmin ingress that routes from Kong’s namespace. |
| Arbitrary peers | opt-in | allowFrom[] |
Full NetworkPolicyPeer escape hatch — cross-namespace tenants, specific labelled pods, IP blocks. |
Same-namespace (default)
When networkPolicy.enabled: true (the default), every pod in the same
namespace can connect to MySQL on port 3306 (and the metrics port, if
enabled). The rule renders as:
- action: Allow
protocol: TCP
source:
selector: all()
destination:
ports: [...]
A Calico source.selector with no namespaceSelector matches every pod and is
implicitly scoped to the NetworkPolicy’s own namespace. This covers:
- App pods deployed alongside MySQL in the same project namespace.
- GR member-to-member traffic in HA mode.
- The chart’s own phpMyAdmin client (when
client.enabled: true).
No configuration needed.
Ingress controller (Kong)
Enable when MySQL needs to be reachable through Kong — typically for one of:
- TCPIngress for external MySQL access. Customers connecting their app to MySQL from outside the cluster (over TLS) via a Kong TCP route.
- phpMyAdmin via Kong from a different namespace. If Kong terminates
HTTP for
db-foo.example.comand the resulting upstream pod is in your MySQL release’s namespace, Kong needs to be able to reach it.
networkPolicy:
enabled: true
allowFromIngressController:
enabled: true
namespace: kong # the namespace Kong runs in
podLabels:
app.kubernetes.io/name: kong # selector for Kong pods
The rule renders as:
- action: Allow
protocol: TCP
source:
namespaceSelector: kubernetes.io/metadata.name == "kong"
selector: app.kubernetes.io/name == "kong"
destination:
ports: [...]
namespaceSelector + selector in the same Calico source are ANDed
— only pods matching BOTH the namespace label and the pod labels.
How to find your Kong pod label
# Check what labels Kong pods carry in your install
kubectl get pods -n kong --show-labels
# Look for: app.kubernetes.io/name=kong, app=kong, or a release-specific label
For Konghq Operator installs the labels may include
app.kubernetes.io/instance: <KongCluster-name>. Adjust podLabels
accordingly — you can list as many key/value pairs as you need; all are ANDed.
Arbitrary cross-namespace peers (allowFrom)
For anything the two convenience channels don’t cover — cross-namespace
tenants, shared-services databases, specific pods labelled across the
cluster — use the allowFrom escape hatch. Each entry is a standard
Kubernetes NetworkPolicyPeer.
Allow an entire namespace
networkPolicy:
allowFrom:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: shared-services
The well-known label kubernetes.io/metadata.name is set automatically by
the kubelet on every namespace, so you don’t have to label namespaces
manually. (Requires Kubernetes 1.22+.)
Allow specific pods across the cluster
networkPolicy:
allowFrom:
- namespaceSelector: {} # any namespace
podSelector:
matchLabels:
mysql.bahriya.cloud/access: "yes"
This lets ops label individual pods anywhere in the cluster to grant them MySQL access without changing the chart’s values.
Allow an IP block (e.g. CI runner subnet)
networkPolicy:
allowFrom:
- ipBlock:
cidr: 10.42.0.0/16
except:
- 10.42.99.0/24
All three together
A realistic production config might look like:
networkPolicy:
enabled: true
allowFromIngressController:
enabled: true
namespace: kong
podLabels:
app.kubernetes.io/name: kong
allowFrom:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: monitoring
podSelector:
matchLabels:
app.kubernetes.io/name: netdata
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: tenant-foo-production
This permits:
- Anything in the same namespace (built-in).
- Kong ingress controller pods.
- Netdata pods in the
monitoringnamespace. - Everything in
tenant-foo-production.
Everything else is blocked by the chart’s NetworkPolicy + the namespace’s default-deny.
Disabling
Two ways:
# (a) Don't render any NetworkPolicy — defer to whatever your namespace ships
networkPolicy:
enabled: false
# (b) Render the NetworkPolicy but with NOTHING allowed — strict deny mode
networkPolicy:
enabled: true
allowFromIngressController:
enabled: false
allowFrom: []
# (Note: same-namespace allow is hard-coded when enabled is true; if you
# want strict deny including same-namespace, set enabled: false and write
# your own NetworkPolicy alongside the release.)
Debugging
If a client can’t reach MySQL after upgrade:
# 1. Confirm the policy exists and what it selects
kubectl get networkpolicy -n <NS> <release>-mysql -o yaml
# 2. Spin up a debug pod in the suspect source namespace
kubectl run -it --rm dbg --image=busybox -n <SOURCE_NS> --restart=Never -- sh
nc -zv <release>-mysql.<NS>.svc.cluster.local 3306
# Connection times out → policy is blocking; success → policy is OK, look elsewhere
# 3. Check that the source pod's namespace has the expected label
kubectl get namespace <SOURCE_NS> --show-labels
# Look for kubernetes.io/metadata.name=<SOURCE_NS> (auto-set on 1.22+)
# 4. If using podLabels in allowFromIngressController, verify Kong's labels
kubectl get pods -n kong --show-labels