Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ rules:
- apiGroups:
- security.openshift.io
resourceNames:
- anyuid
- nonroot-v2
resources:
- securitycontextconstraints
verbs:
Expand Down
4 changes: 2 additions & 2 deletions internal/controller/galera_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,7 @@ func clearOldPodsAttributesOnScaleDown(ctx context.Context, instance *mariadbv1.
// +kubebuilder:rbac:groups="rbac.authorization.k8s.io",resources=rolebindings,verbs=get;list;watch;create;update;patch

// RBAC required to grant the service account role these capabilities
// +kubebuilder:rbac:groups="security.openshift.io",resourceNames=anyuid,resources=securitycontextconstraints,verbs=use
// +kubebuilder:rbac:groups="security.openshift.io",resourceNames=nonroot-v2,resources=securitycontextconstraints,verbs=use
// +kubebuilder:rbac:groups="",resources=pods,verbs=create;delete;get;list;patch;update;watch

// +kubebuilder:rbac:groups=core,resources=persistentvolumeclaims,verbs=get;list;watch;create;update;delete;patch
Expand Down Expand Up @@ -622,7 +622,7 @@ func (r *GaleraReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res
rbacRules := []rbacv1.PolicyRule{
{
APIGroups: []string{"security.openshift.io"},
ResourceNames: []string{"anyuid"},
ResourceNames: []string{"nonroot-v2"},
Resources: []string{"securitycontextconstraints"},
Verbs: []string{"use"},
},
Expand Down
4 changes: 2 additions & 2 deletions internal/controller/galerabackup_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ type GaleraBackupReconciler struct {
// +kubebuilder:rbac:groups="rbac.authorization.k8s.io",resources=rolebindings,verbs=get;list;watch;create;update;patch

// RBAC required to grant the service account role these capabilities
// +kubebuilder:rbac:groups="security.openshift.io",resourceNames=anyuid,resources=securitycontextconstraints,verbs=use
// +kubebuilder:rbac:groups="security.openshift.io",resourceNames=nonroot-v2,resources=securitycontextconstraints,verbs=use
// +kubebuilder:rbac:groups="",resources=pods,verbs=create;delete;get;list;patch;update;watch

// RBAC for PVC
Expand Down Expand Up @@ -172,7 +172,7 @@ func (r *GaleraBackupReconciler) Reconcile(ctx context.Context, req ctrl.Request
rbacRules := []rbacv1.PolicyRule{
{
APIGroups: []string{"security.openshift.io"},
ResourceNames: []string{"anyuid"},
ResourceNames: []string{"nonroot-v2"},
Resources: []string{"securitycontextconstraints"},
Verbs: []string{"use"},
},
Expand Down
4 changes: 2 additions & 2 deletions internal/controller/galerarestore_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ type GaleraRestoreReconciler struct {
// +kubebuilder:rbac:groups="rbac.authorization.k8s.io",resources=rolebindings,verbs=get;list;watch;create;update;patch

// RBAC required to grant the service account role these capabilities
// +kubebuilder:rbac:groups="security.openshift.io",resourceNames=anyuid,resources=securitycontextconstraints,verbs=use
// +kubebuilder:rbac:groups="security.openshift.io",resourceNames=nonroot-v2,resources=securitycontextconstraints,verbs=use
// +kubebuilder:rbac:groups="",resources=pods,verbs=create;delete;get;list;patch;update;watch

// Reconcile handles the reconciliation logic for GaleraRestore resources
Expand Down Expand Up @@ -162,7 +162,7 @@ func (r *GaleraRestoreReconciler) Reconcile(ctx context.Context, req ctrl.Reques
rbacRules := []rbacv1.PolicyRule{
{
APIGroups: []string{"security.openshift.io"},
ResourceNames: []string{"anyuid"},
ResourceNames: []string{"nonroot-v2"},
Resources: []string{"securitycontextconstraints"},
Verbs: []string{"use"},
},
Expand Down
12 changes: 7 additions & 5 deletions internal/mariadb/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ func CreateOrUpdateDbAccountJob(galera *mariadbv1.Galera, account *mariadbv1.Mar
},
},
},
VolumeMounts: getGaleraRootOnlyVolumeMounts(),
VolumeMounts: getGaleraRootOnlyVolumeMounts(),
SecurityContext: GaleraSecurityContext(),
},
},
Volumes: getGaleraRootOnlyVolumes(galera),
Expand Down Expand Up @@ -115,10 +116,11 @@ func DeleteDbAccountJob(galera *mariadbv1.Galera, account *mariadbv1.MariaDBAcco
ServiceAccountName: serviceAccountName,
Containers: []corev1.Container{
{
Name: "mariadb-account-delete",
Image: containerImage,
Command: []string{"/bin/sh", "-c", delCmd},
VolumeMounts: getGaleraRootOnlyVolumeMounts(),
Name: "mariadb-account-delete",
Image: containerImage,
Command: []string{"/bin/sh", "-c", delCmd},
VolumeMounts: getGaleraRootOnlyVolumeMounts(),
SecurityContext: GaleraSecurityContext(),
},
},
Volumes: getGaleraRootOnlyVolumes(galera),
Expand Down
18 changes: 6 additions & 12 deletions internal/mariadb/backup/cronjob.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
batchv1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/ptr"
)

// BackupCronJob returns a CronJob object for the galera backup
Expand Down Expand Up @@ -54,9 +53,6 @@ func getBackupPodTemplate(b *mariadbv1.GaleraBackup, g *mariadbv1.Galera, config
}, {
Name: "DB",
Value: g.Name,
}, {
Name: "KOLLA_CONFIG_STRATEGY",
Value: "COPY_ALWAYS",
}, {
Name: "RETENTION",
Value: retentionTime,
Expand All @@ -79,15 +75,13 @@ func getBackupPodTemplate(b *mariadbv1.GaleraBackup, g *mariadbv1.Galera, config
Subdomain: svcName,
RestartPolicy: corev1.RestartPolicyOnFailure,
ServiceAccountName: b.RbacResourceName(),
SecurityContext: &corev1.PodSecurityContext{
FSGroup: ptr.To[int64](42434),
},
InitContainers: []corev1.Container{},
SecurityContext: mariadb.PodSecurityContext(),
Containers: []corev1.Container{{
Image: g.Spec.ContainerImage,
Name: "backup",
Command: []string{"/usr/bin/dumb-init", "--", "/usr/local/bin/kolla_start"},
Env: environ,
Image: g.Spec.ContainerImage,
Name: "backup",
Command: []string{"/usr/bin/dumb-init", "--", "/var/lib/backup-scripts/backup_galera"},
Env: environ,
SecurityContext: mariadb.GaleraSecurityContext(),
Ports: []corev1.ContainerPort{{
ContainerPort: 4567,
Name: "galera",
Expand Down
24 changes: 8 additions & 16 deletions internal/mariadb/backup/restorepod.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ package mariadbbackup

import (
mariadbv1 "github.com/openstack-k8s-operators/mariadb-operator/api/v1beta1"
mariadb "github.com/openstack-k8s-operators/mariadb-operator/internal/mariadb"
batchv1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/ptr"
)

// RestorePod returns a Pod object for a galera restore CR
Expand All @@ -22,9 +22,6 @@ func RestorePod(restoreCR *mariadbv1.GaleraRestore, backupCR *mariadbv1.GaleraBa
environ := []corev1.EnvVar{{
Name: "DB",
Value: backupCR.Spec.DatabaseInstance,
}, {
Name: "KOLLA_CONFIG_STRATEGY",
Value: "COPY_ALWAYS",
}}

// The restore pod uses the same container image as the configured backup CR,
Expand All @@ -43,19 +40,14 @@ func RestorePod(restoreCR *mariadbv1.GaleraRestore, backupCR *mariadbv1.GaleraBa
Spec: corev1.PodSpec{
RestartPolicy: corev1.RestartPolicyOnFailure,
ServiceAccountName: restoreCR.RbacResourceName(),
SecurityContext: &corev1.PodSecurityContext{
FSGroup: ptr.To[int64](42434),
},
InitContainers: []corev1.Container{},
SecurityContext: mariadb.PodSecurityContext(),
Containers: []corev1.Container{{
Image: backupPodSpec.Containers[0].Image,
Name: "restore",
Command: []string{"/usr/bin/dumb-init", "--", "/bin/bash", "-c",
"sudo -E /usr/local/bin/kolla_set_configs;" +
"sudo -E /usr/local/bin/kolla_copy_cacerts;" +
"sleep infinity"},
Env: environ,
VolumeMounts: RestoreVolumeMounts(backupCR, galeraCR),
Image: backupPodSpec.Containers[0].Image,
Name: "restore",
Command: []string{"/usr/bin/dumb-init", "--", "sleep", "infinity"},
Env: environ,
SecurityContext: mariadb.GaleraSecurityContext(),
VolumeMounts: RestoreVolumeMounts(backupCR, galeraCR),
}},
Volumes: RestoreVolumes(backupCR, galeraCR),
},
Expand Down
33 changes: 11 additions & 22 deletions internal/mariadb/backup/volumes.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,12 @@ const (
)

// baseVolumes returns the volumes shared by both backup and restore pods:
// kolla-config, operator-scripts, backup-scripts, and backup-data PVC.
// var-local, operator-scripts, backup-scripts, and backup-data PVC.
func baseVolumes(b *mariadbv1.GaleraBackup, g *mariadbv1.Galera) []corev1.Volume {
return []corev1.Volume{{
Name: "kolla-config",
Name: "var-local",
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: b.Name + "-backup-config",
},
Items: []corev1.KeyToPath{
{
Key: "backup-config.json",
Path: "config.json",
},
},
},
EmptyDir: &corev1.EmptyDirVolumeSource{},
},
}, {
Name: "operator-scripts",
Expand Down Expand Up @@ -82,8 +72,8 @@ func tlsVolumes(b *mariadbv1.GaleraBackup, g *mariadbv1.Galera) []corev1.Volume
if g.Spec.TLS.Enabled() {
svc := tls.Service{
SecretName: *g.Spec.TLS.SecretName,
CertMount: nil,
KeyMount: nil,
CertMount: ptr.To("/etc/pki/tls/certs/galera.crt"),
KeyMount: ptr.To("/etc/pki/tls/private/galera.key"),
CaMount: nil,
}
volumes = append(volumes, svc.CreateVolume(GaleraCertPrefix))
Expand Down Expand Up @@ -112,20 +102,19 @@ func tlsVolumes(b *mariadbv1.GaleraBackup, g *mariadbv1.Galera) []corev1.Volume
}

// baseVolumeMounts returns the volume mounts shared by both backup and restore pods:
// kolla-config, operator-scripts, and backup-scripts.
// operator-scripts, backup-scripts, and var-local.
func baseVolumeMounts() []corev1.VolumeMount {
return []corev1.VolumeMount{{
MountPath: "/var/lib/kolla/config_files",
ReadOnly: true,
Name: "kolla-config",
}, {
MountPath: "/var/lib/operator-scripts",
ReadOnly: true,
Name: "operator-scripts",
}, {
MountPath: "/var/lib/backup-scripts",
ReadOnly: true,
Name: "backup-scripts",
}, {
MountPath: "/var/local",
Name: "var-local",
}}
}

Expand All @@ -135,8 +124,8 @@ func tlsVolumeMounts(g *mariadbv1.Galera) []corev1.VolumeMount {
if g.Spec.TLS.Enabled() {
svc := tls.Service{
SecretName: *g.Spec.TLS.SecretName,
CertMount: nil,
KeyMount: nil,
CertMount: ptr.To("/etc/pki/tls/certs/galera.crt"),
KeyMount: ptr.To("/etc/pki/tls/private/galera.key"),
CaMount: nil,
}
mounts = append(mounts, svc.CreateVolumeMounts(GaleraCertPrefix)...)
Expand Down
3 changes: 3 additions & 0 deletions internal/mariadb/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,7 @@ const (

// StartupProbeTimeout is the time allowed during the startup probe (in seconds)
StartupProbeTimeout = 240

// MysqlUID is the UID/GID of the mysql user in the container image (from TCIB)
MysqlUID int64 = 42434
)
22 changes: 12 additions & 10 deletions internal/mariadb/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,12 @@ func DbDatabaseJob(galera *mariadbv1.Galera, database *mariadbv1.MariaDBDatabase
ServiceAccountName: serviceAccountName,
Containers: []corev1.Container{
{
Name: "mariadb-database-create",
Image: containerImage,
Command: []string{"/bin/sh", "-c", dbCmd},
Env: scriptEnv,
VolumeMounts: getGaleraRootOnlyVolumeMounts(),
Name: "mariadb-database-create",
Image: containerImage,
Command: []string{"/bin/sh", "-c", dbCmd},
Env: scriptEnv,
VolumeMounts: getGaleraRootOnlyVolumeMounts(),
SecurityContext: GaleraSecurityContext(),
},
},
Volumes: getGaleraRootOnlyVolumes(galera),
Expand Down Expand Up @@ -155,11 +156,12 @@ func DeleteDbDatabaseJob(galera *mariadbv1.Galera, database *mariadbv1.MariaDBDa
ServiceAccountName: serviceAccountName,
Containers: []corev1.Container{
{
Name: "mariadb-database-create",
Image: containerImage,
Command: []string{"/bin/sh", "-c", delCmd},
Env: scriptEnv,
VolumeMounts: getGaleraRootOnlyVolumeMounts(),
Name: "mariadb-database-create",
Image: containerImage,
Command: []string{"/bin/sh", "-c", delCmd},
Env: scriptEnv,
VolumeMounts: getGaleraRootOnlyVolumeMounts(),
SecurityContext: GaleraSecurityContext(),
},
},
Volumes: getGaleraRootOnlyVolumes(galera),
Expand Down
34 changes: 34 additions & 0 deletions internal/mariadb/security.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package mariadb

import (
corev1 "k8s.io/api/core/v1"
"k8s.io/utils/ptr"
)

// PodSecurityContext returns a PodSecurityContext with FSGroup set to the
// mysql UID. This ensures that EmptyDir and ConfigMap volumes are group-owned
// by the mysql user, which is required for pods that write to those volumes
// (e.g. galera pods writing to config-data-generated and var-local, or
// backup/restore pods writing to their working directories).
func PodSecurityContext() *corev1.PodSecurityContext {
return &corev1.PodSecurityContext{
FSGroup: ptr.To(MysqlUID),
}
}

// GaleraSecurityContext returns a SecurityContext for galera and related containers
func GaleraSecurityContext() *corev1.SecurityContext {
return &corev1.SecurityContext{
RunAsUser: ptr.To(MysqlUID),
RunAsGroup: ptr.To(MysqlUID),
RunAsNonRoot: ptr.To(true),
AllowPrivilegeEscalation: ptr.To(false),
ReadOnlyRootFilesystem: ptr.To(false),
Capabilities: &corev1.Capabilities{
Drop: []corev1.Capability{"ALL"},
},
SeccompProfile: &corev1.SeccompProfile{
Type: corev1.SeccompProfileTypeRuntimeDefault,
},
}
}
Loading