mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-26 21:17:23 +00:00
chore(*): update election example (#82821)
* feat(*): simplify leader election example * chore(*): fix with comment * chore(*): add os.exit * chore(*): fix typo
This commit is contained in:
parent
f985367ba4
commit
1185012da6
@ -23,7 +23,7 @@ go_library(
|
|||||||
"//staging/src/k8s.io/client-go/tools/clientcmd:go_default_library",
|
"//staging/src/k8s.io/client-go/tools/clientcmd:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/tools/leaderelection:go_default_library",
|
"//staging/src/k8s.io/client-go/tools/leaderelection:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/tools/leaderelection/resourcelock:go_default_library",
|
"//staging/src/k8s.io/client-go/tools/leaderelection/resourcelock:go_default_library",
|
||||||
"//staging/src/k8s.io/client-go/transport:go_default_library",
|
"//vendor/github.com/google/uuid:go_default_library",
|
||||||
"//vendor/k8s.io/klog:go_default_library",
|
"//vendor/k8s.io/klog:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -8,14 +8,15 @@ Run the following three commands in separate terminals. Each terminal needs a un
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# first terminal
|
# first terminal
|
||||||
go run *.go -kubeconfig=/my/config -logtostderr=true -id=1
|
go run main.go -kubeconfig=/path/to/kubeconfig -logtostderr=true -lease-lock-name=example -lease-lock-namespace=default -id=1
|
||||||
|
|
||||||
# second terminal
|
# second terminal
|
||||||
go run *.go -kubeconfig=/my/config -logtostderr=true -id=2
|
go run main.go -kubeconfig=/path/to/kubeconfig -logtostderr=true -lease-lock-name=example -lease-lock-namespace=default -id=2
|
||||||
|
|
||||||
# third terminal
|
# third terminal
|
||||||
go run *.go -kubeconfig=/my/config -logtostderr=true -id=3
|
go run main.go -kubeconfig=/path/to/kubeconfig -logtostderr=true -lease-lock-name=example -lease-lock-namespace=default -id=3
|
||||||
```
|
```
|
||||||
|
|
||||||
> You can ignore the `-kubeconfig` flag if you are running these commands in the Kubernetes cluster.
|
> You can ignore the `-kubeconfig` flag if you are running these commands in the Kubernetes cluster.
|
||||||
|
|
||||||
Now kill the existing leader. You will see from the terminal outputs that one of the remaining two processes will be elected as the new leader.
|
Now kill the existing leader. You will see from the terminal outputs that one of the remaining two processes will be elected as the new leader.
|
||||||
|
@ -19,21 +19,18 @@ package main
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"strings"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
"k8s.io/client-go/rest"
|
"k8s.io/client-go/rest"
|
||||||
"k8s.io/client-go/tools/clientcmd"
|
"k8s.io/client-go/tools/clientcmd"
|
||||||
"k8s.io/client-go/tools/leaderelection"
|
"k8s.io/client-go/tools/leaderelection"
|
||||||
"k8s.io/client-go/tools/leaderelection/resourcelock"
|
"k8s.io/client-go/tools/leaderelection/resourcelock"
|
||||||
"k8s.io/client-go/transport"
|
|
||||||
"k8s.io/klog"
|
"k8s.io/klog"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -62,13 +59,16 @@ func main() {
|
|||||||
var id string
|
var id string
|
||||||
|
|
||||||
flag.StringVar(&kubeconfig, "kubeconfig", "", "absolute path to the kubeconfig file")
|
flag.StringVar(&kubeconfig, "kubeconfig", "", "absolute path to the kubeconfig file")
|
||||||
flag.StringVar(&id, "id", "", "the holder identity name")
|
flag.StringVar(&id, "id", uuid.New().String(), "the holder identity name")
|
||||||
flag.StringVar(&leaseLockName, "lease-lock-name", "example", "the lease lock resource name")
|
flag.StringVar(&leaseLockName, "lease-lock-name", "", "the lease lock resource name")
|
||||||
flag.StringVar(&leaseLockNamespace, "lease-lock-namespace", "default", "the lease lock resource namespace")
|
flag.StringVar(&leaseLockNamespace, "lease-lock-namespace", "", "the lease lock resource namespace")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
if id == "" {
|
if leaseLockName == "" {
|
||||||
klog.Fatal("unable to get id (missing id flag).")
|
klog.Fatal("unable to get lease lock resource name (missing lease-lock-name flag).")
|
||||||
|
}
|
||||||
|
if leaseLockNamespace == "" {
|
||||||
|
klog.Fatal("unable to get lease lock resource namespace (missing lease-lock-namespace flag).")
|
||||||
}
|
}
|
||||||
|
|
||||||
// leader election uses the Kubernetes API by writing to a
|
// leader election uses the Kubernetes API by writing to a
|
||||||
@ -82,6 +82,29 @@ func main() {
|
|||||||
}
|
}
|
||||||
client := clientset.NewForConfigOrDie(config)
|
client := clientset.NewForConfigOrDie(config)
|
||||||
|
|
||||||
|
run := func(ctx context.Context) {
|
||||||
|
// complete your controller loop here
|
||||||
|
klog.Info("Controller loop...")
|
||||||
|
|
||||||
|
select {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// use a Go context so we can tell the leaderelection code when we
|
||||||
|
// want to step down
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
// listen for interrupts or the Linux SIGTERM signal and cancel
|
||||||
|
// our context, which the leader election code will observe and
|
||||||
|
// step down
|
||||||
|
ch := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(ch, os.Interrupt, syscall.SIGTERM)
|
||||||
|
go func() {
|
||||||
|
<-ch
|
||||||
|
klog.Info("Received termination, signaling shutdown")
|
||||||
|
cancel()
|
||||||
|
}()
|
||||||
|
|
||||||
// we use the Lease lock type since edits to Leases are less common
|
// we use the Lease lock type since edits to Leases are less common
|
||||||
// and fewer objects in the cluster watch "all Leases".
|
// and fewer objects in the cluster watch "all Leases".
|
||||||
lock := &resourcelock.LeaseLock{
|
lock := &resourcelock.LeaseLock{
|
||||||
@ -95,25 +118,6 @@ func main() {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// use a Go context so we can tell the leaderelection code when we
|
|
||||||
// want to step down
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
// use a client that will stop allowing new requests once the context ends
|
|
||||||
config.Wrap(transport.ContextCanceller(ctx, fmt.Errorf("the leader is shutting down")))
|
|
||||||
|
|
||||||
// listen for interrupts or the Linux SIGTERM signal and cancel
|
|
||||||
// our context, which the leader election code will observe and
|
|
||||||
// step down
|
|
||||||
ch := make(chan os.Signal, 1)
|
|
||||||
signal.Notify(ch, os.Interrupt, syscall.SIGTERM)
|
|
||||||
go func() {
|
|
||||||
<-ch
|
|
||||||
log.Printf("Received termination, signaling shutdown")
|
|
||||||
cancel()
|
|
||||||
}()
|
|
||||||
|
|
||||||
// start the leader election code loop
|
// start the leader election code loop
|
||||||
leaderelection.RunOrDie(ctx, leaderelection.LeaderElectionConfig{
|
leaderelection.RunOrDie(ctx, leaderelection.LeaderElectionConfig{
|
||||||
Lock: lock,
|
Lock: lock,
|
||||||
@ -131,12 +135,12 @@ func main() {
|
|||||||
OnStartedLeading: func(ctx context.Context) {
|
OnStartedLeading: func(ctx context.Context) {
|
||||||
// we're notified when we start - this is where you would
|
// we're notified when we start - this is where you would
|
||||||
// usually put your code
|
// usually put your code
|
||||||
klog.Infof("%s: leading", id)
|
run(ctx)
|
||||||
},
|
},
|
||||||
OnStoppedLeading: func() {
|
OnStoppedLeading: func() {
|
||||||
// we can do cleanup here, or after the RunOrDie method
|
// we can do cleanup here
|
||||||
// returns
|
klog.Infof("leader lost: %s", id)
|
||||||
klog.Infof("%s: lost", id)
|
os.Exit(0)
|
||||||
},
|
},
|
||||||
OnNewLeader: func(identity string) {
|
OnNewLeader: func(identity string) {
|
||||||
// we're notified when new leader elected
|
// we're notified when new leader elected
|
||||||
@ -144,18 +148,8 @@ func main() {
|
|||||||
// I just got the lock
|
// I just got the lock
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
klog.Infof("new leader elected: %v", identity)
|
klog.Infof("new leader elected: %s", identity)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// because the context is closed, the client should report errors
|
|
||||||
_, err = client.CoordinationV1().Leases(leaseLockNamespace).Get(leaseLockName, metav1.GetOptions{})
|
|
||||||
if err == nil || !strings.Contains(err.Error(), "the leader is shutting down") {
|
|
||||||
log.Fatalf("%s: expected to get an error when trying to make a client call: %v", id, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// we no longer hold the lease, so perform any cleanup and then
|
|
||||||
// exit
|
|
||||||
log.Printf("%s: done", id)
|
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ require (
|
|||||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903
|
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903
|
||||||
github.com/golang/protobuf v1.3.1
|
github.com/golang/protobuf v1.3.1
|
||||||
github.com/google/gofuzz v1.0.0
|
github.com/google/gofuzz v1.0.0
|
||||||
|
github.com/google/uuid v1.1.1
|
||||||
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d
|
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d
|
||||||
github.com/gophercloud/gophercloud v0.1.0
|
github.com/gophercloud/gophercloud v0.1.0
|
||||||
github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7
|
github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7
|
||||||
|
1
staging/src/k8s.io/client-go/go.sum
generated
1
staging/src/k8s.io/client-go/go.sum
generated
@ -64,6 +64,7 @@ github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
|
|||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||||
|
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||||
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d h1:7XGaL1e6bYS1yIonGp9761ExpPPV1ui0SAC59Yube9k=
|
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d h1:7XGaL1e6bYS1yIonGp9761ExpPPV1ui0SAC59Yube9k=
|
||||||
|
Loading…
Reference in New Issue
Block a user