Commit 973fa6b3 authored by Kubernetes Submit Queue's avatar Kubernetes Submit Queue Committed by GitHub

Merge pull request #35821 from vishh/gci-mounter-scope

Automatic merge from submit-queue [Kubelet] Use the custom mounter script for Nfs and Glusterfs only This patch reduces the scope for the containerized mounter to NFS and GlusterFS on GCE + GCI clusters This patch also enabled the containerized mounter on GCI nodes Shepherding multiple PRs through the submit queue is painful. Hence I combined them into this PR. Please review each commit individually. cc @jingxu97 @saad-ali https://github.com/kubernetes/kubernetes/pull/35652 has also been reverted as part of this PR
parents 41b5fe86 40fc8048
...@@ -473,6 +473,7 @@ function start-kubelet { ...@@ -473,6 +473,7 @@ function start-kubelet {
flags+=" --cluster-dns=${DNS_SERVER_IP}" flags+=" --cluster-dns=${DNS_SERVER_IP}"
flags+=" --cluster-domain=${DNS_DOMAIN}" flags+=" --cluster-domain=${DNS_DOMAIN}"
flags+=" --config=/etc/kubernetes/manifests" flags+=" --config=/etc/kubernetes/manifests"
flags+=" --experimental-mounter-path=${KUBE_HOME}/bin/mounter"
if [[ -n "${KUBELET_PORT:-}" ]]; then if [[ -n "${KUBELET_PORT:-}" ]]; then
flags+=" --port=${KUBELET_PORT}" flags+=" --port=${KUBELET_PORT}"
...@@ -1171,6 +1172,10 @@ function override-kubectl { ...@@ -1171,6 +1172,10 @@ function override-kubectl {
echo "export PATH=${KUBE_HOME}/bin:\$PATH" > /etc/profile.d/kube_env.sh echo "export PATH=${KUBE_HOME}/bin:\$PATH" > /etc/profile.d/kube_env.sh
} }
function pre-warm-mounter {
${KUBE_HOME}/bin/mounter &> /dev/null
}
########### Main Function ########### ########### Main Function ###########
echo "Start to configure instance for kubernetes" echo "Start to configure instance for kubernetes"
...@@ -1205,6 +1210,8 @@ else ...@@ -1205,6 +1210,8 @@ else
fi fi
override-kubectl override-kubectl
# Run the containerized mounter once to pre-cache the container image.
pre-warm-mounter
assemble-docker-flags assemble-docker-flags
load-docker-images load-docker-images
start-kubelet start-kubelet
......
...@@ -23,14 +23,25 @@ MOUNTER_USER=root ...@@ -23,14 +23,25 @@ MOUNTER_USER=root
RKT_BINARY=/home/kubernetes/bin/rkt RKT_BINARY=/home/kubernetes/bin/rkt
function gc { function gc {
${RKT_BINARY} gc --grace-period=0s &> /dev/null # Attempt to garbage collect rkt pods with 5 retries.
# Rkt pods end up creating new copies of mounts on the host. Hence it is ideal to clean them up right away.
attempt=0
until [ $attempt -ge 5 ]; do
${RKT_BINARY} gc --grace-period=0s && break
attempt=$[$attempt+1]
sleep 1
done
} }
# Garbage collect old rkt containers on exit # Garbage collect old rkt containers on exit
trap gc EXIT trap gc EXIT
echo "Running mount using a rkt fly container"
${RKT_BINARY} run --stage1-name="coreos.com/rkt/stage1-fly:1.18.0" \ ${RKT_BINARY} run --stage1-name="coreos.com/rkt/stage1-fly:1.18.0" \
--insecure-options=image \ --insecure-options=image \
--volume=rootfs,kind=host,source=/,readOnly=false,recursive=true \ --volume=kubelet,kind=host,source=/var/lib/kubelet,readOnly=false,recursive=true \
--mount volume=rootfs,target=/media/root \ --mount volume=kubelet,target=/var/lib/kubelet \
docker://${MOUNTER_DOCKER_IMAGE}:${MOUNTER_DOCKER_VERSION} --user=${MOUNTER_USER} --exec /bin/mount -- "$@" docker://${MOUNTER_DOCKER_IMAGE}:${MOUNTER_DOCKER_VERSION} --user=${MOUNTER_USER} --exec /bin/mount -- "$@"
echo "Successfully ran mount using a rkt fly container"
\ No newline at end of file
...@@ -67,7 +67,7 @@ func (realConntracker) SetTCPEstablishedTimeout(seconds int) error { ...@@ -67,7 +67,7 @@ func (realConntracker) SetTCPEstablishedTimeout(seconds int) error {
func isSysFSWritable() (bool, error) { func isSysFSWritable() (bool, error) {
const permWritable = "rw" const permWritable = "rw"
const sysfsDevice = "sysfs" const sysfsDevice = "sysfs"
m := mount.New() m := mount.New("" /* default mount path */)
mountPoints, err := m.List() mountPoints, err := m.List()
if err != nil { if err != nil {
glog.Errorf("failed to list mount points: %v", err) glog.Errorf("failed to list mount points: %v", err)
......
...@@ -200,7 +200,6 @@ func (s *KubeletServer) AddFlags(fs *pflag.FlagSet) { ...@@ -200,7 +200,6 @@ func (s *KubeletServer) AddFlags(fs *pflag.FlagSet) {
fs.BoolVar(&s.ExitOnLockContention, "exit-on-lock-contention", s.ExitOnLockContention, "Whether kubelet should exit upon lock-file contention.") fs.BoolVar(&s.ExitOnLockContention, "exit-on-lock-contention", s.ExitOnLockContention, "Whether kubelet should exit upon lock-file contention.")
fs.StringVar(&s.RktPath, "rkt-path", s.RktPath, "Path of rkt binary. Leave empty to use the first rkt in $PATH. Only used if --container-runtime='rkt'.") fs.StringVar(&s.RktPath, "rkt-path", s.RktPath, "Path of rkt binary. Leave empty to use the first rkt in $PATH. Only used if --container-runtime='rkt'.")
fs.StringVar(&s.ExperimentalMounterPath, "experimental-mounter-path", s.ExperimentalMounterPath, "[Experimental] Path of mounter binary. Leave empty to use the default mount.") fs.StringVar(&s.ExperimentalMounterPath, "experimental-mounter-path", s.ExperimentalMounterPath, "[Experimental] Path of mounter binary. Leave empty to use the default mount.")
fs.StringVar(&s.ExperimentalMounterRootfsPath, "experimental-mounter-rootfs-path", s.ExperimentalMounterRootfsPath, "[Experimental] Absolute path to the root filesystem for the mounter binary.")
fs.StringVar(&s.RktAPIEndpoint, "rkt-api-endpoint", s.RktAPIEndpoint, "The endpoint of the rkt API service to communicate with. Only used if --container-runtime='rkt'.") fs.StringVar(&s.RktAPIEndpoint, "rkt-api-endpoint", s.RktAPIEndpoint, "The endpoint of the rkt API service to communicate with. Only used if --container-runtime='rkt'.")
fs.StringVar(&s.RktStage1Image, "rkt-stage1-image", s.RktStage1Image, "image to use as stage1. Local paths and http/https URLs are supported. If empty, the 'stage1.aci' in the same directory as '--rkt-path' will be used.") fs.StringVar(&s.RktStage1Image, "rkt-stage1-image", s.RktStage1Image, "image to use as stage1. Local paths and http/https URLs are supported. If empty, the 'stage1.aci' in the same directory as '--rkt-path' will be used.")
fs.MarkDeprecated("rkt-stage1-image", "Will be removed in a future version. The default stage1 image will be specified by the rkt configurations, see https://github.com/coreos/rkt/blob/master/Documentation/configuration.md for more details.") fs.MarkDeprecated("rkt-stage1-image", "Will be removed in a future version. The default stage1 image will be specified by the rkt configurations, see https://github.com/coreos/rkt/blob/master/Documentation/configuration.md for more details.")
......
...@@ -118,7 +118,7 @@ func UnsecuredKubeletDeps(s *options.KubeletServer) (*kubelet.KubeletDeps, error ...@@ -118,7 +118,7 @@ func UnsecuredKubeletDeps(s *options.KubeletServer) (*kubelet.KubeletDeps, error
return nil, err return nil, err
} }
mounter := mount.NewCustomMounter(s.ExperimentalMounterPath, s.ExperimentalMounterRootfsPath) mounter := mount.New(s.ExperimentalMounterPath)
var writer kubeio.Writer = &kubeio.StdWriter{} var writer kubeio.Writer = &kubeio.StdWriter{}
if s.Containerized { if s.Containerized {
glog.V(2).Info("Running kubelet in containerized mode (experimental)") glog.V(2).Info("Running kubelet in containerized mode (experimental)")
......
...@@ -189,7 +189,6 @@ experimental-allowed-unsafe-sysctls ...@@ -189,7 +189,6 @@ experimental-allowed-unsafe-sysctls
experimental-bootstrap-kubeconfig experimental-bootstrap-kubeconfig
experimental-keystone-url experimental-keystone-url
experimental-mounter-path experimental-mounter-path
experimental-mounter-rootfs-path
experimental-nvidia-gpus experimental-nvidia-gpus
experimental-prefix experimental-prefix
experimental-runtime-integration-type experimental-runtime-integration-type
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -319,8 +319,6 @@ type KubeletConfiguration struct { ...@@ -319,8 +319,6 @@ type KubeletConfiguration struct {
RktPath string `json:"rktPath,omitempty"` RktPath string `json:"rktPath,omitempty"`
// experimentalMounterPath is the path of mounter binary. Leave empty to use the default mount path // experimentalMounterPath is the path of mounter binary. Leave empty to use the default mount path
ExperimentalMounterPath string `json:"experimentalMounterPath,omitempty"` ExperimentalMounterPath string `json:"experimentalMounterPath,omitempty"`
// experimentalMounterRootfsPath is the absolute path to root filesystem for the mounter binary.
ExperimentalMounterRootfsPath string `json:"experimentalMounterRootfsPath,omitempty"`
// rktApiEndpoint is the endpoint of the rkt API service to communicate with. // rktApiEndpoint is the endpoint of the rkt API service to communicate with.
// +optional // +optional
RktAPIEndpoint string `json:"rktAPIEndpoint,omitempty"` RktAPIEndpoint string `json:"rktAPIEndpoint,omitempty"`
......
...@@ -367,8 +367,6 @@ type KubeletConfiguration struct { ...@@ -367,8 +367,6 @@ type KubeletConfiguration struct {
// experimentalMounterPath is the path to mounter binary. If not set, kubelet will attempt to use mount // experimentalMounterPath is the path to mounter binary. If not set, kubelet will attempt to use mount
// binary that is available via $PATH, // binary that is available via $PATH,
ExperimentalMounterPath string `json:"experimentalMounterPath,omitempty"` ExperimentalMounterPath string `json:"experimentalMounterPath,omitempty"`
// experimentalMounterRootfsPath is the absolute path to root filesystem for the mounter binary.
ExperimentalMounterRootfsPath string `json:"experimentalMounterRootfsPath,omitempty"`
// rktApiEndpoint is the endpoint of the rkt API service to communicate with. // rktApiEndpoint is the endpoint of the rkt API service to communicate with.
RktAPIEndpoint string `json:"rktAPIEndpoint"` RktAPIEndpoint string `json:"rktAPIEndpoint"`
// rktStage1Image is the image to use as stage1. Local paths and // rktStage1Image is the image to use as stage1. Local paths and
......
...@@ -336,7 +336,6 @@ func autoConvert_v1alpha1_KubeletConfiguration_To_componentconfig_KubeletConfigu ...@@ -336,7 +336,6 @@ func autoConvert_v1alpha1_KubeletConfiguration_To_componentconfig_KubeletConfigu
out.RuntimeRequestTimeout = in.RuntimeRequestTimeout out.RuntimeRequestTimeout = in.RuntimeRequestTimeout
out.RktPath = in.RktPath out.RktPath = in.RktPath
out.ExperimentalMounterPath = in.ExperimentalMounterPath out.ExperimentalMounterPath = in.ExperimentalMounterPath
out.ExperimentalMounterRootfsPath = in.ExperimentalMounterRootfsPath
out.RktAPIEndpoint = in.RktAPIEndpoint out.RktAPIEndpoint = in.RktAPIEndpoint
out.RktStage1Image = in.RktStage1Image out.RktStage1Image = in.RktStage1Image
if err := api.Convert_Pointer_string_To_string(&in.LockFilePath, &out.LockFilePath, s); err != nil { if err := api.Convert_Pointer_string_To_string(&in.LockFilePath, &out.LockFilePath, s); err != nil {
...@@ -504,7 +503,6 @@ func autoConvert_componentconfig_KubeletConfiguration_To_v1alpha1_KubeletConfigu ...@@ -504,7 +503,6 @@ func autoConvert_componentconfig_KubeletConfiguration_To_v1alpha1_KubeletConfigu
out.RuntimeRequestTimeout = in.RuntimeRequestTimeout out.RuntimeRequestTimeout = in.RuntimeRequestTimeout
out.RktPath = in.RktPath out.RktPath = in.RktPath
out.ExperimentalMounterPath = in.ExperimentalMounterPath out.ExperimentalMounterPath = in.ExperimentalMounterPath
out.ExperimentalMounterRootfsPath = in.ExperimentalMounterRootfsPath
out.RktAPIEndpoint = in.RktAPIEndpoint out.RktAPIEndpoint = in.RktAPIEndpoint
out.RktStage1Image = in.RktStage1Image out.RktStage1Image = in.RktStage1Image
if err := api.Convert_string_To_Pointer_string(&in.LockFilePath, &out.LockFilePath, s); err != nil { if err := api.Convert_string_To_Pointer_string(&in.LockFilePath, &out.LockFilePath, s); err != nil {
......
...@@ -314,7 +314,6 @@ func DeepCopy_v1alpha1_KubeletConfiguration(in interface{}, out interface{}, c * ...@@ -314,7 +314,6 @@ func DeepCopy_v1alpha1_KubeletConfiguration(in interface{}, out interface{}, c *
out.RuntimeRequestTimeout = in.RuntimeRequestTimeout out.RuntimeRequestTimeout = in.RuntimeRequestTimeout
out.RktPath = in.RktPath out.RktPath = in.RktPath
out.ExperimentalMounterPath = in.ExperimentalMounterPath out.ExperimentalMounterPath = in.ExperimentalMounterPath
out.ExperimentalMounterRootfsPath = in.ExperimentalMounterRootfsPath
out.RktAPIEndpoint = in.RktAPIEndpoint out.RktAPIEndpoint = in.RktAPIEndpoint
out.RktStage1Image = in.RktStage1Image out.RktStage1Image = in.RktStage1Image
if in.LockFilePath != nil { if in.LockFilePath != nil {
......
...@@ -316,7 +316,6 @@ func DeepCopy_componentconfig_KubeletConfiguration(in interface{}, out interface ...@@ -316,7 +316,6 @@ func DeepCopy_componentconfig_KubeletConfiguration(in interface{}, out interface
out.RuntimeRequestTimeout = in.RuntimeRequestTimeout out.RuntimeRequestTimeout = in.RuntimeRequestTimeout
out.RktPath = in.RktPath out.RktPath = in.RktPath
out.ExperimentalMounterPath = in.ExperimentalMounterPath out.ExperimentalMounterPath = in.ExperimentalMounterPath
out.ExperimentalMounterRootfsPath = in.ExperimentalMounterRootfsPath
out.RktAPIEndpoint = in.RktAPIEndpoint out.RktAPIEndpoint = in.RktAPIEndpoint
out.RktStage1Image = in.RktStage1Image out.RktStage1Image = in.RktStage1Image
out.LockFilePath = in.LockFilePath out.LockFilePath = in.LockFilePath
......
...@@ -95,7 +95,7 @@ func getMetadataFromConfigDrive() (*Metadata, error) { ...@@ -95,7 +95,7 @@ func getMetadataFromConfigDrive() (*Metadata, error) {
glog.V(4).Infof("Attempting to mount configdrive %s on %s", dev, mntdir) glog.V(4).Infof("Attempting to mount configdrive %s on %s", dev, mntdir)
mounter := mount.New() mounter := mount.New("" /* default mount path */)
err = mounter.Mount(dev, mntdir, "iso9660", []string{"ro"}) err = mounter.Mount(dev, mntdir, "iso9660", []string{"ro"})
if err != nil { if err != nil {
err = mounter.Mount(dev, mntdir, "vfat", []string{"ro"}) err = mounter.Mount(dev, mntdir, "vfat", []string{"ro"})
......
...@@ -2657,13 +2657,6 @@ var OpenAPIDefinitions *common.OpenAPIDefinitions = &common.OpenAPIDefinitions{ ...@@ -2657,13 +2657,6 @@ var OpenAPIDefinitions *common.OpenAPIDefinitions = &common.OpenAPIDefinitions{
Format: "", Format: "",
}, },
}, },
"experimentalMounterRootfsPath": {
SchemaProps: spec.SchemaProps{
Description: "experimentalMounterRootfsPath is the absolute path to root filesystem for the mounter binary.",
Type: []string{"string"},
Format: "",
},
},
"rktAPIEndpoint": { "rktAPIEndpoint": {
SchemaProps: spec.SchemaProps{ SchemaProps: spec.SchemaProps{
Description: "rktApiEndpoint is the endpoint of the rkt API service to communicate with.", Description: "rktApiEndpoint is the endpoint of the rkt API service to communicate with.",
...@@ -2985,7 +2978,7 @@ var OpenAPIDefinitions *common.OpenAPIDefinitions = &common.OpenAPIDefinitions{ ...@@ -2985,7 +2978,7 @@ var OpenAPIDefinitions *common.OpenAPIDefinitions = &common.OpenAPIDefinitions{
}, },
}, },
}, },
Required: []string{"TypeMeta", "podManifestPath", "syncFrequency", "fileCheckFrequency", "httpCheckFrequency", "manifestURL", "manifestURLHeader", "enableServer", "address", "port", "readOnlyPort", "tlsCertFile", "tlsPrivateKeyFile", "certDirectory", "authentication", "authorization", "hostnameOverride", "podInfraContainerImage", "dockerEndpoint", "rootDirectory", "seccompProfileRoot", "allowPrivileged", "hostNetworkSources", "hostPIDSources", "hostIPCSources", "registryPullQPS", "registryBurst", "eventRecordQPS", "eventBurst", "enableDebuggingHandlers", "minimumGCAge", "maxPerPodContainerCount", "maxContainerCount", "cAdvisorPort", "healthzPort", "healthzBindAddress", "oomScoreAdj", "registerNode", "clusterDomain", "masterServiceNamespace", "clusterDNS", "streamingConnectionIdleTimeout", "nodeStatusUpdateFrequency", "imageMinimumGCAge", "imageGCHighThresholdPercent", "imageGCLowThresholdPercent", "lowDiskSpaceThresholdMB", "volumeStatsAggPeriod", "networkPluginName", "networkPluginMTU", "networkPluginDir", "cniConfDir", "cniBinDir", "volumePluginDir", "containerRuntime", "remoteRuntimeEndpoint", "remoteImageEndpoint", "experimentalMounterPath", "experimentalMounterRootfsPath", "lockFilePath", "exitOnLockContention", "hairpinMode", "babysitDaemons", "maxPods", "nvidiaGPUs", "dockerExecHandlerName", "podCIDR", "resolvConf", "cpuCFSQuota", "containerized", "maxOpenFiles", "reconcileCIDR", "registerSchedulable", "contentType", "kubeAPIQPS", "kubeAPIBurst", "serializeImagePulls", "nodeLabels", "nonMasqueradeCIDR", "enableCustomMetrics", "podsPerCore", "enableControllerAttachDetach", "systemReserved", "kubeReserved", "protectKernelDefaults", "makeIPTablesUtilChains", "iptablesMasqueradeBit", "iptablesDropBit", "featureGates"}, Required: []string{"TypeMeta", "podManifestPath", "syncFrequency", "fileCheckFrequency", "httpCheckFrequency", "manifestURL", "manifestURLHeader", "enableServer", "address", "port", "readOnlyPort", "tlsCertFile", "tlsPrivateKeyFile", "certDirectory", "authentication", "authorization", "hostnameOverride", "podInfraContainerImage", "dockerEndpoint", "rootDirectory", "seccompProfileRoot", "allowPrivileged", "hostNetworkSources", "hostPIDSources", "hostIPCSources", "registryPullQPS", "registryBurst", "eventRecordQPS", "eventBurst", "enableDebuggingHandlers", "minimumGCAge", "maxPerPodContainerCount", "maxContainerCount", "cAdvisorPort", "healthzPort", "healthzBindAddress", "oomScoreAdj", "registerNode", "clusterDomain", "masterServiceNamespace", "clusterDNS", "streamingConnectionIdleTimeout", "nodeStatusUpdateFrequency", "imageMinimumGCAge", "imageGCHighThresholdPercent", "imageGCLowThresholdPercent", "lowDiskSpaceThresholdMB", "volumeStatsAggPeriod", "networkPluginName", "networkPluginMTU", "networkPluginDir", "cniConfDir", "cniBinDir", "volumePluginDir", "containerRuntime", "remoteRuntimeEndpoint", "remoteImageEndpoint", "experimentalMounterPath", "lockFilePath", "exitOnLockContention", "hairpinMode", "babysitDaemons", "maxPods", "nvidiaGPUs", "dockerExecHandlerName", "podCIDR", "resolvConf", "cpuCFSQuota", "containerized", "maxOpenFiles", "reconcileCIDR", "registerSchedulable", "contentType", "kubeAPIQPS", "kubeAPIBurst", "serializeImagePulls", "nodeLabels", "nonMasqueradeCIDR", "enableCustomMetrics", "podsPerCore", "enableControllerAttachDetach", "systemReserved", "kubeReserved", "protectKernelDefaults", "makeIPTablesUtilChains", "iptablesMasqueradeBit", "iptablesDropBit", "featureGates"},
}, },
}, },
Dependencies: []string{ Dependencies: []string{
...@@ -14408,13 +14401,6 @@ var OpenAPIDefinitions *common.OpenAPIDefinitions = &common.OpenAPIDefinitions{ ...@@ -14408,13 +14401,6 @@ var OpenAPIDefinitions *common.OpenAPIDefinitions = &common.OpenAPIDefinitions{
Format: "", Format: "",
}, },
}, },
"experimentalMounterRootfsPath": {
SchemaProps: spec.SchemaProps{
Description: "experimentalMounterRootfsPath is the absolute path to root filesystem for the mounter binary.",
Type: []string{"string"},
Format: "",
},
},
"rktAPIEndpoint": { "rktAPIEndpoint": {
SchemaProps: spec.SchemaProps{ SchemaProps: spec.SchemaProps{
Description: "rktApiEndpoint is the endpoint of the rkt API service to communicate with.", Description: "rktApiEndpoint is the endpoint of the rkt API service to communicate with.",
...@@ -14736,7 +14722,7 @@ var OpenAPIDefinitions *common.OpenAPIDefinitions = &common.OpenAPIDefinitions{ ...@@ -14736,7 +14722,7 @@ var OpenAPIDefinitions *common.OpenAPIDefinitions = &common.OpenAPIDefinitions{
}, },
}, },
}, },
Required: []string{"TypeMeta", "podManifestPath", "syncFrequency", "fileCheckFrequency", "httpCheckFrequency", "manifestURL", "manifestURLHeader", "enableServer", "address", "port", "readOnlyPort", "tlsCertFile", "tlsPrivateKeyFile", "certDirectory", "authentication", "authorization", "hostnameOverride", "podInfraContainerImage", "dockerEndpoint", "rootDirectory", "seccompProfileRoot", "allowPrivileged", "hostNetworkSources", "hostPIDSources", "hostIPCSources", "registryPullQPS", "registryBurst", "eventRecordQPS", "eventBurst", "enableDebuggingHandlers", "minimumGCAge", "maxPerPodContainerCount", "maxContainerCount", "cAdvisorPort", "healthzPort", "healthzBindAddress", "oomScoreAdj", "registerNode", "clusterDomain", "masterServiceNamespace", "clusterDNS", "streamingConnectionIdleTimeout", "nodeStatusUpdateFrequency", "imageMinimumGCAge", "imageGCHighThresholdPercent", "imageGCLowThresholdPercent", "lowDiskSpaceThresholdMB", "volumeStatsAggPeriod", "networkPluginName", "networkPluginDir", "cniConfDir", "cniBinDir", "networkPluginMTU", "volumePluginDir", "cloudProvider", "cloudConfigFile", "kubeletCgroups", "runtimeCgroups", "systemCgroups", "cgroupRoot", "containerRuntime", "remoteRuntimeEndpoint", "remoteImageEndpoint", "runtimeRequestTimeout", "rktPath", "experimentalMounterPath", "experimentalMounterRootfsPath", "rktAPIEndpoint", "rktStage1Image", "lockFilePath", "exitOnLockContention", "hairpinMode", "babysitDaemons", "maxPods", "nvidiaGPUs", "dockerExecHandlerName", "podCIDR", "resolvConf", "cpuCFSQuota", "containerized", "maxOpenFiles", "reconcileCIDR", "registerSchedulable", "contentType", "kubeAPIQPS", "kubeAPIBurst", "serializeImagePulls", "outOfDiskTransitionFrequency", "nodeIP", "nodeLabels", "nonMasqueradeCIDR", "enableCustomMetrics", "evictionHard", "evictionSoft", "evictionSoftGracePeriod", "evictionPressureTransitionPeriod", "evictionMaxPodGracePeriod", "evictionMinimumReclaim", "podsPerCore", "enableControllerAttachDetach", "systemReserved", "kubeReserved", "protectKernelDefaults", "makeIPTablesUtilChains", "iptablesMasqueradeBit", "iptablesDropBit", "featureGates"}, Required: []string{"TypeMeta", "podManifestPath", "syncFrequency", "fileCheckFrequency", "httpCheckFrequency", "manifestURL", "manifestURLHeader", "enableServer", "address", "port", "readOnlyPort", "tlsCertFile", "tlsPrivateKeyFile", "certDirectory", "authentication", "authorization", "hostnameOverride", "podInfraContainerImage", "dockerEndpoint", "rootDirectory", "seccompProfileRoot", "allowPrivileged", "hostNetworkSources", "hostPIDSources", "hostIPCSources", "registryPullQPS", "registryBurst", "eventRecordQPS", "eventBurst", "enableDebuggingHandlers", "minimumGCAge", "maxPerPodContainerCount", "maxContainerCount", "cAdvisorPort", "healthzPort", "healthzBindAddress", "oomScoreAdj", "registerNode", "clusterDomain", "masterServiceNamespace", "clusterDNS", "streamingConnectionIdleTimeout", "nodeStatusUpdateFrequency", "imageMinimumGCAge", "imageGCHighThresholdPercent", "imageGCLowThresholdPercent", "lowDiskSpaceThresholdMB", "volumeStatsAggPeriod", "networkPluginName", "networkPluginDir", "cniConfDir", "cniBinDir", "networkPluginMTU", "volumePluginDir", "cloudProvider", "cloudConfigFile", "kubeletCgroups", "runtimeCgroups", "systemCgroups", "cgroupRoot", "containerRuntime", "remoteRuntimeEndpoint", "remoteImageEndpoint", "runtimeRequestTimeout", "rktPath", "experimentalMounterPath", "rktAPIEndpoint", "rktStage1Image", "lockFilePath", "exitOnLockContention", "hairpinMode", "babysitDaemons", "maxPods", "nvidiaGPUs", "dockerExecHandlerName", "podCIDR", "resolvConf", "cpuCFSQuota", "containerized", "maxOpenFiles", "reconcileCIDR", "registerSchedulable", "contentType", "kubeAPIQPS", "kubeAPIBurst", "serializeImagePulls", "outOfDiskTransitionFrequency", "nodeIP", "nodeLabels", "nonMasqueradeCIDR", "enableCustomMetrics", "evictionHard", "evictionSoft", "evictionSoftGracePeriod", "evictionPressureTransitionPeriod", "evictionMaxPodGracePeriod", "evictionMinimumReclaim", "podsPerCore", "enableControllerAttachDetach", "systemReserved", "kubeReserved", "protectKernelDefaults", "makeIPTablesUtilChains", "iptablesMasqueradeBit", "iptablesDropBit", "featureGates"},
}, },
}, },
Dependencies: []string{ Dependencies: []string{
......
...@@ -72,7 +72,7 @@ func NewHollowKubelet( ...@@ -72,7 +72,7 @@ func NewHollowKubelet(
TLSOptions: nil, TLSOptions: nil,
OOMAdjuster: oom.NewFakeOOMAdjuster(), OOMAdjuster: oom.NewFakeOOMAdjuster(),
Writer: &kubeio.StdWriter{}, Writer: &kubeio.StdWriter{},
Mounter: mount.New(), Mounter: mount.New("" /* default mount path */),
} }
return &HollowKubelet{ return &HollowKubelet{
......
...@@ -22,6 +22,7 @@ go_library( ...@@ -22,6 +22,7 @@ go_library(
tags = ["automanaged"], tags = ["automanaged"],
deps = [ deps = [
"//pkg/util/exec:go_default_library", "//pkg/util/exec:go_default_library",
"//pkg/util/sets:go_default_library",
"//vendor:github.com/golang/glog", "//vendor:github.com/golang/glog",
], ],
) )
......
...@@ -30,7 +30,7 @@ import ( ...@@ -30,7 +30,7 @@ import (
const ( const (
// Default mount command if mounter path is not specified // Default mount command if mounter path is not specified
mount = "mount" defaultMountCommand = "mount"
) )
type Interface interface { type Interface interface {
...@@ -94,25 +94,16 @@ func (mounter *SafeFormatAndMount) FormatAndMount(source string, target string, ...@@ -94,25 +94,16 @@ func (mounter *SafeFormatAndMount) FormatAndMount(source string, target string,
} }
// New returns a mount.Interface for the current system. // New returns a mount.Interface for the current system.
func New() Interface {
return &Mounter{}
}
// NewCustomMounter returns a mount.Interface for the current system.
// It provides options to override the default mounter behavior. // It provides options to override the default mounter behavior.
// mounterPath allows using an alternative to `/bin/mount` for mounting. // mounterPath allows using an alternative to `/bin/mount` for mounting.
// mounterRootfsPath allows specifying a custom root filesystem path for non default `mounterPath`. func New(mounterPath string) Interface {
func NewCustomMounter(mounterPath, mounterRootfsPath string) Interface {
// If mounter-path flag is not set, use default mount path // If mounter-path flag is not set, use default mount path
if mounterPath == "" { if mounterPath == "" {
mounterPath = mount mounterPath = defaultMountCommand
}
if mounterRootfsPath == "" {
mounterRootfsPath = "/"
} }
return &Mounter{ return &Mounter{
mounterPath: mounterPath, mounterPath: mounterPath,
mounterRootfsPath: mounterRootfsPath,
} }
} }
......
...@@ -25,13 +25,13 @@ import ( ...@@ -25,13 +25,13 @@ import (
"io" "io"
"os" "os"
"os/exec" "os/exec"
"path"
"strconv" "strconv"
"strings" "strings"
"syscall" "syscall"
"github.com/golang/glog" "github.com/golang/glog"
utilExec "k8s.io/kubernetes/pkg/util/exec" utilExec "k8s.io/kubernetes/pkg/util/exec"
"k8s.io/kubernetes/pkg/util/sets"
) )
const ( const (
...@@ -54,8 +54,7 @@ const ( ...@@ -54,8 +54,7 @@ const (
// for the linux platform. This implementation assumes that the // for the linux platform. This implementation assumes that the
// kubelet is running in the host's root mount namespace. // kubelet is running in the host's root mount namespace.
type Mounter struct { type Mounter struct {
mounterPath string mounterPath string
mounterRootfsPath string
} }
// Mount mounts source to target as fstype with given options. 'source' and 'fstype' must // Mount mounts source to target as fstype with given options. 'source' and 'fstype' must
...@@ -63,18 +62,24 @@ type Mounter struct { ...@@ -63,18 +62,24 @@ type Mounter struct {
// type, where kernel handles fs type for you. The mount 'options' is a list of options, // type, where kernel handles fs type for you. The mount 'options' is a list of options,
// currently come from mount(8), e.g. "ro", "remount", "bind", etc. If no more option is // currently come from mount(8), e.g. "ro", "remount", "bind", etc. If no more option is
// required, call Mount with an empty string list or nil. // required, call Mount with an empty string list or nil.
// Update source path to include a root filesystem override to make a containerized mounter (specified via `mounterPath`) work.
func (mounter *Mounter) Mount(source string, target string, fstype string, options []string) error { func (mounter *Mounter) Mount(source string, target string, fstype string, options []string) error {
// Path to mounter binary. Set to mount accessible via $PATH by default.
// All Linux distros are expected to be shipped with a mount utility that an support bind mounts.
mounterPath := defaultMountCommand
bind, bindRemountOpts := isBind(options) bind, bindRemountOpts := isBind(options)
if bind { if bind {
err := doMount(mounter.mounterPath, path.Join(mounter.mounterRootfsPath, source), path.Join(mounter.mounterRootfsPath, target), fstype, []string{"bind"}) err := doMount(mounterPath, source, target, fstype, []string{"bind"})
if err != nil { if err != nil {
return err return err
} }
return doMount(mounter.mounterPath, path.Join(mounter.mounterRootfsPath, source), path.Join(mounter.mounterRootfsPath, target), fstype, bindRemountOpts) return doMount(mounterPath, source, target, fstype, bindRemountOpts)
} else {
return doMount(mounter.mounterPath, source, path.Join(mounter.mounterRootfsPath, target), fstype, options)
} }
// These filesystem types are expected to be supported by the mount utility on the host across all Linux distros.
var defaultMounterFsTypes = sets.NewString("tmpfs", "ext4", "ext3", "ext2")
if !defaultMounterFsTypes.Has(fstype) {
mounterPath = mounter.mounterPath
}
return doMount(mounterPath, source, target, fstype, options)
} }
// isBind detects whether a bind mount is being requested and makes the remount options to // isBind detects whether a bind mount is being requested and makes the remount options to
......
...@@ -19,8 +19,7 @@ limitations under the License. ...@@ -19,8 +19,7 @@ limitations under the License.
package mount package mount
type Mounter struct { type Mounter struct {
mounterPath string mounterPath string
mounterRootfsPath string
} }
func (mounter *Mounter) Mount(source string, target string, fstype string, options []string) error { func (mounter *Mounter) Mount(source string, target string, fstype string, options []string) error {
......
...@@ -121,8 +121,6 @@ type NodeTestContextType struct { ...@@ -121,8 +121,6 @@ type NodeTestContextType struct {
ContainerRuntimeEndpoint string ContainerRuntimeEndpoint string
// MounterPath is the path to the program to run to perform a mount // MounterPath is the path to the program to run to perform a mount
MounterPath string MounterPath string
// MounterRootfsPath is the path to the root filesystem for the program used to perform a mount in kubelet
MounterRootfsPath string
} }
type CloudConfig struct { type CloudConfig struct {
...@@ -220,7 +218,6 @@ func RegisterNodeFlags() { ...@@ -220,7 +218,6 @@ func RegisterNodeFlags() {
flag.StringVar(&TestContext.RuntimeIntegrationType, "runtime-integration-type", "", "Choose the integration path for the container runtime, mainly used for CRI validation.") flag.StringVar(&TestContext.RuntimeIntegrationType, "runtime-integration-type", "", "Choose the integration path for the container runtime, mainly used for CRI validation.")
flag.StringVar(&TestContext.ContainerRuntimeEndpoint, "container-runtime-endpoint", "", "The endpoint of remote container runtime grpc server, mainly used for Remote CRI validation.") flag.StringVar(&TestContext.ContainerRuntimeEndpoint, "container-runtime-endpoint", "", "The endpoint of remote container runtime grpc server, mainly used for Remote CRI validation.")
flag.StringVar(&TestContext.MounterPath, "experimental-mounter-path", "", "Path of mounter binary. Leave empty to use the default mount.") flag.StringVar(&TestContext.MounterPath, "experimental-mounter-path", "", "Path of mounter binary. Leave empty to use the default mount.")
flag.StringVar(&TestContext.MounterRootfsPath, "experimental-mounter-rootfs-path", "", "Absolute path to root filesystem for the mounter binary.")
} }
// overwriteFlagsWithViperConfig finds and writes values to flags using viper as input. // overwriteFlagsWithViperConfig finds and writes values to flags using viper as input.
......
...@@ -45,8 +45,6 @@ const ( ...@@ -45,8 +45,6 @@ const (
archiveName = "e2e_node_test.tar.gz" archiveName = "e2e_node_test.tar.gz"
CNIRelease = "07a8a28637e97b22eb8dfe710eeae1344f69d16e" CNIRelease = "07a8a28637e97b22eb8dfe710eeae1344f69d16e"
CNIDirectory = "cni" CNIDirectory = "cni"
// Note: This path needs to be in sync with the "target" path for `/` in cluster/gce/gci/mounter/mounter
mounterRootfsPath string = "/media/root"
) )
var CNIURL = fmt.Sprintf("https://storage.googleapis.com/kubernetes-release/network-plugins/cni-%s.tar.gz", CNIRelease) var CNIURL = fmt.Sprintf("https://storage.googleapis.com/kubernetes-release/network-plugins/cni-%s.tar.gz", CNIRelease)
...@@ -265,6 +263,7 @@ func RunRemote(archive string, host string, cleanup bool, junitFilePrefix string ...@@ -265,6 +263,7 @@ func RunRemote(archive string, host string, cleanup bool, junitFilePrefix string
return "", false, fmt.Errorf("Issue detecting node's OS via node's /etc/os-release. Err: %v, Output:\n%s", err, output) return "", false, fmt.Errorf("Issue detecting node's OS via node's /etc/os-release. Err: %v, Output:\n%s", err, output)
} }
if strings.Contains(output, "ID=gci") { if strings.Contains(output, "ID=gci") {
glog.Infof("GCI node and GCI mounter both detected, modifying --experimental-mounter-path accordingly")
// Note this implicitly requires the script to be where we expect in the tarball, so if that location changes the error // Note this implicitly requires the script to be where we expect in the tarball, so if that location changes the error
// here will tell us to update the remote test runner. // here will tell us to update the remote test runner.
mounterPath := filepath.Join(tmp, "cluster/gce/gci/mounter/mounter") mounterPath := filepath.Join(tmp, "cluster/gce/gci/mounter/mounter")
...@@ -274,9 +273,7 @@ func RunRemote(archive string, host string, cleanup bool, junitFilePrefix string ...@@ -274,9 +273,7 @@ func RunRemote(archive string, host string, cleanup bool, junitFilePrefix string
return "", false, err return "", false, err
} }
// Insert args at beginning of testArgs, so any values from command line take precedence // Insert args at beginning of testArgs, so any values from command line take precedence
testArgs = fmt.Sprintf("--experimental-mounter-rootfs-path=%s ", mounterRootfsPath) + testArgs
testArgs = fmt.Sprintf("--experimental-mounter-path=%s ", mounterPath) + testArgs testArgs = fmt.Sprintf("--experimental-mounter-path=%s ", mounterPath) + testArgs
glog.Infof("GCI node and GCI mounter both detected, setting --experimental-mounter-path=%q and --experimental-mounter-rootfs-path=%q accordingly", mounterPath, mounterRootfsPath)
} }
// Run the tests // Run the tests
......
...@@ -212,7 +212,6 @@ func (e *E2EServices) startKubelet() (*server, error) { ...@@ -212,7 +212,6 @@ func (e *E2EServices) startKubelet() (*server, error) {
"--feature-gates", framework.TestContext.FeatureGates, "--feature-gates", framework.TestContext.FeatureGates,
"--v", LOG_VERBOSITY_LEVEL, "--logtostderr", "--v", LOG_VERBOSITY_LEVEL, "--logtostderr",
"--experimental-mounter-path", framework.TestContext.MounterPath, "--experimental-mounter-path", framework.TestContext.MounterPath,
"--experimental-mounter-rootfs-path", framework.TestContext.MounterRootfsPath,
) )
if framework.TestContext.RuntimeIntegrationType != "" { if framework.TestContext.RuntimeIntegrationType != "" {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment