Skip to content

Commit 35cbadc

Browse files
authored
*: rebuild from special pod #652 (#658)
1 parent c654a2a commit 35cbadc

File tree

5 files changed

+80
-5
lines changed

5 files changed

+80
-5
lines changed

config/samples/nfs_server.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ spec:
1414
containers:
1515
- name: nfs-server
1616
## TODO: radondb/volume-nfs:0.8
17-
image: gcr.azk8s.cn/google_containers/volume-nfs:0.8
17+
image: k8s.gcr.io/volume-nfs:0.8
1818
ports:
1919
- name: nfs
2020
containerPort: 2049

mysqlcluster/syncer/role.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ func NewRoleSyncer(cli client.Client, c *mysqlcluster.MysqlCluster) syncer.Inter
4242
return syncer.NewObjectSyncer("Role", c.Unwrap(), role, cli, func() error {
4343
role.Rules = []rbacv1.PolicyRule{
4444
{
45-
Verbs: []string{"get", "patch"},
45+
Verbs: []string{"get", "patch", "list"},
4646
APIGroups: []string{""},
4747
Resources: []string{"pods"},
4848
},

mysqlcluster/syncer/status.go

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package syncer
1919
import (
2020
"context"
2121
"fmt"
22+
"strconv"
2223
"time"
2324

2425
"github.com/presslabs/controller-util/syncer"
@@ -102,8 +103,8 @@ func (s *StatusSyncer) Sync(ctx context.Context) (syncer.SyncResult, error) {
102103
// get ready nodes.
103104
var readyNodes []corev1.Pod
104105
for _, pod := range list.Items {
105-
if pod.ObjectMeta.Labels[utils.LableRebuild] == "true" {
106-
if err := s.AutoRebuild(ctx, &pod); err != nil {
106+
if len(pod.ObjectMeta.Labels[utils.LableRebuild]) > 0 {
107+
if err := s.AutoRebuild(ctx, &pod, list.Items); err != nil {
107108
s.log.Error(err, "failed to AutoRebuild", "pod", pod.Name, "namespace", pod.Namespace)
108109
}
109110
continue
@@ -199,12 +200,32 @@ func (s *StatusSyncer) updateClusterStatus() apiv1alpha1.ClusterCondition {
199200
// Rebuild Pod by deleting and creating it.
200201
// Notice: This function just delete Pod and PVC,
201202
// then after k8s recreate pod, it will clone and initial it.
202-
func (s *StatusSyncer) AutoRebuild(ctx context.Context, pod *corev1.Pod) error {
203+
func (s *StatusSyncer) AutoRebuild(ctx context.Context, pod *corev1.Pod, items []corev1.Pod) error {
203204
ordinal, err := utils.GetOrdinal(pod.Name)
204205
if err != nil {
205206
return err
206207

207208
}
209+
if pod.ObjectMeta.Labels[utils.LableRebuild] != "true" {
210+
podNumber, err := strconv.Atoi(pod.ObjectMeta.Labels[utils.LableRebuild])
211+
if err != nil {
212+
return fmt.Errorf("rebuild label should be true, or number")
213+
}
214+
for _, other := range items {
215+
ord, err2 := utils.GetOrdinal(other.Name)
216+
if err2 != nil {
217+
return err
218+
219+
}
220+
if ord == podNumber {
221+
other.Labels[utils.LabelRebuildFrom] = "true"
222+
if err := s.cli.Update(ctx, &other); err != nil {
223+
return err
224+
}
225+
break
226+
}
227+
}
228+
}
208229
// Set Pod UnHealthy.
209230
pod.Labels["healthy"] = "no"
210231
if err := s.cli.Update(ctx, pod); err != nil {

sidecar/init.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
package sidecar
1818

1919
import (
20+
"context"
2021
"fmt"
2122
"io/ioutil"
2223
"net/http"
@@ -30,6 +31,11 @@ import (
3031
"github.com/go-ini/ini"
3132
"github.com/radondb/radondb-mysql-kubernetes/utils"
3233
"github.com/spf13/cobra"
34+
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
35+
"k8s.io/apimachinery/pkg/labels"
36+
"k8s.io/apimachinery/pkg/types"
37+
"k8s.io/client-go/kubernetes"
38+
"k8s.io/client-go/rest"
3339
)
3440

3541
// NewInitCommand return a pointer to cobra.Command.
@@ -82,6 +88,13 @@ func CheckServiceExist(cfg *Config, service string) bool {
8288
func runCloneAndInit(cfg *Config) error {
8389
//check follower is exists?
8490
serviceURL := ""
91+
// Check the rebuildFrom exist?
92+
if service, err := getPod(cfg); err == nil {
93+
serviceURL = service
94+
log.Info("found the rebuild-from pod", "service", serviceURL)
95+
} else {
96+
log.Info("found the rebuild-from pod", "error", err.Error())
97+
}
8598
if len(serviceURL) == 0 && CheckServiceExist(cfg, "follower") {
8699
serviceURL = fmt.Sprintf("http://%s-%s:%v", cfg.ClusterName, "follower", utils.XBackupPort)
87100
}
@@ -339,3 +352,43 @@ func buildSSLdata() error {
339352
}
340353
return nil
341354
}
355+
356+
func getPod(cfg *Config) (string, error) {
357+
log.Info("Now check the pod which has got rebuild-from")
358+
config, err := rest.InClusterConfig()
359+
if err != nil {
360+
return "", err
361+
}
362+
// creates the clientset
363+
clientset, err := kubernetes.NewForConfig(config)
364+
if err != nil {
365+
return "", err
366+
}
367+
match := map[string]string{
368+
utils.LabelRebuildFrom: "true",
369+
}
370+
podList, err := clientset.CoreV1().Pods(cfg.NameSpace).
371+
List(context.TODO(), v1.ListOptions{
372+
LabelSelector: labels.SelectorFromSet(match).String()})
373+
if err != nil {
374+
return "", err
375+
}
376+
if len(podList.Items) == 1 {
377+
pod := podList.Items[0]
378+
// Patch remove rebuild-from
379+
if err := removeRebuildFrom(clientset, cfg, pod.Name); err != nil {
380+
log.Info("remove rebuild from", "error", err.Error())
381+
}
382+
return fmt.Sprintf("%s.%s-mysql.%s:%v", pod.Name, cfg.ClusterName, cfg.NameSpace, utils.XBackupPort), nil
383+
} else {
384+
return "", fmt.Errorf("not correct pod choose")
385+
}
386+
387+
}
388+
389+
func removeRebuildFrom(clientset *kubernetes.Clientset, cfg *Config, podName string) error {
390+
patch := fmt.Sprintf(`[{"op": "remove", "path": "/metadata/labels/%s"}]`, utils.LabelRebuildFrom)
391+
_, err := clientset.CoreV1().Pods(cfg.NameSpace).Patch(context.TODO(), podName, types.JSONPatchType, []byte(patch), v1.PatchOptions{})
392+
393+
return err
394+
}

utils/constants.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ const (
195195
)
196196

197197
const LableRebuild = "rebuild"
198+
const LabelRebuildFrom = "rebuild-from"
198199

199200
// XenonHttpUrl is a http url corresponding to the xenon instruction.
200201
type XenonHttpUrl string

0 commit comments

Comments
 (0)