mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-03 09:22:44 +00:00
Merge pull request #120371 from atiratree/encapsulate-kcm-controllers
Encapsulate KCM controllers with their metadata
This commit is contained in:
commit
ee474e6ec5
@ -27,13 +27,21 @@ import (
|
|||||||
"k8s.io/client-go/util/flowcontrol"
|
"k8s.io/client-go/util/flowcontrol"
|
||||||
"k8s.io/controller-manager/controller"
|
"k8s.io/controller-manager/controller"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
|
"k8s.io/kubernetes/cmd/kube-controller-manager/names"
|
||||||
"k8s.io/kubernetes/pkg/controller/daemon"
|
"k8s.io/kubernetes/pkg/controller/daemon"
|
||||||
"k8s.io/kubernetes/pkg/controller/deployment"
|
"k8s.io/kubernetes/pkg/controller/deployment"
|
||||||
"k8s.io/kubernetes/pkg/controller/replicaset"
|
"k8s.io/kubernetes/pkg/controller/replicaset"
|
||||||
"k8s.io/kubernetes/pkg/controller/statefulset"
|
"k8s.io/kubernetes/pkg/controller/statefulset"
|
||||||
)
|
)
|
||||||
|
|
||||||
func startDaemonSetController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newDaemonSetControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.DaemonSetController,
|
||||||
|
aliases: []string{"daemonset"},
|
||||||
|
initFunc: startDaemonSetController,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func startDaemonSetController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
dsc, err := daemon.NewDaemonSetsController(
|
dsc, err := daemon.NewDaemonSetsController(
|
||||||
ctx,
|
ctx,
|
||||||
controllerContext.InformerFactory.Apps().V1().DaemonSets(),
|
controllerContext.InformerFactory.Apps().V1().DaemonSets(),
|
||||||
@ -50,7 +58,14 @@ func startDaemonSetController(ctx context.Context, controllerContext ControllerC
|
|||||||
return nil, true, nil
|
return nil, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func startStatefulSetController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newStatefulSetControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.StatefulSetController,
|
||||||
|
aliases: []string{"statefulset"},
|
||||||
|
initFunc: startStatefulSetController,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func startStatefulSetController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
go statefulset.NewStatefulSetController(
|
go statefulset.NewStatefulSetController(
|
||||||
ctx,
|
ctx,
|
||||||
controllerContext.InformerFactory.Core().V1().Pods(),
|
controllerContext.InformerFactory.Core().V1().Pods(),
|
||||||
@ -62,7 +77,15 @@ func startStatefulSetController(ctx context.Context, controllerContext Controlle
|
|||||||
return nil, true, nil
|
return nil, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func startReplicaSetController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newReplicaSetControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.ReplicaSetController,
|
||||||
|
aliases: []string{"replicaset"},
|
||||||
|
initFunc: startReplicaSetController,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startReplicaSetController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
go replicaset.NewReplicaSetController(
|
go replicaset.NewReplicaSetController(
|
||||||
klog.FromContext(ctx),
|
klog.FromContext(ctx),
|
||||||
controllerContext.InformerFactory.Apps().V1().ReplicaSets(),
|
controllerContext.InformerFactory.Apps().V1().ReplicaSets(),
|
||||||
@ -73,7 +96,15 @@ func startReplicaSetController(ctx context.Context, controllerContext Controller
|
|||||||
return nil, true, nil
|
return nil, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func startDeploymentController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newDeploymentControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.DeploymentController,
|
||||||
|
aliases: []string{"deployment"},
|
||||||
|
initFunc: startDeploymentController,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startDeploymentController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
dc, err := deployment.NewDeploymentController(
|
dc, err := deployment.NewDeploymentController(
|
||||||
ctx,
|
ctx,
|
||||||
controllerContext.InformerFactory.Apps().V1().Deployments(),
|
controllerContext.InformerFactory.Apps().V1().Deployments(),
|
||||||
|
@ -26,6 +26,7 @@ import (
|
|||||||
"k8s.io/client-go/dynamic"
|
"k8s.io/client-go/dynamic"
|
||||||
"k8s.io/client-go/scale"
|
"k8s.io/client-go/scale"
|
||||||
"k8s.io/controller-manager/controller"
|
"k8s.io/controller-manager/controller"
|
||||||
|
"k8s.io/kubernetes/cmd/kube-controller-manager/names"
|
||||||
"k8s.io/kubernetes/pkg/controller/podautoscaler"
|
"k8s.io/kubernetes/pkg/controller/podautoscaler"
|
||||||
"k8s.io/kubernetes/pkg/controller/podautoscaler/metrics"
|
"k8s.io/kubernetes/pkg/controller/podautoscaler/metrics"
|
||||||
"k8s.io/kubernetes/pkg/features"
|
"k8s.io/kubernetes/pkg/features"
|
||||||
@ -35,11 +36,15 @@ import (
|
|||||||
"k8s.io/metrics/pkg/client/external_metrics"
|
"k8s.io/metrics/pkg/client/external_metrics"
|
||||||
)
|
)
|
||||||
|
|
||||||
func startHPAController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newHorizontalPodAutoscalerControllerDescriptor() *ControllerDescriptor {
|
||||||
return startHPAControllerWithRESTClient(ctx, controllerContext)
|
return &ControllerDescriptor{
|
||||||
|
name: names.HorizontalPodAutoscalerController,
|
||||||
|
aliases: []string{"horizontalpodautoscaling"},
|
||||||
|
initFunc: startHorizontalPodAutoscalerControllerWithRESTClient,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func startHPAControllerWithRESTClient(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func startHorizontalPodAutoscalerControllerWithRESTClient(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
|
|
||||||
clientConfig := controllerContext.ClientBuilder.ConfigOrDie("horizontal-pod-autoscaler")
|
clientConfig := controllerContext.ClientBuilder.ConfigOrDie("horizontal-pod-autoscaler")
|
||||||
hpaClient := controllerContext.ClientBuilder.ClientOrDie("horizontal-pod-autoscaler")
|
hpaClient := controllerContext.ClientBuilder.ClientOrDie("horizontal-pod-autoscaler")
|
||||||
|
@ -24,11 +24,20 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"k8s.io/controller-manager/controller"
|
"k8s.io/controller-manager/controller"
|
||||||
|
"k8s.io/kubernetes/cmd/kube-controller-manager/names"
|
||||||
"k8s.io/kubernetes/pkg/controller/cronjob"
|
"k8s.io/kubernetes/pkg/controller/cronjob"
|
||||||
"k8s.io/kubernetes/pkg/controller/job"
|
"k8s.io/kubernetes/pkg/controller/job"
|
||||||
)
|
)
|
||||||
|
|
||||||
func startJobController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newJobControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.JobController,
|
||||||
|
aliases: []string{"job"},
|
||||||
|
initFunc: startJobController,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startJobController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
jobController, err := job.NewController(
|
jobController, err := job.NewController(
|
||||||
ctx,
|
ctx,
|
||||||
controllerContext.InformerFactory.Core().V1().Pods(),
|
controllerContext.InformerFactory.Core().V1().Pods(),
|
||||||
@ -42,7 +51,15 @@ func startJobController(ctx context.Context, controllerContext ControllerContext
|
|||||||
return nil, true, nil
|
return nil, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func startCronJobController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newCronJobControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.CronJobController,
|
||||||
|
aliases: []string{"cronjob"},
|
||||||
|
initFunc: startCronJobController,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startCronJobController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
cj2c, err := cronjob.NewControllerV2(ctx, controllerContext.InformerFactory.Batch().V1().Jobs(),
|
cj2c, err := cronjob.NewControllerV2(ctx, controllerContext.InformerFactory.Batch().V1().Jobs(),
|
||||||
controllerContext.InformerFactory.Batch().V1().CronJobs(),
|
controllerContext.InformerFactory.Batch().V1().CronJobs(),
|
||||||
controllerContext.ClientBuilder.ClientOrDie("cronjob-controller"),
|
controllerContext.ClientBuilder.ClientOrDie("cronjob-controller"),
|
||||||
|
@ -21,10 +21,19 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"k8s.io/controller-manager/controller"
|
"k8s.io/controller-manager/controller"
|
||||||
|
"k8s.io/kubernetes/cmd/kube-controller-manager/names"
|
||||||
"k8s.io/kubernetes/pkg/controller/bootstrap"
|
"k8s.io/kubernetes/pkg/controller/bootstrap"
|
||||||
)
|
)
|
||||||
|
|
||||||
func startBootstrapSignerController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newBootstrapSignerControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.BootstrapSignerController,
|
||||||
|
aliases: []string{"bootstrapsigner"},
|
||||||
|
initFunc: startBootstrapSignerController,
|
||||||
|
isDisabledByDefault: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func startBootstrapSignerController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
bsc, err := bootstrap.NewSigner(
|
bsc, err := bootstrap.NewSigner(
|
||||||
controllerContext.ClientBuilder.ClientOrDie("bootstrap-signer"),
|
controllerContext.ClientBuilder.ClientOrDie("bootstrap-signer"),
|
||||||
controllerContext.InformerFactory.Core().V1().Secrets(),
|
controllerContext.InformerFactory.Core().V1().Secrets(),
|
||||||
@ -38,7 +47,15 @@ func startBootstrapSignerController(ctx context.Context, controllerContext Contr
|
|||||||
return nil, true, nil
|
return nil, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func startTokenCleanerController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newTokenCleanerControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.TokenCleanerController,
|
||||||
|
aliases: []string{"tokencleaner"},
|
||||||
|
initFunc: startTokenCleanerController,
|
||||||
|
isDisabledByDefault: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func startTokenCleanerController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
tcc, err := bootstrap.NewTokenCleaner(
|
tcc, err := bootstrap.NewTokenCleaner(
|
||||||
controllerContext.ClientBuilder.ClientOrDie("token-cleaner"),
|
controllerContext.ClientBuilder.ClientOrDie("token-cleaner"),
|
||||||
controllerContext.InformerFactory.Core().V1().Secrets(),
|
controllerContext.InformerFactory.Core().V1().Secrets(),
|
||||||
|
@ -25,6 +25,7 @@ import (
|
|||||||
|
|
||||||
"k8s.io/controller-manager/controller"
|
"k8s.io/controller-manager/controller"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
|
"k8s.io/kubernetes/cmd/kube-controller-manager/names"
|
||||||
"k8s.io/kubernetes/pkg/controller/certificates/approver"
|
"k8s.io/kubernetes/pkg/controller/certificates/approver"
|
||||||
"k8s.io/kubernetes/pkg/controller/certificates/cleaner"
|
"k8s.io/kubernetes/pkg/controller/certificates/cleaner"
|
||||||
"k8s.io/kubernetes/pkg/controller/certificates/rootcacertpublisher"
|
"k8s.io/kubernetes/pkg/controller/certificates/rootcacertpublisher"
|
||||||
@ -32,7 +33,15 @@ import (
|
|||||||
csrsigningconfig "k8s.io/kubernetes/pkg/controller/certificates/signer/config"
|
csrsigningconfig "k8s.io/kubernetes/pkg/controller/certificates/signer/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
func startCSRSigningController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newCertificateSigningRequestSigningControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.CertificateSigningRequestSigningController,
|
||||||
|
aliases: []string{"csrsigning"},
|
||||||
|
initFunc: startCertificateSigningRequestSigningController,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startCertificateSigningRequestSigningController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
logger := klog.FromContext(ctx)
|
logger := klog.FromContext(ctx)
|
||||||
missingSingleSigningFile := controllerContext.ComponentConfig.CSRSigningController.ClusterSigningCertFile == "" || controllerContext.ComponentConfig.CSRSigningController.ClusterSigningKeyFile == ""
|
missingSingleSigningFile := controllerContext.ComponentConfig.CSRSigningController.ClusterSigningCertFile == "" || controllerContext.ComponentConfig.CSRSigningController.ClusterSigningKeyFile == ""
|
||||||
if missingSingleSigningFile && !anySpecificFilesSet(controllerContext.ComponentConfig.CSRSigningController) {
|
if missingSingleSigningFile && !anySpecificFilesSet(controllerContext.ComponentConfig.CSRSigningController) {
|
||||||
@ -148,7 +157,14 @@ func getLegacyUnknownSignerFiles(config csrsigningconfig.CSRSigningControllerCon
|
|||||||
return config.ClusterSigningCertFile, config.ClusterSigningKeyFile
|
return config.ClusterSigningCertFile, config.ClusterSigningKeyFile
|
||||||
}
|
}
|
||||||
|
|
||||||
func startCSRApprovingController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newCertificateSigningRequestApprovingControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.CertificateSigningRequestApprovingController,
|
||||||
|
aliases: []string{"csrapproving"},
|
||||||
|
initFunc: startCertificateSigningRequestApprovingController,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func startCertificateSigningRequestApprovingController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
approver := approver.NewCSRApprovingController(
|
approver := approver.NewCSRApprovingController(
|
||||||
ctx,
|
ctx,
|
||||||
controllerContext.ClientBuilder.ClientOrDie("certificate-controller"),
|
controllerContext.ClientBuilder.ClientOrDie("certificate-controller"),
|
||||||
@ -159,7 +175,14 @@ func startCSRApprovingController(ctx context.Context, controllerContext Controll
|
|||||||
return nil, true, nil
|
return nil, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func startCSRCleanerController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newCertificateSigningRequestCleanerControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.CertificateSigningRequestCleanerController,
|
||||||
|
aliases: []string{"csrcleaner"},
|
||||||
|
initFunc: startCertificateSigningRequestCleanerController,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func startCertificateSigningRequestCleanerController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
cleaner := cleaner.NewCSRCleanerController(
|
cleaner := cleaner.NewCSRCleanerController(
|
||||||
controllerContext.ClientBuilder.ClientOrDie("certificate-controller").CertificatesV1().CertificateSigningRequests(),
|
controllerContext.ClientBuilder.ClientOrDie("certificate-controller").CertificatesV1().CertificateSigningRequests(),
|
||||||
controllerContext.InformerFactory.Certificates().V1().CertificateSigningRequests(),
|
controllerContext.InformerFactory.Certificates().V1().CertificateSigningRequests(),
|
||||||
@ -168,7 +191,15 @@ func startCSRCleanerController(ctx context.Context, controllerContext Controller
|
|||||||
return nil, true, nil
|
return nil, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func startRootCACertPublisher(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newRootCACertificatePublisherControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.RootCACertificatePublisherController,
|
||||||
|
aliases: []string{"root-ca-cert-publisher"},
|
||||||
|
initFunc: startRootCACertificatePublisherController,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startRootCACertificatePublisherController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
var (
|
var (
|
||||||
rootCA []byte
|
rootCA []byte
|
||||||
err error
|
err error
|
||||||
|
@ -25,6 +25,7 @@ import (
|
|||||||
"math/rand"
|
"math/rand"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"sort"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
@ -35,7 +36,6 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
"k8s.io/apimachinery/pkg/util/uuid"
|
"k8s.io/apimachinery/pkg/util/uuid"
|
||||||
"k8s.io/apimachinery/pkg/util/wait"
|
"k8s.io/apimachinery/pkg/util/wait"
|
||||||
genericfeatures "k8s.io/apiserver/pkg/features"
|
|
||||||
"k8s.io/apiserver/pkg/server/healthz"
|
"k8s.io/apiserver/pkg/server/healthz"
|
||||||
"k8s.io/apiserver/pkg/server/mux"
|
"k8s.io/apiserver/pkg/server/mux"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
@ -51,10 +51,10 @@ import (
|
|||||||
certutil "k8s.io/client-go/util/cert"
|
certutil "k8s.io/client-go/util/cert"
|
||||||
"k8s.io/client-go/util/keyutil"
|
"k8s.io/client-go/util/keyutil"
|
||||||
cloudprovider "k8s.io/cloud-provider"
|
cloudprovider "k8s.io/cloud-provider"
|
||||||
cpnames "k8s.io/cloud-provider/names"
|
|
||||||
cliflag "k8s.io/component-base/cli/flag"
|
cliflag "k8s.io/component-base/cli/flag"
|
||||||
"k8s.io/component-base/cli/globalflag"
|
"k8s.io/component-base/cli/globalflag"
|
||||||
"k8s.io/component-base/configz"
|
"k8s.io/component-base/configz"
|
||||||
|
"k8s.io/component-base/featuregate"
|
||||||
"k8s.io/component-base/logs"
|
"k8s.io/component-base/logs"
|
||||||
logsapi "k8s.io/component-base/logs/api/v1"
|
logsapi "k8s.io/component-base/logs/api/v1"
|
||||||
"k8s.io/component-base/metrics/features"
|
"k8s.io/component-base/metrics/features"
|
||||||
@ -70,8 +70,6 @@ import (
|
|||||||
"k8s.io/controller-manager/pkg/informerfactory"
|
"k8s.io/controller-manager/pkg/informerfactory"
|
||||||
"k8s.io/controller-manager/pkg/leadermigration"
|
"k8s.io/controller-manager/pkg/leadermigration"
|
||||||
"k8s.io/klog/v2"
|
"k8s.io/klog/v2"
|
||||||
kubefeatures "k8s.io/kubernetes/pkg/features"
|
|
||||||
|
|
||||||
"k8s.io/kubernetes/cmd/kube-controller-manager/app/config"
|
"k8s.io/kubernetes/cmd/kube-controller-manager/app/config"
|
||||||
"k8s.io/kubernetes/cmd/kube-controller-manager/app/options"
|
"k8s.io/kubernetes/cmd/kube-controller-manager/app/options"
|
||||||
"k8s.io/kubernetes/cmd/kube-controller-manager/names"
|
"k8s.io/kubernetes/cmd/kube-controller-manager/names"
|
||||||
@ -137,7 +135,7 @@ controller, and serviceaccounts controller.`,
|
|||||||
}
|
}
|
||||||
cliflag.PrintFlags(cmd.Flags())
|
cliflag.PrintFlags(cmd.Flags())
|
||||||
|
|
||||||
c, err := s.Config(KnownControllers(), ControllersDisabledByDefault.List(), names.KCMControllerAliases())
|
c, err := s.Config(KnownControllers(), ControllersDisabledByDefault(), ControllerAliases())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -156,7 +154,7 @@ controller, and serviceaccounts controller.`,
|
|||||||
}
|
}
|
||||||
|
|
||||||
fs := cmd.Flags()
|
fs := cmd.Flags()
|
||||||
namedFlagSets := s.Flags(KnownControllers(), ControllersDisabledByDefault.List(), names.KCMControllerAliases())
|
namedFlagSets := s.Flags(KnownControllers(), ControllersDisabledByDefault(), ControllerAliases())
|
||||||
verflag.AddFlags(namedFlagSets.FlagSet("global"))
|
verflag.AddFlags(namedFlagSets.FlagSet("global"))
|
||||||
globalflag.AddGlobalFlags(namedFlagSets.FlagSet("global"), cmd.Name(), logs.SkipLoggingConfigurationFlags())
|
globalflag.AddGlobalFlags(namedFlagSets.FlagSet("global"), cmd.Name(), logs.SkipLoggingConfigurationFlags())
|
||||||
registerLegacyGlobalFlags(namedFlagSets)
|
registerLegacyGlobalFlags(namedFlagSets)
|
||||||
@ -226,16 +224,16 @@ func Run(ctx context.Context, c *config.CompletedConfig) error {
|
|||||||
|
|
||||||
clientBuilder, rootClientBuilder := createClientBuilders(logger, c)
|
clientBuilder, rootClientBuilder := createClientBuilders(logger, c)
|
||||||
|
|
||||||
saTokenControllerInitFunc := serviceAccountTokenControllerStarter{rootClientBuilder: rootClientBuilder}.startServiceAccountTokenController
|
saTokenControllerDescriptor := newServiceAccountTokenControllerDescriptor(rootClientBuilder)
|
||||||
|
|
||||||
run := func(ctx context.Context, startSATokenController InitFunc, initializersFunc ControllerInitializersFunc) {
|
run := func(ctx context.Context, controllerDescriptors map[string]*ControllerDescriptor) {
|
||||||
controllerContext, err := CreateControllerContext(logger, c, rootClientBuilder, clientBuilder, ctx.Done())
|
controllerContext, err := CreateControllerContext(logger, c, rootClientBuilder, clientBuilder, ctx.Done())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(err, "Error building controller context")
|
logger.Error(err, "Error building controller context")
|
||||||
klog.FlushAndExit(klog.ExitFlushTimeout, 1)
|
klog.FlushAndExit(klog.ExitFlushTimeout, 1)
|
||||||
}
|
}
|
||||||
controllerInitializers := initializersFunc(controllerContext.LoopMode)
|
|
||||||
if err := StartControllers(ctx, controllerContext, startSATokenController, controllerInitializers, unsecuredMux, healthzHandler); err != nil {
|
if err := StartControllers(ctx, controllerContext, controllerDescriptors, unsecuredMux, healthzHandler); err != nil {
|
||||||
logger.Error(err, "Error starting controllers")
|
logger.Error(err, "Error starting controllers")
|
||||||
klog.FlushAndExit(klog.ExitFlushTimeout, 1)
|
klog.FlushAndExit(klog.ExitFlushTimeout, 1)
|
||||||
}
|
}
|
||||||
@ -249,7 +247,9 @@ func Run(ctx context.Context, c *config.CompletedConfig) error {
|
|||||||
|
|
||||||
// No leader election, run directly
|
// No leader election, run directly
|
||||||
if !c.ComponentConfig.Generic.LeaderElection.LeaderElect {
|
if !c.ComponentConfig.Generic.LeaderElection.LeaderElect {
|
||||||
run(ctx, saTokenControllerInitFunc, NewControllerInitializers)
|
controllerDescriptors := NewControllerDescriptors()
|
||||||
|
controllerDescriptors[names.ServiceAccountTokenController] = saTokenControllerDescriptor
|
||||||
|
run(ctx, controllerDescriptors)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,9 +264,6 @@ func Run(ctx context.Context, c *config.CompletedConfig) error {
|
|||||||
// leaderMigrator will be non-nil if and only if Leader Migration is enabled.
|
// leaderMigrator will be non-nil if and only if Leader Migration is enabled.
|
||||||
var leaderMigrator *leadermigration.LeaderMigrator = nil
|
var leaderMigrator *leadermigration.LeaderMigrator = nil
|
||||||
|
|
||||||
// startSATokenController will be original saTokenControllerInitFunc if leader migration is not enabled.
|
|
||||||
startSATokenController := saTokenControllerInitFunc
|
|
||||||
|
|
||||||
// If leader migration is enabled, create the LeaderMigrator and prepare for migration
|
// If leader migration is enabled, create the LeaderMigrator and prepare for migration
|
||||||
if leadermigration.Enabled(&c.ComponentConfig.Generic) {
|
if leadermigration.Enabled(&c.ComponentConfig.Generic) {
|
||||||
logger.Info("starting leader migration")
|
logger.Info("starting leader migration")
|
||||||
@ -274,11 +271,14 @@ func Run(ctx context.Context, c *config.CompletedConfig) error {
|
|||||||
leaderMigrator = leadermigration.NewLeaderMigrator(&c.ComponentConfig.Generic.LeaderMigration,
|
leaderMigrator = leadermigration.NewLeaderMigrator(&c.ComponentConfig.Generic.LeaderMigration,
|
||||||
"kube-controller-manager")
|
"kube-controller-manager")
|
||||||
|
|
||||||
// Wrap saTokenControllerInitFunc to signal readiness for migration after starting
|
// startSATokenControllerInit is the original InitFunc.
|
||||||
|
startSATokenControllerInit := saTokenControllerDescriptor.GetInitFunc()
|
||||||
|
|
||||||
|
// Wrap saTokenControllerDescriptor to signal readiness for migration after starting
|
||||||
// the controller.
|
// the controller.
|
||||||
startSATokenController = func(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
saTokenControllerDescriptor.initFunc = func(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
defer close(leaderMigrator.MigrationReady)
|
defer close(leaderMigrator.MigrationReady)
|
||||||
return saTokenControllerInitFunc(ctx, controllerContext)
|
return startSATokenControllerInit(ctx, controllerContext, controllerName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,14 +288,15 @@ func Run(ctx context.Context, c *config.CompletedConfig) error {
|
|||||||
c.ComponentConfig.Generic.LeaderElection.ResourceName,
|
c.ComponentConfig.Generic.LeaderElection.ResourceName,
|
||||||
leaderelection.LeaderCallbacks{
|
leaderelection.LeaderCallbacks{
|
||||||
OnStartedLeading: func(ctx context.Context) {
|
OnStartedLeading: func(ctx context.Context) {
|
||||||
initializersFunc := NewControllerInitializers
|
controllerDescriptors := NewControllerDescriptors()
|
||||||
if leaderMigrator != nil {
|
if leaderMigrator != nil {
|
||||||
// If leader migration is enabled, we should start only non-migrated controllers
|
// If leader migration is enabled, we should start only non-migrated controllers
|
||||||
// for the main lock.
|
// for the main lock.
|
||||||
initializersFunc = createInitializersFunc(leaderMigrator.FilterFunc, leadermigration.ControllerNonMigrated)
|
controllerDescriptors = filteredControllerDescriptors(controllerDescriptors, leaderMigrator.FilterFunc, leadermigration.ControllerNonMigrated)
|
||||||
logger.Info("leader migration: starting main controllers.")
|
logger.Info("leader migration: starting main controllers.")
|
||||||
}
|
}
|
||||||
run(ctx, startSATokenController, initializersFunc)
|
controllerDescriptors[names.ServiceAccountTokenController] = saTokenControllerDescriptor
|
||||||
|
run(ctx, controllerDescriptors)
|
||||||
},
|
},
|
||||||
OnStoppedLeading: func() {
|
OnStoppedLeading: func() {
|
||||||
logger.Error(nil, "leaderelection lost")
|
logger.Error(nil, "leaderelection lost")
|
||||||
@ -318,8 +319,11 @@ func Run(ctx context.Context, c *config.CompletedConfig) error {
|
|||||||
leaderelection.LeaderCallbacks{
|
leaderelection.LeaderCallbacks{
|
||||||
OnStartedLeading: func(ctx context.Context) {
|
OnStartedLeading: func(ctx context.Context) {
|
||||||
logger.Info("leader migration: starting migrated controllers.")
|
logger.Info("leader migration: starting migrated controllers.")
|
||||||
|
controllerDescriptors := NewControllerDescriptors()
|
||||||
|
controllerDescriptors = filteredControllerDescriptors(controllerDescriptors, leaderMigrator.FilterFunc, leadermigration.ControllerMigrated)
|
||||||
// DO NOT start saTokenController under migration lock
|
// DO NOT start saTokenController under migration lock
|
||||||
run(ctx, nil, createInitializersFunc(leaderMigrator.FilterFunc, leadermigration.ControllerMigrated))
|
delete(controllerDescriptors, names.ServiceAccountTokenController)
|
||||||
|
run(ctx, controllerDescriptors)
|
||||||
},
|
},
|
||||||
OnStoppedLeading: func() {
|
OnStoppedLeading: func() {
|
||||||
logger.Error(nil, "migration leaderelection lost")
|
logger.Error(nil, "migration leaderelection lost")
|
||||||
@ -377,8 +381,12 @@ type ControllerContext struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// IsControllerEnabled checks if the context's controllers enabled or not
|
// IsControllerEnabled checks if the context's controllers enabled or not
|
||||||
func (c ControllerContext) IsControllerEnabled(name string) bool {
|
func (c ControllerContext) IsControllerEnabled(controllerDescriptor *ControllerDescriptor) bool {
|
||||||
return genericcontrollermanager.IsControllerEnabled(name, ControllersDisabledByDefault, c.ComponentConfig.Generic.Controllers)
|
controllersDisabledByDefault := sets.NewString()
|
||||||
|
if controllerDescriptor.IsDisabledByDefault() {
|
||||||
|
controllersDisabledByDefault.Insert(controllerDescriptor.Name())
|
||||||
|
}
|
||||||
|
return genericcontrollermanager.IsControllerEnabled(controllerDescriptor.Name(), controllersDisabledByDefault, c.ComponentConfig.Generic.Controllers)
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitFunc is used to launch a particular controller. It returns a controller
|
// InitFunc is used to launch a particular controller. It returns a controller
|
||||||
@ -388,100 +396,171 @@ func (c ControllerContext) IsControllerEnabled(name string) bool {
|
|||||||
// that requests no additional features from the controller manager.
|
// that requests no additional features from the controller manager.
|
||||||
// Any error returned will cause the controller process to `Fatal`
|
// Any error returned will cause the controller process to `Fatal`
|
||||||
// The bool indicates whether the controller was enabled.
|
// The bool indicates whether the controller was enabled.
|
||||||
type InitFunc func(ctx context.Context, controllerCtx ControllerContext) (controller controller.Interface, enabled bool, err error)
|
type InitFunc func(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller controller.Interface, enabled bool, err error)
|
||||||
|
|
||||||
// ControllerInitializersFunc is used to create a collection of initializers
|
type ControllerDescriptor struct {
|
||||||
// given the loopMode.
|
name string
|
||||||
type ControllerInitializersFunc func(loopMode ControllerLoopMode) (initializers map[string]InitFunc)
|
initFunc InitFunc
|
||||||
|
requiredFeatureGates []featuregate.Feature
|
||||||
|
aliases []string
|
||||||
|
isDisabledByDefault bool
|
||||||
|
isCloudProviderController bool
|
||||||
|
requiresSpecialHandling bool
|
||||||
|
}
|
||||||
|
|
||||||
var _ ControllerInitializersFunc = NewControllerInitializers
|
func (r *ControllerDescriptor) Name() string {
|
||||||
|
return r.name
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ControllerDescriptor) GetInitFunc() InitFunc {
|
||||||
|
return r.initFunc
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ControllerDescriptor) GetRequiredFeatureGates() []featuregate.Feature {
|
||||||
|
return append([]featuregate.Feature(nil), r.requiredFeatureGates...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAliases returns aliases to ensure backwards compatibility and should never be removed!
|
||||||
|
// Only addition of new aliases is allowed, and only when a canonical name is changed (please see CHANGE POLICY of controller names)
|
||||||
|
func (r *ControllerDescriptor) GetAliases() []string {
|
||||||
|
return append([]string(nil), r.aliases...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ControllerDescriptor) IsDisabledByDefault() bool {
|
||||||
|
return r.isDisabledByDefault
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ControllerDescriptor) IsCloudProviderController() bool {
|
||||||
|
return r.isCloudProviderController
|
||||||
|
}
|
||||||
|
|
||||||
|
// RequiresSpecialHandling should return true only in a special non-generic controllers like ServiceAccountTokenController
|
||||||
|
func (r *ControllerDescriptor) RequiresSpecialHandling() bool {
|
||||||
|
return r.requiresSpecialHandling
|
||||||
|
}
|
||||||
|
|
||||||
// KnownControllers returns all known controllers's name
|
// KnownControllers returns all known controllers's name
|
||||||
func KnownControllers() []string {
|
func KnownControllers() []string {
|
||||||
ret := sets.StringKeySet(NewControllerInitializers(IncludeCloudLoops))
|
return sets.StringKeySet(NewControllerDescriptors()).List()
|
||||||
|
|
||||||
// add "special" controllers that aren't initialized normally. These controllers cannot be initialized
|
|
||||||
// using a normal function. The only known special case is the SA token controller which *must* be started
|
|
||||||
// first to ensure that the SA tokens for future controllers will exist. Think very carefully before adding
|
|
||||||
// to this list.
|
|
||||||
ret.Insert(
|
|
||||||
names.ServiceAccountTokenController,
|
|
||||||
)
|
|
||||||
|
|
||||||
return ret.List()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ControllersDisabledByDefault is the set of controllers which is disabled by default
|
// ControllerAliases returns a mapping of aliases to canonical controller names
|
||||||
var ControllersDisabledByDefault = sets.NewString(
|
func ControllerAliases() map[string]string {
|
||||||
names.BootstrapSignerController,
|
aliases := map[string]string{}
|
||||||
names.TokenCleanerController,
|
for name, c := range NewControllerDescriptors() {
|
||||||
)
|
for _, alias := range c.GetAliases() {
|
||||||
|
aliases[alias] = name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return aliases
|
||||||
|
}
|
||||||
|
|
||||||
// NewControllerInitializers is a public map of named controller groups (you can start more than one in an init func)
|
func ControllersDisabledByDefault() []string {
|
||||||
// paired to their InitFunc. This allows for structured downstream composition and subdivision.
|
var controllersDisabledByDefault []string
|
||||||
func NewControllerInitializers(loopMode ControllerLoopMode) map[string]InitFunc {
|
|
||||||
controllers := map[string]InitFunc{}
|
|
||||||
|
|
||||||
// All of the controllers must have unique names, or else we will explode.
|
for name, c := range NewControllerDescriptors() {
|
||||||
register := func(name string, fn InitFunc) {
|
if c.IsDisabledByDefault() {
|
||||||
|
controllersDisabledByDefault = append(controllersDisabledByDefault, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Strings(controllersDisabledByDefault)
|
||||||
|
|
||||||
|
return controllersDisabledByDefault
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewControllerDescriptors is a public map of named controller groups (you can start more than one in an init func)
|
||||||
|
// paired to their ControllerDescriptor wrapper object that includes InitFunc.
|
||||||
|
// This allows for structured downstream composition and subdivision.
|
||||||
|
func NewControllerDescriptors() map[string]*ControllerDescriptor {
|
||||||
|
controllers := map[string]*ControllerDescriptor{}
|
||||||
|
aliases := sets.NewString()
|
||||||
|
|
||||||
|
// All the controllers must fulfil common constraints, or else we will explode.
|
||||||
|
register := func(controllerDesc *ControllerDescriptor) {
|
||||||
|
if controllerDesc == nil {
|
||||||
|
panic("received nil controller for a registration")
|
||||||
|
}
|
||||||
|
name := controllerDesc.Name()
|
||||||
|
if len(name) == 0 {
|
||||||
|
panic("received controller without a name for a registration")
|
||||||
|
}
|
||||||
if _, found := controllers[name]; found {
|
if _, found := controllers[name]; found {
|
||||||
panic(fmt.Sprintf("controller name %q was registered twice", name))
|
panic(fmt.Sprintf("controller name %q was registered twice", name))
|
||||||
}
|
}
|
||||||
controllers[name] = fn
|
if controllerDesc.GetInitFunc() == nil {
|
||||||
|
panic(fmt.Sprintf("controller %q does not have an init function", name))
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, alias := range controllerDesc.GetAliases() {
|
||||||
|
if aliases.Has(alias) {
|
||||||
|
panic(fmt.Sprintf("controller %q has a duplicate alias %q", name, alias))
|
||||||
|
}
|
||||||
|
aliases.Insert(alias)
|
||||||
|
}
|
||||||
|
|
||||||
|
controllers[name] = controllerDesc
|
||||||
}
|
}
|
||||||
|
|
||||||
register(names.EndpointsController, startEndpointController)
|
// First add "special" controllers that aren't initialized normally. These controllers cannot be initialized
|
||||||
register(names.EndpointSliceController, startEndpointSliceController)
|
// in the main controller loop initialization, so we add them here only for the metadata and duplication detection.
|
||||||
register(names.EndpointSliceMirroringController, startEndpointSliceMirroringController)
|
// app.ControllerDescriptor#RequiresSpecialHandling should return true for such controllers
|
||||||
register(names.ReplicationControllerController, startReplicationController)
|
// The only known special case is the ServiceAccountTokenController which *must* be started
|
||||||
register(names.PodGarbageCollectorController, startPodGCController)
|
// first to ensure that the SA tokens for future controllers will exist. Think very carefully before adding new
|
||||||
register(names.ResourceQuotaController, startResourceQuotaController)
|
// special controllers.
|
||||||
register(names.NamespaceController, startNamespaceController)
|
register(newServiceAccountTokenControllerDescriptor(nil))
|
||||||
register(names.ServiceAccountController, startServiceAccountController)
|
|
||||||
register(names.GarbageCollectorController, startGarbageCollectorController)
|
register(newEndpointsControllerDescriptor())
|
||||||
register(names.DaemonSetController, startDaemonSetController)
|
register(newEndpointSliceControllerDescriptor())
|
||||||
register(names.JobController, startJobController)
|
register(newEndpointSliceMirroringControllerDescriptor())
|
||||||
register(names.DeploymentController, startDeploymentController)
|
register(newReplicationControllerDescriptor())
|
||||||
register(names.ReplicaSetController, startReplicaSetController)
|
register(newPodGarbageCollectorControllerDescriptor())
|
||||||
register(names.HorizontalPodAutoscalerController, startHPAController)
|
register(newResourceQuotaControllerDescriptor())
|
||||||
register(names.DisruptionController, startDisruptionController)
|
register(newNamespaceControllerDescriptor())
|
||||||
register(names.StatefulSetController, startStatefulSetController)
|
register(newServiceAccountControllerDescriptor())
|
||||||
register(names.CronJobController, startCronJobController)
|
register(newGarbageCollectorControllerDescriptor())
|
||||||
register(names.CertificateSigningRequestSigningController, startCSRSigningController)
|
register(newDaemonSetControllerDescriptor())
|
||||||
register(names.CertificateSigningRequestApprovingController, startCSRApprovingController)
|
register(newJobControllerDescriptor())
|
||||||
register(names.CertificateSigningRequestCleanerController, startCSRCleanerController)
|
register(newDeploymentControllerDescriptor())
|
||||||
register(names.TTLController, startTTLController)
|
register(newReplicaSetControllerDescriptor())
|
||||||
register(names.BootstrapSignerController, startBootstrapSignerController)
|
register(newHorizontalPodAutoscalerControllerDescriptor())
|
||||||
register(names.TokenCleanerController, startTokenCleanerController)
|
register(newDisruptionControllerDescriptor())
|
||||||
register(names.NodeIpamController, startNodeIpamController)
|
register(newStatefulSetControllerDescriptor())
|
||||||
register(names.NodeLifecycleController, startNodeLifecycleController)
|
register(newCronJobControllerDescriptor())
|
||||||
if loopMode == IncludeCloudLoops {
|
register(newCertificateSigningRequestSigningControllerDescriptor())
|
||||||
register(cpnames.ServiceLBController, startServiceController)
|
register(newCertificateSigningRequestApprovingControllerDescriptor())
|
||||||
register(cpnames.NodeRouteController, startRouteController)
|
register(newCertificateSigningRequestCleanerControllerDescriptor())
|
||||||
register(cpnames.CloudNodeLifecycleController, startCloudNodeLifecycleController)
|
register(newTTLControllerDescriptor())
|
||||||
// TODO: persistent volume controllers into the IncludeCloudLoops only set.
|
register(newBootstrapSignerControllerDescriptor())
|
||||||
}
|
register(newTokenCleanerControllerDescriptor())
|
||||||
register(names.PersistentVolumeBinderController, startPersistentVolumeBinderController)
|
register(newNodeIpamControllerDescriptor())
|
||||||
register(names.PersistentVolumeAttachDetachController, startAttachDetachController)
|
register(newNodeLifecycleControllerDescriptor())
|
||||||
register(names.PersistentVolumeExpanderController, startVolumeExpandController)
|
|
||||||
register(names.ClusterRoleAggregationController, startClusterRoleAggregrationController)
|
register(newServiceLBControllerDescriptor()) // cloud provider controller
|
||||||
register(names.PersistentVolumeClaimProtectionController, startPVCProtectionController)
|
register(newNodeRouteControllerDescriptor()) // cloud provider controller
|
||||||
register(names.PersistentVolumeProtectionController, startPVProtectionController)
|
register(newCloudNodeLifecycleControllerDescriptor()) // cloud provider controller
|
||||||
register(names.TTLAfterFinishedController, startTTLAfterFinishedController)
|
// TODO: persistent volume controllers into the IncludeCloudLoops only set as a cloud provider controller.
|
||||||
register(names.RootCACertificatePublisherController, startRootCACertPublisher)
|
|
||||||
register(names.EphemeralVolumeController, startEphemeralVolumeController)
|
register(newPersistentVolumeBinderControllerDescriptor())
|
||||||
if utilfeature.DefaultFeatureGate.Enabled(genericfeatures.APIServerIdentity) &&
|
register(newPersistentVolumeAttachDetachControllerDescriptor())
|
||||||
utilfeature.DefaultFeatureGate.Enabled(genericfeatures.StorageVersionAPI) {
|
register(newPersistentVolumeExpanderControllerDescriptor())
|
||||||
register(names.StorageVersionGarbageCollectorController, startStorageVersionGCController)
|
register(newClusterRoleAggregrationControllerDescriptor())
|
||||||
}
|
register(newPersistentVolumeClaimProtectionControllerDescriptor())
|
||||||
if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.DynamicResourceAllocation) {
|
register(newPersistentVolumeProtectionControllerDescriptor())
|
||||||
register(names.ResourceClaimController, startResourceClaimController)
|
register(newTTLAfterFinishedControllerDescriptor())
|
||||||
}
|
register(newRootCACertificatePublisherControllerDescriptor())
|
||||||
if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.LegacyServiceAccountTokenCleanUp) {
|
register(newEphemeralVolumeControllerDescriptor())
|
||||||
register(names.LegacyServiceAccountTokenCleanerController, startLegacySATokenCleaner)
|
|
||||||
}
|
// feature gated
|
||||||
if utilfeature.DefaultFeatureGate.Enabled(genericfeatures.ValidatingAdmissionPolicy) {
|
register(newStorageVersionGarbageCollectorControllerDescriptor())
|
||||||
register(names.ValidatingAdmissionPolicyStatusController, startValidatingAdmissionPolicyStatusController)
|
register(newResourceClaimControllerDescriptor())
|
||||||
|
register(newLegacyServiceAccountTokenCleanerControllerDescriptor())
|
||||||
|
register(newValidatingAdmissionPolicyStatusControllerDescriptor())
|
||||||
|
|
||||||
|
for _, alias := range aliases.UnsortedList() {
|
||||||
|
if _, ok := controllers[alias]; ok {
|
||||||
|
panic(fmt.Sprintf("alias %q conflicts with a controller name", alias))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return controllers
|
return controllers
|
||||||
@ -542,16 +621,21 @@ func CreateControllerContext(logger klog.Logger, s *config.CompletedConfig, root
|
|||||||
}
|
}
|
||||||
|
|
||||||
// StartControllers starts a set of controllers with a specified ControllerContext
|
// StartControllers starts a set of controllers with a specified ControllerContext
|
||||||
func StartControllers(ctx context.Context, controllerCtx ControllerContext, startSATokenController InitFunc, controllers map[string]InitFunc,
|
func StartControllers(ctx context.Context, controllerCtx ControllerContext, controllerDescriptors map[string]*ControllerDescriptor,
|
||||||
unsecuredMux *mux.PathRecorderMux, healthzHandler *controllerhealthz.MutableHealthzHandler) error {
|
unsecuredMux *mux.PathRecorderMux, healthzHandler *controllerhealthz.MutableHealthzHandler) error {
|
||||||
logger := klog.FromContext(ctx)
|
var controllerChecks []healthz.HealthChecker
|
||||||
|
|
||||||
// Always start the SA token controller first using a full-power client, since it needs to mint tokens for the rest
|
// Always start the SA token controller first using a full-power client, since it needs to mint tokens for the rest
|
||||||
// If this fails, just return here and fail since other controllers won't be able to get credentials.
|
// If this fails, just return here and fail since other controllers won't be able to get credentials.
|
||||||
if startSATokenController != nil {
|
if serviceAccountTokenControllerDescriptor, ok := controllerDescriptors[names.ServiceAccountTokenController]; ok {
|
||||||
if _, _, err := startSATokenController(ctx, controllerCtx); err != nil {
|
check, err := StartController(ctx, controllerCtx, serviceAccountTokenControllerDescriptor, unsecuredMux)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if check != nil {
|
||||||
|
// HealthChecker should be present when controller has started
|
||||||
|
controllerChecks = append(controllerChecks, check)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the cloud provider with a reference to the clientBuilder only after token controller
|
// Initialize the cloud provider with a reference to the clientBuilder only after token controller
|
||||||
@ -560,55 +644,28 @@ func StartControllers(ctx context.Context, controllerCtx ControllerContext, star
|
|||||||
controllerCtx.Cloud.Initialize(controllerCtx.ClientBuilder, ctx.Done())
|
controllerCtx.Cloud.Initialize(controllerCtx.ClientBuilder, ctx.Done())
|
||||||
}
|
}
|
||||||
|
|
||||||
var controllerChecks []healthz.HealthChecker
|
|
||||||
|
|
||||||
// Each controller is passed a context where the logger has the name of
|
// Each controller is passed a context where the logger has the name of
|
||||||
// the controller set through WithName. That name then becomes the prefix of
|
// the controller set through WithName. That name then becomes the prefix of
|
||||||
// of all log messages emitted by that controller.
|
// of all log messages emitted by that controller.
|
||||||
//
|
//
|
||||||
// In this loop, an explicit "controller" key is used instead, for two reasons:
|
// In StartController, an explicit "controller" key is used instead, for two reasons:
|
||||||
// - while contextual logging is alpha, klog.LoggerWithName is still a no-op,
|
// - while contextual logging is alpha, klog.LoggerWithName is still a no-op,
|
||||||
// so we cannot rely on it yet to add the name
|
// so we cannot rely on it yet to add the name
|
||||||
// - it allows distinguishing between log entries emitted by the controller
|
// - it allows distinguishing between log entries emitted by the controller
|
||||||
// and those emitted for it - this is a bit debatable and could be revised.
|
// and those emitted for it - this is a bit debatable and could be revised.
|
||||||
for controllerName, initFn := range controllers {
|
for _, controllerDesc := range controllerDescriptors {
|
||||||
if !controllerCtx.IsControllerEnabled(controllerName) {
|
if controllerDesc.RequiresSpecialHandling() {
|
||||||
logger.Info("Warning: controller is disabled", "controller", controllerName)
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
time.Sleep(wait.Jitter(controllerCtx.ComponentConfig.Generic.ControllerStartInterval.Duration, ControllerStartJitter))
|
check, err := StartController(ctx, controllerCtx, controllerDesc, unsecuredMux)
|
||||||
|
|
||||||
logger.V(1).Info("Starting controller", "controller", controllerName)
|
|
||||||
ctrl, started, err := initFn(klog.NewContext(ctx, klog.LoggerWithName(logger, controllerName)), controllerCtx)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error(err, "Error starting controller", "controller", controllerName)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !started {
|
if check != nil {
|
||||||
logger.Info("Warning: skipping controller", "controller", controllerName)
|
// HealthChecker should be present when controller has started
|
||||||
continue
|
controllerChecks = append(controllerChecks, check)
|
||||||
}
|
}
|
||||||
check := controllerhealthz.NamedPingChecker(controllerName)
|
|
||||||
if ctrl != nil {
|
|
||||||
// check if the controller supports and requests a debugHandler
|
|
||||||
// and it needs the unsecuredMux to mount the handler onto.
|
|
||||||
if debuggable, ok := ctrl.(controller.Debuggable); ok && unsecuredMux != nil {
|
|
||||||
if debugHandler := debuggable.DebuggingHandler(); debugHandler != nil {
|
|
||||||
basePath := "/debug/controllers/" + controllerName
|
|
||||||
unsecuredMux.UnlistedHandle(basePath, http.StripPrefix(basePath, debugHandler))
|
|
||||||
unsecuredMux.UnlistedHandlePrefix(basePath+"/", http.StripPrefix(basePath, debugHandler))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if healthCheckable, ok := ctrl.(controller.HealthCheckable); ok {
|
|
||||||
if realCheck := healthCheckable.HealthChecker(); realCheck != nil {
|
|
||||||
check = controllerhealthz.NamedHealthChecker(controllerName, realCheck)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
controllerChecks = append(controllerChecks, check)
|
|
||||||
|
|
||||||
logger.Info("Started controller", "controller", controllerName)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
healthzHandler.AddHealthChecker(controllerChecks...)
|
healthzHandler.AddHealthChecker(controllerChecks...)
|
||||||
@ -616,22 +673,85 @@ func StartControllers(ctx context.Context, controllerCtx ControllerContext, star
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// serviceAccountTokenControllerStarter is special because it must run first to set up permissions for other controllers.
|
// StartController starts a controller with a specified ControllerContext
|
||||||
// It cannot use the "normal" client builder, so it tracks its own. It must also avoid being included in the "normal"
|
// and performs required pre- and post- checks/actions
|
||||||
// init map so that it can always run first.
|
func StartController(ctx context.Context, controllerCtx ControllerContext, controllerDescriptor *ControllerDescriptor,
|
||||||
type serviceAccountTokenControllerStarter struct {
|
unsecuredMux *mux.PathRecorderMux) (healthz.HealthChecker, error) {
|
||||||
rootClientBuilder clientbuilder.ControllerClientBuilder
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c serviceAccountTokenControllerStarter) startServiceAccountTokenController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
|
||||||
logger := klog.FromContext(ctx)
|
logger := klog.FromContext(ctx)
|
||||||
if !controllerContext.IsControllerEnabled(names.ServiceAccountTokenController) {
|
controllerName := controllerDescriptor.Name()
|
||||||
logger.Info("Warning: controller is disabled", "controller", names.ServiceAccountTokenController)
|
|
||||||
return nil, false, nil
|
for _, featureGate := range controllerDescriptor.GetRequiredFeatureGates() {
|
||||||
|
if !utilfeature.DefaultFeatureGate.Enabled(featureGate) {
|
||||||
|
logger.Info("Controller is disabled by a feature gate", "controller", controllerName, "requiredFeatureGates", controllerDescriptor.GetRequiredFeatureGates())
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if controllerDescriptor.IsCloudProviderController() && controllerCtx.LoopMode != IncludeCloudLoops {
|
||||||
|
logger.Info("Skipping a cloud provider controller", "controller", controllerName, "loopMode", controllerCtx.LoopMode)
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if !controllerCtx.IsControllerEnabled(controllerDescriptor) {
|
||||||
|
logger.Info("Warning: controller is disabled", "controller", controllerName)
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
time.Sleep(wait.Jitter(controllerCtx.ComponentConfig.Generic.ControllerStartInterval.Duration, ControllerStartJitter))
|
||||||
|
|
||||||
|
logger.V(1).Info("Starting controller", "controller", controllerName)
|
||||||
|
|
||||||
|
initFunc := controllerDescriptor.GetInitFunc()
|
||||||
|
ctrl, started, err := initFunc(klog.NewContext(ctx, klog.LoggerWithName(logger, controllerName)), controllerCtx, controllerName)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error(err, "Error starting controller", "controller", controllerName)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !started {
|
||||||
|
logger.Info("Warning: skipping controller", "controller", controllerName)
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
check := controllerhealthz.NamedPingChecker(controllerName)
|
||||||
|
if ctrl != nil {
|
||||||
|
// check if the controller supports and requests a debugHandler
|
||||||
|
// and it needs the unsecuredMux to mount the handler onto.
|
||||||
|
if debuggable, ok := ctrl.(controller.Debuggable); ok && unsecuredMux != nil {
|
||||||
|
if debugHandler := debuggable.DebuggingHandler(); debugHandler != nil {
|
||||||
|
basePath := "/debug/controllers/" + controllerName
|
||||||
|
unsecuredMux.UnlistedHandle(basePath, http.StripPrefix(basePath, debugHandler))
|
||||||
|
unsecuredMux.UnlistedHandlePrefix(basePath+"/", http.StripPrefix(basePath, debugHandler))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if healthCheckable, ok := ctrl.(controller.HealthCheckable); ok {
|
||||||
|
if realCheck := healthCheckable.HealthChecker(); realCheck != nil {
|
||||||
|
check = controllerhealthz.NamedHealthChecker(controllerName, realCheck)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Info("Started controller", "controller", controllerName)
|
||||||
|
return check, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// serviceAccountTokenControllerStarter is special because it must run first to set up permissions for other controllers.
|
||||||
|
// It cannot use the "normal" client builder, so it tracks its own.
|
||||||
|
func newServiceAccountTokenControllerDescriptor(rootClientBuilder clientbuilder.ControllerClientBuilder) *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.ServiceAccountTokenController,
|
||||||
|
aliases: []string{"serviceaccount-token"},
|
||||||
|
initFunc: func(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
|
return startServiceAccountTokenController(ctx, controllerContext, controllerName, rootClientBuilder)
|
||||||
|
},
|
||||||
|
// will make sure it runs first before other controllers
|
||||||
|
requiresSpecialHandling: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startServiceAccountTokenController(ctx context.Context, controllerContext ControllerContext, controllerName string, rootClientBuilder clientbuilder.ControllerClientBuilder) (controller.Interface, bool, error) {
|
||||||
|
logger := klog.FromContext(ctx)
|
||||||
if len(controllerContext.ComponentConfig.SAController.ServiceAccountKeyFile) == 0 {
|
if len(controllerContext.ComponentConfig.SAController.ServiceAccountKeyFile) == 0 {
|
||||||
logger.Info("Controller is disabled because there is no private key", "controller", names.ServiceAccountTokenController)
|
logger.Info("Controller is disabled because there is no private key", "controller", controllerName)
|
||||||
return nil, false, nil
|
return nil, false, nil
|
||||||
}
|
}
|
||||||
privateKey, err := keyutil.PrivateKeyFromFile(controllerContext.ComponentConfig.SAController.ServiceAccountKeyFile)
|
privateKey, err := keyutil.PrivateKeyFromFile(controllerContext.ComponentConfig.SAController.ServiceAccountKeyFile)
|
||||||
@ -645,7 +765,7 @@ func (c serviceAccountTokenControllerStarter) startServiceAccountTokenController
|
|||||||
return nil, true, fmt.Errorf("error parsing root-ca-file at %s: %v", controllerContext.ComponentConfig.SAController.RootCAFile, err)
|
return nil, true, fmt.Errorf("error parsing root-ca-file at %s: %v", controllerContext.ComponentConfig.SAController.RootCAFile, err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rootCA = c.rootClientBuilder.ConfigOrDie("tokens-controller").CAData
|
rootCA = rootClientBuilder.ConfigOrDie("tokens-controller").CAData
|
||||||
}
|
}
|
||||||
|
|
||||||
tokenGenerator, err := serviceaccount.JWTTokenGenerator(serviceaccount.LegacyIssuer, privateKey)
|
tokenGenerator, err := serviceaccount.JWTTokenGenerator(serviceaccount.LegacyIssuer, privateKey)
|
||||||
@ -655,7 +775,7 @@ func (c serviceAccountTokenControllerStarter) startServiceAccountTokenController
|
|||||||
tokenController, err := serviceaccountcontroller.NewTokensController(
|
tokenController, err := serviceaccountcontroller.NewTokensController(
|
||||||
controllerContext.InformerFactory.Core().V1().ServiceAccounts(),
|
controllerContext.InformerFactory.Core().V1().ServiceAccounts(),
|
||||||
controllerContext.InformerFactory.Core().V1().Secrets(),
|
controllerContext.InformerFactory.Core().V1().Secrets(),
|
||||||
c.rootClientBuilder.ClientOrDie("tokens-controller"),
|
rootClientBuilder.ClientOrDie("tokens-controller"),
|
||||||
serviceaccountcontroller.TokensControllerOptions{
|
serviceaccountcontroller.TokensControllerOptions{
|
||||||
TokenGenerator: tokenGenerator,
|
TokenGenerator: tokenGenerator,
|
||||||
RootCA: rootCA,
|
RootCA: rootCA,
|
||||||
@ -737,16 +857,13 @@ func leaderElectAndRun(ctx context.Context, c *config.CompletedConfig, lockIdent
|
|||||||
panic("unreachable")
|
panic("unreachable")
|
||||||
}
|
}
|
||||||
|
|
||||||
// createInitializersFunc creates a initializersFunc that returns all initializer
|
// filteredControllerDescriptors returns all controllerDescriptors after filtering through filterFunc.
|
||||||
// with expected as the result after filtering through filterFunc.
|
func filteredControllerDescriptors(controllerDescriptors map[string]*ControllerDescriptor, filterFunc leadermigration.FilterFunc, expected leadermigration.FilterResult) map[string]*ControllerDescriptor {
|
||||||
func createInitializersFunc(filterFunc leadermigration.FilterFunc, expected leadermigration.FilterResult) ControllerInitializersFunc {
|
resultControllers := make(map[string]*ControllerDescriptor)
|
||||||
return func(loopMode ControllerLoopMode) map[string]InitFunc {
|
for name, controllerDesc := range controllerDescriptors {
|
||||||
initializers := make(map[string]InitFunc)
|
if filterFunc(name) == expected {
|
||||||
for name, initializer := range NewControllerInitializers(loopMode) {
|
resultControllers[name] = controllerDesc
|
||||||
if filterFunc(name) == expected {
|
|
||||||
initializers[name] = initializer
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return initializers
|
|
||||||
}
|
}
|
||||||
|
return resultControllers
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,13 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/google/go-cmp/cmp"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
cpnames "k8s.io/cloud-provider/names"
|
cpnames "k8s.io/cloud-provider/names"
|
||||||
|
"k8s.io/component-base/featuregate"
|
||||||
|
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||||
|
|
||||||
"k8s.io/kubernetes/cmd/kube-controller-manager/names"
|
"k8s.io/kubernetes/cmd/kube-controller-manager/names"
|
||||||
)
|
)
|
||||||
@ -41,7 +46,7 @@ func TestControllerNamesConsistency(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestControllerNamesDeclaration(t *testing.T) {
|
func TestControllerNamesDeclaration(t *testing.T) {
|
||||||
declaredControllers := sets.New(
|
declaredControllers := sets.NewString(
|
||||||
names.ServiceAccountTokenController,
|
names.ServiceAccountTokenController,
|
||||||
names.EndpointsController,
|
names.EndpointsController,
|
||||||
names.EndpointSliceController,
|
names.EndpointSliceController,
|
||||||
@ -83,6 +88,7 @@ func TestControllerNamesDeclaration(t *testing.T) {
|
|||||||
names.StorageVersionGarbageCollectorController,
|
names.StorageVersionGarbageCollectorController,
|
||||||
names.ResourceClaimController,
|
names.ResourceClaimController,
|
||||||
names.LegacyServiceAccountTokenCleanerController,
|
names.LegacyServiceAccountTokenCleanerController,
|
||||||
|
names.ValidatingAdmissionPolicyStatusController,
|
||||||
)
|
)
|
||||||
|
|
||||||
for _, name := range KnownControllers() {
|
for _, name := range KnownControllers() {
|
||||||
@ -91,3 +97,62 @@ func TestControllerNamesDeclaration(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestNewControllerDescriptorsShouldNotPanic(t *testing.T) {
|
||||||
|
NewControllerDescriptors()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewControllerDescriptorsAlwaysReturnsDescriptorsForAllControllers(t *testing.T) {
|
||||||
|
controllersWithoutFeatureGates := KnownControllers()
|
||||||
|
|
||||||
|
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, "AllAlpha", true)()
|
||||||
|
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, "AllBeta", true)()
|
||||||
|
|
||||||
|
controllersWithFeatureGates := KnownControllers()
|
||||||
|
|
||||||
|
if diff := cmp.Diff(controllersWithoutFeatureGates, controllersWithFeatureGates); diff != "" {
|
||||||
|
t.Errorf("unexpected controllers after enabling feature gates, NewControllerDescriptors should always return all controller descriptors. Controllers should define required feature gates in ControllerDescriptor.requiredFeatureGates. Diff of returned controllers:\n%s", diff)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFeatureGatedControllersShouldNotDefineAliases(t *testing.T) {
|
||||||
|
featureGateRegex := regexp.MustCompile("^([a-zA-Z0-9]+)")
|
||||||
|
|
||||||
|
alphaFeatures := sets.NewString()
|
||||||
|
for _, featureText := range utilfeature.DefaultFeatureGate.KnownFeatures() {
|
||||||
|
// we have to parse this from KnownFeatures, because usage of mutable FeatureGate is not allowed in unit tests
|
||||||
|
feature := featureGateRegex.FindString(featureText)
|
||||||
|
if strings.Contains(featureText, string(featuregate.Alpha)) && feature != "AllAlpha" {
|
||||||
|
alphaFeatures.Insert(feature)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, controller := range NewControllerDescriptors() {
|
||||||
|
if len(controller.GetAliases()) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
requiredFeatureGates := controller.GetRequiredFeatureGates()
|
||||||
|
if len(requiredFeatureGates) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// DO NOT ADD any new controllers here. These two controllers are an exception, because they were added before this test was introduced
|
||||||
|
if name == names.LegacyServiceAccountTokenCleanerController || name == names.ResourceClaimController {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
areAllRequiredFeaturesAlpha := true
|
||||||
|
for _, feature := range requiredFeatureGates {
|
||||||
|
if !alphaFeatures.Has(string(feature)) {
|
||||||
|
areAllRequiredFeaturesAlpha = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if areAllRequiredFeaturesAlpha {
|
||||||
|
t.Errorf("alias check failed: controller name %q should not be aliased as it is still guarded by alpha feature gates (%v) and thus should have only a canonical name", name, requiredFeatureGates)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -31,6 +31,7 @@ import (
|
|||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
genericfeatures "k8s.io/apiserver/pkg/features"
|
||||||
"k8s.io/apiserver/pkg/quota/v1/generic"
|
"k8s.io/apiserver/pkg/quota/v1/generic"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
@ -39,8 +40,11 @@ import (
|
|||||||
cloudnodelifecyclecontroller "k8s.io/cloud-provider/controllers/nodelifecycle"
|
cloudnodelifecyclecontroller "k8s.io/cloud-provider/controllers/nodelifecycle"
|
||||||
routecontroller "k8s.io/cloud-provider/controllers/route"
|
routecontroller "k8s.io/cloud-provider/controllers/route"
|
||||||
servicecontroller "k8s.io/cloud-provider/controllers/service"
|
servicecontroller "k8s.io/cloud-provider/controllers/service"
|
||||||
|
cpnames "k8s.io/cloud-provider/names"
|
||||||
|
"k8s.io/component-base/featuregate"
|
||||||
"k8s.io/controller-manager/controller"
|
"k8s.io/controller-manager/controller"
|
||||||
csitrans "k8s.io/csi-translation-lib"
|
csitrans "k8s.io/csi-translation-lib"
|
||||||
|
"k8s.io/kubernetes/cmd/kube-controller-manager/names"
|
||||||
pkgcontroller "k8s.io/kubernetes/pkg/controller"
|
pkgcontroller "k8s.io/kubernetes/pkg/controller"
|
||||||
endpointcontroller "k8s.io/kubernetes/pkg/controller/endpoint"
|
endpointcontroller "k8s.io/kubernetes/pkg/controller/endpoint"
|
||||||
"k8s.io/kubernetes/pkg/controller/garbagecollector"
|
"k8s.io/kubernetes/pkg/controller/garbagecollector"
|
||||||
@ -63,6 +67,7 @@ import (
|
|||||||
persistentvolumecontroller "k8s.io/kubernetes/pkg/controller/volume/persistentvolume"
|
persistentvolumecontroller "k8s.io/kubernetes/pkg/controller/volume/persistentvolume"
|
||||||
"k8s.io/kubernetes/pkg/controller/volume/pvcprotection"
|
"k8s.io/kubernetes/pkg/controller/volume/pvcprotection"
|
||||||
"k8s.io/kubernetes/pkg/controller/volume/pvprotection"
|
"k8s.io/kubernetes/pkg/controller/volume/pvprotection"
|
||||||
|
"k8s.io/kubernetes/pkg/features"
|
||||||
quotainstall "k8s.io/kubernetes/pkg/quota/v1/install"
|
quotainstall "k8s.io/kubernetes/pkg/quota/v1/install"
|
||||||
"k8s.io/kubernetes/pkg/volume/csimigration"
|
"k8s.io/kubernetes/pkg/volume/csimigration"
|
||||||
"k8s.io/utils/clock"
|
"k8s.io/utils/clock"
|
||||||
@ -76,7 +81,16 @@ const (
|
|||||||
defaultNodeMaskCIDRIPv6 = 64
|
defaultNodeMaskCIDRIPv6 = 64
|
||||||
)
|
)
|
||||||
|
|
||||||
func startServiceController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newServiceLBControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: cpnames.ServiceLBController,
|
||||||
|
aliases: []string{"service"},
|
||||||
|
initFunc: startServiceLBController,
|
||||||
|
isCloudProviderController: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startServiceLBController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
serviceController, err := servicecontroller.New(
|
serviceController, err := servicecontroller.New(
|
||||||
controllerContext.Cloud,
|
controllerContext.Cloud,
|
||||||
controllerContext.ClientBuilder.ClientOrDie("service-controller"),
|
controllerContext.ClientBuilder.ClientOrDie("service-controller"),
|
||||||
@ -93,8 +107,15 @@ func startServiceController(ctx context.Context, controllerContext ControllerCon
|
|||||||
go serviceController.Run(ctx, int(controllerContext.ComponentConfig.ServiceController.ConcurrentServiceSyncs), controllerContext.ControllerManagerMetrics)
|
go serviceController.Run(ctx, int(controllerContext.ComponentConfig.ServiceController.ConcurrentServiceSyncs), controllerContext.ControllerManagerMetrics)
|
||||||
return nil, true, nil
|
return nil, true, nil
|
||||||
}
|
}
|
||||||
|
func newNodeIpamControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.NodeIpamController,
|
||||||
|
aliases: []string{"nodeipam"},
|
||||||
|
initFunc: startNodeIpamController,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func startNodeIpamController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func startNodeIpamController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
var serviceCIDR *net.IPNet
|
var serviceCIDR *net.IPNet
|
||||||
var secondaryServiceCIDR *net.IPNet
|
var secondaryServiceCIDR *net.IPNet
|
||||||
logger := klog.FromContext(ctx)
|
logger := klog.FromContext(ctx)
|
||||||
@ -166,7 +187,15 @@ func startNodeIpamController(ctx context.Context, controllerContext ControllerCo
|
|||||||
return nil, true, nil
|
return nil, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func startNodeLifecycleController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newNodeLifecycleControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.NodeLifecycleController,
|
||||||
|
aliases: []string{"nodelifecycle"},
|
||||||
|
initFunc: startNodeLifecycleController,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startNodeLifecycleController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
lifecycleController, err := lifecyclecontroller.NewNodeLifecycleController(
|
lifecycleController, err := lifecyclecontroller.NewNodeLifecycleController(
|
||||||
ctx,
|
ctx,
|
||||||
controllerContext.InformerFactory.Coordination().V1().Leases(),
|
controllerContext.InformerFactory.Coordination().V1().Leases(),
|
||||||
@ -190,7 +219,16 @@ func startNodeLifecycleController(ctx context.Context, controllerContext Control
|
|||||||
return nil, true, nil
|
return nil, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func startCloudNodeLifecycleController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newCloudNodeLifecycleControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: cpnames.CloudNodeLifecycleController,
|
||||||
|
aliases: []string{"cloud-node-lifecycle"},
|
||||||
|
initFunc: startCloudNodeLifecycleController,
|
||||||
|
isCloudProviderController: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startCloudNodeLifecycleController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
logger := klog.FromContext(ctx)
|
logger := klog.FromContext(ctx)
|
||||||
cloudNodeLifecycleController, err := cloudnodelifecyclecontroller.NewCloudNodeLifecycleController(
|
cloudNodeLifecycleController, err := cloudnodelifecyclecontroller.NewCloudNodeLifecycleController(
|
||||||
controllerContext.InformerFactory.Core().V1().Nodes(),
|
controllerContext.InformerFactory.Core().V1().Nodes(),
|
||||||
@ -210,7 +248,16 @@ func startCloudNodeLifecycleController(ctx context.Context, controllerContext Co
|
|||||||
return nil, true, nil
|
return nil, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func startRouteController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newNodeRouteControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: cpnames.NodeRouteController,
|
||||||
|
aliases: []string{"route"},
|
||||||
|
initFunc: startNodeRouteController,
|
||||||
|
isCloudProviderController: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startNodeRouteController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
logger := klog.FromContext(ctx)
|
logger := klog.FromContext(ctx)
|
||||||
if !controllerContext.ComponentConfig.KubeCloudShared.AllocateNodeCIDRs || !controllerContext.ComponentConfig.KubeCloudShared.ConfigureCloudRoutes {
|
if !controllerContext.ComponentConfig.KubeCloudShared.AllocateNodeCIDRs || !controllerContext.ComponentConfig.KubeCloudShared.ConfigureCloudRoutes {
|
||||||
logger.Info("Will not configure cloud provider routes for allocate-node-cidrs", "CIDRs", controllerContext.ComponentConfig.KubeCloudShared.AllocateNodeCIDRs, "routes", controllerContext.ComponentConfig.KubeCloudShared.ConfigureCloudRoutes)
|
logger.Info("Will not configure cloud provider routes for allocate-node-cidrs", "CIDRs", controllerContext.ComponentConfig.KubeCloudShared.AllocateNodeCIDRs, "routes", controllerContext.ComponentConfig.KubeCloudShared.ConfigureCloudRoutes)
|
||||||
@ -240,7 +287,15 @@ func startRouteController(ctx context.Context, controllerContext ControllerConte
|
|||||||
return nil, true, nil
|
return nil, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func startPersistentVolumeBinderController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newPersistentVolumeBinderControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.PersistentVolumeBinderController,
|
||||||
|
aliases: []string{"persistentvolume-binder"},
|
||||||
|
initFunc: startPersistentVolumeBinderController,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startPersistentVolumeBinderController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
logger := klog.FromContext(ctx)
|
logger := klog.FromContext(ctx)
|
||||||
plugins, err := ProbeControllerVolumePlugins(logger, controllerContext.Cloud, controllerContext.ComponentConfig.PersistentVolumeBinderController.VolumeConfiguration)
|
plugins, err := ProbeControllerVolumePlugins(logger, controllerContext.Cloud, controllerContext.ComponentConfig.PersistentVolumeBinderController.VolumeConfiguration)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -268,7 +323,15 @@ func startPersistentVolumeBinderController(ctx context.Context, controllerContex
|
|||||||
return nil, true, nil
|
return nil, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func startAttachDetachController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newPersistentVolumeAttachDetachControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.PersistentVolumeAttachDetachController,
|
||||||
|
aliases: []string{"attachdetach"},
|
||||||
|
initFunc: startPersistentVolumeAttachDetachController,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startPersistentVolumeAttachDetachController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
logger := klog.FromContext(ctx)
|
logger := klog.FromContext(ctx)
|
||||||
csiNodeInformer := controllerContext.InformerFactory.Storage().V1().CSINodes()
|
csiNodeInformer := controllerContext.InformerFactory.Storage().V1().CSINodes()
|
||||||
csiDriverInformer := controllerContext.InformerFactory.Storage().V1().CSIDrivers()
|
csiDriverInformer := controllerContext.InformerFactory.Storage().V1().CSIDrivers()
|
||||||
@ -304,7 +367,15 @@ func startAttachDetachController(ctx context.Context, controllerContext Controll
|
|||||||
return nil, true, nil
|
return nil, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func startVolumeExpandController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newPersistentVolumeExpanderControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.PersistentVolumeExpanderController,
|
||||||
|
aliases: []string{"persistentvolume-expander"},
|
||||||
|
initFunc: startPersistentVolumeExpanderController,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startPersistentVolumeExpanderController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
logger := klog.FromContext(ctx)
|
logger := klog.FromContext(ctx)
|
||||||
plugins, err := ProbeExpandableVolumePlugins(logger, controllerContext.ComponentConfig.PersistentVolumeBinderController.VolumeConfiguration)
|
plugins, err := ProbeExpandableVolumePlugins(logger, controllerContext.ComponentConfig.PersistentVolumeBinderController.VolumeConfiguration)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -326,10 +397,17 @@ func startVolumeExpandController(ctx context.Context, controllerContext Controll
|
|||||||
}
|
}
|
||||||
go expandController.Run(ctx)
|
go expandController.Run(ctx)
|
||||||
return nil, true, nil
|
return nil, true, nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func startEphemeralVolumeController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newEphemeralVolumeControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.EphemeralVolumeController,
|
||||||
|
aliases: []string{"ephemeral-volume"},
|
||||||
|
initFunc: startEphemeralVolumeController,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startEphemeralVolumeController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
ephemeralController, err := ephemeral.NewController(
|
ephemeralController, err := ephemeral.NewController(
|
||||||
controllerContext.ClientBuilder.ClientOrDie("ephemeral-volume-controller"),
|
controllerContext.ClientBuilder.ClientOrDie("ephemeral-volume-controller"),
|
||||||
controllerContext.InformerFactory.Core().V1().Pods(),
|
controllerContext.InformerFactory.Core().V1().Pods(),
|
||||||
@ -343,7 +421,18 @@ func startEphemeralVolumeController(ctx context.Context, controllerContext Contr
|
|||||||
|
|
||||||
const defaultResourceClaimControllerWorkers = 10
|
const defaultResourceClaimControllerWorkers = 10
|
||||||
|
|
||||||
func startResourceClaimController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newResourceClaimControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.ResourceClaimController,
|
||||||
|
aliases: []string{"resource-claim-controller"},
|
||||||
|
initFunc: startResourceClaimController,
|
||||||
|
requiredFeatureGates: []featuregate.Feature{
|
||||||
|
features.DynamicResourceAllocation, // TODO update app.TestFeatureGatedControllersShouldNotDefineAliases when removing this feature
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startResourceClaimController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
ephemeralController, err := resourceclaim.NewController(
|
ephemeralController, err := resourceclaim.NewController(
|
||||||
klog.FromContext(ctx),
|
klog.FromContext(ctx),
|
||||||
controllerContext.ClientBuilder.ClientOrDie("resource-claim-controller"),
|
controllerContext.ClientBuilder.ClientOrDie("resource-claim-controller"),
|
||||||
@ -358,18 +447,34 @@ func startResourceClaimController(ctx context.Context, controllerContext Control
|
|||||||
return nil, true, nil
|
return nil, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func startEndpointController(ctx context.Context, controllerCtx ControllerContext) (controller.Interface, bool, error) {
|
func newEndpointsControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.EndpointsController,
|
||||||
|
aliases: []string{"endpoint"},
|
||||||
|
initFunc: startEndpointsController,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startEndpointsController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
go endpointcontroller.NewEndpointController(
|
go endpointcontroller.NewEndpointController(
|
||||||
controllerCtx.InformerFactory.Core().V1().Pods(),
|
controllerContext.InformerFactory.Core().V1().Pods(),
|
||||||
controllerCtx.InformerFactory.Core().V1().Services(),
|
controllerContext.InformerFactory.Core().V1().Services(),
|
||||||
controllerCtx.InformerFactory.Core().V1().Endpoints(),
|
controllerContext.InformerFactory.Core().V1().Endpoints(),
|
||||||
controllerCtx.ClientBuilder.ClientOrDie("endpoint-controller"),
|
controllerContext.ClientBuilder.ClientOrDie("endpoint-controller"),
|
||||||
controllerCtx.ComponentConfig.EndpointController.EndpointUpdatesBatchPeriod.Duration,
|
controllerContext.ComponentConfig.EndpointController.EndpointUpdatesBatchPeriod.Duration,
|
||||||
).Run(ctx, int(controllerCtx.ComponentConfig.EndpointController.ConcurrentEndpointSyncs))
|
).Run(ctx, int(controllerContext.ComponentConfig.EndpointController.ConcurrentEndpointSyncs))
|
||||||
return nil, true, nil
|
return nil, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func startReplicationController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newReplicationControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.ReplicationControllerController,
|
||||||
|
aliases: []string{"replicationcontroller"},
|
||||||
|
initFunc: startReplicationController,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startReplicationController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
go replicationcontroller.NewReplicationManager(
|
go replicationcontroller.NewReplicationManager(
|
||||||
klog.FromContext(ctx),
|
klog.FromContext(ctx),
|
||||||
controllerContext.InformerFactory.Core().V1().Pods(),
|
controllerContext.InformerFactory.Core().V1().Pods(),
|
||||||
@ -380,7 +485,15 @@ func startReplicationController(ctx context.Context, controllerContext Controlle
|
|||||||
return nil, true, nil
|
return nil, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func startPodGCController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newPodGarbageCollectorControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.PodGarbageCollectorController,
|
||||||
|
aliases: []string{"podgc"},
|
||||||
|
initFunc: startPodGarbageCollectorController,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startPodGarbageCollectorController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
go podgc.NewPodGC(
|
go podgc.NewPodGC(
|
||||||
ctx,
|
ctx,
|
||||||
controllerContext.ClientBuilder.ClientOrDie("pod-garbage-collector"),
|
controllerContext.ClientBuilder.ClientOrDie("pod-garbage-collector"),
|
||||||
@ -391,7 +504,15 @@ func startPodGCController(ctx context.Context, controllerContext ControllerConte
|
|||||||
return nil, true, nil
|
return nil, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func startResourceQuotaController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newResourceQuotaControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.ResourceQuotaController,
|
||||||
|
aliases: []string{"resourcequota"},
|
||||||
|
initFunc: startResourceQuotaController,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startResourceQuotaController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
resourceQuotaControllerClient := controllerContext.ClientBuilder.ClientOrDie("resourcequota-controller")
|
resourceQuotaControllerClient := controllerContext.ClientBuilder.ClientOrDie("resourcequota-controller")
|
||||||
resourceQuotaControllerDiscoveryClient := controllerContext.ClientBuilder.DiscoveryClientOrDie("resourcequota-controller")
|
resourceQuotaControllerDiscoveryClient := controllerContext.ClientBuilder.DiscoveryClientOrDie("resourcequota-controller")
|
||||||
discoveryFunc := resourceQuotaControllerDiscoveryClient.ServerPreferredNamespacedResources
|
discoveryFunc := resourceQuotaControllerDiscoveryClient.ServerPreferredNamespacedResources
|
||||||
@ -422,7 +543,15 @@ func startResourceQuotaController(ctx context.Context, controllerContext Control
|
|||||||
return nil, true, nil
|
return nil, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func startNamespaceController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newNamespaceControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.NamespaceController,
|
||||||
|
aliases: []string{"namespace"},
|
||||||
|
initFunc: startNamespaceController,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startNamespaceController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
// the namespace cleanup controller is very chatty. It makes lots of discovery calls and then it makes lots of delete calls
|
// the namespace cleanup controller is very chatty. It makes lots of discovery calls and then it makes lots of delete calls
|
||||||
// the ratelimiter negatively affects its speed. Deleting 100 total items in a namespace (that's only a few of each resource
|
// the ratelimiter negatively affects its speed. Deleting 100 total items in a namespace (that's only a few of each resource
|
||||||
// including events), takes ~10 seconds by default.
|
// including events), takes ~10 seconds by default.
|
||||||
@ -456,7 +585,15 @@ func startModifiedNamespaceController(ctx context.Context, controllerContext Con
|
|||||||
return nil, true, nil
|
return nil, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func startServiceAccountController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newServiceAccountControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.ServiceAccountController,
|
||||||
|
aliases: []string{"serviceaccount"},
|
||||||
|
initFunc: startServiceAccountController,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startServiceAccountController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
sac, err := serviceaccountcontroller.NewServiceAccountsController(
|
sac, err := serviceaccountcontroller.NewServiceAccountsController(
|
||||||
controllerContext.InformerFactory.Core().V1().ServiceAccounts(),
|
controllerContext.InformerFactory.Core().V1().ServiceAccounts(),
|
||||||
controllerContext.InformerFactory.Core().V1().Namespaces(),
|
controllerContext.InformerFactory.Core().V1().Namespaces(),
|
||||||
@ -470,7 +607,15 @@ func startServiceAccountController(ctx context.Context, controllerContext Contro
|
|||||||
return nil, true, nil
|
return nil, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func startTTLController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newTTLControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.TTLController,
|
||||||
|
aliases: []string{"ttl"},
|
||||||
|
initFunc: startTTLController,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startTTLController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
go ttlcontroller.NewTTLController(
|
go ttlcontroller.NewTTLController(
|
||||||
ctx,
|
ctx,
|
||||||
controllerContext.InformerFactory.Core().V1().Nodes(),
|
controllerContext.InformerFactory.Core().V1().Nodes(),
|
||||||
@ -479,7 +624,15 @@ func startTTLController(ctx context.Context, controllerContext ControllerContext
|
|||||||
return nil, true, nil
|
return nil, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func startGarbageCollectorController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newGarbageCollectorControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.GarbageCollectorController,
|
||||||
|
aliases: []string{"garbagecollector"},
|
||||||
|
initFunc: startGarbageCollectorController,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startGarbageCollectorController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
if !controllerContext.ComponentConfig.GarbageCollectorController.EnableGarbageCollector {
|
if !controllerContext.ComponentConfig.GarbageCollectorController.EnableGarbageCollector {
|
||||||
return nil, false, nil
|
return nil, false, nil
|
||||||
}
|
}
|
||||||
@ -523,7 +676,15 @@ func startGarbageCollectorController(ctx context.Context, controllerContext Cont
|
|||||||
return garbageCollector, true, nil
|
return garbageCollector, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func startPVCProtectionController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newPersistentVolumeClaimProtectionControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.PersistentVolumeClaimProtectionController,
|
||||||
|
aliases: []string{"pvc-protection"},
|
||||||
|
initFunc: startPersistentVolumeClaimProtectionController,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startPersistentVolumeClaimProtectionController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
pvcProtectionController, err := pvcprotection.NewPVCProtectionController(
|
pvcProtectionController, err := pvcprotection.NewPVCProtectionController(
|
||||||
klog.FromContext(ctx),
|
klog.FromContext(ctx),
|
||||||
controllerContext.InformerFactory.Core().V1().PersistentVolumeClaims(),
|
controllerContext.InformerFactory.Core().V1().PersistentVolumeClaims(),
|
||||||
@ -537,7 +698,15 @@ func startPVCProtectionController(ctx context.Context, controllerContext Control
|
|||||||
return nil, true, nil
|
return nil, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func startPVProtectionController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newPersistentVolumeProtectionControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.PersistentVolumeProtectionController,
|
||||||
|
aliases: []string{"pv-protection"},
|
||||||
|
initFunc: startPersistentVolumeProtectionController,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startPersistentVolumeProtectionController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
go pvprotection.NewPVProtectionController(
|
go pvprotection.NewPVProtectionController(
|
||||||
klog.FromContext(ctx),
|
klog.FromContext(ctx),
|
||||||
controllerContext.InformerFactory.Core().V1().PersistentVolumes(),
|
controllerContext.InformerFactory.Core().V1().PersistentVolumes(),
|
||||||
@ -546,7 +715,15 @@ func startPVProtectionController(ctx context.Context, controllerContext Controll
|
|||||||
return nil, true, nil
|
return nil, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func startTTLAfterFinishedController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newTTLAfterFinishedControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.TTLAfterFinishedController,
|
||||||
|
aliases: []string{"ttl-after-finished"},
|
||||||
|
initFunc: startTTLAfterFinishedController,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startTTLAfterFinishedController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
go ttlafterfinished.New(
|
go ttlafterfinished.New(
|
||||||
ctx,
|
ctx,
|
||||||
controllerContext.InformerFactory.Batch().V1().Jobs(),
|
controllerContext.InformerFactory.Batch().V1().Jobs(),
|
||||||
@ -555,7 +732,18 @@ func startTTLAfterFinishedController(ctx context.Context, controllerContext Cont
|
|||||||
return nil, true, nil
|
return nil, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func startLegacySATokenCleaner(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newLegacyServiceAccountTokenCleanerControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.LegacyServiceAccountTokenCleanerController,
|
||||||
|
aliases: []string{"legacy-service-account-token-cleaner"},
|
||||||
|
initFunc: startLegacyServiceAccountTokenCleanerController,
|
||||||
|
requiredFeatureGates: []featuregate.Feature{
|
||||||
|
features.LegacyServiceAccountTokenCleanUp, // TODO update app.TestFeatureGatedControllersShouldNotDefineAliases when removing this feature
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startLegacyServiceAccountTokenCleanerController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
cleanUpPeriod := controllerContext.ComponentConfig.LegacySATokenCleaner.CleanUpPeriod.Duration
|
cleanUpPeriod := controllerContext.ComponentConfig.LegacySATokenCleaner.CleanUpPeriod.Duration
|
||||||
legacySATokenCleaner, err := serviceaccountcontroller.NewLegacySATokenCleaner(
|
legacySATokenCleaner, err := serviceaccountcontroller.NewLegacySATokenCleaner(
|
||||||
controllerContext.InformerFactory.Core().V1().ServiceAccounts(),
|
controllerContext.InformerFactory.Core().V1().ServiceAccounts(),
|
||||||
@ -690,7 +878,19 @@ func setNodeCIDRMaskSizes(cfg nodeipamconfig.NodeIPAMControllerConfiguration, cl
|
|||||||
return sortedSizes(ipv4Mask, ipv6Mask), nil
|
return sortedSizes(ipv4Mask, ipv6Mask), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func startStorageVersionGCController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newStorageVersionGarbageCollectorControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.StorageVersionGarbageCollectorController,
|
||||||
|
aliases: []string{"storage-version-gc"},
|
||||||
|
initFunc: startStorageVersionGarbageCollectorController,
|
||||||
|
requiredFeatureGates: []featuregate.Feature{
|
||||||
|
genericfeatures.APIServerIdentity,
|
||||||
|
genericfeatures.StorageVersionAPI,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startStorageVersionGarbageCollectorController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
go storageversiongc.NewStorageVersionGC(
|
go storageversiongc.NewStorageVersionGC(
|
||||||
ctx,
|
ctx,
|
||||||
controllerContext.ClientBuilder.ClientOrDie("storage-version-garbage-collector"),
|
controllerContext.ClientBuilder.ClientOrDie("storage-version-garbage-collector"),
|
||||||
|
@ -28,7 +28,6 @@ import (
|
|||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
fakeclientset "k8s.io/client-go/kubernetes/fake"
|
fakeclientset "k8s.io/client-go/kubernetes/fake"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
"k8s.io/controller-manager/controller"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// TestClientBuilder inherits ClientBuilder and can accept a given fake clientset.
|
// TestClientBuilder inherits ClientBuilder and can accept a given fake clientset.
|
||||||
@ -105,15 +104,13 @@ func possibleDiscoveryResource() []*metav1.APIResourceList {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type controllerInitFunc func(context.Context, ControllerContext) (controller.Interface, bool, error)
|
|
||||||
|
|
||||||
func TestController_DiscoveryError(t *testing.T) {
|
func TestController_DiscoveryError(t *testing.T) {
|
||||||
controllerInitFuncMap := map[string]controllerInitFunc{
|
controllerDescriptorMap := map[string]*ControllerDescriptor{
|
||||||
"ResourceQuotaController": startResourceQuotaController,
|
"ResourceQuotaController": newResourceQuotaControllerDescriptor(),
|
||||||
"GarbageCollectorController": startGarbageCollectorController,
|
"GarbageCollectorController": newGarbageCollectorControllerDescriptor(),
|
||||||
"EndpointSliceController": startEndpointSliceController,
|
"EndpointSliceController": newEndpointSliceControllerDescriptor(),
|
||||||
"EndpointSliceMirroringController": startEndpointSliceMirroringController,
|
"EndpointSliceMirroringController": newEndpointSliceMirroringControllerDescriptor(),
|
||||||
"PodDisruptionBudgetController": startDisruptionController,
|
"PodDisruptionBudgetController": newDisruptionControllerDescriptor(),
|
||||||
}
|
}
|
||||||
|
|
||||||
tcs := map[string]struct {
|
tcs := map[string]struct {
|
||||||
@ -143,10 +140,10 @@ func TestController_DiscoveryError(t *testing.T) {
|
|||||||
ObjectOrMetadataInformerFactory: testInformerFactory,
|
ObjectOrMetadataInformerFactory: testInformerFactory,
|
||||||
InformersStarted: make(chan struct{}),
|
InformersStarted: make(chan struct{}),
|
||||||
}
|
}
|
||||||
for funcName, controllerInit := range controllerInitFuncMap {
|
for controllerName, controllerDesc := range controllerDescriptorMap {
|
||||||
_, _, err := controllerInit(context.TODO(), ctx)
|
_, _, err := controllerDesc.GetInitFunc()(context.TODO(), ctx, controllerName)
|
||||||
if test.expectedErr != (err != nil) {
|
if test.expectedErr != (err != nil) {
|
||||||
t.Errorf("%v test failed for use case: %v", funcName, name)
|
t.Errorf("%v test failed for use case: %v", controllerName, name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_, _, err := startModifiedNamespaceController(
|
_, _, err := startModifiedNamespaceController(
|
||||||
|
@ -23,11 +23,20 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"k8s.io/controller-manager/controller"
|
"k8s.io/controller-manager/controller"
|
||||||
|
"k8s.io/kubernetes/cmd/kube-controller-manager/names"
|
||||||
endpointslicecontroller "k8s.io/kubernetes/pkg/controller/endpointslice"
|
endpointslicecontroller "k8s.io/kubernetes/pkg/controller/endpointslice"
|
||||||
endpointslicemirroringcontroller "k8s.io/kubernetes/pkg/controller/endpointslicemirroring"
|
endpointslicemirroringcontroller "k8s.io/kubernetes/pkg/controller/endpointslicemirroring"
|
||||||
)
|
)
|
||||||
|
|
||||||
func startEndpointSliceController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newEndpointSliceControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.EndpointSliceController,
|
||||||
|
aliases: []string{"endpointslice"},
|
||||||
|
initFunc: startEndpointSliceController,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startEndpointSliceController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
go endpointslicecontroller.NewController(
|
go endpointslicecontroller.NewController(
|
||||||
ctx,
|
ctx,
|
||||||
controllerContext.InformerFactory.Core().V1().Pods(),
|
controllerContext.InformerFactory.Core().V1().Pods(),
|
||||||
@ -41,7 +50,15 @@ func startEndpointSliceController(ctx context.Context, controllerContext Control
|
|||||||
return nil, true, nil
|
return nil, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func startEndpointSliceMirroringController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newEndpointSliceMirroringControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.EndpointSliceMirroringController,
|
||||||
|
aliases: []string{"endpointslicemirroring"},
|
||||||
|
initFunc: startEndpointSliceMirroringController,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startEndpointSliceMirroringController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
go endpointslicemirroringcontroller.NewController(
|
go endpointslicemirroringcontroller.NewController(
|
||||||
ctx,
|
ctx,
|
||||||
controllerContext.InformerFactory.Core().V1().Endpoints(),
|
controllerContext.InformerFactory.Core().V1().Endpoints(),
|
||||||
|
@ -25,10 +25,19 @@ import (
|
|||||||
"k8s.io/client-go/dynamic"
|
"k8s.io/client-go/dynamic"
|
||||||
"k8s.io/client-go/scale"
|
"k8s.io/client-go/scale"
|
||||||
"k8s.io/controller-manager/controller"
|
"k8s.io/controller-manager/controller"
|
||||||
|
"k8s.io/kubernetes/cmd/kube-controller-manager/names"
|
||||||
"k8s.io/kubernetes/pkg/controller/disruption"
|
"k8s.io/kubernetes/pkg/controller/disruption"
|
||||||
)
|
)
|
||||||
|
|
||||||
func startDisruptionController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newDisruptionControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.DisruptionController,
|
||||||
|
aliases: []string{"disruption"},
|
||||||
|
initFunc: startDisruptionController,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startDisruptionController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
client := controllerContext.ClientBuilder.ClientOrDie("disruption-controller")
|
client := controllerContext.ClientBuilder.ClientOrDie("disruption-controller")
|
||||||
config := controllerContext.ClientBuilder.ConfigOrDie("disruption-controller")
|
config := controllerContext.ClientBuilder.ConfigOrDie("disruption-controller")
|
||||||
scaleKindResolver := scale.NewDiscoveryScaleKindResolver(client.Discovery())
|
scaleKindResolver := scale.NewDiscoveryScaleKindResolver(client.Discovery())
|
||||||
|
@ -20,10 +20,19 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"k8s.io/controller-manager/controller"
|
"k8s.io/controller-manager/controller"
|
||||||
|
"k8s.io/kubernetes/cmd/kube-controller-manager/names"
|
||||||
"k8s.io/kubernetes/pkg/controller/clusterroleaggregation"
|
"k8s.io/kubernetes/pkg/controller/clusterroleaggregation"
|
||||||
)
|
)
|
||||||
|
|
||||||
func startClusterRoleAggregrationController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newClusterRoleAggregrationControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.ClusterRoleAggregationController,
|
||||||
|
aliases: []string{"clusterrole-aggregation"},
|
||||||
|
initFunc: startClusterRoleAggregationController,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startClusterRoleAggregationController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
go clusterroleaggregation.NewClusterRoleAggregation(
|
go clusterroleaggregation.NewClusterRoleAggregation(
|
||||||
controllerContext.InformerFactory.Rbac().V1().ClusterRoles(),
|
controllerContext.InformerFactory.Rbac().V1().ClusterRoles(),
|
||||||
controllerContext.ClientBuilder.ClientOrDie("clusterrole-aggregation-controller").RbacV1(),
|
controllerContext.ClientBuilder.ClientOrDie("clusterrole-aggregation-controller").RbacV1(),
|
||||||
|
@ -33,7 +33,6 @@ import (
|
|||||||
"k8s.io/kubernetes/cmd/kube-controller-manager/app"
|
"k8s.io/kubernetes/cmd/kube-controller-manager/app"
|
||||||
kubecontrollerconfig "k8s.io/kubernetes/cmd/kube-controller-manager/app/config"
|
kubecontrollerconfig "k8s.io/kubernetes/cmd/kube-controller-manager/app/config"
|
||||||
"k8s.io/kubernetes/cmd/kube-controller-manager/app/options"
|
"k8s.io/kubernetes/cmd/kube-controller-manager/app/options"
|
||||||
"k8s.io/kubernetes/cmd/kube-controller-manager/names"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -97,7 +96,7 @@ func StartTestServer(ctx context.Context, customFlags []string) (result TestServ
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return TestServer{}, err
|
return TestServer{}, err
|
||||||
}
|
}
|
||||||
all, disabled, aliases := app.KnownControllers(), app.ControllersDisabledByDefault.List(), names.KCMControllerAliases()
|
all, disabled, aliases := app.KnownControllers(), app.ControllersDisabledByDefault(), app.ControllerAliases()
|
||||||
namedFlagSets := s.Flags(all, disabled, aliases)
|
namedFlagSets := s.Flags(all, disabled, aliases)
|
||||||
for _, f := range namedFlagSets.FlagSets {
|
for _, f := range namedFlagSets.FlagSets {
|
||||||
fs.AddFlagSet(f)
|
fs.AddFlagSet(f)
|
||||||
|
@ -21,14 +21,26 @@ import (
|
|||||||
|
|
||||||
pluginvalidatingadmissionpolicy "k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy"
|
pluginvalidatingadmissionpolicy "k8s.io/apiserver/pkg/admission/plugin/validatingadmissionpolicy"
|
||||||
"k8s.io/apiserver/pkg/cel/openapi/resolver"
|
"k8s.io/apiserver/pkg/cel/openapi/resolver"
|
||||||
|
genericfeatures "k8s.io/apiserver/pkg/features"
|
||||||
"k8s.io/client-go/kubernetes/scheme"
|
"k8s.io/client-go/kubernetes/scheme"
|
||||||
|
"k8s.io/component-base/featuregate"
|
||||||
"k8s.io/controller-manager/controller"
|
"k8s.io/controller-manager/controller"
|
||||||
"k8s.io/kubernetes/cmd/kube-controller-manager/names"
|
"k8s.io/kubernetes/cmd/kube-controller-manager/names"
|
||||||
"k8s.io/kubernetes/pkg/controller/validatingadmissionpolicystatus"
|
"k8s.io/kubernetes/pkg/controller/validatingadmissionpolicystatus"
|
||||||
"k8s.io/kubernetes/pkg/generated/openapi"
|
"k8s.io/kubernetes/pkg/generated/openapi"
|
||||||
)
|
)
|
||||||
|
|
||||||
func startValidatingAdmissionPolicyStatusController(ctx context.Context, controllerContext ControllerContext) (controller.Interface, bool, error) {
|
func newValidatingAdmissionPolicyStatusControllerDescriptor() *ControllerDescriptor {
|
||||||
|
return &ControllerDescriptor{
|
||||||
|
name: names.ValidatingAdmissionPolicyStatusController,
|
||||||
|
initFunc: startValidatingAdmissionPolicyStatusController,
|
||||||
|
requiredFeatureGates: []featuregate.Feature{
|
||||||
|
genericfeatures.ValidatingAdmissionPolicy,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func startValidatingAdmissionPolicyStatusController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
|
||||||
// KCM won't start the controller without the feature gate set.
|
// KCM won't start the controller without the feature gate set.
|
||||||
typeChecker := &pluginvalidatingadmissionpolicy.TypeChecker{
|
typeChecker := &pluginvalidatingadmissionpolicy.TypeChecker{
|
||||||
SchemaResolver: resolver.NewDefinitionsSchemaResolver(scheme.Scheme, openapi.GetOpenAPIDefinitions),
|
SchemaResolver: resolver.NewDefinitionsSchemaResolver(scheme.Scheme, openapi.GetOpenAPIDefinitions),
|
||||||
|
@ -16,8 +16,6 @@ limitations under the License.
|
|||||||
|
|
||||||
package names
|
package names
|
||||||
|
|
||||||
import cpnames "k8s.io/cloud-provider/names"
|
|
||||||
|
|
||||||
// Canonical controller names
|
// Canonical controller names
|
||||||
//
|
//
|
||||||
// NAMING CONVENTIONS
|
// NAMING CONVENTIONS
|
||||||
@ -28,23 +26,19 @@ import cpnames "k8s.io/cloud-provider/names"
|
|||||||
// CHANGE POLICY
|
// CHANGE POLICY
|
||||||
// The controller names should be treated as IDs.
|
// The controller names should be treated as IDs.
|
||||||
// They can only be changed if absolutely necessary. For example if an inappropriate name was chosen in the past, or if the scope of the controller changes.
|
// They can only be changed if absolutely necessary. For example if an inappropriate name was chosen in the past, or if the scope of the controller changes.
|
||||||
// When a name is changed, the old name should be aliased in KCMControllerAliases, while preserving all old aliases.
|
// When a name is changed, the old name should be aliased in app.ControllerDescriptor#GetAliases, while preserving all old aliases.
|
||||||
// This is done to achieve backwards compatibility
|
// This is done to achieve backwards compatibility
|
||||||
//
|
//
|
||||||
// USE CASES
|
// USE CASES
|
||||||
// The following places should use the controller name constants, when:
|
// The following places should use the controller name constants, when:
|
||||||
// 1. registering a controller in app.NewControllerInitializers or app.KnownControllers:
|
// 1. defining a new app.ControllerDescriptor so it can be used in app.NewControllerDescriptors or app.KnownControllers:
|
||||||
// 1.1. disabling a controller by default in app.ControllersDisabledByDefault
|
|
||||||
// 1.2. checking if IsControllerEnabled
|
|
||||||
// 1.3. defining an alias in KCMControllerAliases (for backwards compatibility only)
|
|
||||||
// 2. used anywhere inside the controller itself:
|
// 2. used anywhere inside the controller itself:
|
||||||
// 2.1. [TODO] logger component should be configured with the controller name by calling LoggerWithName
|
// 2.1. [TODO] logging should use a canonical controller name when referencing a controller (Eg. Starting X, Shutting down X)
|
||||||
// 2.2. [TODO] logging should use a canonical controller name when referencing a controller (Eg. Starting X, Shutting down X)
|
// 2.2. [TODO] emitted events should have an EventSource.Component set to the controller name (usually when initializing an EventRecorder)
|
||||||
// 2.3. [TODO] emitted events should have an EventSource.Component set to the controller name (usually when initializing an EventRecorder)
|
// 2.3. [TODO] registering ControllerManagerMetrics with ControllerStarted and ControllerStopped
|
||||||
// 2.4. [TODO] registering ControllerManagerMetrics with ControllerStarted and ControllerStopped
|
// 2.4. [TODO] calling WaitForNamedCacheSync
|
||||||
// 2.5. [TODO] calling WaitForNamedCacheSync
|
|
||||||
// 3. defining controller options for "--help" command or generated documentation
|
// 3. defining controller options for "--help" command or generated documentation
|
||||||
// 3.1. controller name should be used to create a pflag.FlagSet when registering controller options (the name is rendered in a controller flag group header)
|
// 3.1. controller name should be used to create a pflag.FlagSet when registering controller options (the name is rendered in a controller flag group header) in options.KubeControllerManagerOptions
|
||||||
// 3.2. when defined flag's help mentions a controller name
|
// 3.2. when defined flag's help mentions a controller name
|
||||||
// 4. defining a new service account for a new controller (old controllers may have inconsistent service accounts to stay backwards compatible)
|
// 4. defining a new service account for a new controller (old controllers may have inconsistent service accounts to stay backwards compatible)
|
||||||
const (
|
const (
|
||||||
@ -88,54 +82,3 @@ const (
|
|||||||
LegacyServiceAccountTokenCleanerController = "legacy-serviceaccount-token-cleaner-controller"
|
LegacyServiceAccountTokenCleanerController = "legacy-serviceaccount-token-cleaner-controller"
|
||||||
ValidatingAdmissionPolicyStatusController = "validatingadmissionpolicy-status-controller"
|
ValidatingAdmissionPolicyStatusController = "validatingadmissionpolicy-status-controller"
|
||||||
)
|
)
|
||||||
|
|
||||||
// KCMControllerAliases returns a mapping of aliases to canonical controller names
|
|
||||||
//
|
|
||||||
// These aliases ensure backwards compatibility and should never be removed!
|
|
||||||
// Only addition of new aliases is allowed, and only when a canonical name is changed (please see CHANGE POLICY of controller names)
|
|
||||||
func KCMControllerAliases() map[string]string {
|
|
||||||
// return a new reference to achieve immutability of the mapping
|
|
||||||
return map[string]string{
|
|
||||||
"serviceaccount-token": ServiceAccountTokenController,
|
|
||||||
"endpoint": EndpointsController,
|
|
||||||
"endpointslice": EndpointSliceController,
|
|
||||||
"endpointslicemirroring": EndpointSliceMirroringController,
|
|
||||||
"replicationcontroller": ReplicationControllerController,
|
|
||||||
"podgc": PodGarbageCollectorController,
|
|
||||||
"resourcequota": ResourceQuotaController,
|
|
||||||
"namespace": NamespaceController,
|
|
||||||
"serviceaccount": ServiceAccountController,
|
|
||||||
"garbagecollector": GarbageCollectorController,
|
|
||||||
"daemonset": DaemonSetController,
|
|
||||||
"job": JobController,
|
|
||||||
"deployment": DeploymentController,
|
|
||||||
"replicaset": ReplicaSetController,
|
|
||||||
"horizontalpodautoscaling": HorizontalPodAutoscalerController,
|
|
||||||
"disruption": DisruptionController,
|
|
||||||
"statefulset": StatefulSetController,
|
|
||||||
"cronjob": CronJobController,
|
|
||||||
"csrsigning": CertificateSigningRequestSigningController,
|
|
||||||
"csrapproving": CertificateSigningRequestApprovingController,
|
|
||||||
"csrcleaner": CertificateSigningRequestCleanerController,
|
|
||||||
"ttl": TTLController,
|
|
||||||
"bootstrapsigner": BootstrapSignerController,
|
|
||||||
"tokencleaner": TokenCleanerController,
|
|
||||||
"nodeipam": NodeIpamController,
|
|
||||||
"nodelifecycle": NodeLifecycleController,
|
|
||||||
"service": cpnames.ServiceLBController,
|
|
||||||
"route": cpnames.NodeRouteController,
|
|
||||||
"cloud-node-lifecycle": cpnames.CloudNodeLifecycleController,
|
|
||||||
"persistentvolume-binder": PersistentVolumeBinderController,
|
|
||||||
"attachdetach": PersistentVolumeAttachDetachController,
|
|
||||||
"persistentvolume-expander": PersistentVolumeExpanderController,
|
|
||||||
"clusterrole-aggregation": ClusterRoleAggregationController,
|
|
||||||
"pvc-protection": PersistentVolumeClaimProtectionController,
|
|
||||||
"pv-protection": PersistentVolumeProtectionController,
|
|
||||||
"ttl-after-finished": TTLAfterFinishedController,
|
|
||||||
"root-ca-cert-publisher": RootCACertificatePublisherController,
|
|
||||||
"ephemeral-volume": EphemeralVolumeController,
|
|
||||||
"storage-version-gc": StorageVersionGarbageCollectorController,
|
|
||||||
"resource-claim-controller": ResourceClaimController,
|
|
||||||
"legacy-service-account-token-cleaner": LegacyServiceAccountTokenCleanerController,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user