Merge pull request #1400 from 24sama/master

fix: etcd backup service does not work
This commit is contained in:
KubeSphere CI Bot 2022-07-25 14:45:00 +08:00 committed by GitHub
commit d98cc07fd9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 181 additions and 44 deletions

View File

@ -17,10 +17,13 @@
package etcd
import (
"path/filepath"
kubekeyapiv1alpha2 "github.com/kubesphere/kubekey/apis/kubekey/v1alpha2"
"github.com/kubesphere/kubekey/pkg/common"
"github.com/kubesphere/kubekey/pkg/core/action"
"github.com/kubesphere/kubekey/pkg/core/task"
"github.com/kubesphere/kubekey/pkg/core/util"
"github.com/kubesphere/kubekey/pkg/etcd/templates"
)
@ -387,7 +390,46 @@ func (b *BackupModule) Init() {
Parallel: true,
}
generateBackupETCDService := &task.RemoteTask{
Name: "GenerateBackupETCDService",
Desc: "Generate backup ETCD service",
Hosts: b.Runtime.GetHostsByRole(common.ETCD),
Action: &action.Template{
Template: templates.BackupETCDService,
Dst: filepath.Join("/etc/systemd/system/", templates.BackupETCDService.Name()),
Data: util.Data{
"ScriptPath": filepath.Join(b.KubeConf.Cluster.Etcd.BackupScriptDir, "etcd-backup.sh"),
},
},
Parallel: true,
}
generateBackupETCDTimer := &task.RemoteTask{
Name: "GenerateBackupETCDTimer",
Desc: "Generate backup ETCD timer",
Hosts: b.Runtime.GetHostsByRole(common.ETCD),
Action: &action.Template{
Template: templates.BackupETCDTimer,
Dst: filepath.Join("/etc/systemd/system/", templates.BackupETCDTimer.Name()),
Data: util.Data{
"OnCalendarStr": templates.BackupTimeOnCalendar(b.KubeConf.Cluster.Etcd.BackupPeriod),
},
},
Parallel: true,
}
enable := &task.RemoteTask{
Name: "EnableBackupETCDService",
Desc: "Enable backup etcd service",
Hosts: b.Runtime.GetHostsByRole(common.ETCD),
Action: new(EnableBackupETCDService),
Parallel: true,
}
b.Tasks = []task.Interface{
backupETCD,
generateBackupETCDService,
generateBackupETCDTimer,
enable,
}
}

View File

@ -18,10 +18,13 @@ package etcd
import (
"fmt"
"github.com/kubesphere/kubekey/pkg/files"
"path/filepath"
"strings"
"github.com/kubesphere/kubekey/pkg/files"
"github.com/pkg/errors"
kubekeyapiv1alpha2 "github.com/kubesphere/kubekey/apis/kubekey/v1alpha2"
"github.com/kubesphere/kubekey/pkg/common"
"github.com/kubesphere/kubekey/pkg/core/action"
@ -29,7 +32,6 @@ import (
"github.com/kubesphere/kubekey/pkg/core/util"
"github.com/kubesphere/kubekey/pkg/etcd/templates"
"github.com/kubesphere/kubekey/pkg/utils"
"github.com/pkg/errors"
)
type EtcdNode struct {
@ -390,9 +392,7 @@ func (b *BackupETCD) Execute(runtime connector.Runtime) error {
"Etcdendpoint": fmt.Sprintf("https://%s:2379", runtime.RemoteHost().GetInternalAddress()),
"Backupdir": b.KubeConf.Cluster.Etcd.BackupDir,
"KeepbackupNumber": b.KubeConf.Cluster.Etcd.KeepBackupNumber,
"EtcdBackupPeriod": b.KubeConf.Cluster.Etcd.BackupPeriod,
"EtcdBackupScriptDir": b.KubeConf.Cluster.Etcd.BackupScriptDir,
"EtcdBackupHour": templates.BackupTimeInterval(runtime, b.KubeConf),
},
}
@ -404,9 +404,17 @@ func (b *BackupETCD) Execute(runtime connector.Runtime) error {
if _, err := runtime.GetRunner().SudoCmd(fmt.Sprintf("chmod +x %s/etcd-backup.sh", b.KubeConf.Cluster.Etcd.BackupScriptDir), false); err != nil {
return errors.Wrap(errors.WithStack(err), "chmod etcd backup script failed")
}
return nil
}
if _, err := runtime.GetRunner().SudoCmd(fmt.Sprintf("sh %s/etcd-backup.sh", b.KubeConf.Cluster.Etcd.BackupScriptDir), false); err != nil {
return errors.Wrap(errors.WithStack(err), "Failed to run the etcd-backup.sh")
type EnableBackupETCDService struct {
common.KubeAction
}
func (e *EnableBackupETCDService) Execute(runtime connector.Runtime) error {
if _, err := runtime.GetRunner().SudoCmd("systemctl enable --now backup-etcd.timer",
false); err != nil {
return errors.Wrap(errors.WithStack(err), "enable backup-etcd.service failed")
}
return nil
}

View File

@ -17,12 +17,9 @@
package templates
import (
"github.com/kubesphere/kubekey/pkg/common"
"github.com/kubesphere/kubekey/pkg/core/connector"
"github.com/kubesphere/kubekey/pkg/core/logger"
"github.com/lithammer/dedent"
"strconv"
"text/template"
"github.com/lithammer/dedent"
)
// EtcdBackupScriptTmpl defines the template of etcd backup script.
@ -34,9 +31,7 @@ ENDPOINTS='{{ .Etcdendpoint }}'
ETCD_DATA_DIR="/var/lib/etcd"
BACKUP_DIR="{{ .Backupdir }}/etcd-$(date +%Y-%m-%d-%H-%M-%S)"
KEEPBACKUPNUMBER='{{ .KeepbackupNumber }}'
ETCDBACKUPPERIOD='{{ .EtcdBackupPeriod }}'
ETCDBACKUPSCIPT='{{ .EtcdBackupScriptDir }}'
ETCDBACKUPHOUR='{{ .EtcdBackupHour }}'
ETCDCTL_CERT="/etc/ssl/etcd/ssl/admin-{{ .Hostname }}.pem"
ETCDCTL_KEY="/etc/ssl/etcd/ssl/admin-{{ .Hostname }}-key.pem"
@ -59,35 +54,4 @@ sleep 3
cd $BACKUP_DIR/../;ls -lt |awk '{if(NR > '$KEEPBACKUPNUMBER'){print "rm -rf "$9}}'|sh
if [[ ! $ETCDBACKUPHOUR ]]; then
time="*/$ETCDBACKUPPERIOD * * * *"
else
if [[ 0 == $ETCDBACKUPPERIOD ]];then
time="* */$ETCDBACKUPHOUR * * *"
else
time="*/$ETCDBACKUPPERIOD */$ETCDBACKUPHOUR * * *"
fi
fi
crontab -l | grep -v '#' > /tmp/file
echo "$time sh $ETCDBACKUPSCIPT/etcd-backup.sh" >> /tmp/file && awk ' !x[$0]++{print > "/tmp/file"}' /tmp/file
crontab /tmp/file
rm -rf /tmp/file
`)))
func BackupTimeInterval(runtime connector.Runtime, kubeConf *common.KubeConf) string {
var etcdBackupHour string
if kubeConf.Cluster.Etcd.BackupPeriod != 0 {
period := kubeConf.Cluster.Etcd.BackupPeriod
if period > 60 && period < 1440 {
kubeConf.Cluster.Etcd.BackupPeriod = period % 60
etcdBackupHour = strconv.Itoa(period / 60)
}
if period > 1440 {
logger.Log.Message(runtime.RemoteHost().GetName(), "etcd backup cannot last more than one day, Please change it to within one day or KubeKey will set it to the default value '24'.")
return "24"
}
}
return etcdBackupHour
}

View File

@ -0,0 +1,71 @@
/*
Copyright 2022 The KubeSphere Authors.
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 templates
import (
"fmt"
"strconv"
"text/template"
"github.com/lithammer/dedent"
)
var (
// BackupETCDService defines the template of backup-etcd service for systemd.
BackupETCDService = template.Must(template.New("backup-etcd.service").Parse(
dedent.Dedent(`[Unit]
Description=Backup ETCD
[Service]
Type=oneshot
ExecStart={{ .ScriptPath }}
`)))
// BackupETCDTimer defines the template of backup-etcd timer for systemd.
BackupETCDTimer = template.Must(template.New("backup-etcd.timer").Parse(
dedent.Dedent(`[Unit]
Description=Timer to backup ETCD
[Timer]
{{- if .OnCalendarStr }}
OnCalendar={{ .OnCalendarStr }}
{{- else }}
OnCalendar=*-*-* *:*/30:00
{{- end }}
Unit=backup-etcd.service
[Install]
WantedBy=multi-user.target
`)))
)
func BackupTimeOnCalendar(period int) string {
var onCalendar string
if period <= 0 {
onCalendar = "*-*-* *:00/30:00"
} else if period < 60 {
onCalendar = fmt.Sprintf("*-*-* *:00/%d:00", period)
} else if period >= 60 && period < 1440 {
hour := strconv.Itoa(period / 60)
minute := strconv.Itoa(period % 60)
if period%60 == 0 {
onCalendar = fmt.Sprintf("*-*-* 00/%s:00:00", hour)
} else {
onCalendar = fmt.Sprintf("*-*-* 00/%s:%s:00", hour, minute)
}
} else {
onCalendar = "*-*-* 00:00:00"
}
return onCalendar
}

View File

@ -0,0 +1,52 @@
/*
Copyright 2022 The KubeSphere Authors.
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 templates
import (
"testing"
)
func TestBackupTimeOnCalendar(t *testing.T) {
tests := []struct {
period int
want string
}{
{
30,
"*-*-* *:00/30:00",
},
{
60,
"*-*-* 00/1:00:00",
},
{
70,
"*-*-* 00/1:10:00",
},
{
1500,
"*-*-* 00:00:00",
},
}
for _, tt := range tests {
t.Run("", func(t *testing.T) {
if got := BackupTimeOnCalendar(tt.period); got != tt.want {
t.Errorf("BackupTimeOnCalendar() = %v, want %v", got, tt.want)
}
})
}
}