From 067b014cb713f56777a7dfdf8364d7e81b46d816 Mon Sep 17 00:00:00 2001 From: Arsenii Pastushenko Date: Mon, 1 Nov 2021 12:36:29 +0200 Subject: [PATCH 1/2] Support additional configuration for master / replicas services --- Changelog.md | 2 ++ .../mysql.presslabs.org_mysqlclusters.yaml | 28 +++++++++++++++++++ .../mysql.presslabs.org_mysqlclusters.yaml | 24 ++++++++++++++++ pkg/apis/mysql/v1alpha1/mysqlcluster_types.go | 19 +++++++++++++ .../mysql/v1alpha1/zz_generated.deepcopy.go | 24 ++++++++++++++++ .../syncer/healthy_replicas_service.go | 11 ++++++++ .../internal/syncer/master_service.go | 11 ++++++++ .../mysqlcluster/mysqlcluster_test.go | 3 ++ 8 files changed, 122 insertions(+) diff --git a/Changelog.md b/Changelog.md index 76dd97361..253cd07b1 100644 --- a/Changelog.md +++ b/Changelog.md @@ -11,6 +11,8 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). provisioners wich don't support fsGroup in security context (fixes #615) * Add `appSecretLabels`, `appSecretAnnotations`, `backupSecretLabels`, `backupSecretAnnotations` to provide custom labels and annotations to created app and backup secrets + * Add ability to provision LoadBalancers for master/replica services + * Support specifying additional annotations for master/replica services ### Changed * Allow setting pod security context when deploying with Helm * Use [distroless](https://github.com/GoogleContainerTools/distroless) as base image for orchestrator container diff --git a/config/crd/bases/mysql.presslabs.org_mysqlclusters.yaml b/config/crd/bases/mysql.presslabs.org_mysqlclusters.yaml index 2bbc3af3a..8c82057f1 100644 --- a/config/crd/bases/mysql.presslabs.org_mysqlclusters.yaml +++ b/config/crd/bases/mysql.presslabs.org_mysqlclusters.yaml @@ -51,6 +51,20 @@ spec: description: 'MysqlClusterSpec defines the desired state of MysqlCluster nolint: maligned' properties: + MasterServiceSpec: + description: Master service extra specification + properties: + annotations: + additionalProperties: + type: string + description: Annotations allow to specify annotations for MysqlCluster's + services + type: object + loadBalancer: + description: LoadBalancer configures whether a service is a LoadBalancer + or not. + type: boolean + type: object backupCompressCommand: description: BackupCompressCommand is a command to use for compressing the backup. @@ -6161,6 +6175,20 @@ spec: in case of a failover the cluster will be writable for at least a few seconds. type: boolean + replicaServiceSpec: + description: Healthy replica service extra specification + properties: + annotations: + additionalProperties: + type: string + description: Annotations allow to specify annotations for MysqlCluster's + services + type: object + loadBalancer: + description: LoadBalancer configures whether a service is a LoadBalancer + or not. + type: boolean + type: object replicas: description: The number of pods. This updates replicas filed Defaults to 0 diff --git a/deploy/charts/mysql-operator/crds/mysql.presslabs.org_mysqlclusters.yaml b/deploy/charts/mysql-operator/crds/mysql.presslabs.org_mysqlclusters.yaml index 76b8852e9..b14b74d50 100644 --- a/deploy/charts/mysql-operator/crds/mysql.presslabs.org_mysqlclusters.yaml +++ b/deploy/charts/mysql-operator/crds/mysql.presslabs.org_mysqlclusters.yaml @@ -46,6 +46,18 @@ spec: spec: description: 'MysqlClusterSpec defines the desired state of MysqlCluster nolint: maligned' properties: + MasterServiceSpec: + description: Master service extra specification + properties: + annotations: + additionalProperties: + type: string + description: Annotations allow to specify annotations for MysqlCluster's services + type: object + loadBalancer: + description: LoadBalancer configures whether a service is a LoadBalancer or not. + type: boolean + type: object backupCompressCommand: description: BackupCompressCommand is a command to use for compressing the backup. items: @@ -3759,6 +3771,18 @@ spec: readOnly: description: Makes the cluster READ ONLY. This has not a strong guarantee, in case of a failover the cluster will be writable for at least a few seconds. type: boolean + replicaServiceSpec: + description: Healthy replica service extra specification + properties: + annotations: + additionalProperties: + type: string + description: Annotations allow to specify annotations for MysqlCluster's services + type: object + loadBalancer: + description: LoadBalancer configures whether a service is a LoadBalancer or not. + type: boolean + type: object replicas: description: The number of pods. This updates replicas filed Defaults to 0 format: int32 diff --git a/pkg/apis/mysql/v1alpha1/mysqlcluster_types.go b/pkg/apis/mysql/v1alpha1/mysqlcluster_types.go index ebe19c8f9..c12c5b511 100644 --- a/pkg/apis/mysql/v1alpha1/mysqlcluster_types.go +++ b/pkg/apis/mysql/v1alpha1/mysqlcluster_types.go @@ -107,6 +107,14 @@ type MysqlClusterSpec struct { // +optional VolumeSpec VolumeSpec `json:"volumeSpec,omitempty"` + // Master service extra specification + // +optional + MasterServiceSpec ServiceSpec `json:"MasterServiceSpec,omitempty"` + + // Healthy replica service extra specification + // +optional + ReplicaServiceSpec ServiceSpec `json:"replicaServiceSpec,omitempty"` + // TmpfsSize if specified, mounts a tmpfs of this size into /tmp // DEPRECATED: use instead PodSpec.Volumes and PodSpec.VolumeMounts // +optional @@ -241,6 +249,17 @@ type VolumeSpec struct { PersistentVolumeClaim *core.PersistentVolumeClaimSpec `json:"persistentVolumeClaim,omitempty"` } +// ServiceSpec s the desired spec for addition configuration of MysqlCluster services +type ServiceSpec struct { + // LoadBalancer configures whether a service is a LoadBalancer or not. + // +optional + LoadBalancer bool `json:"loadBalancer,omitempty"` + + // Annotations allow to specify annotations for MysqlCluster's services + // +optional + Annotations map[string]string `json:"annotations,omitempty"` +} + // QueryLimits represents the pt-kill parameters, more info can be found // here: https://www.percona.com/doc/percona-toolkit/LATEST/pt-kill.html type QueryLimits struct { diff --git a/pkg/apis/mysql/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/mysql/v1alpha1/zz_generated.deepcopy.go index 3a053a939..a11c06486 100644 --- a/pkg/apis/mysql/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/mysql/v1alpha1/zz_generated.deepcopy.go @@ -267,6 +267,8 @@ func (in *MysqlClusterSpec) DeepCopyInto(out *MysqlClusterSpec) { } in.PodSpec.DeepCopyInto(&out.PodSpec) in.VolumeSpec.DeepCopyInto(&out.VolumeSpec) + in.MasterServiceSpec.DeepCopyInto(&out.MasterServiceSpec) + in.ReplicaServiceSpec.DeepCopyInto(&out.ReplicaServiceSpec) if in.TmpfsSize != nil { in, out := &in.TmpfsSize, &out.TmpfsSize x := (*in).DeepCopy() @@ -831,6 +833,28 @@ func (in *QueryLimits) DeepCopy() *QueryLimits { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceSpec) DeepCopyInto(out *ServiceSpec) { + *out = *in + if in.Annotations != nil { + in, out := &in.Annotations, &out.Annotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceSpec. +func (in *ServiceSpec) DeepCopy() *ServiceSpec { + if in == nil { + return nil + } + out := new(ServiceSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VolumeSpec) DeepCopyInto(out *VolumeSpec) { *out = *in diff --git a/pkg/controller/mysqlcluster/internal/syncer/healthy_replicas_service.go b/pkg/controller/mysqlcluster/internal/syncer/healthy_replicas_service.go index 5d15931b3..0ee8ba64f 100644 --- a/pkg/controller/mysqlcluster/internal/syncer/healthy_replicas_service.go +++ b/pkg/controller/mysqlcluster/internal/syncer/healthy_replicas_service.go @@ -17,6 +17,7 @@ limitations under the License. package mysqlcluster import ( + "github.com/imdario/mergo" "github.com/presslabs/controller-util/syncer" core "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -36,6 +37,16 @@ func NewHealthyReplicasSVCSyncer(c client.Client, scheme *runtime.Scheme, cluste } return syncer.NewObjectSyncer("HealthyReplicasSVC", cluster.Unwrap(), service, c, func() error { + // set service type + if cluster.Spec.ReplicaServiceSpec.LoadBalancer { + service.Spec.Type = core.ServiceTypeLoadBalancer + } + + // merge annotations + if err := mergo.Merge(&service.ObjectMeta.Annotations, cluster.Spec.ReplicaServiceSpec.Annotations); err != nil { + return err + } + // set service labels service.Labels = cluster.GetLabels() service.Labels["mysql.presslabs.org/service-type"] = "ready-replicas" diff --git a/pkg/controller/mysqlcluster/internal/syncer/master_service.go b/pkg/controller/mysqlcluster/internal/syncer/master_service.go index e7374cb1b..156e83904 100644 --- a/pkg/controller/mysqlcluster/internal/syncer/master_service.go +++ b/pkg/controller/mysqlcluster/internal/syncer/master_service.go @@ -17,6 +17,7 @@ limitations under the License. package mysqlcluster import ( + "github.com/imdario/mergo" "github.com/presslabs/controller-util/syncer" core "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -36,6 +37,16 @@ func NewMasterSVCSyncer(c client.Client, scheme *runtime.Scheme, cluster *mysqlc } return syncer.NewObjectSyncer("MasterSVC", cluster.Unwrap(), service, c, func() error { + // set service type + if cluster.Spec.MasterServiceSpec.LoadBalancer { + service.Spec.Type = core.ServiceTypeLoadBalancer + } + + // merge annotations + if err := mergo.Merge(&service.ObjectMeta.Annotations, cluster.Spec.MasterServiceSpec.Annotations); err != nil { + return err + } + // set service labels service.Labels = cluster.GetLabels() service.Labels["mysql.presslabs.org/service-type"] = "master" diff --git a/pkg/internal/mysqlcluster/mysqlcluster_test.go b/pkg/internal/mysqlcluster/mysqlcluster_test.go index a472f8640..21654130a 100644 --- a/pkg/internal/mysqlcluster/mysqlcluster_test.go +++ b/pkg/internal/mysqlcluster/mysqlcluster_test.go @@ -75,6 +75,9 @@ var _ = Describe("Test MySQL cluster wrapper", func() { Expect(cluster.Spec.MysqlConf).To(HaveKey(Equal("innodb-buffer-pool-size"))) Expect(cluster.Spec.MysqlConf).To(HaveKey(Equal("innodb-log-file-size"))) Expect(cluster.Spec.MysqlConf).NotTo(HaveKey(Equal("max-binlog-size"))) + + Expect(cluster.Spec.MasterServiceSpec.LoadBalancer).To(Equal(false)) + Expect(cluster.Spec.ReplicaServiceSpec.LoadBalancer).To(Equal(false)) }) It("should use init MySQL container", func() { From 1b16804272a43b06cfb74221ee8656c652f3fe92 Mon Sep 17 00:00:00 2001 From: Arsenii Pastushenko Date: Thu, 4 Nov 2021 21:19:42 +0200 Subject: [PATCH 2/2] Support loadBalancerSourceRanges configuration for master/replica services --- .../mysql.presslabs.org_mysqlclusters.yaml | 40 ++++++++++++------- .../mysql.presslabs.org_mysqlclusters.yaml | 34 ++++++++++------ pkg/apis/mysql/v1alpha1/mysqlcluster_types.go | 8 +++- .../mysql/v1alpha1/zz_generated.deepcopy.go | 5 +++ .../syncer/healthy_replicas_service.go | 1 + .../internal/syncer/master_service.go | 1 + 6 files changed, 61 insertions(+), 28 deletions(-) diff --git a/config/crd/bases/mysql.presslabs.org_mysqlclusters.yaml b/config/crd/bases/mysql.presslabs.org_mysqlclusters.yaml index 8c82057f1..a940278a5 100644 --- a/config/crd/bases/mysql.presslabs.org_mysqlclusters.yaml +++ b/config/crd/bases/mysql.presslabs.org_mysqlclusters.yaml @@ -51,20 +51,6 @@ spec: description: 'MysqlClusterSpec defines the desired state of MysqlCluster nolint: maligned' properties: - MasterServiceSpec: - description: Master service extra specification - properties: - annotations: - additionalProperties: - type: string - description: Annotations allow to specify annotations for MysqlCluster's - services - type: object - loadBalancer: - description: LoadBalancer configures whether a service is a LoadBalancer - or not. - type: boolean - type: object backupCompressCommand: description: BackupCompressCommand is a command to use for compressing the backup. @@ -116,6 +102,26 @@ spec: items: type: string type: array + masterServiceSpec: + description: Master service extra specification + properties: + allowedSourceRanges: + description: AllowedSourceRanges sets a list of CIDR blocks allowed + to access the cluster using LoadBalancer service. + items: + type: string + type: array + annotations: + additionalProperties: + type: string + description: Annotations allow to specify annotations for MysqlCluster's + services + type: object + loadBalancer: + description: LoadBalancer configures whether a service is a LoadBalancer + or not. + type: boolean + type: object maxSlaveLatency: description: MaxSlaveLatency represents the allowed latency for a slave node in seconds. If set then the node with a latency grater @@ -6178,6 +6184,12 @@ spec: replicaServiceSpec: description: Healthy replica service extra specification properties: + allowedSourceRanges: + description: AllowedSourceRanges sets a list of CIDR blocks allowed + to access the cluster using LoadBalancer service. + items: + type: string + type: array annotations: additionalProperties: type: string diff --git a/deploy/charts/mysql-operator/crds/mysql.presslabs.org_mysqlclusters.yaml b/deploy/charts/mysql-operator/crds/mysql.presslabs.org_mysqlclusters.yaml index b14b74d50..4d8d1fe51 100644 --- a/deploy/charts/mysql-operator/crds/mysql.presslabs.org_mysqlclusters.yaml +++ b/deploy/charts/mysql-operator/crds/mysql.presslabs.org_mysqlclusters.yaml @@ -46,18 +46,6 @@ spec: spec: description: 'MysqlClusterSpec defines the desired state of MysqlCluster nolint: maligned' properties: - MasterServiceSpec: - description: Master service extra specification - properties: - annotations: - additionalProperties: - type: string - description: Annotations allow to specify annotations for MysqlCluster's services - type: object - loadBalancer: - description: LoadBalancer configures whether a service is a LoadBalancer or not. - type: boolean - type: object backupCompressCommand: description: BackupCompressCommand is a command to use for compressing the backup. items: @@ -99,6 +87,23 @@ spec: items: type: string type: array + masterServiceSpec: + description: Master service extra specification + properties: + allowedSourceRanges: + description: AllowedSourceRanges sets a list of CIDR blocks allowed to access the cluster using LoadBalancer service. + items: + type: string + type: array + annotations: + additionalProperties: + type: string + description: Annotations allow to specify annotations for MysqlCluster's services + type: object + loadBalancer: + description: LoadBalancer configures whether a service is a LoadBalancer or not. + type: boolean + type: object maxSlaveLatency: description: MaxSlaveLatency represents the allowed latency for a slave node in seconds. If set then the node with a latency grater than this is removed from service. format: int64 @@ -3774,6 +3779,11 @@ spec: replicaServiceSpec: description: Healthy replica service extra specification properties: + allowedSourceRanges: + description: AllowedSourceRanges sets a list of CIDR blocks allowed to access the cluster using LoadBalancer service. + items: + type: string + type: array annotations: additionalProperties: type: string diff --git a/pkg/apis/mysql/v1alpha1/mysqlcluster_types.go b/pkg/apis/mysql/v1alpha1/mysqlcluster_types.go index c12c5b511..6f1337e1d 100644 --- a/pkg/apis/mysql/v1alpha1/mysqlcluster_types.go +++ b/pkg/apis/mysql/v1alpha1/mysqlcluster_types.go @@ -109,7 +109,7 @@ type MysqlClusterSpec struct { // Master service extra specification // +optional - MasterServiceSpec ServiceSpec `json:"MasterServiceSpec,omitempty"` + MasterServiceSpec ServiceSpec `json:"masterServiceSpec,omitempty"` // Healthy replica service extra specification // +optional @@ -249,12 +249,16 @@ type VolumeSpec struct { PersistentVolumeClaim *core.PersistentVolumeClaimSpec `json:"persistentVolumeClaim,omitempty"` } -// ServiceSpec s the desired spec for addition configuration of MysqlCluster services +// ServiceSpec is the desired spec for addition configuration of MysqlCluster services type ServiceSpec struct { // LoadBalancer configures whether a service is a LoadBalancer or not. // +optional LoadBalancer bool `json:"loadBalancer,omitempty"` + // AllowedSourceRanges sets a list of CIDR blocks allowed to access the cluster using LoadBalancer service. + // +optional + AllowedSourceRanges []string `json:"allowedSourceRanges,omitempty"` + // Annotations allow to specify annotations for MysqlCluster's services // +optional Annotations map[string]string `json:"annotations,omitempty"` diff --git a/pkg/apis/mysql/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/mysql/v1alpha1/zz_generated.deepcopy.go index a11c06486..99267564b 100644 --- a/pkg/apis/mysql/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/mysql/v1alpha1/zz_generated.deepcopy.go @@ -836,6 +836,11 @@ func (in *QueryLimits) DeepCopy() *QueryLimits { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ServiceSpec) DeepCopyInto(out *ServiceSpec) { *out = *in + if in.AllowedSourceRanges != nil { + in, out := &in.AllowedSourceRanges, &out.AllowedSourceRanges + *out = make([]string, len(*in)) + copy(*out, *in) + } if in.Annotations != nil { in, out := &in.Annotations, &out.Annotations *out = make(map[string]string, len(*in)) diff --git a/pkg/controller/mysqlcluster/internal/syncer/healthy_replicas_service.go b/pkg/controller/mysqlcluster/internal/syncer/healthy_replicas_service.go index 0ee8ba64f..0261630e5 100644 --- a/pkg/controller/mysqlcluster/internal/syncer/healthy_replicas_service.go +++ b/pkg/controller/mysqlcluster/internal/syncer/healthy_replicas_service.go @@ -40,6 +40,7 @@ func NewHealthyReplicasSVCSyncer(c client.Client, scheme *runtime.Scheme, cluste // set service type if cluster.Spec.ReplicaServiceSpec.LoadBalancer { service.Spec.Type = core.ServiceTypeLoadBalancer + service.Spec.LoadBalancerSourceRanges = cluster.Spec.ReplicaServiceSpec.AllowedSourceRanges } // merge annotations diff --git a/pkg/controller/mysqlcluster/internal/syncer/master_service.go b/pkg/controller/mysqlcluster/internal/syncer/master_service.go index 156e83904..734745a81 100644 --- a/pkg/controller/mysqlcluster/internal/syncer/master_service.go +++ b/pkg/controller/mysqlcluster/internal/syncer/master_service.go @@ -40,6 +40,7 @@ func NewMasterSVCSyncer(c client.Client, scheme *runtime.Scheme, cluster *mysqlc // set service type if cluster.Spec.MasterServiceSpec.LoadBalancer { service.Spec.Type = core.ServiceTypeLoadBalancer + service.Spec.LoadBalancerSourceRanges = cluster.Spec.MasterServiceSpec.AllowedSourceRanges } // merge annotations