@@ -19,6 +19,7 @@ package deploymentreplicassyncer
19
19
import (
20
20
"context"
21
21
"encoding/json"
22
+ "fmt"
22
23
"time"
23
24
24
25
appsv1 "k8s.io/api/apps/v1"
@@ -71,7 +72,10 @@ var predicateFunc = predicate.Funcs{
71
72
}
72
73
73
74
if oldObj .Spec .Replicas == nil || newObj .Spec .Replicas == nil {
74
- klog .Errorf ("spec.replicas field unexpectedly become nil: %+v, %+v" , oldObj .Spec .Replicas , newObj .Spec .Replicas )
75
+ klog .ErrorS (fmt .Errorf ("spec.replicas is nil in either old or new deployment object" ),
76
+ "Unexpected nil spec.replicas" ,
77
+ "oldReplicas" , oldObj .Spec .Replicas , "newReplicas" , newObj .Spec .Replicas ,
78
+ "namespace" , oldObj .Namespace , "name" , oldObj .Name )
75
79
return false
76
80
}
77
81
@@ -99,7 +103,7 @@ func (r *DeploymentReplicasSyncer) SetupWithManager(mgr controllerruntime.Manage
99
103
// The Controller will requeue the Request to be processed again if an error is non-nil or
100
104
// Result.Requeue is true, otherwise upon completion it will remove the work from the queue.
101
105
func (r * DeploymentReplicasSyncer ) Reconcile (ctx context.Context , req controllerruntime.Request ) (controllerruntime.Result , error ) {
102
- klog .V (4 ).Infof ("Reconciling for Deployment %s/%s" , req .Namespace , req .Name )
106
+ klog .V (4 ).InfoS ("Reconciling for Deployment" , "namespace" , req .Namespace , "name" , req .Name )
103
107
104
108
deployment := & appsv1.Deployment {}
105
109
binding := & workv1alpha2.ResourceBinding {}
@@ -108,7 +112,8 @@ func (r *DeploymentReplicasSyncer) Reconcile(ctx context.Context, req controller
108
112
// 1. get latest binding
109
113
if err := r .Client .Get (ctx , client.ObjectKey {Namespace : req .Namespace , Name : bindingName }, binding ); err != nil {
110
114
if apierrors .IsNotFound (err ) {
111
- klog .Infof ("no need to update deployment replicas for binding not found" )
115
+ klog .InfoS ("no need to update deployment replicas as binding was not found" ,
116
+ "namespace" , req .Namespace , "name" , req .Name )
112
117
return controllerruntime.Result {}, nil
113
118
}
114
119
return controllerruntime.Result {}, err
@@ -122,15 +127,18 @@ func (r *DeploymentReplicasSyncer) Reconcile(ctx context.Context, req controller
122
127
// 3. get latest deployment
123
128
if err := r .Client .Get (ctx , req .NamespacedName , deployment ); err != nil {
124
129
if apierrors .IsNotFound (err ) {
125
- klog .Infof ("no need to update deployment replicas for deployment not found" )
130
+ klog .InfoS ("no need to update deployment replicas as deployment was not found" ,
131
+ "namespace" , req .Namespace , "name" , req .Name )
126
132
return controllerruntime.Result {}, nil
127
133
}
128
134
return controllerruntime.Result {}, err
129
135
}
130
136
131
137
// 4. if replicas in spec already the same as in status, no need to update replicas
132
138
if deployment .Spec .Replicas != nil && * deployment .Spec .Replicas == deployment .Status .Replicas {
133
- klog .Infof ("replicas in spec field (%d) already equal to in status field (%d)" , * deployment .Spec .Replicas , deployment .Status .Replicas )
139
+ klog .InfoS ("replicas in spec field are already equal to those in status field" ,
140
+ "specReplicas" , * deployment .Spec .Replicas , "statusReplicas" , deployment .Status .Replicas ,
141
+ "namespace" , deployment .Namespace , "name" , deployment .Name )
134
142
return controllerruntime.Result {}, nil
135
143
}
136
144
@@ -143,55 +151,64 @@ func (r *DeploymentReplicasSyncer) Reconcile(ctx context.Context, req controller
143
151
oldReplicas := * deployment .Spec .Replicas
144
152
deployment .Spec .Replicas = & deployment .Status .Replicas
145
153
if err := r .Client .Update (ctx , deployment ); err != nil {
146
- klog .Errorf ( "failed to update deployment (%s/%s) replicas: %+v" , deployment .Namespace , deployment .Name , err )
154
+ klog .ErrorS ( err , "failed to update deployment replicas" , "namespace" , deployment .Namespace , "name" , deployment .Name )
147
155
return controllerruntime.Result {}, err
148
156
}
149
157
150
- klog .Infof ("successfully update deployment (%s/%s) replicas from %d to %d" , deployment .Namespace ,
151
- deployment .Name , oldReplicas , deployment .Status .Replicas )
158
+ klog .InfoS ("successfully update deployment replicas" ,
159
+ "namespace" , deployment .Namespace , "name" , deployment .Name ,
160
+ "oldReplicas" , oldReplicas , "newReplicas" , deployment .Status .Replicas )
152
161
153
162
return controllerruntime.Result {}, nil
154
163
}
155
164
156
165
// isDeploymentStatusCollected judge whether deployment modification in spec has taken effect and its status has been collected.
157
166
func isDeploymentStatusCollected (deployment * appsv1.Deployment , binding * workv1alpha2.ResourceBinding ) bool {
158
167
// make sure the replicas change in deployment.spec can sync to binding.spec, otherwise retry
159
- if deployment .Spec .Replicas == nil || * deployment .Spec .Replicas != binding .Spec .Replicas {
160
- klog .V (4 ).Infof ("wait until replicas of binding (%d) equal to replicas of deployment (%d)" ,
161
- binding .Spec .Replicas , * deployment .Spec .Replicas )
168
+ if deployment .Spec .Replicas == nil {
169
+ // should never happen, as karmada-apiserver defaults `deployment.spec.Replicas` to 1 if it is not set.
170
+ klog .ErrorS (nil , "deployment replicas is nil" , "namespace" , deployment .Namespace , "name" , deployment .Name )
171
+ return false
172
+ }
173
+ if * deployment .Spec .Replicas != binding .Spec .Replicas {
174
+ klog .V (4 ).InfoS ("wait until binding replicas are equal to deployment replicas" ,
175
+ "bindingReplicas" , binding .Spec .Replicas , "deploymentReplicas" , * deployment .Spec .Replicas ,
176
+ "namespace" , deployment .Namespace , "deploymentName" , deployment .Name , "bindingName" , binding .Name )
162
177
return false
163
178
}
164
179
165
180
// make sure the scheduler observed generation equal to generation in binding, otherwise retry
166
181
if binding .Generation != binding .Status .SchedulerObservedGeneration {
167
- klog .V (4 ).Infof ("wait until scheduler observed generation (%d) equal to generation in binding (%d)" ,
168
- binding .Status .SchedulerObservedGeneration , binding .Generation )
182
+ klog .V (4 ).InfoS ("wait until scheduler observed generation is equal to generation in binding" ,
183
+ "schedulerObservedGeneration" , binding .Status .SchedulerObservedGeneration , "generation" , binding .Generation ,
184
+ "namespace" , binding .Namespace , "name" , binding .Name )
169
185
return false
170
186
}
171
187
172
188
// make sure the number of aggregated status in binding is as expected.
173
189
if len (binding .Status .AggregatedStatus ) != len (binding .Spec .Clusters ) {
174
- klog .V (4 ).Infof ("wait until all clusters status collected, got: %d, expected: %d" ,
175
- len (binding .Status .AggregatedStatus ), len (binding .Spec .Clusters ))
190
+ klog .V (4 ).InfoS ("wait until all clusters' statuses are collected" ,
191
+ "got" , len (binding .Status .AggregatedStatus ), "expected" , len (binding .Spec .Clusters ),
192
+ "namespace" , binding .Namespace , "name" , binding .Name )
176
193
return false
177
194
}
178
195
179
196
// make sure the status.replicas in binding has been collected from work to binding.
180
197
bindingStatusSumReplicas := int32 (0 )
181
198
for _ , status := range binding .Status .AggregatedStatus {
182
199
if status .Status == nil {
183
- klog .V (4 ).Infof ("wait until aggregated status of cluster %s collected" , status .ClusterName )
200
+ klog .V (4 ).InfoS ("wait until aggregated status of cluster is collected" , "cluster " , status .ClusterName )
184
201
return false
185
202
}
186
203
itemStatus := & appsv1.DeploymentStatus {}
187
204
if err := json .Unmarshal (status .Status .Raw , itemStatus ); err != nil {
188
- klog .Errorf ( "unmarshal status.raw of cluster %s in binding failed: %+v" , status .ClusterName , err )
205
+ klog .ErrorS ( err , "Failed to unmarshal aggregated status" , "cluster" , status .ClusterName )
189
206
return false
190
207
}
191
208
// if member cluster deployment is controlled by hpa, its status.replicas must > 0 (since hpa.minReplicas > 0),
192
209
// so, if its status replicas is 0, means the status haven't been collected from member cluster, and needs waiting.
193
210
if itemStatus .Replicas <= 0 {
194
- klog .V (4 ).Infof ("wait until aggregated status replicas of cluster %s collected" , status .ClusterName )
211
+ klog .V (4 ).InfoS ("wait until aggregated status replicas of cluster are collected" , "cluster " , status .ClusterName )
195
212
return false
196
213
}
197
214
bindingStatusSumReplicas += itemStatus .Replicas
@@ -201,8 +218,9 @@ func isDeploymentStatusCollected(deployment *appsv1.Deployment, binding *workv1a
201
218
// e.g: user set deployment.spec.replicas = 2, then sum replicas in binding.status becomes 2, however, if now
202
219
// deployment.status.replicas is still 1, we shouldn't update spec.replicas to 1 until status.replicas becomes 2.
203
220
if deployment .Status .Replicas != bindingStatusSumReplicas {
204
- klog .V (4 ).Infof ("wait until deployment status replicas (%d) equal to binding status replicas (%d)" ,
205
- deployment .Status .Replicas , bindingStatusSumReplicas )
221
+ klog .V (4 ).InfoS ("wait until deployment status replicas are equal to binding status replicas" ,
222
+ "deploymentStatusReplicas" , deployment .Status .Replicas , "bindingStatusReplicas" , bindingStatusSumReplicas ,
223
+ "namespace" , binding .Namespace , "bindingName" , binding .Name , "deploymentName" , deployment .Name )
206
224
return false
207
225
}
208
226
0 commit comments