This is an automated email from the ASF dual-hosted git repository.
villebro pushed a commit to branch main
in repository
https://gitbox.apache.org/repos/asf/superset-kubernetes-operator.git
The following commit(s) were added to refs/heads/main by this push:
new c506c3b fix(lifecycle): default MySQL tool image to mysql:8.4 (#389)
c506c3b is described below
commit c506c3bb65f14c168873a311e3a7d794650672f1
Author: Younsung Lee <[email protected]>
AuthorDate: Sat Sep 26 00:56:45 2026 +0900
fix(lifecycle): default MySQL tool image to mysql:8.4 (#389)
* fix(lifecycle): default MySQL tool image to mysql:8.4
The default image for MySQL seed Jobs and the createDatabase init
container was mysql:8-alpine, a tag that does not exist on Docker Hub, so
both failed with an image pull error unless an image was set explicitly.
Use mysql:8.4 (LTS), which ships mysql, mysqldump, and a mysql user with
UID 999 that the non-root helper security context already assumes.
Staging instances that seed from MySQL with the default image re-seed
once after upgrading, because the seed image is part of the seed task
checksum.
Signed-off-by: younsl <[email protected]>
* docs: add PR reference and attribution to MySQL image changelog
Signed-off-by: younsl <[email protected]>
---------
Signed-off-by: younsl <[email protected]>
---
api/v1alpha1/shared_types.go | 2 +-
api/v1alpha1/superset_types.go | 2 +-
docs/reference/api-reference.md | 4 ++--
docs/reference/releases.md | 1 +
docs/user-guide/configuration.md | 2 +-
docs/user-guide/lifecycle.md | 2 +-
internal/common/names.go | 2 +-
internal/controller/lifecycle_create_db.go | 2 +-
internal/controller/lifecycle_seed.go | 2 +-
internal/controller/seed_test.go | 4 ++--
10 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/api/v1alpha1/shared_types.go b/api/v1alpha1/shared_types.go
index c121b69..8c60c62 100644
--- a/api/v1alpha1/shared_types.go
+++ b/api/v1alpha1/shared_types.go
@@ -78,7 +78,7 @@ type ImageOverrideSpec struct {
// has no Superset-specific repository default — the operator selects a
// context-appropriate default at reconcile time when fields are omitted (e.g.,
// `nginx:alpine` for the maintenance page, `postgres:17-alpine` /
-// `mysql:8-alpine` for the seed Job). Use this type for non-Superset images.
+// `mysql:8.4` for the seed Job). Use this type for non-Superset images.
type ContainerImageSpec struct {
// Container image repository.
// +optional
diff --git a/api/v1alpha1/superset_types.go b/api/v1alpha1/superset_types.go
index 201e550..385bf35 100644
--- a/api/v1alpha1/superset_types.go
+++ b/api/v1alpha1/superset_types.go
@@ -599,7 +599,7 @@ type SeedTaskSpec struct {
PostSeedSQL []string `json:"postSeedSQL,omitempty"`
// Image for the seed Job. Defaults to postgres:17-alpine (PostgreSQL)
- // or mysql:8-alpine (MySQL) based on source.type. Partial specs (e.g.,
+ // or mysql:8.4 (MySQL) based on source.type. Partial specs (e.g.,
// only `tag` set) inherit the type-appropriate default for omitted
fields.
// +optional
Image *ContainerImageSpec `json:"image,omitempty"`
diff --git a/docs/reference/api-reference.md b/docs/reference/api-reference.md
index ca7c89c..30fdda5 100644
--- a/docs/reference/api-reference.md
+++ b/docs/reference/api-reference.md
@@ -299,7 +299,7 @@ ContainerImageSpec defines a generic container image.
Unlike ImageSpec, it
has no Superset-specific repository default — the operator selects a
context-appropriate default at reconcile time when fields are omitted (e.g.,
`nginx:alpine` for the maintenance page, `postgres:17-alpine` /
-`mysql:8-alpine` for the seed Job). Use this type for non-Superset images.
+`mysql:8.4` for the seed Job). Use this type for non-Superset images.
@@ -995,7 +995,7 @@ _Appears in:_
| `excludeTables` _string array_ | Tables to exclude entirely from the dump
(schema and data). | | Optional: \{\} <br /> |
| `excludeTableData` _string array_ | Tables where schema is dumped but data
is not. Useful for large tables needed by migrations but not for testing (e.g.,
"logs", "query"). | | Optional: \{\} <br /> |
| `postSeedSQL` _string array_ | SQL statements to execute against the target
database after seeding. Useful for sanitizing seeded data (e.g., disabling
alerts, deleting OAuth tokens, masking PII). | | Optional: \{\} <br /> |
-| `image` _[ContainerImageSpec](#containerimagespec)_ | Image for the seed
Job. Defaults to postgres:17-alpine (PostgreSQL) or mysql:8-alpine (MySQL)
based on source.type. Partial specs (e.g., only `tag` set) inherit the
type-appropriate default for omitted fields. | | Optional: \{\} <br /> |
+| `image` _[ContainerImageSpec](#containerimagespec)_ | Image for the seed
Job. Defaults to postgres:17-alpine (PostgreSQL) or mysql:8.4 (MySQL) based on
source.type. Partial specs (e.g., only `tag` set) inherit the type-appropriate
default for omitted fields. | | Optional: \{\} <br /> |
| `podTemplate` _[PodTemplate](#podtemplate)_ | Pod and container template for
the seed task Job. | | Optional: \{\} <br /> |
| `podRetention` _[PodRetentionSpec](#podretentionspec)_ | Retention policy
for completed seed Jobs and their Pods. | | Optional: \{\} <br /> |
diff --git a/docs/reference/releases.md b/docs/reference/releases.md
index 7179eaa..265b41f 100644
--- a/docs/reference/releases.md
+++ b/docs/reference/releases.md
@@ -35,6 +35,7 @@ This page tracks notable changes in Apache Superset
Kubernetes Operator releases
### Fixed
+- The default MySQL tool image for the seed task and the `createDatabase` init
container is now `mysql:8.4`. The previous default, `mysql:8-alpine`, does not
exist on Docker Hub, so MySQL seeding and database auto-creation failed with an
image pull error unless an image was set explicitly. Staging instances that
seed from MySQL with the default image re-seed once after upgrading, because
the seed image is part of the seed task checksum
([#389](https://github.com/apache/superset-kubernete [...]
- The operator-managed maintenance page now sets `seccompProfile:
RuntimeDefault` on its container, so it is admitted in namespaces enforcing the
restricted Pod Security Standard (its other hardened defaults were already set,
but the missing seccomp profile caused rejection)
([#362](https://github.com/apache/superset-kubernetes-operator/pull/362),
[@villebro](https://github.com/villebro)).
- The operator no longer crash-loops on clusters where Gateway API is
installed but serves only `v1beta1`: optional-API detection now pins the
version the operator actually uses (`HTTPRoute` v1, `ServiceMonitor` v1)
instead of matching any version of the Kind
([#361](https://github.com/apache/superset-kubernetes-operator/pull/361),
[@villebro](https://github.com/villebro)).
- Component Services of type `NodePort` or `LoadBalancer` that do not pin
`service.nodePort` no longer churn: the operator now preserves the
apiserver-allocated node port across reconciles instead of triggering a
re-allocation each time, which previously changed the external port and broke
external access
([#360](https://github.com/apache/superset-kubernetes-operator/pull/360),
[@villebro](https://github.com/villebro)).
diff --git a/docs/user-guide/configuration.md b/docs/user-guide/configuration.md
index 3c5c476..110e765 100644
--- a/docs/user-guide/configuration.md
+++ b/docs/user-guide/configuration.md
@@ -188,7 +188,7 @@ Requirements and caveats:
- **Structured metastore only.** Rejected by CRD validation when `uri` or
`uriFrom` is set — the operator needs the individual host/database/username
fields to issue admin-level statements.
- **Privileges.** The configured metastore user must have `CREATEDB`
(PostgreSQL) or `CREATE` (MySQL) privilege on the server. The init container
connects to the `postgres` admin database (PostgreSQL) or runs `CREATE DATABASE
IF NOT EXISTS` (MySQL).
-- **Init container image.** The operator uses `postgres:17-alpine` or
`mysql:8-alpine` (matching the seed task) — the Superset image is not assumed
to ship database client tools.
+- **Init container image.** The operator uses `postgres:17-alpine` or
`mysql:8.4` (matching the seed task) — the Superset image is not assumed to
ship database client tools.
- **Resources and securityContext are inherited from
`spec.lifecycle.podTemplate.container`.** Whatever you set on
`spec.lifecycle.podTemplate.container.resources` and
`spec.lifecycle.podTemplate.container.securityContext` is applied to the
create-database init container. This lets you satisfy strict admission policies
(Pod Security Standards `restricted`, Kyverno, OPA) without a dedicated knob.
The init container also defaults to a non-root UID (matching its DB-tool
image), so it starts [...]
- **Redundant with `lifecycle.seed`.** Seed already drops and re-creates its
target database every time it runs, so toggling `createDatabase` on alongside
seed is harmless but does no extra work in practice — the init container
detects the existing database (created by seed) and no-ops.
diff --git a/docs/user-guide/lifecycle.md b/docs/user-guide/lifecycle.md
index ec4f287..1b2327f 100644
--- a/docs/user-guide/lifecycle.md
+++ b/docs/user-guide/lifecycle.md
@@ -537,7 +537,7 @@ The seed pod uses a database-tool image (not the Superset
image):
| Source type | Default image |
|---|---|
| `postgresql` | `postgres:17-alpine` |
-| `mysql` | `mysql:8-alpine` |
+| `mysql` | `mysql:8.4` |
Override with `seed.image` if you need additional tools.
diff --git a/internal/common/names.go b/internal/common/names.go
index 338e28a..56c13e2 100644
--- a/internal/common/names.go
+++ b/internal/common/names.go
@@ -96,7 +96,7 @@ const (
// Seed default images.
const (
SeedImagePostgres = "postgres:17-alpine"
- SeedImageMySQL = "mysql:8-alpine"
+ SeedImageMySQL = "mysql:8.4"
)
// Env var names for operator-managed environment variables.
diff --git a/internal/controller/lifecycle_create_db.go
b/internal/controller/lifecycle_create_db.go
index a61940e..9d3403e 100644
--- a/internal/controller/lifecycle_create_db.go
+++ b/internal/controller/lifecycle_create_db.go
@@ -93,7 +93,7 @@ echo "Ensured MySQL database $SUPERSET_OPERATOR__DB_NAME
exists"`
// Standards, Kyverno, OPA) by configuring lifecycle hardening once. The
// image stays operator-default — the migrate task uses the Superset image,
// but this init container needs psql/mysql clients (postgres:17-alpine /
-// mysql:8-alpine).
+// mysql:8.4).
//
// The DB-tool images run as root by default, so an inherited pod-level
// runAsNonRoot would make kubelet reject this container with
diff --git a/internal/controller/lifecycle_seed.go
b/internal/controller/lifecycle_seed.go
index 92f56eb..24a88d5 100644
--- a/internal/controller/lifecycle_seed.go
+++ b/internal/controller/lifecycle_seed.go
@@ -195,7 +195,7 @@ func collectSeedEnvVars(superset
*supersetv1alpha1.Superset) []corev1.EnvVar {
}
// resolveSeedImage determines the image for the seed pod. Defaults are
-// type-aware: postgres:17-alpine for PostgreSQL sources, mysql:8-alpine for
+// type-aware: postgres:17-alpine for PostgreSQL sources, mysql:8.4 for
// MySQL. Partial user specs inherit the default repository or tag for omitted
// fields rather than the Superset image (which would be incorrect for a
// database tooling container).
diff --git a/internal/controller/seed_test.go b/internal/controller/seed_test.go
index 88bd4a1..3792c54 100644
--- a/internal/controller/seed_test.go
+++ b/internal/controller/seed_test.go
@@ -629,8 +629,8 @@ func TestResolveSeedImage(t *testing.T) {
img := resolveSeedImage(seed)
- if img.Repository != "mysql" || img.Tag != "8-alpine" {
- t.Errorf("expected mysql:8-alpine, got: %s:%s",
img.Repository, img.Tag)
+ if img.Repository != "mysql" || img.Tag != "8.4" {
+ t.Errorf("expected mysql:8.4, got: %s:%s",
img.Repository, img.Tag)
}
})