sigs.k8s.io/cluster-api@v1.7.1/docs/proposals/20190709-cluster-spec-crds.md (about)

     1  ---
     2  title: Cluster Provider Spec and Status as CRDs
     3  authors:
     4    - "@pablochacin"
     5  reviewers:
     6      - "@justinsb"
     7      - "@detiber"
     8      - "@ncdc"
     9      - "@vincepri"
    10  creation-date: 2019-07-09
    11  last-updated: 2019-09-06
    12  status: implemented
    13  see-also:
    14    - "/docs/proposals/20190610-machine-states-preboot-bootstrapping.md"
    15  ---
    16  
    17  # Cluster Spec & Status CRDs
    18  
    19  ## Table of Contents
    20  
    21  <!-- START doctoc generated TOC please keep comment here to allow auto update -->
    22  <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
    23  
    24  - [Summary](#summary)
    25  - [Motivation](#motivation)
    26    - [Goals](#goals)
    27    - [Non-Goals/Future Work](#non-goalsfuture-work)
    28  - [Proposal](#proposal)
    29    - [Data Model changes](#data-model-changes)
    30    - [Controller collaboration](#controller-collaboration)
    31    - [States and Transitions](#states-and-transitions)
    32      - [Pending](#pending)
    33        - [Conditions](#conditions)
    34        - [Expectations](#expectations)
    35      - [Provisioning](#provisioning)
    36        - [Transition Conditions](#transition-conditions)
    37        - [Expectations](#expectations-1)
    38      - [Provisioned](#provisioned)
    39        - [Transition Conditions](#transition-conditions-1)
    40        - [Expectations](#expectations-2)
    41    - [User Stories](#user-stories)
    42      - [As an infrastructure provider author, I would like to take advantage of the Kubernetes API to provide validation for provider-specific data needed to provision a cluster infrastructure.](#as-an-infrastructure-provider-author-i-would-like-to-take-advantage-of-the-kubernetes-api-to-provide-validation-for-provider-specific-data-needed-to-provision-a-cluster-infrastructure)
    43      - [As an infrastructure provider author, I would like to build a controller to manage provisioning cluster infrastructure using tools of my own choosing.](#as-an-infrastructure-provider-author-i-would-like-to-build-a-controller-to-manage-provisioning-cluster-infrastructure-using-tools-of-my-own-choosing)
    44      - [As an infrastructure provider author, I would like to build a controller to manage provisioning clusters without being restricted to a CRUD API.](#as-an-infrastructure-provider-author-i-would-like-to-build-a-controller-to-manage-provisioning-clusters-without-being-restricted-to-a-crud-api)
    45    - [Implementation Details/Notes/Constraints](#implementation-detailsnotesconstraints)
    46      - [Role of Cluster Controller](#role-of-cluster-controller)
    47      - [Cluster Controller dynamic watchers](#cluster-controller-dynamic-watchers)
    48    - [Risks and Mitigations](#risks-and-mitigations)
    49  - [Design Details](#design-details)
    50    - [Test Plan](#test-plan)
    51    - [Graduation Criteria](#graduation-criteria)
    52    - [Upgrade / Downgrade Strategy](#upgrade--downgrade-strategy)
    53    - [Version Skew Strategy](#version-skew-strategy)
    54  - [Implementation History](#implementation-history)
    55  - [Drawbacks [optional]](#drawbacks-optional)
    56  - [Alternatives [optional]](#alternatives-optional)
    57  
    58  <!-- END doctoc generated TOC please keep comment here to allow auto update -->
    59  
    60  ## Summary
    61  
    62  In Cluster API (CAPI) v1alpha1 Cluster object contains the `ClusterSpec` and `ClusterStatus` structs. Both structs contain provider-specific fields, `ProviderSpec` and `ProviderStatus` respectively, embedded as opaque [RawExtensions](https://godoc.org/k8s.io/apimachinery/pkg/runtime#RawExtension).
    63  
    64  The Cluster controller does not handle these fields directly. Instead, the provider-specific actuator receives the `ProviderSpec` as part of the Cluster object and sets the `ProviderStatus` to reflect the status of the cluster infrastructure.
    65  
    66  This proposal outlines the replacement of these provider-specific embedded fields by references to objects managed by a provider controller, effectively eliminating the actuator interface. The new objects are introduced and the cooperation between the Cluster controller and the Cluster Infrastructure Controller is outlined. This process introduces a new field `InfrastructureReady` which reflects the state of the provisioning process.
    67  
    68  ## Motivation
    69  
    70  Embedding opaque provider-specific information has some disadvantages:
    71  - Using an embedded provider spec as a `RawExtension` means its content is not validated as part of the Cluster object validation
    72  - Embedding the provider spec makes difficult implementing the logic of the provider as an independent controller watching for changes in the specs. Instead, providers implement cluster controllers which embed the generic logic and a provider-specific actuator which implements the logic for handling events in the Cluster object.
    73  - Embedding the provider status as part of the Cluster requires that either the generic cluster controller be responsible for pulling this state from the provider (e.g. by invoking a provider actuator) or the provider updating this field, incurring in overlapping responsibilities.
    74  
    75  ### Goals
    76  
    77  1. To use Kubernetes Controllers to manage the lifecycle of provider specific cluster infrastructure object.
    78  1. To validate provider-specific object as early as possible (create, update).
    79  1. Allow cluster providers to expose the status via a status subresource, eliminating the need of status updates across controllers.
    80  
    81  ### Non-Goals/Future Work
    82  1. To modify the generic Cluster object beyond the elements related to the provider-specific specs and status.
    83  1. Splitting the provider-specific infrastructure into more granular elements, such as network infrastructure and control plane specs. Revisiting the definition of the provider specific infrastructure is left for further proposals.
    84  1. To replace the cluster status by alternative representations, such as a list of conditions.
    85  1. To propose cluster state lifecycle hooks. This must be part of a future proposal that builds on these proposed changes
    86  
    87  ## Proposal
    88  
    89  This proposal introduces changes in the Cluster data model and describes a collaboration model between the Cluster controller and the provider infrastructure controller, including a model for managing the state transition during the provisioning process.
    90  
    91  ### Data Model changes
    92  
    93  ```go
    94  type ClusterSpec struct
    95  ```
    96  - **To remove**
    97      - **ProviderSpec** [optional] _Superseded by InfrastructureRef_
    98          - Type: `ProviderSpec`
    99          - Description:  Provider-specific serialized configuration to use during cluster creation. It is recommended that providers maintain  their own versioned API types that should be  serialized/deserialized from this field.
   100  
   101  - **To add**
   102      - **InfrastructureRef**
   103          - Type: `*corev1.ObjectReference`
   104          - Description: InfrastructureRef is a reference to a provider-specific resource that holds the details for provisioning infrastructure for a cluster in said provider.
   105  
   106  ```go
   107  type ClusterStatus struct
   108  ```
   109  - **To remove**
   110      - **ProviderStatus** [optional]
   111          - Type: `*runtime.RawExtension`
   112          - Description:  Provider-specific status. It is recommended that providers maintain their own versioned API types that should be serialized/deserialized from this field.
   113  
   114  - **To add**
   115      - **InfrastructureReady** [optional]
   116         - Type: `bool`
   117         - Description: InfrastructureReady indicates the state of the infrastructure provisioning process.
   118  
   119  ### Controller collaboration
   120  
   121  Moving the provider-specific infrastructure specs to a separate object makes a clear separation of responsibilities between the generic Cluster controller and the provider's cluster infrastructure controller, but also introduces the need for coordination as the provider controller will likely require information from the Cluster object during the cluster provisioning process.
   122  
   123  It is also necessary to model the state of the cluster along the provisioning process to be able to keep track of its progress. In order to do so, a new `InfrastructureReady` field is introduced as part of the `ClusterStatus` struct. The state and their transitions conditions are explained in detail in section [States and Transition](#states-and-transitions).
   124  
   125  The sequence diagram below describes the high-level process, collaborations and state transitions.
   126  <!--https://sequencediagram.org/index.html#initialData=C4S2BsFMAIDEQOYFcBOMDMAuaBVAzpCtAMZoCGwke0Z0AtmcQBYgB2MA7mE9ANZIAjSGQAmdaAID2k4HmAoyAB0WEAUKsbBJRfGtUBiaAFoj0AOIAlAPI4ACgGVo9gCoBBC8+Mn1isilDEIL6swAgokkiK0PrgiEyhaJCs0Kq+-iCBwcDQrrYAkk6EAG5qSSI+fgFBZCFhEVExccAC4EgwqZUZ1SHQAMKtcoQ5+dAAsows7H2SIeHgUCiqZeqGJubWdo4AogByACJeRuq6KEYAfLkF9sWEmPxCxBA0yuAAnsYAZvQTbJAAdK8yHRwKpLoUUCVTuczv0kIMiGDxsxftNZpJ5rdoDtIBwxj92OpYfDhgUkZMYL0ZvJ0Qtzn0BpQESMySjKWiMShMCypmzqRzoBZIMQZoEoBpHiAihQKQyhoj8RSqXMFupVKwZDBJJD6XDGSS8cieUqaZjTIBQcgN5L+9mAFDhf1sTDIBGgIGokDoimArwAOqxzZbftaVMQ-gAhaSyeRKP57Ci0N3QAA8rBA4DOfoD3P+9hD4cjcgUij+bI+iEFX0TikkiiQ4GlIkz0At2eDQvzMkLMdL5cgXzpNrteAdTpdifV2QARILRK9J+oa9lBQBHJAgNAiaAzN6ur7AJiagQAKyF2VHrAA5NkhEloARb0IPtpIKoiXr5YbFezaWcdcSP+SqJ8gsmCuCIm4cBQzBDE+RB+q2ubthGnbRsWPYIBWfwANJsJukjHqeeBLKw5SqIuAqQKu66QHhrA7iAe4HluBGPNA55XhIkC3veySPs+r6ykypIKkByqEHSb5ysyIm8mJnJgRBUEHkQsHQPBCptqGeSsB8CiFkgjyoJAmE4SRzEno81DQNZ1nEaR5ErmuG5bnR7wMdA+6HhZZ7Ope15cckPGcbBL6SUJgZGt+4m-mF+rZqJJryeB0CQcA0EqdoamsAhebIVGRYljMZYYX22G4eZhF2QuXoUVRznbm5jFeae0AiJIVB+WxZAlDQEWahw7BEGgHyEEkxChYJcUycaHISZNAGsjNIHXNkOVIQWqGFTpvb9r+VgDYQFajaw414AA2gADAAuh5kh9QJupScJn4JbNFwjNcEKYjgigiNK0BYYIwhiHlXaKOhD3-tJL2yYlSZJiYYKfZC2CCng1asAQVVkTVjnUbR9FNRVrFtR1HFOj1tDxZIB1DX2x3jZD77Q4BsNvX+zPPazS23CtfWaX82m6c68gGcARkVsYe200daAnVQl03Vo92xQtkXAdFSM3JyuC-f9rgAOr2ELemi4ZaAQ6rLOLVFKDw4jH3a6jVAY1jyxM09fWvT+HOe-FbPLZAq0aYO4vDo6zowAAvNAk62GUbAIPOHvhf7POnO9VxO7rf2UF7odwinU0w+n9tGFrX062jrsvqoIjCBKUp51bXM2xrKBAA -->
   127  ![Figure 1](./images/cluster-spec-crds/figure1.png)
   128  
   129  Figure 1 presents the sequence of actions involved in provisioning a cluster, highlighting the coordination required between the CAPI cluster controller and the provider infrastructure controller.
   130  
   131  The creation of the Cluster and provider infrastructure objects are independent events. It is expected that the cluster infrastructure object to be created before the cluster object and the reference be set to in the cluster object at creation time.
   132  
   133  When a provider infrastructure object is created, the provider's controller will do nothing unless its owner reference is set to a cluster object.
   134  
   135  When the cluster object is created, the cluster controller will retrieve the infrastructure object. If the object has not been seen before, it will start watching it. Also, if the object's owner is not set, it will set to the Cluster object.
   136  
   137  When an infrastructure object is updated, the provider controller will check the owner reference. If it is set, it will retrieve the cluster object to obtain the required cluster specification and starts the provisioning process. When the process finishes, it sets the `Infrastructure.Status.Ready` to true.
   138  
   139  When the cluster controller detects the `Infrastructure.Status.Ready` is set to true, it updates `Cluster.Status.APIEndpoints` from `Infrastructure.Status.APIEndpoints` and sets `Cluster.Status.InfrastructureReady` to true.
   140  
   141  ### States and Transitions
   142  
   143  The Cluster Controller has the responsibility of managing the state transitions during cluster lifecycle. In order to do so, it requires collaboration with the provider's controller to clearly signal the state transitions without requiring knowledge of the internals of the provider.
   144  
   145  #### Pending
   146  
   147  The initial state when the Cluster object has been created but the infrastructure object referenced by `InfrastructureRef` has not yet been associated with it.
   148  
   149  ##### Conditions
   150  - `Cluster.InsfrastructureRef`->Metadata.OwnerRefences is `<nil>`
   151  
   152  ##### Expectations
   153  - `InfrastructureRef->Metadata.OwnerRefences` is expected to be set by the cluster controller to reference the cluster object.
   154  - `Cluster.Status.InfrastructureReady` is `False`
   155  
   156  #### Provisioning
   157  
   158  The cluster has a provider infrastructure object associated. The provider can start provisioning the infrastructure.
   159  
   160  ##### Transition Conditions
   161  
   162  - The Infrastructure object referenced by `InfrastructureRef` has its owner set to the Cluster
   163  
   164  ##### Expectations
   165  - The cluster infrastructure is in the process of being provisioned
   166  - `Cluster.Status.InfrastructureReady` is  `False`
   167  
   168  #### Provisioned
   169  
   170  The provider has finished provisioning the infrastructure.
   171  
   172  ##### Transition Conditions
   173  - The Infrastructure object referenced by `InfrastructureRef` has the `Status.Ready` field set to true
   174  
   175  ##### Expectations
   176  - The cluster infrastructure has been provisioned
   177  - Cluster status has been populated with information from the `Infrastructure.Status` such as the `APIEndpoints`
   178  - `Cluster.Status.InfrastructureReady` is `True`
   179  
   180  ![Figure 2](./images/cluster-spec-crds/figure2.png)
   181  
   182  ### User Stories
   183  
   184  #### As an infrastructure provider author, I would like to take advantage of the Kubernetes API to provide validation for provider-specific data needed to provision a cluster infrastructure.
   185  
   186  #### As an infrastructure provider author, I would like to build a controller to manage provisioning cluster infrastructure using tools of my own choosing.
   187  
   188  #### As an infrastructure provider author, I would like to build a controller to manage provisioning clusters without being restricted to a CRUD API.
   189  
   190  
   191  ### Implementation Details/Notes/Constraints
   192  
   193  #### Role of Cluster Controller
   194  The Cluster Controller should be the only controller having write permissions to the Cluster objects. Its main responsibility is to
   195  - Manage cluster finalizers
   196  - Set provider's infrastructure object's OwnerRef to Cluster
   197  - Update the state of the infrastructure provisioning
   198  
   199  #### Cluster Controller dynamic watchers
   200  
   201  As the provider spec data is no longer inlined in the Cluster object, the Cluster Controller needs to watch for updates to provider specific resources so it can detect events. To achieve this, when the Cluster Controller reconciles a Cluster and detects a reference to a provider-specific infrastructure object, it starts watching this resource using the [dynamic informer](https://godoc.org/k8s.io/client-go/dynamic/dynamicinformer) and a [`handler.EnqueueRequestForOwner`](https://godoc.org/sigs.k8s.io/controller-runtime/pkg/handler#EnqueueRequestForOwner) configured with Cluster as the OwnerType, to ensure it only watches provider objects related to a CAPI cluster.
   202  
   203  ### Risks and Mitigations
   204  
   205  ## Design Details
   206  
   207  ### Test Plan
   208  
   209  TODO
   210  
   211  ### Graduation Criteria
   212  
   213  TODO
   214  
   215  ### Upgrade / Downgrade Strategy
   216  
   217  TODO
   218  
   219  ### Version Skew Strategy
   220  
   221  TODO
   222  
   223  ## Implementation History
   224  
   225  - [x] 03/20/2019 [Issue Opened](https://github.com/kubernetes-sigs/cluster-api/issues/833) proposing the externalization of embedded provider objects as CRDs
   226  - [x] 06/19/2009 [Discussed](https://github.com/kubernetes-sigs/cluster-api/issues/833#issuecomment-501380522) the inclusion in the scope of v1alpha2.
   227  - [x] 07/09/2019 initial version of the proposal created
   228  - [X] 07/11/2019 Presentation of proposal to the community
   229  - [X] Feedback
   230  
   231  ## Drawbacks [optional]
   232  
   233  TODO
   234  
   235  ## Alternatives [optional]
   236