|
| 1 | +# Using ClusterResourcePlacementEviction and ClusterResourcePlacementDisruptionBudget |
| 2 | + |
| 3 | +This how-to guide discusses how to create `ClusterResourcePlacementEviction` objects and `ClusterResourcePlacementDisruptionBudget` objects to evict resources from member clusters and protect resources on member clusters from voluntary disruption, respectively. |
| 4 | + |
| 5 | +## Evicting Resources from Member Clusters using ClusterResourcePlacementEviction |
| 6 | + |
| 7 | +The `ClusterResourcePlacementEviction` object is used to remove resources from a member cluster once the resources have already been propagated from the hub cluster. |
| 8 | + |
| 9 | +To successfully evict resources from a cluster, the user needs to specify: |
| 10 | +- The name of the `ClusterResourcePlacement` object which propagated resources to the target cluster. |
| 11 | +- The name of the target cluster from which we need to evict resources. |
| 12 | + |
| 13 | +In this example, we will create a `ClusterResourcePlacement` object with PickAll placement policy to propagate resources to an existing `MemberCluster`, add a taint to the member cluster |
| 14 | +resource and then create a `ClusterResourcePlacementEviction` object to evict resources from the `MemberCluster`. |
| 15 | + |
| 16 | +We will first create a namespace that we will propagate to the member cluster. |
| 17 | + |
| 18 | +``` |
| 19 | +kubectl create ns test-ns |
| 20 | +``` |
| 21 | + |
| 22 | +Then we will apply a `ClusterResourcePlacement` with the following spec: |
| 23 | + |
| 24 | +```yaml |
| 25 | +spec: |
| 26 | + resourceSelectors: |
| 27 | + - group: "" |
| 28 | + kind: Namespace |
| 29 | + version: v1 |
| 30 | + name: test-ns |
| 31 | + policy: |
| 32 | + placementType: PickAll |
| 33 | +``` |
| 34 | +
|
| 35 | +The `CRP` status after applying should look something like this: |
| 36 | + |
| 37 | +```yaml |
| 38 | +kubectl get crp test-crp |
| 39 | +NAME GEN SCHEDULED SCHEDULED-GEN AVAILABLE AVAILABLE-GEN AGE |
| 40 | +test-crp 2 True 2 True 2 5m49s |
| 41 | +``` |
| 42 | + |
| 43 | +let's now add a taint to the member cluster to ensure this cluster is not picked again by the scheduler once we evict resources from it. |
| 44 | + |
| 45 | +Modify the cluster object to add a taint: |
| 46 | + |
| 47 | +```yaml |
| 48 | +spec: |
| 49 | + heartbeatPeriodSeconds: 60 |
| 50 | + identity: |
| 51 | + kind: ServiceAccount |
| 52 | + name: fleet-member-agent-cluster-1 |
| 53 | + namespace: fleet-system |
| 54 | + taints: |
| 55 | + - effect: NoSchedule |
| 56 | + key: test-key |
| 57 | + value: test-value |
| 58 | +``` |
| 59 | + |
| 60 | +Now we will create a `ClusterResourcePlacementEviction` object to evict resources from the member cluster: |
| 61 | + |
| 62 | +```yaml |
| 63 | +apiVersion: placement.kubernetes-fleet.io/v1beta1 |
| 64 | +kind: ClusterResourcePlacementEviction |
| 65 | +metadata: |
| 66 | + name: test-eviction |
| 67 | +spec: |
| 68 | + placementName: test-crp |
| 69 | + clusterName: kind-cluster-1 |
| 70 | +``` |
| 71 | + |
| 72 | +the eviction object should look like this, if the eviction was successful: |
| 73 | + |
| 74 | +```yaml |
| 75 | +kubectl get crpe test-eviction |
| 76 | +NAME VALID EXECUTED |
| 77 | +test-eviction True True |
| 78 | +``` |
| 79 | + |
| 80 | +since the eviction is successful, the resources should be removed from the cluster, let's take a look at the `CRP` object status to verify: |
| 81 | + |
| 82 | +```yaml |
| 83 | +kubectl get crp test-crp |
| 84 | +NAME GEN SCHEDULED SCHEDULED-GEN AVAILABLE AVAILABLE-GEN AGE |
| 85 | +test-crp 2 True 2 15m |
| 86 | +``` |
| 87 | + |
| 88 | +from the object we can clearly tell that the resources were evicted since the `AVAILABLE` column is empty. If the user needs more information `ClusterResourcePlacement` object's status can be checked. |
| 89 | + |
| 90 | +## Protecting resources from voluntary disruptions using ClusterResourcePlacementDisruptionBudget |
| 91 | + |
| 92 | +In this example, we will create a `ClusterResourcePlacement` object with PickN placement policy to propagate resources to an existing MemberCluster, |
| 93 | +then create a `ClusterResourcePlacementDisruptionBudget` object to protect resources on the MemberCluster from voluntary disruption and |
| 94 | +then try to evict resources from the MemberCluster using `ClusterResourcePlacementEviction`. |
| 95 | + |
| 96 | +We will first create a namespace that we will propagate to the member cluster. |
| 97 | + |
| 98 | +``` |
| 99 | +kubectl create ns test-ns |
| 100 | +``` |
| 101 | +
|
| 102 | +Then we will apply a `ClusterResourcePlacement` with the following spec: |
| 103 | +
|
| 104 | +```yaml |
| 105 | +spec: |
| 106 | + resourceSelectors: |
| 107 | + - group: "" |
| 108 | + kind: Namespace |
| 109 | + version: v1 |
| 110 | + name: test-ns |
| 111 | + policy: |
| 112 | + placementType: PickN |
| 113 | + numberOfClusters: 1 |
| 114 | +``` |
| 115 | + |
| 116 | +The `CRP` object after applying should look something like this: |
| 117 | + |
| 118 | +```yaml |
| 119 | +kubectl get crp test-crp |
| 120 | +NAME GEN SCHEDULED SCHEDULED-GEN AVAILABLE AVAILABLE-GEN AGE |
| 121 | +test-crp 2 True 2 True 2 8s |
| 122 | +``` |
| 123 | + |
| 124 | +Now we will create a `ClusterResourcePlacementDisruptionBudget` object to protect resources on the member cluster from voluntary disruption: |
| 125 | + |
| 126 | +```yaml |
| 127 | +apiVersion: placement.kubernetes-fleet.io/v1beta1 |
| 128 | +kind: ClusterResourcePlacementDisruptionBudget |
| 129 | +metadata: |
| 130 | + name: test-crp |
| 131 | +spec: |
| 132 | + minAvailable: 1 |
| 133 | +``` |
| 134 | +
|
| 135 | +> **Note:** An eviction object is only reconciled once, after which it reaches a terminal state, if the user desires to create/apply the same eviction object again they need to delete the existing eviction object and re-create the object for the eviction to occur again. |
| 136 | +
|
| 137 | +Now we will create a `ClusterResourcePlacementEviction` object to evict resources from the member cluster: |
| 138 | + |
| 139 | +```yaml |
| 140 | +apiVersion: placement.kubernetes-fleet.io/v1beta1 |
| 141 | +kind: ClusterResourcePlacementEviction |
| 142 | +metadata: |
| 143 | + name: test-eviction |
| 144 | +spec: |
| 145 | + placementName: test-crp |
| 146 | + clusterName: kind-cluster-1 |
| 147 | +``` |
| 148 | + |
| 149 | +> **Note:** The eviction controller will try to get the corresponding `ClusterResourcePlacementDisruptionBudget` object when a `ClusterResourcePlacementEviction` object is reconciled to check if the specified MaxAvailable or MinAvailable allows the eviction to be executed. |
| 150 | + |
| 151 | +let's take a look at the eviction object to see if the eviction was executed, |
| 152 | + |
| 153 | +```yaml |
| 154 | +kubectl get crpe test-eviction |
| 155 | +NAME VALID EXECUTED |
| 156 | +test-eviction True False |
| 157 | +``` |
| 158 | + |
| 159 | +from the eviction object we can see the eviction was not executed. |
| 160 | + |
| 161 | +let's take a look at the `ClusterResourcePlacementEviction` object status to verify why the eviction was not executed: |
| 162 | + |
| 163 | +```yaml |
| 164 | +status: |
| 165 | + conditions: |
| 166 | + - lastTransitionTime: "2025-01-21T15:52:29Z" |
| 167 | + message: Eviction is valid |
| 168 | + observedGeneration: 1 |
| 169 | + reason: ClusterResourcePlacementEvictionValid |
| 170 | + status: "True" |
| 171 | + type: Valid |
| 172 | + - lastTransitionTime: "2025-01-21T15:52:29Z" |
| 173 | + message: 'Eviction is blocked by specified ClusterResourcePlacementDisruptionBudget, |
| 174 | + availablePlacements: 1, totalPlacements: 1' |
| 175 | + observedGeneration: 1 |
| 176 | + reason: ClusterResourcePlacementEvictionNotExecuted |
| 177 | + status: "False" |
| 178 | + type: Executed |
| 179 | +``` |
| 180 | + |
| 181 | +the eviction status clearly mentions that the eviction was blocked by the specified `ClusterResourcePlacementDisruptionBudget`. |
0 commit comments