Windows: Fixes termination-file mounting for containerd
If Containerd is used on Windows, then we can also mount individual files into containers (e.g.: termination-log files), which was not possible with Docker. Checks if the container runtime is containerd, and if it is, then also mount the termination-log file.
This commit is contained in:
parent
3a50184421
commit
d4d7f58362
@ -63,6 +63,9 @@ type Runtime interface {
|
||||
// Type returns the type of the container runtime.
|
||||
Type() string
|
||||
|
||||
//SupportsSingleFileMapping returns whether the container runtime supports single file mappings or not.
|
||||
SupportsSingleFileMapping() bool
|
||||
|
||||
// Version returns the version information of the container runtime.
|
||||
Version() (Version, error)
|
||||
|
||||
|
@ -177,6 +177,10 @@ func (f *FakeRuntime) Type() string {
|
||||
return f.RuntimeType
|
||||
}
|
||||
|
||||
func (f *FakeRuntime) SupportsSingleFileMapping() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (f *FakeRuntime) Version() (kubecontainer.Version, error) {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
|
@ -47,6 +47,11 @@ func (r *Mock) Type() string {
|
||||
return args.Get(0).(string)
|
||||
}
|
||||
|
||||
func (r *Mock) SupportsSingleFileMapping() bool {
|
||||
args := r.Called()
|
||||
return args.Get(0).(bool)
|
||||
}
|
||||
|
||||
func (r *Mock) Version() (kubecontainer.Version, error) {
|
||||
args := r.Called()
|
||||
return args.Get(0).(kubecontainer.Version), args.Error(1)
|
||||
|
@ -471,9 +471,10 @@ func (kl *Kubelet) GenerateRunContainerOptions(pod *v1.Pod, container *v1.Contai
|
||||
}
|
||||
opts.Mounts = append(opts.Mounts, mounts...)
|
||||
|
||||
// Disabling adding TerminationMessagePath on Windows as these files would be mounted as docker volume and
|
||||
// Docker for Windows has a bug where only directories can be mounted
|
||||
if len(container.TerminationMessagePath) != 0 && runtime.GOOS != "windows" {
|
||||
// adding TerminationMessagePath on Windows is only allowed if ContainerD is used. Individual files cannot
|
||||
// be mounted as volumes using Docker for Windows.
|
||||
supportsSingleFileMapping := kl.containerRuntime.SupportsSingleFileMapping()
|
||||
if len(container.TerminationMessagePath) != 0 && supportsSingleFileMapping {
|
||||
p := kl.getPodContainerDir(pod.UID, container.Name)
|
||||
if err := os.MkdirAll(p, 0750); err != nil {
|
||||
klog.Errorf("Error on creating %q: %v", p, err)
|
||||
|
@ -53,6 +53,7 @@ go_library(
|
||||
"//pkg/util/parsers:go_default_library",
|
||||
"//pkg/util/selinux:go_default_library",
|
||||
"//pkg/util/tail:go_default_library",
|
||||
"//pkg/volume/util:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
|
||||
|
@ -25,6 +25,7 @@ import (
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
goruntime "runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
@ -47,6 +48,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/kubelet/util/format"
|
||||
"k8s.io/kubernetes/pkg/util/selinux"
|
||||
"k8s.io/kubernetes/pkg/util/tail"
|
||||
volumeutil "k8s.io/kubernetes/pkg/volume/util"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -292,7 +294,9 @@ func (m *kubeGenericRuntimeManager) makeMounts(opts *kubecontainer.RunContainerO
|
||||
// The reason we create and mount the log file in here (not in kubelet) is because
|
||||
// the file's location depends on the ID of the container, and we need to create and
|
||||
// mount the file before actually starting the container.
|
||||
if opts.PodContainerDir != "" && len(container.TerminationMessagePath) != 0 {
|
||||
// we can only mount individual files (e.g.: /etc/hosts, termination-log files) on Windows only if we're using Containerd.
|
||||
supportsSingleFileMapping := m.SupportsSingleFileMapping()
|
||||
if opts.PodContainerDir != "" && len(container.TerminationMessagePath) != 0 && supportsSingleFileMapping {
|
||||
// Because the PodContainerDir contains pod uid and container name which is unique enough,
|
||||
// here we just add a random id to make the path unique for different instances
|
||||
// of the same container.
|
||||
@ -312,10 +316,13 @@ func (m *kubeGenericRuntimeManager) makeMounts(opts *kubecontainer.RunContainerO
|
||||
utilruntime.HandleError(fmt.Errorf("unable to set termination-log file permissions %q: %v", containerLogPath, err))
|
||||
}
|
||||
|
||||
// Volume Mounts fail on Windows if it is not of the form C:/
|
||||
containerLogPath = volumeutil.MakeAbsolutePath(goruntime.GOOS, containerLogPath)
|
||||
terminationMessagePath := volumeutil.MakeAbsolutePath(goruntime.GOOS, container.TerminationMessagePath)
|
||||
selinuxRelabel := selinux.SELinuxEnabled()
|
||||
volumeMounts = append(volumeMounts, &runtimeapi.Mount{
|
||||
HostPath: containerLogPath,
|
||||
ContainerPath: container.TerminationMessagePath,
|
||||
ContainerPath: terminationMessagePath,
|
||||
SelinuxRelabel: selinuxRelabel,
|
||||
})
|
||||
}
|
||||
@ -355,6 +362,8 @@ func getTerminationMessage(status *runtimeapi.ContainerStatus, terminationMessag
|
||||
if len(terminationMessagePath) == 0 {
|
||||
return "", fallbackToLogs
|
||||
}
|
||||
// Volume Mounts fail on Windows if it is not of the form C:/
|
||||
terminationMessagePath = volumeutil.MakeAbsolutePath(goruntime.GOOS, terminationMessagePath)
|
||||
for _, mount := range status.Mounts {
|
||||
if mount.ContainerPath != terminationMessagePath {
|
||||
continue
|
||||
|
@ -20,6 +20,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
goruntime "runtime"
|
||||
"time"
|
||||
|
||||
cadvisorapi "github.com/google/cadvisor/info/v1"
|
||||
@ -243,6 +244,17 @@ func (m *kubeGenericRuntimeManager) Type() string {
|
||||
return m.runtimeName
|
||||
}
|
||||
|
||||
// SupportsSingleFileMapping returns whether the container runtime supports single file mappings or not.
|
||||
// It is supported on Windows only if the container runtime is containerd.
|
||||
func (m *kubeGenericRuntimeManager) SupportsSingleFileMapping() bool {
|
||||
switch goruntime.GOOS {
|
||||
case "windows":
|
||||
return m.Type() != types.DockerContainerRuntime
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
func newRuntimeVersion(version string) (*utilversion.Version, error) {
|
||||
if ver, err := utilversion.ParseSemantic(version); err == nil {
|
||||
return ver, err
|
||||
|
Loading…
Reference in New Issue
Block a user