mirror of
https://github.com/kubernetes/client-go.git
synced 2025-09-01 15:17:19 +00:00
chore(*): update election example (#82821)
* feat(*): simplify leader election example * chore(*): fix with comment * chore(*): add os.exit * chore(*): fix typo Kubernetes-commit: 1185012da65edf802f22aff24141c0466a2a3ac8
This commit is contained in:
committed by
Kubernetes Publisher
parent
172b42569c
commit
c51c673cf8
2
Godeps/Godeps.json
generated
2
Godeps/Godeps.json
generated
@@ -348,7 +348,7 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/apimachinery",
|
||||
"Rev": "f9f2f3f8ab02"
|
||||
"Rev": "fb3eea214746"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/gengo",
|
||||
|
@@ -8,14 +8,15 @@ Run the following three commands in separate terminals. Each terminal needs a un
|
||||
|
||||
```bash
|
||||
# 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
|
||||
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
|
||||
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.
|
||||
|
||||
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 (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
clientset "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
"k8s.io/client-go/tools/leaderelection"
|
||||
"k8s.io/client-go/tools/leaderelection/resourcelock"
|
||||
"k8s.io/client-go/transport"
|
||||
"k8s.io/klog"
|
||||
)
|
||||
|
||||
@@ -62,13 +59,16 @@ func main() {
|
||||
var id string
|
||||
|
||||
flag.StringVar(&kubeconfig, "kubeconfig", "", "absolute path to the kubeconfig file")
|
||||
flag.StringVar(&id, "id", "", "the holder identity name")
|
||||
flag.StringVar(&leaseLockName, "lease-lock-name", "example", "the lease lock resource name")
|
||||
flag.StringVar(&leaseLockNamespace, "lease-lock-namespace", "default", "the lease lock resource namespace")
|
||||
flag.StringVar(&id, "id", uuid.New().String(), "the holder identity name")
|
||||
flag.StringVar(&leaseLockName, "lease-lock-name", "", "the lease lock resource name")
|
||||
flag.StringVar(&leaseLockNamespace, "lease-lock-namespace", "", "the lease lock resource namespace")
|
||||
flag.Parse()
|
||||
|
||||
if id == "" {
|
||||
klog.Fatal("unable to get id (missing id flag).")
|
||||
if leaseLockName == "" {
|
||||
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
|
||||
@@ -82,6 +82,29 @@ func main() {
|
||||
}
|
||||
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
|
||||
// and fewer objects in the cluster watch "all Leases".
|
||||
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
|
||||
leaderelection.RunOrDie(ctx, leaderelection.LeaderElectionConfig{
|
||||
Lock: lock,
|
||||
@@ -131,12 +135,12 @@ func main() {
|
||||
OnStartedLeading: func(ctx context.Context) {
|
||||
// we're notified when we start - this is where you would
|
||||
// usually put your code
|
||||
klog.Infof("%s: leading", id)
|
||||
run(ctx)
|
||||
},
|
||||
OnStoppedLeading: func() {
|
||||
// we can do cleanup here, or after the RunOrDie method
|
||||
// returns
|
||||
klog.Infof("%s: lost", id)
|
||||
// we can do cleanup here
|
||||
klog.Infof("leader lost: %s", id)
|
||||
os.Exit(0)
|
||||
},
|
||||
OnNewLeader: func(identity string) {
|
||||
// we're notified when new leader elected
|
||||
@@ -144,18 +148,8 @@ func main() {
|
||||
// I just got the lock
|
||||
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)
|
||||
}
|
||||
|
5
go.mod
5
go.mod
@@ -14,6 +14,7 @@ require (
|
||||
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903
|
||||
github.com/golang/protobuf v1.3.1
|
||||
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/gophercloud/gophercloud v0.1.0
|
||||
github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7
|
||||
@@ -27,7 +28,7 @@ require (
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c
|
||||
google.golang.org/appengine v1.5.0 // indirect
|
||||
k8s.io/api v0.0.0-20191010143144-fbf594f18f80
|
||||
k8s.io/apimachinery v0.0.0-20191006235458-f9f2f3f8ab02
|
||||
k8s.io/apimachinery v0.0.0-20191014065749-fb3eea214746
|
||||
k8s.io/klog v1.0.0
|
||||
k8s.io/utils v0.0.0-20190920012459-5008bf6f8cd6
|
||||
sigs.k8s.io/yaml v1.1.0
|
||||
@@ -42,5 +43,5 @@ replace (
|
||||
golang.org/x/text => golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db
|
||||
golang.org/x/time => golang.org/x/time v0.0.0-20161028155119-f51c12702a4d
|
||||
k8s.io/api => k8s.io/api v0.0.0-20191010143144-fbf594f18f80
|
||||
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20191006235458-f9f2f3f8ab02
|
||||
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20191014065749-fb3eea214746
|
||||
)
|
||||
|
3
go.sum
3
go.sum
@@ -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/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/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||
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/gnostic v0.0.0-20170729233727-0c5108395e2d h1:7XGaL1e6bYS1yIonGp9761ExpPPV1ui0SAC59Yube9k=
|
||||
@@ -180,7 +181,7 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
k8s.io/api v0.0.0-20191010143144-fbf594f18f80/go.mod h1:X3kixOyiuC4u4LU6y2BxLg5tsvw+hrMhstfga7LZ4Gw=
|
||||
k8s.io/apimachinery v0.0.0-20191006235458-f9f2f3f8ab02/go.mod h1:92mWDd8Ji2sw2157KIgino5wCxffA8KSvhW2oY4ypdw=
|
||||
k8s.io/apimachinery v0.0.0-20191014065749-fb3eea214746/go.mod h1:92mWDd8Ji2sw2157KIgino5wCxffA8KSvhW2oY4ypdw=
|
||||
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
|
Reference in New Issue
Block a user