mirror of https://github.com/k3s-io/k3s
Merge pull request #71764 from linxiulei/fix_cri_pullimage
Pass PodSandboxConfig to PullImage method in CRIpull/564/head
commit
998167767f
|
@ -111,7 +111,7 @@ type ImageManagerService interface {
|
|||
// ImageStatus returns the status of the image.
|
||||
ImageStatus(image *runtimeapi.ImageSpec) (*runtimeapi.Image, error)
|
||||
// PullImage pulls an image with the authentication config.
|
||||
PullImage(image *runtimeapi.ImageSpec, auth *runtimeapi.AuthConfig) (string, error)
|
||||
PullImage(image *runtimeapi.ImageSpec, auth *runtimeapi.AuthConfig, podSandboxConfig *runtimeapi.PodSandboxConfig) (string, error)
|
||||
// RemoveImage removes the image.
|
||||
RemoveImage(image *runtimeapi.ImageSpec) error
|
||||
// ImageFsInfo returns information of the filesystem that is used to store images.
|
||||
|
|
|
@ -105,7 +105,7 @@ func (r *FakeImageService) ImageStatus(image *runtimeapi.ImageSpec) (*runtimeapi
|
|||
return r.Images[image.Image], nil
|
||||
}
|
||||
|
||||
func (r *FakeImageService) PullImage(image *runtimeapi.ImageSpec, auth *runtimeapi.AuthConfig) (string, error) {
|
||||
func (r *FakeImageService) PullImage(image *runtimeapi.ImageSpec, auth *runtimeapi.AuthConfig, podSandboxConfig *runtimeapi.PodSandboxConfig) (string, error) {
|
||||
r.Lock()
|
||||
defer r.Unlock()
|
||||
|
||||
|
|
|
@ -137,7 +137,7 @@ type StreamingRuntime interface {
|
|||
type ImageService interface {
|
||||
// PullImage pulls an image from the network to local storage using the supplied
|
||||
// secrets if necessary. It returns a reference (digest or ID) to the pulled image.
|
||||
PullImage(image ImageSpec, pullSecrets []v1.Secret) (string, error)
|
||||
PullImage(image ImageSpec, pullSecrets []v1.Secret, podSandboxConfig *runtimeapi.PodSandboxConfig) (string, error)
|
||||
// GetImageRef gets the reference (digest or ID) of the image which has already been in
|
||||
// the local storage. It returns ("", nil) if the image isn't in the local storage.
|
||||
GetImageRef(image ImageSpec) (string, error)
|
||||
|
|
|
@ -28,6 +28,7 @@ import (
|
|||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/util/flowcontrol"
|
||||
runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
. "k8s.io/kubernetes/pkg/kubelet/container"
|
||||
"k8s.io/kubernetes/pkg/volume"
|
||||
)
|
||||
|
@ -298,7 +299,7 @@ func (f *FakeRuntime) GetContainerLogs(_ context.Context, pod *v1.Pod, container
|
|||
return f.Err
|
||||
}
|
||||
|
||||
func (f *FakeRuntime) PullImage(image ImageSpec, pullSecrets []v1.Secret) (string, error) {
|
||||
func (f *FakeRuntime) PullImage(image ImageSpec, pullSecrets []v1.Secret, podSandboxConfig *runtimeapi.PodSandboxConfig) (string, error) {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ import (
|
|||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/tools/remotecommand"
|
||||
"k8s.io/client-go/util/flowcontrol"
|
||||
runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
. "k8s.io/kubernetes/pkg/kubelet/container"
|
||||
"k8s.io/kubernetes/pkg/volume"
|
||||
)
|
||||
|
@ -106,7 +107,7 @@ func (r *Mock) GetContainerLogs(_ context.Context, pod *v1.Pod, containerID Cont
|
|||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (r *Mock) PullImage(image ImageSpec, pullSecrets []v1.Secret) (string, error) {
|
||||
func (r *Mock) PullImage(image ImageSpec, pullSecrets []v1.Secret, podSandboxConfig *runtimeapi.PodSandboxConfig) (string, error) {
|
||||
args := r.Called(image, pullSecrets)
|
||||
return image.Image, args.Error(0)
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ go_library(
|
|||
],
|
||||
importpath = "k8s.io/kubernetes/pkg/kubelet/images",
|
||||
deps = [
|
||||
"//pkg/kubelet/apis/cri/runtime/v1alpha2:go_default_library",
|
||||
"//pkg/kubelet/apis/stats/v1alpha1:go_default_library",
|
||||
"//pkg/kubelet/container:go_default_library",
|
||||
"//pkg/kubelet/events:go_default_library",
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/client-go/util/flowcontrol"
|
||||
runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
||||
)
|
||||
|
||||
|
@ -42,9 +43,9 @@ type throttledImageService struct {
|
|||
limiter flowcontrol.RateLimiter
|
||||
}
|
||||
|
||||
func (ts throttledImageService) PullImage(image kubecontainer.ImageSpec, secrets []v1.Secret) (string, error) {
|
||||
func (ts throttledImageService) PullImage(image kubecontainer.ImageSpec, secrets []v1.Secret, podSandboxConfig *runtimeapi.PodSandboxConfig) (string, error) {
|
||||
if ts.limiter.TryAccept() {
|
||||
return ts.ImageService.PullImage(image, secrets)
|
||||
return ts.ImageService.PullImage(image, secrets, podSandboxConfig)
|
||||
}
|
||||
return "", fmt.Errorf("pull QPS exceeded")
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@ import (
|
|||
"k8s.io/client-go/tools/record"
|
||||
"k8s.io/client-go/util/flowcontrol"
|
||||
"k8s.io/klog"
|
||||
|
||||
runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
||||
"k8s.io/kubernetes/pkg/kubelet/events"
|
||||
"k8s.io/kubernetes/pkg/util/parsers"
|
||||
|
@ -84,7 +86,7 @@ func (m *imageManager) logIt(ref *v1.ObjectReference, eventtype, event, prefix,
|
|||
|
||||
// EnsureImageExists pulls the image for the specified pod and container, and returns
|
||||
// (imageRef, error message, error).
|
||||
func (m *imageManager) EnsureImageExists(pod *v1.Pod, container *v1.Container, pullSecrets []v1.Secret) (string, string, error) {
|
||||
func (m *imageManager) EnsureImageExists(pod *v1.Pod, container *v1.Container, pullSecrets []v1.Secret, podSandboxConfig *runtimeapi.PodSandboxConfig) (string, string, error) {
|
||||
logPrefix := fmt.Sprintf("%s/%s", pod.Name, container.Image)
|
||||
ref, err := kubecontainer.GenerateContainerRef(pod, container)
|
||||
if err != nil {
|
||||
|
@ -127,7 +129,7 @@ func (m *imageManager) EnsureImageExists(pod *v1.Pod, container *v1.Container, p
|
|||
}
|
||||
m.logIt(ref, v1.EventTypeNormal, events.PullingImage, logPrefix, fmt.Sprintf("pulling image %q", container.Image), klog.Info)
|
||||
pullChan := make(chan pullResult)
|
||||
m.puller.pullImage(spec, pullSecrets, pullChan)
|
||||
m.puller.pullImage(spec, pullSecrets, pullChan, podSandboxConfig)
|
||||
imagePullResult := <-pullChan
|
||||
if imagePullResult.err != nil {
|
||||
m.logIt(ref, v1.EventTypeWarning, events.FailedToPullImage, logPrefix, fmt.Sprintf("Failed to pull image %q: %v", container.Image, imagePullResult.err), klog.Warning)
|
||||
|
|
|
@ -151,7 +151,7 @@ func TestParallelPuller(t *testing.T) {
|
|||
for tick, expected := range c.expected {
|
||||
fakeRuntime.CalledFunctions = nil
|
||||
fakeClock.Step(time.Second)
|
||||
_, _, err := puller.EnsureImageExists(pod, container, nil)
|
||||
_, _, err := puller.EnsureImageExists(pod, container, nil, nil)
|
||||
assert.NoError(t, fakeRuntime.AssertCalls(expected.calls), "in test %d tick=%d", i, tick)
|
||||
assert.Equal(t, expected.err, err, "in test %d tick=%d", i, tick)
|
||||
}
|
||||
|
@ -176,7 +176,7 @@ func TestSerializedPuller(t *testing.T) {
|
|||
for tick, expected := range c.expected {
|
||||
fakeRuntime.CalledFunctions = nil
|
||||
fakeClock.Step(time.Second)
|
||||
_, _, err := puller.EnsureImageExists(pod, container, nil)
|
||||
_, _, err := puller.EnsureImageExists(pod, container, nil, nil)
|
||||
assert.NoError(t, fakeRuntime.AssertCalls(expected.calls), "in test %d tick=%d", i, tick)
|
||||
assert.Equal(t, expected.err, err, "in test %d tick=%d", i, tick)
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
||||
)
|
||||
|
||||
|
@ -30,7 +31,7 @@ type pullResult struct {
|
|||
}
|
||||
|
||||
type imagePuller interface {
|
||||
pullImage(kubecontainer.ImageSpec, []v1.Secret, chan<- pullResult)
|
||||
pullImage(kubecontainer.ImageSpec, []v1.Secret, chan<- pullResult, *runtimeapi.PodSandboxConfig)
|
||||
}
|
||||
|
||||
var _, _ imagePuller = ¶llelImagePuller{}, &serialImagePuller{}
|
||||
|
@ -43,9 +44,9 @@ func newParallelImagePuller(imageService kubecontainer.ImageService) imagePuller
|
|||
return ¶llelImagePuller{imageService}
|
||||
}
|
||||
|
||||
func (pip *parallelImagePuller) pullImage(spec kubecontainer.ImageSpec, pullSecrets []v1.Secret, pullChan chan<- pullResult) {
|
||||
func (pip *parallelImagePuller) pullImage(spec kubecontainer.ImageSpec, pullSecrets []v1.Secret, pullChan chan<- pullResult, podSandboxConfig *runtimeapi.PodSandboxConfig) {
|
||||
go func() {
|
||||
imageRef, err := pip.imageService.PullImage(spec, pullSecrets)
|
||||
imageRef, err := pip.imageService.PullImage(spec, pullSecrets, podSandboxConfig)
|
||||
pullChan <- pullResult{
|
||||
imageRef: imageRef,
|
||||
err: err,
|
||||
|
@ -68,22 +69,24 @@ func newSerialImagePuller(imageService kubecontainer.ImageService) imagePuller {
|
|||
}
|
||||
|
||||
type imagePullRequest struct {
|
||||
spec kubecontainer.ImageSpec
|
||||
pullSecrets []v1.Secret
|
||||
pullChan chan<- pullResult
|
||||
spec kubecontainer.ImageSpec
|
||||
pullSecrets []v1.Secret
|
||||
pullChan chan<- pullResult
|
||||
podSandboxConfig *runtimeapi.PodSandboxConfig
|
||||
}
|
||||
|
||||
func (sip *serialImagePuller) pullImage(spec kubecontainer.ImageSpec, pullSecrets []v1.Secret, pullChan chan<- pullResult) {
|
||||
func (sip *serialImagePuller) pullImage(spec kubecontainer.ImageSpec, pullSecrets []v1.Secret, pullChan chan<- pullResult, podSandboxConfig *runtimeapi.PodSandboxConfig) {
|
||||
sip.pullRequests <- &imagePullRequest{
|
||||
spec: spec,
|
||||
pullSecrets: pullSecrets,
|
||||
pullChan: pullChan,
|
||||
spec: spec,
|
||||
pullSecrets: pullSecrets,
|
||||
pullChan: pullChan,
|
||||
podSandboxConfig: podSandboxConfig,
|
||||
}
|
||||
}
|
||||
|
||||
func (sip *serialImagePuller) processImagePullRequests() {
|
||||
for pullRequest := range sip.pullRequests {
|
||||
imageRef, err := sip.imageService.PullImage(pullRequest.spec, pullRequest.pullSecrets)
|
||||
imageRef, err := sip.imageService.PullImage(pullRequest.spec, pullRequest.pullSecrets, pullRequest.podSandboxConfig)
|
||||
pullRequest.pullChan <- pullResult{
|
||||
imageRef: imageRef,
|
||||
err: err,
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"errors"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -49,7 +50,7 @@ var (
|
|||
// Implementations are expected to be thread safe.
|
||||
type ImageManager interface {
|
||||
// EnsureImageExists ensures that image specified in `container` exists.
|
||||
EnsureImageExists(pod *v1.Pod, container *v1.Container, pullSecrets []v1.Secret) (string, string, error)
|
||||
EnsureImageExists(pod *v1.Pod, container *v1.Container, pullSecrets []v1.Secret, podSandboxConfig *runtimeapi.PodSandboxConfig) (string, string, error)
|
||||
|
||||
// TODO(ronl): consolidating image managing and deleting operation in this interface
|
||||
}
|
||||
|
|
|
@ -275,11 +275,11 @@ func (in instrumentedImageManagerService) ImageStatus(image *runtimeapi.ImageSpe
|
|||
return out, err
|
||||
}
|
||||
|
||||
func (in instrumentedImageManagerService) PullImage(image *runtimeapi.ImageSpec, auth *runtimeapi.AuthConfig) (string, error) {
|
||||
func (in instrumentedImageManagerService) PullImage(image *runtimeapi.ImageSpec, auth *runtimeapi.AuthConfig, podSandboxConfig *runtimeapi.PodSandboxConfig) (string, error) {
|
||||
const operation = "pull_image"
|
||||
defer recordOperation(operation, time.Now())
|
||||
|
||||
imageRef, err := in.service.PullImage(image, auth)
|
||||
imageRef, err := in.service.PullImage(image, auth, podSandboxConfig)
|
||||
recordError(operation, err)
|
||||
return imageRef, err
|
||||
}
|
||||
|
|
|
@ -92,7 +92,7 @@ func (m *kubeGenericRuntimeManager) recordContainerEvent(pod *v1.Pod, container
|
|||
// * run the post start lifecycle hooks (if applicable)
|
||||
func (m *kubeGenericRuntimeManager) startContainer(podSandboxID string, podSandboxConfig *runtimeapi.PodSandboxConfig, container *v1.Container, pod *v1.Pod, podStatus *kubecontainer.PodStatus, pullSecrets []v1.Secret, podIP string, containerType kubecontainer.ContainerType) (string, error) {
|
||||
// Step 1: pull the image.
|
||||
imageRef, msg, err := m.imagePuller.EnsureImageExists(pod, container, pullSecrets)
|
||||
imageRef, msg, err := m.imagePuller.EnsureImageExists(pod, container, pullSecrets, podSandboxConfig)
|
||||
if err != nil {
|
||||
m.recordContainerEvent(pod, container, "", v1.EventTypeWarning, events.FailedToCreateContainer, "Error: %v", grpc.ErrorDesc(err))
|
||||
return msg, err
|
||||
|
|
|
@ -124,7 +124,7 @@ func TestGenerateContainerConfig(t *testing.T) {
|
|||
_, _, err = m.generateContainerConfig(&podWithContainerSecurityContext.Spec.Containers[0], podWithContainerSecurityContext, 0, "", podWithContainerSecurityContext.Spec.Containers[0].Image, kubecontainer.ContainerTypeRegular)
|
||||
assert.Error(t, err)
|
||||
|
||||
imageID, _ := imageService.PullImage(&runtimeapi.ImageSpec{Image: "busybox"}, nil)
|
||||
imageID, _ := imageService.PullImage(&runtimeapi.ImageSpec{Image: "busybox"}, nil, nil)
|
||||
image, _ := imageService.ImageStatus(&runtimeapi.ImageSpec{Image: imageID})
|
||||
|
||||
image.Uid = nil
|
||||
|
|
|
@ -29,7 +29,7 @@ import (
|
|||
|
||||
// PullImage pulls an image from the network to local storage using the supplied
|
||||
// secrets if necessary.
|
||||
func (m *kubeGenericRuntimeManager) PullImage(image kubecontainer.ImageSpec, pullSecrets []v1.Secret) (string, error) {
|
||||
func (m *kubeGenericRuntimeManager) PullImage(image kubecontainer.ImageSpec, pullSecrets []v1.Secret, podSandboxConfig *runtimeapi.PodSandboxConfig) (string, error) {
|
||||
img := image.Image
|
||||
repoToPull, _, _, err := parsers.ParseImageName(img)
|
||||
if err != nil {
|
||||
|
@ -46,7 +46,7 @@ func (m *kubeGenericRuntimeManager) PullImage(image kubecontainer.ImageSpec, pul
|
|||
if !withCredentials {
|
||||
klog.V(3).Infof("Pulling image %q without credentials", img)
|
||||
|
||||
imageRef, err := m.imageService.PullImage(imgSpec, nil)
|
||||
imageRef, err := m.imageService.PullImage(imgSpec, nil, podSandboxConfig)
|
||||
if err != nil {
|
||||
klog.Errorf("Pull image %q failed: %v", img, err)
|
||||
return "", err
|
||||
|
@ -67,7 +67,7 @@ func (m *kubeGenericRuntimeManager) PullImage(image kubecontainer.ImageSpec, pul
|
|||
RegistryToken: authConfig.RegistryToken,
|
||||
}
|
||||
|
||||
imageRef, err := m.imageService.PullImage(imgSpec, auth)
|
||||
imageRef, err := m.imageService.PullImage(imgSpec, auth, podSandboxConfig)
|
||||
// If there was no error, return success
|
||||
if err == nil {
|
||||
return imageRef, nil
|
||||
|
|
|
@ -34,7 +34,7 @@ func TestPullImage(t *testing.T) {
|
|||
_, _, fakeManager, err := createTestRuntimeManager()
|
||||
assert.NoError(t, err)
|
||||
|
||||
imageRef, err := fakeManager.PullImage(kubecontainer.ImageSpec{Image: "busybox"}, nil)
|
||||
imageRef, err := fakeManager.PullImage(kubecontainer.ImageSpec{Image: "busybox"}, nil, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "busybox", imageRef)
|
||||
|
||||
|
@ -77,7 +77,7 @@ func TestRemoveImage(t *testing.T) {
|
|||
_, fakeImageService, fakeManager, err := createTestRuntimeManager()
|
||||
assert.NoError(t, err)
|
||||
|
||||
_, err = fakeManager.PullImage(kubecontainer.ImageSpec{Image: "busybox"}, nil)
|
||||
_, err = fakeManager.PullImage(kubecontainer.ImageSpec{Image: "busybox"}, nil, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1, len(fakeImageService.Images))
|
||||
|
||||
|
@ -166,7 +166,7 @@ func TestPullWithSecrets(t *testing.T) {
|
|||
_, fakeImageService, fakeManager, err := customTestRuntimeManager(builtInKeyRing)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = fakeManager.PullImage(kubecontainer.ImageSpec{Image: test.imageName}, test.passedSecrets)
|
||||
_, err = fakeManager.PullImage(kubecontainer.ImageSpec{Image: test.imageName}, test.passedSecrets, nil)
|
||||
require.NoError(t, err)
|
||||
fakeImageService.AssertImagePulledWithAuth(t, &runtimeapi.ImageSpec{Image: test.imageName}, test.expectedAuth, description)
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ func (f *RemoteRuntime) ImageStatus(ctx context.Context, req *kubeapi.ImageStatu
|
|||
|
||||
// PullImage pulls an image with authentication config.
|
||||
func (f *RemoteRuntime) PullImage(ctx context.Context, req *kubeapi.PullImageRequest) (*kubeapi.PullImageResponse, error) {
|
||||
image, err := f.ImageService.PullImage(req.Image, req.Auth)
|
||||
image, err := f.ImageService.PullImage(req.Image, req.Auth, req.SandboxConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -100,13 +100,14 @@ func (r *RemoteImageService) ImageStatus(image *runtimeapi.ImageSpec) (*runtimea
|
|||
}
|
||||
|
||||
// PullImage pulls an image with authentication config.
|
||||
func (r *RemoteImageService) PullImage(image *runtimeapi.ImageSpec, auth *runtimeapi.AuthConfig) (string, error) {
|
||||
func (r *RemoteImageService) PullImage(image *runtimeapi.ImageSpec, auth *runtimeapi.AuthConfig, podSandboxConfig *runtimeapi.PodSandboxConfig) (string, error) {
|
||||
ctx, cancel := getContextWithCancel()
|
||||
defer cancel()
|
||||
|
||||
resp, err := r.imageClient.PullImage(ctx, &runtimeapi.PullImageRequest{
|
||||
Image: image,
|
||||
Auth: auth,
|
||||
Image: image,
|
||||
Auth: auth,
|
||||
SandboxConfig: podSandboxConfig,
|
||||
})
|
||||
if err != nil {
|
||||
klog.Errorf("PullImage %q from image service failed: %v", image.Image, err)
|
||||
|
|
|
@ -96,7 +96,7 @@ func (rp *remotePuller) Pull(image string) ([]byte, error) {
|
|||
if err == nil && imageStatus != nil {
|
||||
return nil, nil
|
||||
}
|
||||
_, err = rp.imageService.PullImage(&runtimeapi.ImageSpec{Image: image}, nil)
|
||||
_, err = rp.imageService.PullImage(&runtimeapi.ImageSpec{Image: image}, nil, nil)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue