Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix the bug in webhook with AdvancedStatefulSet (#2507) #2551

Merged
merged 6 commits into from
May 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pkg/webhook/pod/pd_deleter.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func (pc *PodAdmissionControl) admitDeletePdPods(payload *admitPayload) *admissi
// check the pd pods which have been upgraded before were all health
if isUpgrading {
klog.Infof("receive delete pd pod[%s/%s] of tc[%s/%s] is upgrading, make sure former pd upgraded status was health", namespace, name, namespace, tcName)
err = checkFormerPDPodStatus(pc.kubeCli, payload.pdClient, payload.tc, namespace, ordinal, *payload.ownerStatefulSet.Spec.Replicas)
err = checkFormerPDPodStatus(pc.kubeCli, payload.pdClient, payload.tc, payload.ownerStatefulSet, ordinal)
if err != nil {
return util.ARFail(err)
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/webhook/pod/pd_deleter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ package pod

import (
"fmt"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"testing"

. "github.com/onsi/gomega"
Expand All @@ -30,7 +28,9 @@ import (
admission "k8s.io/api/admission/v1beta1"
apps "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
kubefake "k8s.io/client-go/kubernetes/fake"
k8sTesting "k8s.io/client-go/testing"
)
Expand Down Expand Up @@ -67,7 +67,7 @@ func TestPDDeleterDelete(t *testing.T) {

deletePod := newPDPodForPDPodAdmissionControl()
ownerStatefulSet := newOwnerStatefulSetForPDPodAdmissionControl()
tc := newTidbClusterForPodAdmissionControl()
tc := newTidbClusterForPodAdmissionControl(pdReplicas, tikvReplicas)
kubeCli := kubefake.NewSimpleClientset()

if test.UpdatePVCErr {
Expand Down
42 changes: 23 additions & 19 deletions pkg/webhook/pod/pods_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
package pod

import (
"strconv"
"testing"

. "github.com/onsi/gomega"
Expand Down Expand Up @@ -139,8 +140,8 @@ func newPodAdmissionControl(kubeCli kubernetes.Interface) *PodAdmissionControl {
}
}

func newTidbClusterForPodAdmissionControl() *v1alpha1.TidbCluster {
return &v1alpha1.TidbCluster{
func newTidbClusterForPodAdmissionControl(pdReplicas int32, tikvReplicas int32) *v1alpha1.TidbCluster {
tc := &v1alpha1.TidbCluster{
TypeMeta: metav1.TypeMeta{
Kind: "TidbCluster",
APIVersion: "pingcap.com/v1alpha1",
Expand Down Expand Up @@ -171,26 +172,29 @@ func newTidbClusterForPodAdmissionControl() *v1alpha1.TidbCluster {
TiKV: v1alpha1.TiKVStatus{
Synced: true,
Phase: v1alpha1.NormalPhase,
Stores: map[string]v1alpha1.TiKVStore{
"0": {
PodName: memberUtils.TikvPodName(tcName, 0),
LeaderCount: 1,
State: v1alpha1.TiKVStateUp,
},
"1": {
PodName: memberUtils.TikvPodName(tcName, 1),
LeaderCount: 1,
State: v1alpha1.TiKVStateUp,
},
"2": {
PodName: memberUtils.TikvPodName(tcName, 2),
LeaderCount: 1,
State: v1alpha1.TiKVStateUp,
},
},
Stores: map[string]v1alpha1.TiKVStore{},
},
PD: v1alpha1.PDStatus{
Synced: true,
Phase: v1alpha1.NormalPhase,
Members: map[string]v1alpha1.PDMember{},
},
},
}
for i := 0; int32(i) < tikvReplicas; i++ {
tc.Status.TiKV.Stores[strconv.Itoa(i)] = v1alpha1.TiKVStore{
PodName: memberUtils.TikvPodName(tcName, int32(i)),
LeaderCount: 1,
State: v1alpha1.TiKVStateUp,
}
}
for i := 0; int32(i) < pdReplicas; i++ {
tc.Status.PD.Members[memberUtils.PdPodName(tcName, int32(i))] = v1alpha1.PDMember{
Health: true,
Name: memberUtils.PdPodName(tcName, int32(i)),
}
}
return tc
}

func newNormalPod() *corev1.Pod {
Expand Down
2 changes: 1 addition & 1 deletion pkg/webhook/pod/tikv_deleter.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ func (pc *PodAdmissionControl) admitDeleteUpTiKVPod(payload *admitPayload, store
}

if isUpgrading {
err = checkFormerTiKVPodStatus(pc.kubeCli, payload.tc, ordinal, *payload.ownerStatefulSet.Spec.Replicas, storesInfo)
err = checkFormerTiKVPodStatus(pc.kubeCli, payload.tc, ordinal, payload.ownerStatefulSet, storesInfo)
if err != nil {
klog.Infof("tc[%s/%s]'s tikv pod[%s/%s] failed to delete,%v", namespace, tcName, namespace, name, err)
return util.ARFail(err)
Expand Down
2 changes: 1 addition & 1 deletion pkg/webhook/pod/tikv_deleter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func TestTiKVDeleterDelete(t *testing.T) {
t.Log(test.name)
deleteTiKVPod := newTiKVPod(1)
ownerStatefulSet := newOwnerStatefulsetForTikv()
tc := newTidbClusterForPodAdmissionControl()
tc := newTidbClusterForPodAdmissionControl(pdReplicas, tikvReplicas)
kubeCli := kubefake.NewSimpleClientset()

podAdmissionControl := newPodAdmissionControl(kubeCli)
Expand Down
13 changes: 8 additions & 5 deletions pkg/webhook/pod/tikv_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,28 @@ import (
"strings"
"time"

"k8s.io/client-go/kubernetes"
"k8s.io/klog"

"github.com/pingcap/advanced-statefulset/client/apis/apps/v1/helper"
"github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1"
memberUtil "github.com/pingcap/tidb-operator/pkg/manager/member"
"github.com/pingcap/tidb-operator/pkg/pdapi"
apps "k8s.io/api/apps/v1"
core "k8s.io/api/core/v1"
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/klog"
)

// checkFormerTiKVPodStatus would check all the former tikv pods whether their store state were UP during Upgrading
// check need both check former pod is ready ,store up, and no evict leader
func checkFormerTiKVPodStatus(kubeCli kubernetes.Interface, tc *v1alpha1.TidbCluster, ordinal int32, replicas int32, storesInfo *pdapi.StoresInfo) error {
func checkFormerTiKVPodStatus(kubeCli kubernetes.Interface, tc *v1alpha1.TidbCluster, ordinal int32, set *apps.StatefulSet, storesInfo *pdapi.StoresInfo) error {

tcName := tc.Name
namespace := tc.Namespace

for i := replicas - 1; i > ordinal; i-- {
for i := range helper.GetPodOrdinals(tc.Spec.TiKV.Replicas, set) {
if i <= ordinal {
continue
}
podName := memberUtil.TikvPodName(tcName, i)
pod, err := kubeCli.CoreV1().Pods(namespace).Get(podName, meta.GetOptions{})
if err != nil {
Expand Down
29 changes: 11 additions & 18 deletions pkg/webhook/pod/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (

"github.com/pingcap/advanced-statefulset/client/apis/apps/v1/helper"
"github.com/pingcap/tidb-operator/pkg/apis/pingcap/v1alpha1"
"github.com/pingcap/tidb-operator/pkg/features"
"github.com/pingcap/tidb-operator/pkg/label"
memberUtil "github.com/pingcap/tidb-operator/pkg/manager/member"
"github.com/pingcap/tidb-operator/pkg/pdapi"
Expand Down Expand Up @@ -64,7 +63,7 @@ func addDeferDeletingToPVC(pvc *core.PersistentVolumeClaim, kubeCli kubernetes.I

// check whether the former upgraded pd pods were healthy in PD cluster during PD upgrading.
// If not,then return an error
func checkFormerPDPodStatus(kubeCli kubernetes.Interface, pdClient pdapi.PDClient, tc *v1alpha1.TidbCluster, namespace string, ordinal int32, replicas int32) error {
func checkFormerPDPodStatus(kubeCli kubernetes.Interface, pdClient pdapi.PDClient, tc *v1alpha1.TidbCluster, set *apps.StatefulSet, ordinal int32) error {
healthInfo, err := pdClient.GetHealth()
if err != nil {
return err
Expand All @@ -73,9 +72,14 @@ func checkFormerPDPodStatus(kubeCli kubernetes.Interface, pdClient pdapi.PDClien
for _, memberHealth := range healthInfo.Healths {
membersHealthMap[memberHealth.Name] = memberHealth.Health
}
namespace := tc.Namespace

tcName := tc.Name
for i := replicas - 1; i > ordinal; i-- {

for i := range helper.GetPodOrdinals(tc.Spec.PD.Replicas, set) {
if i <= ordinal {
continue
}
podName := memberUtil.PdPodName(tcName, i)
pod, err := kubeCli.CoreV1().Pods(namespace).Get(podName, meta.GetOptions{})
if err != nil {
Expand Down Expand Up @@ -155,21 +159,9 @@ func checkFormerPodRestartStatus(kubeCli kubernetes.Interface, memberType v1alph
return false, nil
}

if features.DefaultFeatureGate.Enabled(features.AdvancedStatefulSet) {
for k := range helper.GetPodOrdinals(replicas, payload.ownerStatefulSet) {
if k > ordinal {
existed, err := f(tc.Name, k, memberType)
if err != nil {
return false, err
}
if existed {
return true, nil
}
}
}
} else {
for i := replicas - 1; i > ordinal; i-- {
existed, err := f(tc.Name, i, memberType)
for k := range helper.GetPodOrdinals(replicas, payload.ownerStatefulSet) {
if k > ordinal {
existed, err := f(tc.Name, k, memberType)
if err != nil {
return false, err
}
Expand All @@ -178,6 +170,7 @@ func checkFormerPodRestartStatus(kubeCli kubernetes.Interface, memberType v1alph
}
}
}

return false, nil
}

Expand Down
Loading