From 6ca6049081b96e634a1805694090479e832c017f Mon Sep 17 00:00:00 2001 From: acekingke Date: Fri, 19 May 2023 15:38:11 +0800 Subject: [PATCH 1/2] *: merge he v2.4.0 function --- Makefile | 13 +- api/v1alpha1/mysqlcluster_types.go | 41 +- api/v1alpha1/mysqlcluster_webhook.go | 24 + api/v1alpha1/zz_generated.deepcopy.go | 57 + api/v1beta1/mysqlcluster_types.go | 41 +- api/v1beta1/zz_generated.conversion.go | 76 + api/v1beta1/zz_generated.deepcopy.go | 57 + .../crds/mysql.radondb.com_mysqlclusters.yaml | 4370 ++++++++++++----- .../mysql-operator/templates/deployment.yaml | 11 +- cmd/mysql/main.go | 21 + .../mysql.radondb.com_mysqlclusters.yaml | 4370 ++++++++++++----- config/manager/kustomization.yaml | 2 +- .../samples/mysql_v1alpha1_mysqlcluster.yaml | 3 + controllers/mysqlcluster_controller.go | 4 + internal/pod_executor.go | 118 + internal/sql_runner.go | 39 +- mysqlcluster/mysqlcluster.go | 4 + mysqlcluster/syncer/readonly_service.go | 123 + mysqlcluster/syncer/readonly_statefulset.go | 512 ++ mysqlcluster/syncer/statefulset.go | 36 + mysqlcluster/syncer/status.go | 189 +- sidecar/config.go | 9 +- sidecar/init.go | 32 +- sidecar/util.go | 3 + utils/constants.go | 8 + 25 files changed, 7679 insertions(+), 2484 deletions(-) create mode 100644 internal/pod_executor.go create mode 100644 mysqlcluster/syncer/readonly_service.go create mode 100644 mysqlcluster/syncer/readonly_statefulset.go diff --git a/Makefile b/Makefile index 8f37189d..eced009d 100644 --- a/Makefile +++ b/Makefile @@ -68,7 +68,7 @@ fmt: ## Run go fmt against code. vet: ## Run go vet against code. go vet ./... - + CONVERSION_GEN := $(shell pwd)/bin/conversion-gen CODE_GENERATOR_VERSION := $(shell awk '/k8s.io\/client-go/ {print substr($$2, 2)}' go.mod) conversion-gen: ## Donwload conversion-gen locally if necessary. @@ -94,11 +94,12 @@ build: generate fmt vet ## Build manager binary. run: manifests generate fmt vet ## Run a controller from your host. go run ./cmd/manager/main.go -docker-build: ## Build docker image with the manager. - DOCKER_BUILDKIT=1 docker build --build-arg GO_PROXY=${GO_PROXY} -t ${IMG} . - DOCKER_BUILDKIT=1 docker build -f Dockerfile.sidecar --build-arg GO_PROXY=${GO_PROXY} -t ${SIDECAR57_IMG} . - DOCKER_BUILDKIT=1 docker build -f build/xenon/Dockerfile --build-arg GO_PROXY=${GO_PROXY} -t ${XENON_IMG} . - DOCKER_BUILDKIT=1 docker build --build-arg XTRABACKUP_PKG=percona-xtrabackup-80 --build-arg GO_PROXY=${GO_PROXY} -f Dockerfile.sidecar -t ${SIDECAR80_IMG} . +docker-build: test ## Build docker image with the manager. + DOCKER_BUILDKIT=1 docker build --build-arg GO_PROXY=${GO_PROXY} -t ${IMG} . + DOCKER_BUILDKIT=1 docker build -f Dockerfile.sidecar --build-arg GO_PROXY=${GO_PROXY} -t ${SIDECAR57_IMG} . + DOCKER_BUILDKIT=1 docker build -f Dockerfile.sidecar --build-arg GO_PROXY=${GO_PROXY} -t ${SIDECAR80_IMG} . + DOCKER_BUILDKIT=1 docker build -f build/xenon/Dockerfile --build-arg GO_PROXY=${GO_PROXY} -t ${XENON_IMG} . + DOCKER_BUILDKIT=1 docker build --build-arg XTRABACKUP_PKG=percona-xtrabackup-80 --build-arg GO_PROXY=${GO_PROXY} -f Dockerfile.sidecar -t ${SIDECAR80_IMG} . docker-push: ## Push docker image with the manager. docker push ${IMG} docker push ${SIDECAR57_IMG} diff --git a/api/v1alpha1/mysqlcluster_types.go b/api/v1alpha1/mysqlcluster_types.go index 25b4c32f..aee8dc2a 100644 --- a/api/v1alpha1/mysqlcluster_types.go +++ b/api/v1alpha1/mysqlcluster_types.go @@ -34,7 +34,9 @@ type MysqlClusterSpec struct { // +kubebuilder:validation:Enum=0;1;2;3;5 // +kubebuilder:default:=3 Replicas *int32 `json:"replicas,omitempty"` - + // Readonlys Info. + // +optional + ReadOnlys *ReadOnlyType `json:"readonlys,omitempty"` // The number of pods from that set that must still be available after the // eviction, even in the absence of the evicted pod // +optional @@ -106,6 +108,22 @@ type MysqlClusterSpec struct { TlsSecretName string `json:"tlsSecretName,omitempty"` } +// ReadOnly define the ReadOnly pods +type ReadOnlyType struct { + // ReadOnlys is the number of readonly pods. + Num int32 `json:"num"` + // When the host name is empty, use the leader to change master + // +optional + Host string `json:"hostname"` + // The compute resource requirements. + // +optional + Resources *corev1.ResourceRequirements `json:"resources,omitempty"` + // +optional + Affinity *corev1.Affinity `json:"affinity,omitempty"` + // +optional + Tolerations []corev1.Toleration `json:"tolerations,omitempty"` +} + // MysqlOpts defines the options of MySQL container. type MysqlOpts struct { // Specifies mysql image to use. @@ -367,6 +385,8 @@ type NodeStatus struct { Message string `json:"message,omitempty"` // RaftStatus is the raft status of the node. RaftStatus RaftStatus `json:"raftStatus,omitempty"` + // (RO) ReadOnly Status + RoStatus *RoStatus `json:"roStatus,omitempty"` // Conditions contains the list of the node conditions fulfilled. Conditions []NodeCondition `json:"conditions,omitempty"` } @@ -380,6 +400,13 @@ type RaftStatus struct { Nodes []string `json:"nodes,omitempty"` } +// (RO) node status +type RoStatus struct { + ReadOnly bool `json:"readOnlyReady,omitempty"` + Replication bool `json:"Replication,omitempty"` + Master string `json:"master,omitempty"` +} + // NodeCondition defines type for representing node conditions. type NodeCondition struct { // Type of the node condition. @@ -398,6 +425,10 @@ const ( IndexLeader IndexReadOnly IndexReplicating + IndexRoInit + IndexRoReadOnly + IndexRoSemiClose + IndexRoReplicating ) // NodeConditionType defines type for node condition type. @@ -412,6 +443,14 @@ const ( NodeConditionReadOnly NodeConditionType = "ReadOnly" // NodeConditionReplicating represents if the node is replicating or not. NodeConditionReplicating NodeConditionType = "Replicating" + // ReadOnly Pod initing + NodeConditionRoInitial NodeConditionType = "RoInitial" + // ReadOnly Pod Set ReadOnly + NodeConditionRoReadOnly NodeConditionType = "RoReadOnly" + // ReadOnly Semi check close + NodeConditionRoSemiClose NodeConditionType = "RoSemiClose" + // ReadOnly Pod Ready + NodeConditionRoReplicating NodeConditionType = "RoReplicating" ) // MysqlClusterStatus defines the observed state of MysqlCluster diff --git a/api/v1alpha1/mysqlcluster_webhook.go b/api/v1alpha1/mysqlcluster_webhook.go index d2eb56e6..36dbb298 100644 --- a/api/v1alpha1/mysqlcluster_webhook.go +++ b/api/v1alpha1/mysqlcluster_webhook.go @@ -20,6 +20,7 @@ import ( "context" "fmt" "net" + "strconv" "strings" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -108,6 +109,9 @@ func (r *MysqlCluster) ValidateUpdate(old runtime.Object) error { if err := r.validateNFSServerAddress(oldCluster); err != nil { return err } + if err := r.ValidataRo(); err != nil { + return err + } return nil } @@ -230,3 +234,23 @@ func (r *MysqlCluster) validBothS3NFS() error { } return nil } + +// Validata Readonly +func (r *MysqlCluster) ValidataRo() error { + if r.Spec.ReadOnlys != nil && len(r.Spec.ReadOnlys.Host) != 0 { + // 1. Host name must startwith -mysql- + if !strings.HasPrefix(r.Spec.ReadOnlys.Host, r.Name+"-mysql-") { + goto err + } + numstr := strings.TrimPrefix(r.Spec.ReadOnlys.Host, r.Name+"-mysql-") + // if not num, or num is greater than Spec Replica - 1, return error + if num, err := strconv.Atoi(numstr); err != nil { + goto err + } else if num >= int(*r.Spec.Replicas) || num < 0 { + goto err + } + } + return nil +err: + return apierrors.NewForbidden(schema.GroupResource{}, "", fmt.Errorf("spec.readonly's hostname is not exist in the cluster")) +} diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index db850e7c..30e30b39 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -274,6 +274,11 @@ func (in *MysqlClusterSpec) DeepCopyInto(out *MysqlClusterSpec) { *out = new(int32) **out = **in } + if in.ReadOnlys != nil { + in, out := &in.ReadOnlys, &out.ReadOnlys + *out = new(ReadOnlyType) + (*in).DeepCopyInto(*out) + } in.MysqlOpts.DeepCopyInto(&out.MysqlOpts) in.XenonOpts.DeepCopyInto(&out.XenonOpts) in.MetricsOpts.DeepCopyInto(&out.MetricsOpts) @@ -460,6 +465,11 @@ func (in *NodeCondition) DeepCopy() *NodeCondition { func (in *NodeStatus) DeepCopyInto(out *NodeStatus) { *out = *in in.RaftStatus.DeepCopyInto(&out.RaftStatus) + if in.RoStatus != nil { + in, out := &in.RoStatus, &out.RoStatus + *out = new(RoStatus) + **out = **in + } if in.Conditions != nil { in, out := &in.Conditions, &out.Conditions *out = make([]NodeCondition, len(*in)) @@ -566,6 +576,53 @@ func (in *RaftStatus) DeepCopy() *RaftStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ReadOnlyType) DeepCopyInto(out *ReadOnlyType) { + *out = *in + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = new(v1.ResourceRequirements) + (*in).DeepCopyInto(*out) + } + if in.Affinity != nil { + in, out := &in.Affinity, &out.Affinity + *out = new(v1.Affinity) + (*in).DeepCopyInto(*out) + } + if in.Tolerations != nil { + in, out := &in.Tolerations, &out.Tolerations + *out = make([]v1.Toleration, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReadOnlyType. +func (in *ReadOnlyType) DeepCopy() *ReadOnlyType { + if in == nil { + return nil + } + out := new(ReadOnlyType) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RoStatus) DeepCopyInto(out *RoStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RoStatus. +func (in *RoStatus) DeepCopy() *RoStatus { + if in == nil { + return nil + } + out := new(RoStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SecretSelector) DeepCopyInto(out *SecretSelector) { *out = *in diff --git a/api/v1beta1/mysqlcluster_types.go b/api/v1beta1/mysqlcluster_types.go index 79235848..1faf38b3 100644 --- a/api/v1beta1/mysqlcluster_types.go +++ b/api/v1beta1/mysqlcluster_types.go @@ -34,7 +34,9 @@ type MysqlClusterSpec struct { // +kubebuilder:validation:Enum=0;1;2;3;5 // +kubebuilder:default:=3 Replicas *int32 `json:"replicas,omitempty"` - + // Readonlys Info. + // +optional + ReadOnlys *ReadOnlyType `json:"readonlys,omitempty"` // Username of new user to create. // Only be a combination of letters, numbers or underlines. The length can not exceed 26 characters. // +optional @@ -146,6 +148,22 @@ type MysqlClusterSpec struct { Service *ServiceSpec `json:"service,omitempty"` } +// ReadOnly define the ReadOnly pods +type ReadOnlyType struct { + // ReadOnlys is the number of readonly pods. + Num int32 `json:"num"` + // When the host name is empty, use the leader to change master + // +optional + Host string `json:"hostname"` + // The compute resource requirements. + // +optional + Resources *corev1.ResourceRequirements `json:"resources,omitempty"` + // +optional + Affinity *corev1.Affinity `json:"affinity,omitempty"` + // +optional + Tolerations []corev1.Toleration `json:"tolerations,omitempty"` +} + type MySQLConfigs struct { // Name of the `ConfigMap` containing MySQL config. // +optional @@ -269,6 +287,8 @@ type NodeStatus struct { Message string `json:"message,omitempty"` // RaftStatus is the raft status of the node. RaftStatus RaftStatus `json:"raftStatus,omitempty"` + // (RO) ReadOnly Status + RoStatus *RoStatus `json:"roStatus,omitempty"` // Conditions contains the list of the node conditions fulfilled. Conditions []NodeCondition `json:"conditions,omitempty"` } @@ -282,6 +302,13 @@ type RaftStatus struct { Nodes []string `json:"nodes,omitempty"` } +// (RO) node status +type RoStatus struct { + ReadOnly bool `json:"readOnlyReady,omitempty"` + Replication bool `json:"Replication,omitempty"` + Master string `json:"master,omitempty"` +} + // NodeCondition defines type for representing node conditions. type NodeCondition struct { // Type of the node condition. @@ -300,6 +327,10 @@ const ( IndexLeader IndexReadOnly IndexReplicating + IndexRoInit + IndexRoReadOnly + IndexRoSemiClose + IndexRoReplicating ) // NodeConditionType defines type for node condition type. @@ -314,6 +345,14 @@ const ( NodeConditionReadOnly NodeConditionType = "ReadOnly" // NodeConditionReplicating represents if the node is replicating or not. NodeConditionReplicating NodeConditionType = "Replicating" + // ReadOnly Pod initing + NodeConditionRoInitial NodeConditionType = "RoInitial" + // ReadOnly Pod Set ReadOnly + NodeConditionRoReadOnly NodeConditionType = "RoReadOnly" + // ReadOnly Semi check close + NodeConditionRoSemiClose NodeConditionType = "RoSemiClose" + // ReadOnly Pod Ready + NodeConditionRoReplicating NodeConditionType = "RoReplicating" ) type XenonOpts struct { diff --git a/api/v1beta1/zz_generated.conversion.go b/api/v1beta1/zz_generated.conversion.go index 00d1e6c3..ba01de49 100644 --- a/api/v1beta1/zz_generated.conversion.go +++ b/api/v1beta1/zz_generated.conversion.go @@ -126,6 +126,26 @@ func RegisterConversions(s *runtime.Scheme) error { }); err != nil { return err } + if err := s.AddGeneratedConversionFunc((*ReadOnlyType)(nil), (*v1alpha1.ReadOnlyType)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_ReadOnlyType_To_v1alpha1_ReadOnlyType(a.(*ReadOnlyType), b.(*v1alpha1.ReadOnlyType), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha1.ReadOnlyType)(nil), (*ReadOnlyType)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_ReadOnlyType_To_v1beta1_ReadOnlyType(a.(*v1alpha1.ReadOnlyType), b.(*ReadOnlyType), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*RoStatus)(nil), (*v1alpha1.RoStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1beta1_RoStatus_To_v1alpha1_RoStatus(a.(*RoStatus), b.(*v1alpha1.RoStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha1.RoStatus)(nil), (*RoStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_RoStatus_To_v1beta1_RoStatus(a.(*v1alpha1.RoStatus), b.(*RoStatus), scope) + }); err != nil { + return err + } if err := s.AddGeneratedConversionFunc((*XenonOpts)(nil), (*v1alpha1.XenonOpts)(nil), func(a, b interface{}, scope conversion.Scope) error { return Convert_v1beta1_XenonOpts_To_v1alpha1_XenonOpts(a.(*XenonOpts), b.(*v1alpha1.XenonOpts), scope) }); err != nil { @@ -387,6 +407,7 @@ func Convert_v1alpha1_MysqlClusterList_To_v1beta1_MysqlClusterList(in *v1alpha1. func autoConvert_v1beta1_MysqlClusterSpec_To_v1alpha1_MysqlClusterSpec(in *MysqlClusterSpec, out *v1alpha1.MysqlClusterSpec, s conversion.Scope) error { out.Replicas = (*int32)(unsafe.Pointer(in.Replicas)) + out.ReadOnlys = (*v1alpha1.ReadOnlyType)(unsafe.Pointer(in.ReadOnlys)) // WARNING: in.User requires manual conversion: does not exist in peer-type // WARNING: in.MySQLConfig requires manual conversion: does not exist in peer-type // WARNING: in.Resources requires manual conversion: does not exist in peer-type @@ -413,6 +434,7 @@ func autoConvert_v1beta1_MysqlClusterSpec_To_v1alpha1_MysqlClusterSpec(in *Mysql func autoConvert_v1alpha1_MysqlClusterSpec_To_v1beta1_MysqlClusterSpec(in *v1alpha1.MysqlClusterSpec, out *MysqlClusterSpec, s conversion.Scope) error { out.Replicas = (*int32)(unsafe.Pointer(in.Replicas)) + out.ReadOnlys = (*ReadOnlyType)(unsafe.Pointer(in.ReadOnlys)) out.MinAvailable = in.MinAvailable // WARNING: in.MysqlOpts requires manual conversion: does not exist in peer-type // WARNING: in.XenonOpts requires manual conversion: does not exist in peer-type @@ -486,6 +508,7 @@ func autoConvert_v1beta1_NodeStatus_To_v1alpha1_NodeStatus(in *NodeStatus, out * if err := Convert_v1beta1_RaftStatus_To_v1alpha1_RaftStatus(&in.RaftStatus, &out.RaftStatus, s); err != nil { return err } + out.RoStatus = (*v1alpha1.RoStatus)(unsafe.Pointer(in.RoStatus)) out.Conditions = *(*[]v1alpha1.NodeCondition)(unsafe.Pointer(&in.Conditions)) return nil } @@ -501,6 +524,7 @@ func autoConvert_v1alpha1_NodeStatus_To_v1beta1_NodeStatus(in *v1alpha1.NodeStat if err := Convert_v1alpha1_RaftStatus_To_v1beta1_RaftStatus(&in.RaftStatus, &out.RaftStatus, s); err != nil { return err } + out.RoStatus = (*RoStatus)(unsafe.Pointer(in.RoStatus)) out.Conditions = *(*[]NodeCondition)(unsafe.Pointer(&in.Conditions)) return nil } @@ -534,6 +558,58 @@ func Convert_v1alpha1_RaftStatus_To_v1beta1_RaftStatus(in *v1alpha1.RaftStatus, return autoConvert_v1alpha1_RaftStatus_To_v1beta1_RaftStatus(in, out, s) } +func autoConvert_v1beta1_ReadOnlyType_To_v1alpha1_ReadOnlyType(in *ReadOnlyType, out *v1alpha1.ReadOnlyType, s conversion.Scope) error { + out.Num = in.Num + out.Host = in.Host + out.Resources = (*v1.ResourceRequirements)(unsafe.Pointer(in.Resources)) + out.Affinity = (*v1.Affinity)(unsafe.Pointer(in.Affinity)) + out.Tolerations = *(*[]v1.Toleration)(unsafe.Pointer(&in.Tolerations)) + return nil +} + +// Convert_v1beta1_ReadOnlyType_To_v1alpha1_ReadOnlyType is an autogenerated conversion function. +func Convert_v1beta1_ReadOnlyType_To_v1alpha1_ReadOnlyType(in *ReadOnlyType, out *v1alpha1.ReadOnlyType, s conversion.Scope) error { + return autoConvert_v1beta1_ReadOnlyType_To_v1alpha1_ReadOnlyType(in, out, s) +} + +func autoConvert_v1alpha1_ReadOnlyType_To_v1beta1_ReadOnlyType(in *v1alpha1.ReadOnlyType, out *ReadOnlyType, s conversion.Scope) error { + out.Num = in.Num + out.Host = in.Host + out.Resources = (*v1.ResourceRequirements)(unsafe.Pointer(in.Resources)) + out.Affinity = (*v1.Affinity)(unsafe.Pointer(in.Affinity)) + out.Tolerations = *(*[]v1.Toleration)(unsafe.Pointer(&in.Tolerations)) + return nil +} + +// Convert_v1alpha1_ReadOnlyType_To_v1beta1_ReadOnlyType is an autogenerated conversion function. +func Convert_v1alpha1_ReadOnlyType_To_v1beta1_ReadOnlyType(in *v1alpha1.ReadOnlyType, out *ReadOnlyType, s conversion.Scope) error { + return autoConvert_v1alpha1_ReadOnlyType_To_v1beta1_ReadOnlyType(in, out, s) +} + +func autoConvert_v1beta1_RoStatus_To_v1alpha1_RoStatus(in *RoStatus, out *v1alpha1.RoStatus, s conversion.Scope) error { + out.ReadOnly = in.ReadOnly + out.Replication = in.Replication + out.Master = in.Master + return nil +} + +// Convert_v1beta1_RoStatus_To_v1alpha1_RoStatus is an autogenerated conversion function. +func Convert_v1beta1_RoStatus_To_v1alpha1_RoStatus(in *RoStatus, out *v1alpha1.RoStatus, s conversion.Scope) error { + return autoConvert_v1beta1_RoStatus_To_v1alpha1_RoStatus(in, out, s) +} + +func autoConvert_v1alpha1_RoStatus_To_v1beta1_RoStatus(in *v1alpha1.RoStatus, out *RoStatus, s conversion.Scope) error { + out.ReadOnly = in.ReadOnly + out.Replication = in.Replication + out.Master = in.Master + return nil +} + +// Convert_v1alpha1_RoStatus_To_v1beta1_RoStatus is an autogenerated conversion function. +func Convert_v1alpha1_RoStatus_To_v1beta1_RoStatus(in *v1alpha1.RoStatus, out *RoStatus, s conversion.Scope) error { + return autoConvert_v1alpha1_RoStatus_To_v1beta1_RoStatus(in, out, s) +} + func autoConvert_v1beta1_XenonOpts_To_v1alpha1_XenonOpts(in *XenonOpts, out *v1alpha1.XenonOpts, s conversion.Scope) error { out.Image = in.Image out.AdmitDefeatHearbeatCount = (*int32)(unsafe.Pointer(in.AdmitDefeatHearbeatCount)) diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index 133da1eb..9c52fc5b 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -462,6 +462,11 @@ func (in *MysqlClusterSpec) DeepCopyInto(out *MysqlClusterSpec) { *out = new(int32) **out = **in } + if in.ReadOnlys != nil { + in, out := &in.ReadOnlys, &out.ReadOnlys + *out = new(ReadOnlyType) + (*in).DeepCopyInto(*out) + } in.MySQLConfig.DeepCopyInto(&out.MySQLConfig) in.Resources.DeepCopyInto(&out.Resources) if in.CustomTLSSecret != nil { @@ -590,6 +595,11 @@ func (in *NodeCondition) DeepCopy() *NodeCondition { func (in *NodeStatus) DeepCopyInto(out *NodeStatus) { *out = *in in.RaftStatus.DeepCopyInto(&out.RaftStatus) + if in.RoStatus != nil { + in, out := &in.RoStatus, &out.RoStatus + *out = new(RoStatus) + **out = **in + } if in.Conditions != nil { in, out := &in.Conditions, &out.Conditions *out = make([]NodeCondition, len(*in)) @@ -629,6 +639,38 @@ func (in *RaftStatus) DeepCopy() *RaftStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ReadOnlyType) DeepCopyInto(out *ReadOnlyType) { + *out = *in + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = new(v1.ResourceRequirements) + (*in).DeepCopyInto(*out) + } + if in.Affinity != nil { + in, out := &in.Affinity, &out.Affinity + *out = new(v1.Affinity) + (*in).DeepCopyInto(*out) + } + if in.Tolerations != nil { + in, out := &in.Tolerations, &out.Tolerations + *out = make([]v1.Toleration, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReadOnlyType. +func (in *ReadOnlyType) DeepCopy() *ReadOnlyType { + if in == nil { + return nil + } + out := new(ReadOnlyType) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RemoteDataSource) DeepCopyInto(out *RemoteDataSource) { *out = *in @@ -649,6 +691,21 @@ func (in *RemoteDataSource) DeepCopy() *RemoteDataSource { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RoStatus) DeepCopyInto(out *RoStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RoStatus. +func (in *RoStatus) DeepCopy() *RoStatus { + if in == nil { + return nil + } + out := new(RoStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *S3) DeepCopyInto(out *S3) { *out = *in diff --git a/charts/mysql-operator/crds/mysql.radondb.com_mysqlclusters.yaml b/charts/mysql-operator/crds/mysql.radondb.com_mysqlclusters.yaml index cb88261b..bbc68b20 100644 --- a/charts/mysql-operator/crds/mysql.radondb.com_mysqlclusters.yaml +++ b/charts/mysql-operator/crds/mysql.radondb.com_mysqlclusters.yaml @@ -1300,505 +1300,106 @@ spec: type: object type: array type: object - replicas: - default: 3 - description: Replicas is the number of pods. - enum: - - 0 - - 1 - - 2 - - 3 - - 5 - format: int32 - type: integer - restoreFrom: - description: Represents the name of the cluster restore from backup - path. - type: string - tlsSecretName: - description: Containing CA (ca.crt) and server cert (tls.crt), server - private key (tls.key) for SSL - type: string - xenonOpts: - default: - admitDefeatHearbeatCount: 5 - electionTimeout: 10000 - image: radondb/xenon:v3.0.0-alpha - resources: - limits: - cpu: 100m - memory: 256Mi - requests: - cpu: 50m - memory: 128Mi - description: XenonOpts is the options of xenon container. + readonlys: + description: Readonlys Info. properties: - admitDefeatHearbeatCount: - default: 5 - description: High available component admit defeat heartbeat count. - format: int32 - type: integer - electionTimeout: - default: 10000 - description: High available component election timeout. The unit - is millisecond. - format: int32 - type: integer - enableAutoRebuild: - default: false - description: If true, when the data is inconsistent, Xenon will - automatically rebuild the invalid node. - type: boolean - image: - default: radondb/xenon:v3.0.0-alpha - description: To specify the image that will be used for xenon - container. - type: string - resources: - default: - limits: - cpu: 100m - memory: 256Mi - requests: - cpu: 50m - memory: 128Mi - description: The compute resource requirements. + affinity: + description: Affinity is a group of affinity scheduling rules. properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - type: object - type: object - status: - description: MysqlClusterStatus defines the observed state of MysqlCluster - properties: - conditions: - description: Conditions contains the list of the cluster conditions - fulfilled. - items: - description: ClusterCondition defines type for cluster conditions. - properties: - lastTransitionTime: - description: The last time this Condition type changed. - format: date-time - type: string - message: - description: Full text reason for current status of the condition. - type: string - reason: - description: One word, camel-case reason for current status - of the condition. - type: string - status: - description: Status of the condition, one of (\"True\", \"False\", - \"Unknown\"). - type: string - type: - description: Type of cluster condition, values in (\"Initializing\", - \"Ready\", \"Error\"). - type: string - required: - - lastTransitionTime - - status - - type - type: object - type: array - nodes: - description: Nodes contains the list of the node status fulfilled. - items: - description: NodeStatus defines type for status of a node into cluster. - properties: - conditions: - description: Conditions contains the list of the node conditions - fulfilled. - items: - description: NodeCondition defines type for representing node - conditions. + nodeAffinity: + description: Describes node affinity scheduling rules for + the pod. properties: - lastTransitionTime: - description: The last time this Condition type changed. - format: date-time - type: string - status: - description: Status of the node, one of (\"True\", \"False\", - \"Unknown\"). - type: string - type: - description: Type of the node condition. - type: string - required: - - lastTransitionTime - - status - - type - type: object - type: array - message: - description: Full text reason for current status of the node. - type: string - name: - description: Name of the node. - type: string - raftStatus: - description: RaftStatus is the raft status of the node. - properties: - leader: - description: Leader is the name of the Leader of the current - node. - type: string - nodes: - description: Nodes is a list of nodes that can be identified - by the current node. - items: - type: string - type: array - role: - description: Role is one of (LEADER/CANDIDATE/FOLLOWER/IDLE/INVALID) - type: string - type: object - required: - - name - type: object - type: array - readyNodes: - description: ReadyNodes represents number of the nodes that are in - ready state. - type: integer - state: - description: State - type: string - type: object - type: object - served: true - storage: true - subresources: - scale: - specReplicasPath: .spec.replicas - statusReplicasPath: .status.readyNodes - status: {} - - additionalPrinterColumns: - - description: The cluster status - jsonPath: .status.state - name: State - type: string - - description: The number of desired replicas - jsonPath: .spec.replicas - name: Desired - type: integer - - description: The number of current replicas - jsonPath: .status.readyNodes - name: Current - type: integer - - description: Name of the leader node - jsonPath: .status.nodes[?(@.raftStatus.role == 'LEADER')].name - name: Leader - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1beta1 - schema: - openAPIV3Schema: - description: MysqlCluster is the Schema for the mysqlclusters API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: MysqlClusterSpec defines the desired state of MysqlCluster - properties: - affinity: - description: 'Scheduling constraints of MySQL pod. Changing this value - causes MySQL to restart. More info: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node' - properties: - nodeAffinity: - description: Describes node affinity scheduling rules for the - pod. - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods to - nodes that satisfy the affinity expressions specified by - this field, but it may choose a node that violates one or - more of the expressions. The node that is most preferred - is the one with the greatest sum of weights, i.e. for each - node that meets all of the scheduling requirements (resource - request, requiredDuringScheduling affinity expressions, - etc.), compute a sum by iterating through the elements of - this field and adding "weight" to the sum if the node matches - the corresponding matchExpressions; the node(s) with the - highest sum are the most preferred. - items: - description: An empty preferred scheduling term matches - all objects with implicit weight 0 (i.e. it's a no-op). - A null preferred scheduling term matches no objects (i.e. - is also a no-op). - properties: - preference: - description: A node selector term, associated with the - corresponding weight. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: A node selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists, DoesNotExist. Gt, and - Lt. - type: string - values: - description: An array of string values. If - the operator is In or NotIn, the values - array must be non-empty. If the operator - is Exists or DoesNotExist, the values array - must be empty. If the operator is Gt or - Lt, the values array must have a single - element, which will be interpreted as an - integer. This array is replaced during a - strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: A node selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists, DoesNotExist. Gt, and - Lt. - type: string - values: - description: An array of string values. If - the operator is In or NotIn, the values - array must be non-empty. If the operator - is Exists or DoesNotExist, the values array - must be empty. If the operator is Gt or - Lt, the values array must have a single - element, which will be interpreted as an - integer. This array is replaced during a - strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - weight: - description: Weight associated with matching the corresponding - nodeSelectorTerm, in the range 1-100. - format: int32 - type: integer - required: - - preference - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified by this - field are not met at scheduling time, the pod will not be - scheduled onto the node. If the affinity requirements specified - by this field cease to be met at some point during pod execution - (e.g. due to an update), the system may or may not try to - eventually evict the pod from its node. - properties: - nodeSelectorTerms: - description: Required. A list of node selector terms. - The terms are ORed. + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node matches the corresponding matchExpressions; + the node(s) with the highest sum are the most preferred. items: - description: A null or empty node selector term matches - no objects. The requirements of them are ANDed. The - TopologySelectorTerm type implements a subset of the - NodeSelectorTerm. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: A node selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists, DoesNotExist. Gt, and - Lt. - type: string - values: - description: An array of string values. If - the operator is In or NotIn, the values - array must be non-empty. If the operator - is Exists or DoesNotExist, the values array - must be empty. If the operator is Gt or - Lt, the values array must have a single - element, which will be interpreted as an - integer. This array is replaced during a - strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: A node selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists, DoesNotExist. Gt, and - Lt. - type: string - values: - description: An array of string values. If - the operator is In or NotIn, the values - array must be non-empty. If the operator - is Exists or DoesNotExist, the values array - must be empty. If the operator is Gt or - Lt, the values array must have a single - element, which will be interpreted as an - integer. This array is replaced during a - strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - type: array - required: - - nodeSelectorTerms - type: object - type: object - podAffinity: - description: Describes pod affinity scheduling rules (e.g. co-locate - this pod in the same node, zone, etc. as some other pod(s)). - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods to - nodes that satisfy the affinity expressions specified by - this field, but it may choose a node that violates one or - more of the expressions. The node that is most preferred - is the one with the greatest sum of weights, i.e. for each - node that meets all of the scheduling requirements (resource - request, requiredDuringScheduling affinity expressions, - etc.), compute a sum by iterating through the elements of - this field and adding "weight" to the sum if the node has - pods which matches the corresponding podAffinityTerm; the - node(s) with the highest sum are the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, associated - with the corresponding weight. + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects + (i.e. is also a no-op). properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. + preference: + description: A node selector term, associated with + the corresponding weight. properties: matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. + description: A list of node selector requirements + by node's labels. items: - description: A label selector requirement - is a selector that contains values, a key, + description: A node selector requirement is + a selector that contains values, a key, and an operator that relates the key and values. properties: key: - description: key is the label key that - the selector applies to. + description: The label key that the selector + applies to. type: string operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. type: string values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. items: type: string type: array @@ -1807,56 +1408,103 @@ spec: - operator type: object type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. - type: object type: object - namespaceSelector: - description: A label query over the set of namespaces - that the term applies to. The term is applied - to the union of the namespaces selected by this - field and the ones listed in the namespaces field. - null selector and null or empty namespaces list - means "this pod's namespace". An empty selector - ({}) matches all namespaces. This field is beta-level - and is only honored when PodAffinityNamespaceSelector - feature is enabled. + weight: + description: Weight associated with matching the + corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from + its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: A null or empty node selector term + matches no objects. The requirements of them are + ANDed. The TopologySelectorTerm type implements + a subset of the NodeSelectorTerm. properties: matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. + description: A list of node selector requirements + by node's labels. items: - description: A label selector requirement - is a selector that contains values, a key, + description: A node selector requirement is + a selector that contains values, a key, and an operator that relates the key and values. properties: key: - description: key is the label key that - the selector applies to. + description: The label key that the selector + applies to. type: string operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. type: string values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. items: type: string type: array @@ -1865,266 +1513,252 @@ spec: - operator type: object type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. - type: object type: object - namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. The - term is applied to the union of the namespaces - listed in this field and the ones selected by - namespaceSelector. null or empty namespaces list - and null namespaceSelector means "this pod's namespace" - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods - matching the labelSelector in the specified namespaces, - where co-located is defined as running on a node - whose value of the label with key topologyKey - matches that of any node on which any of the selected - pods is running. Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - weight: - description: weight associated with matching the corresponding - podAffinityTerm, in the range 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified by this - field are not met at scheduling time, the pod will not be - scheduled onto the node. If the affinity requirements specified - by this field cease to be met at some point during pod execution - (e.g. due to a pod label update), the system may or may - not try to eventually evict the pod from its node. When - there are multiple elements, the lists of nodes corresponding - to each podAffinityTerm are intersected, i.e. all terms - must be satisfied. - items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) - that this pod should be co-located (affinity) or not co-located - (anti-affinity) with, where co-located is defined as running - on a node whose value of the label with key - matches that of any node on which a pod of the set of - pods is running - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are ANDed. - items: - description: A label selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. - properties: - key: - description: key is the label key that the - selector applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. If the - operator is Exists or DoesNotExist, the - values array must be empty. This array is - replaced during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is "In", - and the values array contains only "value". The - requirements are ANDed. - type: object - type: object - namespaceSelector: - description: A label query over the set of namespaces - that the term applies to. The term is applied to the - union of the namespaces selected by this field and - the ones listed in the namespaces field. null selector - and null or empty namespaces list means "this pod's - namespace". An empty selector ({}) matches all namespaces. - This field is beta-level and is only honored when - PodAffinityNamespaceSelector feature is enabled. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are ANDed. - items: - description: A label selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. - properties: - key: - description: key is the label key that the - selector applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. If the - operator is Exists or DoesNotExist, the - values array must be empty. This array is - replaced during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is "In", - and the values array contains only "value". The - requirements are ANDed. - type: object - type: object - namespaces: - description: namespaces specifies a static list of namespace - names that the term applies to. The term is applied - to the union of the namespaces listed in this field - and the ones selected by namespaceSelector. null or - empty namespaces list and null namespaceSelector means - "this pod's namespace" - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods matching - the labelSelector in the specified namespaces, where - co-located is defined as running on a node whose value - of the label with key topologyKey matches that of - any node on which any of the selected pods is running. - Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - type: array - type: object - podAntiAffinity: - description: Describes pod anti-affinity scheduling rules (e.g. - avoid putting this pod in the same node, zone, etc. as some - other pod(s)). - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods to - nodes that satisfy the anti-affinity expressions specified - by this field, but it may choose a node that violates one - or more of the expressions. The node that is most preferred - is the one with the greatest sum of weights, i.e. for each - node that meets all of the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity expressions, - etc.), compute a sum by iterating through the elements of - this field and adding "weight" to the sum if the node has - pods which matches the corresponding podAffinityTerm; the - node(s) with the highest sum are the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, associated - with the corresponding weight. + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. + co-locate this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. - items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: key is the label key that - the selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by + this field and the ones listed in the namespaces + field. null selector and null or empty namespaces + list means "this pod's namespace". An empty + selector ({}) matches all namespaces. This + field is beta-level and is only honored when + PodAffinityNamespaceSelector feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected + by namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to a pod label update), + the system may or may not try to eventually evict the + pod from its node. When there are multiple elements, + the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any node + on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. type: object type: object namespaceSelector: @@ -2207,168 +1841,343 @@ spec: required: - topologyKey type: object - weight: - description: weight associated with matching the corresponding - podAffinityTerm, in the range 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements specified by - this field are not met at scheduling time, the pod will - not be scheduled onto the node. If the anti-affinity requirements - specified by this field cease to be met at some point during - pod execution (e.g. due to a pod label update), the system - may or may not try to eventually evict the pod from its - node. When there are multiple elements, the lists of nodes - corresponding to each podAffinityTerm are intersected, i.e. - all terms must be satisfied. - items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) - that this pod should be co-located (affinity) or not co-located - (anti-affinity) with, where co-located is defined as running - on a node whose value of the label with key - matches that of any node on which a pod of the set of - pods is running - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules + (e.g. avoid putting this pod in the same node, zone, etc. + as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the anti-affinity expressions + specified by this field, but it may choose a node that + violates one or more of the expressions. The node that + is most preferred is the one with the greatest sum of + weights, i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + anti-affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are ANDed. - items: - description: A label selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. - properties: - key: - description: key is the label key that the - selector applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. If the - operator is Exists or DoesNotExist, the - values array must be empty. This array is - replaced during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is "In", - and the values array contains only "value". The - requirements are ANDed. + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by + this field and the ones listed in the namespaces + field. null selector and null or empty namespaces + list means "this pod's namespace". An empty + selector ({}) matches all namespaces. This + field is beta-level and is only honored when + PodAffinityNamespaceSelector feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected + by namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight type: object - namespaceSelector: - description: A label query over the set of namespaces - that the term applies to. The term is applied to the - union of the namespaces selected by this field and - the ones listed in the namespaces field. null selector - and null or empty namespaces list means "this pod's - namespace". An empty selector ({}) matches all namespaces. - This field is beta-level and is only honored when - PodAffinityNamespaceSelector feature is enabled. + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified + by this field are not met at scheduling time, the pod + will not be scheduled onto the node. If the anti-affinity + requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod + label update), the system may or may not try to eventually + evict the pod from its node. When there are multiple + elements, the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any node + on which a pod of the set of pods is running properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are ANDed. - items: - description: A label selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. - properties: - key: - description: key is the label key that the - selector applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists and DoesNotExist. + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. If the - operator is Exists or DoesNotExist, the - values array must be empty. This array is - replaced during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is "In", - and the values array contains only "value". The - requirements are ANDed. + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. This field is beta-level + and is only honored when PodAffinityNamespaceSelector + feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey type: object - namespaces: - description: namespaces specifies a static list of namespace - names that the term applies to. The term is applied - to the union of the namespaces listed in this field - and the ones selected by namespaceSelector. null or - empty namespaces list and null namespaceSelector means - "this pod's namespace" - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods matching - the labelSelector in the specified namespaces, where - co-located is defined as running on a node whose value - of the label with key topologyKey matches that of - any node on which any of the selected pods is running. - Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - type: array + type: array + type: object type: object - type: object - backupOpts: - description: Backup is the options of backup container. - properties: - image: - description: Image is the image of backup container. + hostname: + description: When the host name is empty, use the leader to change + master type: string + num: + description: ReadOnlys is the number of readonly pods. + format: int32 + type: integer resources: - description: 'Changing this value causes MySQL More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers' + description: The compute resource requirements. properties: limits: additionalProperties: @@ -2393,188 +2202,2378 @@ spec: to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object - type: object - customTLSSecret: - description: Containing CA (ca.crt) and server cert (tls.crt), server - private key (tls.key) for SSL - properties: - items: - description: If unspecified, each key-value pair in the Data field - of the referenced Secret will be projected into the volume as - a file whose name is the key and content is the value. If specified, - the listed keys will be projected into the specified paths, - and unlisted keys will not be present. If a key is specified - which is not present in the Secret, the volume setup will error - unless it is marked optional. Paths must be relative and may - not contain the '..' path or start with '..'. + tolerations: items: - description: Maps a string key to a path within a volume. + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, allowed + values are NoSchedule, PreferNoSchedule and NoExecute. + type: string key: - description: The key to project. + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match + all values and all keys. type: string - mode: - description: 'Optional: mode bits used to set permissions - on this file. Must be an octal value between 0000 and - 0777 or a decimal value between 0 and 511. YAML accepts - both octal and decimal values, JSON requires decimal values - for mode bits. If not specified, the volume defaultMode - will be used. This might be in conflict with other options - that affect the file mode, like fsGroup, and the result - can be other mode bits set.' - format: int32 + operator: + description: Operator represents a key's relationship to + the value. Valid operators are Exists and Equal. Defaults + to Equal. Exists is equivalent to wildcard for value, + so that a pod can tolerate all taints of a particular + category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of + time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the taint + forever (do not evict). Zero and negative values will + be treated as 0 (evict immediately) by the system. + format: int64 type: integer - path: - description: The relative path of the file to map the key - to. May not be an absolute path. May not contain the path - element '..'. May not start with the string '..'. + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. type: string - required: - - key - - path type: object type: array - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must be defined - type: boolean + required: + - num type: object - dataSource: - description: Specifies a data source for bootstrapping the MySQL cluster. + replicas: + default: 3 + description: Replicas is the number of pods. + enum: + - 0 + - 1 + - 2 + - 3 + - 5 + format: int32 + type: integer + restoreFrom: + description: Represents the name of the cluster restore from backup + path. + type: string + tlsSecretName: + description: Containing CA (ca.crt) and server cert (tls.crt), server + private key (tls.key) for SSL + type: string + xenonOpts: + default: + admitDefeatHearbeatCount: 5 + electionTimeout: 10000 + image: radondb/xenon:v3.0.0-alpha + resources: + limits: + cpu: 100m + memory: 256Mi + requests: + cpu: 50m + memory: 128Mi + description: XenonOpts is the options of xenon container. properties: - Nfsbackup: - description: restore from nfs - properties: - name: - description: Backup name - type: string - volume: - description: Secret name - properties: - path: - description: 'Path that is exported by the NFS server. - More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' - type: string - readOnly: - description: 'ReadOnly here will force the NFS export - to be mounted with read-only permissions. Defaults to - false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' - type: boolean - server: - description: 'Server is the hostname or IP address of - the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' - type: string - required: - - path - - server - type: object - required: - - name - type: object - S3backup: - description: Bootstraping from backup + admitDefeatHearbeatCount: + default: 5 + description: High available component admit defeat heartbeat count. + format: int32 + type: integer + electionTimeout: + default: 10000 + description: High available component election timeout. The unit + is millisecond. + format: int32 + type: integer + enableAutoRebuild: + default: false + description: If true, when the data is inconsistent, Xenon will + automatically rebuild the invalid node. + type: boolean + image: + default: radondb/xenon:v3.0.0-alpha + description: To specify the image that will be used for xenon + container. + type: string + resources: + default: + limits: + cpu: 100m + memory: 256Mi + requests: + cpu: 50m + memory: 128Mi + description: The compute resource requirements. properties: - name: - description: Backup name - type: string - secretName: - description: Secret name - type: string + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object type: object - remote: - description: Bootstraping from remote data source - properties: - sourceConfig: - description: "Adapts a secret into a projected volume. \n - The contents of the target Secret's Data field will be presented - in a projected volume as files using the keys in the Data - field as the file names. Note that this is identical to - a secret volume source without the default mode." + type: object + type: object + status: + description: MysqlClusterStatus defines the observed state of MysqlCluster + properties: + conditions: + description: Conditions contains the list of the cluster conditions + fulfilled. + items: + description: ClusterCondition defines type for cluster conditions. + properties: + lastTransitionTime: + description: The last time this Condition type changed. + format: date-time + type: string + message: + description: Full text reason for current status of the condition. + type: string + reason: + description: One word, camel-case reason for current status + of the condition. + type: string + status: + description: Status of the condition, one of (\"True\", \"False\", + \"Unknown\"). + type: string + type: + description: Type of cluster condition, values in (\"Initializing\", + \"Ready\", \"Error\"). + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + nodes: + description: Nodes contains the list of the node status fulfilled. + items: + description: NodeStatus defines type for status of a node into cluster. + properties: + conditions: + description: Conditions contains the list of the node conditions + fulfilled. + items: + description: NodeCondition defines type for representing node + conditions. properties: + lastTransitionTime: + description: The last time this Condition type changed. + format: date-time + type: string + status: + description: Status of the node, one of (\"True\", \"False\", + \"Unknown\"). + type: string + type: + description: Type of the node condition. + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + message: + description: Full text reason for current status of the node. + type: string + name: + description: Name of the node. + type: string + raftStatus: + description: RaftStatus is the raft status of the node. + properties: + leader: + description: Leader is the name of the Leader of the current + node. + type: string + nodes: + description: Nodes is a list of nodes that can be identified + by the current node. items: - description: If unspecified, each key-value pair in the - Data field of the referenced Secret will be projected - into the volume as a file whose name is the key and - content is the value. If specified, the listed keys - will be projected into the specified paths, and unlisted - keys will not be present. If a key is specified which - is not present in the Secret, the volume setup will - error unless it is marked optional. Paths must be relative - and may not contain the '..' path or start with '..'. - items: - description: Maps a string key to a path within a volume. - properties: - key: - description: The key to project. - type: string - mode: - description: 'Optional: mode bits used to set permissions - on this file. Must be an octal value between 0000 - and 0777 or a decimal value between 0 and 511. - YAML accepts both octal and decimal values, JSON - requires decimal values for mode bits. If not - specified, the volume defaultMode will be used. - This might be in conflict with other options that - affect the file mode, like fsGroup, and the result - can be other mode bits set.' - format: int32 - type: integer - path: - description: The relative path of the file to map - the key to. May not be an absolute path. May not - contain the path element '..'. May not start with - the string '..'. + type: string + type: array + role: + description: Role is one of (LEADER/CANDIDATE/FOLLOWER/IDLE/INVALID) + type: string + type: object + roStatus: + description: (RO) ReadOnly Status + properties: + Replication: + type: boolean + master: + type: string + readOnlyReady: + type: boolean + type: object + required: + - name + type: object + type: array + readyNodes: + description: ReadyNodes represents number of the nodes that are in + ready state. + type: integer + state: + description: State + type: string + type: object + type: object + served: true + storage: true + subresources: + scale: + specReplicasPath: .spec.replicas + statusReplicasPath: .status.readyNodes + status: {} + - additionalPrinterColumns: + - description: The cluster status + jsonPath: .status.state + name: State + type: string + - description: The number of desired replicas + jsonPath: .spec.replicas + name: Desired + type: integer + - description: The number of current replicas + jsonPath: .status.readyNodes + name: Current + type: integer + - description: Name of the leader node + jsonPath: .status.nodes[?(@.raftStatus.role == 'LEADER')].name + name: Leader + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: MysqlCluster is the Schema for the mysqlclusters API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: MysqlClusterSpec defines the desired state of MysqlCluster + properties: + affinity: + description: 'Scheduling constraints of MySQL pod. Changing this value + causes MySQL to restart. More info: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node' + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the + pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the affinity expressions specified by + this field, but it may choose a node that violates one or + more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node matches + the corresponding matchExpressions; the node(s) with the + highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects (i.e. + is also a no-op). + properties: + preference: + description: A node selector term, associated with the + corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching the corresponding + nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not be + scheduled onto the node. If the affinity requirements specified + by this field cease to be met at some point during pod execution + (e.g. due to an update), the system may or may not try to + eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: A null or empty node selector term matches + no objects. The requirements of them are ANDed. The + TopologySelectorTerm type implements a subset of the + NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate + this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the affinity expressions specified by + this field, but it may choose a node that violates one or + more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. This field is beta-level + and is only honored when PodAffinityNamespaceSelector + feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not be + scheduled onto the node. If the affinity requirements specified + by this field cease to be met at some point during pod execution + (e.g. due to a pod label update), the system may or may + not try to eventually evict the pod from its node. When + there are multiple elements, the lists of nodes corresponding + to each podAffinityTerm are intersected, i.e. all terms + must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not co-located + (anti-affinity) with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on which a pod of the set of + pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied to the + union of the namespaces selected by this field and + the ones listed in the namespaces field. null selector + and null or empty namespaces list means "this pod's + namespace". An empty selector ({}) matches all namespaces. + This field is beta-level and is only honored when + PodAffinityNamespaceSelector feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace + names that the term applies to. The term is applied + to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. null or + empty namespaces list and null namespaceSelector means + "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where + co-located is defined as running on a node whose value + of the label with key topologyKey matches that of + any node on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. + avoid putting this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the anti-affinity expressions specified + by this field, but it may choose a node that violates one + or more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. This field is beta-level + and is only honored when PodAffinityNamespaceSelector + feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the anti-affinity requirements + specified by this field cease to be met at some point during + pod execution (e.g. due to a pod label update), the system + may or may not try to eventually evict the pod from its + node. When there are multiple elements, the lists of nodes + corresponding to each podAffinityTerm are intersected, i.e. + all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not co-located + (anti-affinity) with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on which a pod of the set of + pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied to the + union of the namespaces selected by this field and + the ones listed in the namespaces field. null selector + and null or empty namespaces list means "this pod's + namespace". An empty selector ({}) matches all namespaces. + This field is beta-level and is only honored when + PodAffinityNamespaceSelector feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace + names that the term applies to. The term is applied + to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. null or + empty namespaces list and null namespaceSelector means + "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where + co-located is defined as running on a node whose value + of the label with key topologyKey matches that of + any node on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + backupOpts: + description: Backup is the options of backup container. + properties: + image: + description: Image is the image of backup container. + type: string + resources: + description: 'Changing this value causes MySQL More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + type: object + customTLSSecret: + description: Containing CA (ca.crt) and server cert (tls.crt), server + private key (tls.key) for SSL + properties: + items: + description: If unspecified, each key-value pair in the Data field + of the referenced Secret will be projected into the volume as + a file whose name is the key and content is the value. If specified, + the listed keys will be projected into the specified paths, + and unlisted keys will not be present. If a key is specified + which is not present in the Secret, the volume setup will error + unless it is marked optional. Paths must be relative and may + not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode bits used to set permissions + on this file. Must be an octal value between 0000 and + 0777 or a decimal value between 0 and 511. YAML accepts + both octal and decimal values, JSON requires decimal values + for mode bits. If not specified, the volume defaultMode + will be used. This might be in conflict with other options + that affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: The relative path of the file to map the key + to. May not be an absolute path. May not contain the path + element '..'. May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + type: object + dataSource: + description: Specifies a data source for bootstrapping the MySQL cluster. + properties: + Nfsbackup: + description: restore from nfs + properties: + name: + description: Backup name + type: string + volume: + description: Secret name + properties: + path: + description: 'Path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + readOnly: + description: 'ReadOnly here will force the NFS export + to be mounted with read-only permissions. Defaults to + false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: boolean + server: + description: 'Server is the hostname or IP address of + the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + required: + - path + - server + type: object + required: + - name + type: object + S3backup: + description: Bootstraping from backup + properties: + name: + description: Backup name + type: string + secretName: + description: Secret name + type: string + type: object + remote: + description: Bootstraping from remote data source + properties: + sourceConfig: + description: "Adapts a secret into a projected volume. \n + The contents of the target Secret's Data field will be presented + in a projected volume as files using the keys in the Data + field as the file names. Note that this is identical to + a secret volume source without the default mode." + properties: + items: + description: If unspecified, each key-value pair in the + Data field of the referenced Secret will be projected + into the volume as a file whose name is the key and + content is the value. If specified, the listed keys + will be projected into the specified paths, and unlisted + keys will not be present. If a key is specified which + is not present in the Secret, the volume setup will + error unless it is marked optional. Paths must be relative + and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode bits used to set permissions + on this file. Must be an octal value between 0000 + and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON + requires decimal values for mode bits. If not + specified, the volume defaultMode will be used. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: The relative path of the file to map + the key to. May not be an absolute path. May not + contain the path element '..'. May not start with + the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + type: object + type: object + type: object + enableAutoRebuild: + default: false + description: If true, when the data is inconsistent, Xenon will automatically + rebuild the invalid node. + type: boolean + image: + default: percona/percona-server:5.7.34 + description: Specifies mysql image to use. + type: string + imagePullPolicy: + description: 'ImagePullPolicy is used to determine when Kubernetes + will attempt to pull (download) container images. More info: https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy' + enum: + - Always + - Never + - IfNotPresent + type: string + logOpts: + description: LogOpts is the options of log settings. + properties: + auditLogTail: + default: false + description: AuditLogTail represents if tail the mysql audit log. + type: boolean + image: + default: busybox:1.32 + description: To specify the image that will be used for log container. + The busybox image. + type: string + resources: + description: Log container resources of a MySQL container. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + slowLogTail: + default: false + description: SlowLogTail represents if tail the mysql slow log. + type: boolean + type: object + maxLagTime: + default: 30 + description: MaxLagSeconds configures the readiness probe of mysqld + container if the replication lag is greater than MaxLagSeconds, + the mysqld container will not be not healthy. + minimum: 0 + type: integer + minAvailable: + default: 50% + description: The number of pods from that set that must still be available + after the eviction, even in the absence of the evicted pod + type: string + monitoringSpec: + description: Monitoring is the options of metrics container. + properties: + exporter: + properties: + customTLSSecret: + description: Projected secret containing custom TLS certificates + to encrypt output from the exporter web server + properties: + items: + description: If unspecified, each key-value pair in the + Data field of the referenced Secret will be projected + into the volume as a file whose name is the key and + content is the value. If specified, the listed keys + will be projected into the specified paths, and unlisted + keys will not be present. If a key is specified which + is not present in the Secret, the volume setup will + error unless it is marked optional. Paths must be relative + and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode bits used to set permissions + on this file. Must be an octal value between 0000 + and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON + requires decimal values for mode bits. If not + specified, the volume defaultMode will be used. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: The relative path of the file to map + the key to. May not be an absolute path. May not + contain the path element '..'. May not start with + the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + type: object + enabled: + default: true + description: enabled is used to enable/disable the exporter. + type: boolean + image: + default: prom/mysqld-exporter:v0.12.1 + description: To specify the image that will be used for metrics + container. + type: string + resources: + description: 'Changing this value causes MySQL and the exporter + to restart. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of + compute resources required. If Requests is omitted for + a container, it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined value. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + type: object + type: object + mysqlConfig: + description: MySQLConfig `ConfigMap` name of MySQL config. + properties: + configMapName: + description: Name of the `ConfigMap` containing MySQL config. + type: string + myCnf: + additionalProperties: + type: string + description: A map[string]string that will be passed to my.cnf + file. The key/value pairs is persisted in the configmap. + type: object + pluginCnf: + additionalProperties: + type: string + type: object + type: object + mysqlVersion: + default: "5.7" + description: 'Represents the MySQL version that will be run. The available + version can be found here: This field should be set even if the + Image is set to let the operator know which mysql version is running. + Based on this version the operator can take decisions which features + can be used.' + type: string + priorityClassName: + description: 'Priority class name for the MySQL pods. Changing this + value causes MySQL to restart. More info: https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/' + type: string + readonlys: + description: Readonlys Info. + properties: + affinity: + description: Affinity is a group of affinity scheduling rules. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for + the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node matches the corresponding matchExpressions; + the node(s) with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects + (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with + the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching the + corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from + its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: A null or empty node selector term + matches no objects. The requirements of them are + ANDed. The TopologySelectorTerm type implements + a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. + co-locate this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by + this field and the ones listed in the namespaces + field. null selector and null or empty namespaces + list means "this pod's namespace". An empty + selector ({}) matches all namespaces. This + field is beta-level and is only honored when + PodAffinityNamespaceSelector feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected + by namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to a pod label update), + the system may or may not try to eventually evict the + pod from its node. When there are multiple elements, + the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any node + on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. This field is beta-level + and is only honored when PodAffinityNamespaceSelector + feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules + (e.g. avoid putting this pod in the same node, zone, etc. + as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the anti-affinity expressions + specified by this field, but it may choose a node that + violates one or more of the expressions. The node that + is most preferred is the one with the greatest sum of + weights, i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + anti-affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by + this field and the ones listed in the namespaces + field. null selector and null or empty namespaces + list means "this pod's namespace". An empty + selector ({}) matches all namespaces. This + field is beta-level and is only honored when + PodAffinityNamespaceSelector feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected + by namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified + by this field are not met at scheduling time, the pod + will not be scheduled onto the node. If the anti-affinity + requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod + label update), the system may or may not try to eventually + evict the pod from its node. When there are multiple + elements, the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any node + on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. This field is beta-level + and is only honored when PodAffinityNamespaceSelector + feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. type: string required: - - key - - path + - topologyKey type: object type: array - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean type: object type: object - type: object - enableAutoRebuild: - default: false - description: If true, when the data is inconsistent, Xenon will automatically - rebuild the invalid node. - type: boolean - image: - default: percona/percona-server:5.7.34 - description: Specifies mysql image to use. - type: string - imagePullPolicy: - description: 'ImagePullPolicy is used to determine when Kubernetes - will attempt to pull (download) container images. More info: https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy' - enum: - - Always - - Never - - IfNotPresent - type: string - logOpts: - description: LogOpts is the options of log settings. - properties: - auditLogTail: - default: false - description: AuditLogTail represents if tail the mysql audit log. - type: boolean - image: - default: busybox:1.32 - description: To specify the image that will be used for log container. - The busybox image. + hostname: + description: When the host name is empty, use the leader to change + master type: string + num: + description: ReadOnlys is the number of readonly pods. + format: int32 + type: integer resources: - description: Log container resources of a MySQL container. + description: The compute resource requirements. properties: limits: additionalProperties: @@ -2599,148 +4598,49 @@ spec: to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object - slowLogTail: - default: false - description: SlowLogTail represents if tail the mysql slow log. - type: boolean - type: object - maxLagTime: - default: 30 - description: MaxLagSeconds configures the readiness probe of mysqld - container if the replication lag is greater than MaxLagSeconds, - the mysqld container will not be not healthy. - minimum: 0 - type: integer - minAvailable: - default: 50% - description: The number of pods from that set that must still be available - after the eviction, even in the absence of the evicted pod - type: string - monitoringSpec: - description: Monitoring is the options of metrics container. - properties: - exporter: - properties: - customTLSSecret: - description: Projected secret containing custom TLS certificates - to encrypt output from the exporter web server - properties: - items: - description: If unspecified, each key-value pair in the - Data field of the referenced Secret will be projected - into the volume as a file whose name is the key and - content is the value. If specified, the listed keys - will be projected into the specified paths, and unlisted - keys will not be present. If a key is specified which - is not present in the Secret, the volume setup will - error unless it is marked optional. Paths must be relative - and may not contain the '..' path or start with '..'. - items: - description: Maps a string key to a path within a volume. - properties: - key: - description: The key to project. - type: string - mode: - description: 'Optional: mode bits used to set permissions - on this file. Must be an octal value between 0000 - and 0777 or a decimal value between 0 and 511. - YAML accepts both octal and decimal values, JSON - requires decimal values for mode bits. If not - specified, the volume defaultMode will be used. - This might be in conflict with other options that - affect the file mode, like fsGroup, and the result - can be other mode bits set.' - format: int32 - type: integer - path: - description: The relative path of the file to map - the key to. May not be an absolute path. May not - contain the path element '..'. May not start with - the string '..'. - type: string - required: - - key - - path - type: object - type: array - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean - type: object - enabled: - default: true - description: enabled is used to enable/disable the exporter. - type: boolean - image: - default: prom/mysqld-exporter:v0.12.1 - description: To specify the image that will be used for metrics - container. - type: string - resources: - description: 'Changing this value causes MySQL and the exporter - to restart. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers' - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of - compute resources required. If Requests is omitted for - a container, it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined value. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - type: object - type: object - mysqlConfig: - description: MySQLConfig `ConfigMap` name of MySQL config. - properties: - configMapName: - description: Name of the `ConfigMap` containing MySQL config. - type: string - myCnf: - additionalProperties: - type: string - description: A map[string]string that will be passed to my.cnf - file. The key/value pairs is persisted in the configmap. - type: object - pluginCnf: - additionalProperties: - type: string - type: object + tolerations: + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, allowed + values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match + all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to + the value. Valid operators are Exists and Equal. Defaults + to Equal. Exists is equivalent to wildcard for value, + so that a pod can tolerate all taints of a particular + category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of + time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the taint + forever (do not evict). Zero and negative values will + be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + required: + - num type: object - mysqlVersion: - default: "5.7" - description: 'Represents the MySQL version that will be run. The available - version can be found here: This field should be set even if the - Image is set to let the operator know which mysql version is running. - Based on this version the operator can take decisions which features - can be used.' - type: string - priorityClassName: - description: 'Priority class name for the MySQL pods. Changing this - value causes MySQL to restart. More info: https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/' - type: string replicas: default: 3 description: Replicas is the number of pods. @@ -3188,6 +5088,16 @@ spec: description: Role is one of (LEADER/CANDIDATE/FOLLOWER/IDLE/INVALID) type: string type: object + roStatus: + description: (RO) ReadOnly Status + properties: + Replication: + type: boolean + master: + type: string + readOnlyReady: + type: boolean + type: object required: - name type: object diff --git a/charts/mysql-operator/templates/deployment.yaml b/charts/mysql-operator/templates/deployment.yaml index b3a7c479..f1c4817f 100644 --- a/charts/mysql-operator/templates/deployment.yaml +++ b/charts/mysql-operator/templates/deployment.yaml @@ -34,7 +34,9 @@ spec: containers: {{- if .Values.rbacProxy.create }} - name: kube-rbac-proxy - {{- $imagerepo:=(split "/" .Values.rbacProxy.image)._0 }} + {{- $imageList:=(splitList "/" .Values.rbacProxy.image) }} + {{- $imagerepo:=(join "/" (slice $imageList 0 (sub (len $imageList) 1)) | default "library") }} + {{- $imagetag:= printf "%s:%s" $imageList .Values.manager.tag }} {{- $imagetag:= (splitList "/" .Values.rbacProxy.image )|last }} {{- if .Values.imageNamespaceOverride}} {{- if .Values.imagePrefix}} @@ -81,8 +83,9 @@ spec: - --health-probe-bind-address=:8081 - --metrics-bind-address=127.0.0.1:8080 - --leader-elect - {{- $imagerepo:=(split "/" .Values.manager.image)._0 }} - {{- $imagetag:= printf "%s:%s" (splitList "/" .Values.manager.image|last) .Values.manager.tag }} + {{- $imageList:=(splitList "/" .Values.manager.image) }} + {{- $imagerepo:=(join "/" (slice $imageList 0 (sub (len $imageList) 1)) | default "library") }} + {{- $imagetag:= printf "%s:%s" ($imageList | last) .Values.manager.tag }} {{- if .Values.imageNamespaceOverride}} {{- if .Values.imagePrefix}} image: {{ printf "%s/%s/%s" .Values.imagePrefix .Values.imageNamespaceOverride $imagetag|quote }} @@ -140,4 +143,4 @@ spec: operator: In values: - {{ template "mysql-operator.name" . }} - topologyKey: "kubernetes.io/hostname" + topologyKey: "kubernetes.io/hostname" \ No newline at end of file diff --git a/cmd/mysql/main.go b/cmd/mysql/main.go index 50d34621..eb692bb2 100644 --- a/cmd/mysql/main.go +++ b/cmd/mysql/main.go @@ -23,6 +23,7 @@ import ( "fmt" "os" "strconv" + "strings" "time" "github.com/go-ini/ini" @@ -257,7 +258,24 @@ func (c *Agent) readiness() error { } } + default: + if strings.Contains(c.podName, "-ro-") { //is ro pod + status := &SlaveStatus{} + err1 := c.db.GetContext(context.Background(), status, `show slave status`) + if err1 != nil { + return err + } + if status.SlaveIORunning != "Yes" || status.SlaveSQLRunning != "Yes" { + return fmt.Errorf("replication threads are stopped") + } + if status.LastError != "" { + return fmt.Errorf("slave has error: %s", status.LastError) + } + if status.SecondsBehindMaster.Int64 > int64(c.maxDelay.Seconds()) { + return fmt.Errorf("slave is too far behind master") + } + } } return nil } @@ -322,6 +340,9 @@ func getMySQLConn(conf *MySQLConfig) (*sqlx.DB, error) { } func (c *Agent) getRoleBylabel() (string, error) { + if strings.Contains(c.podName, "-ro-") { // it's readonly pod + return "RO", nil + } podMeta, err := c.ksClient.CoreV1().Pods(c.nameSpace).Get(context.TODO(), c.podName, metav1.GetOptions{}) if err != nil { return "", err diff --git a/config/crd/bases/mysql.radondb.com_mysqlclusters.yaml b/config/crd/bases/mysql.radondb.com_mysqlclusters.yaml index 42852fa0..a673435f 100644 --- a/config/crd/bases/mysql.radondb.com_mysqlclusters.yaml +++ b/config/crd/bases/mysql.radondb.com_mysqlclusters.yaml @@ -1288,505 +1288,106 @@ spec: type: object type: array type: object - replicas: - default: 3 - description: Replicas is the number of pods. - enum: - - 0 - - 1 - - 2 - - 3 - - 5 - format: int32 - type: integer - restoreFrom: - description: Represents the name of the cluster restore from backup - path. - type: string - tlsSecretName: - description: Containing CA (ca.crt) and server cert (tls.crt), server - private key (tls.key) for SSL - type: string - xenonOpts: - default: - admitDefeatHearbeatCount: 5 - electionTimeout: 10000 - image: radondb/xenon:v3.0.0-alpha - resources: - limits: - cpu: 100m - memory: 256Mi - requests: - cpu: 50m - memory: 128Mi - description: XenonOpts is the options of xenon container. + readonlys: + description: Readonlys Info. properties: - admitDefeatHearbeatCount: - default: 5 - description: High available component admit defeat heartbeat count. - format: int32 - type: integer - electionTimeout: - default: 10000 - description: High available component election timeout. The unit - is millisecond. - format: int32 - type: integer - enableAutoRebuild: - default: false - description: If true, when the data is inconsistent, Xenon will - automatically rebuild the invalid node. - type: boolean - image: - default: radondb/xenon:v3.0.0-alpha - description: To specify the image that will be used for xenon - container. - type: string - resources: - default: - limits: - cpu: 100m - memory: 256Mi - requests: - cpu: 50m - memory: 128Mi - description: The compute resource requirements. + affinity: + description: Affinity is a group of affinity scheduling rules. properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - type: object - type: object - status: - description: MysqlClusterStatus defines the observed state of MysqlCluster - properties: - conditions: - description: Conditions contains the list of the cluster conditions - fulfilled. - items: - description: ClusterCondition defines type for cluster conditions. - properties: - lastTransitionTime: - description: The last time this Condition type changed. - format: date-time - type: string - message: - description: Full text reason for current status of the condition. - type: string - reason: - description: One word, camel-case reason for current status - of the condition. - type: string - status: - description: Status of the condition, one of (\"True\", \"False\", - \"Unknown\"). - type: string - type: - description: Type of cluster condition, values in (\"Initializing\", - \"Ready\", \"Error\"). - type: string - required: - - lastTransitionTime - - status - - type - type: object - type: array - nodes: - description: Nodes contains the list of the node status fulfilled. - items: - description: NodeStatus defines type for status of a node into cluster. - properties: - conditions: - description: Conditions contains the list of the node conditions - fulfilled. - items: - description: NodeCondition defines type for representing node - conditions. + nodeAffinity: + description: Describes node affinity scheduling rules for + the pod. properties: - lastTransitionTime: - description: The last time this Condition type changed. - format: date-time - type: string - status: - description: Status of the node, one of (\"True\", \"False\", - \"Unknown\"). - type: string - type: - description: Type of the node condition. - type: string - required: - - lastTransitionTime - - status - - type - type: object - type: array - message: - description: Full text reason for current status of the node. - type: string - name: - description: Name of the node. - type: string - raftStatus: - description: RaftStatus is the raft status of the node. - properties: - leader: - description: Leader is the name of the Leader of the current - node. - type: string - nodes: - description: Nodes is a list of nodes that can be identified - by the current node. - items: - type: string - type: array - role: - description: Role is one of (LEADER/CANDIDATE/FOLLOWER/IDLE/INVALID) - type: string - type: object - required: - - name - type: object - type: array - readyNodes: - description: ReadyNodes represents number of the nodes that are in - ready state. - type: integer - state: - description: State - type: string - type: object - type: object - served: true - storage: true - subresources: - scale: - specReplicasPath: .spec.replicas - statusReplicasPath: .status.readyNodes - status: {} - - additionalPrinterColumns: - - description: The cluster status - jsonPath: .status.state - name: State - type: string - - description: The number of desired replicas - jsonPath: .spec.replicas - name: Desired - type: integer - - description: The number of current replicas - jsonPath: .status.readyNodes - name: Current - type: integer - - description: Name of the leader node - jsonPath: .status.nodes[?(@.raftStatus.role == 'LEADER')].name - name: Leader - type: string - - jsonPath: .metadata.creationTimestamp - name: Age - type: date - name: v1beta1 - schema: - openAPIV3Schema: - description: MysqlCluster is the Schema for the mysqlclusters API - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: MysqlClusterSpec defines the desired state of MysqlCluster - properties: - affinity: - description: 'Scheduling constraints of MySQL pod. Changing this value - causes MySQL to restart. More info: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node' - properties: - nodeAffinity: - description: Describes node affinity scheduling rules for the - pod. - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods to - nodes that satisfy the affinity expressions specified by - this field, but it may choose a node that violates one or - more of the expressions. The node that is most preferred - is the one with the greatest sum of weights, i.e. for each - node that meets all of the scheduling requirements (resource - request, requiredDuringScheduling affinity expressions, - etc.), compute a sum by iterating through the elements of - this field and adding "weight" to the sum if the node matches - the corresponding matchExpressions; the node(s) with the - highest sum are the most preferred. - items: - description: An empty preferred scheduling term matches - all objects with implicit weight 0 (i.e. it's a no-op). - A null preferred scheduling term matches no objects (i.e. - is also a no-op). - properties: - preference: - description: A node selector term, associated with the - corresponding weight. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: A node selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists, DoesNotExist. Gt, and - Lt. - type: string - values: - description: An array of string values. If - the operator is In or NotIn, the values - array must be non-empty. If the operator - is Exists or DoesNotExist, the values array - must be empty. If the operator is Gt or - Lt, the values array must have a single - element, which will be interpreted as an - integer. This array is replaced during a - strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: A node selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists, DoesNotExist. Gt, and - Lt. - type: string - values: - description: An array of string values. If - the operator is In or NotIn, the values - array must be non-empty. If the operator - is Exists or DoesNotExist, the values array - must be empty. If the operator is Gt or - Lt, the values array must have a single - element, which will be interpreted as an - integer. This array is replaced during a - strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - weight: - description: Weight associated with matching the corresponding - nodeSelectorTerm, in the range 1-100. - format: int32 - type: integer - required: - - preference - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified by this - field are not met at scheduling time, the pod will not be - scheduled onto the node. If the affinity requirements specified - by this field cease to be met at some point during pod execution - (e.g. due to an update), the system may or may not try to - eventually evict the pod from its node. - properties: - nodeSelectorTerms: - description: Required. A list of node selector terms. - The terms are ORed. + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node matches the corresponding matchExpressions; + the node(s) with the highest sum are the most preferred. items: - description: A null or empty node selector term matches - no objects. The requirements of them are ANDed. The - TopologySelectorTerm type implements a subset of the - NodeSelectorTerm. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: A node selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists, DoesNotExist. Gt, and - Lt. - type: string - values: - description: An array of string values. If - the operator is In or NotIn, the values - array must be non-empty. If the operator - is Exists or DoesNotExist, the values array - must be empty. If the operator is Gt or - Lt, the values array must have a single - element, which will be interpreted as an - integer. This array is replaced during a - strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: A node selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists, DoesNotExist. Gt, and - Lt. - type: string - values: - description: An array of string values. If - the operator is In or NotIn, the values - array must be non-empty. If the operator - is Exists or DoesNotExist, the values array - must be empty. If the operator is Gt or - Lt, the values array must have a single - element, which will be interpreted as an - integer. This array is replaced during a - strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - type: array - required: - - nodeSelectorTerms - type: object - type: object - podAffinity: - description: Describes pod affinity scheduling rules (e.g. co-locate - this pod in the same node, zone, etc. as some other pod(s)). - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods to - nodes that satisfy the affinity expressions specified by - this field, but it may choose a node that violates one or - more of the expressions. The node that is most preferred - is the one with the greatest sum of weights, i.e. for each - node that meets all of the scheduling requirements (resource - request, requiredDuringScheduling affinity expressions, - etc.), compute a sum by iterating through the elements of - this field and adding "weight" to the sum if the node has - pods which matches the corresponding podAffinityTerm; the - node(s) with the highest sum are the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, associated - with the corresponding weight. + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects + (i.e. is also a no-op). properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. + preference: + description: A node selector term, associated with + the corresponding weight. properties: matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. + description: A list of node selector requirements + by node's labels. items: - description: A label selector requirement - is a selector that contains values, a key, + description: A node selector requirement is + a selector that contains values, a key, and an operator that relates the key and values. properties: key: - description: key is the label key that - the selector applies to. + description: The label key that the selector + applies to. type: string operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. type: string values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. items: type: string type: array @@ -1795,56 +1396,103 @@ spec: - operator type: object type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. - type: object type: object - namespaceSelector: - description: A label query over the set of namespaces - that the term applies to. The term is applied - to the union of the namespaces selected by this - field and the ones listed in the namespaces field. - null selector and null or empty namespaces list - means "this pod's namespace". An empty selector - ({}) matches all namespaces. This field is beta-level - and is only honored when PodAffinityNamespaceSelector - feature is enabled. + weight: + description: Weight associated with matching the + corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from + its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: A null or empty node selector term + matches no objects. The requirements of them are + ANDed. The TopologySelectorTerm type implements + a subset of the NodeSelectorTerm. properties: matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. + description: A list of node selector requirements + by node's labels. items: - description: A label selector requirement - is a selector that contains values, a key, + description: A node selector requirement is + a selector that contains values, a key, and an operator that relates the key and values. properties: key: - description: key is the label key that - the selector applies to. + description: The label key that the selector + applies to. type: string operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. type: string values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. items: type: string type: array @@ -1853,266 +1501,252 @@ spec: - operator type: object type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. - type: object type: object - namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. The - term is applied to the union of the namespaces - listed in this field and the ones selected by - namespaceSelector. null or empty namespaces list - and null namespaceSelector means "this pod's namespace" - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods - matching the labelSelector in the specified namespaces, - where co-located is defined as running on a node - whose value of the label with key topologyKey - matches that of any node on which any of the selected - pods is running. Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - weight: - description: weight associated with matching the corresponding - podAffinityTerm, in the range 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified by this - field are not met at scheduling time, the pod will not be - scheduled onto the node. If the affinity requirements specified - by this field cease to be met at some point during pod execution - (e.g. due to a pod label update), the system may or may - not try to eventually evict the pod from its node. When - there are multiple elements, the lists of nodes corresponding - to each podAffinityTerm are intersected, i.e. all terms - must be satisfied. - items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) - that this pod should be co-located (affinity) or not co-located - (anti-affinity) with, where co-located is defined as running - on a node whose value of the label with key - matches that of any node on which a pod of the set of - pods is running - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are ANDed. - items: - description: A label selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. - properties: - key: - description: key is the label key that the - selector applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. If the - operator is Exists or DoesNotExist, the - values array must be empty. This array is - replaced during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is "In", - and the values array contains only "value". The - requirements are ANDed. - type: object - type: object - namespaceSelector: - description: A label query over the set of namespaces - that the term applies to. The term is applied to the - union of the namespaces selected by this field and - the ones listed in the namespaces field. null selector - and null or empty namespaces list means "this pod's - namespace". An empty selector ({}) matches all namespaces. - This field is beta-level and is only honored when - PodAffinityNamespaceSelector feature is enabled. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are ANDed. - items: - description: A label selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. - properties: - key: - description: key is the label key that the - selector applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. If the - operator is Exists or DoesNotExist, the - values array must be empty. This array is - replaced during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is "In", - and the values array contains only "value". The - requirements are ANDed. - type: object - type: object - namespaces: - description: namespaces specifies a static list of namespace - names that the term applies to. The term is applied - to the union of the namespaces listed in this field - and the ones selected by namespaceSelector. null or - empty namespaces list and null namespaceSelector means - "this pod's namespace" - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods matching - the labelSelector in the specified namespaces, where - co-located is defined as running on a node whose value - of the label with key topologyKey matches that of - any node on which any of the selected pods is running. - Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - type: array - type: object - podAntiAffinity: - description: Describes pod anti-affinity scheduling rules (e.g. - avoid putting this pod in the same node, zone, etc. as some - other pod(s)). - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods to - nodes that satisfy the anti-affinity expressions specified - by this field, but it may choose a node that violates one - or more of the expressions. The node that is most preferred - is the one with the greatest sum of weights, i.e. for each - node that meets all of the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity expressions, - etc.), compute a sum by iterating through the elements of - this field and adding "weight" to the sum if the node has - pods which matches the corresponding podAffinityTerm; the - node(s) with the highest sum are the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, associated - with the corresponding weight. + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. + co-locate this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. - items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: key is the label key that - the selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by + this field and the ones listed in the namespaces + field. null selector and null or empty namespaces + list means "this pod's namespace". An empty + selector ({}) matches all namespaces. This + field is beta-level and is only honored when + PodAffinityNamespaceSelector feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected + by namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to a pod label update), + the system may or may not try to eventually evict the + pod from its node. When there are multiple elements, + the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any node + on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. type: object type: object namespaceSelector: @@ -2195,168 +1829,343 @@ spec: required: - topologyKey type: object - weight: - description: weight associated with matching the corresponding - podAffinityTerm, in the range 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements specified by - this field are not met at scheduling time, the pod will - not be scheduled onto the node. If the anti-affinity requirements - specified by this field cease to be met at some point during - pod execution (e.g. due to a pod label update), the system - may or may not try to eventually evict the pod from its - node. When there are multiple elements, the lists of nodes - corresponding to each podAffinityTerm are intersected, i.e. - all terms must be satisfied. - items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) - that this pod should be co-located (affinity) or not co-located - (anti-affinity) with, where co-located is defined as running - on a node whose value of the label with key - matches that of any node on which a pod of the set of - pods is running - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules + (e.g. avoid putting this pod in the same node, zone, etc. + as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the anti-affinity expressions + specified by this field, but it may choose a node that + violates one or more of the expressions. The node that + is most preferred is the one with the greatest sum of + weights, i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + anti-affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are ANDed. - items: - description: A label selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. - properties: - key: - description: key is the label key that the - selector applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. If the - operator is Exists or DoesNotExist, the - values array must be empty. This array is - replaced during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is "In", - and the values array contains only "value". The - requirements are ANDed. + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by + this field and the ones listed in the namespaces + field. null selector and null or empty namespaces + list means "this pod's namespace". An empty + selector ({}) matches all namespaces. This + field is beta-level and is only honored when + PodAffinityNamespaceSelector feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected + by namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight type: object - namespaceSelector: - description: A label query over the set of namespaces - that the term applies to. The term is applied to the - union of the namespaces selected by this field and - the ones listed in the namespaces field. null selector - and null or empty namespaces list means "this pod's - namespace". An empty selector ({}) matches all namespaces. - This field is beta-level and is only honored when - PodAffinityNamespaceSelector feature is enabled. + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified + by this field are not met at scheduling time, the pod + will not be scheduled onto the node. If the anti-affinity + requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod + label update), the system may or may not try to eventually + evict the pod from its node. When there are multiple + elements, the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any node + on which a pod of the set of pods is running properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are ANDed. - items: - description: A label selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. - properties: - key: - description: key is the label key that the - selector applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists and DoesNotExist. + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. If the - operator is Exists or DoesNotExist, the - values array must be empty. This array is - replaced during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is "In", - and the values array contains only "value". The - requirements are ANDed. + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. This field is beta-level + and is only honored when PodAffinityNamespaceSelector + feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey type: object - namespaces: - description: namespaces specifies a static list of namespace - names that the term applies to. The term is applied - to the union of the namespaces listed in this field - and the ones selected by namespaceSelector. null or - empty namespaces list and null namespaceSelector means - "this pod's namespace" - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods matching - the labelSelector in the specified namespaces, where - co-located is defined as running on a node whose value - of the label with key topologyKey matches that of - any node on which any of the selected pods is running. - Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - type: array + type: array + type: object type: object - type: object - backupOpts: - description: Backup is the options of backup container. - properties: - image: - description: Image is the image of backup container. + hostname: + description: When the host name is empty, use the leader to change + master type: string + num: + description: ReadOnlys is the number of readonly pods. + format: int32 + type: integer resources: - description: 'Changing this value causes MySQL More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers' + description: The compute resource requirements. properties: limits: additionalProperties: @@ -2381,188 +2190,2378 @@ spec: to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object - type: object - customTLSSecret: - description: Containing CA (ca.crt) and server cert (tls.crt), server - private key (tls.key) for SSL - properties: - items: - description: If unspecified, each key-value pair in the Data field - of the referenced Secret will be projected into the volume as - a file whose name is the key and content is the value. If specified, - the listed keys will be projected into the specified paths, - and unlisted keys will not be present. If a key is specified - which is not present in the Secret, the volume setup will error - unless it is marked optional. Paths must be relative and may - not contain the '..' path or start with '..'. + tolerations: items: - description: Maps a string key to a path within a volume. + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, allowed + values are NoSchedule, PreferNoSchedule and NoExecute. + type: string key: - description: The key to project. + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match + all values and all keys. type: string - mode: - description: 'Optional: mode bits used to set permissions - on this file. Must be an octal value between 0000 and - 0777 or a decimal value between 0 and 511. YAML accepts - both octal and decimal values, JSON requires decimal values - for mode bits. If not specified, the volume defaultMode - will be used. This might be in conflict with other options - that affect the file mode, like fsGroup, and the result - can be other mode bits set.' - format: int32 + operator: + description: Operator represents a key's relationship to + the value. Valid operators are Exists and Equal. Defaults + to Equal. Exists is equivalent to wildcard for value, + so that a pod can tolerate all taints of a particular + category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of + time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the taint + forever (do not evict). Zero and negative values will + be treated as 0 (evict immediately) by the system. + format: int64 type: integer - path: - description: The relative path of the file to map the key - to. May not be an absolute path. May not contain the path - element '..'. May not start with the string '..'. + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. type: string - required: - - key - - path type: object type: array - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must be defined - type: boolean + required: + - num type: object - dataSource: - description: Specifies a data source for bootstrapping the MySQL cluster. + replicas: + default: 3 + description: Replicas is the number of pods. + enum: + - 0 + - 1 + - 2 + - 3 + - 5 + format: int32 + type: integer + restoreFrom: + description: Represents the name of the cluster restore from backup + path. + type: string + tlsSecretName: + description: Containing CA (ca.crt) and server cert (tls.crt), server + private key (tls.key) for SSL + type: string + xenonOpts: + default: + admitDefeatHearbeatCount: 5 + electionTimeout: 10000 + image: radondb/xenon:v3.0.0-alpha + resources: + limits: + cpu: 100m + memory: 256Mi + requests: + cpu: 50m + memory: 128Mi + description: XenonOpts is the options of xenon container. properties: - Nfsbackup: - description: restore from nfs - properties: - name: - description: Backup name - type: string - volume: - description: Secret name - properties: - path: - description: 'Path that is exported by the NFS server. - More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' - type: string - readOnly: - description: 'ReadOnly here will force the NFS export - to be mounted with read-only permissions. Defaults to - false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' - type: boolean - server: - description: 'Server is the hostname or IP address of - the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' - type: string - required: - - path - - server - type: object - required: - - name - type: object - S3backup: - description: Bootstraping from backup + admitDefeatHearbeatCount: + default: 5 + description: High available component admit defeat heartbeat count. + format: int32 + type: integer + electionTimeout: + default: 10000 + description: High available component election timeout. The unit + is millisecond. + format: int32 + type: integer + enableAutoRebuild: + default: false + description: If true, when the data is inconsistent, Xenon will + automatically rebuild the invalid node. + type: boolean + image: + default: radondb/xenon:v3.0.0-alpha + description: To specify the image that will be used for xenon + container. + type: string + resources: + default: + limits: + cpu: 100m + memory: 256Mi + requests: + cpu: 50m + memory: 128Mi + description: The compute resource requirements. properties: - name: - description: Backup name - type: string - secretName: - description: Secret name - type: string + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object type: object - remote: - description: Bootstraping from remote data source - properties: - sourceConfig: - description: "Adapts a secret into a projected volume. \n - The contents of the target Secret's Data field will be presented - in a projected volume as files using the keys in the Data - field as the file names. Note that this is identical to - a secret volume source without the default mode." + type: object + type: object + status: + description: MysqlClusterStatus defines the observed state of MysqlCluster + properties: + conditions: + description: Conditions contains the list of the cluster conditions + fulfilled. + items: + description: ClusterCondition defines type for cluster conditions. + properties: + lastTransitionTime: + description: The last time this Condition type changed. + format: date-time + type: string + message: + description: Full text reason for current status of the condition. + type: string + reason: + description: One word, camel-case reason for current status + of the condition. + type: string + status: + description: Status of the condition, one of (\"True\", \"False\", + \"Unknown\"). + type: string + type: + description: Type of cluster condition, values in (\"Initializing\", + \"Ready\", \"Error\"). + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + nodes: + description: Nodes contains the list of the node status fulfilled. + items: + description: NodeStatus defines type for status of a node into cluster. + properties: + conditions: + description: Conditions contains the list of the node conditions + fulfilled. + items: + description: NodeCondition defines type for representing node + conditions. properties: + lastTransitionTime: + description: The last time this Condition type changed. + format: date-time + type: string + status: + description: Status of the node, one of (\"True\", \"False\", + \"Unknown\"). + type: string + type: + description: Type of the node condition. + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + message: + description: Full text reason for current status of the node. + type: string + name: + description: Name of the node. + type: string + raftStatus: + description: RaftStatus is the raft status of the node. + properties: + leader: + description: Leader is the name of the Leader of the current + node. + type: string + nodes: + description: Nodes is a list of nodes that can be identified + by the current node. items: - description: If unspecified, each key-value pair in the - Data field of the referenced Secret will be projected - into the volume as a file whose name is the key and - content is the value. If specified, the listed keys - will be projected into the specified paths, and unlisted - keys will not be present. If a key is specified which - is not present in the Secret, the volume setup will - error unless it is marked optional. Paths must be relative - and may not contain the '..' path or start with '..'. - items: - description: Maps a string key to a path within a volume. - properties: - key: - description: The key to project. - type: string - mode: - description: 'Optional: mode bits used to set permissions - on this file. Must be an octal value between 0000 - and 0777 or a decimal value between 0 and 511. - YAML accepts both octal and decimal values, JSON - requires decimal values for mode bits. If not - specified, the volume defaultMode will be used. - This might be in conflict with other options that - affect the file mode, like fsGroup, and the result - can be other mode bits set.' - format: int32 - type: integer - path: - description: The relative path of the file to map - the key to. May not be an absolute path. May not - contain the path element '..'. May not start with - the string '..'. + type: string + type: array + role: + description: Role is one of (LEADER/CANDIDATE/FOLLOWER/IDLE/INVALID) + type: string + type: object + roStatus: + description: (RO) ReadOnly Status + properties: + Replication: + type: boolean + master: + type: string + readOnlyReady: + type: boolean + type: object + required: + - name + type: object + type: array + readyNodes: + description: ReadyNodes represents number of the nodes that are in + ready state. + type: integer + state: + description: State + type: string + type: object + type: object + served: true + storage: true + subresources: + scale: + specReplicasPath: .spec.replicas + statusReplicasPath: .status.readyNodes + status: {} + - additionalPrinterColumns: + - description: The cluster status + jsonPath: .status.state + name: State + type: string + - description: The number of desired replicas + jsonPath: .spec.replicas + name: Desired + type: integer + - description: The number of current replicas + jsonPath: .status.readyNodes + name: Current + type: integer + - description: Name of the leader node + jsonPath: .status.nodes[?(@.raftStatus.role == 'LEADER')].name + name: Leader + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: MysqlCluster is the Schema for the mysqlclusters API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: MysqlClusterSpec defines the desired state of MysqlCluster + properties: + affinity: + description: 'Scheduling constraints of MySQL pod. Changing this value + causes MySQL to restart. More info: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node' + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the + pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the affinity expressions specified by + this field, but it may choose a node that violates one or + more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node matches + the corresponding matchExpressions; the node(s) with the + highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects (i.e. + is also a no-op). + properties: + preference: + description: A node selector term, associated with the + corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching the corresponding + nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not be + scheduled onto the node. If the affinity requirements specified + by this field cease to be met at some point during pod execution + (e.g. due to an update), the system may or may not try to + eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: A null or empty node selector term matches + no objects. The requirements of them are ANDed. The + TopologySelectorTerm type implements a subset of the + NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate + this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the affinity expressions specified by + this field, but it may choose a node that violates one or + more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. This field is beta-level + and is only honored when PodAffinityNamespaceSelector + feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not be + scheduled onto the node. If the affinity requirements specified + by this field cease to be met at some point during pod execution + (e.g. due to a pod label update), the system may or may + not try to eventually evict the pod from its node. When + there are multiple elements, the lists of nodes corresponding + to each podAffinityTerm are intersected, i.e. all terms + must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not co-located + (anti-affinity) with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on which a pod of the set of + pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied to the + union of the namespaces selected by this field and + the ones listed in the namespaces field. null selector + and null or empty namespaces list means "this pod's + namespace". An empty selector ({}) matches all namespaces. + This field is beta-level and is only honored when + PodAffinityNamespaceSelector feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace + names that the term applies to. The term is applied + to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. null or + empty namespaces list and null namespaceSelector means + "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where + co-located is defined as running on a node whose value + of the label with key topologyKey matches that of + any node on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. + avoid putting this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the anti-affinity expressions specified + by this field, but it may choose a node that violates one + or more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. This field is beta-level + and is only honored when PodAffinityNamespaceSelector + feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the anti-affinity requirements + specified by this field cease to be met at some point during + pod execution (e.g. due to a pod label update), the system + may or may not try to eventually evict the pod from its + node. When there are multiple elements, the lists of nodes + corresponding to each podAffinityTerm are intersected, i.e. + all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not co-located + (anti-affinity) with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on which a pod of the set of + pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied to the + union of the namespaces selected by this field and + the ones listed in the namespaces field. null selector + and null or empty namespaces list means "this pod's + namespace". An empty selector ({}) matches all namespaces. + This field is beta-level and is only honored when + PodAffinityNamespaceSelector feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace + names that the term applies to. The term is applied + to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. null or + empty namespaces list and null namespaceSelector means + "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where + co-located is defined as running on a node whose value + of the label with key topologyKey matches that of + any node on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + backupOpts: + description: Backup is the options of backup container. + properties: + image: + description: Image is the image of backup container. + type: string + resources: + description: 'Changing this value causes MySQL More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + type: object + customTLSSecret: + description: Containing CA (ca.crt) and server cert (tls.crt), server + private key (tls.key) for SSL + properties: + items: + description: If unspecified, each key-value pair in the Data field + of the referenced Secret will be projected into the volume as + a file whose name is the key and content is the value. If specified, + the listed keys will be projected into the specified paths, + and unlisted keys will not be present. If a key is specified + which is not present in the Secret, the volume setup will error + unless it is marked optional. Paths must be relative and may + not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode bits used to set permissions + on this file. Must be an octal value between 0000 and + 0777 or a decimal value between 0 and 511. YAML accepts + both octal and decimal values, JSON requires decimal values + for mode bits. If not specified, the volume defaultMode + will be used. This might be in conflict with other options + that affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: The relative path of the file to map the key + to. May not be an absolute path. May not contain the path + element '..'. May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + type: object + dataSource: + description: Specifies a data source for bootstrapping the MySQL cluster. + properties: + Nfsbackup: + description: restore from nfs + properties: + name: + description: Backup name + type: string + volume: + description: Secret name + properties: + path: + description: 'Path that is exported by the NFS server. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + readOnly: + description: 'ReadOnly here will force the NFS export + to be mounted with read-only permissions. Defaults to + false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: boolean + server: + description: 'Server is the hostname or IP address of + the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + required: + - path + - server + type: object + required: + - name + type: object + S3backup: + description: Bootstraping from backup + properties: + name: + description: Backup name + type: string + secretName: + description: Secret name + type: string + type: object + remote: + description: Bootstraping from remote data source + properties: + sourceConfig: + description: "Adapts a secret into a projected volume. \n + The contents of the target Secret's Data field will be presented + in a projected volume as files using the keys in the Data + field as the file names. Note that this is identical to + a secret volume source without the default mode." + properties: + items: + description: If unspecified, each key-value pair in the + Data field of the referenced Secret will be projected + into the volume as a file whose name is the key and + content is the value. If specified, the listed keys + will be projected into the specified paths, and unlisted + keys will not be present. If a key is specified which + is not present in the Secret, the volume setup will + error unless it is marked optional. Paths must be relative + and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode bits used to set permissions + on this file. Must be an octal value between 0000 + and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON + requires decimal values for mode bits. If not + specified, the volume defaultMode will be used. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: The relative path of the file to map + the key to. May not be an absolute path. May not + contain the path element '..'. May not start with + the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + type: object + type: object + type: object + enableAutoRebuild: + default: false + description: If true, when the data is inconsistent, Xenon will automatically + rebuild the invalid node. + type: boolean + image: + default: percona/percona-server:5.7.34 + description: Specifies mysql image to use. + type: string + imagePullPolicy: + description: 'ImagePullPolicy is used to determine when Kubernetes + will attempt to pull (download) container images. More info: https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy' + enum: + - Always + - Never + - IfNotPresent + type: string + logOpts: + description: LogOpts is the options of log settings. + properties: + auditLogTail: + default: false + description: AuditLogTail represents if tail the mysql audit log. + type: boolean + image: + default: busybox:1.32 + description: To specify the image that will be used for log container. + The busybox image. + type: string + resources: + description: Log container resources of a MySQL container. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + slowLogTail: + default: false + description: SlowLogTail represents if tail the mysql slow log. + type: boolean + type: object + maxLagTime: + default: 30 + description: MaxLagSeconds configures the readiness probe of mysqld + container if the replication lag is greater than MaxLagSeconds, + the mysqld container will not be not healthy. + minimum: 0 + type: integer + minAvailable: + default: 50% + description: The number of pods from that set that must still be available + after the eviction, even in the absence of the evicted pod + type: string + monitoringSpec: + description: Monitoring is the options of metrics container. + properties: + exporter: + properties: + customTLSSecret: + description: Projected secret containing custom TLS certificates + to encrypt output from the exporter web server + properties: + items: + description: If unspecified, each key-value pair in the + Data field of the referenced Secret will be projected + into the volume as a file whose name is the key and + content is the value. If specified, the listed keys + will be projected into the specified paths, and unlisted + keys will not be present. If a key is specified which + is not present in the Secret, the volume setup will + error unless it is marked optional. Paths must be relative + and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: The key to project. + type: string + mode: + description: 'Optional: mode bits used to set permissions + on this file. Must be an octal value between 0000 + and 0777 or a decimal value between 0 and 511. + YAML accepts both octal and decimal values, JSON + requires decimal values for mode bits. If not + specified, the volume defaultMode will be used. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: The relative path of the file to map + the key to. May not be an absolute path. May not + contain the path element '..'. May not start with + the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + type: object + enabled: + default: true + description: enabled is used to enable/disable the exporter. + type: boolean + image: + default: prom/mysqld-exporter:v0.12.1 + description: To specify the image that will be used for metrics + container. + type: string + resources: + description: 'Changing this value causes MySQL and the exporter + to restart. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers' + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of + compute resources required. If Requests is omitted for + a container, it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined value. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + type: object + type: object + mysqlConfig: + description: MySQLConfig `ConfigMap` name of MySQL config. + properties: + configMapName: + description: Name of the `ConfigMap` containing MySQL config. + type: string + myCnf: + additionalProperties: + type: string + description: A map[string]string that will be passed to my.cnf + file. The key/value pairs is persisted in the configmap. + type: object + pluginCnf: + additionalProperties: + type: string + type: object + type: object + mysqlVersion: + default: "5.7" + description: 'Represents the MySQL version that will be run. The available + version can be found here: This field should be set even if the + Image is set to let the operator know which mysql version is running. + Based on this version the operator can take decisions which features + can be used.' + type: string + priorityClassName: + description: 'Priority class name for the MySQL pods. Changing this + value causes MySQL to restart. More info: https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/' + type: string + readonlys: + description: Readonlys Info. + properties: + affinity: + description: Affinity is a group of affinity scheduling rules. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for + the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node matches the corresponding matchExpressions; + the node(s) with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects + (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with + the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching the + corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from + its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: A null or empty node selector term + matches no objects. The requirements of them are + ANDed. The TopologySelectorTerm type implements + a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. + co-locate this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by + this field and the ones listed in the namespaces + field. null selector and null or empty namespaces + list means "this pod's namespace". An empty + selector ({}) matches all namespaces. This + field is beta-level and is only honored when + PodAffinityNamespaceSelector feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected + by namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to a pod label update), + the system may or may not try to eventually evict the + pod from its node. When there are multiple elements, + the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any node + on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. This field is beta-level + and is only honored when PodAffinityNamespaceSelector + feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules + (e.g. avoid putting this pod in the same node, zone, etc. + as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the anti-affinity expressions + specified by this field, but it may choose a node that + violates one or more of the expressions. The node that + is most preferred is the one with the greatest sum of + weights, i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + anti-affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by + this field and the ones listed in the namespaces + field. null selector and null or empty namespaces + list means "this pod's namespace". An empty + selector ({}) matches all namespaces. This + field is beta-level and is only honored when + PodAffinityNamespaceSelector feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected + by namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified + by this field are not met at scheduling time, the pod + will not be scheduled onto the node. If the anti-affinity + requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod + label update), the system may or may not try to eventually + evict the pod from its node. When there are multiple + elements, the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any node + on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. This field is beta-level + and is only honored when PodAffinityNamespaceSelector + feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. type: string required: - - key - - path + - topologyKey type: object type: array - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean type: object type: object - type: object - enableAutoRebuild: - default: false - description: If true, when the data is inconsistent, Xenon will automatically - rebuild the invalid node. - type: boolean - image: - default: percona/percona-server:5.7.34 - description: Specifies mysql image to use. - type: string - imagePullPolicy: - description: 'ImagePullPolicy is used to determine when Kubernetes - will attempt to pull (download) container images. More info: https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy' - enum: - - Always - - Never - - IfNotPresent - type: string - logOpts: - description: LogOpts is the options of log settings. - properties: - auditLogTail: - default: false - description: AuditLogTail represents if tail the mysql audit log. - type: boolean - image: - default: busybox:1.32 - description: To specify the image that will be used for log container. - The busybox image. + hostname: + description: When the host name is empty, use the leader to change + master type: string + num: + description: ReadOnlys is the number of readonly pods. + format: int32 + type: integer resources: - description: Log container resources of a MySQL container. + description: The compute resource requirements. properties: limits: additionalProperties: @@ -2587,148 +4586,49 @@ spec: to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' type: object type: object - slowLogTail: - default: false - description: SlowLogTail represents if tail the mysql slow log. - type: boolean - type: object - maxLagTime: - default: 30 - description: MaxLagSeconds configures the readiness probe of mysqld - container if the replication lag is greater than MaxLagSeconds, - the mysqld container will not be not healthy. - minimum: 0 - type: integer - minAvailable: - default: 50% - description: The number of pods from that set that must still be available - after the eviction, even in the absence of the evicted pod - type: string - monitoringSpec: - description: Monitoring is the options of metrics container. - properties: - exporter: - properties: - customTLSSecret: - description: Projected secret containing custom TLS certificates - to encrypt output from the exporter web server - properties: - items: - description: If unspecified, each key-value pair in the - Data field of the referenced Secret will be projected - into the volume as a file whose name is the key and - content is the value. If specified, the listed keys - will be projected into the specified paths, and unlisted - keys will not be present. If a key is specified which - is not present in the Secret, the volume setup will - error unless it is marked optional. Paths must be relative - and may not contain the '..' path or start with '..'. - items: - description: Maps a string key to a path within a volume. - properties: - key: - description: The key to project. - type: string - mode: - description: 'Optional: mode bits used to set permissions - on this file. Must be an octal value between 0000 - and 0777 or a decimal value between 0 and 511. - YAML accepts both octal and decimal values, JSON - requires decimal values for mode bits. If not - specified, the volume defaultMode will be used. - This might be in conflict with other options that - affect the file mode, like fsGroup, and the result - can be other mode bits set.' - format: int32 - type: integer - path: - description: The relative path of the file to map - the key to. May not be an absolute path. May not - contain the path element '..'. May not start with - the string '..'. - type: string - required: - - key - - path - type: object - type: array - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean - type: object - enabled: - default: true - description: enabled is used to enable/disable the exporter. - type: boolean - image: - default: prom/mysqld-exporter:v0.12.1 - description: To specify the image that will be used for metrics - container. - type: string - resources: - description: 'Changing this value causes MySQL and the exporter - to restart. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers' - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of - compute resources required. If Requests is omitted for - a container, it defaults to Limits if that is explicitly - specified, otherwise to an implementation-defined value. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - type: object - type: object - mysqlConfig: - description: MySQLConfig `ConfigMap` name of MySQL config. - properties: - configMapName: - description: Name of the `ConfigMap` containing MySQL config. - type: string - myCnf: - additionalProperties: - type: string - description: A map[string]string that will be passed to my.cnf - file. The key/value pairs is persisted in the configmap. - type: object - pluginCnf: - additionalProperties: - type: string - type: object + tolerations: + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, allowed + values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match + all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to + the value. Valid operators are Exists and Equal. Defaults + to Equal. Exists is equivalent to wildcard for value, + so that a pod can tolerate all taints of a particular + category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of + time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the taint + forever (do not evict). Zero and negative values will + be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + required: + - num type: object - mysqlVersion: - default: "5.7" - description: 'Represents the MySQL version that will be run. The available - version can be found here: This field should be set even if the - Image is set to let the operator know which mysql version is running. - Based on this version the operator can take decisions which features - can be used.' - type: string - priorityClassName: - description: 'Priority class name for the MySQL pods. Changing this - value causes MySQL to restart. More info: https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/' - type: string replicas: default: 3 description: Replicas is the number of pods. @@ -3176,6 +5076,16 @@ spec: description: Role is one of (LEADER/CANDIDATE/FOLLOWER/IDLE/INVALID) type: string type: object + roStatus: + description: (RO) ReadOnly Status + properties: + Replication: + type: boolean + master: + type: string + readOnlyReady: + type: boolean + type: object required: - name type: object diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index 4f882b30..73b6dbdc 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -13,4 +13,4 @@ kind: Kustomization images: - name: controller newName: radondb/mysql-operator - newTag: latest + newTag: 3.0.0-alpha diff --git a/config/samples/mysql_v1alpha1_mysqlcluster.yaml b/config/samples/mysql_v1alpha1_mysqlcluster.yaml index cea3247c..3b73202d 100644 --- a/config/samples/mysql_v1alpha1_mysqlcluster.yaml +++ b/config/samples/mysql_v1alpha1_mysqlcluster.yaml @@ -16,6 +16,9 @@ spec: # Restore from NFS, uncomment below and set the ip of NFS server # such as nfsServerAddress: "10.233.55.172" # nfsServerAddress: + readonlys: + num: 1 + mysqlOpts: image: percona/percona-server:5.7.34 user: radondb_usr diff --git a/controllers/mysqlcluster_controller.go b/controllers/mysqlcluster_controller.go index 7ba9c18d..8b9eed54 100644 --- a/controllers/mysqlcluster_controller.go +++ b/controllers/mysqlcluster_controller.go @@ -139,6 +139,10 @@ func (r *MysqlClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request clustersyncer.NewHeadlessSVCSyncer(r.Client, instance), clustersyncer.NewLeaderSVCSyncer(r.Client, instance), } + if instance.Unwrap().Spec.ReadOnlys != nil { + syncers = append(syncers, clustersyncer.NewHeadlessReadOnlySVCSyncer(r.Client, instance), + clustersyncer.NewReadOnlySVCSyncer(r.Client, instance)) + } if *instance.Unwrap().Spec.Replicas == 1 { // Delete follower service r.deleteFollowerService(ctx, req, instance.Unwrap()) diff --git a/internal/pod_executor.go b/internal/pod_executor.go new file mode 100644 index 00000000..4bfa35a2 --- /dev/null +++ b/internal/pod_executor.go @@ -0,0 +1,118 @@ +/* +Copyright 2021 RadonDB. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package internal + +import ( + "bufio" + "bytes" + "fmt" + + corev1 "k8s.io/api/core/v1" + "k8s.io/client-go/kubernetes/scheme" + corev1client "k8s.io/client-go/kubernetes/typed/core/v1" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + "k8s.io/client-go/tools/remotecommand" +) + +type PodExecutor struct { + client corev1client.CoreV1Interface + config *rest.Config +} + +func NewPodExecutor() (*PodExecutor, error) { + // Instantiate loader for kubeconfig file. + kubeconfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig( + clientcmd.NewDefaultClientConfigLoadingRules(), + &clientcmd.ConfigOverrides{}, + ) + + // Get a rest.Config from the kubeconfig file. This will be passed into all + // the client objects we create. + config, err := kubeconfig.ClientConfig() + if err != nil { + return nil, err + } + + // Create a Kubernetes core/v1 client. + client, err := corev1client.NewForConfig(config) + if err != nil { + return nil, err + } + + return &PodExecutor{ + client: client, + config: config, + }, nil +} + +func (p *PodExecutor) Exec(namespace, podName, containerName string, command ...string) ([]byte, []byte, error) { + request := p.client.RESTClient(). + Post(). + Resource("pods"). + Namespace(namespace). + Name(podName). + SubResource("exec"). + VersionedParams(&corev1.PodExecOptions{ + Container: containerName, + Command: command, + Stdout: true, + Stderr: true, + Stdin: false, + }, scheme.ParameterCodec) + + exec, err := remotecommand.NewSPDYExecutor(p.config, "POST", request.URL()) + if err != nil { + return nil, nil, err + } + + stdOut := bytes.Buffer{} + stdErr := bytes.Buffer{} + + err = exec.Stream(remotecommand.StreamOptions{ + Stdout: bufio.NewWriter(&stdOut), + Stderr: bufio.NewWriter(&stdErr), + Stdin: nil, + Tty: false, + }) + + return stdOut.Bytes(), stdErr.Bytes(), err +} + +func (p *PodExecutor) SetGlobalSysVar(namespace, podName string, query string) error { + cmd := []string{"xenoncli", "mysql", "sysvar", query} + _, stderr, err := p.Exec(namespace, podName, "xenon", cmd...) + if err != nil { + return err + } + if len(stderr) != 0 { + return fmt.Errorf("run command %s in xenon failed: %s", cmd, stderr) + } + return nil +} + +func (p *PodExecutor) CloseXenonSemiCheck(namespace, podName string) error { + cmd := []string{"xenoncli", "raft", "disablechecksemisync"} + _, stderr, err := p.Exec(namespace, podName, "xenon", cmd...) + if err != nil { + return err + } + if len(stderr) != 0 { + return fmt.Errorf("run command %s in xenon failed: %s", cmd, stderr) + } + return nil +} diff --git a/internal/sql_runner.go b/internal/sql_runner.go index b4af246c..99d323ff 100644 --- a/internal/sql_runner.go +++ b/internal/sql_runner.go @@ -188,7 +188,7 @@ func CheckSlaveStatusWithRetry(sqlRunner SQLRunner, retry uint32) (isLagged, isR break } - if isLagged, isReplicating, err = checkSlaveStatus(sqlRunner); err == nil { + if isLagged, isReplicating, err = CheckSlaveStatus(sqlRunner); err == nil { return } @@ -199,8 +199,8 @@ func CheckSlaveStatusWithRetry(sqlRunner SQLRunner, retry uint32) (isLagged, isR return } -// checkSlaveStatus check the slave status. -func checkSlaveStatus(sqlRunner SQLRunner) (isLagged, isReplicating corev1.ConditionStatus, err error) { +// CheckSlaveStatus check the slave status. +func CheckSlaveStatus(sqlRunner SQLRunner) (isLagged, isReplicating corev1.ConditionStatus, err error) { var rows *sql.Rows isLagged, isReplicating = corev1.ConditionUnknown, corev1.ConditionUnknown rows, err = sqlRunner.QueryRows(NewQuery("show slave status;")) @@ -235,13 +235,16 @@ func checkSlaveStatus(sqlRunner SQLRunner) (isLagged, isReplicating corev1.Condi slaveIOState := strings.ToLower(columnValue(scanArgs, cols, "Slave_IO_State")) slaveSQLRunning := columnValue(scanArgs, cols, "Slave_SQL_Running") + ioRunning := columnValue(scanArgs, cols, "Slave_IO_Running") lastSQLError := columnValue(scanArgs, cols, "Last_SQL_Error") secondsBehindMaster := columnValue(scanArgs, cols, "Seconds_Behind_Master") if utils.StringInArray(slaveIOState, errorConnectionStates) { return isLagged, corev1.ConditionFalse, fmt.Errorf("Slave_IO_State: %s", slaveIOState) } - + if ioRunning != "Yes" { + return isLagged, corev1.ConditionFalse, fmt.Errorf("Last_SQL_Error: %s", lastSQLError) + } if slaveSQLRunning != "Yes" { return isLagged, corev1.ConditionFalse, fmt.Errorf("Last_SQL_Error: %s", lastSQLError) } @@ -485,3 +488,31 @@ func Escape(sql string) string { return string(dest) } + +// check readonly node, rpl_semi_sync_slave_enabled +func CheckSemSync(sqlRunner SQLRunner) (corev1.ConditionStatus, error) { + var SemiSync uint8 + if err := GetGlobalVariable(sqlRunner, "rpl_semi_sync_slave_enabled", &SemiSync); err != nil { + return corev1.ConditionUnknown, err + } + + if SemiSync == 0 { + return corev1.ConditionFalse, nil + } + + return corev1.ConditionTrue, nil +} + +// check Super readonly +func CheckSuperReadOnly(sqlRunner SQLRunner) (corev1.ConditionStatus, error) { + var readOnly uint8 + if err := GetGlobalVariable(sqlRunner, "super_read_only", &readOnly); err != nil { + return corev1.ConditionUnknown, err + } + + if readOnly == 0 { + return corev1.ConditionFalse, nil + } + + return corev1.ConditionTrue, nil +} diff --git a/mysqlcluster/mysqlcluster.go b/mysqlcluster/mysqlcluster.go index 8e38905f..de3900fb 100644 --- a/mysqlcluster/mysqlcluster.go +++ b/mysqlcluster/mysqlcluster.go @@ -343,6 +343,10 @@ func (c *MysqlCluster) GetNameForResource(name utils.ResourceName) string { return template } return fmt.Sprintf("%s-mysql", c.Name) + case utils.ReadOnlyHeadlessSVC: + return fmt.Sprintf("%s-ro", c.Name) + case utils.ReadOnlySvc: + return fmt.Sprintf("%s-ro-nodeport", c.Name) default: return c.Name } diff --git a/mysqlcluster/syncer/readonly_service.go b/mysqlcluster/syncer/readonly_service.go new file mode 100644 index 00000000..3c43f19d --- /dev/null +++ b/mysqlcluster/syncer/readonly_service.go @@ -0,0 +1,123 @@ +/* +Copyright 2021 RadonDB. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package syncer + +import ( + "github.com/presslabs/controller-util/pkg/syncer" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/util/intstr" + "sigs.k8s.io/controller-runtime/pkg/client" + + "github.com/radondb/radondb-mysql-kubernetes/mysqlcluster" + "github.com/radondb/radondb-mysql-kubernetes/utils" +) + +// NewReadOnlyHeadlessSVCSyncer returns headless service syncer. +func NewHeadlessReadOnlySVCSyncer(cli client.Client, c *mysqlcluster.MysqlCluster) syncer.Interface { + service := &corev1.Service{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "Service", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: c.GetNameForResource(utils.ReadOnlyHeadlessSVC), + Namespace: c.Namespace, + Labels: map[string]string{ + "app.kubernetes.io/name": "mysql-readonly", + "app.kubernetes.io/managed-by": "mysql.radondb.com", + + "mysql.radondb.com/cluster": c.Name, + "mysql.radondb.com/service-type": string(utils.ReadOnlyHeadlessSVC), + }, + }, + } + + return syncer.NewObjectSyncer("HeadlessReadOnlySVC", c.Unwrap(), service, cli, func() error { + service.Spec.Type = "ClusterIP" + service.Spec.ClusterIP = "None" + service.Spec.Selector = labels.Set{ + "app.kubernetes.io/name": "mysql-readonly", + "app.kubernetes.io/managed-by": "mysql.radondb.com", + "app.kubernetes.io/instance": c.Name, + "readonly": "true", + } + + // Use `publishNotReadyAddresses` to be able to access pods even if the pod is not ready. + service.Spec.PublishNotReadyAddresses = true + + if len(service.Spec.Ports) != 2 { + service.Spec.Ports = make([]corev1.ServicePort, 2) + } + + service.Spec.Ports[0].Name = utils.MysqlPortName + service.Spec.Ports[0].Port = utils.MysqlPort + service.Spec.Ports[0].TargetPort = intstr.FromInt(utils.MysqlPort) + //xtrabckup + service.Spec.Ports[1].Name = utils.XBackupPortName + service.Spec.Ports[1].Port = utils.XBackupPort + service.Spec.Ports[1].TargetPort = intstr.FromInt(utils.XBackupPort) + return nil + }) +} + +// NewFollowerSVCSyncer returns follower service syncer. +func NewReadOnlySVCSyncer(cli client.Client, c *mysqlcluster.MysqlCluster) syncer.Interface { + service := &corev1.Service{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "v1", + Kind: "Service", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: c.GetNameForResource(utils.ReadOnlySvc), + Namespace: c.Namespace, + Labels: map[string]string{ + "app.kubernetes.io/name": "mysql-readonly", + "app.kubernetes.io/managed-by": "mysql.radondb.com", + + "mysql.radondb.com/cluster": c.Name, + "mysql.radondb.com/service-type": string(utils.ReadOnlySvc), + }, + }, + } + return syncer.NewObjectSyncer("ReadOnlySVC", c.Unwrap(), service, cli, func() error { + // Allows to modify the service access method, the default is ClusterIP. + if service.Spec.Type == "" { + service.Spec.Type = "NodePort" + } + service.Spec.Selector = labels.Set{ + "app.kubernetes.io/name": "mysql-readonly", + "app.kubernetes.io/managed-by": "mysql.radondb.com", + "app.kubernetes.io/instance": c.Name, + "readonly": "true", + } + + if len(service.Spec.Ports) != 2 { + service.Spec.Ports = make([]corev1.ServicePort, 2) + } + + service.Spec.Ports[0].Name = utils.MysqlPortName + service.Spec.Ports[0].Port = utils.MysqlPort + service.Spec.Ports[0].TargetPort = intstr.FromInt(utils.MysqlPort) + //xtrabckup + service.Spec.Ports[1].Name = utils.XBackupPortName + service.Spec.Ports[1].Port = utils.XBackupPort + service.Spec.Ports[1].TargetPort = intstr.FromInt(utils.XBackupPort) + return nil + }) +} diff --git a/mysqlcluster/syncer/readonly_statefulset.go b/mysqlcluster/syncer/readonly_statefulset.go new file mode 100644 index 00000000..9e425d1d --- /dev/null +++ b/mysqlcluster/syncer/readonly_statefulset.go @@ -0,0 +1,512 @@ +/* +Copyright 2021 RadonDB. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package syncer + +import ( + "context" + "fmt" + "math" + "strconv" + "time" + + "github.com/pkg/errors" + + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/equality" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/wait" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + + apiv1alpha1 "github.com/radondb/radondb-mysql-kubernetes/api/v1alpha1" + "github.com/radondb/radondb-mysql-kubernetes/internal" + "github.com/radondb/radondb-mysql-kubernetes/mysqlcluster/container" + "github.com/radondb/radondb-mysql-kubernetes/utils" +) + +func (s *StatefulSetSyncer) SfsReadOnly(ctx context.Context) error { + if s.Spec.ReadOnlys == nil { + currentStatefulset := appsv1.StatefulSet{} + err := s.cli.Get(context.TODO(), types.NamespacedName{Name: getReadOnlyStatefulSetName(s), Namespace: s.Namespace}, ¤tStatefulset) + if err != nil && k8serrors.IsNotFound(err) { + goto next1 + } else { + s.cli.Delete(context.TODO(), ¤tStatefulset) + pvcs := corev1.PersistentVolumeClaimList{} + if err := s.cli.List(ctx, + &pvcs, + &client.ListOptions{ + Namespace: s.sfs.Namespace, + LabelSelector: readOnlyLables(s).AsSelector(), + }, + ); err != nil { + return err + } + + for _, item := range pvcs.Items { + if err := s.cli.Delete(ctx, &item); err != nil { + return err + } + } + } + next1: + // delete the readonly service + service := corev1.Service{} + err = s.cli.Get(ctx, types.NamespacedName{Name: s.GetNameForResource(utils.ReadOnlyHeadlessSVC), Namespace: s.Namespace}, &service) + if err != nil && k8serrors.IsNotFound(err) { + goto next2 + } else { + s.cli.Delete(ctx, &service) + } + next2: + serviceNodeport := corev1.Service{} + err = s.cli.Get(ctx, types.NamespacedName{Name: s.GetNameForResource(utils.ReadOnlySvc), Namespace: s.Namespace}, &serviceNodeport) + if err != nil && k8serrors.IsNotFound(err) { + return nil + } else { + s.cli.Delete(ctx, &serviceNodeport) + } + return nil + } + + if s.Status.State == apiv1alpha1.ClusterReadyState { + // check and create the Statefulset + readonlyStatefulSet, err := GetReadonlyStatefulSet(s) + if err != nil { + return errors.Errorf("get readonly deployment for cluster '%s': %v", s.Name, err) + } + if err := controllerutil.SetControllerReference(s.Unwrap(), readonlyStatefulSet, s.cli.Scheme()); err != nil { + return err + } + //1. get Statefulset exist? + currentStatefulset := appsv1.StatefulSet{} + err = s.cli.Get(context.TODO(), types.NamespacedName{Name: readonlyStatefulSet.Name, Namespace: readonlyStatefulSet.Namespace}, ¤tStatefulset) + //2. if not exist, do nothing + if err != nil && k8serrors.IsNotFound(err) { + if err := s.cli.Create(context.TODO(), readonlyStatefulSet); err != nil && !k8serrors.IsAlreadyExists(err) { + return errors.Wrapf(err, "create readonlhy statefulset for cluster '%s'", s.Name) + } + } else if err != nil { + return errors.Wrapf(err, "get readonly deployment '%s'", readonlyStatefulSet.Name) + } + //3. update it + currentStatefulset.Spec = readonlyStatefulSet.Spec + if err := s.cli.Update(context.TODO(), ¤tStatefulset); err != nil { + // do expand pvc + if k8serrors.IsInvalid(err) && ReadOnlyCanExtend(ctx, s, readonlyStatefulSet) { + if err := ExtendReadOnlyPVCs(ctx, s, readonlyStatefulSet); err != nil { + return errors.Wrapf(err, "extend readonly's pvc for cluster '%s'", s.Name) + } + } else { + return errors.Wrapf(err, "update readonly statefulset '%s'", s.Name) + } + + } + // Update pvc. + if err := deletePvcReadOnly(ctx, s); err != nil { + return errors.Wrapf(err, "delete extra readonly pvc '%s'", s.Name) + } + // 4. if all finished, do the change master + if err = wait.PollImmediate(time.Second*5, time.Minute*2, func() (bool, error) { + err = s.cli.Get(context.TODO(), types.NamespacedName{Name: readonlyStatefulSet.Name, Namespace: readonlyStatefulSet.Namespace}, ¤tStatefulset) + if err != nil { + return false, err + } + if currentStatefulset.Status.ReadyReplicas == currentStatefulset.Status.Replicas { + return true, nil + } else { + return false, nil + } + }); err != nil { + return errors.Wrapf(err, "wait readonly statefulset ready '%s'", s.Name) + } + + for i := 0; i < int(currentStatefulset.Status.Replicas); i++ { + hostName := buildHostName(¤tStatefulset, i) + if err := putMySQLReadOnly(s, hostName); err != nil { + return errors.Wrapf(err, "set mysql to readonly '%s'", s.Name) + } + } + + } + return nil +} + +func GetReadonlyStatefulSet(cr *StatefulSetSyncer) (*appsv1.StatefulSet, error) { + readonlySfs := getReadOnlyStatefulSetName(cr) + + initSidecar := container.EnsureContainer(utils.ContainerInitSidecarName, cr.MysqlCluster) + initMysql := container.EnsureContainer(utils.ContainerInitMysqlName, cr.MysqlCluster) + if cr.Spec.ReadOnlys.Resources != nil { + initMysql.Resources = *cr.Spec.ReadOnlys.Resources + } + + var containers []corev1.Container + for _, v := range cr.sfs.Spec.Template.Spec.Containers { + if v.Name != utils.ContainerXenonName && v.Name != utils.ContainerMysqlName { + containers = append(containers, v) + } + } + + mysql := container.EnsureContainer(utils.ContainerMysqlName, cr.MysqlCluster) + if cr.Spec.ReadOnlys.Resources != nil { + mysql.Resources = *cr.Spec.ReadOnlys.Resources + // TODO (RO) calc innodb buffer and add it to env + ib_pool, ib_inst, ib_logsize := cr.calcInnodbParam(cr.Spec.ReadOnlys.Resources) + initSidecar.Env = append(initSidecar.Env, + corev1.EnvVar{ + Name: utils.ROIbPool, + Value: ib_pool, + }, + corev1.EnvVar{ + Name: utils.ROIbInst, + Value: ib_inst, + }, + corev1.EnvVar{ + Name: utils.ROIbLog, + Value: ib_logsize, + }, + ) + } + initContainers := []corev1.Container{initSidecar, initMysql} + containers = append(containers, mysql) + return &appsv1.StatefulSet{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "apps/v1", + Kind: "StatefulSet", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: readonlySfs, + Namespace: cr.Namespace, + //OwnerReferences: cr.OwnerReferences, need set outside. + Annotations: cr.Annotations, + }, + Spec: appsv1.StatefulSetSpec{ + Replicas: &cr.Spec.ReadOnlys.Num, + Selector: &metav1.LabelSelector{ + MatchLabels: readOnlyLables(cr), + }, + ServiceName: cr.GetNameForResource(utils.ReadOnlyHeadlessSVC), + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Name: readonlySfs, + Namespace: cr.Namespace, + Labels: readOnlyLables(cr), + //Annotations: cr.sfs.Spec.Template.Annotations, + Annotations: func() map[string]string { + tmp := make(map[string]string) + for k, v := range cr.sfs.Spec.Template.Annotations { + tmp[k] = v + } + tmp["host-name"] = cr.Spec.ReadOnlys.Host + return tmp + }(), + }, + Spec: corev1.PodSpec{ + InitContainers: initContainers, + Containers: containers, + Volumes: cr.EnsureVolumes(), + SchedulerName: cr.Spec.PodPolicy.SchedulerName, + ServiceAccountName: cr.GetNameForResource(utils.ServiceAccount), + Affinity: cr.Spec.ReadOnlys.Affinity, + PriorityClassName: cr.Spec.PodPolicy.PriorityClassName, + Tolerations: func() []corev1.Toleration { + if cr.Spec.ReadOnlys.Tolerations != nil { + return cr.Spec.ReadOnlys.Tolerations + } else { + return cr.Spec.PodPolicy.Tolerations + } + }(), + }, + }, + VolumeClaimTemplates: cr.sfs.Spec.VolumeClaimTemplates, + }, + }, nil +} + +func getReadOnlyStatefulSetName(cr *StatefulSetSyncer) string { + return cr.Name + "-ro" +} + +func readOnlyLables(cr *StatefulSetSyncer) labels.Set { + labels := cr.GetLabels() + labels["app.kubernetes.io/name"] = "mysql-readonly" + labels["readonly"] = "true" + return labels +} + +func putMySQLReadOnly(s *StatefulSetSyncer, host string) error { + var sqlRunner internal.SQLRunner + closeCh := make(chan func()) + + var closeConn func() + errCh := make(chan error) + + cfg, errOut := internal.NewConfigFromClusterKey( + s.cli, s.MysqlCluster.GetClusterKey(), utils.RootUser, host) + go func(sqlRunner *internal.SQLRunner, errCh chan error, closeCh chan func()) { + var err error + *sqlRunner, closeConn, err = s.SQLRunnerFactory(cfg, errOut) + if err != nil { + s.log.V(1).Info("failed to get sql runner", "error", err) + errCh <- err + return + } + if closeConn != nil { + closeCh <- closeConn + return + } + errCh <- nil + }(&sqlRunner, errCh, closeCh) + + select { + case errOut = <-errCh: + return errOut + case closeConn := <-closeCh: + defer closeConn() + case <-time.After(time.Second * 5): + } + if sqlRunner != nil { + // 1. set it to readonly + if status, err := internal.CheckReadOnly(sqlRunner); err != nil { + return err + } else { + if status != corev1.ConditionTrue { + sqlRunner.QueryExec(internal.NewQuery("SET GLOBAL read_only=on")) + } + } + + if status, err := internal.CheckSuperReadOnly(sqlRunner); err != nil { + return err + } else { + if status != corev1.ConditionTrue { + sqlRunner.QueryExec(internal.NewQuery("SET GLOBAL super_read_only=on")) + } + } + + // 2. set rpl_semi_sync_slave_enabled off + if status, err := internal.CheckSemSync(sqlRunner); err != nil { + return err + } else { + if status == corev1.ConditionTrue { + sqlRunner.QueryExec(internal.NewQuery("SET GLOBAL rpl_semi_sync_slave_enabled=off")) + } + } + // 3. change master + var isReplicating corev1.ConditionStatus + var err error + if _, isReplicating, err = internal.CheckSlaveStatus(sqlRunner); err != nil { + //Notice!!! this has error, just show error message, can not return. + s.log.V(1).Info("slave status has gotten error", "error", err) + } + if isReplicating == corev1.ConditionFalse { + // chang master + changeSql := fmt.Sprintf(`stop slave;CHANGE MASTER TO MASTER_HOST='%s', MASTER_PORT=%d, MASTER_USER='%s', MASTER_PASSWORD='%s', +MASTER_AUTO_POSITION=1; start slave;`, buildMasterName(s), 3306, "root", cfg.Password) + sqlRunner.QueryExec(internal.NewQuery(changeSql)) + } + } + return errOut +} + +func buildHostName(cr *appsv1.StatefulSet, index int) string { + return fmt.Sprintf("%s-%d.%s.%s", cr.Name, index, cr.Name, cr.Namespace) +} + +func buildMasterName(cr *StatefulSetSyncer) string { + // if the ReadOnlyType Host is nil + if *cr.Spec.Replicas == 1 { + return fmt.Sprintf("%s-0.%s.%s", cr.sfs.Spec.ServiceName, cr.sfs.Spec.ServiceName, cr.Namespace) + } + if len(cr.Spec.ReadOnlys.Host) == 0 { + return fmt.Sprintf("%s-follower", cr.Name) + } else { + return fmt.Sprintf("%s.%s.%s", cr.Spec.ReadOnlys.Host, cr.sfs.Spec.ServiceName, cr.Namespace) + } + +} + +func deletePvcReadOnly(ctx context.Context, s *StatefulSetSyncer) error { + if s.Spec.ReadOnlys.Num == 0 { + s.log.Info("skip update pvc because replicas is 0") + return nil + } + pvcs := corev1.PersistentVolumeClaimList{} + if err := s.cli.List(ctx, + &pvcs, + &client.ListOptions{ + Namespace: s.sfs.Namespace, + LabelSelector: readOnlyLables(s).AsSelector(), + }, + ); err != nil { + return err + } + + for _, item := range pvcs.Items { + if item.DeletionTimestamp != nil { + s.log.Info("pvc is being deleted", "pvc", item.Name, "key", s.Unwrap()) + continue + } + + ordinal, err := utils.GetOrdinal(item.Name) + if err != nil { + s.log.Error(err, "pvc deletion error", "key", s.Unwrap()) + continue + } + + if ordinal >= int(s.Spec.ReadOnlys.Num) { + s.log.Info("cleaning up pvc", "pvc", item.Name, "key", s.Unwrap()) + if err := s.cli.Delete(ctx, &item); err != nil { + return err + } + } + } + + return nil +} + +func ReadOnlyCanExtend(ctx context.Context, s *StatefulSetSyncer, roSfs *appsv1.StatefulSet) bool { + // Get it again. Becaus it has been mutated in Sync. + var cursfs = appsv1.StatefulSet{} + if err := s.cli.Get(ctx, client.ObjectKeyFromObject(roSfs), &cursfs); err != nil { + if k8serrors.IsNotFound(err) { + return false + } + } + oldRequest := cursfs.Spec.VolumeClaimTemplates[0].Spec.Resources.Requests.DeepCopy() + + newStorage := roSfs.Spec.VolumeClaimTemplates[0].Spec.Resources.Requests.Storage() + // If newStorage is not greater than oldStorage, do not expand. + if newStorage.Cmp(*oldRequest.Storage()) != 1 { + s.log.Info("read only pod ExpandPVC", "result", "can not expand", "reason", "new pvc is not larger than old pvc") + return false + } + return true +} + +func ExtendReadOnlyPVCs(ctx context.Context, s *StatefulSetSyncer, roSfs *appsv1.StatefulSet) error { + // delelete statefulset + if err := s.cli.Delete(ctx, roSfs); err != nil { + return err + } + pvcs := corev1.PersistentVolumeClaimList{} + if err := s.cli.List(ctx, + &pvcs, + &client.ListOptions{ + Namespace: s.sfs.Namespace, + LabelSelector: readOnlyLables(s).AsSelector(), + }, + ); err != nil { + return err + } + + for _, item := range pvcs.Items { + // Notice: Only Resources.Requests can update, other field update will failure. + // If storage Class's allowVolumeExpansion is false, update will failure. + item.Spec.Resources.Requests = s.sfs.Spec.VolumeClaimTemplates[0].Spec.Resources.Requests + if err := s.cli.Update(ctx, &item); err != nil { + return err + } + if err := wait.PollImmediate(time.Second*2, time.Duration(waitLimit)*time.Second, func() (bool, error) { + // Check the pvc status. + var currentPVC corev1.PersistentVolumeClaim + if err2 := s.cli.Get(ctx, client.ObjectKeyFromObject(&item), ¤tPVC); err2 != nil { + return true, err2 + } + var conditons = currentPVC.Status.Conditions + // Notice: When expanding not start, or been completed, conditons is nil + if conditons == nil { + // If change storage request when replicas are creating, should check the currentPVC.Status.Capacity. + // for example: + // Pod0 has created successful,but Pod1 is creating. then change PVC from 20Gi to 30Gi . + // Pod0's PVC need to expand, but Pod1's PVC has created as 30Gi, so need to skip it. + if equality.Semantic.DeepEqual(currentPVC.Status.Capacity, item.Spec.Resources.Requests) { + return true, nil + } + return false, nil + } + status := conditons[0].Type + if status == "FileSystemResizePending" { + return true, nil + } + return false, nil + }); err != nil { + return err + } + } + if err := s.cli.Create(ctx, roSfs); err != nil { + return err + } + return nil +} + +func (s *StatefulSetSyncer) calcInnodbParam(resource *corev1.ResourceRequirements) (string, string, string) { + const ( + _ = iota // ignore first value by assigning to blank identifier + kb uint64 = 1 << (10 * iota) + mb + gb + ) + var defaultSize, innodbBufferPoolSize uint64 + innodbBufferPoolSize = 128 * mb + mem := uint64(resource.Requests.Memory().Value()) + cpu := resource.Limits.Cpu().MilliValue() + if mem <= 1*gb { + defaultSize = uint64(0.45 * float64(mem)) + } else { + defaultSize = uint64(0.6 * float64(mem)) + } + innodbBufferPoolSize = utils.Max(defaultSize, innodbBufferPoolSize) + + instances := math.Max(math.Min(math.Ceil(float64(cpu)/float64(1000)), math.Floor(float64(innodbBufferPoolSize)/float64(gb))), 1) + // c.Spec.MysqlOpts.MysqlConf["innodb_buffer_pool_size"] = strconv.FormatUint(innodbBufferPoolSize, 10) + // c.Spec.MysqlOpts.MysqlConf["innodb_buffer_pool_instances"] = strconv.Itoa(int(instances)) + + // innodb_log_file_size = 25 % of innodb_buffer_pool_size + // Minimum Value (≥ 5.7.11) 4194304 + // Minimum Value (≤ 5.7.10) 1048576 + // Maximum Value 512GB / innodb_log_files_in_group + // but wet set it not over than 8G, you should set it in the config file when you want over 8G. + // See https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_log_file_size + + const innodbDefaultLogFileSize uint64 = 1073741824 + var innodbLogFileSize uint64 = innodbDefaultLogFileSize // 1GB, default value + // if innodb_log_file_size is not set, calculate it + logGroups, err := strconv.Atoi(s.Spec.MysqlOpts.MysqlConf["innodb_log_file_groups"]) + if err != nil { + logGroups = 1 + } + + // https://dev.mysql.com/doc/refman/8.0/en/innodb-dedicated-server.html + // Table 15.9 Automatically Configured Log File Size + // Buffer Pool Size Log File Size + // Less than 8GB 512MiB + // 8GB to 128GB 1024MiB + // Greater than 128GB 2048MiB + if innodbBufferPoolSize < (8 * gb) { + innodbLogFileSize = (512 * mb) / (uint64(logGroups)) + } else if innodbBufferPoolSize <= (128 * gb) { + innodbLogFileSize = 1 * gb + } else { + innodbLogFileSize = 2 * gb + } + return strconv.FormatUint(innodbBufferPoolSize, 10), strconv.Itoa(int(instances)), strconv.FormatUint(innodbLogFileSize, 10) +} diff --git a/mysqlcluster/syncer/statefulset.go b/mysqlcluster/syncer/statefulset.go index c885fdcd..32318ca3 100644 --- a/mysqlcluster/syncer/statefulset.go +++ b/mysqlcluster/syncer/statefulset.go @@ -151,6 +151,11 @@ func (s *StatefulSetSyncer) Sync(ctx context.Context) (syncer.SyncResult, error) } default: + // readonly node processing. + s.SfsReadOnly(ctx) + if err = s.SingleLeaderAction(); err != nil { + s.log.Error(err, "single Leader operation", "key", key, "kind", kind) + } result.SetEventData("Normal", basicEventReason(s.Name, err), fmt.Sprintf("%s %s %s successfully", kind, key, result.Operation)) s.log.Info(string(result.Operation), "key", key, "kind", kind) @@ -616,3 +621,34 @@ func (s *StatefulSetSyncer) podsAllUpdated(ctx context.Context) bool { } return len(podlist.Items) == 0 } + +// Execute Comm +func (s *StatefulSetSyncer) SingleLeaderAction() error { + if *s.Spec.Replicas != 1 { + return nil + } + if s.Status.State != apiv1alpha1.ClusterReadyState { + return nil + } + // 1. close the xenon's SemiCheck. + executor, err := internal.NewPodExecutor() + if err != nil { + return err + } + podName := fmt.Sprintf("%s-mysql-0", s.Name) + err = executor.CloseXenonSemiCheck(s.Namespace, podName) + s.log.Info("close the xenon's semicheck", "pod", podName) + if err != nil { + return err + } + // 2. close mysql semi + + // SET GLOBAL rpl_semi_sync_master_enabled=OFF + err = executor.SetGlobalSysVar(s.Namespace, podName, "SET GLOBAL rpl_semi_sync_master_enabled=off") + s.log.Info("close the mysql's rpl_semi_sync_master_enabled", "pod", podName) + if err != nil { + return err + } + + return nil +} diff --git a/mysqlcluster/syncer/status.go b/mysqlcluster/syncer/status.go index 799d9917..a70994e5 100644 --- a/mysqlcluster/syncer/status.go +++ b/mysqlcluster/syncer/status.go @@ -25,7 +25,9 @@ import ( "github.com/presslabs/controller-util/pkg/syncer" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/selection" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" logf "sigs.k8s.io/controller-runtime/pkg/log" @@ -86,14 +88,22 @@ func (s *StatusSyncer) GetOwner() runtime.Object { return s.MysqlCluster } // Sync persists data into the external store. func (s *StatusSyncer) Sync(ctx context.Context) (syncer.SyncResult, error) { clusterCondition := s.updateClusterStatus() + labelSelector := s.GetLabels().AsSelector() + // Find the pods that revision is old. + r, err := labels.NewRequirement("readonly", selection.DoesNotExist, []string{}) + if err != nil { + s.log.V(1).Info("failed to create label requirement", "error", err) + return syncer.SyncResult{}, err + } + labelSelector = labelSelector.Add(*r) list := corev1.PodList{} - err := s.cli.List( + err = s.cli.List( ctx, &list, &client.ListOptions{ Namespace: s.Namespace, - LabelSelector: s.GetLabels().AsSelector(), + LabelSelector: labelSelector, }, ) if err != nil { @@ -153,7 +163,12 @@ func (s *StatusSyncer) Sync(ctx context.Context) (syncer.SyncResult, error) { if len(s.Status.Conditions) > maxStatusesQuantity { s.Status.Conditions = s.Status.Conditions[len(s.Status.Conditions)-maxStatusesQuantity:] } - + //(RO) because the ReadOnly Pods create after the cluster ready, so the ReadOnly pods are always + // the last part of node status + if err := s.updateReadOnlyNodeStatus(ctx, s.cli); err != nil { + //Notice!!! ReadOnly node fail, just show the error log, do not return here! + s.log.Error(err, "ReadOnly pod fail", "namespace", s.Namespace) + } // Update all nodes' status. return syncer.SyncResult{}, s.updateNodeStatus(ctx, s.cli, list.Items) } @@ -329,7 +344,14 @@ func (s *StatusSyncer) updateNodeStatus(ctx context.Context, cli client.Client, // Delete node status of nodes that have been deleted. if len(s.Status.Nodes) > len(pods) { - s.Status.Nodes = s.Status.Nodes[:len(pods)] + trimNodes := s.Status.Nodes[:len(pods)] + if s.Spec.ReadOnlys != nil { + // get the last parts of ReadOnly Nodes. + roNodes := s.Status.Nodes[len(s.Status.Nodes)-int(s.Spec.ReadOnlys.Num) : len(s.Status.Nodes)] + trimNodes = append(trimNodes, roNodes...) + } + s.Status.Nodes = trimNodes + } return nil } @@ -497,3 +519,162 @@ func (s *StatusSyncer) updatePodLabel(ctx context.Context, pod *corev1.Pod, node } return nil } + +// Update the Readonly node status +func (s *StatusSyncer) updateReadOnlyNodeStatus(ctx context.Context, cli client.Client) error { + labels := s.GetLabels() + labels["app.kubernetes.io/name"] = "mysql-readonly" + labels["readonly"] = "true" + + list := corev1.PodList{} + err := s.cli.List( + ctx, + &list, + &client.ListOptions{ + Namespace: s.Namespace, + LabelSelector: labels.AsSelector(), + }, + ) + if err != nil { + return err + } + // (RO) 1. status update + if err := s.RoCheckStatus(ctx, cli, list.Items); err != nil { + return err + } + return nil +} + +// (RO) check readonly and check semi replication +func (s *StatusSyncer) RoCheckStatus(ctx context.Context, cli client.Client, pods []corev1.Pod) error { + closeCh := make(chan func()) + for _, pod := range pods { + podName := pod.Name + host := fmt.Sprintf("%s.%s.%s", podName, s.GetNameForResource(utils.ReadOnlyHeadlessSVC), s.Namespace) + index := s.getRoStatusIndex(host) + node := &s.Status.Nodes[index] + node.Message = "" + + isInitial, isReadonly, isCloseSemi, isReplicating := corev1.ConditionUnknown, corev1.ConditionUnknown, corev1.ConditionUnknown, corev1.ConditionUnknown + isSupperReadOnly := corev1.ConditionUnknown + if pod.Status.Phase == corev1.PodRunning { + isInitial = corev1.ConditionTrue + } + var sqlRunner internal.SQLRunner + var closeConn func() + errCh := make(chan error) + go func(sqlRunner *internal.SQLRunner, errCh chan error, closeCh chan func()) { + var err error + *sqlRunner, closeConn, err = s.SQLRunnerFactory(internal.NewConfigFromClusterKey( + s.cli, s.MysqlCluster.GetClusterKey(), utils.OperatorUser, host)) + if err != nil { + s.log.V(1).Info("failed to get sql runner", "node", node.Name, "error", err) + errCh <- err + return + } + if closeConn != nil { + closeCh <- closeConn + return + } + errCh <- nil + }(&sqlRunner, errCh, closeCh) + + select { + case <-errCh: + case closeConn := <-closeCh: + defer closeConn() + case <-time.After(time.Second * 5): + } + var err error + + if sqlRunner != nil { + // (RO) 1. add check readonly + if isReadonly, err = internal.CheckReadOnly(sqlRunner); err != nil { + node.Message = err.Error() + } + if isSupperReadOnly, err = internal.CheckSuperReadOnly(sqlRunner); err != nil { + node.Message = err.Error() + } + // 2. set rpl_semi_sync_slave_enabled off + if status, err := internal.CheckSemSync(sqlRunner); err != nil { + node.Message = err.Error() + + } else if status == corev1.ConditionFalse { + isCloseSemi = corev1.ConditionTrue + } + // 3. change master + if _, isReplicating, err = internal.CheckSlaveStatus(sqlRunner); err != nil { + node.Message = err.Error() + } + } + //update node Rostatus + node.RoStatus = &apiv1alpha1.RoStatus{ + ReadOnly: isReadonly == corev1.ConditionTrue && isSupperReadOnly == corev1.ConditionTrue, + Replication: isReplicating == corev1.ConditionTrue && isCloseSemi == corev1.ConditionTrue, + Master: func(cr *StatusSyncer) string { + if *cr.Spec.Replicas == 1 { + return fmt.Sprintf("%s-0.%s.%s", cr.GetNameForResource(utils.StatefulSet), + s.GetNameForResource(utils.StatefulSet), cr.Namespace) + } + if cr.Spec.ReadOnlys != nil { + if len(cr.Spec.ReadOnlys.Host) == 0 { + return fmt.Sprintf("%s-follower", cr.Name) + } else { + return fmt.Sprintf("%s.%s.%s", cr.Spec.ReadOnlys.Host, cr.GetNameForResource(utils.StatefulSet), cr.Namespace) + } + } else { + return "" + } + }(s), + } + // update apiv1alpha1.NodeConditionLagged. + s.updateNodeCondition(node, 0, isInitial) + // readonly + s.updateNodeCondition(node, int(apiv1alpha1.IndexRoReadOnly-apiv1alpha1.IndexRoInit), isReadonly) + // close semi check + s.updateNodeCondition(node, int(apiv1alpha1.IndexRoSemiClose-apiv1alpha1.IndexRoInit), isCloseSemi) + // update apiv1alpha1.NodeConditionReplicating. + s.updateNodeCondition(node, int(apiv1alpha1.IndexRoReplicating-apiv1alpha1.IndexRoInit), isReplicating) + + } + return nil +} + +// (RO) 3. get status index and set conditon +func (s *StatusSyncer) getRoStatusIndex(name string) int { + len := len(s.Status.Nodes) + for i := 0; i < len; i++ { + if s.Status.Nodes[i].Name == name { + return i + } + } + + lastTransitionTime := metav1.NewTime(time.Now()) + status := apiv1alpha1.NodeStatus{ + Name: name, + Conditions: []apiv1alpha1.NodeCondition{ + { + Type: apiv1alpha1.NodeConditionRoInitial, + Status: corev1.ConditionUnknown, + LastTransitionTime: lastTransitionTime, + }, + { + Type: apiv1alpha1.NodeConditionRoReadOnly, + Status: corev1.ConditionUnknown, + LastTransitionTime: lastTransitionTime, + }, + { + Type: apiv1alpha1.NodeConditionRoSemiClose, + Status: corev1.ConditionUnknown, + LastTransitionTime: lastTransitionTime, + }, + { + Type: apiv1alpha1.NodeConditionRoReplicating, + Status: corev1.ConditionUnknown, + LastTransitionTime: lastTransitionTime, + }, + }, + } + s.Status.Nodes = append(s.Status.Nodes, status) + return len +} diff --git a/sidecar/config.go b/sidecar/config.go index 6461b829..b075dec9 100644 --- a/sidecar/config.go +++ b/sidecar/config.go @@ -282,12 +282,17 @@ func (cfg *Config) XBackupName() (string, string) { func (cfg *Config) buildExtraConfig(filePath string) (*ini.File, error) { conf := ini.Empty() sec := conf.Section("mysqld") - + startIndex := mysqlServerIDOffset ordinal, err := utils.GetOrdinal(cfg.HostName) + arr := strings.Split(cfg.HostName, "-") + if len(arr) == 3 && arr[1] == "ro" { + log.Info("It is readonly pod, server-id start at 200") + startIndex = mysqlReadOnlyIDOffset + } if err != nil { return nil, err } - if _, err := sec.NewKey("server-id", strconv.Itoa(mysqlServerIDOffset+ordinal)); err != nil { + if _, err := sec.NewKey("server-id", strconv.Itoa(startIndex+ordinal)); err != nil { return nil, err } diff --git a/sidecar/init.go b/sidecar/init.go index 0e51af63..e5b014ca 100644 --- a/sidecar/init.go +++ b/sidecar/init.go @@ -162,7 +162,37 @@ func runInitCommand(cfg *Config, hasInitialized bool) error { if err = copyFile(path.Join(mysqlCMPath, "my.cnf"), path.Join(mysqlConfigPath, "my.cnf")); err != nil { return fmt.Errorf("failed to copy my.cnf: %s", err) } - + // check env exist + if ib_pool := getEnvValue(utils.ROIbPool); len(ib_pool) != 0 { + //replace sed + arg := fmt.Sprintf("sed -i 's/^innodb_buffer_pool_size.*/innodb_buffer_pool_size\t=\t%s/' "+path.Join(mysqlConfigPath, "my.cnf"), ib_pool) + log.Info("run sed", "arg", arg) + cmd := exec.Command("sh", "-c", arg) + cmd.Stderr = os.Stderr + if err = cmd.Run(); err != nil { + return fmt.Errorf("failed to sed innodb_buffer_pool_size : %s", err) + } + } + if ib_inst := getEnvValue(utils.ROIbInst); len(ib_inst) != 0 { + //replace sed + arg := fmt.Sprintf("sed -i 's/^innodb_buffer_pool_instances.*/innodb_buffer_pool_instances\t=\t%s/' "+path.Join(mysqlConfigPath, "my.cnf"), ib_inst) + log.Info("run sed", "arg", arg) + cmd := exec.Command("sh", "-c", arg) + cmd.Stderr = os.Stderr + if err = cmd.Run(); err != nil { + return fmt.Errorf("failed to sed innodb_buffer_pool_instances : %s", err) + } + } + if ib_log := getEnvValue(utils.ROIbLog); len(ib_log) != 0 { + //replace sed + arg := fmt.Sprintf("sed -i 's/^innodb_log_file_size.*/innodb_log_file_size\t=\t%s/' "+path.Join(mysqlConfigPath, "my.cnf"), ib_log) + log.Info("run sed", "arg", arg) + cmd := exec.Command("sh", "-c", arg) + cmd.Stderr = os.Stderr + if err = cmd.Run(); err != nil { + return fmt.Errorf("failed to sed innodb_log_file_size : %s", err) + } + } // SSL settings. if exists, _ := checkIfPathExists(utils.TlsMountPath); exists { buildSSLdata() diff --git a/sidecar/util.go b/sidecar/util.go index f48c710b..6cd1cce9 100644 --- a/sidecar/util.go +++ b/sidecar/util.go @@ -31,6 +31,9 @@ var ( // MysqlServerIDOffset represents the offset with which all server ids are shifted from 0 mysqlServerIDOffset = 100 + //MySQL readonly server id start index + mysqlReadOnlyIDOffset = 200 + // mysqlConfigPath is the mysql configs path. mysqlConfigPath = utils.MysqlConfVolumeMountPath diff --git a/utils/constants.go b/utils/constants.go index 75f26880..e5836e6a 100644 --- a/utils/constants.go +++ b/utils/constants.go @@ -131,6 +131,11 @@ const ( // TlsMountPath is the volume mount path for tls TlsMountPath = "/etc/mysql-ssl" + //extra env for readonly + ROIbPool = "IB_POOL" + ROIbInst = "IB_INST" + ROIbLog = "IB_LOG" + // RadonDB excutable files dir RadonDBBinDir = "/opt/radondb" ) @@ -141,6 +146,9 @@ type ResourceName string const ( // HeadlessSVC is the alias of the headless service resource. HeadlessSVC ResourceName = "headless" + // ReadOnlyHeadlessSVC is the alias of the headless service resource + ReadOnlyHeadlessSVC = "ROHeadless" + ReadOnlySvc = "Ro-service" // StatefulSet is the alias of the statefulset resource. StatefulSet ResourceName = "mysql" // ConfigMap is the alias for mysql configs, the config map resource. From d40e512101617f22230ca3364f8e2b3e12ddf940 Mon Sep 17 00:00:00 2001 From: acekingke Date: Thu, 25 May 2023 13:12:17 +0800 Subject: [PATCH 2/2] mysqlcluster: add the readonly rebuild function --- mysqlcluster/syncer/status.go | 65 +++++++++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 2 deletions(-) diff --git a/mysqlcluster/syncer/status.go b/mysqlcluster/syncer/status.go index a70994e5..2a95c1ba 100644 --- a/mysqlcluster/syncer/status.go +++ b/mysqlcluster/syncer/status.go @@ -165,7 +165,7 @@ func (s *StatusSyncer) Sync(ctx context.Context) (syncer.SyncResult, error) { } //(RO) because the ReadOnly Pods create after the cluster ready, so the ReadOnly pods are always // the last part of node status - if err := s.updateReadOnlyNodeStatus(ctx, s.cli); err != nil { + if err := s.updateReadOnlyNodeStatus(ctx, s.cli, list.Items); err != nil { //Notice!!! ReadOnly node fail, just show the error log, do not return here! s.log.Error(err, "ReadOnly pod fail", "namespace", s.Namespace) } @@ -521,7 +521,7 @@ func (s *StatusSyncer) updatePodLabel(ctx context.Context, pod *corev1.Pod, node } // Update the Readonly node status -func (s *StatusSyncer) updateReadOnlyNodeStatus(ctx context.Context, cli client.Client) error { +func (s *StatusSyncer) updateReadOnlyNodeStatus(ctx context.Context, cli client.Client, cluster_pods []corev1.Pod) error { labels := s.GetLabels() labels["app.kubernetes.io/name"] = "mysql-readonly" labels["readonly"] = "true" @@ -542,6 +542,13 @@ func (s *StatusSyncer) updateReadOnlyNodeStatus(ctx context.Context, cli client. if err := s.RoCheckStatus(ctx, cli, list.Items); err != nil { return err } + for _, pod := range list.Items { + if err := s.DoRoRebuild(ctx, &pod, cluster_pods); err != nil { + // Cannot return ,just print log. + s.log.Error(err, "failed to AutoRebuild", "pod", pod.Name, "namespace", pod.Namespace) + } + } + return nil } @@ -678,3 +685,57 @@ func (s *StatusSyncer) getRoStatusIndex(name string) int { s.Status.Nodes = append(s.Status.Nodes, status) return len } + +func (s *StatusSyncer) DoRoRebuild(ctx context.Context, pod *corev1.Pod, items []corev1.Pod) error { + if len(pod.ObjectMeta.Labels[utils.LableRebuild]) == 0 { + return nil + } + ordinal, err := utils.GetOrdinal(pod.Name) + if err != nil { + return err + + } + if pod.ObjectMeta.Labels[utils.LableRebuild] != "true" { + podNumber, err := strconv.Atoi(pod.ObjectMeta.Labels[utils.LableRebuild]) + if err != nil { + return fmt.Errorf("rebuild label should be true, or number") + } + for _, other := range items { + ord, err2 := utils.GetOrdinal(other.Name) + if err2 != nil { + return err + + } + if ord == podNumber { + other.Labels[utils.LabelRebuildFrom] = "true" + if err := s.cli.Update(ctx, &other); err != nil { + return err + } + break + } + } + } + // Set Pod UnHealthy. + pod.Labels["healthy"] = "no" + if err := s.cli.Update(ctx, pod); err != nil { + return err + } + // Delete the Pod. + if err := s.cli.Delete(ctx, pod); err != nil { + return err + } + // Delete the pvc. + pvcName := fmt.Sprintf("%s-%s-%d", utils.DataVolumeName, + s.GetNameForResource(utils.ReadOnlyHeadlessSVC), ordinal) + pvc := corev1.PersistentVolumeClaim{} + + if err := s.cli.Get(ctx, + types.NamespacedName{Name: pvcName, Namespace: s.Namespace}, + &pvc); err != nil { + return err + } + if err := s.cli.Delete(ctx, &pvc); err != nil { + return err + } + return nil +}