Commit e62a8b91 authored by Kubernetes Submit Queue's avatar Kubernetes Submit Queue Committed by GitHub

Merge pull request #34962 from deads2k/cotnroller-08-rs-controller

Automatic merge from submit-queue convert replica set controller to shared informer Switches the replicaset to a shared informer. @kargakis fyi
parents 2f990ac4 b471398f
...@@ -422,7 +422,7 @@ func StartControllers(s *options.CMServer, kubeconfig *restclient.Config, rootCl ...@@ -422,7 +422,7 @@ func StartControllers(s *options.CMServer, kubeconfig *restclient.Config, rootCl
if containsResource(resources, "replicasets") { if containsResource(resources, "replicasets") {
glog.Infof("Starting ReplicaSet controller") glog.Infof("Starting ReplicaSet controller")
go replicaset.NewReplicaSetController(sharedInformers.Pods().Informer(), client("replicaset-controller"), ResyncPeriod(s), replicaset.BurstReplicas, int(s.LookupCacheSizeForRS), s.EnableGarbageCollector). go replicaset.NewReplicaSetController(sharedInformers.ReplicaSets(), sharedInformers.Pods(), client("replicaset-controller"), replicaset.BurstReplicas, int(s.LookupCacheSizeForRS), s.EnableGarbageCollector).
Run(int(s.ConcurrentRSSyncs), wait.NeverStop) Run(int(s.ConcurrentRSSyncs), wait.NeverStop)
time.Sleep(wait.Jitter(s.ControllerStartInterval.Duration, ControllerStartJitter)) time.Sleep(wait.Jitter(s.ControllerStartInterval.Duration, ControllerStartJitter))
} }
......
...@@ -22,6 +22,8 @@ import ( ...@@ -22,6 +22,8 @@ import (
"fmt" "fmt"
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/apis/extensions"
unversionedextensions "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/extensions/unversioned" unversionedextensions "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/extensions/unversioned"
) )
...@@ -38,6 +40,15 @@ func updateReplicaCount(rsClient unversionedextensions.ReplicaSetInterface, rs e ...@@ -38,6 +40,15 @@ func updateReplicaCount(rsClient unversionedextensions.ReplicaSetInterface, rs e
rs.Generation == rs.Status.ObservedGeneration { rs.Generation == rs.Status.ObservedGeneration {
return nil return nil
} }
// deep copy to avoid mutation now.
// TODO this method need some work. Retry on conflict probably, though I suspect this is stomping status to something it probably shouldn't
copyObj, err := api.Scheme.DeepCopy(rs)
if err != nil {
return err
}
rs = copyObj.(extensions.ReplicaSet)
// Save the generation number we acted on, otherwise we might wrongfully indicate // Save the generation number we acted on, otherwise we might wrongfully indicate
// that we've seen a spec update when we retry. // that we've seen a spec update when we retry.
// TODO: This can clobber an update if we allow multiple agents to write to the // TODO: This can clobber an update if we allow multiple agents to write to the
......
...@@ -52,11 +52,27 @@ type FakeHandler struct { ...@@ -52,11 +52,27 @@ type FakeHandler struct {
lock sync.Mutex lock sync.Mutex
requestCount int requestCount int
hasBeenChecked bool hasBeenChecked bool
SkipRequestFn func(verb string, url url.URL) bool
}
func (f *FakeHandler) SetResponseBody(responseBody string) {
f.lock.Lock()
defer f.lock.Unlock()
f.ResponseBody = responseBody
} }
func (f *FakeHandler) ServeHTTP(response http.ResponseWriter, request *http.Request) { func (f *FakeHandler) ServeHTTP(response http.ResponseWriter, request *http.Request) {
f.lock.Lock() f.lock.Lock()
defer f.lock.Unlock() defer f.lock.Unlock()
if f.SkipRequestFn != nil && f.SkipRequestFn(request.Method, *request.URL) {
response.Header().Set("Content-Type", "application/json")
response.WriteHeader(f.StatusCode)
response.Write([]byte(f.ResponseBody))
return
}
f.requestCount++ f.requestCount++
if f.hasBeenChecked { if f.hasBeenChecked {
panic("got request after having been validated") panic("got request after having been validated")
......
...@@ -127,7 +127,7 @@ func verifyRemainingObjects(t *testing.T, clientSet clientset.Interface, namespa ...@@ -127,7 +127,7 @@ func verifyRemainingObjects(t *testing.T, clientSet clientset.Interface, namespa
return ret, nil return ret, nil
} }
func rmSetup(t *testing.T, enableGarbageCollector bool) (*httptest.Server, *replicaset.ReplicaSetController, cache.SharedIndexInformer, clientset.Interface) { func rmSetup(t *testing.T, enableGarbageCollector bool) (*httptest.Server, *replicaset.ReplicaSetController, cache.SharedIndexInformer, cache.SharedIndexInformer, clientset.Interface) {
masterConfig := framework.NewIntegrationTestMasterConfig() masterConfig := framework.NewIntegrationTestMasterConfig()
_, s := framework.RunAMaster(masterConfig) _, s := framework.RunAMaster(masterConfig)
...@@ -137,14 +137,12 @@ func rmSetup(t *testing.T, enableGarbageCollector bool) (*httptest.Server, *repl ...@@ -137,14 +137,12 @@ func rmSetup(t *testing.T, enableGarbageCollector bool) (*httptest.Server, *repl
t.Fatalf("Error in create clientset: %v", err) t.Fatalf("Error in create clientset: %v", err)
} }
resyncPeriod := 12 * time.Hour resyncPeriod := 12 * time.Hour
resyncPeriodFunc := func() time.Duration { informers := informers.NewSharedInformerFactory(internalclientset.NewForConfigOrDie(restclient.AddUserAgent(&config, "rs-informers")), resyncPeriod)
return resyncPeriod
}
podInformer := informers.NewPodInformer(internalclientset.NewForConfigOrDie(restclient.AddUserAgent(&config, "pod-informer")), resyncPeriod)
rm := replicaset.NewReplicaSetController( rm := replicaset.NewReplicaSetController(
podInformer, informers.ReplicaSets(),
informers.Pods(),
internalclientset.NewForConfigOrDie(restclient.AddUserAgent(&config, "replicaset-controller")), internalclientset.NewForConfigOrDie(restclient.AddUserAgent(&config, "replicaset-controller")),
resyncPeriodFunc,
replicaset.BurstReplicas, replicaset.BurstReplicas,
4096, 4096,
enableGarbageCollector, enableGarbageCollector,
...@@ -153,7 +151,7 @@ func rmSetup(t *testing.T, enableGarbageCollector bool) (*httptest.Server, *repl ...@@ -153,7 +151,7 @@ func rmSetup(t *testing.T, enableGarbageCollector bool) (*httptest.Server, *repl
if err != nil { if err != nil {
t.Fatalf("Failed to create replicaset controller") t.Fatalf("Failed to create replicaset controller")
} }
return s, rm, podInformer, clientSet return s, rm, informers.ReplicaSets().Informer(), informers.Pods().Informer(), clientSet
} }
// wait for the podInformer to observe the pods. Call this function before // wait for the podInformer to observe the pods. Call this function before
...@@ -223,7 +221,7 @@ func TestAdoption(t *testing.T) { ...@@ -223,7 +221,7 @@ func TestAdoption(t *testing.T) {
}, },
} }
for i, tc := range testCases { for i, tc := range testCases {
s, rm, podInformer, clientSet := rmSetup(t, true) s, rm, rsInformer, podInformer, clientSet := rmSetup(t, true)
ns := framework.CreateTestingNamespace(fmt.Sprintf("rs-adoption-%d", i), s, t) ns := framework.CreateTestingNamespace(fmt.Sprintf("rs-adoption-%d", i), s, t)
defer framework.DeleteTestingNamespace(ns, s, t) defer framework.DeleteTestingNamespace(ns, s, t)
...@@ -243,6 +241,7 @@ func TestAdoption(t *testing.T) { ...@@ -243,6 +241,7 @@ func TestAdoption(t *testing.T) {
} }
stopCh := make(chan struct{}) stopCh := make(chan struct{})
go rsInformer.Run(stopCh)
go podInformer.Run(stopCh) go podInformer.Run(stopCh)
waitToObservePods(t, podInformer, 1) waitToObservePods(t, podInformer, 1)
go rm.Run(5, stopCh) go rm.Run(5, stopCh)
...@@ -300,7 +299,7 @@ func TestUpdateSelectorToAdopt(t *testing.T) { ...@@ -300,7 +299,7 @@ func TestUpdateSelectorToAdopt(t *testing.T) {
// We have pod1, pod2 and rs. rs.spec.replicas=1. At first rs.Selector // We have pod1, pod2 and rs. rs.spec.replicas=1. At first rs.Selector
// matches pod1 only; change the selector to match pod2 as well. Verify // matches pod1 only; change the selector to match pod2 as well. Verify
// there is only one pod left. // there is only one pod left.
s, rm, podInformer, clientSet := rmSetup(t, true) s, rm, rsInformer, podInformer, clientSet := rmSetup(t, true)
ns := framework.CreateTestingNamespace("rs-update-selector-to-adopt", s, t) ns := framework.CreateTestingNamespace("rs-update-selector-to-adopt", s, t)
defer framework.DeleteTestingNamespace(ns, s, t) defer framework.DeleteTestingNamespace(ns, s, t)
rs := newRS("rs", ns.Name, 1) rs := newRS("rs", ns.Name, 1)
...@@ -314,6 +313,7 @@ func TestUpdateSelectorToAdopt(t *testing.T) { ...@@ -314,6 +313,7 @@ func TestUpdateSelectorToAdopt(t *testing.T) {
createRSsPods(t, clientSet, []*v1beta1.ReplicaSet{rs}, []*v1.Pod{pod1, pod2}, ns.Name) createRSsPods(t, clientSet, []*v1beta1.ReplicaSet{rs}, []*v1.Pod{pod1, pod2}, ns.Name)
stopCh := make(chan struct{}) stopCh := make(chan struct{})
go rsInformer.Run(stopCh)
go podInformer.Run(stopCh) go podInformer.Run(stopCh)
go rm.Run(5, stopCh) go rm.Run(5, stopCh)
waitRSStable(t, clientSet, rs, ns.Name) waitRSStable(t, clientSet, rs, ns.Name)
...@@ -340,7 +340,7 @@ func TestUpdateSelectorToRemoveControllerRef(t *testing.T) { ...@@ -340,7 +340,7 @@ func TestUpdateSelectorToRemoveControllerRef(t *testing.T) {
// matches pod1 and pod2; change the selector to match only pod1. Verify // matches pod1 and pod2; change the selector to match only pod1. Verify
// that rs creates one more pod, so there are 3 pods. Also verify that // that rs creates one more pod, so there are 3 pods. Also verify that
// pod2's controllerRef is cleared. // pod2's controllerRef is cleared.
s, rm, podInformer, clientSet := rmSetup(t, true) s, rm, rsInformer, podInformer, clientSet := rmSetup(t, true)
ns := framework.CreateTestingNamespace("rs-update-selector-to-remove-controllerref", s, t) ns := framework.CreateTestingNamespace("rs-update-selector-to-remove-controllerref", s, t)
defer framework.DeleteTestingNamespace(ns, s, t) defer framework.DeleteTestingNamespace(ns, s, t)
rs := newRS("rs", ns.Name, 2) rs := newRS("rs", ns.Name, 2)
...@@ -351,6 +351,7 @@ func TestUpdateSelectorToRemoveControllerRef(t *testing.T) { ...@@ -351,6 +351,7 @@ func TestUpdateSelectorToRemoveControllerRef(t *testing.T) {
createRSsPods(t, clientSet, []*v1beta1.ReplicaSet{rs}, []*v1.Pod{pod1, pod2}, ns.Name) createRSsPods(t, clientSet, []*v1beta1.ReplicaSet{rs}, []*v1.Pod{pod1, pod2}, ns.Name)
stopCh := make(chan struct{}) stopCh := make(chan struct{})
go rsInformer.Run(stopCh)
go podInformer.Run(stopCh) go podInformer.Run(stopCh)
waitToObservePods(t, podInformer, 2) waitToObservePods(t, podInformer, 2)
go rm.Run(5, stopCh) go rm.Run(5, stopCh)
...@@ -386,7 +387,7 @@ func TestUpdateLabelToRemoveControllerRef(t *testing.T) { ...@@ -386,7 +387,7 @@ func TestUpdateLabelToRemoveControllerRef(t *testing.T) {
// matches pod1 and pod2; change pod2's labels to non-matching. Verify // matches pod1 and pod2; change pod2's labels to non-matching. Verify
// that rs creates one more pod, so there are 3 pods. Also verify that // that rs creates one more pod, so there are 3 pods. Also verify that
// pod2's controllerRef is cleared. // pod2's controllerRef is cleared.
s, rm, podInformer, clientSet := rmSetup(t, true) s, rm, rsInformer, podInformer, clientSet := rmSetup(t, true)
ns := framework.CreateTestingNamespace("rs-update-label-to-remove-controllerref", s, t) ns := framework.CreateTestingNamespace("rs-update-label-to-remove-controllerref", s, t)
defer framework.DeleteTestingNamespace(ns, s, t) defer framework.DeleteTestingNamespace(ns, s, t)
rs := newRS("rs", ns.Name, 2) rs := newRS("rs", ns.Name, 2)
...@@ -395,6 +396,7 @@ func TestUpdateLabelToRemoveControllerRef(t *testing.T) { ...@@ -395,6 +396,7 @@ func TestUpdateLabelToRemoveControllerRef(t *testing.T) {
createRSsPods(t, clientSet, []*v1beta1.ReplicaSet{rs}, []*v1.Pod{pod1, pod2}, ns.Name) createRSsPods(t, clientSet, []*v1beta1.ReplicaSet{rs}, []*v1.Pod{pod1, pod2}, ns.Name)
stopCh := make(chan struct{}) stopCh := make(chan struct{})
go rsInformer.Run(stopCh)
go podInformer.Run(stopCh) go podInformer.Run(stopCh)
go rm.Run(5, stopCh) go rm.Run(5, stopCh)
waitRSStable(t, clientSet, rs, ns.Name) waitRSStable(t, clientSet, rs, ns.Name)
...@@ -428,7 +430,7 @@ func TestUpdateLabelToBeAdopted(t *testing.T) { ...@@ -428,7 +430,7 @@ func TestUpdateLabelToBeAdopted(t *testing.T) {
// matches pod1 only; change pod2's labels to be matching. Verify the RS // matches pod1 only; change pod2's labels to be matching. Verify the RS
// controller adopts pod2 and delete one of them, so there is only 1 pod // controller adopts pod2 and delete one of them, so there is only 1 pod
// left. // left.
s, rm, podInformer, clientSet := rmSetup(t, true) s, rm, rsInformer, podInformer, clientSet := rmSetup(t, true)
ns := framework.CreateTestingNamespace("rs-update-label-to-be-adopted", s, t) ns := framework.CreateTestingNamespace("rs-update-label-to-be-adopted", s, t)
defer framework.DeleteTestingNamespace(ns, s, t) defer framework.DeleteTestingNamespace(ns, s, t)
rs := newRS("rs", ns.Name, 1) rs := newRS("rs", ns.Name, 1)
...@@ -442,6 +444,7 @@ func TestUpdateLabelToBeAdopted(t *testing.T) { ...@@ -442,6 +444,7 @@ func TestUpdateLabelToBeAdopted(t *testing.T) {
createRSsPods(t, clientSet, []*v1beta1.ReplicaSet{rs}, []*v1.Pod{pod1, pod2}, ns.Name) createRSsPods(t, clientSet, []*v1beta1.ReplicaSet{rs}, []*v1.Pod{pod1, pod2}, ns.Name)
stopCh := make(chan struct{}) stopCh := make(chan struct{})
go rsInformer.Run(stopCh)
go podInformer.Run(stopCh) go podInformer.Run(stopCh)
go rm.Run(5, stopCh) go rm.Run(5, stopCh)
waitRSStable(t, clientSet, rs, ns.Name) waitRSStable(t, clientSet, rs, ns.Name)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment