restore only one node to local

This commit is contained in:
louisehong
2020-08-21 17:23:22 +08:00
parent 82edbe258c
commit 55df307d98
5 changed files with 103 additions and 8 deletions
+20
View File
@@ -0,0 +1,20 @@
FROM golang:1.14.3 AS builder
ENV GO111MODULE=on
ENV GOPROXY=https://goproxy.io
WORKDIR /root
COPY . .
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /sealos -mod vendor -ldflags "-X github.com/fanux/sealos/version.Version=latest -X github.com/fanux/sealos/version.Build= -X 'github.com/fanux/sealos/version.BuildTime='" main.go
FROM alpine:3.7
ENV TZ=Asia/Shangha
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \
apk add tzdata ca-certificates && \
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
echo "Asia/Shanghai" > /etc/timezone && apk add --update bash && \
rm -rf /var/cache/apk/*
COPY --from=builder /sealos /bin/sealos
ENTRYPOINT ["/bin/sealos"]
+15 -6
View File
@@ -22,12 +22,14 @@ import (
)
var exampleCmd = `
# snapshot save the etcd
sealos etcd --snap-save --name snapshot --path /opt/sealos/ectd-backup
# snapshot save the etcd, the backupPath is on etcd nodes. not on the sealos init machine.
sealos etcd --snap-save --name snapshot --backupPath /opt/sealos/ectd-backup
# snapshot restore the etcd
sealos etcd --restore --name snapshot --path /opt/sealos/ectd-backup
sealos etcd --snap-restore --name snapshot --backupPath /opt/sealos/ectd-backup
# etcd health check
sealos etcd --health
`
// etcdCmd represents the etcd command
@@ -47,6 +49,12 @@ var etcdCmd = &cobra.Command{
e := install.GetEtcdBackFlags()
e.HealthCheck()
}
if install.EtcdRestore {
e := install.GetRestoreFlags()
e.Restore()
logger.Info("check your Restore dir: %s", e.RestoreDir)
logger.Info("restore kubernetes yourself glad~")
}
},
}
@@ -55,10 +63,11 @@ func init() {
rootCmd.AddCommand(etcdCmd)
etcdCmd.Flags().BoolVar(&install.EtcdSnapshotSave, "snap-save", false, "snapshot your kubernets etcd ")
etcdCmd.Flags().BoolVar(&install.EtcdRestore, "restore", false, "restore your kubernets etcd")
etcdCmd.Flags().BoolVar(&install.EtcdRestore, "snap-restore", false, "restore your kubernets etcd")
etcdCmd.Flags().BoolVar(&install.EtcdHealthCheck, "health", false, "check your kubernets etcd")
etcdCmd.Flags().StringVar(&install.SnapshotName,"name",install.ETCDSNAPSHOTDEFAULTNAME,"Specify snapshot name")
etcdCmd.Flags().StringVar(&install.EtcdBackDir,"path",install.ETCDDEFAULTBACKUPDIR,"Specify snapshot backup dir")
etcdCmd.Flags().StringVar(&install.EtcdBackDir,"backupPath",install.ETCDDEFAULTBACKUPDIR,"Specify snapshot backup dir")
etcdCmd.Flags().StringVar(&install.RestorePath,"restorePath",install.ETCDDEFAULTRESTOREDIR,"Specify snapshot restore dir")
// Here you will define your flags and configuration settings.
+1
View File
@@ -16,6 +16,7 @@ const (
// etcd backup
ETCDSNAPSHOTDEFAULTNAME = "snapshot"
ETCDDEFAULTBACKUPDIR = "/opt/sealos/ectd-backup"
ETCDDEFAULTRESTOREDIR = "/opt/sealos/ectd-restore"
EtcdCacart = "/root/.sealos/pki/etcd/ca.crt"
EtcdCert = "/root/.sealos/pki/etcd/healthcheck-client.crt"
EtcdKey = "/root/.sealos/pki/etcd/healthcheck-client.key"
+56
View File
@@ -3,7 +3,10 @@ package install
import (
"fmt"
"github.com/wonderivan/logger"
"go.etcd.io/etcd/clientv3/snapshot"
"go.uber.org/zap"
"os"
"path/filepath"
)
func GetRestoreFlags() *EtcdFlags {
@@ -27,6 +30,7 @@ func GetRestoreFlags() *EtcdFlags {
return e
}
// we don't restore kubernetes but restore etcd
func (e *EtcdFlags) Prepare() error {
// stop kube-apiserver kube-controller-manager kube-scheduler etcd
// on every etcd nodes , and back all data to /var/lib/etcd.bak
@@ -48,6 +52,58 @@ func (e *EtcdFlags) Prepare() error {
return nil
}
func (e *EtcdFlags) Restore() {
restorePeerURLs := GetEtcdPeerURLs(e.EtcdHosts)
restoreClusterToken := "etcd-cluster"
restoreCluster:= GetEtcdInitialCluster(e.EtcdHosts)
walDir := filepath.Join(e.RestoreDir, "member", "wal")
lg, err := zap.NewProduction()
if err != nil {
logger.Error("get lg error: ", err)
os.Exit(-1)
}
sp := snapshot.NewV3(lg)
// get master name.
host := SSHConfig.CmdToString(e.EtcdHosts[0], "hostname", "")
if err := sp.Restore(snapshot.RestoreConfig{
SnapshotPath: e.LongName,
Name: "etcd-"+host,
OutputDataDir: e.RestoreDir,
OutputWALDir: walDir,
PeerURLs: restorePeerURLs,
InitialCluster: restoreCluster,
InitialClusterToken: restoreClusterToken,
SkipHashCheck: true,
}); err != nil {
logger.Error("restore etcd error: ", err)
os.Exit(-1)
}
}
func GetEtcdInitialCluster(hosts []string) string {
initialCluster := ""
for i, host := range hosts {
hostname := SSHConfig.CmdToString(host, "hostname", "")
ip := reFormatHostToIp(host)
initialCluster += fmt.Sprintf("etcd-%s=https://%s:2380", hostname, ip)
if i < (len(hosts) - 1) {
initialCluster += ","
}
}
return initialCluster
}
func GetEtcdPeerURLs(hosts []string) []string {
var peerUrls []string
for _, host := range hosts {
ip := reFormatHostToIp(host)
url := fmt.Sprintf("https://%s:2380", ip)
peerUrls = append(peerUrls, url)
}
return peerUrls
}
func CmdWork(node, cmd, workdir string) error {
command := fmt.Sprintf("cd %s && %s", workdir, cmd)
// not safe when use etcdctl to backup
+11 -2
View File
@@ -53,6 +53,14 @@ func GetEtcdBackFlags() *EtcdFlags {
}
func Save(e *EtcdFlags) {
if !FileExist(e.BackDir) {
err := os.MkdirAll(e.BackDir, os.ModePerm)
if err != nil {
logger.Error("mkdir BackDir err: ",err)
os.Exit(1)
}
}
cfg, err := GetCfg(e.Endpoints)
if err != nil {
logger.Error("get etcd cfg error: ", err)
@@ -69,6 +77,7 @@ func Save(e *EtcdFlags) {
if err := sp.Save(ctx, *cfg, e.LongName); err != nil {
logger.Error("snapshot save err: ", err)
os.Exit(-1)
}
fmt.Printf("Snapshot saved at %s\n", e.LongName)
}
@@ -130,7 +139,7 @@ type epHealth struct {
Error string `json:"error"`
}
func (e *EtcdFlags)HealthCheck() {
func (e *EtcdFlags) HealthCheck() {
cfgs := []*clientv3.Config{}
for _, ep := range e.Endpoints {
cfg, err := GetCfg([]string{ep})
@@ -183,4 +192,4 @@ func (e *EtcdFlags)HealthCheck() {
if errs {
logger.Error("unhealthy cluster")
}
}
}