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
}
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
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)
members, err := etcdClient.RemoveMember(id)
members, err = etcdClient.RemoveMember(id)
if err != nil {
return err
}

View File

@ -246,6 +246,10 @@ func (c fakeTLSEtcdClient) CheckClusterHealth() error {
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) {
return []etcdutil.Member{}, nil
}
@ -277,6 +281,10 @@ func (c fakePodManifestEtcdClient) CheckClusterHealth() error {
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) {
return []etcdutil.Member{}, nil
}

View File

@ -55,6 +55,7 @@ type ClusterInterrogator interface {
CheckClusterHealth() error
WaitForClusterAvailable(retries int, retryInterval time.Duration) (bool, error)
Sync() error
ListMembers() ([]Member, error)
AddMember(name string, peerAddrs string) ([]Member, error)
GetMemberID(peerURL string) (uint64, error)
RemoveMember(id uint64) ([]Member, error)
@ -258,8 +259,7 @@ type Member struct {
PeerURL string
}
// GetMemberID returns the member ID of the given peer URL
func (c *Client) GetMemberID(peerURL string) (uint64, error) {
func (c *Client) listMembers() (*clientv3.MemberListResponse, error) {
cli, err := clientv3.New(clientv3.Config{
Endpoints: c.Endpoints,
DialTimeout: dialTimeout,
@ -269,7 +269,7 @@ func (c *Client) GetMemberID(peerURL string) (uint64, error) {
TLS: c.TLS,
})
if err != nil {
return 0, err
return nil, err
}
defer cli.Close()
@ -288,7 +288,16 @@ func (c *Client) GetMemberID(peerURL string) (uint64, error) {
return false, 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 {
@ -299,6 +308,20 @@ func (c *Client) GetMemberID(peerURL string) (uint64, error) {
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
func (c *Client) RemoveMember(id uint64) ([]Member, error) {
cli, err := clientv3.New(clientv3.Config{