From f41fc62d978c501a3c6b1a6c3c2a5069a273efd2 Mon Sep 17 00:00:00 2001 From: Chris Hein Date: Mon, 24 Feb 2020 16:44:51 -0800 Subject: [PATCH] Adding component config proposal Signed-off-by: Chris Hein --- designs/component-config.md | 241 +++++++++++++++++++++++ designs/images/component-config-load.png | Bin 0 -> 28512 bytes 2 files changed, 241 insertions(+) create mode 100644 designs/component-config.md create mode 100644 designs/images/component-config-load.png diff --git a/designs/component-config.md b/designs/component-config.md new file mode 100644 index 0000000000..26b9fb56a9 --- /dev/null +++ b/designs/component-config.md @@ -0,0 +1,241 @@ +# ComponentConfig Controller Runtime Support + +Author: @christopherhein +Last Updated on: 02/24/2020 + +## Table of Contents + + + * [ComponentConfig Controller Runtime Support](#componentconfig-controller-runtime-support) + * [Table of Contents](#table-of-contents) + * [Summary](#summary) + * [Motivation](#motivation) + * [Links to Open Issues](#links-to-open-issues) + * [Goals](#goals) + * [Non-Goals/Future Work](#non-goalsfuture-work) + * [Proposal](#proposal) + * [ComponentConfig Load Order](#componentconfig-load-order) + * [User Stories](#user-stories) + * [Controller Author with controller-runtime](#controller-author-with-controller-runtime) + * [Controller Author with kubebuilder (tbd proposal for kubebuilder)](#controller-author-with-kubebuilder-tbd-proposal-for-kubebuilder) + * [Controller User without modifications to config](#controller-user-without-modifications-to-config) + * [Controller User with modifications to config](#controller-user-with-modifications-to-config) + * [Risks and Mitigations](#risks-and-mitigations) + * [Alternatives](#alternatives) + * [Implementation History](#implementation-history) + + + +## Summary + +Currently all any controller that uses `controller-runtime` needs to configure the `ctrl.Manager` by using flags or hard coding values into the initialization methods. Core Kubernetes resources have started to move away from using flags as a mechanism for configuring the component and standardized along the pattern of [`ComponentConfig` or Versioned Component Configuration Files](https://docs.google.com/document/d/1FdaEJUEh091qf5B98HM6_8MS764iXrxxigNIdwHYW9c/edit). This proposal is to bring `ComponentConfig` patterns into `controller-runtime` to allow controller authors to make `go` types backed by apimachinery to unmarshal and configure the `ctrl.Manager` reducing the flags and allowing code based tools to easily configure controllers instead of requiring them to mutate CLI args. + +## Motivation + +This change is important because: +- it will help make it easier for controllers to be configured by other machine processes +- it will reduce the upfront flags required to start a controller +- allow for more configuration types which flags don't natively support + +### Links to Open Issues + +- [Provide a ComponentConfig to tweak the Manager](https://github.com/kubernetes-sigs/controller-runtime/issues/518) +- [Reduce command line flag boilerplate](https://github.com/kubernetes-sigs/controller-runtime/issues/207) +- [Implement ComponentConfig by default & stop using (most) flags](https://github.com/kubernetes-sigs/kubebuilder/issues/722) + +### Goals + +- Provide an interface for pulling configuration data out of exposed `ComponentConfig` types (see below for implementation) +- Provide a new `ctrl.NewFromComponentConfig()` function for initializing a manager + +### Non-Goals/Future Work + +- `kubebuilder` implementation and design in another PR +- Changing the default `controller-runtime` implementation +- Dynamically reloading ComponentConfig object + +## Proposal + +The `ctrl.Manager` _SHOULD_ to be able to support load configurations from an interface with getters to pull the specific configuration parameters out of it so that we can use `ComponentConfig` like objects to load the configuration from. + +Without breaking the current `ctrl.NewManager` which uses an exported `ctrl.Options{}` the `manager.go` can expose a new func, `NewFromComponentConfig()` this would be able to loop through the getters to hydrate an internal `ctrl.Options{}` and pass that into `New()`. + +File: _`pkg/manager/manager.go`_ +```golang +// ManagerConfiguration defines what the ComponentConfig object for ControllerRuntime needs to support +type ManagerConfiguration interface { + GetSyncPeriod() *time.Duration + + GetLeaderElection() bool + GetLeaderElectionNamespace() string + GetLeaderElectionID() string + + GetLeaseDuration() *time.Duration + GetRenewDeadline() *time.Duration + GetRetryPeriod() *time.Duration + + GetNamespace() string + GetMetricsBindAddress() string + GetHealthProbeBindAddress() string + + GetReadinessEndpointName() string + GetLivenessEndpointName() string + + GetPort() int + GetHost() string + + GetCertDir() string +} + +func NewFromComponentConfig(config *rest.Config, scheme *runtime.Scheme, managerconfig ManagerConfiguration) (Manager, error) { + options := Options{} + + if scheme != nil { + options.Scheme = scheme + } + + // Loop through getters + if managerconfig.GetLeaderElection() { + managerconfig.GetLeaderElection() + } + // ... + + return New(config, options) +} +``` + +#### ComponentConfig Load Order + +![ComponentConfig Load Order](/designs/images/component-config-load.png) + +Within a separate design (link once created) this will require controller authors to generate a type that implements the `ManagerConfiguration` interface. The following is a sample of what this looks like: + +```golang +package config + +import ( + "time" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type ControllerNameConfigurationSpec struct { + LeaderElection ControllerNameConfigurationLeaderElection `json:"leaderElection,omitempty"` + + LeaseDuration *time.Duration `json:"leaseDuration,omitempty"` + RenewDeadline *time.Duration `json:"renewDeadline,omitempty"` + RetryPeriod *time.Duration`json:"retryPeriod,omitempty"` + + Namespace string `json:"namespace,omitempty"` + + MetricsBindAddress string `json:"metricsBindAddress,omitempty"` + + Health ControllerNameConfigurationHealth + + Port int `json:"port,omitempty"` + Host string `json:"host,omitempty"` + + CertDir string `json:"certDir,omitempty"` +} + +type ControllerNameConfigurationLeaderElection struct { + Enabled bool `json:"enabled,omitempty"` + Namespace string `json:"namespace,omitempty"` + ID string `json:"id,omitempty"` +} + +type ControllerNameConfigurationHealth struct { + HealthProbeBindAddress string `json:"healthProbeBindAddress,omitempty"` + + ReadinessEndpointName string `json:"readinessEndpointName,omitempty"` + LivenessEndpointName string `json:"livenessEndpointName,omitempty"` +} + +type ControllerNameConfiguration struct { + metav1.TypeMeta + + Spec ControllerNameConfigurationSpec `json:"spec"` +} +``` + +With the above `struct` we would need to implement the getters to satisfy the `ManagerConfiguration` interface, these could be automatically generated when you `init` or `create componentconfig` from the `kubebuilder` CLI. This could be something as simple as the following. + +```golang +package config + +import ( + "time" +) + +func (in *ControllerNameConfiguration) GetSyncPeriod() *time.Duration {} +func (in *ControllerNameConfiguration) GetLeaderElection() bool {} +func (in *ControllerNameConfiguration) GetLeaderElectionNamespace() string {} +func (in *ControllerNameConfiguration) GetLeaderElectionID() string {} + +func (in *ControllerNameConfiguration) GetLeaseDuration() *time.Duration {} +func (in *ControllerNameConfiguration) GetRenewDeadline() *time.Duration {} +func (in *ControllerNameConfiguration) GetRetryPeriod() *time.Duration {} + +func (in *ControllerNameConfiguration) GetNamespace() string {} +func (in *ControllerNameConfiguration) GetMetricsBindAddress() string {} +func (in *ControllerNameConfiguration) GetHealthProbeBindAddress() string {} + +func (in *ControllerNameConfiguration) GetReadinessEndpointName() string {} +func (in *ControllerNameConfiguration) GetLivenessEndpointName() string {} + +func (in *ControllerNameConfiguration) GetPort() int {} +func (in *ControllerNameConfiguration) GetHost() string {} + +func (in *ControllerNameConfiguration) GetCertDir() string {} +``` + +Besides the implementation of the `ComponentConfig` The controller author as it stands would also need to implement the unmarshalling of the `ConfigMap` into the `ComponentConfig`, for this `controller-runtime` could expose helper methods to load a file from disk, unmarshal to the struct and pass the pointer into the `NewFromComponentConfig()` to return the `ctrl.Manager` + +### User Stories + +#### Controller Author with `controller-runtime` + +- Implement `ComponentConfig` type +- Implement `ManagerConfiguration` interface for `ComponentConfig` object +- Set up `ConfigMap` unmarshalling into `ComponentConfig` type +- Initialize `ctrl.Manager` with `NewFromComponentConfig` +- Build custom controller as usual + +#### Controller Author with `kubebuilder` (tbd proposal for `kubebuilder`) + +- Initialize `kubebuilder` project using `--component-config-name=XYZConfiguration` +- Build custom controller as usual + +#### Controller User without modifications to config + +_Provided that the controller provides manifests_ + +- Apply the controller to the cluster +- Deploy custom resources + +#### Controller User with modifications to config + +- _Following from previous example without changes_ +- Create a new `ConfigMap` for changes +- Modify the `controller-runtime` pod to use the new `ConfigMap` +- Apply the controller to the cluster +- Deploy custom resources + + +### Risks and Mitigations + +- Given that this isn't changing the core Manager initialization for `controller-runtime` it's fairly low risk +- If the underlaying `ctrl.Options{}` + +## Alternatives + +* `NewFromComponentConfig()` could load the object from disk and hydrate the `ComponentConfig` type + +## Implementation History + +- [x] 02/19/2020: Proposed idea in an issue or [community meeting] +- [x] 02/24/2020: Proposal submitted to `controller-runtime` + + + +[community meeting]: https://docs.google.com/document/d/1Ih-2cgg1bUrLwLVTB9tADlPcVdgnuMNBGbUl4D-0TIk diff --git a/designs/images/component-config-load.png b/designs/images/component-config-load.png new file mode 100644 index 0000000000000000000000000000000000000000..04619779dad03e3102f9697368367e39b73e3a3f GIT binary patch literal 28512 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

5bb5p(62J3+YwQHS zfPfTrTeAKNKUBpgT)$3`3)ogn$?-Q8jB9C%;#nU0Qv*@S>rG8e>ZhD(hRci`iApJS zFr$jfzR1<``0-VCFSJA`XtGp28l7-5epc!kPMl9(FfN>Kjz7dE6j3qu+2GC}D8M5V zIm>^658X6@vl!uOXPT8vN`w8n`}@HchH$=^W{1p~2FHekMDzRi_ZrEwT(HUf0>op8Uj$ln-0q^f?cqRUDQB2HV`$~7*A+P z#&!c149-HlKFTw-ziDXv0BA-i3oG2+5!0$jwYZ94zbD^@VW;kajS7y;{BZ0ZNQdhM zj%2Z4Q%J8_Q``>F$l$=7G=HLVDOMciFk2P?MfNzDT2Yy`n@;VMok<$!-xD1#K@1KwBxssAo0RiiBjlN0ZzAhFI zwvzFg%!~n7Nv1p;rN#)LD0=+ne?Nyh_ zymLpA3JBBZoX6=j44Xd*wuX#-8WRQw-O$hwm|`q?&=QIJ&fvg61G007I!?7Rc-FxS zO}}vrfpU2TR?sI;_TxhlzQAEe!EMyTRg8bVE>cSnpxAHD-yJPi0;hztSZUQNLjMAV z2=M;+95^<9NcC#5;zsc>rBw0;%AE@!M3?2{Ji|r_juA%#WMzUPJjX8#oNbmjltrr} z-VK?V3y(An-A{_w9*{c1_Z$0V^`8U}WSRfJKhkIB{H`~>YL4z%cj7*ETTHi^+@~Hm_fNRdV2A(! literal 0 HcmV?d00001