Skip to content

Commit d4c1c2a

Browse files
authored
Merge pull request #11127 from afbjorklund/image-pull
new command "image pull: allow to load remote images directly without cache
2 parents a7c9617 + 7c7c25d commit d4c1c2a

File tree

8 files changed

+134
-1
lines changed

8 files changed

+134
-1
lines changed

cmd/minikube/cmd/image.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ var imageCmd = &cobra.Command{
3838
}
3939

4040
var (
41+
pull bool
4142
imgDaemon bool
4243
imgRemote bool
4344
)
@@ -74,6 +75,15 @@ var loadImageCmd = &cobra.Command{
7475
exit.Error(reason.Usage, "loading profile", err)
7576
}
7677

78+
if pull {
79+
// Pull image from remote registry, without doing any caching except in container runtime.
80+
// This is similar to daemon.Image but it is done by the container runtime in the cluster.
81+
if err := machine.PullImages(args, profile); err != nil {
82+
exit.Error(reason.GuestImageLoad, "Failed to pull image", err)
83+
}
84+
return
85+
}
86+
7787
var local bool
7888
if imgRemote || imgDaemon {
7989
local = false
@@ -166,6 +176,7 @@ $ minikube image list
166176
func init() {
167177
imageCmd.AddCommand(loadImageCmd)
168178
imageCmd.AddCommand(removeImageCmd)
179+
loadImageCmd.Flags().BoolVarP(&pull, "pull", "", false, "Pull the remote image (no caching)")
169180
loadImageCmd.Flags().BoolVar(&imgDaemon, "daemon", false, "Cache image from docker daemon")
170181
loadImageCmd.Flags().BoolVar(&imgRemote, "remote", false, "Cache image from remote registry")
171182
imageCmd.AddCommand(listImageCmd)

pkg/minikube/cruntime/containerd.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,11 @@ func (r *Containerd) LoadImage(path string) error {
267267
return nil
268268
}
269269

270+
// PullImage pulls an image into this runtime
271+
func (r *Containerd) PullImage(name string) error {
272+
return pullCRIImage(r.Runner, name)
273+
}
274+
270275
// RemoveImage removes a image
271276
func (r *Containerd) RemoveImage(name string) error {
272277
return removeCRIImage(r.Runner, name)

pkg/minikube/cruntime/cri.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,19 @@ func killCRIContainers(cr CommandRunner, ids []string) error {
187187
return nil
188188
}
189189

190+
// pullCRIImage pulls image using crictl
191+
func pullCRIImage(cr CommandRunner, name string) error {
192+
klog.Infof("Pulling image: %s", name)
193+
194+
crictl := getCrictlPath(cr)
195+
args := append([]string{crictl, "pull"}, name)
196+
c := exec.Command("sudo", args...)
197+
if _, err := cr.RunCmd(c); err != nil {
198+
return errors.Wrap(err, "crictl")
199+
}
200+
return nil
201+
}
202+
190203
// removeCRIImage remove image using crictl
191204
func removeCRIImage(cr CommandRunner, name string) error {
192205
klog.Infof("Removing image: %s", name)

pkg/minikube/cruntime/crio.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,11 @@ func (r *CRIO) LoadImage(path string) error {
187187
return nil
188188
}
189189

190+
// PullImage pulls an image
191+
func (r *CRIO) PullImage(name string) error {
192+
return pullCRIImage(r.Runner, name)
193+
}
194+
190195
// RemoveImage removes a image
191196
func (r *CRIO) RemoveImage(name string) error {
192197
return removeCRIImage(r.Runner, name)

pkg/minikube/cruntime/cruntime.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ type Manager interface {
9595

9696
// Load an image idempotently into the runtime on a host
9797
LoadImage(string) error
98+
// Pull an image to the runtime from the container registry
99+
PullImage(string) error
98100

99101
// ImageExists takes image name and image sha checks if an it exists
100102
ImageExists(string, string) bool
@@ -150,7 +152,7 @@ type ListContainersOptions struct {
150152
Namespaces []string
151153
}
152154

153-
// ListImageOptions are the options to use for listing images
155+
// ListImagesOptions are the options to use for listing images
154156
type ListImagesOptions struct {
155157
}
156158

pkg/minikube/cruntime/docker.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,19 @@ func (r *Docker) LoadImage(path string) error {
191191
return nil
192192
}
193193

194+
// PullImage pulls an image
195+
func (r *Docker) PullImage(name string) error {
196+
klog.Infof("Pulling image: %s", name)
197+
if r.UseCRI {
198+
return pullCRIImage(r.Runner, name)
199+
}
200+
c := exec.Command("docker", "pull", name)
201+
if _, err := r.Runner.RunCmd(c); err != nil {
202+
return errors.Wrap(err, "pull image docker.")
203+
}
204+
return nil
205+
}
206+
194207
// RemoveImage removes a image
195208
func (r *Docker) RemoveImage(name string) error {
196209
klog.Infof("Removing image: %s", name)

pkg/minikube/machine/cache_images.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,87 @@ func transferAndLoadImage(cr command.Runner, k8s config.KubernetesConfig, src st
294294
return nil
295295
}
296296

297+
// pullImages pulls images to the container run time
298+
func pullImages(cruntime cruntime.Manager, images []string) error {
299+
klog.Infof("PullImages start: %s", images)
300+
start := time.Now()
301+
302+
defer func() {
303+
klog.Infof("PullImages completed in %s", time.Since(start))
304+
}()
305+
306+
var g errgroup.Group
307+
308+
for _, image := range images {
309+
image := image
310+
g.Go(func() error {
311+
return cruntime.PullImage(image)
312+
})
313+
}
314+
if err := g.Wait(); err != nil {
315+
return errors.Wrap(err, "error pulling images")
316+
}
317+
klog.Infoln("Successfully pulled images")
318+
return nil
319+
}
320+
321+
// PullImages pulls images to all nodes in profile
322+
func PullImages(images []string, profile *config.Profile) error {
323+
api, err := NewAPIClient()
324+
if err != nil {
325+
return errors.Wrap(err, "error creating api client")
326+
}
327+
defer api.Close()
328+
329+
succeeded := []string{}
330+
failed := []string{}
331+
332+
pName := profile.Name
333+
334+
c, err := config.Load(pName)
335+
if err != nil {
336+
klog.Errorf("Failed to load profile %q: %v", pName, err)
337+
return errors.Wrapf(err, "error loading config for profile :%v", pName)
338+
}
339+
340+
for _, n := range c.Nodes {
341+
m := config.MachineName(*c, n)
342+
343+
status, err := Status(api, m)
344+
if err != nil {
345+
klog.Warningf("error getting status for %s: %v", m, err)
346+
continue
347+
}
348+
349+
if status == state.Running.String() {
350+
h, err := api.Load(m)
351+
if err != nil {
352+
klog.Warningf("Failed to load machine %q: %v", m, err)
353+
continue
354+
}
355+
runner, err := CommandRunner(h)
356+
if err != nil {
357+
return err
358+
}
359+
cruntime, err := cruntime.New(cruntime.Config{Type: c.KubernetesConfig.ContainerRuntime, Runner: runner})
360+
if err != nil {
361+
return errors.Wrap(err, "error creating container runtime")
362+
}
363+
err = pullImages(cruntime, images)
364+
if err != nil {
365+
failed = append(failed, m)
366+
klog.Warningf("Failed to pull images for profile %s %v", pName, err.Error())
367+
continue
368+
}
369+
succeeded = append(succeeded, m)
370+
}
371+
}
372+
373+
klog.Infof("succeeded pulling to: %s", strings.Join(succeeded, " "))
374+
klog.Infof("failed pulling to: %s", strings.Join(failed, " "))
375+
return nil
376+
}
377+
297378
// removeImages removes images from the container run time
298379
func removeImages(cruntime cruntime.Manager, images []string) error {
299380
klog.Infof("RemovingImages start: %s", images)
@@ -318,6 +399,7 @@ func removeImages(cruntime cruntime.Manager, images []string) error {
318399
return nil
319400
}
320401

402+
// RemoveImages removes images from all nodes in profile
321403
func RemoveImages(images []string, profile *config.Profile) error {
322404
api, err := NewAPIClient()
323405
if err != nil {
@@ -374,6 +456,7 @@ func RemoveImages(images []string, profile *config.Profile) error {
374456
return nil
375457
}
376458

459+
// ListImages lists images on all nodes in profile
377460
func ListImages(profile *config.Profile) error {
378461
api, err := NewAPIClient()
379462
if err != nil {

site/content/en/docs/commands/image.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ minikube image load image.tar
139139

140140
```
141141
--daemon Cache image from docker daemon
142+
--pull Pull the remote image (no caching)
142143
--remote Cache image from remote registry
143144
```
144145

0 commit comments

Comments
 (0)