Merge pull request #32903 from yujuhong/enable_docker_shim

Automatic merge from submit-queue

kubelet: Add a hidden flag to enable docker CRI integration for testing
This commit is contained in:
Kubernetes Submit Queue 2016-09-20 11:19:26 -07:00 committed by GitHub
commit 650715d231
12 changed files with 2575 additions and 2469 deletions

View File

@ -221,4 +221,8 @@ func (s *KubeletServer) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&s.EvictionMinimumReclaim, "eviction-minimum-reclaim", s.EvictionMinimumReclaim, "A set of minimum reclaims (e.g. imagefs.available=2Gi) that describes the minimum amount of resource the kubelet will reclaim when performing a pod eviction if that resource is under pressure.") fs.StringVar(&s.EvictionMinimumReclaim, "eviction-minimum-reclaim", s.EvictionMinimumReclaim, "A set of minimum reclaims (e.g. imagefs.available=2Gi) that describes the minimum amount of resource the kubelet will reclaim when performing a pod eviction if that resource is under pressure.")
fs.Int32Var(&s.PodsPerCore, "pods-per-core", s.PodsPerCore, "Number of Pods per core that can run on this Kubelet. The total number of Pods on this Kubelet cannot exceed max-pods, so max-pods will be used if this calculation results in a larger number of Pods allowed on the Kubelet. A value of 0 disables this limit.") fs.Int32Var(&s.PodsPerCore, "pods-per-core", s.PodsPerCore, "Number of Pods per core that can run on this Kubelet. The total number of Pods on this Kubelet cannot exceed max-pods, so max-pods will be used if this calculation results in a larger number of Pods allowed on the Kubelet. A value of 0 disables this limit.")
fs.BoolVar(&s.ProtectKernelDefaults, "protect-kernel-defaults", s.ProtectKernelDefaults, "Default kubelet behaviour for kernel tuning. If set, kubelet errors if any of kernel tunables is different than kubelet defaults.") fs.BoolVar(&s.ProtectKernelDefaults, "protect-kernel-defaults", s.ProtectKernelDefaults, "Default kubelet behaviour for kernel tuning. If set, kubelet errors if any of kernel tunables is different than kubelet defaults.")
// Hidden flags for experimental features that are still under development.
fs.StringVar(&s.ExperimentalRuntimeIntegrationType, "experimental-runtime-integration-type", s.ExperimentalRuntimeIntegrationType, "Choose the integration path for the container runtime (specified via --container-runtime). Currently, this supports only Docker. If set to \"cri\", Kubelet will use interact with docker through the new Container Runtime Interface.")
fs.MarkHidden("experimental-runtime-integration-type")
} }

View File

@ -175,6 +175,7 @@ experimental-flannel-overlay
experimental-keystone-url experimental-keystone-url
experimental-nvidia-gpus experimental-nvidia-gpus
experimental-prefix experimental-prefix
experimental-runtime-integration-type
external-hostname external-hostname
external-ip external-ip
extra-peer-dirs extra-peer-dirs

File diff suppressed because it is too large Load Diff

View File

@ -427,6 +427,9 @@ type KubeletConfiguration struct {
IPTablesDropBit int32 `json:"iptablesDropBit"` IPTablesDropBit int32 `json:"iptablesDropBit"`
// Whitelist of unsafe sysctls or sysctl patterns (ending in *). // Whitelist of unsafe sysctls or sysctl patterns (ending in *).
AllowedUnsafeSysctls []string `json:"experimentalAllowedUnsafeSysctls,omitempty"` AllowedUnsafeSysctls []string `json:"experimentalAllowedUnsafeSysctls,omitempty"`
// How to integrate with runtime. If set to cri, kubelet will switch to
// using the new Container Runtine Interface.
ExperimentalRuntimeIntegrationType string `json:"experimentalRuntimeIntegrationType,omitempty"`
} }
type KubeSchedulerConfiguration struct { type KubeSchedulerConfiguration struct {

View File

@ -483,4 +483,7 @@ type KubeletConfiguration struct {
// Whitelist of unsafe sysctls or sysctl patterns (ending in *). Use these at your own risk. // Whitelist of unsafe sysctls or sysctl patterns (ending in *). Use these at your own risk.
// Resource isolation might be lacking and pod might influence each other on the same node. // Resource isolation might be lacking and pod might influence each other on the same node.
AllowedUnsafeSysctls []string `json:"allowedUnsafeSysctls,omitempty"` AllowedUnsafeSysctls []string `json:"allowedUnsafeSysctls,omitempty"`
// How to integrate with runtime. If set to CRI, kubelet will switch to
// using the new Container Runtine Interface.
ExperimentalRuntimeIntegrationType string `json:"experimentalRuntimeIntegrationType,omitempty"`
} }

View File

@ -335,6 +335,7 @@ func autoConvert_v1alpha1_KubeletConfiguration_To_componentconfig_KubeletConfigu
return err return err
} }
out.AllowedUnsafeSysctls = in.AllowedUnsafeSysctls out.AllowedUnsafeSysctls = in.AllowedUnsafeSysctls
out.ExperimentalRuntimeIntegrationType = in.ExperimentalRuntimeIntegrationType
return nil return nil
} }
@ -515,6 +516,7 @@ func autoConvert_componentconfig_KubeletConfiguration_To_v1alpha1_KubeletConfigu
return err return err
} }
out.AllowedUnsafeSysctls = in.AllowedUnsafeSysctls out.AllowedUnsafeSysctls = in.AllowedUnsafeSysctls
out.ExperimentalRuntimeIntegrationType = in.ExperimentalRuntimeIntegrationType
return nil return nil
} }

View File

@ -411,6 +411,7 @@ func DeepCopy_v1alpha1_KubeletConfiguration(in interface{}, out interface{}, c *
} else { } else {
out.AllowedUnsafeSysctls = nil out.AllowedUnsafeSysctls = nil
} }
out.ExperimentalRuntimeIntegrationType = in.ExperimentalRuntimeIntegrationType
return nil return nil
} }
} }

View File

@ -347,6 +347,7 @@ func DeepCopy_componentconfig_KubeletConfiguration(in interface{}, out interface
} else { } else {
out.AllowedUnsafeSysctls = nil out.AllowedUnsafeSysctls = nil
} }
out.ExperimentalRuntimeIntegrationType = in.ExperimentalRuntimeIntegrationType
return nil return nil
} }
} }

View File

@ -2875,8 +2875,15 @@ func (_ openAPI) OpenAPIDefinitions() *common.OpenAPIDefinitions {
}, },
}, },
}, },
"ExperimentalRuntimeIntegrationType": {
SchemaProps: spec.SchemaProps{
Description: "How to integrate with runtime. If set to CRI, kubelet will switch to using the new Container Runtine Interface.",
Type: []string{"string"},
Format: "",
},
},
}, },
Required: []string{"TypeMeta", "podManifestPath", "syncFrequency", "fileCheckFrequency", "httpCheckFrequency", "manifestURL", "manifestURLHeader", "enableServer", "address", "port", "readOnlyPort", "tlsCertFile", "tlsPrivateKeyFile", "certDirectory", "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", "lockFilePath", "exitOnLockContention", "configureCbr0", "hairpinMode", "babysitDaemons", "maxPods", "nvidiaGPUs", "dockerExecHandlerName", "podCIDR", "resolvConf", "cpuCFSQuota", "containerized", "maxOpenFiles", "reconcileCIDR", "registerSchedulable", "contentType", "kubeAPIQPS", "kubeAPIBurst", "serializeImagePulls", "experimentalFlannelOverlay", "nodeLabels", "nonMasqueradeCIDR", "enableCustomMetrics", "podsPerCore", "enableControllerAttachDetach", "systemReserved", "kubeReserved", "protectKernelDefaults", "makeIPTablesUtilChains", "iptablesMasqueradeBit", "iptablesDropBit"}, Required: []string{"TypeMeta", "podManifestPath", "syncFrequency", "fileCheckFrequency", "httpCheckFrequency", "manifestURL", "manifestURLHeader", "enableServer", "address", "port", "readOnlyPort", "tlsCertFile", "tlsPrivateKeyFile", "certDirectory", "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", "lockFilePath", "exitOnLockContention", "configureCbr0", "hairpinMode", "babysitDaemons", "maxPods", "nvidiaGPUs", "dockerExecHandlerName", "podCIDR", "resolvConf", "cpuCFSQuota", "containerized", "maxOpenFiles", "reconcileCIDR", "registerSchedulable", "contentType", "kubeAPIQPS", "kubeAPIBurst", "serializeImagePulls", "experimentalFlannelOverlay", "nodeLabels", "nonMasqueradeCIDR", "enableCustomMetrics", "podsPerCore", "enableControllerAttachDetach", "systemReserved", "kubeReserved", "protectKernelDefaults", "makeIPTablesUtilChains", "iptablesMasqueradeBit", "iptablesDropBit", "ExperimentalRuntimeIntegrationType"},
}, },
}, },
Dependencies: []string{ Dependencies: []string{
@ -14260,8 +14267,15 @@ func (_ openAPI) OpenAPIDefinitions() *common.OpenAPIDefinitions {
}, },
}, },
}, },
"ExperimentalRuntimeIntegrationType": {
SchemaProps: spec.SchemaProps{
Description: "How to integrate with runtime. If set to CRI, kubelet will switch to using the new Container Runtine Interface.",
Type: []string{"string"},
Format: "",
},
},
}, },
Required: []string{"TypeMeta", "podManifestPath", "syncFrequency", "fileCheckFrequency", "httpCheckFrequency", "manifestURL", "manifestURLHeader", "enableServer", "address", "port", "readOnlyPort", "tlsCertFile", "tlsPrivateKeyFile", "certDirectory", "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", "rktAPIEndpoint", "rktStage1Image", "lockFilePath", "exitOnLockContention", "configureCbr0", "hairpinMode", "babysitDaemons", "maxPods", "nvidiaGPUs", "dockerExecHandlerName", "podCIDR", "resolvConf", "cpuCFSQuota", "containerized", "maxOpenFiles", "reconcileCIDR", "registerSchedulable", "contentType", "kubeAPIQPS", "kubeAPIBurst", "serializeImagePulls", "experimentalFlannelOverlay", "outOfDiskTransitionFrequency", "nodeIP", "nodeLabels", "nonMasqueradeCIDR", "enableCustomMetrics", "evictionHard", "evictionSoft", "evictionSoftGracePeriod", "evictionPressureTransitionPeriod", "evictionMaxPodGracePeriod", "evictionMinimumReclaim", "podsPerCore", "enableControllerAttachDetach", "systemReserved", "kubeReserved", "protectKernelDefaults", "makeIPTablesUtilChains", "iptablesMasqueradeBit", "iptablesDropBit"}, Required: []string{"TypeMeta", "podManifestPath", "syncFrequency", "fileCheckFrequency", "httpCheckFrequency", "manifestURL", "manifestURLHeader", "enableServer", "address", "port", "readOnlyPort", "tlsCertFile", "tlsPrivateKeyFile", "certDirectory", "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", "rktAPIEndpoint", "rktStage1Image", "lockFilePath", "exitOnLockContention", "configureCbr0", "hairpinMode", "babysitDaemons", "maxPods", "nvidiaGPUs", "dockerExecHandlerName", "podCIDR", "resolvConf", "cpuCFSQuota", "containerized", "maxOpenFiles", "reconcileCIDR", "registerSchedulable", "contentType", "kubeAPIQPS", "kubeAPIBurst", "serializeImagePulls", "experimentalFlannelOverlay", "outOfDiskTransitionFrequency", "nodeIP", "nodeLabels", "nonMasqueradeCIDR", "enableCustomMetrics", "evictionHard", "evictionSoft", "evictionSoftGracePeriod", "evictionPressureTransitionPeriod", "evictionMaxPodGracePeriod", "evictionMinimumReclaim", "podsPerCore", "enableControllerAttachDetach", "systemReserved", "kubeReserved", "protectKernelDefaults", "makeIPTablesUtilChains", "iptablesMasqueradeBit", "iptablesDropBit", "ExperimentalRuntimeIntegrationType"},
}, },
}, },
Dependencies: []string{ Dependencies: []string{

View File

@ -51,6 +51,7 @@ import (
"k8s.io/kubernetes/pkg/kubelet/cm" "k8s.io/kubernetes/pkg/kubelet/cm"
"k8s.io/kubernetes/pkg/kubelet/config" "k8s.io/kubernetes/pkg/kubelet/config"
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
"k8s.io/kubernetes/pkg/kubelet/dockershim"
"k8s.io/kubernetes/pkg/kubelet/dockertools" "k8s.io/kubernetes/pkg/kubelet/dockertools"
"k8s.io/kubernetes/pkg/kubelet/envvars" "k8s.io/kubernetes/pkg/kubelet/envvars"
"k8s.io/kubernetes/pkg/kubelet/events" "k8s.io/kubernetes/pkg/kubelet/events"
@ -544,39 +545,64 @@ func NewMainKubelet(kubeCfg *componentconfig.KubeletConfiguration, kubeDeps *Kub
// Initialize the runtime. // Initialize the runtime.
switch kubeCfg.ContainerRuntime { switch kubeCfg.ContainerRuntime {
case "docker": case "docker":
// Only supported one for now, continue. switch kubeCfg.ExperimentalRuntimeIntegrationType {
klet.containerRuntime = dockertools.NewDockerManager( case "cri":
kubeDeps.DockerClient, // Use the new CRI shim for docker. This is need for testing the
kubecontainer.FilterEventRecorder(kubeDeps.Recorder), // docker integration through CRI, and may be removed in the future.
klet.livenessManager, dockerService := dockershim.NewDockerService(klet.dockerClient)
containerRefManager, klet.containerRuntime, err = kuberuntime.NewKubeGenericRuntimeManager(
klet.podManager, kubecontainer.FilterEventRecorder(kubeDeps.Recorder),
machineInfo, klet.livenessManager,
kubeCfg.PodInfraContainerImage, containerRefManager,
float32(kubeCfg.RegistryPullQPS), klet.podManager,
int(kubeCfg.RegistryBurst), kubeDeps.OSInterface,
containerLogsDir, klet.networkPlugin,
kubeDeps.OSInterface, klet,
klet.networkPlugin, klet.httpClient,
klet, imageBackOff,
klet.httpClient, kubeCfg.SerializeImagePulls,
dockerExecHandler, klet.cpuCFSQuota,
kubeDeps.OOMAdjuster, dockerService,
procFs, dockerService,
klet.cpuCFSQuota, )
imageBackOff, if err != nil {
kubeCfg.SerializeImagePulls, return nil, err
kubeCfg.EnableCustomMetrics, }
// If using "kubenet", the Kubernetes network plugin that wraps default:
// CNI's bridge plugin, it knows how to set the hairpin veth flag // Only supported one for now, continue.
// so we tell the container runtime to back away from setting it. klet.containerRuntime = dockertools.NewDockerManager(
// If the kubelet is started with any other plugin we can't be kubeDeps.DockerClient,
// sure it handles the hairpin case so we instruct the docker kubecontainer.FilterEventRecorder(kubeDeps.Recorder),
// runtime to set the flag instead. klet.livenessManager,
klet.hairpinMode == componentconfig.HairpinVeth && kubeCfg.NetworkPluginName != "kubenet", containerRefManager,
kubeCfg.SeccompProfileRoot, klet.podManager,
kubeDeps.ContainerRuntimeOptions..., machineInfo,
) kubeCfg.PodInfraContainerImage,
float32(kubeCfg.RegistryPullQPS),
int(kubeCfg.RegistryBurst),
containerLogsDir,
kubeDeps.OSInterface,
klet.networkPlugin,
klet,
klet.httpClient,
dockerExecHandler,
kubeDeps.OOMAdjuster,
procFs,
klet.cpuCFSQuota,
imageBackOff,
kubeCfg.SerializeImagePulls,
kubeCfg.EnableCustomMetrics,
// If using "kubenet", the Kubernetes network plugin that wraps
// CNI's bridge plugin, it knows how to set the hairpin veth flag
// so we tell the container runtime to back away from setting it.
// If the kubelet is started with any other plugin we can't be
// sure it handles the hairpin case so we instruct the docker
// runtime to set the flag instead.
klet.hairpinMode == componentconfig.HairpinVeth && kubeCfg.NetworkPluginName != "kubenet",
kubeCfg.SeccompProfileRoot,
kubeDeps.ContainerRuntimeOptions...,
)
}
case "rkt": case "rkt":
// TODO: Include hairpin mode settings in rkt? // TODO: Include hairpin mode settings in rkt?
conf := &rkt.Config{ conf := &rkt.Config{

View File

@ -17,8 +17,6 @@ limitations under the License.
package kuberuntime package kuberuntime
import ( import (
"fmt"
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/credentialprovider" "k8s.io/kubernetes/pkg/credentialprovider"
@ -130,7 +128,8 @@ func (m *kubeGenericRuntimeManager) RemoveImage(image kubecontainer.ImageSpec) e
} }
// ImageStats returns the statistics of the image. // ImageStats returns the statistics of the image.
// TODO: Implement this function.
func (m *kubeGenericRuntimeManager) ImageStats() (*kubecontainer.ImageStats, error) { func (m *kubeGenericRuntimeManager) ImageStats() (*kubecontainer.ImageStats, error) {
// TODO: support image stats in new runtime interface var usageBytes uint64 = 0
return nil, fmt.Errorf("not implemented") return &kubecontainer.ImageStats{TotalStorageBytes: usageBytes}, nil
} }

View File

@ -27,6 +27,10 @@ import (
const ( const (
UnsupportedReason = "SysctlUnsupported" UnsupportedReason = "SysctlUnsupported"
// CRI uses semver-compatible API version, while docker does not
// (e.g., 1.24). Append the version with a ".0" so that it works
// with both the CRI and dockertools comparison logic.
dockerMinimumAPIVersion = "1.24.0"
) )
type runtimeAdmitHandler struct { type runtimeAdmitHandler struct {
@ -45,7 +49,7 @@ func NewRuntimeAdmitHandler(runtime container.Runtime) (*runtimeAdmitHandler, er
} }
// only Docker >= 1.12 supports sysctls // only Docker >= 1.12 supports sysctls
c, err := v.Compare(dockertools.DockerV112APIVersion) c, err := v.Compare(dockerMinimumAPIVersion)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to compare Docker version for sysctl support: %v", err) return nil, fmt.Errorf("failed to compare Docker version for sysctl support: %v", err)
} }