Skip to content
This repository was archived by the owner on Oct 28, 2024. It is now read-only.

Commit 44c6456

Browse files
edit the proposal
1 parent 462c67d commit 44c6456

File tree

1 file changed

+89
-42
lines changed

1 file changed

+89
-42
lines changed

proposals/20201026-creating-control-plane.md

Lines changed: 89 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ authors:
55
reviewers:
66
- "@christopherhein"
77
- "@Fei-Guo"
8+
- "@vincepri"
9+
- "@brightzheng100"
810
creation-date: 2020-10-26
911
last-updated: 2020-11-09
1012
status: provisional
@@ -46,6 +48,12 @@ The followings are terms that will be used in the proposal. Whether including th
4648

4749
* **NestedControlPlane(NCP)** - The control plane that are hosted on the super cluster.
4850

51+
* **NestedEtcd(NEtcd)** - The etcd that belongs to the control plane of the nested cluster.
52+
53+
* **NestedAPIServer(NKAS)** - The kube-apiserver which belongs to the control plane of the nested cluster.
54+
55+
* **NestedControllerManager(NKCM)** - The kube-control-manager which belongs to the control plane of the nested cluster.
56+
4957
* **Component Controller** - Operators that create components of the NCP, including the Etcd controller, KAS controller and KCM controller.
5058

5159
To better illustrate the creation process, we define two Roles with different responsibilities:
@@ -61,7 +69,7 @@ The goal of this proposal is to define CRDs of the three major components (kube-
6169

6270
## Motivation
6371

64-
CAPN aims at providing control-plane level isolation while sharing physical resources among control planes. There exist various approaches to creating isolated control-planes. For example, one can run components of the nested control-plane as pods on the underlying clusters, create NCPs through cloud providers' Kubernetes services or use third-party component providers to create each component. In this proposal, we try to define CRDs of the NCP's three major components and a standard process of creating the three components regardless of which underlying approach is used. As examples, we introduce two setups that 1) creating each component natively, 2) creating KAM and KCM natively while using the [Etcd-cluster-operator](https://github.com/improbable-eng/etcd-cluster-operator) to create the Etcd.
72+
CAPN aims at providing control plane level isolation while sharing physical resources among control planes. There exist various approaches to creating isolated control planes. For example, one can run components of the nested control plane as pods on the underlying clusters, create NCPs through cloud providers' Kubernetes services or use third-party component providers to create each component. In this proposal, we try to define CRDs of the NCP's three major components and a standard process of creating the three components regardless of which underlying approach is used. As examples, we introduce two setups that 1) creating each component natively, 2) creating KAM and KCM natively while using the [Etcd-cluster-operator](https://github.com/improbable-eng/etcd-cluster-operator) to create the Etcd.
6573

6674
### Goals
6775

@@ -77,17 +85,17 @@ CAPN aims at providing control-plane level isolation while sharing physical reso
7785

7886
- Define how NCP controller works.
7987

80-
- Discuss the details of how the third-party component provider work.
88+
- Discuss the implementation details of the out-of-tree component controllers.
8189

8290
## Proposal
8391

8492
### Portability and Customizability
8593

86-
Generally, creating the three major components requires similar high-level information, like the components' version, the number of replicas, and the amount of computing resources. Meanwhile, end-users should be able to customize NCP components, i.e., specifying the component image, version, and command-line options. Therefore, we define a new struct `ComponentSpec` that contains common information required by different providers as well as customized information specified by the end-users. The `ComponentSpec` will look like the following
94+
Generally, creating the three major components requires similar high-level information, like the components' version, the number of replicas, and the amount of computing resources. Meanwhile, end-users should be able to customize NCP components, i.e., specifying the component image, version, and command-line options. Therefore, we define a new struct `NestedComponentSpec` that contains common information required by different providers as well as customized information specified by the end-users. The `NestedComponentSpec` will look like the following
8795

8896
```go
89-
type ComponentSpec struct {
90-
// ComponentSpec defines the common information for creating the component
97+
type NestedComponentSpec struct {
98+
// NestedComponentSpec defines the common information for creating the component
9199
// +optional
92100
addonv1alpha1.CommonSpec `json:",inline"`
93101

@@ -129,19 +137,58 @@ type PatchSpec struct {
129137

130138
#### Create prerequisites
131139

132-
We assume that the APIServer, ContollerManager, Etcd and the NCP CR are located in the same namespace. To create an NCP, we need to first create APIserver CR, ControllerManager CR, Etcd CR, NCP CR, and a namespace that holds all the CRs, then the sub-controllers can cooperate with each other to create components for the NCP.
140+
We assume that the APIServer, ContollerManager, Etcd and the NCP CR are located in the same namespace. To create an NCP, we need to first create APIserver CR, ControllerManager CR, Etcd CR, NCP CR, and a namespace that holds all the CRs, then the component controller can cooperate with each other to create components for the NCP.
133141

134-
As there exist dependencies between components, i.e., KAS cannot run without Etcd, KCM cannot work without KAS, when creating the NCP component, sub-controllers will need to get information and status of other CRs. Also, as all CRs of an NCP will be located in the same namespace, we will set `metav1.OwnerReference` in each component CR as the NCP that owns the CR, which can help the CR to find its belonging NCP. As the NCP status will include all required [CAPI status](https://cluster-api.sigs.k8s.io/developer/architecture/controllers/control-plane.html#required-status-fields), we can then use the `Selector` field to get the desired CR.
142+
As there exist dependencies between components, i.e., KAS cannot run without Etcd, KCM cannot work without KAS, when creating NCP components, component controllers will need to get information and status of other CRs. Also, as all CRs of an NCP will be located in the same namespace, we will set `metav1.OwnerReference` in each component CR as the NCP that owns the CR, which can help the CR to find its belonging NCP. As the NCP status will include all required [CAPI status](https://cluster-api.sigs.k8s.io/developer/architecture/controllers/control-plane.html#required-status-fields), we can then use the `Selector` field to get the desired CR.
135143

136144
### Creation
137145

138-
End-users can create component CRs manually and apply them to the cluster with an NCP to create the resources. In the future, we might introduce the `Template` CR, which will handle the creation of the component CRs in it's controller. We assume that on a super cluster, there will be only one sub-controller for each component CR, and it's the cluster admin's responsibility to setup sub-controllers.
146+
End-users can create component CRs manually and apply them to the cluster with an NCP to create the resources. In the future, we might introduce the `Template` CR, which will handle the creation of the component CRs in it's controller. If the end-user intend to use out-of-tree controllers, they can specify them in the NCP spec, we define three new types:
147+
148+
```go
149+
type NestedKASProvider string
150+
151+
type NestedEtcdProvider string
152+
153+
type NestedKCMProvider string
154+
155+
const (
156+
NativeKASProvider NestedKASProvider = "NativeKASProvider"
157+
158+
NativeEtcdProvider NestedEtcdProvider = "NativeEtcdProvider"
159+
EtcdClusterOperator NestedEtcdProvider = "EtcdClusterOperator"
160+
EtcdOperator NestedEtcdProvider = "EtcdOperator"
161+
162+
NativeKCMProvider NestedKCMProvider = "NativeKCMProvider"
163+
)
164+
```
165+
166+
and adds three new fields into the NCP spec:
167+
168+
```go
169+
type NestedControlPlaneSpec struct {
170+
// other fields ...
171+
172+
// EtcdProvider specifies which EtcdProvider will be used to create the Etcd
173+
// +optional
174+
EtcdProvider NestedEtcdProvider `json:"etcdProvider,omitempty"`
175+
176+
// ApiServerProvider specifies which KASProvider will be used to create the kube-apiserver
177+
// +optional
178+
ApiServerProvider NestedKASProvider `json:"apiServerProvider,omitempty"`
179+
180+
// ControllerManagerProvider specifies which KCMProvider will be used to create the kube-controller-manager
181+
// +optional
182+
ControllerManagerProvider NestedKCMProvider `json:"controllerManagerProvider,omitempty"`
183+
}
184+
```
185+
139186

140187
#### Native way
141188

142-
If no component provider is specified, the sub-controller will create the component under the native mode, which will create the component using the default manifests. The readiness and liveness probe will be used, and we will mark each component as ready only when the corresponding workload is ready. As the KAS cannot work without available Etcd and the KCM cannot run without KAS, the three components need to be created by their respective controllers in the order of Etcd, KAS, and KCM. Creation order is maintained using cross resource status checks to "wait" until the dependencies are provisioned before booting.
189+
If no component provider is specified, the component controller will create the component under the native mode, which will create the component using the default manifests. The readiness and liveness probe will be used, and we will mark each component as ready only when the corresponding workload is ready. As the KAS cannot work without available Etcd and the KCM cannot run without KAS, the three components need to be created by their respective controllers in the order of Etcd, KAS, and KCM. Creation order is maintained using cross resource status checks to "wait" until the dependencies are provisioned before booting.
143190

144-
Except using `OwnerReference` and `CAPI.Status.Selector`, another option of sharing status across components are adding initContainer to each component. The sub-controllers will then create the component workload without polling the status of other CRs while having the initContainer to check and wait for other components to be ready.
191+
Except using `OwnerReference` and `CAPI.Status.Selector`, another option of sharing status across components are adding initContainer to each component. The component controllers will then create the component workload without polling the status of other CRs while having the initContainer to check and wait for other components to be ready.
145192

146193
We will host sets of default templates in this repositor. Users can specify which set of templates they intend to use by specifying the corresponding `version` or `channel` in the embedded `CommonSpec` in the component's CR.
147194

@@ -185,18 +232,18 @@ In the following example, we assume that the user intend to use Etcd-cluster-ope
185232

186233
The followings are CRDs of the three components.
187234

188-
### Etcd CRD
235+
### NestedEtcd CRD
189236
```go
190-
// EtcdSpec defines the desired state of Etcd
191-
type EtcdSpec struct {
192-
// ComponentSpec contains the common and user-specified information that are
237+
// NestedEtcdSpec defines the desired state of Etcd
238+
type NestedEtcdSpec struct {
239+
// NestedComponentSpec contains the common and user-specified information that are
193240
// required for creating the component
194241
// +optional
195-
ComponentSpec ComponentSpec `json:",inline"`
242+
NestedComponentSpec `json:",inline"`
196243
}
197244

198-
// EtcdStatus defines the observed state of Etcd
199-
type EtcdStatus struct {
245+
// NestedEtcdStatus defines the observed state of Etcd
246+
type NestedEtcdStatus struct {
200247
// Ready is set if all resources have been created
201248
Ready bool `json:"ready,omitempty"`
202249

@@ -207,14 +254,14 @@ type EtcdStatus struct {
207254
ProviderObject *corev1.ObjectReference `json:referralObject,omitempty`
208255

209256
// EtcdDomain defines how to address the etcd instance
210-
Addresses []EtcdAddress `json:"addresses,omitempty"`
257+
Addresses []NestedEtcdAddress `json:"addresses,omitempty"`
211258

212259
// CommonStatus allows addons status monitoring
213260
CommonStatus addonv1alpha1. CommonStatus `json:",inline"`
214261
}
215262

216263
// EtcdAddress defines the observed addresses for etcd
217-
type EtcdAddress struct {
264+
type NestedEtcdAddress struct {
218265
// IP Address of the etcd instance.
219266
// +optional
220267
IP string `json:"ip,omitempty"`
@@ -227,8 +274,8 @@ type EtcdAddress struct {
227274
Port int32 `json:"port"`
228275
}
229276

230-
// Etcd is the Schema for the Etcd API
231-
type Etcd struct {
277+
// NestedEtcd is the Schema for the Etcd API
278+
type NestedEtcd struct {
232279
metav1.TypeMeta `json:",inline"`
233280
metav1.ObjectMeta `json:"metadata,omitempty"`
234281

@@ -237,18 +284,18 @@ type Etcd struct {
237284
}
238285
```
239286

240-
### APIServer CRD
287+
### NestedAPIServer CRD
241288

242289
```go
243-
type APIServerSpec struct {
244-
// ComponentSpec contains the common and user-specified information that are
290+
type NestedAPIServerSpec struct {
291+
// NestedComponentSpec contains the common and user-specified information that are
245292
// required for creating the component
246293
// +optional
247-
ComponentSpec ComponentSpec `json:",inline"`
294+
NestedComponentSpec `json:",inline"`
248295
}
249296

250-
// APIServerStatus defines the observed state of APIServer
251-
type APIServerStatus struct {
297+
// NestedAPIServerStatus defines the observed state of APIServer
298+
type NestedAPIServerStatus struct {
252299
// Ready is set if all resources have been created
253300
// +kubebuilder:default=false
254301
Ready bool `json:"ready,omitempty"`
@@ -266,29 +313,29 @@ type APIServerStatus struct {
266313
CommonStatus addonv1alpha1. CommonStatus `json:",inline"`
267314
}
268315

269-
// APIServer is the Schema for the APIServers API
270-
type APIServer struct {
316+
// NestedAPIServer is the Schema for the APIServers API
317+
type NestedAPIServer struct {
271318
metav1.TypeMeta `json:",inline"`
272319
metav1.ObjectMeta `json:"metadata,omitempty"`
273320

274-
Spec APIServerSpec `json:"spec,omitempty"`
275-
Status APIServerStatus `json:"status,omitempty"`
321+
Spec NestedAPIServerSpec `json:"spec,omitempty"`
322+
Status NestedAPIServerStatus `json:"status,omitempty"`
276323
}
277324
```
278325

279-
### ControllerManager CRD
326+
### NestedControllerManager CRD
280327

281328
```go
282-
// ControllerManagerSpec defines the desired state of ControllerManager
283-
type ControllerManagerSec struct {
284-
// ComponentSpec contains the common and user-specified information that are
329+
// NestedControllerManagerSpec defines the desired state of ControllerManager
330+
type NestedControllerManagerSec struct {
331+
// NestedComponentSpec contains the common and user-specified information that are
285332
// required for creating the component
286333
// +optional
287-
ComponentSpec ComponentSpec `json:",inline"`
334+
NestedComponentSpec `json:",inline"`
288335
}
289336

290-
// ControllerManagerStatus defines the observed state of ControllerManager
291-
type ControllerManagerStatus struct {
337+
// NestedControllerManagerStatus defines the observed state of ControllerManager
338+
type NestedControllerManagerStatus struct {
292339
// Ready is set if all resources have been created
293340
Ready bool `json:"ready,omitempty"`
294341

@@ -301,13 +348,13 @@ type ControllerManagerStatus struct {
301348
CommonStatus addonv1alpha1. CommonStatus `json:",inline"`
302349
}
303350

304-
// ControllerManager is the Schema for the ControllerManagers API
305-
type ControllerManager struct {
351+
// NestedControllerManager is the Schema for the ControllerManagers API
352+
type NestedControllerManager struct {
306353
metav1.TypeMeta `json:",inline"`
307354
metav1.ObjectMeta `json:"metadata,omitempty"`
308355

309-
Spec ControllerManagerSpec `json:"spec,omitempty"`
310-
Status ControllerManagerStatus `json:"status,omitempty"`
356+
Spec NestedControllerManagerSpec `json:"spec,omitempty"`
357+
Status NestedControllerManagerStatus `json:"status,omitempty"`
311358
}
312359
```
313360

0 commit comments

Comments
 (0)