Skip to content

Commit

Permalink
Add Support for MariaDB Replication (#1383)
Browse files Browse the repository at this point in the history
Signed-off-by: SK Ali Arman <arman@appscode.com>
  • Loading branch information
sheikh-arman authored Jan 28, 2025
1 parent 7ad4392 commit e5366d5
Show file tree
Hide file tree
Showing 11 changed files with 3,596 additions and 4 deletions.
2 changes: 2 additions & 0 deletions apis/catalog/v1alpha1/mariadb_version_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,14 @@ func (m MariaDBVersion) ValidateSpecs() error {
if m.Spec.Version == "" ||
m.Spec.DB.Image == "" ||
m.Spec.Exporter.Image == "" ||
m.Spec.Maxscale.Image == "" ||
m.Spec.InitContainer.Image == "" ||
m.Spec.Coordinator.Image == "" {
return fmt.Errorf(`atleast one of the following specs is not set for mariadbversion "%v":
spec.version,
spec.db.image,
spec.exporter.image,
spec.maxscale.image,
spec.initContainer.image,
spec.coordinator.image.`, m.Name)
}
Expand Down
10 changes: 10 additions & 0 deletions apis/catalog/v1alpha1/mariadb_version_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ type MariaDBVersionSpec struct {
Version string `json:"version"`
// Database Image
DB MariaDBVersionDatabase `json:"db"`
// Maxscale Image
Maxscale MariaDBVersionMaxscale `json:"maxscale"`
// Exporter Image
Exporter MariaDBVersionExporter `json:"exporter"`
// Coordinator Image
Expand Down Expand Up @@ -87,6 +89,14 @@ type MariaDBVersionDatabase struct {
Image string `json:"image"`
}

// MariaDBVersionMaxscale is the mariadb maxscale image
type MariaDBVersionMaxscale struct {
Image string `json:"image"`
// SecurityContext is for the additional config for the maxscale container
// +optional
SecurityContext SecurityContext `json:"securityContext"`
}

// MariaDBVersionExporter is the image for the MariaDB exporter
type MariaDBVersionExporter struct {
Image string `json:"image"`
Expand Down
42 changes: 40 additions & 2 deletions apis/catalog/v1alpha1/openapi_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions apis/catalog/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions apis/kubedb/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,23 @@ const (
MariaDBMetricsExporterTLSVolumeName = "metrics-exporter-config"
MariaDBMetricsExporterConfigPath = "/etc/mysql/config/exporter"
MariaDBDataVolumeName = "data"
DatabasePodPrimaryComponent = "Primary"
DatabasePodMasterComponent = "Master"
DatabasePodSlaveComponent = "Slave"

// Maxscale
MaxscaleCommonName = "mx"
MaxscaleContainerName = "maxscale"
MaxscaleInitContainerName = "maxscale-init"
MaxscaleServerName = "server"
MaxscaleConfigName = "config"
MaxscaleConfigPath = "/etc/maxscale.cnf.d"
MaxscaleDefaultConfigName = "default-config"
MaxscaleDefaultConfigPath = "/etc/maxscale"
MaxscaleDataVolumeName = "data"
MaxscaleDataVolumePath = "/var/lib/maxscale"
MaxscaleUIPort = 8989
MaxscaleUIPortName = "ui"

// =========================== SingleStore Constants ============================
SinglestoreDatabasePortName = "db"
Expand Down
140 changes: 139 additions & 1 deletion apis/kubedb/v1/mariadb_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ func (m MariaDB) OffshootName() string {
return m.Name
}

func (m MariaDB) OffshootMaxscaleName() string {
return meta_util.NameWithSuffix(m.Name, kubedb.MaxscaleCommonName)
}

func (m MariaDB) OffshootSelectors() map[string]string {
return map[string]string{
meta_util.NameLabelKey: m.ResourceFQN(),
Expand All @@ -66,18 +70,38 @@ func (m MariaDB) OffshootSelectors() map[string]string {
}
}

func (m MariaDB) OffshootMaxscaleSelectors() map[string]string {
return map[string]string{
meta_util.NameLabelKey: m.ResourceFQN(),
meta_util.InstanceLabelKey: m.OffshootMaxscaleName(),
meta_util.ManagedByLabelKey: kubedb.GroupName,
}
}

func (m MariaDB) OffshootLabels() map[string]string {
return m.offshootLabels(m.OffshootSelectors(), nil)
}

func (m MariaDB) OffshootMaxscaleLabels() map[string]string {
return m.offshootLabels(m.OffshootMaxscaleSelectors(), nil)
}

func (m MariaDB) PodLabels() map[string]string {
return m.offshootLabels(m.OffshootSelectors(), m.Spec.PodTemplate.Labels)
}

func (m MariaDB) MaxscalePodLabels() map[string]string {
return m.offshootLabels(m.OffshootMaxscaleSelectors(), m.Spec.PodTemplate.Labels)
}

func (m MariaDB) PodControllerLabels() map[string]string {
return m.offshootLabels(m.OffshootSelectors(), m.Spec.PodTemplate.Controller.Labels)
}

func (m MariaDB) MaxscalePodControllerLabels() map[string]string {
return m.offshootLabels(m.OffshootMaxscaleSelectors(), m.Spec.PodTemplate.Controller.Labels)
}

func (m MariaDB) SidekickLabels(skName string) map[string]string {
return meta_util.OverwriteKeys(nil, kubedb.CommonSidekickLabels(), map[string]string{
meta_util.InstanceLabelKey: skName,
Expand Down Expand Up @@ -124,10 +148,26 @@ func (m MariaDB) IsCluster() bool {
return pointer.Int32(m.Spec.Replicas) > 1
}

func (m MariaDB) IsGaleraCluster() bool {
return m.Spec.Topology != nil &&
m.Spec.Topology.Mode != nil &&
*m.Spec.Topology.Mode == MariaDBModeGaleraCluster
}

func (m MariaDB) IsMariaDBReplication() bool {
return m.Spec.Topology != nil &&
m.Spec.Topology.Mode != nil &&
*m.Spec.Topology.Mode == MariaDBModeReplication
}

func (m MariaDB) GoverningServiceName() string {
return meta_util.NameWithSuffix(m.ServiceName(), "pods")
}

func (m MariaDB) MaxscaleGoverningServiceName() string {
return meta_util.NameWithSuffix(m.OffshootMaxscaleName(), "pods")
}

func (m MariaDB) PeerName(idx int) string {
return fmt.Sprintf("%s-%d.%s.%s", m.OffshootName(), idx, m.GoverningServiceName(), m.Namespace)
}
Expand Down Expand Up @@ -218,7 +258,11 @@ func (m *MariaDB) SetDefaults(mdVersion *v1alpha1.MariaDBVersion) {
if m.Spec.Replicas == nil {
m.Spec.Replicas = pointer.Int32P(1)
}

if *m.Spec.Replicas > 1 && m.Spec.Topology == nil {
m.Spec.Topology = &MariaDBTopology{
Mode: ptr.To(MariaDBModeGaleraCluster),
}
}
if m.Spec.PodTemplate.Spec.ServiceAccountName == "" {
m.Spec.PodTemplate.Spec.ServiceAccountName = m.OffshootName()
}
Expand All @@ -239,6 +283,30 @@ func (m *MariaDB) SetDefaults(mdVersion *v1alpha1.MariaDBVersion) {
m.Spec.Monitor.Prometheus.Exporter.SecurityContext.RunAsGroup = mdVersion.Spec.SecurityContext.RunAsUser
}
}
if m.IsCluster() && m.IsMariaDBReplication() {
m.SetDefaultsMaxscale(mdVersion, m.Spec.Topology.MaxScale)
}
}

func (m *MariaDB) SetDefaultsMaxscale(mdVersion *v1alpha1.MariaDBVersion, maxscale *MaxScaleSpec) {
if maxscale == nil {
return
}
if maxscale.StorageType == "" {
maxscale.StorageType = StorageTypeDurable
}

if maxscale.Replicas == nil {
maxscale.Replicas = pointer.Int32P(1)
}
if maxscale.PodTemplate.Spec.ServiceAccountName == "" {
maxscale.PodTemplate.Spec.ServiceAccountName = m.OffshootName()
}
if maxscale.EnableUI == nil {
maxscale.EnableUI = pointer.BoolP(true)
}
m.setMaxscaleDefaultContainerSecurityContext(mdVersion, &maxscale.PodTemplate)
m.setMaxscaleDefaultContainerResourceLimits(&maxscale.PodTemplate)
}

func (m *MariaDB) setDefaultContainerSecurityContext(mdVersion *v1alpha1.MariaDBVersion, podTemplate *ofstv2.PodTemplateSpec) {
Expand Down Expand Up @@ -291,6 +359,41 @@ func (m *MariaDB) setDefaultContainerSecurityContext(mdVersion *v1alpha1.MariaDB
}
}

func (m *MariaDB) setMaxscaleDefaultContainerSecurityContext(mdVersion *v1alpha1.MariaDBVersion, podTemplate *ofstv2.PodTemplateSpec) {
if podTemplate == nil {
return
}
if podTemplate.Spec.SecurityContext == nil {
podTemplate.Spec.SecurityContext = &core.PodSecurityContext{}
}
if podTemplate.Spec.SecurityContext.FSGroup == nil {
podTemplate.Spec.SecurityContext.FSGroup = mdVersion.Spec.Maxscale.SecurityContext.RunAsUser
}
dbContainer := core_util.GetContainerByName(podTemplate.Spec.Containers, kubedb.MaxscaleContainerName)
if dbContainer == nil {
dbContainer = &core.Container{
Name: kubedb.MaxscaleContainerName,
}
}
if dbContainer.SecurityContext == nil {
dbContainer.SecurityContext = &core.SecurityContext{}
}
m.assignMaxscaleDefaultContainerSecurityContext(mdVersion, dbContainer.SecurityContext)
podTemplate.Spec.Containers = core_util.UpsertContainer(podTemplate.Spec.Containers, *dbContainer)

initContainer := core_util.GetContainerByName(podTemplate.Spec.InitContainers, kubedb.MaxscaleInitContainerName)
if initContainer == nil {
initContainer = &core.Container{
Name: kubedb.MaxscaleInitContainerName,
}
}
if initContainer.SecurityContext == nil {
initContainer.SecurityContext = &core.SecurityContext{}
}
m.assignMaxscaleDefaultContainerSecurityContext(mdVersion, initContainer.SecurityContext)
podTemplate.Spec.InitContainers = core_util.UpsertContainer(podTemplate.Spec.InitContainers, *initContainer)
}

func (m *MariaDB) assignDefaultContainerSecurityContext(mdVersion *v1alpha1.MariaDBVersion, sc *core.SecurityContext) {
if sc.AllowPrivilegeEscalation == nil {
sc.AllowPrivilegeEscalation = pointer.BoolP(false)
Expand All @@ -314,6 +417,29 @@ func (m *MariaDB) assignDefaultContainerSecurityContext(mdVersion *v1alpha1.Mari
}
}

func (m *MariaDB) assignMaxscaleDefaultContainerSecurityContext(mdVersion *v1alpha1.MariaDBVersion, sc *core.SecurityContext) {
if sc.AllowPrivilegeEscalation == nil {
sc.AllowPrivilegeEscalation = pointer.BoolP(false)
}
if sc.Capabilities == nil {
sc.Capabilities = &core.Capabilities{
Drop: []core.Capability{"ALL"},
}
}
if sc.RunAsNonRoot == nil {
sc.RunAsNonRoot = pointer.BoolP(true)
}
if sc.RunAsUser == nil {
sc.RunAsUser = mdVersion.Spec.Maxscale.SecurityContext.RunAsUser
}
if sc.RunAsGroup == nil {
sc.RunAsUser = mdVersion.Spec.Maxscale.SecurityContext.RunAsUser
}
if sc.SeccompProfile == nil {
sc.SeccompProfile = secomp.DefaultSeccompProfile()
}
}

func (m *MariaDB) setDefaultContainerResourceLimits(podTemplate *ofstv2.PodTemplateSpec) {
dbContainer := core_util.GetContainerByName(podTemplate.Spec.Containers, kubedb.MariaDBContainerName)
if dbContainer != nil && (dbContainer.Resources.Requests == nil && dbContainer.Resources.Limits == nil) {
Expand All @@ -332,6 +458,18 @@ func (m *MariaDB) setDefaultContainerResourceLimits(podTemplate *ofstv2.PodTempl
}
}

func (m *MariaDB) setMaxscaleDefaultContainerResourceLimits(podTemplate *ofstv2.PodTemplateSpec) {
dbContainer := core_util.GetContainerByName(podTemplate.Spec.Containers, kubedb.MaxscaleCommonName)
if dbContainer != nil && (dbContainer.Resources.Requests == nil && dbContainer.Resources.Limits == nil) {
apis.SetDefaultResourceLimits(&dbContainer.Resources, kubedb.DefaultResources)
}

initContainer := core_util.GetContainerByName(podTemplate.Spec.InitContainers, kubedb.MaxscaleInitContainerName)
if initContainer != nil && (initContainer.Resources.Requests == nil && initContainer.Resources.Limits == nil) {
apis.SetDefaultResourceLimits(&initContainer.Resources, kubedb.DefaultInitContainerResource)
}
}

func (m *MariaDB) SetHealthCheckerDefaults() {
if m.Spec.HealthChecker.PeriodSeconds == nil {
m.Spec.HealthChecker.PeriodSeconds = pointer.Int32P(10)
Expand Down
Loading

0 comments on commit e5366d5

Please sign in to comment.