Browse Source

Add support for multiple etcd endpoints

Sometimes an etcd endpoint may be unavailable, this doesn't mean the
cluster is down. Add the possibility to pass multiple etcd endpoints to
flannel.

Warning: this changes the etcd-endpoint option to etcd-endpoints.
Josselin Costanzi 10 years ago
parent
commit
74f9413deb
3 changed files with 16 additions and 14 deletions
  1. 11 9
      main.go
  2. 4 4
      subnet/registry.go
  3. 1 1
      subnet/subnet.go

+ 11 - 9
main.go

@@ -24,19 +24,19 @@ import (
 )
 
 type CmdLineOpts struct {
-	etcdEndpoint string
-	etcdPrefix   string
-	help         bool
-	version      bool
-	ipMasq       bool
-	subnetFile   string
-	iface        string
+	etcdEndpoints string
+	etcdPrefix    string
+	help          bool
+	version       bool
+	ipMasq        bool
+	subnetFile    string
+	iface         string
 }
 
 var opts CmdLineOpts
 
 func init() {
-	flag.StringVar(&opts.etcdEndpoint, "etcd-endpoint", "http://127.0.0.1:4001", "etcd endpoint")
+	flag.StringVar(&opts.etcdEndpoints, "etcd-endpoints", "http://127.0.0.1:4001", "a comma-delimited list of etcd endpoints")
 	flag.StringVar(&opts.etcdPrefix, "etcd-prefix", "/coreos.com/network", "etcd prefix")
 	flag.StringVar(&opts.subnetFile, "subnet-file", "/run/flannel/subnet.env", "filename where env variables (subnet and MTU values) will be written to")
 	flag.StringVar(&opts.iface, "iface", "", "interface to use (IP or name) for inter-host communication")
@@ -125,8 +125,10 @@ func lookupIface() (*net.Interface, net.IP, error) {
 }
 
 func makeSubnetManager() *subnet.SubnetManager {
+	peers := strings.Split(opts.etcdEndpoints, ",")
+
 	for {
-		sm, err := subnet.NewSubnetManager(opts.etcdEndpoint, opts.etcdPrefix)
+		sm, err := subnet.NewSubnetManager(peers, opts.etcdPrefix)
 		if err == nil {
 			return sm
 		}

+ 4 - 4
subnet/registry.go

@@ -20,13 +20,13 @@ type subnetRegistry interface {
 type etcdSubnetRegistry struct {
 	mux      sync.Mutex
 	cli      *etcd.Client
-	endpoint string
+	endpoint []string
 	prefix   string
 }
 
-func newEtcdSubnetRegistry(endpoint, prefix string) subnetRegistry {
+func newEtcdSubnetRegistry(endpoint []string, prefix string) subnetRegistry {
 	return &etcdSubnetRegistry{
-		cli:      etcd.NewClient([]string{endpoint}),
+		cli:      etcd.NewClient(endpoint),
 		endpoint: endpoint,
 		prefix:   prefix,
 	}
@@ -101,7 +101,7 @@ func (esr *etcdSubnetRegistry) client() *etcd.Client {
 func (esr *etcdSubnetRegistry) resetClient() {
 	esr.mux.Lock()
 	defer esr.mux.Unlock()
-	esr.cli = etcd.NewClient([]string{esr.endpoint})
+	esr.cli = etcd.NewClient(esr.endpoint)
 }
 
 func ensureExpiration(resp *etcd.Response, ttl uint64) {

+ 1 - 1
subnet/subnet.go

@@ -61,7 +61,7 @@ type Event struct {
 
 type EventBatch []Event
 
-func NewSubnetManager(etcdEndpoint, prefix string) (*SubnetManager, error) {
+func NewSubnetManager(etcdEndpoint []string, prefix string) (*SubnetManager, error) {
 	esr := newEtcdSubnetRegistry(etcdEndpoint, prefix)
 	return newSubnetManager(esr)
 }