Skip to content

Commit 42e2346

Browse files
committed
run kube controllers separately based on their command
1 parent 76d8825 commit 42e2346

File tree

3 files changed

+189
-43
lines changed

3 files changed

+189
-43
lines changed

pkg/cmd/server/start/start_kube_controller_manager.go

+155-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,24 @@
11
package start
22

33
import (
4-
"github.com/openshift/origin/pkg/cmd/server/bootstrappolicy"
4+
"strconv"
5+
6+
"github.com/golang/glog"
7+
"github.com/spf13/pflag"
8+
9+
kerrors "k8s.io/apimachinery/pkg/util/errors"
10+
controllerapp "k8s.io/kubernetes/cmd/kube-controller-manager/app"
11+
controlleroptions "k8s.io/kubernetes/cmd/kube-controller-manager/app/options"
512
"k8s.io/kubernetes/pkg/api/v1"
613
kapiv1 "k8s.io/kubernetes/pkg/api/v1"
14+
kubeexternalinformers "k8s.io/kubernetes/pkg/client/informers/informers_generated/externalversions"
15+
"k8s.io/kubernetes/pkg/controller"
716
"k8s.io/kubernetes/pkg/volume"
17+
_ "k8s.io/kubernetes/plugin/pkg/scheduler/algorithmprovider"
18+
19+
"github.com/openshift/origin/pkg/cmd/server/bootstrappolicy"
20+
cmdflags "github.com/openshift/origin/pkg/cmd/util/flags"
21+
"k8s.io/kubernetes/pkg/apis/componentconfig"
822
)
923

1024
// newPersistentVolumeRecyclerPodTemplate provides a function which makes our recycler pod template for use in the kube-controller-manager
@@ -26,3 +40,143 @@ func newPersistentVolumeRecyclerPodTemplate(recyclerImageName string) func() *v1
2640
return defaultScrubPod
2741
}
2842
}
43+
44+
// newControllerContext provides a function which overrides the default and plugs a different set of informers in
45+
func newControllerContext(kubeExternalInformers kubeexternalinformers.SharedInformerFactory) func(s *controlleroptions.CMServer, rootClientBuilder, clientBuilder controller.ControllerClientBuilder, stop <-chan struct{}) (controllerapp.ControllerContext, error) {
46+
oldContextFunc := controllerapp.CreateControllerContext
47+
return func(s *controlleroptions.CMServer, rootClientBuilder, clientBuilder controller.ControllerClientBuilder, stop <-chan struct{}) (controllerapp.ControllerContext, error) {
48+
ret, err := oldContextFunc(s, rootClientBuilder, clientBuilder, stop)
49+
if err != nil {
50+
return controllerapp.ControllerContext{}, err
51+
}
52+
53+
// Overwrite the informers. Since nothing accessed the existing informers that we're overwriting, they are inert.
54+
// TODO Remove this. It keeps in-process memory utilization down, but we shouldn't do it.
55+
ret.InformerFactory = kubeExternalInformers
56+
57+
return ret, nil
58+
}
59+
}
60+
61+
func kubeControllerManagerAddFlags(cmserver *controlleroptions.CMServer) func(flags *pflag.FlagSet) {
62+
return func(flags *pflag.FlagSet) {
63+
cmserver.AddFlags(flags, controllerapp.KnownControllers(), controllerapp.ControllersDisabledByDefault.List())
64+
}
65+
}
66+
67+
func newKubeControllerManager(kubeconfigFile, saPrivateKeyFile, saRootCAFile, podEvictionTimeout string, dynamicProvisioningEnabled bool, cmdLineArgs map[string][]string) (*controlleroptions.CMServer, error) {
68+
if cmdLineArgs == nil {
69+
cmdLineArgs = map[string][]string{}
70+
}
71+
72+
if _, ok := cmdLineArgs["controllers"]; !ok {
73+
cmdLineArgs["controllers"] = []string{
74+
"*", // start everything but the exceptions}
75+
// we don't appear to use this
76+
"-ttl",
77+
// we have to configure this separately until it is generic
78+
"-horizontalpodautoscaling",
79+
// we carry patches on this. For now....
80+
"-serviceaccount-token",
81+
}
82+
}
83+
if _, ok := cmdLineArgs["service-account-private-key-file"]; !ok {
84+
cmdLineArgs["service-account-private-key-file"] = []string{saPrivateKeyFile}
85+
}
86+
if _, ok := cmdLineArgs["root-ca-file"]; !ok {
87+
cmdLineArgs["root-ca-file"] = []string{saRootCAFile}
88+
}
89+
if _, ok := cmdLineArgs["kubeconfig"]; !ok {
90+
cmdLineArgs["kubeconfig"] = []string{kubeconfigFile}
91+
}
92+
if _, ok := cmdLineArgs["pod-eviction-timeout"]; !ok {
93+
cmdLineArgs["pod-eviction-timeout"] = []string{podEvictionTimeout}
94+
}
95+
if _, ok := cmdLineArgs["enable-dynamic-provisioning"]; !ok {
96+
cmdLineArgs["enable-dynamic-provisioning"] = []string{strconv.FormatBool(dynamicProvisioningEnabled)}
97+
}
98+
99+
// disable serving http since we didn't used to expose it
100+
if _, ok := cmdLineArgs["port"]; !ok {
101+
cmdLineArgs["port"] = []string{"-1"}
102+
}
103+
104+
// these force "default" values to match what we want
105+
if _, ok := cmdLineArgs["use-service-account-credentials"]; !ok {
106+
cmdLineArgs["use-service-account-credentials"] = []string{"true"}
107+
}
108+
if _, ok := cmdLineArgs["cluster-signing-cert-file"]; !ok {
109+
cmdLineArgs["cluster-signing-cert-file"] = []string{""}
110+
}
111+
if _, ok := cmdLineArgs["cluster-signing-key-file"]; !ok {
112+
cmdLineArgs["cluster-signing-key-file"] = []string{""}
113+
}
114+
if _, ok := cmdLineArgs["experimental-cluster-signing-duration"]; !ok {
115+
cmdLineArgs["experimental-cluster-signing-duration"] = []string{"0s"}
116+
}
117+
if _, ok := cmdLineArgs["leader-elect-retry-period"]; !ok {
118+
cmdLineArgs["leader-elect-retry-period"] = []string{"3s"}
119+
}
120+
if _, ok := cmdLineArgs["leader-elect-resource-lock"]; !ok {
121+
cmdLineArgs["leader-elect-resource-lock"] = []string{"configmaps"}
122+
}
123+
124+
// resolve arguments
125+
controllerManager := controlleroptions.NewCMServer()
126+
if err := cmdflags.Resolve(cmdLineArgs, kubeControllerManagerAddFlags(controllerManager)); len(err) > 0 {
127+
return nil, kerrors.NewAggregate(err)
128+
}
129+
130+
// TODO make this configurable or discoverable. This is going to prevent us from running the stock GC controller
131+
// IF YOU ADD ANYTHING TO THIS LIST, MAKE SURE THAT YOU UPDATE THEIR STRATEGIES TO PREVENT GC FINALIZERS
132+
controllerManager.GCIgnoredResources = append(controllerManager.GCIgnoredResources,
133+
// explicitly disabled from GC for now - not enough value to track them
134+
componentconfig.GroupResource{Group: "authorization.openshift.io", Resource: "rolebindingrestrictions"},
135+
componentconfig.GroupResource{Group: "network.openshift.io", Resource: "clusternetworks"},
136+
componentconfig.GroupResource{Group: "network.openshift.io", Resource: "egressnetworkpolicies"},
137+
componentconfig.GroupResource{Group: "network.openshift.io", Resource: "hostsubnets"},
138+
componentconfig.GroupResource{Group: "network.openshift.io", Resource: "netnamespaces"},
139+
componentconfig.GroupResource{Group: "oauth.openshift.io", Resource: "oauthclientauthorizations"},
140+
componentconfig.GroupResource{Group: "oauth.openshift.io", Resource: "oauthclients"},
141+
componentconfig.GroupResource{Group: "quota.openshift.io", Resource: "clusterresourcequotas"},
142+
componentconfig.GroupResource{Group: "user.openshift.io", Resource: "groups"},
143+
componentconfig.GroupResource{Group: "user.openshift.io", Resource: "identities"},
144+
componentconfig.GroupResource{Group: "user.openshift.io", Resource: "users"},
145+
componentconfig.GroupResource{Group: "image.openshift.io", Resource: "images"},
146+
147+
// virtual resource
148+
componentconfig.GroupResource{Group: "project.openshift.io", Resource: "projects"},
149+
// these resources contain security information in their names, and we don't need to track them
150+
componentconfig.GroupResource{Group: "oauth.openshift.io", Resource: "oauthaccesstokens"},
151+
componentconfig.GroupResource{Group: "oauth.openshift.io", Resource: "oauthauthorizetokens"},
152+
// exposed already as cronjobs
153+
componentconfig.GroupResource{Group: "batch", Resource: "scheduledjobs"},
154+
// exposed already as extensions v1beta1 by other controllers
155+
componentconfig.GroupResource{Group: "apps", Resource: "deployments"},
156+
// exposed as autoscaling v1
157+
componentconfig.GroupResource{Group: "extensions", Resource: "horizontalpodautoscalers"},
158+
)
159+
160+
return controllerManager, nil
161+
}
162+
163+
func runEmbeddedKubeControllerManager(kubeconfigFile, saPrivateKeyFile, saRootCAFile, podEvictionTimeout string, dynamicProvisioningEnabled bool, cmdLineArgs map[string][]string,
164+
recyclerImage string, kubeExternalInformers kubeexternalinformers.SharedInformerFactory) {
165+
volume.NewPersistentVolumeRecyclerPodTemplate = newPersistentVolumeRecyclerPodTemplate(recyclerImage)
166+
controllerapp.CreateControllerContext = newControllerContext(kubeExternalInformers)
167+
168+
for {
169+
// TODO we need a real identity for this. Right now it's just using the loopback connection like it used to.
170+
controllerManager, err := newKubeControllerManager(kubeconfigFile, saPrivateKeyFile, saRootCAFile, podEvictionTimeout, dynamicProvisioningEnabled, cmdLineArgs)
171+
if err != nil {
172+
glog.Error(err)
173+
continue
174+
}
175+
// this does a second leader election, but doing the second leader election will allow us to move out process in
176+
// 3.8 if we so choose.
177+
if err := controllerapp.Run(controllerManager); err != nil {
178+
glog.Error(err)
179+
continue
180+
}
181+
}
182+
}

pkg/cmd/server/start/start_master.go

+13-23
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,13 @@ import (
2727
clientgoclientset "k8s.io/client-go/kubernetes"
2828
"k8s.io/client-go/tools/cache"
2929
aggregatorinstall "k8s.io/kube-aggregator/pkg/apis/apiregistration/install"
30-
kubecontroller "k8s.io/kubernetes/cmd/kube-controller-manager/app"
3130
kapi "k8s.io/kubernetes/pkg/api"
3231
"k8s.io/kubernetes/pkg/capabilities"
3332
kinformers "k8s.io/kubernetes/pkg/client/informers/informers_generated/externalversions"
3433
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
3534
kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
3635
kubelettypes "k8s.io/kubernetes/pkg/kubelet/types"
3736
"k8s.io/kubernetes/pkg/master"
38-
"k8s.io/kubernetes/pkg/volume"
3937
kutilerrors "k8s.io/kubernetes/staging/src/k8s.io/apimachinery/pkg/util/errors"
4038

4139
assetapiserver "github.com/openshift/origin/pkg/assets/apiserver"
@@ -410,10 +408,10 @@ func (m *Master) Start() error {
410408
imageTemplate := variable.NewDefaultImageTemplate()
411409
imageTemplate.Format = m.config.ImageConfig.Format
412410
imageTemplate.Latest = m.config.ImageConfig.Latest
413-
volume.NewPersistentVolumeRecyclerPodTemplate = newPersistentVolumeRecyclerPodTemplate(imageTemplate.ExpandOrDie("recycler"))
411+
recyclerImage := imageTemplate.ExpandOrDie("recycler")
414412

413+
// you can't double run healthz, so only do this next bit if we aren't starting the API
415414
if !m.api {
416-
// you can't double run healthz, so only do this next bit if we aren't starting the API
417415

418416
glog.Infof("Starting controllers on %s (%s)", m.config.ServingInfo.BindAddress, version.Get().String())
419417
if len(m.config.DisabledFeatures) > 0 {
@@ -478,6 +476,16 @@ func (m *Master) Start() error {
478476
// continuously run the scheduler while we have the primary lease
479477
go runEmbeddedScheduler(m.config.MasterClients.OpenShiftLoopbackKubeConfig, m.config.KubernetesMasterConfig.SchedulerConfigFile, m.config.KubernetesMasterConfig.SchedulerArguments)
480478

479+
go runEmbeddedKubeControllerManager(
480+
m.config.MasterClients.OpenShiftLoopbackKubeConfig,
481+
m.config.ServiceAccountConfig.PrivateKeyFile,
482+
m.config.ServiceAccountConfig.MasterCA,
483+
m.config.KubernetesMasterConfig.PodEvictionTimeout,
484+
m.config.VolumeConfig.DynamicProvisioningEnabled,
485+
m.config.KubernetesMasterConfig.ControllerArguments,
486+
recyclerImage,
487+
informers.GetExternalKubeInformers())
488+
481489
controllerContext, err := getControllerContext(*m.config, kubeControllerManagerConfig, cloudProvider, informers, utilwait.NeverStop)
482490
if err != nil {
483491
glog.Fatal(err)
@@ -702,20 +710,10 @@ func startControllers(options configapi.MasterConfig, allocationController origi
702710

703711
allocationController.RunSecurityAllocationController()
704712

705-
// set the upstream default until it is configurable
706-
kubernetesControllerInitializers := kubecontroller.NewControllerInitializers()
707713
openshiftControllerInitializers, err := openshiftControllerConfig.GetControllerInitializers()
708714
if err != nil {
709715
return err
710716
}
711-
// Add kubernetes controllers initialized from Origin
712-
for name, initFn := range kubernetesControllerInitializers {
713-
if _, exists := openshiftControllerInitializers[name]; exists {
714-
// don't overwrite, openshift takes priority
715-
continue
716-
}
717-
openshiftControllerInitializers[name] = origincontrollers.FromKubeInitFunc(initFn)
718-
}
719717

720718
excludedControllers := getExcludedControllers(options)
721719

@@ -749,19 +747,11 @@ func startControllers(options configapi.MasterConfig, allocationController origi
749747
}
750748

751749
func getExcludedControllers(options configapi.MasterConfig) sets.String {
752-
excludedControllers := sets.NewString(
753-
// not used in openshift. Yet?
754-
"ttl",
755-
"bootstrapsigner",
756-
"tokencleaner",
757-
// remove the HPA controller until it is generic
758-
"horizontalpodautoscaling",
759-
)
750+
excludedControllers := sets.NewString()
760751
if !configapi.IsBuildEnabled(&options) {
761752
excludedControllers.Insert("openshift.io/build")
762753
excludedControllers.Insert("openshift.io/build-config-change")
763754
}
764-
765755
return excludedControllers
766756
}
767757

vendor/k8s.io/kubernetes/cmd/kube-controller-manager/app/controllermanager.go

+21-19
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)