-
Notifications
You must be signed in to change notification settings - Fork 67
WIP: Adding initial proof of concept creating nested CRDs for each object #1
WIP: Adding initial proof of concept creating nested CRDs for each object #1
Conversation
Signed-off-by: Chris Hein <[email protected]>
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: christopherhein The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
/hold |
// annotations that are not visible to Nested Cluster but are kept in | ||
// super master. For example, the annotations added by syncer controller. | ||
// +optional | ||
OpaqueMetaPrefixes []string `json:"opaqueMetaPrefixes,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be removed an implemented somewhere else since this specific to VC
// +kubebuilder:rbac:groups=controlplane.cluster.x-k8s.io,resources=nestedpkis,verbs=get;list;watch;create;update;patch;delete | ||
// +kubebuilder:rbac:groups=controlplane.cluster.x-k8s.io,resources=nestedpkis/status,verbs=get;update;patch | ||
|
||
func (r *NestedPKIReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we implement some of these functions with cert-manager
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// cluster PKI, if not set the PKI will expire after 1 year. | ||
// +optional | ||
// +kubebuilder:default=365 | ||
PKIExpireDays int64 `json:"pkiExpireDays,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I saw PKI and had some quick thoughts:
- it feels rather coarse to set the expiry at the granularity of the whole PKI, rather than specific credentials
- are you thinking about rotation yet?
- Why put this in NestedControlPlaneSpec instead of NestedPKI?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should err on the side of caution with adding fields. If we don't need to expose this as a user-configurable option yet, I think we should not do it. The above questions raise great points, and I am not sure we have enough of an understanding of the problem space to know where best to put it just yet.
Why put this in NestedControlPlaneSpec instead of NestedPKI?
👍 - I also think this is a question we should answer more generally. What is the purpose of the NestedControlPlane vs the NestedControlPlaneTemplate resource? What defines what should go where?
// TemplateRef allows you to specify the control plane template to create | ||
// the control plane. | ||
// +optional | ||
TemplateRef *corev1.ObjectReference `json:"configRef,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just to clarify on what a template is here:
is the NestedControlPlane controller meant to create additional CR instances out of this templateRef as in https://github.com/kubernetes-sigs/cluster-api/blob/master/controllers/machineset_controller.go#L344?
Or is this referencing a CR which fields input will just be consumed by the controller? If this is the latter we should may reconsider having "template" in the naming.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This TemplateRef will refer to an NestedControlPlaneTemplate
object. There may exist multiple NestedControlPlaneTemplate
objects, and each NestedControlPlane
object will refer to one of them. The NestedControlPlane
controller will then create CR NestedKAS
, NestedEtcd
and NestedKCM
, And the NestedKAS
, NestedEtcd
and the NestedKCM
controllers will actually start each component.
// receive requests and that the VPC infra is ready. | ||
// +optional | ||
Ready bool `json:"ready"` | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should probably also include a field to signal error here. E.g
// ErrorMessage indicates that there is a terminal problem reconciling the
// state, and will be set to a descriptive error message.
Probably to be done in hand with conditions.
// +optional
FailureMessage *string `json:"failureMessage,omitempty"`
Though this can probably be detailed later when introducing conditions
// +kubebuilder:printcolumn:name="ClusterNamespace",type="string",JSONPath=".status.clusterNamespace",description="Namespace of the cluster",priority=1 | ||
|
||
// NestedControlPlane is the Schema for the nestedcontrolplanes API | ||
type NestedControlPlane struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just out of curiosity if there has been any discussion for naming nested vs hosted?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've not reviewed all changes in here as I think we need to take a step back and write up a document outlining what CRDs we are adding and their intended purpose/meaning.
As it stands it seems like we're adding in a lot of things that we know we want to implement, without first establishing the baseline definitions for what does what, and how it works.
There's a few points in here that intend to make it 'general purpose' so anyone can bring along their own implementation of how to provision a nested cluster. What's the model that an implementor should take to do this? Is it to create their own CRD types and reference them from templates? Is it to just build a controller that watches for NestedCluster resources and take appropriate action?
// prefixes used for all Namespaces in the cluster. | ||
// e.g. {namespace}-{vcp.uid}-{vc-namespace} | ||
// +optional | ||
ClusterNamespace string `json:"clusterNamespace,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the vcp.uid
? We should make these doc comments as clear as possible for the 'layman' user and avoid ambiguous terms if possible 😄
This also makes up the prefixes used for all Namespaces in the cluster. e.g. {namespace}-{vcp.uid}-{vc-namespace}
This seems okay for now. In future though it may be worth having some kind of namespacePrefix
field to explicitly set this to some other value. It may be worth noting here that whilst it is true today, it should not be relied upon? If so, can we expose the chosen prefix through a status field to make it easier for other consumers of this API to make use of/build upon?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, I think there needs to be a length restriction on this field. We should also call out how the length of this field influences the restrictions on namespace names within nested clusters too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 for the namespacePrefix
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to call out this is typically defaulted and that it needs to have a max length validation and warning about it's usage for conflicting namespace prefixes, also rename to NamespacePrefix
// cluster. e.g. a pod dns will be | ||
// {some-pod}.{some-namespace}.svc.{ClusterDomain} | ||
// +kubebuilder:default=cluster.local | ||
ClusterDomain string `json:"clusterDomain,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should also have // +optional
tags? Though perhaps kubebuilder automatically marks this as optional if it is omitempty
? 👀
// TemplateRef allows you to specify the control plane template to create | ||
// the control plane. | ||
// +optional | ||
TemplateRef *corev1.ObjectReference `json:"configRef,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a reference to an object that itself describes how to provision the cluster? Does this refer to a NestedControlPlaneTemplate
? I see this is marked optional - what happens if it is not specified?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should create a default NestedControlPlaneTemplate
, which will be used when the TemplateRef
is not set.
// cluster PKI, if not set the PKI will expire after 1 year. | ||
// +optional | ||
// +kubebuilder:default=365 | ||
PKIExpireDays int64 `json:"pkiExpireDays,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should err on the side of caution with adding fields. If we don't need to expose this as a user-configurable option yet, I think we should not do it. The above questions raise great points, and I am not sure we have enough of an understanding of the problem space to know where best to put it just yet.
Why put this in NestedControlPlaneSpec instead of NestedPKI?
👍 - I also think this is a question we should answer more generally. What is the purpose of the NestedControlPlane vs the NestedControlPlaneTemplate resource? What defines what should go where?
// meta data are generated by super master controllers, which are needed by | ||
// nested cluster to interact with external systems. | ||
// +optional | ||
TransparentMetaPrefixes []string `json:"transparentMetaPrefixes,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not too sure what this means - does "back populated" mean synced? It'd really help if we had a proposal document that explained some of this stuff and set out some definitions.
// Ready denotes that the NestedControlPlane API Server is ready to | ||
// receive requests and that the VPC infra is ready. | ||
// +optional | ||
Ready bool `json:"ready"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this field should exist as-is. If we are going to have an overarching concept of readiness, it should be denoted as a condition. That said, I think we should be careful to clearly define what we call ready or not. If an apiserver is failing 50% of requests, is it ready?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can probably use ReadyReplicas
since we'll likely have multiple replicas, this is pulled from the Control Plane types for CAPI -https://cluster-api.sigs.k8s.io/developer/architecture/controllers/control-plane.html#required-status-fields
// Components allows you to specify the multiple components necessary to | ||
// provision a Virtual Control Plane | ||
// +optional | ||
Components []configv1alpha1.Addon `json:"components,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does KubernetesVersion
and Components
relate? What if I define a component that uses an image on version 1.16
of k8s, and the KubernetesVersion
is set to 1.18
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO, the Components
should have higher privilege, sometimes users may wanna try out customized component.
In additon, Maybe we can use the KubernetesVersion
as the default component version? say, the KubernetesVersion
is set to 1.16 while only the KAS and etcd addon is provided, then the default 1.16 KCM template will be used.
// Default allows you to set this NestedTemplate as a a default template, | ||
// by setting this to true any new NestedClusters will be created without | ||
// a TemplateRef will be deployed with this template. | ||
Default bool `json:"default,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd expect something like default templates to be a feature we add further down the line - initially, in this early development phase, requiring users to specify something explicitly works fine. If we introduce this without consideration, we end out not answering questions like "what if multiple templates exist that are all marked default?"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use a validating webhook to prevent multiple templates from being marked as default?
// prefixes used for all Namespaces in the cluster. | ||
// e.g. {namespace}-{vcp.uid}-{vc-namespace} | ||
// +optional | ||
ClusterNamespace string `json:"clusterNamespace,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 for the namespacePrefix
// TemplateRef allows you to specify the control plane template to create | ||
// the control plane. | ||
// +optional | ||
TemplateRef *corev1.ObjectReference `json:"configRef,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This TemplateRef will refer to an NestedControlPlaneTemplate
object. There may exist multiple NestedControlPlaneTemplate
objects, and each NestedControlPlane
object will refer to one of them. The NestedControlPlane
controller will then create CR NestedKAS
, NestedEtcd
and NestedKCM
, And the NestedKAS
, NestedEtcd
and the NestedKCM
controllers will actually start each component.
// TemplateRef allows you to specify the control plane template to create | ||
// the control plane. | ||
// +optional | ||
TemplateRef *corev1.ObjectReference `json:"configRef,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should create a default NestedControlPlaneTemplate
, which will be used when the TemplateRef
is not set.
Ready bool `json:"ready"` | ||
|
||
// Conditions specifies the cpnditions for the managed control plane | ||
// Conditions clusterv1.Conditions `json:"conditions,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we going to use the Conditions
? I think it could be useful for debugging and monitoring.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, we need to have conditions on these types. This should follow the base required fields from CAPI - https://cluster-api.sigs.k8s.io/developer/architecture/controllers/control-plane.html
// Components allows you to specify the multiple components necessary to | ||
// provision a Virtual Control Plane | ||
// +optional | ||
Components []configv1alpha1.Addon `json:"components,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO, the Components
should have higher privilege, sometimes users may wanna try out customized component.
In additon, Maybe we can use the KubernetesVersion
as the default component version? say, the KubernetesVersion
is set to 1.16 while only the KAS and etcd addon is provided, then the default 1.16 KCM template will be used.
// Default allows you to set this NestedTemplate as a a default template, | ||
// by setting this to true any new NestedClusters will be created without | ||
// a TemplateRef will be deployed with this template. | ||
Default bool `json:"default,omitempty"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use a validating webhook to prevent multiple templates from being marked as default?
// +kubebuilder:resource:scope=Namespaced,categories=cluster-api;capn;capi,shortName=ne | ||
|
||
// NestedEtcd is the Schema for the nestedetcds API | ||
type NestedEtcd struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There will also be a NestedKAS
and a NestedKCM
, right?
/close |
@christopherhein: Closed this PR. In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
Adding an initial Proof of Concept for CAPN style, this is not full featured but currently implements part of the ControlPlane provider, the idea is that when a control plane is created it can downstream create the objects/components which are reconciled separately allowing us to swap out specific implementations, for example this currently will take an
NestedControlPlane
and will kick off creating aNestedPKI
(Not necessarily the greatest name but solves to prove the model) the NestedPKI controller will create all the object necessary like the rootca, apiserver crt and key, etc crt and key. This pulls a lot from the original VC for implementation but could be easily replaced if you needed to implement a custom PKI generator.This PR doesn't necessarily need to be merged but serves to help explain one path.
Signed-off-by: Chris Hein [email protected]