kubelet - adding pod annotations to various image calls to get runtime-handler info to CRI

This commit is contained in:
marosset 2020-04-10 17:24:55 +00:00
parent 348153d55a
commit 03479e4d12
6 changed files with 233 additions and 5 deletions

View File

@ -25,7 +25,7 @@ import (
"strings"
"time"
"k8s.io/api/core/v1"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/tools/remotecommand"
"k8s.io/client-go/util/flowcontrol"
@ -47,7 +47,11 @@ type Version interface {
// value of a Container's Image field, but in the future it will include more detailed
// information about the different image types.
type ImageSpec struct {
// ID of the image.
Image string
// The annotations for the image.
// This should be passed to CRI during image pulls and returned when images are listed.
Annotations []Annotation
}
// ImageStats contains statistics about all the images currently available.
@ -349,6 +353,8 @@ type Image struct {
RepoDigests []string
// The size of the image in bytes.
Size int64
// ImageSpec for the image which include annotations.
Spec ImageSpec
}
type EnvVar struct {

View File

@ -101,7 +101,18 @@ func (m *imageManager) EnsureImageExists(pod *v1.Pod, container *v1.Container, p
return "", msg, ErrInvalidImageName
}
spec := kubecontainer.ImageSpec{Image: image}
var podAnnotations []kubecontainer.Annotation
for k, v := range pod.GetAnnotations() {
podAnnotations = append(podAnnotations, kubecontainer.Annotation{
Name: k,
Value: v,
})
}
spec := kubecontainer.ImageSpec{
Image: image,
Annotations: podAnnotations,
}
imageRef, err := m.imageService.GetImageRef(spec)
if err != nil {
msg := fmt.Sprintf("Failed to inspect image %q: %v", container.Image, err)

View File

@ -9,6 +9,7 @@ load(
go_library(
name = "go_default_library",
srcs = [
"convert.go",
"doc.go",
"fake_kuberuntime_manager.go",
"helpers.go",
@ -91,6 +92,7 @@ go_library(
go_test(
name = "go_default_test",
srcs = [
"convert_test.go",
"helpers_linux_test.go",
"helpers_test.go",
"instrumented_services_test.go",

View File

@ -0,0 +1,55 @@
/*
Copyright 2020 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package kuberuntime
import (
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
)
// This file contains help function to kuberuntime types to CRI runtime API types, or vice versa.
func toKubeContainerImageSpec(image *runtimeapi.Image) kubecontainer.ImageSpec {
var annotations []kubecontainer.Annotation
if image.Spec != nil && image.Spec.Annotations != nil {
for k, v := range image.Spec.Annotations {
annotations = append(annotations, kubecontainer.Annotation{
Name: k,
Value: v,
})
}
}
return kubecontainer.ImageSpec{
Image: image.Id,
Annotations: annotations,
}
}
func toRuntimeAPIImageSpec(imageSpec kubecontainer.ImageSpec) *runtimeapi.ImageSpec {
var annotations = make(map[string]string)
if imageSpec.Annotations != nil {
for _, a := range imageSpec.Annotations {
annotations[a.Name] = a.Value
}
}
return &runtimeapi.ImageSpec{
Image: imageSpec.Image,
Annotations: annotations,
}
}

View File

@ -0,0 +1,152 @@
/*
Copyright 2020 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package kuberuntime
import (
"testing"
"github.com/stretchr/testify/assert"
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
)
func TestConvertToKubeContainerImageSpec(t *testing.T) {
testCases := []struct {
input *runtimeapi.Image
expected kubecontainer.ImageSpec
}{
{
input: &runtimeapi.Image{
Id: "test",
Spec: nil,
},
expected: kubecontainer.ImageSpec{
Image: "test",
Annotations: []kubecontainer.Annotation(nil),
},
},
{
input: &runtimeapi.Image{
Id: "test",
Spec: &runtimeapi.ImageSpec{
Annotations: nil,
},
},
expected: kubecontainer.ImageSpec{
Image: "test",
Annotations: []kubecontainer.Annotation(nil),
},
},
{
input: &runtimeapi.Image{
Id: "test",
Spec: &runtimeapi.ImageSpec{
Annotations: map[string]string{},
},
},
expected: kubecontainer.ImageSpec{
Image: "test",
Annotations: []kubecontainer.Annotation(nil),
},
},
{
input: &runtimeapi.Image{
Id: "test",
Spec: &runtimeapi.ImageSpec{
Annotations: map[string]string{
"kubernetes.io/os": "linux",
"kubernetes.io/runtimehandler": "handler",
},
},
},
expected: kubecontainer.ImageSpec{
Image: "test",
Annotations: []kubecontainer.Annotation{
{
Name: "kubernetes.io/os",
Value: "linux",
},
{
Name: "kubernetes.io/runtimehandler",
Value: "handler",
},
},
},
},
}
for _, test := range testCases {
actual := toKubeContainerImageSpec(test.input)
assert.Equal(t, test.expected, actual)
}
}
func TestConvertToRuntimeAPIImageSpec(t *testing.T) {
testCases := []struct {
input kubecontainer.ImageSpec
expected *runtimeapi.ImageSpec
}{
{
input: kubecontainer.ImageSpec{
Image: "test",
Annotations: nil,
},
expected: &runtimeapi.ImageSpec{
Image: "test",
Annotations: map[string]string{},
},
},
{
input: kubecontainer.ImageSpec{
Image: "test",
Annotations: []kubecontainer.Annotation{},
},
expected: &runtimeapi.ImageSpec{
Image: "test",
Annotations: map[string]string{},
},
},
{
input: kubecontainer.ImageSpec{
Image: "test",
Annotations: []kubecontainer.Annotation{
{
Name: "kubernetes.io/os",
Value: "linux",
},
{
Name: "kubernetes.io/runtimehandler",
Value: "handler",
},
},
},
expected: &runtimeapi.ImageSpec{
Image: "test",
Annotations: map[string]string{
"kubernetes.io/os": "linux",
"kubernetes.io/runtimehandler": "handler",
},
},
},
}
for _, test := range testCases {
actual := toRuntimeAPIImageSpec(test.input)
assert.Equal(t, test.expected, actual)
}
}

View File

@ -17,7 +17,7 @@ limitations under the License.
package kuberuntime
import (
"k8s.io/api/core/v1"
v1 "k8s.io/api/core/v1"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
"k8s.io/klog"
@ -40,7 +40,8 @@ func (m *kubeGenericRuntimeManager) PullImage(image kubecontainer.ImageSpec, pul
return "", err
}
imgSpec := &runtimeapi.ImageSpec{Image: img}
imgSpec := toRuntimeAPIImageSpec(image)
creds, withCredentials := keyring.Lookup(repoToPull)
if !withCredentials {
klog.V(3).Infof("Pulling image %q without credentials", img)
@ -80,7 +81,7 @@ func (m *kubeGenericRuntimeManager) PullImage(image kubecontainer.ImageSpec, pul
// GetImageRef gets the ID of the image which has already been in
// the local storage. It returns ("", nil) if the image isn't in the local storage.
func (m *kubeGenericRuntimeManager) GetImageRef(image kubecontainer.ImageSpec) (string, error) {
status, err := m.imageService.ImageStatus(&runtimeapi.ImageSpec{Image: image.Image})
status, err := m.imageService.ImageStatus(toRuntimeAPIImageSpec(image))
if err != nil {
klog.Errorf("ImageStatus for image %q failed: %v", image, err)
return "", err
@ -107,6 +108,7 @@ func (m *kubeGenericRuntimeManager) ListImages() ([]kubecontainer.Image, error)
Size: int64(img.Size_),
RepoTags: img.RepoTags,
RepoDigests: img.RepoDigests,
Spec: toKubeContainerImageSpec(img),
})
}