kubeadm: do not remove the only remaining etcd member during reset

If this is the only remaining stacked etcd member in the cluster,
calling RemoveMember() is not needed.
This commit is contained in:
Quan Tian 2020-05-15 19:27:57 +08:00
parent 71277de4d6
commit 9cc416e7df
3 changed files with 52 additions and 5 deletions

View File

@ -103,6 +103,22 @@ func RemoveStackedEtcdMemberFromCluster(client clientset.Interface, cfg *kubeadm
return err return err
} }
members, err := etcdClient.ListMembers()
if err != nil {
return err
}
// If this is the only remaining stacked etcd member in the cluster, calling RemoveMember()
// is not needed.
if len(members) == 1 {
etcdClientAddress := etcdutil.GetClientURL(&cfg.LocalAPIEndpoint)
for _, endpoint := range etcdClient.Endpoints {
if endpoint == etcdClientAddress {
klog.V(1).Info("[etcd] This is the only remaining etcd member in the etcd cluster, skip removing it")
return nil
}
}
}
// notifies the other members of the etcd cluster about the removing member // notifies the other members of the etcd cluster about the removing member
etcdPeerAddress := etcdutil.GetPeerURL(&cfg.LocalAPIEndpoint) etcdPeerAddress := etcdutil.GetPeerURL(&cfg.LocalAPIEndpoint)
@ -113,7 +129,7 @@ func RemoveStackedEtcdMemberFromCluster(client clientset.Interface, cfg *kubeadm
} }
klog.V(1).Infof("[etcd] removing etcd member: %s, id: %d", etcdPeerAddress, id) klog.V(1).Infof("[etcd] removing etcd member: %s, id: %d", etcdPeerAddress, id)
members, err := etcdClient.RemoveMember(id) members, err = etcdClient.RemoveMember(id)
if err != nil { if err != nil {
return err return err
} }

View File

@ -246,6 +246,10 @@ func (c fakeTLSEtcdClient) CheckClusterHealth() error {
func (c fakeTLSEtcdClient) Sync() error { return nil } func (c fakeTLSEtcdClient) Sync() error { return nil }
func (c fakeTLSEtcdClient) ListMembers() ([]etcdutil.Member, error) {
return []etcdutil.Member{}, nil
}
func (c fakeTLSEtcdClient) AddMember(name string, peerAddrs string) ([]etcdutil.Member, error) { func (c fakeTLSEtcdClient) AddMember(name string, peerAddrs string) ([]etcdutil.Member, error) {
return []etcdutil.Member{}, nil return []etcdutil.Member{}, nil
} }
@ -277,6 +281,10 @@ func (c fakePodManifestEtcdClient) CheckClusterHealth() error {
func (c fakePodManifestEtcdClient) Sync() error { return nil } func (c fakePodManifestEtcdClient) Sync() error { return nil }
func (c fakePodManifestEtcdClient) ListMembers() ([]etcdutil.Member, error) {
return []etcdutil.Member{}, nil
}
func (c fakePodManifestEtcdClient) AddMember(name string, peerAddrs string) ([]etcdutil.Member, error) { func (c fakePodManifestEtcdClient) AddMember(name string, peerAddrs string) ([]etcdutil.Member, error) {
return []etcdutil.Member{}, nil return []etcdutil.Member{}, nil
} }

View File

@ -55,6 +55,7 @@ type ClusterInterrogator interface {
CheckClusterHealth() error CheckClusterHealth() error
WaitForClusterAvailable(retries int, retryInterval time.Duration) (bool, error) WaitForClusterAvailable(retries int, retryInterval time.Duration) (bool, error)
Sync() error Sync() error
ListMembers() ([]Member, error)
AddMember(name string, peerAddrs string) ([]Member, error) AddMember(name string, peerAddrs string) ([]Member, error)
GetMemberID(peerURL string) (uint64, error) GetMemberID(peerURL string) (uint64, error)
RemoveMember(id uint64) ([]Member, error) RemoveMember(id uint64) ([]Member, error)
@ -258,8 +259,7 @@ type Member struct {
PeerURL string PeerURL string
} }
// GetMemberID returns the member ID of the given peer URL func (c *Client) listMembers() (*clientv3.MemberListResponse, error) {
func (c *Client) GetMemberID(peerURL string) (uint64, error) {
cli, err := clientv3.New(clientv3.Config{ cli, err := clientv3.New(clientv3.Config{
Endpoints: c.Endpoints, Endpoints: c.Endpoints,
DialTimeout: dialTimeout, DialTimeout: dialTimeout,
@ -269,7 +269,7 @@ func (c *Client) GetMemberID(peerURL string) (uint64, error) {
TLS: c.TLS, TLS: c.TLS,
}) })
if err != nil { if err != nil {
return 0, err return nil, err
} }
defer cli.Close() defer cli.Close()
@ -288,7 +288,16 @@ func (c *Client) GetMemberID(peerURL string) (uint64, error) {
return false, nil return false, nil
}) })
if err != nil { if err != nil {
return 0, lastError return nil, lastError
}
return resp, nil
}
// GetMemberID returns the member ID of the given peer URL
func (c *Client) GetMemberID(peerURL string) (uint64, error) {
resp, err := c.listMembers()
if err != nil {
return 0, err
} }
for _, member := range resp.Members { for _, member := range resp.Members {
@ -299,6 +308,20 @@ func (c *Client) GetMemberID(peerURL string) (uint64, error) {
return 0, nil return 0, nil
} }
// ListMembers returns the member list.
func (c *Client) ListMembers() ([]Member, error) {
resp, err := c.listMembers()
if err != nil {
return nil, err
}
ret := make([]Member, 0, len(resp.Members))
for _, m := range resp.Members {
ret = append(ret, Member{Name: m.Name, PeerURL: m.PeerURLs[0]})
}
return ret, nil
}
// RemoveMember notifies an etcd cluster to remove an existing member // RemoveMember notifies an etcd cluster to remove an existing member
func (c *Client) RemoveMember(id uint64) ([]Member, error) { func (c *Client) RemoveMember(id uint64) ([]Member, error) {
cli, err := clientv3.New(clientv3.Config{ cli, err := clientv3.New(clientv3.Config{