executor/docker: pull init image only when needed

Use the same logic of k8s and pull init image only when has the latest (or
empty) tag or it doesn't exist.
This commit is contained in:
Simone Gotti 2021-05-25 10:27:36 +02:00
parent 0b0d05f2a0
commit b403fd558a
2 changed files with 36 additions and 19 deletions

View File

@ -15,7 +15,6 @@
package driver package driver
import ( import (
"bufio"
"context" "context"
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
@ -73,16 +72,8 @@ func (d *DockerDriver) Setup(ctx context.Context) error {
return nil return nil
} }
func (d *DockerDriver) createToolboxVolume(ctx context.Context, podID string) (*dockertypes.Volume, error) { func (d *DockerDriver) createToolboxVolume(ctx context.Context, podID string, out io.Writer) (*dockertypes.Volume, error) {
reader, err := d.client.ImagePull(ctx, d.initImage, dockertypes.ImagePullOptions{}) if err := d.fetchImage(ctx, d.initImage, false, nil, out); err != nil {
if err != nil {
return nil, err
}
scanner := bufio.NewScanner(reader)
for scanner.Scan() {
d.log.Infof("create toolbox volume image pull output: %s", scanner.Text())
}
if err := scanner.Err(); err != nil {
return nil, err return nil, err
} }
@ -153,7 +144,7 @@ func (d *DockerDriver) NewPod(ctx context.Context, podConfig *PodConfig, out io.
return nil, errors.Errorf("empty container config") return nil, errors.Errorf("empty container config")
} }
toolboxVol, err := d.createToolboxVolume(ctx, podConfig.ID) toolboxVol, err := d.createToolboxVolume(ctx, podConfig.ID, out)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -240,7 +231,7 @@ func (d *DockerDriver) NewPod(ctx context.Context, podConfig *PodConfig, out io.
return pod, nil return pod, nil
} }
func (d *DockerDriver) fetchImage(ctx context.Context, image string, registryConfig *registry.DockerConfig, out io.Writer) error { func (d *DockerDriver) fetchImage(ctx context.Context, image string, alwaysFetch bool, registryConfig *registry.DockerConfig, out io.Writer) error {
regName, err := registry.GetRegistry(image) regName, err := registry.GetRegistry(image)
if err != nil { if err != nil {
return err return err
@ -257,21 +248,39 @@ func (d *DockerDriver) fetchImage(ctx context.Context, image string, registryCon
} }
registryAuthEnc := base64.URLEncoding.EncodeToString(buf) registryAuthEnc := base64.URLEncoding.EncodeToString(buf)
// by default always try to pull the image so we are sure only authorized users can fetch them tag, err := registry.GetImageTagOrDigest(image)
// see https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#alwayspullimages
reader, err := d.client.ImagePull(ctx, image, dockertypes.ImagePullOptions{RegistryAuth: registryAuthEnc})
if err != nil { if err != nil {
return err return err
} }
_, err = io.Copy(out, reader) args := filters.NewArgs()
return err args.Add("reference", image)
img, err := d.client.ImageList(ctx, dockertypes.ImageListOptions{Filters: args})
if err != nil {
return err
}
exists := len(img) > 0
// fetch only if forced, is latest tag or image doesn't exist
if alwaysFetch || tag == "latest" || !exists {
reader, err := d.client.ImagePull(ctx, image, dockertypes.ImagePullOptions{RegistryAuth: registryAuthEnc})
if err != nil {
return err
}
_, err = io.Copy(out, reader)
return err
}
return nil
} }
func (d *DockerDriver) createContainer(ctx context.Context, index int, podConfig *PodConfig, maincontainerID string, toolboxVol *dockertypes.Volume, out io.Writer) (*container.ContainerCreateCreatedBody, error) { func (d *DockerDriver) createContainer(ctx context.Context, index int, podConfig *PodConfig, maincontainerID string, toolboxVol *dockertypes.Volume, out io.Writer) (*container.ContainerCreateCreatedBody, error) {
containerConfig := podConfig.Containers[index] containerConfig := podConfig.Containers[index]
if err := d.fetchImage(ctx, containerConfig.Image, podConfig.DockerConfig, out); err != nil { // by default always try to pull the image so we are sure only authorized users can fetch them
// see https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#alwayspullimages
if err := d.fetchImage(ctx, containerConfig.Image, true, podConfig.DockerConfig, out); err != nil {
return nil, err return nil, err
} }

View File

@ -76,6 +76,14 @@ var (
} }
) )
func GetImageTagOrDigest(image string) (string, error) {
ref, err := name.ParseReference(image, name.WeakValidation)
if err != nil {
return "", err
}
return ref.Identifier(), nil
}
func GetRegistry(image string) (string, error) { func GetRegistry(image string) (string, error) {
ref, err := name.ParseReference(image, name.WeakValidation) ref, err := name.ParseReference(image, name.WeakValidation)
if err != nil { if err != nil {