Merge pull request #83730 from claudiubelu/windows/containerd-etc-hosts

Windows: Fixes /etc/hosts file mounting support for containerd
This commit is contained in:
Kubernetes Prow Robot 2021-03-05 05:08:22 -08:00 committed by GitHub
commit 55f255208a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 23 additions and 9 deletions

View File

@ -144,7 +144,8 @@ const (
evictionMonitoringPeriod = time.Second * 10
// The path in containers' filesystems where the hosts file is mounted.
etcHostsPath = "/etc/hosts"
linuxEtcHostsPath = "/etc/hosts"
windowsEtcHostsPath = "C:\\Windows\\System32\\drivers\\etc\\hosts"
// Capacity of the channel for receiving pod lifecycle events. This number
// is a bit arbitrary and may be adjusted in the future.
@ -177,6 +178,15 @@ const (
nodeLeaseRenewIntervalFraction = 0.25
)
var etcHostsPath = getContainerEtcHostsPath()
func getContainerEtcHostsPath() string {
if sysruntime.GOOS == "windows" {
return windowsEtcHostsPath
}
return linuxEtcHostsPath
}
// SyncHandler is an interface implemented by Kubelet, for testability
type SyncHandler interface {
HandlePodAdditions(pods []*v1.Pod)

View File

@ -141,14 +141,15 @@ func (kl *Kubelet) makeBlockVolumes(pod *v1.Pod, container *v1.Container, podVol
}
// makeMounts determines the mount points for the given container.
func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, hostDomain string, podIPs []string, podVolumes kubecontainer.VolumeMap, hu hostutil.HostUtils, subpather subpath.Interface, expandEnvs []kubecontainer.EnvVar) ([]kubecontainer.Mount, func(), error) {
func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, hostDomain string, podIPs []string, podVolumes kubecontainer.VolumeMap, hu hostutil.HostUtils, subpather subpath.Interface, expandEnvs []kubecontainer.EnvVar, supportsSingleFileMapping bool) ([]kubecontainer.Mount, func(), error) {
// Kubernetes only mounts on /etc/hosts if:
// - container is not an infrastructure (pause) container
// - container is not already mounting on /etc/hosts
// - OS is not Windows
// - if it is Windows, ContainerD is used.
// Kubernetes will not mount /etc/hosts if:
// - when the Pod sandbox is being created, its IP is still unknown. Hence, PodIP will not have been set.
mountEtcHostsFile := len(podIPs) > 0 && runtime.GOOS != "windows"
mountEtcHostsFile := len(podIPs) > 0 && supportsSingleFileMapping
klog.V(3).Infof("container: %v/%v/%v podIPs: %q creating hosts mount: %v", pod.Namespace, pod.Name, container.Name, podIPs, mountEtcHostsFile)
mounts := []kubecontainer.Mount{}
var cleanupAction func()
@ -302,7 +303,9 @@ func translateMountPropagation(mountMode *v1.MountPropagationMode) (runtimeapi.M
// getEtcHostsPath returns the full host-side path to a pod's generated /etc/hosts file
func getEtcHostsPath(podDir string) string {
return path.Join(podDir, "etc-hosts")
hostsFilePath := path.Join(podDir, "etc-hosts")
// Volume Mounts fail on Windows if it is not of the form C:/
return volumeutil.MakeAbsolutePath(runtime.GOOS, hostsFilePath)
}
// makeHostsMount makes the mountpoint for the hosts file that the containers
@ -488,8 +491,10 @@ func (kl *Kubelet) GenerateRunContainerOptions(pod *v1.Pod, container *v1.Contai
}
opts.Envs = append(opts.Envs, envs...)
// we can only mount individual files (e.g.: /etc/hosts, termination-log files) on Windows only if we're using Containerd.
supportsSingleFileMapping := kl.containerRuntime.SupportsSingleFileMapping()
// only podIPs is sent to makeMounts, as podIPs is populated even if dual-stack feature flag is not enabled.
mounts, cleanupAction, err := makeMounts(pod, kl.getPodDir(pod.UID), container, hostname, hostDomainName, podIPs, volumes, kl.hostutil, kl.subpather, opts.Envs)
mounts, cleanupAction, err := makeMounts(pod, kl.getPodDir(pod.UID), container, hostname, hostDomainName, podIPs, volumes, kl.hostutil, kl.subpather, opts.Envs, supportsSingleFileMapping)
if err != nil {
return nil, cleanupAction, err
}
@ -497,7 +502,6 @@ func (kl *Kubelet) GenerateRunContainerOptions(pod *v1.Pod, container *v1.Contai
// 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 {

View File

@ -249,7 +249,7 @@ func TestMakeMounts(t *testing.T) {
},
}
mounts, _, err := makeMounts(&pod, "/pod", &tc.container, "fakepodname", "", []string{""}, tc.podVolumes, fhu, fsp, nil)
mounts, _, err := makeMounts(&pod, "/pod", &tc.container, "fakepodname", "", []string{""}, tc.podVolumes, fhu, fsp, nil, false)
// validate only the error if we expect an error
if tc.expectErr {

View File

@ -100,7 +100,7 @@ func TestDisabledSubpath(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeSubpath, false)()
for name, test := range cases {
_, _, err := makeMounts(&pod, "/pod", &test.container, "fakepodname", "", []string{}, podVolumes, fhu, fsp, nil)
_, _, err := makeMounts(&pod, "/pod", &test.container, "fakepodname", "", []string{}, podVolumes, fhu, fsp, nil, false)
if err != nil && !test.expectError {
t.Errorf("test %v failed: %v", name, err)
}

View File

@ -84,7 +84,7 @@ func TestMakeMountsWindows(t *testing.T) {
fhu := hostutil.NewFakeHostUtil(nil)
fsp := &subpath.FakeSubpath{}
mounts, _, _ := makeMounts(&pod, "/pod", &container, "fakepodname", "", []string{""}, podVolumes, fhu, fsp, nil)
mounts, _, _ := makeMounts(&pod, "/pod", &container, "fakepodname", "", []string{""}, podVolumes, fhu, fsp, nil, false)
expectedMounts := []kubecontainer.Mount{
{