@@ -25,12 +25,17 @@ import (
25
25
26
26
v1 "k8s.io/api/core/v1"
27
27
"k8s.io/apimachinery/pkg/types"
28
+ utilfeature "k8s.io/apiserver/pkg/util/feature"
28
29
"k8s.io/client-go/tools/record"
29
30
"k8s.io/client-go/util/flowcontrol"
30
31
"k8s.io/klog/v2"
31
32
32
33
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1"
33
34
crierrors "k8s.io/cri-api/pkg/errors"
35
+ "k8s.io/kubernetes/pkg/credentialprovider"
36
+ credentialproviderplugin "k8s.io/kubernetes/pkg/credentialprovider/plugin"
37
+ credentialprovidersecrets "k8s.io/kubernetes/pkg/credentialprovider/secrets"
38
+ "k8s.io/kubernetes/pkg/features"
34
39
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
35
40
"k8s.io/kubernetes/pkg/kubelet/events"
36
41
"k8s.io/kubernetes/pkg/kubelet/metrics"
@@ -50,15 +55,16 @@ type imageManager struct {
50
55
prevPullErrMsg sync.Map
51
56
52
57
// It will check the presence of the image, and report the 'image pulling', image pulled' events correspondingly.
53
- puller imagePuller
58
+ puller imagePuller
59
+ nodeKeyring credentialprovider.DockerKeyring
54
60
55
61
podPullingTimeRecorder ImagePodPullingTimeRecorder
56
62
}
57
63
58
64
var _ ImageManager = & imageManager {}
59
65
60
66
// NewImageManager instantiates a new ImageManager object.
61
- func NewImageManager (recorder record.EventRecorder , imageService kubecontainer.ImageService , imageBackOff * flowcontrol.Backoff , serialized bool , maxParallelImagePulls * int32 , qps float32 , burst int , podPullingTimeRecorder ImagePodPullingTimeRecorder ) ImageManager {
67
+ func NewImageManager (recorder record.EventRecorder , nodeKeyring credentialprovider. DockerKeyring , imageService kubecontainer.ImageService , imageBackOff * flowcontrol.Backoff , serialized bool , maxParallelImagePulls * int32 , qps float32 , burst int , podPullingTimeRecorder ImagePodPullingTimeRecorder ) ImageManager {
62
68
imageService = throttleImagePulling (imageService , qps , burst )
63
69
64
70
var puller imagePuller
@@ -70,6 +76,7 @@ func NewImageManager(recorder record.EventRecorder, imageService kubecontainer.I
70
76
return & imageManager {
71
77
recorder : recorder ,
72
78
imageService : imageService ,
79
+ nodeKeyring : nodeKeyring ,
73
80
backOff : imageBackOff ,
74
81
puller : puller ,
75
82
podPullingTimeRecorder : podPullingTimeRecorder ,
@@ -153,7 +160,39 @@ func (m *imageManager) EnsureImageExists(ctx context.Context, objRef *v1.ObjectR
153
160
return imageRef , msg , nil
154
161
}
155
162
156
- backOffKey := fmt .Sprintf ("%s_%s" , pod .UID , imgRef )
163
+ img := spec .Image
164
+ repoToPull , _ , _ , err := parsers .ParseImageName (img )
165
+ if err != nil {
166
+ return "" , err .Error (), err
167
+ }
168
+
169
+ // construct the dynamic keyring using the providers we have in the kubelet
170
+ var podName , podNamespace , podUID string
171
+ if utilfeature .DefaultFeatureGate .Enabled (features .KubeletServiceAccountTokenForCredentialProviders ) {
172
+ sandboxMetadata := podSandboxConfig .GetMetadata ()
173
+
174
+ podName = sandboxMetadata .Name
175
+ podNamespace = sandboxMetadata .Namespace
176
+ podUID = sandboxMetadata .Uid
177
+ }
178
+
179
+ externalCredentialProviderKeyring := credentialproviderplugin .NewExternalCredentialProviderDockerKeyring (
180
+ podNamespace ,
181
+ podName ,
182
+ podUID ,
183
+ pod .Spec .ServiceAccountName )
184
+
185
+ keyring , err := credentialprovidersecrets .MakeDockerKeyring (pullSecrets , credentialprovider.UnionDockerKeyring {m .nodeKeyring , externalCredentialProviderKeyring })
186
+ if err != nil {
187
+ return "" , err .Error (), err
188
+ }
189
+
190
+ pullCredentials , _ := keyring .Lookup (repoToPull )
191
+ return m .pullImage (ctx , logPrefix , objRef , pod .UID , imgRef , spec , pullCredentials , podSandboxConfig )
192
+ }
193
+
194
+ func (m * imageManager ) pullImage (ctx context.Context , logPrefix string , objRef * v1.ObjectReference , podUID types.UID , imgRef string , imgSpec kubecontainer.ImageSpec , pullCredentials []credentialprovider.TrackedAuthConfig , podSandboxConfig * runtimeapi.PodSandboxConfig ) (imageRef , message string , err error ) {
195
+ backOffKey := fmt .Sprintf ("%s_%s" , podUID , imgRef )
157
196
if m .backOff .IsInBackOffSinceUpdate (backOffKey , m .backOff .Clock .Now ()) {
158
197
msg := fmt .Sprintf ("Back-off pulling image %q" , imgRef )
159
198
m .logIt (objRef , v1 .EventTypeNormal , events .BackOffPullImage , logPrefix , msg , klog .Info )
@@ -171,16 +210,16 @@ func (m *imageManager) EnsureImageExists(ctx context.Context, objRef *v1.ObjectR
171
210
// Ensure that the map cannot grow indefinitely.
172
211
m .prevPullErrMsg .Delete (backOffKey )
173
212
174
- m .podPullingTimeRecorder .RecordImageStartedPulling (pod . UID )
213
+ m .podPullingTimeRecorder .RecordImageStartedPulling (podUID )
175
214
m .logIt (objRef , v1 .EventTypeNormal , events .PullingImage , logPrefix , fmt .Sprintf ("Pulling image %q" , imgRef ), klog .Info )
176
215
startTime := time .Now ()
216
+
177
217
pullChan := make (chan pullResult )
178
- m .puller .pullImage (ctx , spec , pullSecrets , pullChan , podSandboxConfig , pod . Spec . ServiceAccountName )
218
+ m .puller .pullImage (ctx , imgSpec , pullCredentials , pullChan , podSandboxConfig )
179
219
imagePullResult := <- pullChan
180
220
if imagePullResult .err != nil {
181
221
m .logIt (objRef , v1 .EventTypeWarning , events .FailedToPullImage , logPrefix , fmt .Sprintf ("Failed to pull image %q: %v" , imgRef , imagePullResult .err ), klog .Warning )
182
222
m .backOff .Next (backOffKey , m .backOff .Clock .Now ())
183
-
184
223
msg , err := evalCRIPullErr (imgRef , imagePullResult .err )
185
224
186
225
// Store the actual pull error for providing that information during
@@ -189,12 +228,13 @@ func (m *imageManager) EnsureImageExists(ctx context.Context, objRef *v1.ObjectR
189
228
190
229
return "" , msg , err
191
230
}
192
- m .podPullingTimeRecorder .RecordImageFinishedPulling (pod . UID )
231
+ m .podPullingTimeRecorder .RecordImageFinishedPulling (podUID )
193
232
imagePullDuration := time .Since (startTime ).Truncate (time .Millisecond )
194
233
m .logIt (objRef , v1 .EventTypeNormal , events .PulledImage , logPrefix , fmt .Sprintf ("Successfully pulled image %q in %v (%v including waiting). Image size: %v bytes." ,
195
234
imgRef , imagePullResult .pullDuration .Truncate (time .Millisecond ), imagePullDuration , imagePullResult .imageSize ), klog .Info )
196
235
metrics .ImagePullDuration .WithLabelValues (metrics .GetImageSizeBucket (imagePullResult .imageSize )).Observe (imagePullDuration .Seconds ())
197
236
m .backOff .GC ()
237
+
198
238
return imagePullResult .imageRef , "" , nil
199
239
}
200
240
0 commit comments