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:
parent
0b0d05f2a0
commit
b403fd558a
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in New Issue