Skip to content

Commit d40ceb8

Browse files
committed
Remove node role from sidecar side. Don't run node controller on old clusters. Set readyNodes to zero when doing upgrade.
1 parent efa90be commit d40ceb8

File tree

10 files changed

+56
-94
lines changed

10 files changed

+56
-94
lines changed

docs/deploy-mysql-cluster.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ spec:
154154

155155
For more configuration details regarding`hostPath` go [here](https://godoc.org/k8s.io/api/core/v1#HostPathVolumeSource), and more information about `emptyDir` can be found [here](https://godoc.org/k8s.io/api/core/v1#EmptyDirVolumeSource).
156156

157+
> NOTE that EmptyDir is not fully supported from version `v0.3.x` of the operator. Please use `hostPath` instead. See information about the known [issue](https://github.com/presslabs/mysql-operator/issues/250).
157158

158159
## Cluster MySQL configuration
159160

docs/operator-upgrades.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,4 @@ field) to make it smaller that will prevent you from hitting this
4343
The operator should do all the work for you but you have to make sure that you have the latest
4444
`0.2.x` version of the operator.
4545

46+
This release drop support for `emptyDir` volume source.

pkg/controller/mysqlcluster/internal/syncer/master_service.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,6 @@ func NewMasterSVCSyncer(c client.Client, scheme *runtime.Scheme, cluster *mysqlc
4242
out.Labels = cluster.GetLabels()
4343
out.Labels["mysql.presslabs.org/service-type"] = "master"
4444

45-
// make the master endpoint headless, it should always point to only one node
46-
out.Spec.ClusterIP = "None"
47-
4845
// set selectors for master node
4946
out.Spec.Selector = cluster.GetSelectorLabels()
5047
out.Spec.Selector["role"] = "master"

pkg/controller/mysqlcluster/internal/upgrades/upgrades.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import (
3535
orc "github.com/presslabs/mysql-operator/pkg/orchestrator"
3636
)
3737

38-
var log = logf.Log.WithName("upgrader.cluster")
38+
var log = logf.Log.WithName("upgrades.cluster")
3939

4040
const (
4141
// VersionAnnotation represents the annotation used to annotate a cluster to it's version
@@ -74,8 +74,8 @@ func (u *upgrader) Run(ctx context.Context) error {
7474
return err
7575
}
7676

77-
// more than 1 replca so there is the case when node 0 is slave so mark all other nodes as
78-
// in maintenance except node 0. When doint failover the node 0 will be promoted
77+
// more than 1 replica so there is the case when node 0 is slave so mark all other nodes as
78+
// in maintenance except node 0.
7979
// TODO: or set promotion rules
8080
if int(*sts.Spec.Replicas) > 1 {
8181

@@ -88,6 +88,12 @@ func (u *upgrader) Run(ctx context.Context) error {
8888
if err = u.client.Update(ctx, sts); err != nil {
8989
return err
9090
}
91+
92+
// set ready nodes on cluster to 0
93+
u.cluster.Status.ReadyNodes = 0
94+
if err = u.client.Status().Update(ctx, u.cluster.Unwrap()); err != nil {
95+
return err
96+
}
9197
}
9298

9399
if sts.Status.ReadyReplicas > 1 {

pkg/controller/mysqlcluster/mysqlcluster_controller.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,10 +155,11 @@ func (r *ReconcileMysqlCluster) Reconcile(request reconcile.Request) (reconcile.
155155
}
156156
log.Info("syncing cluster", "cluster", request.NamespacedName.String())
157157

158-
// run upgrader
158+
// run upgrades
159+
// TODO: this should be removed in next version (v0.4)
159160
up := upgrades.NewUpgrader(r.Client, r.recorder, cluster, r.opt)
160161
if up.ShouldUpdate() {
161-
log.V(1).Info("running upgrader")
162+
log.V(1).Info("running upgrades")
162163
if err = up.Run(context.TODO()); err != nil {
163164
return reconcile.Result{}, err
164165
}

pkg/controller/node/node_controller.go

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"context"
2121
"fmt"
2222
"regexp"
23+
"strconv"
2324
"time"
2425

2526
corev1 "k8s.io/api/core/v1"
@@ -154,29 +155,37 @@ func (r *ReconcileMysqlNode) Reconcile(request reconcile.Request) (reconcile.Res
154155

155156
log.Info("syncing MySQL Node", "pod", request.NamespacedName.String())
156157

158+
// try to get the related MySQL Cluster for current node
157159
var cluster *mysqlcluster.MysqlCluster
158160
cluster, err = r.getNodeCluster(ctx, pod)
159161
if err != nil {
160162
log.Info("cluster is not found")
161163
return reconcile.Result{}, err
162164
}
163165

166+
// if cluster is deleted then don't do anything
164167
if cluster.DeletionTimestamp != nil {
165168
log.Info("cluster is deleted nothing to do", "pod", pod.Spec.Hostname)
166169
return reconcile.Result{}, nil
167170
}
168171

172+
// if it's a old version cluster then don't do anything
173+
if shouldUpdateToVersion(cluster, 300) {
174+
return reconcile.Result{}, nil
175+
}
176+
177+
// get cluster credentials from k8s secret, like replication and operator credentials
169178
var creds *credentials
170-
creds, err = r.getCredsSecret(ctx, cluster)
171-
if err != nil {
179+
if creds, err = r.getCredsSecret(ctx, cluster); err != nil {
172180
return reconcile.Result{}, err
173181
}
174182

175183
// initialize SQL interface
176184
sql := r.getMySQLConnection(cluster, pod, creds)
177185

178-
err = r.initializeMySQL(ctx, sql, cluster, creds)
179-
if err != nil {
186+
// run the initializer, this will connect to MySQL server and run init queries
187+
if err = r.initializeMySQL(ctx, sql, cluster, creds); err != nil {
188+
// initialization failed, mark node as not yet initialized (by updating pod init condition)
180189
updatePodStatusCondition(pod, mysqlcluster.NodeInitializedConditionType,
181190
corev1.ConditionFalse, "mysqlInitializationFailed", err.Error())
182191

@@ -187,6 +196,7 @@ func (r *ReconcileMysqlNode) Reconcile(request reconcile.Request) (reconcile.Res
187196
return reconcile.Result{}, err
188197
}
189198

199+
// initialization complete
190200
updatePodStatusCondition(pod, mysqlcluster.NodeInitializedConditionType,
191201
corev1.ConditionTrue, "mysqlInitializationSucceeded", "success")
192202

@@ -199,6 +209,7 @@ func (r *ReconcileMysqlNode) initializeMySQL(ctx context.Context, sql SQLInterfa
199209
return err
200210
}
201211

212+
// disable MySQL SUPER readonly to be able to modify settings in MySQL
202213
enableSuperReadOnly, err := sql.DisableSuperReadOnly(ctx)
203214
if err != nil {
204215
return err
@@ -217,6 +228,7 @@ func (r *ReconcileMysqlNode) initializeMySQL(ctx context.Context, sql SQLInterfa
217228
}
218229
}
219230

231+
// write the configuration complete flag into MySQL, this will make the node ready
220232
if err := sql.MarkConfigurationDone(ctx); err != nil {
221233
return err
222234
}
@@ -341,3 +353,21 @@ func podCondIndex(p *corev1.Pod, condType corev1.PodConditionType) (int, bool) {
341353

342354
return 0, false
343355
}
356+
357+
func shouldUpdateToVersion(cluster *mysqlcluster.MysqlCluster, targetVersion int) bool {
358+
var version string
359+
var ok bool
360+
if version, ok = cluster.ObjectMeta.Annotations["mysql.presslabs.org/version"]; !ok {
361+
// no version annotation present, (it's a cluster older than 0.3.0) or it's a new cluster
362+
log.Info("annotation not set on cluster")
363+
return true
364+
}
365+
366+
ver, err := strconv.ParseInt(version, 10, 32)
367+
if err != nil {
368+
log.Error(err, "annotation version can't be parsed", "value", version)
369+
return true
370+
}
371+
372+
return int(ver) < targetVersion
373+
}

pkg/controller/node/node_ctrl_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ var _ = Describe("MysqlNode controller", func() {
8787
ObjectMeta: metav1.ObjectMeta{
8888
Name: fmt.Sprintf("cluster-%d", rand.Int31()),
8989
Namespace: "default",
90+
Annotations: map[string]string{
91+
"mysql.presslabs.org/version": "300",
92+
},
9093
},
9194
Spec: api.MysqlClusterSpec{
9295
Replicas: &one,

pkg/sidecar/appclone.go

Lines changed: 5 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,7 @@ func RunCloneCommand(cfg *Config) error {
3737
return fmt.Errorf("removing lost+found: %s", err)
3838
}
3939

40-
role, err := cfg.NodeRole()
41-
if err != nil {
42-
return err
43-
}
44-
45-
log.Info("configuring server as", "host", cfg.Hostname, "role", role)
46-
if role == MasterNode {
40+
if cfg.ServerID() == 100 {
4741
if len(cfg.InitBucketURL) == 0 {
4842
log.Info("skip cloning init bucket uri is not set.")
4943
// let mysqld initialize data dir
@@ -55,23 +49,10 @@ func RunCloneCommand(cfg *Config) error {
5549
}
5650
} else {
5751
// clonging from prior node
58-
if cfg.ServerID() > 100 {
59-
sourceHost := cfg.FQDNForServer(cfg.ServerID() - 1)
60-
err := cloneFromSource(cfg, sourceHost)
61-
if err != nil {
62-
return fmt.Errorf("failed to clone from %s, err: %s", sourceHost, err)
63-
}
64-
// clone from master if no prior node and node is not master
65-
} else if cfg.ServerID() == 100 {
66-
sourceHost := cfg.MasterFQDN()
67-
err := cloneFromSource(cfg, sourceHost)
68-
if err != nil {
69-
return fmt.Errorf("failed to clone from %s, err: %s", sourceHost, err)
70-
}
71-
} else {
72-
return fmt.Errorf(
73-
"failed to initialize because no prior node exists, check orchestrator maybe",
74-
)
52+
sourceHost := cfg.FQDNForServer(cfg.ServerID() - 1)
53+
err := cloneFromSource(cfg, sourceHost)
54+
if err != nil {
55+
return fmt.Errorf("failed to clone from %s, err: %s", sourceHost, err)
7556
}
7657
}
7758

pkg/sidecar/configs.go

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,6 @@ import (
3232
"github.com/presslabs/mysql-operator/pkg/internal/mysqlcluster"
3333
)
3434

35-
// NodeRole represents the kind of the MySQL server
36-
type NodeRole string
37-
38-
const (
39-
// MasterNode represents the master role for MySQL server
40-
MasterNode NodeRole = "master"
41-
// SlaveNode represents the slave role for MySQL server
42-
SlaveNode NodeRole = "slave"
43-
// Unknown usually used for error, when the role can't be determined
44-
Unknown NodeRole = "unknown"
45-
)
46-
4735
// Config contains information related with the pod.
4836
type Config struct {
4937
// Hostname represents the pod hostname
@@ -99,42 +87,6 @@ func (cfg *Config) MasterFQDN() string {
9987
return mysqlcluster.GetNameForResource(mysqlcluster.MasterService, cfg.ClusterName)
10088
}
10189

102-
// NodeRole returns the role of the current node
103-
func (cfg *Config) NodeRole() (NodeRole, error) {
104-
pod := cfg.FQDNForServer(cfg.ServerID())
105-
podIPs, err := retryLookupHost(pod)
106-
if err != nil {
107-
log.Info("can't lookup pod IP", "pod", pod, "err", err)
108-
return Unknown, err
109-
}
110-
111-
if len(podIPs) != 1 {
112-
// no IPs for given pod
113-
log.Info("no IPs for pod found", "pod", pod)
114-
return Unknown, nil
115-
}
116-
117-
masterSVC := mysqlcluster.GetNameForResource(mysqlcluster.MasterService, cfg.ClusterName)
118-
masterIPs, err := retryLookupHost(masterSVC)
119-
if err != nil {
120-
log.Info("can't lookup master service IP", "svc", masterSVC, "err", err)
121-
return MasterNode, nil
122-
}
123-
124-
if len(masterIPs) != 1 {
125-
log.Info("no IPs for master service", "svc", masterSVC)
126-
return MasterNode, nil
127-
}
128-
129-
if podIPs[0] == masterIPs[0] {
130-
log.Info("this pod is MASTER")
131-
return MasterNode, nil
132-
}
133-
134-
log.Info("this pod is SLAVE")
135-
return SlaveNode, nil
136-
}
137-
13890
// ServerID returns the MySQL server id
13991
func (cfg *Config) ServerID() int {
14092
ordinal := getOrdinalFromHostname(cfg.Hostname)

pkg/sidecar/configs_test.go

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,4 @@ var _ = Describe("Test sidecar configs", func() {
5151
It("should determine the host ip", func() {
5252
Expect(retryLookupHost("localhost")).To(ContainElement("127.0.0.1"))
5353
})
54-
55-
It("should determine the node role", func() {
56-
_, err := cfg.NodeRole()
57-
Expect(err).ToNot(Succeed())
58-
// TODO: fix this test
59-
// Expect().To(Equal(MasterNode))
60-
61-
// cfg.Hostname = "cluster-mysql-2"
62-
// Expect(cfg.NodeRole()).To(Equal(SlaveNode))
63-
})
6454
})

0 commit comments

Comments
 (0)