mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-03 01:06:27 +00:00
dockertools: add image ref to ImageService interfaces
This commit is contained in:
parent
37fc81be0e
commit
fcbf39ea54
@ -94,7 +94,7 @@ func SetContainerNamePrefix(prefix string) {
|
|||||||
// DockerPuller is an abstract interface for testability. It abstracts image pull operations.
|
// DockerPuller is an abstract interface for testability. It abstracts image pull operations.
|
||||||
type DockerPuller interface {
|
type DockerPuller interface {
|
||||||
Pull(image string, secrets []v1.Secret) error
|
Pull(image string, secrets []v1.Secret) error
|
||||||
IsImagePresent(image string) (bool, error)
|
IsImagePresent(image string) (string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// dockerPuller is the default implementation of DockerPuller.
|
// dockerPuller is the default implementation of DockerPuller.
|
||||||
@ -241,11 +241,11 @@ func (p dockerPuller) Pull(image string, secrets []v1.Secret) error {
|
|||||||
err := p.client.PullImage(image, dockertypes.AuthConfig{}, opts)
|
err := p.client.PullImage(image, dockertypes.AuthConfig{}, opts)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// Sometimes PullImage failed with no error returned.
|
// Sometimes PullImage failed with no error returned.
|
||||||
exist, ierr := p.IsImagePresent(image)
|
imageRef, ierr := p.IsImagePresent(image)
|
||||||
if ierr != nil {
|
if ierr != nil {
|
||||||
glog.Warningf("Failed to inspect image %s: %v", image, ierr)
|
glog.Warningf("Failed to inspect image %s: %v", image, ierr)
|
||||||
}
|
}
|
||||||
if !exist {
|
if imageRef == "" {
|
||||||
return fmt.Errorf("image pull failed for unknown error")
|
return fmt.Errorf("image pull failed for unknown error")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -277,15 +277,23 @@ func (p dockerPuller) Pull(image string, secrets []v1.Secret) error {
|
|||||||
return utilerrors.NewAggregate(pullErrs)
|
return utilerrors.NewAggregate(pullErrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p dockerPuller) IsImagePresent(image string) (bool, error) {
|
func (p dockerPuller) IsImagePresent(image string) (string, error) {
|
||||||
_, err := p.client.InspectImageByRef(image)
|
resp, err := p.client.InspectImageByRef(image)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return true, nil
|
if resp == nil {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
imageRef := resp.ID
|
||||||
|
if len(resp.RepoDigests) > 0 {
|
||||||
|
imageRef = resp.RepoDigests[0]
|
||||||
|
}
|
||||||
|
return imageRef, nil
|
||||||
}
|
}
|
||||||
if _, ok := err.(imageNotFoundError); ok {
|
if _, ok := err.(imageNotFoundError); ok {
|
||||||
return false, nil
|
return "", nil
|
||||||
}
|
}
|
||||||
return false, err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a name which can be reversed to identify both full pod name and container name.
|
// Creates a name which can be reversed to identify both full pod name and container name.
|
||||||
|
@ -590,6 +590,7 @@ func (dm *DockerManager) runContainer(
|
|||||||
container *v1.Container,
|
container *v1.Container,
|
||||||
opts *kubecontainer.RunContainerOptions,
|
opts *kubecontainer.RunContainerOptions,
|
||||||
ref *v1.ObjectReference,
|
ref *v1.ObjectReference,
|
||||||
|
imageRef string,
|
||||||
netMode string,
|
netMode string,
|
||||||
ipcMode string,
|
ipcMode string,
|
||||||
utsMode string,
|
utsMode string,
|
||||||
@ -765,7 +766,7 @@ func (dm *DockerManager) runContainer(
|
|||||||
Name: containerName,
|
Name: containerName,
|
||||||
Config: &dockercontainer.Config{
|
Config: &dockercontainer.Config{
|
||||||
Env: makeEnvList(opts.Envs),
|
Env: makeEnvList(opts.Envs),
|
||||||
Image: container.Image,
|
Image: imageRef,
|
||||||
WorkingDir: container.WorkingDir,
|
WorkingDir: container.WorkingDir,
|
||||||
Labels: labels,
|
Labels: labels,
|
||||||
// Interactive containers:
|
// Interactive containers:
|
||||||
@ -958,13 +959,37 @@ func (dm *DockerManager) ListImages() ([]kubecontainer.Image, error) {
|
|||||||
return images, nil
|
return images, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetImageRef returns the image digest if exists, or else returns the image ID.
|
||||||
|
// It is exported for reusing in dockershim.
|
||||||
|
func GetImageRef(client DockerInterface, image string) (string, error) {
|
||||||
|
img, err := client.InspectImageByRef(image)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if img == nil {
|
||||||
|
return "", fmt.Errorf("unable to inspect image %s", image)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the digest if it exist.
|
||||||
|
if len(img.RepoDigests) > 0 {
|
||||||
|
return img.RepoDigests[0], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return img.ID, nil
|
||||||
|
}
|
||||||
|
|
||||||
// PullImage pulls an image from network to local storage.
|
// PullImage pulls an image from network to local storage.
|
||||||
func (dm *DockerManager) PullImage(image kubecontainer.ImageSpec, secrets []v1.Secret) error {
|
func (dm *DockerManager) PullImage(image kubecontainer.ImageSpec, secrets []v1.Secret) (string, error) {
|
||||||
return dm.dockerPuller.Pull(image.Image, secrets)
|
err := dm.dockerPuller.Pull(image.Image, secrets)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetImageRef(dm.client, image.Image)
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsImagePresent checks whether the container image is already in the local storage.
|
// IsImagePresent checks whether the container image is already in the local storage.
|
||||||
func (dm *DockerManager) IsImagePresent(image kubecontainer.ImageSpec) (bool, error) {
|
func (dm *DockerManager) IsImagePresent(image kubecontainer.ImageSpec) (string, error) {
|
||||||
return dm.dockerPuller.IsImagePresent(image.Image)
|
return dm.dockerPuller.IsImagePresent(image.Image)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1683,7 +1708,7 @@ func (dm *DockerManager) applyOOMScoreAdj(pod *v1.Pod, container *v1.Container,
|
|||||||
|
|
||||||
// Run a single container from a pod. Returns the docker container ID
|
// Run a single container from a pod. Returns the docker container ID
|
||||||
// If do not need to pass labels, just pass nil.
|
// If do not need to pass labels, just pass nil.
|
||||||
func (dm *DockerManager) runContainerInPod(pod *v1.Pod, container *v1.Container, netMode, ipcMode, pidMode, podIP string, restartCount int) (kubecontainer.ContainerID, error) {
|
func (dm *DockerManager) runContainerInPod(pod *v1.Pod, container *v1.Container, netMode, ipcMode, pidMode, podIP, imageRef string, restartCount int) (kubecontainer.ContainerID, error) {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
defer func() {
|
defer func() {
|
||||||
metrics.ContainerManagerLatency.WithLabelValues("runContainerInPod").Observe(metrics.SinceInMicroseconds(start))
|
metrics.ContainerManagerLatency.WithLabelValues("runContainerInPod").Observe(metrics.SinceInMicroseconds(start))
|
||||||
@ -1708,7 +1733,7 @@ func (dm *DockerManager) runContainerInPod(pod *v1.Pod, container *v1.Container,
|
|||||||
|
|
||||||
oomScoreAdj := dm.calculateOomScoreAdj(pod, container)
|
oomScoreAdj := dm.calculateOomScoreAdj(pod, container)
|
||||||
|
|
||||||
id, err := dm.runContainer(pod, container, opts, ref, netMode, ipcMode, utsMode, pidMode, restartCount, oomScoreAdj)
|
id, err := dm.runContainer(pod, container, opts, ref, imageRef, netMode, ipcMode, utsMode, pidMode, restartCount, oomScoreAdj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return kubecontainer.ContainerID{}, fmt.Errorf("runContainer: %v", err)
|
return kubecontainer.ContainerID{}, fmt.Errorf("runContainer: %v", err)
|
||||||
}
|
}
|
||||||
@ -1888,12 +1913,13 @@ func (dm *DockerManager) createPodInfraContainer(pod *v1.Pod) (kubecontainer.Doc
|
|||||||
|
|
||||||
// No pod secrets for the infra container.
|
// No pod secrets for the infra container.
|
||||||
// The message isn't needed for the Infra container
|
// The message isn't needed for the Infra container
|
||||||
if err, msg := dm.imagePuller.EnsureImageExists(pod, container, nil); err != nil {
|
imageRef, msg, err := dm.imagePuller.EnsureImageExists(pod, container, nil)
|
||||||
|
if err != nil {
|
||||||
return "", err, msg
|
return "", err, msg
|
||||||
}
|
}
|
||||||
|
|
||||||
// Currently we don't care about restart count of infra container, just set it to 0.
|
// Currently we don't care about restart count of infra container, just set it to 0.
|
||||||
id, err := dm.runContainerInPod(pod, container, netNamespace, getIPCMode(pod), getPidMode(pod), "", 0)
|
id, err := dm.runContainerInPod(pod, container, netNamespace, getIPCMode(pod), getPidMode(pod), "", imageRef, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", kubecontainer.ErrRunContainer, err.Error()
|
return "", kubecontainer.ErrRunContainer, err.Error()
|
||||||
}
|
}
|
||||||
@ -2305,7 +2331,7 @@ func (dm *DockerManager) SyncPod(pod *v1.Pod, _ v1.PodStatus, podStatus *kubecon
|
|||||||
// tryContainerStart attempts to pull and start the container, returning an error and a reason string if the start
|
// tryContainerStart attempts to pull and start the container, returning an error and a reason string if the start
|
||||||
// was not successful.
|
// was not successful.
|
||||||
func (dm *DockerManager) tryContainerStart(container *v1.Container, pod *v1.Pod, podStatus *kubecontainer.PodStatus, pullSecrets []v1.Secret, namespaceMode, pidMode, podIP string) (err error, reason string) {
|
func (dm *DockerManager) tryContainerStart(container *v1.Container, pod *v1.Pod, podStatus *kubecontainer.PodStatus, pullSecrets []v1.Secret, namespaceMode, pidMode, podIP string) (err error, reason string) {
|
||||||
err, msg := dm.imagePuller.EnsureImageExists(pod, container, pullSecrets)
|
imageRef, msg, err := dm.imagePuller.EnsureImageExists(pod, container, pullSecrets)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err, msg
|
return err, msg
|
||||||
}
|
}
|
||||||
@ -2331,7 +2357,7 @@ func (dm *DockerManager) tryContainerStart(container *v1.Container, pod *v1.Pod,
|
|||||||
netMode = namespaceMode
|
netMode = namespaceMode
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = dm.runContainerInPod(pod, container, netMode, namespaceMode, pidMode, podIP, restartCount)
|
_, err = dm.runContainerInPod(pod, container, netMode, namespaceMode, pidMode, podIP, imageRef, restartCount)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO(bburns) : Perhaps blacklist a container after N failures?
|
// TODO(bburns) : Perhaps blacklist a container after N failures?
|
||||||
return kubecontainer.ErrRunContainer, err.Error()
|
return kubecontainer.ErrRunContainer, err.Error()
|
||||||
|
@ -112,8 +112,8 @@ func newFakeImageManager() images.ImageManager {
|
|||||||
return &fakeImageManager{}
|
return &fakeImageManager{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *fakeImageManager) EnsureImageExists(pod *v1.Pod, container *v1.Container, pullSecrets []v1.Secret) (error, string) {
|
func (m *fakeImageManager) EnsureImageExists(pod *v1.Pod, container *v1.Container, pullSecrets []v1.Secret) (string, string, error) {
|
||||||
return nil, ""
|
return container.Image, "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createTestDockerManager(fakeHTTPClient *fakeHTTP, fakeDocker *FakeDockerClient) (*DockerManager, *FakeDockerClient) {
|
func createTestDockerManager(fakeHTTPClient *fakeHTTP, fakeDocker *FakeDockerClient) (*DockerManager, *FakeDockerClient) {
|
||||||
@ -647,9 +647,9 @@ func TestSyncPodCreatesNetAndContainerPullsImage(t *testing.T) {
|
|||||||
|
|
||||||
verifyCalls(t, fakeDocker, []string{
|
verifyCalls(t, fakeDocker, []string{
|
||||||
// Create pod infra container.
|
// Create pod infra container.
|
||||||
"create", "start", "inspect_container", "inspect_container",
|
"inspect_image", "create", "start", "inspect_container", "inspect_container",
|
||||||
// Create container.
|
// Create container.
|
||||||
"create", "start", "inspect_container",
|
"inspect_image", "create", "start", "inspect_container",
|
||||||
})
|
})
|
||||||
|
|
||||||
fakeDocker.Lock()
|
fakeDocker.Lock()
|
||||||
|
@ -592,18 +592,18 @@ func (f *FakeDockerPuller) Pull(image string, secrets []v1.Secret) (err error) {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FakeDockerPuller) IsImagePresent(name string) (bool, error) {
|
func (f *FakeDockerPuller) IsImagePresent(name string) (string, error) {
|
||||||
f.Lock()
|
f.Lock()
|
||||||
defer f.Unlock()
|
defer f.Unlock()
|
||||||
if f.HasImages == nil {
|
if f.HasImages == nil {
|
||||||
return true, nil
|
return name, nil
|
||||||
}
|
}
|
||||||
for _, s := range f.HasImages {
|
for _, s := range f.HasImages {
|
||||||
if s == name {
|
if s == name {
|
||||||
return true, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false, nil
|
return "", nil
|
||||||
}
|
}
|
||||||
func (f *FakeDockerClient) ImageHistory(id string) ([]dockertypes.ImageHistory, error) {
|
func (f *FakeDockerClient) ImageHistory(id string) ([]dockertypes.ImageHistory, error) {
|
||||||
f.Lock()
|
f.Lock()
|
||||||
|
Loading…
Reference in New Issue
Block a user