sigs.k8s.io/cluster-api@v1.7.1/docs/book/src/clusterctl/commands/alpha-topology-plan.md (about) 1 # clusterctl alpha topology plan 2 3 <aside class="note warning"> 4 5 <h1>Warning</h1> 6 7 "clusterctl alpha topology plan" is deprecated and will be removed in one of the upcoming releases. For more details, please see [#10138](https://github.com/kubernetes-sigs/cluster-api/issues/10138). 8 9 </aside> 10 11 The `clusterctl alpha topology plan` command can be used to get a plan of how a Cluster topology evolves given 12 file(s) containing resources to be applied to a Cluster. 13 14 The input file(s) could contain a new/modified Cluster, a new/modified ClusterClass and/or new/modified templates, 15 depending on the use case you are going to plan for (see more details below). 16 17 The topology plan output would provide details about objects that will be created, updated and deleted of a target cluster; 18 If instead the command detects that the change impacts many Clusters, the users will be required to select one to focus on (see flags below). 19 20 ```bash 21 clusterctl alpha topology plan -f input.yaml -o output/ 22 ``` 23 24 <aside class="note"> 25 26 <h1>Running without a management cluster</h1> 27 28 This command can be used with or without a management cluster. In case the command is used without a management cluster 29 the input should have all the objects needed. 30 31 </aside> 32 33 <aside class="note"> 34 35 <h1>Limitations: Server Side Apply</h1> 36 37 The topology controllers uses [Server Side Apply](https://kubernetes.io/docs/reference/using-api/server-side-apply/) 38 to support use cases where other controllers are co-authoring the same objects, but this kind of interactions can't be recreated 39 in a dry-run scenario. 40 41 As a consequence Dry-Run can give some false positives/false negatives when trying to have a preview of 42 changes to a set of existing topology owned objects. In other worlds this limitation impacts all the use cases described 43 below except for "Designing a new ClusterClass". 44 45 More specifically: 46 - DryRun doesn't consider OpenAPI schema extension like +ListMap this can lead to false positives when topology 47 dry run is simulating a change to an existing slice (DryRun always reverts external changes, like server side apply when +ListMap=atomic). 48 - DryRun doesn't consider existing metadata.managedFields, and this can lead to false negatives when topology dry run 49 is simulating a change where a field is dropped from a template (DryRun always preserve dropped fields, like 50 server side apply when the field has more than one manager). 51 52 </aside> 53 54 <aside class="note"> 55 56 <h1>Limitations: RuntimeSDK</h1> 57 58 Please note that `clusterctl` doesn't support Runtime SDK yet. This means that ClusterClasses with external patches are not yet supported. 59 60 </aside> 61 62 ## Example use cases 63 64 ### Designing a new ClusterClass 65 66 When designing a new ClusterClass users might want to preview the Cluster generated using such ClusterClass. 67 The `clusterctl alpha topology plan command` can be used to do so: 68 69 ```bash 70 clusterctl alpha topology plan -f example-cluster-class.yaml -f example-cluster.yaml -o output/ 71 ``` 72 73 `example-cluster-class.yaml` holds the definitions of the ClusterClass and all the associated templates. 74 <details> 75 <summary>View <code>example-cluster-class.yaml</code></summary> 76 77 ```yaml 78 apiVersion: cluster.x-k8s.io/v1beta1 79 kind: ClusterClass 80 metadata: 81 name: example-cluster-class 82 namespace: default 83 spec: 84 controlPlane: 85 ref: 86 apiVersion: controlplane.cluster.x-k8s.io/v1beta1 87 kind: KubeadmControlPlaneTemplate 88 name: example-cluster-control-plane 89 namespace: default 90 machineInfrastructure: 91 ref: 92 kind: DockerMachineTemplate 93 apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 94 name: "example-cluster-control-plane" 95 namespace: default 96 infrastructure: 97 ref: 98 apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 99 kind: DockerClusterTemplate 100 name: example-cluster 101 namespace: default 102 workers: 103 machineDeployments: 104 - class: "default-worker" 105 template: 106 bootstrap: 107 ref: 108 apiVersion: bootstrap.cluster.x-k8s.io/v1beta1 109 kind: KubeadmConfigTemplate 110 name: example-docker-worker-bootstraptemplate 111 infrastructure: 112 ref: 113 apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 114 kind: DockerMachineTemplate 115 name: example-docker-worker-machinetemplate 116 --- 117 apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 118 kind: DockerClusterTemplate 119 metadata: 120 name: example-cluster 121 namespace: default 122 spec: 123 template: 124 spec: {} 125 --- 126 kind: KubeadmControlPlaneTemplate 127 apiVersion: controlplane.cluster.x-k8s.io/v1beta1 128 metadata: 129 name: "example-cluster-control-plane" 130 namespace: default 131 spec: 132 template: 133 spec: 134 machineTemplate: 135 nodeDrainTimeout: 1s 136 kubeadmConfigSpec: 137 clusterConfiguration: 138 apiServer: 139 certSANs: [ localhost, 127.0.0.1 ] 140 initConfiguration: 141 nodeRegistration: {} # node registration parameters are automatically injected by CAPD according to the kindest/node image in use. 142 joinConfiguration: 143 nodeRegistration: {} # node registration parameters are automatically injected by CAPD according to the kindest/node image in use. 144 --- 145 apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 146 kind: DockerMachineTemplate 147 metadata: 148 name: "example-cluster-control-plane" 149 namespace: default 150 spec: 151 template: 152 spec: 153 extraMounts: 154 - containerPath: "/var/run/docker.sock" 155 hostPath: "/var/run/docker.sock" 156 --- 157 apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 158 kind: DockerMachineTemplate 159 metadata: 160 name: "example-docker-worker-machinetemplate" 161 namespace: default 162 spec: 163 template: 164 spec: {} 165 --- 166 apiVersion: bootstrap.cluster.x-k8s.io/v1beta1 167 kind: KubeadmConfigTemplate 168 metadata: 169 name: "example-docker-worker-bootstraptemplate" 170 namespace: default 171 spec: 172 template: 173 spec: 174 joinConfiguration: 175 nodeRegistration: {} # node registration parameters are automatically injected by CAPD according to the kindest/node image in use. 176 ``` 177 178 </details> 179 180 `example-cluster.yaml` holds the definition of `example-cluster` Cluster. 181 <details> 182 <summary>View <code>example-cluster.yaml</code></summary> 183 184 ```yaml 185 apiVersion: cluster.x-k8s.io/v1beta1 186 kind: Cluster 187 metadata: 188 name: "example-cluster" 189 namespace: "default" 190 labels: 191 cni: kindnet 192 spec: 193 clusterNetwork: 194 services: 195 cidrBlocks: ["10.128.0.0/12"] 196 pods: 197 cidrBlocks: ["192.168.0.0/16"] 198 serviceDomain: "cluster.local" 199 topology: 200 class: example-cluster-class 201 version: v1.21.2 202 controlPlane: 203 metadata: {} 204 replicas: 1 205 workers: 206 machineDeployments: 207 - class: "default-worker" 208 name: "md-0" 209 replicas: 1 210 ``` 211 212 </details> 213 214 Produces an output similar to this: 215 ```bash 216 The following ClusterClasses will be affected by the changes: 217 * default/example-cluster-class 218 219 The following Clusters will be affected by the changes: 220 * default/example-cluster 221 222 Changes for Cluster "default/example-cluster": 223 224 NAMESPACE KIND NAME ACTION 225 default DockerCluster example-cluster-rnx2q created 226 default DockerMachineTemplate example-cluster-control-plane-dfnvz created 227 default DockerMachineTemplate example-cluster-md-0-infra-qz9qk created 228 default KubeadmConfigTemplate example-cluster-md-0-bootstrap-m29vz created 229 default KubeadmControlPlane example-cluster-b2lhc created 230 default MachineDeployment example-cluster-md-0-pqscg created 231 default Secret example-cluster-shim created 232 default Cluster example-cluster modified 233 234 Created objects are written to directory "output/created" 235 Modified objects are written to directory "output/modified" 236 ``` 237 238 The contents of the output directory are similar to this: 239 ```bash 240 output 241 ├── created 242 │ ├── DockerCluster_default_example-cluster-rnx2q.yaml 243 │ ├── DockerMachineTemplate_default_example-cluster-control-plane-dfnvz.yaml 244 │ ├── DockerMachineTemplate_default_example-cluster-md-0-infra-qz9qk.yaml 245 │ ├── KubeadmConfigTemplate_default_example-cluster-md-0-bootstrap-m29vz.yaml 246 │ ├── KubeadmControlPlane_default_example-cluster-b2lhc.yaml 247 │ ├── MachineDeployment_default_example-cluster-md-0-pqscg.yaml 248 │ └── Secret_default_example-cluster-shim.yaml 249 └── modified 250 ├── Cluster_default_example-cluster.diff 251 ├── Cluster_default_example-cluster.jsonpatch 252 ├── Cluster_default_example-cluster.modified.yaml 253 └── Cluster_default_example-cluster.original.yaml 254 ``` 255 256 ### Plan changes to Cluster topology 257 258 When making changes to a Cluster topology the `clusterctl alpha topology plan` can be used to analyse how the underlying objects will be affected. 259 260 ```bash 261 clusterctl alpha topology plan -f modified-example-cluster.yaml -o output/ 262 ``` 263 264 The `modified-example-cluster.yaml` scales up the control plane to 3 replicas and adds additional labels to the machine deployment. 265 <details> 266 <summary>View <code>modified-example-cluster.yaml</code></summary> 267 268 ```yaml 269 apiVersion: cluster.x-k8s.io/v1beta1 270 kind: Cluster 271 metadata: 272 name: "example-cluster" 273 namespace: default 274 labels: 275 cni: kindnet 276 spec: 277 clusterNetwork: 278 services: 279 cidrBlocks: ["10.128.0.0/12"] 280 pods: 281 cidrBlocks: ["192.168.0.0/16"] 282 serviceDomain: "cluster.local" 283 topology: 284 class: example-cluster-class 285 version: v1.21.2 286 controlPlane: 287 metadata: {} 288 # Scale up the control plane from 1 -> 3. 289 replicas: 3 290 workers: 291 machineDeployments: 292 - class: "default-worker" 293 # Apply additional labels. 294 metadata: 295 labels: 296 test-label: md-0-label 297 name: "md-0" 298 replicas: 1 299 ``` 300 </details> 301 302 Produces an output similar to this: 303 ```bash 304 Detected a cluster with Cluster API installed. Will use it to fetch missing objects. 305 No ClusterClasses will be affected by the changes. 306 The following Clusters will be affected by the changes: 307 * default/example-cluster 308 309 Changes for Cluster "default/example-cluster": 310 311 NAMESPACE KIND NAME ACTION 312 default KubeadmControlPlane example-cluster-l7kx8 modified 313 default MachineDeployment example-cluster-md-0-j58ln modified 314 315 Modified objects are written to directory "output/modified" 316 ``` 317 318 ### Rebase a Cluster to a different ClusterClass 319 320 The command can be used to plan if a Cluster can be successfully rebased to a different ClusterClass. 321 322 Rebasing a Cluster to a different ClusterClass: 323 ```bash 324 # Rebasing from `example-cluster-class` to `another-cluster-class`. 325 clusterctl alpha topology plan -f rebase-example-cluster.yaml -o output/ 326 ``` 327 The `example-cluster` Cluster is rebased from `example-cluster-class` to `another-cluster-class`. In this example `another-cluster-class` is assumed to be available in the management cluster. 328 329 <details> 330 <summary>View <code>rebase-example-cluster.yaml</code></summary> 331 332 ```yaml 333 apiVersion: cluster.x-k8s.io/v1beta1 334 kind: Cluster 335 metadata: 336 name: "example-cluster" 337 namespace: "default" 338 labels: 339 cni: kindnet 340 spec: 341 clusterNetwork: 342 services: 343 cidrBlocks: ["10.128.0.0/12"] 344 pods: 345 cidrBlocks: ["192.168.0.0/16"] 346 serviceDomain: "cluster.local" 347 topology: 348 # ClusterClass changed from 'example-cluster-class' -> 'another-cluster-class'. 349 class: another-cluster-class 350 version: v1.21.2 351 controlPlane: 352 metadata: {} 353 replicas: 1 354 workers: 355 machineDeployments: 356 - class: "default-worker" 357 name: "md-0" 358 replicas: 1 359 ``` 360 </details> 361 362 If the target ClusterClass is compatible with the original ClusterClass the output be similar to: 363 ```bash 364 Detected a cluster with Cluster API installed. Will use it to fetch missing objects. 365 No ClusterClasses will be affected by the changes. 366 The following Clusters will be affected by the changes: 367 * default/example-cluster 368 369 Changes for Cluster "default/example-cluster": 370 371 NAMESPACE KIND NAME ACTION 372 default DockerCluster example-cluster-7t7pl modified 373 default DockerMachineTemplate example-cluster-control-plane-lt6kw modified 374 default DockerMachineTemplate example-cluster-md-0-infra-cjxs4 modified 375 default KubeadmConfigTemplate example-cluster-md-0-bootstrap-m9sg8 modified 376 default KubeadmControlPlane example-cluster-l7kx8 modified 377 378 Modified objects are written to directory "output/modified" 379 ``` 380 381 Instead, if the command detects that the rebase operation would lead to a non-functional cluster (ClusterClasses are incompatible), the output will be similar to: 382 ```bash 383 Detected a cluster with Cluster API installed. Will use it to fetch missing objects. 384 Error: failed defaulting and validation on input objects: failed to run defaulting and validation on Clusters: failed validation of cluster.x-k8s.io/v1beta1, Kind=Cluster default/example-cluster: Cluster.cluster.x-k8s.io "example-cluster" is invalid: spec.topology.workers.machineDeployments[0].class: Invalid value: "default-worker": MachineDeploymentClass with name "default-worker" does not exist in ClusterClass "another-cluster-class" 385 ``` 386 In this example rebasing will lead to a non-functional Cluster because the ClusterClass is missing a worker class that is used by the Cluster. 387 388 ### Testing the effects of changing a ClusterClass 389 390 When planning for a change on a ClusterClass you might want to understand what effects the change will have on existing clusters. 391 392 ```bash 393 clusterctl alpha topology plan -f modified-first-cluster-class.yaml -o output/ 394 ``` 395 When multiple clusters are affected, only the list of Clusters and ClusterClasses is presented. 396 ```bash 397 Detected a cluster with Cluster API installed. Will use it to fetch missing objects. 398 The following ClusterClasses will be affected by the changes: 399 * default/first-cluster-class 400 401 The following Clusters will be affected by the changes: 402 * default/first-cluster 403 * default/second-cluster 404 405 No target cluster identified. Use --cluster to specify a target cluster to get detailed changes. 406 ``` 407 408 To get the full list of changes for the "first-cluster": 409 ```bash 410 clusterctl alpha topology plan -f modified-first-cluster-class.yaml -o output/ -c "first-cluster" 411 ``` 412 Output will be similar to the full summary output provided in other examples. 413 414 ## How does `topology plan` work? 415 416 The topology plan operation is composed of the following steps: 417 * Set the namespace on objects in the input with missing namespace. 418 * Run the Defaulting and Validation webhooks on the Cluster and ClusterClass objects in the input. 419 * Dry run the topology reconciler on the target cluster. 420 * Capture all changes observed during reconciliation. 421 422 ## Reference 423 424 ### `--file`, `-f` (REQUIRED) 425 426 The input file(s) with the target changes. Supports multiple input files. 427 428 The objects in the input should follow these rules: 429 * All the objects in the input should belong to the same namespace. 430 * Should not have multiple Clusters. 431 * Should not have multiple ClusterClasses. 432 433 <aside class="note warning"> 434 435 <h1>Object namespaces</h1> 436 437 If some of the objects have a defined namespace and some do not, the objects are considered as belonging to different namespaces 438 which is not allowed. 439 440 </aside> 441 442 <aside class="note warning"> 443 444 <h1>Defaulting and Validation</h1> 445 446 All templates in the inputs should be fully valid and have all the default values set. `topology plan` will not run any defaulting 447 or validation on these objects. Defaulting and validation is only run on Cluster and ClusterClass objects. 448 449 </aside> 450 451 <aside class="note warning"> 452 453 <h1>API Versions and Contract compatibility</h1> 454 455 All the objects in the input of the same `Group.Kind` should have the same `apiVersion`. 456 Example: Two `InfraMachineTemplate`s with `apiVersion`s `infrastructure.cluster.x-k8s.io/v1beta1` and `infrastructure.cluster.x-k8s.io/v1alpha4` are not allowed. 457 458 The API version of resource in the input should be compatible with the current version of Cluster API contract. 459 460 </aside> 461 462 ### `--output-directory`, `-o` (REQUIRED) 463 464 Information about the objects that are created and updated is written to this directory. 465 466 For objects that are modified the following files are written to disk: 467 * Original object 468 * Final object 469 * JSON patch between the original and the final objects 470 * Diff of the original and final objects 471 472 ### `--cluster`, `-c` (Optional) 473 474 When multiple clusters are affected by the input, `--cluster` can be used to specify a target cluster. 475 476 If only one cluster is affected or if a Cluster is in the input it defaults as the target cluster. 477 478 ### `--namespace`, `-n` (Optional) 479 480 Namespace used for objects with missing namespaces in the input. 481 482 If not provided, the namespace defined in kubeconfig is used. If a kubeconfig is not available the value `default` is used.