mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
Remove rktnetes code
rktnetes is scheduled to be deprecated in 1.10 (#53601). According to the deprecation policy for beta CLI and flags, we can remove the feature in 1.11. Fixes #58721
This commit is contained in:
parent
90c09c75d6
commit
8df9274e02
@ -29,8 +29,6 @@ const (
|
|||||||
// When these values are updated, also update test/e2e/framework/util.go
|
// When these values are updated, also update test/e2e/framework/util.go
|
||||||
defaultPodSandboxImageName = "k8s.gcr.io/pause"
|
defaultPodSandboxImageName = "k8s.gcr.io/pause"
|
||||||
defaultPodSandboxImageVersion = "3.1"
|
defaultPodSandboxImageVersion = "3.1"
|
||||||
// From pkg/kubelet/rkt/rkt.go to avoid circular import
|
|
||||||
defaultRktAPIServiceEndpoint = "localhost:15441"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -54,7 +52,6 @@ func NewContainerRuntimeOptions() *config.ContainerRuntimeOptions {
|
|||||||
DockerDisableSharedPID: true,
|
DockerDisableSharedPID: true,
|
||||||
PodSandboxImage: defaultPodSandboxImage,
|
PodSandboxImage: defaultPodSandboxImage,
|
||||||
ImagePullProgressDeadline: metav1.Duration{Duration: 1 * time.Minute},
|
ImagePullProgressDeadline: metav1.Duration{Duration: 1 * time.Minute},
|
||||||
RktAPIEndpoint: defaultRktAPIServiceEndpoint,
|
|
||||||
ExperimentalDockershim: false,
|
ExperimentalDockershim: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -196,7 +196,6 @@ pkg/kubelet/prober/results
|
|||||||
pkg/kubelet/prober/testing
|
pkg/kubelet/prober/testing
|
||||||
pkg/kubelet/qos
|
pkg/kubelet/qos
|
||||||
pkg/kubelet/remote
|
pkg/kubelet/remote
|
||||||
pkg/kubelet/rkt
|
|
||||||
pkg/kubelet/secret
|
pkg/kubelet/secret
|
||||||
pkg/kubelet/server
|
pkg/kubelet/server
|
||||||
pkg/kubelet/server/portforward
|
pkg/kubelet/server/portforward
|
||||||
|
@ -74,7 +74,6 @@ go_library(
|
|||||||
"//pkg/kubelet/prober:go_default_library",
|
"//pkg/kubelet/prober:go_default_library",
|
||||||
"//pkg/kubelet/prober/results:go_default_library",
|
"//pkg/kubelet/prober/results:go_default_library",
|
||||||
"//pkg/kubelet/remote:go_default_library",
|
"//pkg/kubelet/remote:go_default_library",
|
||||||
"//pkg/kubelet/rkt:go_default_library",
|
|
||||||
"//pkg/kubelet/secret:go_default_library",
|
"//pkg/kubelet/secret:go_default_library",
|
||||||
"//pkg/kubelet/server:go_default_library",
|
"//pkg/kubelet/server:go_default_library",
|
||||||
"//pkg/kubelet/server/portforward:go_default_library",
|
"//pkg/kubelet/server/portforward:go_default_library",
|
||||||
@ -281,7 +280,6 @@ filegroup(
|
|||||||
"//pkg/kubelet/prober:all-srcs",
|
"//pkg/kubelet/prober:all-srcs",
|
||||||
"//pkg/kubelet/qos:all-srcs",
|
"//pkg/kubelet/qos:all-srcs",
|
||||||
"//pkg/kubelet/remote:all-srcs",
|
"//pkg/kubelet/remote:all-srcs",
|
||||||
"//pkg/kubelet/rkt:all-srcs",
|
|
||||||
"//pkg/kubelet/secret:all-srcs",
|
"//pkg/kubelet/secret:all-srcs",
|
||||||
"//pkg/kubelet/server:all-srcs",
|
"//pkg/kubelet/server:all-srcs",
|
||||||
"//pkg/kubelet/stats:all-srcs",
|
"//pkg/kubelet/stats:all-srcs",
|
||||||
|
@ -38,8 +38,6 @@ func (i *imageFsInfoProvider) ImageFsInfoLabel() (string, error) {
|
|||||||
switch i.runtime {
|
switch i.runtime {
|
||||||
case types.DockerContainerRuntime:
|
case types.DockerContainerRuntime:
|
||||||
return cadvisorfs.LabelDockerImages, nil
|
return cadvisorfs.LabelDockerImages, nil
|
||||||
case types.RktContainerRuntime:
|
|
||||||
return cadvisorfs.LabelRktImages, nil
|
|
||||||
case types.RemoteContainerRuntime:
|
case types.RemoteContainerRuntime:
|
||||||
// This is a temporary workaround to get stats for cri-o from cadvisor
|
// This is a temporary workaround to get stats for cri-o from cadvisor
|
||||||
// and should be removed.
|
// and should be removed.
|
||||||
|
@ -75,7 +75,6 @@ func EphemeralStorageCapacityFromFsInfo(info cadvisorapi2.FsInfo) v1.ResourceLis
|
|||||||
// https://github.com/kubernetes/kubernetes/issues/51798
|
// https://github.com/kubernetes/kubernetes/issues/51798
|
||||||
// UsingLegacyCadvisorStats returns true if container stats are provided by cadvisor instead of through the CRI
|
// UsingLegacyCadvisorStats returns true if container stats are provided by cadvisor instead of through the CRI
|
||||||
func UsingLegacyCadvisorStats(runtime, runtimeEndpoint string) bool {
|
func UsingLegacyCadvisorStats(runtime, runtimeEndpoint string) bool {
|
||||||
return runtime == kubetypes.RktContainerRuntime ||
|
return (runtime == kubetypes.DockerContainerRuntime && goruntime.GOOS == "linux") ||
|
||||||
(runtime == kubetypes.DockerContainerRuntime && goruntime.GOOS == "linux") ||
|
|
||||||
runtimeEndpoint == CrioSocket
|
runtimeEndpoint == CrioSocket
|
||||||
}
|
}
|
||||||
|
@ -67,16 +67,6 @@ type ContainerRuntimeOptions struct {
|
|||||||
// CNIBinDir is the full path of the directory in which to search for
|
// CNIBinDir is the full path of the directory in which to search for
|
||||||
// CNI plugin binaries
|
// CNI plugin binaries
|
||||||
CNIBinDir string
|
CNIBinDir string
|
||||||
|
|
||||||
// rkt-specific options.
|
|
||||||
|
|
||||||
// rktPath is the path of rkt binary. Leave empty to use the first rkt in $PATH.
|
|
||||||
RktPath string
|
|
||||||
// rktApiEndpoint is the endpoint of the rkt API service to communicate with.
|
|
||||||
RktAPIEndpoint string
|
|
||||||
// rktStage1Image is the image to use as stage1. Local paths and
|
|
||||||
// http/https URLs are supported.
|
|
||||||
RktStage1Image string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ContainerRuntimeOptions) AddFlags(fs *pflag.FlagSet) {
|
func (s *ContainerRuntimeOptions) AddFlags(fs *pflag.FlagSet) {
|
||||||
@ -95,17 +85,9 @@ func (s *ContainerRuntimeOptions) AddFlags(fs *pflag.FlagSet) {
|
|||||||
fs.StringVar(&s.DockerEndpoint, "docker-endpoint", s.DockerEndpoint, "Use this for the docker endpoint to communicate with")
|
fs.StringVar(&s.DockerEndpoint, "docker-endpoint", s.DockerEndpoint, "Use this for the docker endpoint to communicate with")
|
||||||
fs.DurationVar(&s.ImagePullProgressDeadline.Duration, "image-pull-progress-deadline", s.ImagePullProgressDeadline.Duration, "If no pulling progress is made before this deadline, the image pulling will be cancelled.")
|
fs.DurationVar(&s.ImagePullProgressDeadline.Duration, "image-pull-progress-deadline", s.ImagePullProgressDeadline.Duration, "If no pulling progress is made before this deadline, the image pulling will be cancelled.")
|
||||||
|
|
||||||
// Network plugin settings. Shared by both docker and rkt.
|
// Network plugin settings for Docker.
|
||||||
fs.StringVar(&s.NetworkPluginName, "network-plugin", s.NetworkPluginName, "<Warning: Alpha feature> The name of the network plugin to be invoked for various events in kubelet/pod lifecycle")
|
fs.StringVar(&s.NetworkPluginName, "network-plugin", s.NetworkPluginName, "<Warning: Alpha feature> The name of the network plugin to be invoked for various events in kubelet/pod lifecycle")
|
||||||
fs.StringVar(&s.CNIConfDir, "cni-conf-dir", s.CNIConfDir, "<Warning: Alpha feature> The full path of the directory in which to search for CNI config files. Default: /etc/cni/net.d")
|
fs.StringVar(&s.CNIConfDir, "cni-conf-dir", s.CNIConfDir, "<Warning: Alpha feature> The full path of the directory in which to search for CNI config files. Default: /etc/cni/net.d")
|
||||||
fs.StringVar(&s.CNIBinDir, "cni-bin-dir", s.CNIBinDir, "<Warning: Alpha feature> A comma-separated list of full paths of directories in which to search for CNI plugin binaries. Default: /opt/cni/bin")
|
fs.StringVar(&s.CNIBinDir, "cni-bin-dir", s.CNIBinDir, "<Warning: Alpha feature> A comma-separated list of full paths of directories in which to search for CNI plugin binaries. Default: /opt/cni/bin")
|
||||||
fs.Int32Var(&s.NetworkPluginMTU, "network-plugin-mtu", s.NetworkPluginMTU, "<Warning: Alpha feature> The MTU to be passed to the network plugin, to override the default. Set to 0 to use the default 1460 MTU.")
|
fs.Int32Var(&s.NetworkPluginMTU, "network-plugin-mtu", s.NetworkPluginMTU, "<Warning: Alpha feature> The MTU to be passed to the network plugin, to override the default. Set to 0 to use the default 1460 MTU.")
|
||||||
|
|
||||||
// Rkt-specific settings.
|
|
||||||
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.MarkDeprecated("rkt-path", "will be removed in a future version. Rktnetes has been deprecated in favor of rktlet (https://github.com/kubernetes-incubator/rktlet).")
|
|
||||||
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.MarkDeprecated("rkt-api-endpoint", "will be removed in a future version. Rktnetes has been deprecated in favor of rktlet (https://github.com/kubernetes-incubator/rktlet).")
|
|
||||||
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. Rktnetes has been deprecated in favor of rktlet (https://github.com/kubernetes-incubator/rktlet).")
|
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,6 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/kubelet/prober"
|
"k8s.io/kubernetes/pkg/kubelet/prober"
|
||||||
proberesults "k8s.io/kubernetes/pkg/kubelet/prober/results"
|
proberesults "k8s.io/kubernetes/pkg/kubelet/prober/results"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/remote"
|
"k8s.io/kubernetes/pkg/kubelet/remote"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/rkt"
|
|
||||||
"k8s.io/kubernetes/pkg/kubelet/secret"
|
"k8s.io/kubernetes/pkg/kubelet/secret"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/server"
|
"k8s.io/kubernetes/pkg/kubelet/server"
|
||||||
serverstats "k8s.io/kubernetes/pkg/kubelet/server/stats"
|
serverstats "k8s.io/kubernetes/pkg/kubelet/server/stats"
|
||||||
@ -600,145 +599,104 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration,
|
|||||||
var nl *NoOpLegacyHost
|
var nl *NoOpLegacyHost
|
||||||
pluginSettings.LegacyRuntimeHost = nl
|
pluginSettings.LegacyRuntimeHost = nl
|
||||||
|
|
||||||
if containerRuntime == kubetypes.RktContainerRuntime {
|
if containerRuntime == "rkt" {
|
||||||
glog.Warningln("rktnetes has been deprecated in favor of rktlet. Please see https://github.com/kubernetes-incubator/rktlet for more information.")
|
glog.Fatalln("rktnetes has been deprecated in favor of rktlet. Please see https://github.com/kubernetes-incubator/rktlet for more information.")
|
||||||
}
|
}
|
||||||
|
|
||||||
// rktnetes cannot be run with CRI.
|
// kubelet defers to the runtime shim to setup networking. Setting
|
||||||
if containerRuntime != kubetypes.RktContainerRuntime {
|
// this to nil will prevent it from trying to invoke the plugin.
|
||||||
// kubelet defers to the runtime shim to setup networking. Setting
|
// It's easier to always probe and initialize plugins till cri
|
||||||
// this to nil will prevent it from trying to invoke the plugin.
|
// becomes the default.
|
||||||
// It's easier to always probe and initialize plugins till cri
|
klet.networkPlugin = nil
|
||||||
// becomes the default.
|
// if left at nil, that means it is unneeded
|
||||||
klet.networkPlugin = nil
|
var legacyLogProvider kuberuntime.LegacyLogProvider
|
||||||
// if left at nil, that means it is unneeded
|
|
||||||
var legacyLogProvider kuberuntime.LegacyLogProvider
|
|
||||||
|
|
||||||
switch containerRuntime {
|
switch containerRuntime {
|
||||||
case kubetypes.DockerContainerRuntime:
|
case kubetypes.DockerContainerRuntime:
|
||||||
// Create and start the CRI shim running as a grpc server.
|
// Create and start the CRI shim running as a grpc server.
|
||||||
streamingConfig := getStreamingConfig(kubeCfg, kubeDeps)
|
streamingConfig := getStreamingConfig(kubeCfg, kubeDeps)
|
||||||
ds, err := dockershim.NewDockerService(kubeDeps.DockerClientConfig, crOptions.PodSandboxImage, streamingConfig,
|
ds, err := dockershim.NewDockerService(kubeDeps.DockerClientConfig, crOptions.PodSandboxImage, streamingConfig,
|
||||||
&pluginSettings, runtimeCgroups, kubeCfg.CgroupDriver, crOptions.DockershimRootDirectory,
|
&pluginSettings, runtimeCgroups, kubeCfg.CgroupDriver, crOptions.DockershimRootDirectory,
|
||||||
crOptions.DockerDisableSharedPID)
|
crOptions.DockerDisableSharedPID)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// For now, the CRI shim redirects the streaming requests to the
|
|
||||||
// kubelet, which handles the requests using DockerService..
|
|
||||||
klet.criHandler = ds
|
|
||||||
|
|
||||||
// The unix socket for kubelet <-> dockershim communication.
|
|
||||||
glog.V(5).Infof("RemoteRuntimeEndpoint: %q, RemoteImageEndpoint: %q",
|
|
||||||
remoteRuntimeEndpoint,
|
|
||||||
remoteImageEndpoint)
|
|
||||||
glog.V(2).Infof("Starting the GRPC server for the docker CRI shim.")
|
|
||||||
server := dockerremote.NewDockerServer(remoteRuntimeEndpoint, ds)
|
|
||||||
if err := server.Start(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create dockerLegacyService when the logging driver is not supported.
|
|
||||||
supported, err := ds.IsCRISupportedLogDriver()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if !supported {
|
|
||||||
klet.dockerLegacyService = ds
|
|
||||||
legacyLogProvider = ds
|
|
||||||
}
|
|
||||||
case kubetypes.RemoteContainerRuntime:
|
|
||||||
// No-op.
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("unsupported CRI runtime: %q", containerRuntime)
|
|
||||||
}
|
|
||||||
runtimeService, imageService, err := getRuntimeAndImageServices(remoteRuntimeEndpoint, remoteImageEndpoint, kubeCfg.RuntimeRequestTimeout)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
klet.runtimeService = runtimeService
|
// For now, the CRI shim redirects the streaming requests to the
|
||||||
runtime, err := kuberuntime.NewKubeGenericRuntimeManager(
|
// kubelet, which handles the requests using DockerService..
|
||||||
kubecontainer.FilterEventRecorder(kubeDeps.Recorder),
|
klet.criHandler = ds
|
||||||
klet.livenessManager,
|
|
||||||
seccompProfileRoot,
|
|
||||||
containerRefManager,
|
|
||||||
machineInfo,
|
|
||||||
klet,
|
|
||||||
kubeDeps.OSInterface,
|
|
||||||
klet,
|
|
||||||
httpClient,
|
|
||||||
imageBackOff,
|
|
||||||
kubeCfg.SerializeImagePulls,
|
|
||||||
float32(kubeCfg.RegistryPullQPS),
|
|
||||||
int(kubeCfg.RegistryBurst),
|
|
||||||
kubeCfg.CPUCFSQuota,
|
|
||||||
runtimeService,
|
|
||||||
imageService,
|
|
||||||
kubeDeps.ContainerManager.InternalContainerLifecycle(),
|
|
||||||
legacyLogProvider,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
klet.containerRuntime = runtime
|
|
||||||
klet.runner = runtime
|
|
||||||
|
|
||||||
if cadvisor.UsingLegacyCadvisorStats(containerRuntime, remoteRuntimeEndpoint) {
|
// The unix socket for kubelet <-> dockershim communication.
|
||||||
klet.StatsProvider = stats.NewCadvisorStatsProvider(
|
glog.V(5).Infof("RemoteRuntimeEndpoint: %q, RemoteImageEndpoint: %q",
|
||||||
klet.cadvisor,
|
remoteRuntimeEndpoint,
|
||||||
klet.resourceAnalyzer,
|
remoteImageEndpoint)
|
||||||
klet.podManager,
|
glog.V(2).Infof("Starting the GRPC server for the docker CRI shim.")
|
||||||
klet.runtimeCache,
|
server := dockerremote.NewDockerServer(remoteRuntimeEndpoint, ds)
|
||||||
klet.containerRuntime)
|
if err := server.Start(); err != nil {
|
||||||
} else {
|
return nil, err
|
||||||
klet.StatsProvider = stats.NewCRIStatsProvider(
|
|
||||||
klet.cadvisor,
|
|
||||||
klet.resourceAnalyzer,
|
|
||||||
klet.podManager,
|
|
||||||
klet.runtimeCache,
|
|
||||||
runtimeService,
|
|
||||||
imageService,
|
|
||||||
stats.NewLogMetricsService())
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// rkt uses the legacy, non-CRI, integration. Configure it the old way.
|
// Create dockerLegacyService when the logging driver is not supported.
|
||||||
// TODO: Include hairpin mode settings in rkt?
|
supported, err := ds.IsCRISupportedLogDriver()
|
||||||
conf := &rkt.Config{
|
|
||||||
Path: crOptions.RktPath,
|
|
||||||
Stage1Image: crOptions.RktStage1Image,
|
|
||||||
InsecureOptions: "image,ondisk",
|
|
||||||
}
|
|
||||||
runtime, err := rkt.New(
|
|
||||||
crOptions.RktAPIEndpoint,
|
|
||||||
conf,
|
|
||||||
klet,
|
|
||||||
kubeDeps.Recorder,
|
|
||||||
containerRefManager,
|
|
||||||
klet,
|
|
||||||
klet.livenessManager,
|
|
||||||
httpClient,
|
|
||||||
klet.networkPlugin,
|
|
||||||
hairpinMode == kubeletconfiginternal.HairpinVeth,
|
|
||||||
utilexec.New(),
|
|
||||||
kubecontainer.RealOS{},
|
|
||||||
imageBackOff,
|
|
||||||
kubeCfg.SerializeImagePulls,
|
|
||||||
float32(kubeCfg.RegistryPullQPS),
|
|
||||||
int(kubeCfg.RegistryBurst),
|
|
||||||
kubeCfg.RuntimeRequestTimeout.Duration,
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
klet.containerRuntime = runtime
|
if !supported {
|
||||||
klet.runner = kubecontainer.DirectStreamingRunner(runtime)
|
klet.dockerLegacyService = ds
|
||||||
|
legacyLogProvider = ds
|
||||||
|
}
|
||||||
|
case kubetypes.RemoteContainerRuntime:
|
||||||
|
// No-op.
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unsupported CRI runtime: %q", containerRuntime)
|
||||||
|
}
|
||||||
|
runtimeService, imageService, err := getRuntimeAndImageServices(remoteRuntimeEndpoint, remoteImageEndpoint, kubeCfg.RuntimeRequestTimeout)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
klet.runtimeService = runtimeService
|
||||||
|
runtime, err := kuberuntime.NewKubeGenericRuntimeManager(
|
||||||
|
kubecontainer.FilterEventRecorder(kubeDeps.Recorder),
|
||||||
|
klet.livenessManager,
|
||||||
|
seccompProfileRoot,
|
||||||
|
containerRefManager,
|
||||||
|
machineInfo,
|
||||||
|
klet,
|
||||||
|
kubeDeps.OSInterface,
|
||||||
|
klet,
|
||||||
|
httpClient,
|
||||||
|
imageBackOff,
|
||||||
|
kubeCfg.SerializeImagePulls,
|
||||||
|
float32(kubeCfg.RegistryPullQPS),
|
||||||
|
int(kubeCfg.RegistryBurst),
|
||||||
|
kubeCfg.CPUCFSQuota,
|
||||||
|
runtimeService,
|
||||||
|
imageService,
|
||||||
|
kubeDeps.ContainerManager.InternalContainerLifecycle(),
|
||||||
|
legacyLogProvider,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
klet.containerRuntime = runtime
|
||||||
|
klet.runner = runtime
|
||||||
|
|
||||||
|
if cadvisor.UsingLegacyCadvisorStats(containerRuntime, remoteRuntimeEndpoint) {
|
||||||
klet.StatsProvider = stats.NewCadvisorStatsProvider(
|
klet.StatsProvider = stats.NewCadvisorStatsProvider(
|
||||||
klet.cadvisor,
|
klet.cadvisor,
|
||||||
klet.resourceAnalyzer,
|
klet.resourceAnalyzer,
|
||||||
klet.podManager,
|
klet.podManager,
|
||||||
klet.runtimeCache,
|
klet.runtimeCache,
|
||||||
klet.containerRuntime)
|
klet.containerRuntime)
|
||||||
|
} else {
|
||||||
|
klet.StatsProvider = stats.NewCRIStatsProvider(
|
||||||
|
klet.cadvisor,
|
||||||
|
klet.resourceAnalyzer,
|
||||||
|
klet.podManager,
|
||||||
|
klet.runtimeCache,
|
||||||
|
runtimeService,
|
||||||
|
imageService,
|
||||||
|
stats.NewLogMetricsService())
|
||||||
}
|
}
|
||||||
|
|
||||||
klet.pleg = pleg.NewGenericPLEG(klet.containerRuntime, plegChannelCapacity, plegRelistPeriod, klet.podCache, clock.RealClock{})
|
klet.pleg = pleg.NewGenericPLEG(klet.containerRuntime, plegChannelCapacity, plegRelistPeriod, klet.podCache, clock.RealClock{})
|
||||||
@ -2108,34 +2066,30 @@ func (kl *Kubelet) updateRuntimeUp() {
|
|||||||
glog.Errorf("Container runtime sanity check failed: %v", err)
|
glog.Errorf("Container runtime sanity check failed: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// rkt uses the legacy, non-CRI integration. Don't check the runtime
|
if s == nil {
|
||||||
// conditions for it.
|
glog.Errorf("Container runtime status is nil")
|
||||||
if kl.containerRuntimeName != kubetypes.RktContainerRuntime {
|
return
|
||||||
if s == nil {
|
}
|
||||||
glog.Errorf("Container runtime status is nil")
|
// Periodically log the whole runtime status for debugging.
|
||||||
return
|
// TODO(random-liu): Consider to send node event when optional
|
||||||
}
|
// condition is unmet.
|
||||||
// Periodically log the whole runtime status for debugging.
|
glog.V(4).Infof("Container runtime status: %v", s)
|
||||||
// TODO(random-liu): Consider to send node event when optional
|
networkReady := s.GetRuntimeCondition(kubecontainer.NetworkReady)
|
||||||
// condition is unmet.
|
if networkReady == nil || !networkReady.Status {
|
||||||
glog.V(4).Infof("Container runtime status: %v", s)
|
glog.Errorf("Container runtime network not ready: %v", networkReady)
|
||||||
networkReady := s.GetRuntimeCondition(kubecontainer.NetworkReady)
|
kl.runtimeState.setNetworkState(fmt.Errorf("runtime network not ready: %v", networkReady))
|
||||||
if networkReady == nil || !networkReady.Status {
|
} else {
|
||||||
glog.Errorf("Container runtime network not ready: %v", networkReady)
|
// Set nil if the container runtime network is ready.
|
||||||
kl.runtimeState.setNetworkState(fmt.Errorf("runtime network not ready: %v", networkReady))
|
kl.runtimeState.setNetworkState(nil)
|
||||||
} else {
|
}
|
||||||
// Set nil if the container runtime network is ready.
|
// TODO(random-liu): Add runtime error in runtimeState, and update it
|
||||||
kl.runtimeState.setNetworkState(nil)
|
// when runtime is not ready, so that the information in RuntimeReady
|
||||||
}
|
// condition will be propagated to NodeReady condition.
|
||||||
// TODO(random-liu): Add runtime error in runtimeState, and update it
|
runtimeReady := s.GetRuntimeCondition(kubecontainer.RuntimeReady)
|
||||||
// when runtime is not ready, so that the information in RuntimeReady
|
// If RuntimeReady is not set or is false, report an error.
|
||||||
// condition will be propagated to NodeReady condition.
|
if runtimeReady == nil || !runtimeReady.Status {
|
||||||
runtimeReady := s.GetRuntimeCondition(kubecontainer.RuntimeReady)
|
glog.Errorf("Container runtime not ready: %v", runtimeReady)
|
||||||
// If RuntimeReady is not set or is false, report an error.
|
return
|
||||||
if runtimeReady == nil || !runtimeReady.Status {
|
|
||||||
glog.Errorf("Container runtime not ready: %v", runtimeReady)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
kl.oneTimeInitializer.Do(kl.initializeRuntimeDependentModules)
|
kl.oneTimeInitializer.Do(kl.initializeRuntimeDependentModules)
|
||||||
kl.runtimeState.setRuntimeSync(kl.clock.Now())
|
kl.runtimeState.setRuntimeSync(kl.clock.Now())
|
||||||
|
@ -1,108 +0,0 @@
|
|||||||
package(default_visibility = ["//visibility:public"])
|
|
||||||
|
|
||||||
load(
|
|
||||||
"@io_bazel_rules_go//go:def.bzl",
|
|
||||||
"go_library",
|
|
||||||
"go_test",
|
|
||||||
)
|
|
||||||
|
|
||||||
go_library(
|
|
||||||
name = "go_default_library",
|
|
||||||
srcs = [
|
|
||||||
"cap.go",
|
|
||||||
"config.go",
|
|
||||||
"container_id.go",
|
|
||||||
"doc.go",
|
|
||||||
"image.go",
|
|
||||||
"log.go",
|
|
||||||
"rkt.go",
|
|
||||||
"systemd.go",
|
|
||||||
"version.go",
|
|
||||||
],
|
|
||||||
importpath = "k8s.io/kubernetes/pkg/kubelet/rkt",
|
|
||||||
deps = [
|
|
||||||
"//pkg/credentialprovider:go_default_library",
|
|
||||||
"//pkg/credentialprovider/secrets:go_default_library",
|
|
||||||
"//pkg/kubelet/container:go_default_library",
|
|
||||||
"//pkg/kubelet/events:go_default_library",
|
|
||||||
"//pkg/kubelet/images:go_default_library",
|
|
||||||
"//pkg/kubelet/leaky:go_default_library",
|
|
||||||
"//pkg/kubelet/lifecycle:go_default_library",
|
|
||||||
"//pkg/kubelet/network:go_default_library",
|
|
||||||
"//pkg/kubelet/network/hairpin:go_default_library",
|
|
||||||
"//pkg/kubelet/prober/results:go_default_library",
|
|
||||||
"//pkg/kubelet/types:go_default_library",
|
|
||||||
"//pkg/kubelet/util/format:go_default_library",
|
|
||||||
"//pkg/securitycontext:go_default_library",
|
|
||||||
"//pkg/util/parsers:go_default_library",
|
|
||||||
"//pkg/util/selinux:go_default_library",
|
|
||||||
"//pkg/util/strings:go_default_library",
|
|
||||||
"//pkg/util/term:go_default_library",
|
|
||||||
"//pkg/util/version:go_default_library",
|
|
||||||
"//vendor/github.com/appc/spec/schema:go_default_library",
|
|
||||||
"//vendor/github.com/appc/spec/schema/types:go_default_library",
|
|
||||||
"//vendor/github.com/coreos/go-systemd/dbus:go_default_library",
|
|
||||||
"//vendor/github.com/coreos/go-systemd/unit:go_default_library",
|
|
||||||
"//vendor/github.com/coreos/rkt/api/v1alpha:go_default_library",
|
|
||||||
"//vendor/github.com/docker/docker/api/types:go_default_library",
|
|
||||||
"//vendor/github.com/golang/glog:go_default_library",
|
|
||||||
"//vendor/google.golang.org/grpc:go_default_library",
|
|
||||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
|
||||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
|
||||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/uuid:go_default_library",
|
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
|
|
||||||
"//vendor/k8s.io/client-go/tools/record:go_default_library",
|
|
||||||
"//vendor/k8s.io/client-go/tools/remotecommand:go_default_library",
|
|
||||||
"//vendor/k8s.io/client-go/util/flowcontrol:go_default_library",
|
|
||||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
go_test(
|
|
||||||
name = "go_default_test",
|
|
||||||
srcs = [
|
|
||||||
"fake_rkt_interface_test.go",
|
|
||||||
"rkt_test.go",
|
|
||||||
],
|
|
||||||
embed = [":go_default_library"],
|
|
||||||
deps = [
|
|
||||||
"//pkg/kubelet/container:go_default_library",
|
|
||||||
"//pkg/kubelet/container/testing:go_default_library",
|
|
||||||
"//pkg/kubelet/lifecycle:go_default_library",
|
|
||||||
"//pkg/kubelet/network:go_default_library",
|
|
||||||
"//pkg/kubelet/network/kubenet:go_default_library",
|
|
||||||
"//pkg/kubelet/network/testing:go_default_library",
|
|
||||||
"//pkg/kubelet/types:go_default_library",
|
|
||||||
"//vendor/github.com/appc/spec/schema:go_default_library",
|
|
||||||
"//vendor/github.com/appc/spec/schema/types:go_default_library",
|
|
||||||
"//vendor/github.com/coreos/go-systemd/dbus:go_default_library",
|
|
||||||
"//vendor/github.com/coreos/go-systemd/unit:go_default_library",
|
|
||||||
"//vendor/github.com/coreos/rkt/api/v1alpha:go_default_library",
|
|
||||||
"//vendor/github.com/golang/mock/gomock:go_default_library",
|
|
||||||
"//vendor/github.com/stretchr/testify/assert:go_default_library",
|
|
||||||
"//vendor/google.golang.org/grpc:go_default_library",
|
|
||||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
|
||||||
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
|
||||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
|
||||||
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
|
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/errors:go_default_library",
|
|
||||||
"//vendor/k8s.io/client-go/util/testing:go_default_library",
|
|
||||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
|
||||||
"//vendor/k8s.io/utils/exec/testing:go_default_library",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "package-srcs",
|
|
||||||
srcs = glob(["**"]),
|
|
||||||
tags = ["automanaged"],
|
|
||||||
visibility = ["//visibility:private"],
|
|
||||||
)
|
|
||||||
|
|
||||||
filegroup(
|
|
||||||
name = "all-srcs",
|
|
||||||
srcs = [":package-srcs"],
|
|
||||||
tags = ["automanaged"],
|
|
||||||
)
|
|
@ -1,3 +0,0 @@
|
|||||||
approvers:
|
|
||||||
- euank
|
|
||||||
- yifan-gu
|
|
@ -1,110 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2015 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 rkt
|
|
||||||
|
|
||||||
// TODO(yifan): Export this to higher level package.
|
|
||||||
const (
|
|
||||||
CAP_CHOWN = iota
|
|
||||||
CAP_DAC_OVERRIDE
|
|
||||||
CAP_DAC_READ_SEARCH
|
|
||||||
CAP_FOWNER
|
|
||||||
CAP_FSETID
|
|
||||||
CAP_KILL
|
|
||||||
CAP_SETGID
|
|
||||||
CAP_SETUID
|
|
||||||
CAP_SETPCAP
|
|
||||||
CAP_LINUX_IMMUTABLE
|
|
||||||
CAP_NET_BIND_SERVICE
|
|
||||||
CAP_NET_BROADCAST
|
|
||||||
CAP_NET_ADMIN
|
|
||||||
CAP_NET_RAW
|
|
||||||
CAP_IPC_LOCK
|
|
||||||
CAP_IPC_OWNER
|
|
||||||
CAP_SYS_MODULE
|
|
||||||
CAP_SYS_RAWIO
|
|
||||||
CAP_SYS_CHROOT
|
|
||||||
CAP_SYS_PTRACE
|
|
||||||
CAP_SYS_PACCT
|
|
||||||
CAP_SYS_ADMIN
|
|
||||||
CAP_SYS_BOOT
|
|
||||||
CAP_SYS_NICE
|
|
||||||
CAP_SYS_RESOURCE
|
|
||||||
CAP_SYS_TIME
|
|
||||||
CAP_SYS_TTY_CONFIG
|
|
||||||
CAP_MKNOD
|
|
||||||
CAP_LEASE
|
|
||||||
CAP_AUDIT_WRITE
|
|
||||||
CAP_AUDIT_CONTROL
|
|
||||||
CAP_SETFCAP
|
|
||||||
CAP_MAC_OVERRIDE
|
|
||||||
CAP_MAC_ADMIN
|
|
||||||
CAP_SYSLOG
|
|
||||||
CAP_WAKE_ALARM
|
|
||||||
CAP_BLOCK_SUSPEND
|
|
||||||
CAP_AUDIT_READ
|
|
||||||
)
|
|
||||||
|
|
||||||
// TODO(yifan): Export this to higher level package.
|
|
||||||
var capabilityList = map[int]string{
|
|
||||||
CAP_CHOWN: "CAP_CHOWN",
|
|
||||||
CAP_DAC_OVERRIDE: "CAP_DAC_OVERRIDE",
|
|
||||||
CAP_DAC_READ_SEARCH: "CAP_DAC_READ_SEARCH",
|
|
||||||
CAP_FOWNER: "CAP_FOWNER",
|
|
||||||
CAP_FSETID: "CAP_FSETID",
|
|
||||||
CAP_KILL: "CAP_KILL",
|
|
||||||
CAP_SETGID: "CAP_SETGID",
|
|
||||||
CAP_SETUID: "CAP_SETUID",
|
|
||||||
CAP_SETPCAP: "CAP_SETPCAP",
|
|
||||||
CAP_LINUX_IMMUTABLE: "CAP_LINUX_IMMUTABLE",
|
|
||||||
CAP_NET_BIND_SERVICE: "CAP_NET_BIND_SERVICE",
|
|
||||||
CAP_NET_BROADCAST: "CAP_NET_BROADCAST",
|
|
||||||
CAP_NET_ADMIN: "CAP_NET_ADMIN",
|
|
||||||
CAP_NET_RAW: "CAP_NET_RAW",
|
|
||||||
CAP_IPC_LOCK: "CAP_IPC_LOCK",
|
|
||||||
CAP_IPC_OWNER: "CAP_IPC_OWNER",
|
|
||||||
CAP_SYS_MODULE: "CAP_SYS_MODULE",
|
|
||||||
CAP_SYS_RAWIO: "CAP_SYS_RAWIO",
|
|
||||||
CAP_SYS_CHROOT: "CAP_SYS_CHROOT",
|
|
||||||
CAP_SYS_PTRACE: "CAP_SYS_PTRACE",
|
|
||||||
CAP_SYS_PACCT: "CAP_SYS_PACCT",
|
|
||||||
CAP_SYS_ADMIN: "CAP_SYS_ADMIN",
|
|
||||||
CAP_SYS_BOOT: "CAP_SYS_BOOT",
|
|
||||||
CAP_SYS_NICE: "CAP_SYS_NICE",
|
|
||||||
CAP_SYS_RESOURCE: "CAP_SYS_RESOURCE",
|
|
||||||
CAP_SYS_TIME: "CAP_SYS_TIME",
|
|
||||||
CAP_SYS_TTY_CONFIG: "CAP_SYS_TTY_CONFIG",
|
|
||||||
CAP_MKNOD: "CAP_MKNOD",
|
|
||||||
CAP_LEASE: "CAP_LEASE",
|
|
||||||
CAP_AUDIT_WRITE: "CAP_AUDIT_WRITE",
|
|
||||||
CAP_AUDIT_CONTROL: "CAP_AUDIT_CONTROL",
|
|
||||||
CAP_SETFCAP: "CAP_SETFCAP",
|
|
||||||
CAP_MAC_OVERRIDE: "CAP_MAC_OVERRIDE",
|
|
||||||
CAP_MAC_ADMIN: "CAP_MAC_ADMIN",
|
|
||||||
CAP_SYSLOG: "CAP_SYSLOG",
|
|
||||||
CAP_WAKE_ALARM: "CAP_WAKE_ALARM",
|
|
||||||
CAP_BLOCK_SUSPEND: "CAP_BLOCK_SUSPEND",
|
|
||||||
CAP_AUDIT_READ: "CAP_AUDIT_READ",
|
|
||||||
}
|
|
||||||
|
|
||||||
// allCapabilities returns the capability list with all capabilities.
|
|
||||||
func allCapabilities() []string {
|
|
||||||
var capabilities []string
|
|
||||||
for _, cap := range capabilityList {
|
|
||||||
capabilities = append(capabilities, cap)
|
|
||||||
}
|
|
||||||
return capabilities
|
|
||||||
}
|
|
@ -1,108 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2015 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 rkt
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
rktapi "github.com/coreos/rkt/api/v1alpha"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Config stores the global configuration for the rkt runtime.
|
|
||||||
// Detailed documents can be found at:
|
|
||||||
// https://github.com/coreos/rkt/blob/master/Documentation/commands.md#global-options
|
|
||||||
type Config struct {
|
|
||||||
// The absolute path to the binary, or leave empty to find it in $PATH.
|
|
||||||
Path string
|
|
||||||
// The rkt data directory.
|
|
||||||
Dir string
|
|
||||||
// The image to use as stage1.
|
|
||||||
Stage1Image string
|
|
||||||
// The debug flag for rkt.
|
|
||||||
Debug bool
|
|
||||||
// Comma-separated list of security features to disable.
|
|
||||||
// Allowed values: "none", "image", "tls", "ondisk", "http", "all".
|
|
||||||
InsecureOptions string
|
|
||||||
// The local config directory.
|
|
||||||
LocalConfigDir string
|
|
||||||
// The user config directory.
|
|
||||||
UserConfigDir string
|
|
||||||
// The system config directory.
|
|
||||||
SystemConfigDir string
|
|
||||||
}
|
|
||||||
|
|
||||||
// buildGlobalOptions returns an array of global command line options.
|
|
||||||
func (c *Config) buildGlobalOptions() []string {
|
|
||||||
var result []string
|
|
||||||
if c == nil {
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.Debug {
|
|
||||||
result = append(result, "--debug=true")
|
|
||||||
}
|
|
||||||
if c.InsecureOptions != "" {
|
|
||||||
result = append(result, fmt.Sprintf("--insecure-options=%s", c.InsecureOptions))
|
|
||||||
}
|
|
||||||
if c.LocalConfigDir != "" {
|
|
||||||
result = append(result, fmt.Sprintf("--local-config=%s", c.LocalConfigDir))
|
|
||||||
}
|
|
||||||
if c.UserConfigDir != "" {
|
|
||||||
result = append(result, fmt.Sprintf("--user-config=%s", c.UserConfigDir))
|
|
||||||
}
|
|
||||||
if c.SystemConfigDir != "" {
|
|
||||||
result = append(result, fmt.Sprintf("--system-config=%s", c.SystemConfigDir))
|
|
||||||
}
|
|
||||||
if c.Dir != "" {
|
|
||||||
result = append(result, fmt.Sprintf("--dir=%s", c.Dir))
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
// getConfig gets configurations from the rkt API service
|
|
||||||
// and merge it with the existing config. The merge rule is
|
|
||||||
// that the fields in the provided config will override the
|
|
||||||
// result that get from the rkt api service.
|
|
||||||
func (r *Runtime) getConfig(cfg *Config) (*Config, error) {
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), r.requestTimeout)
|
|
||||||
defer cancel()
|
|
||||||
resp, err := r.apisvc.GetInfo(ctx, &rktapi.GetInfoRequest{})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
flags := resp.Info.GlobalFlags
|
|
||||||
|
|
||||||
if flags.Dir != "" {
|
|
||||||
cfg.Dir = flags.Dir
|
|
||||||
}
|
|
||||||
if flags.LocalConfigDir != "" {
|
|
||||||
cfg.LocalConfigDir = flags.LocalConfigDir
|
|
||||||
}
|
|
||||||
if flags.UserConfigDir != "" {
|
|
||||||
cfg.UserConfigDir = flags.UserConfigDir
|
|
||||||
}
|
|
||||||
if flags.SystemConfigDir != "" {
|
|
||||||
cfg.SystemConfigDir = flags.SystemConfigDir
|
|
||||||
}
|
|
||||||
if flags.InsecureFlags != "" {
|
|
||||||
cfg.InsecureOptions = fmt.Sprintf("%s,%s", cfg.InsecureOptions, flags.InsecureFlags)
|
|
||||||
}
|
|
||||||
|
|
||||||
return cfg, nil
|
|
||||||
}
|
|
@ -1,55 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2015 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 rkt
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
|
||||||
)
|
|
||||||
|
|
||||||
// containerID defines the ID of rkt containers, it will
|
|
||||||
// be returned to kubelet, and kubelet will use this for
|
|
||||||
// container level operations.
|
|
||||||
type containerID struct {
|
|
||||||
uuid string // rkt uuid of the pod.
|
|
||||||
appName string // Name of the app in that pod.
|
|
||||||
}
|
|
||||||
|
|
||||||
// buildContainerID constructs the containers's ID using containerID,
|
|
||||||
// which consists of the pod uuid and the container name.
|
|
||||||
// The result can be used to uniquely identify a container.
|
|
||||||
func buildContainerID(c *containerID) kubecontainer.ContainerID {
|
|
||||||
return kubecontainer.ContainerID{
|
|
||||||
Type: RktType,
|
|
||||||
ID: fmt.Sprintf("%s:%s", c.uuid, c.appName),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseContainerID parses the containerID into pod uuid and the container name. The
|
|
||||||
// results can be used to get more information of the container.
|
|
||||||
func parseContainerID(id kubecontainer.ContainerID) (*containerID, error) {
|
|
||||||
tuples := strings.Split(id.ID, ":")
|
|
||||||
if len(tuples) != 2 {
|
|
||||||
return nil, fmt.Errorf("rkt: cannot parse container ID for: %q, required format is [UUID:APPNAME]", id)
|
|
||||||
}
|
|
||||||
return &containerID{
|
|
||||||
uuid: tuples[0],
|
|
||||||
appName: tuples[1],
|
|
||||||
}, nil
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2015 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 rkt contains the Containerruntime interface implementation for rkt.
|
|
||||||
package rkt // import "k8s.io/kubernetes/pkg/kubelet/rkt"
|
|
@ -1,218 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2015 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 rkt
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/coreos/go-systemd/dbus"
|
|
||||||
rktapi "github.com/coreos/rkt/api/v1alpha"
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
"k8s.io/apimachinery/pkg/types"
|
|
||||||
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
|
||||||
)
|
|
||||||
|
|
||||||
// fakeRktInterface mocks the rktapi.PublicAPIClient interface for testing purpose.
|
|
||||||
type fakeRktInterface struct {
|
|
||||||
sync.Mutex
|
|
||||||
info rktapi.Info
|
|
||||||
images []*rktapi.Image
|
|
||||||
podFilters []*rktapi.PodFilter
|
|
||||||
pods []*rktapi.Pod
|
|
||||||
called []string
|
|
||||||
err error
|
|
||||||
}
|
|
||||||
|
|
||||||
func newFakeRktInterface() *fakeRktInterface {
|
|
||||||
return &fakeRktInterface{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fakeRktInterface) CleanCalls() {
|
|
||||||
f.Lock()
|
|
||||||
defer f.Unlock()
|
|
||||||
f.called = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fakeRktInterface) GetInfo(ctx context.Context, in *rktapi.GetInfoRequest, opts ...grpc.CallOption) (*rktapi.GetInfoResponse, error) {
|
|
||||||
f.Lock()
|
|
||||||
defer f.Unlock()
|
|
||||||
|
|
||||||
f.called = append(f.called, "GetInfo")
|
|
||||||
return &rktapi.GetInfoResponse{Info: &f.info}, f.err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fakeRktInterface) ListPods(ctx context.Context, in *rktapi.ListPodsRequest, opts ...grpc.CallOption) (*rktapi.ListPodsResponse, error) {
|
|
||||||
f.Lock()
|
|
||||||
defer f.Unlock()
|
|
||||||
|
|
||||||
f.called = append(f.called, "ListPods")
|
|
||||||
f.podFilters = in.Filters
|
|
||||||
return &rktapi.ListPodsResponse{Pods: f.pods}, f.err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fakeRktInterface) InspectPod(ctx context.Context, in *rktapi.InspectPodRequest, opts ...grpc.CallOption) (*rktapi.InspectPodResponse, error) {
|
|
||||||
f.Lock()
|
|
||||||
defer f.Unlock()
|
|
||||||
|
|
||||||
f.called = append(f.called, "InspectPod")
|
|
||||||
for _, pod := range f.pods {
|
|
||||||
if pod.Id == in.Id {
|
|
||||||
return &rktapi.InspectPodResponse{Pod: pod}, f.err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return &rktapi.InspectPodResponse{}, fmt.Errorf("pod %q not found", in.Id)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fakeRktInterface) ListImages(ctx context.Context, in *rktapi.ListImagesRequest, opts ...grpc.CallOption) (*rktapi.ListImagesResponse, error) {
|
|
||||||
f.Lock()
|
|
||||||
defer f.Unlock()
|
|
||||||
|
|
||||||
f.called = append(f.called, "ListImages")
|
|
||||||
return &rktapi.ListImagesResponse{Images: f.images}, f.err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fakeRktInterface) InspectImage(ctx context.Context, in *rktapi.InspectImageRequest, opts ...grpc.CallOption) (*rktapi.InspectImageResponse, error) {
|
|
||||||
return nil, fmt.Errorf("Not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fakeRktInterface) ListenEvents(ctx context.Context, in *rktapi.ListenEventsRequest, opts ...grpc.CallOption) (rktapi.PublicAPI_ListenEventsClient, error) {
|
|
||||||
return nil, fmt.Errorf("Not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fakeRktInterface) GetLogs(ctx context.Context, in *rktapi.GetLogsRequest, opts ...grpc.CallOption) (rktapi.PublicAPI_GetLogsClient, error) {
|
|
||||||
return nil, fmt.Errorf("Not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
// fakeSystemd mocks the systemdInterface for testing purpose.
|
|
||||||
// TODO(yifan): Remove this once we have a package for launching rkt pods.
|
|
||||||
// See https://github.com/coreos/rkt/issues/1769.
|
|
||||||
type fakeSystemd struct {
|
|
||||||
sync.Mutex
|
|
||||||
called []string
|
|
||||||
resetFailedUnits []string
|
|
||||||
version string
|
|
||||||
err error
|
|
||||||
}
|
|
||||||
|
|
||||||
func newFakeSystemd() *fakeSystemd {
|
|
||||||
return &fakeSystemd{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fakeSystemd) CleanCalls() {
|
|
||||||
f.Lock()
|
|
||||||
defer f.Unlock()
|
|
||||||
f.called = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fakeSystemd) Version() (systemdVersion, error) {
|
|
||||||
f.Lock()
|
|
||||||
defer f.Unlock()
|
|
||||||
|
|
||||||
f.called = append(f.called, "Version")
|
|
||||||
v, _ := strconv.Atoi(f.version)
|
|
||||||
return systemdVersion(v), f.err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fakeSystemd) ListUnits() ([]dbus.UnitStatus, error) {
|
|
||||||
return nil, fmt.Errorf("Not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fakeSystemd) StopUnit(name string, mode string, ch chan<- string) (int, error) {
|
|
||||||
return 0, fmt.Errorf("Not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fakeSystemd) RestartUnit(name string, mode string, ch chan<- string) (int, error) {
|
|
||||||
return 0, fmt.Errorf("Not implemented")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fakeSystemd) ResetFailedUnit(name string) error {
|
|
||||||
f.called = append(f.called, "ResetFailedUnit")
|
|
||||||
f.resetFailedUnits = append(f.resetFailedUnits, name)
|
|
||||||
return f.err
|
|
||||||
}
|
|
||||||
|
|
||||||
type fakeRktCli struct {
|
|
||||||
sync.Mutex
|
|
||||||
cmds []string
|
|
||||||
result []string
|
|
||||||
err error
|
|
||||||
}
|
|
||||||
|
|
||||||
func newFakeRktCli() *fakeRktCli {
|
|
||||||
return &fakeRktCli{
|
|
||||||
cmds: []string{},
|
|
||||||
result: []string{},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fakeRktCli) RunCommand(config *Config, args ...string) (result []string, err error) {
|
|
||||||
f.Lock()
|
|
||||||
defer f.Unlock()
|
|
||||||
cmd := append([]string{"rkt"}, args...)
|
|
||||||
f.cmds = append(f.cmds, strings.Join(cmd, " "))
|
|
||||||
return f.result, f.err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fakeRktCli) Reset() {
|
|
||||||
f.cmds = []string{}
|
|
||||||
f.result = []string{}
|
|
||||||
f.err = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type fakePodDeletionProvider struct {
|
|
||||||
pods map[types.UID]struct{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func newFakePodDeletionProvider() *fakePodDeletionProvider {
|
|
||||||
return &fakePodDeletionProvider{
|
|
||||||
pods: make(map[types.UID]struct{}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fakePodDeletionProvider) IsPodDeleted(uid types.UID) bool {
|
|
||||||
_, found := f.pods[uid]
|
|
||||||
return !found
|
|
||||||
}
|
|
||||||
|
|
||||||
type fakeUnitGetter struct {
|
|
||||||
networkNamespace kubecontainer.ContainerID
|
|
||||||
}
|
|
||||||
|
|
||||||
func newfakeUnitGetter() *fakeUnitGetter {
|
|
||||||
return &fakeUnitGetter{
|
|
||||||
networkNamespace: kubecontainer.ContainerID{},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fakeUnitGetter) getNetworkNamespace(uid types.UID, latestPod *rktapi.Pod) (kubecontainer.ContainerID, error) {
|
|
||||||
return kubecontainer.ContainerID{ID: "42"}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fakeUnitGetter) getKubernetesDirective(serviceFilePath string) (podServiceDirective, error) {
|
|
||||||
podService := podServiceDirective{
|
|
||||||
id: "fake",
|
|
||||||
name: "fake",
|
|
||||||
namespace: "fake",
|
|
||||||
hostNetwork: true,
|
|
||||||
networkNamespace: kubecontainer.ContainerID{ID: "42"},
|
|
||||||
}
|
|
||||||
return podService, nil
|
|
||||||
}
|
|
@ -1,294 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2015 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// This file contains all image related functions for rkt runtime.
|
|
||||||
package rkt
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"path/filepath"
|
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
appcschema "github.com/appc/spec/schema"
|
|
||||||
appctypes "github.com/appc/spec/schema/types"
|
|
||||||
rktapi "github.com/coreos/rkt/api/v1alpha"
|
|
||||||
dockertypes "github.com/docker/docker/api/types"
|
|
||||||
"github.com/golang/glog"
|
|
||||||
|
|
||||||
"k8s.io/api/core/v1"
|
|
||||||
"k8s.io/kubernetes/pkg/credentialprovider"
|
|
||||||
credentialprovidersecrets "k8s.io/kubernetes/pkg/credentialprovider/secrets"
|
|
||||||
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
|
||||||
"k8s.io/kubernetes/pkg/util/parsers"
|
|
||||||
)
|
|
||||||
|
|
||||||
// PullImage invokes 'rkt fetch' to download an aci.
|
|
||||||
// TODO(yifan): Now we only support docker images, this should be changed
|
|
||||||
// once the format of image is landed, see:
|
|
||||||
//
|
|
||||||
// http://issue.k8s.io/7203
|
|
||||||
//
|
|
||||||
func (r *Runtime) PullImage(image kubecontainer.ImageSpec, pullSecrets []v1.Secret) (string, error) {
|
|
||||||
img := image.Image
|
|
||||||
// TODO(yifan): The credential operation is a copy from dockertools package,
|
|
||||||
// Need to resolve the code duplication.
|
|
||||||
repoToPull, _, _, err := parsers.ParseImageName(img)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
keyring, err := credentialprovidersecrets.MakeDockerKeyring(pullSecrets, r.dockerKeyring)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
creds, ok := keyring.Lookup(repoToPull)
|
|
||||||
if !ok {
|
|
||||||
glog.V(1).Infof("Pulling image %s without credentials", img)
|
|
||||||
}
|
|
||||||
|
|
||||||
userConfigDir, err := ioutil.TempDir("", "rktnetes-user-config-dir-")
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("rkt: Cannot create a temporary user-config directory: %v", err)
|
|
||||||
}
|
|
||||||
defer os.RemoveAll(userConfigDir)
|
|
||||||
|
|
||||||
config := *r.config
|
|
||||||
config.UserConfigDir = userConfigDir
|
|
||||||
|
|
||||||
if err := r.writeDockerAuthConfig(img, creds, userConfigDir); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Today, `--no-store` will fetch the remote image regardless of whether the content of the image
|
|
||||||
// has changed or not. This causes performance downgrades when the image tag is ':latest' and
|
|
||||||
// the image pull policy is 'always'. The issue is tracked in https://github.com/coreos/rkt/issues/2937.
|
|
||||||
if _, err := r.cli.RunCommand(&config, "fetch", "--no-store", dockerPrefix+img); err != nil {
|
|
||||||
glog.Errorf("Failed to fetch: %v", err)
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return r.getImageID(img)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Runtime) GetImageRef(image kubecontainer.ImageSpec) (string, error) {
|
|
||||||
images, err := r.listImages(image.Image, false)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
if len(images) == 0 {
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
return images[0].Id, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListImages lists all the available appc images on the machine by invoking 'rkt image list'.
|
|
||||||
func (r *Runtime) ListImages() ([]kubecontainer.Image, error) {
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), r.requestTimeout)
|
|
||||||
defer cancel()
|
|
||||||
listResp, err := r.apisvc.ListImages(ctx, &rktapi.ListImagesRequest{})
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("couldn't list images: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
images := make([]kubecontainer.Image, len(listResp.Images))
|
|
||||||
for i, image := range listResp.Images {
|
|
||||||
images[i] = kubecontainer.Image{
|
|
||||||
ID: image.Id,
|
|
||||||
RepoTags: []string{buildImageName(image)},
|
|
||||||
Size: image.Size,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return images, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoveImage removes an on-disk image using 'rkt image rm'.
|
|
||||||
func (r *Runtime) RemoveImage(image kubecontainer.ImageSpec) error {
|
|
||||||
imageID, err := r.getImageID(image.Image)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if _, err := r.cli.RunCommand(nil, "image", "rm", imageID); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// buildImageName constructs the image name for kubecontainer.Image.
|
|
||||||
// If the annotations contain the docker2aci metadata for this image, those are
|
|
||||||
// used instead as they may be more accurate in some cases, namely if a
|
|
||||||
// non-appc valid character is present
|
|
||||||
func buildImageName(img *rktapi.Image) string {
|
|
||||||
registry := ""
|
|
||||||
repository := ""
|
|
||||||
for _, anno := range img.Annotations {
|
|
||||||
if anno.Key == appcDockerRegistryURL {
|
|
||||||
registry = anno.Value
|
|
||||||
}
|
|
||||||
if anno.Key == appcDockerRepository {
|
|
||||||
repository = anno.Value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if registry != "" && repository != "" {
|
|
||||||
// TODO(euank): This could do the special casing for dockerhub and library images
|
|
||||||
return fmt.Sprintf("%s/%s:%s", registry, repository, img.Version)
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Sprintf("%s:%s", img.Name, img.Version)
|
|
||||||
}
|
|
||||||
|
|
||||||
// getImageID tries to find the image ID for the given image name.
|
|
||||||
// imageName should be in the form of 'name[:version]', e.g., 'example.com/app:latest'.
|
|
||||||
// The name should matches the result of 'rkt image list'. If the version is empty,
|
|
||||||
// then 'latest' is assumed.
|
|
||||||
func (r *Runtime) getImageID(imageName string) (string, error) {
|
|
||||||
images, err := r.listImages(imageName, false)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
if len(images) == 0 {
|
|
||||||
return "", fmt.Errorf("cannot find the image %q", imageName)
|
|
||||||
}
|
|
||||||
return images[0].Id, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type sortByImportTime []*rktapi.Image
|
|
||||||
|
|
||||||
func (s sortByImportTime) Len() int { return len(s) }
|
|
||||||
func (s sortByImportTime) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
|
||||||
func (s sortByImportTime) Less(i, j int) bool { return s[i].ImportTimestamp < s[j].ImportTimestamp }
|
|
||||||
|
|
||||||
// listImages lists the images that have the given name. If detail is true,
|
|
||||||
// then image manifest is also included in the result.
|
|
||||||
// Note that there could be more than one images that have the given name, we
|
|
||||||
// will return the result reversely sorted by the import time, so that the latest
|
|
||||||
// image comes first.
|
|
||||||
func (r *Runtime) listImages(image string, detail bool) ([]*rktapi.Image, error) {
|
|
||||||
repoToPull, tag, _, err := parsers.ParseImageName(image)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
imageFilters := []*rktapi.ImageFilter{
|
|
||||||
{
|
|
||||||
// TODO(yifan): Add a field in the ImageFilter to match the whole name,
|
|
||||||
// not just keywords.
|
|
||||||
// https://github.com/coreos/rkt/issues/1872#issuecomment-166456938
|
|
||||||
Keywords: []string{repoToPull},
|
|
||||||
Labels: []*rktapi.KeyValue{{Key: "version", Value: tag}},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the repo name is not a valid ACIdentifier (namely if it has a port),
|
|
||||||
// then it will have a different name in the store. Search for both the
|
|
||||||
// original name and this modified name in case we choose to also change the
|
|
||||||
// api-service to do this un-conversion on its end.
|
|
||||||
if appcRepoToPull, err := appctypes.SanitizeACIdentifier(repoToPull); err != nil {
|
|
||||||
glog.Warningf("could not convert %v to an aci identifier: %v", err)
|
|
||||||
} else {
|
|
||||||
imageFilters = append(imageFilters, &rktapi.ImageFilter{
|
|
||||||
Keywords: []string{appcRepoToPull},
|
|
||||||
Labels: []*rktapi.KeyValue{{Key: "version", Value: tag}},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), r.requestTimeout)
|
|
||||||
defer cancel()
|
|
||||||
listResp, err := r.apisvc.ListImages(ctx, &rktapi.ListImagesRequest{
|
|
||||||
Detail: detail,
|
|
||||||
Filters: imageFilters,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("couldn't list images: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(yifan): Let the API service to sort the result:
|
|
||||||
// See https://github.com/coreos/rkt/issues/1911.
|
|
||||||
sort.Sort(sort.Reverse(sortByImportTime(listResp.Images)))
|
|
||||||
return listResp.Images, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// getImageManifest retrieves the image manifest for the given image.
|
|
||||||
func (r *Runtime) getImageManifest(image string) (*appcschema.ImageManifest, error) {
|
|
||||||
var manifest appcschema.ImageManifest
|
|
||||||
|
|
||||||
images, err := r.listImages(image, true)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if len(images) == 0 {
|
|
||||||
return nil, fmt.Errorf("cannot find the image %q", image)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &manifest, json.Unmarshal(images[0].Manifest, &manifest)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO(yifan): This is very racy, inefficient, and unsafe, we need to provide
|
|
||||||
// different namespaces. See: https://github.com/coreos/rkt/issues/836.
|
|
||||||
func (r *Runtime) writeDockerAuthConfig(image string, credsSlice []credentialprovider.LazyAuthConfiguration, userConfigDir string) error {
|
|
||||||
if len(credsSlice) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
creds := dockertypes.AuthConfig{}
|
|
||||||
// TODO handle multiple creds
|
|
||||||
if len(credsSlice) >= 1 {
|
|
||||||
creds = credentialprovider.LazyProvide(credsSlice[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
registry := "index.docker.io"
|
|
||||||
// Image spec: [<registry>/]<repository>/<image>[:<version]
|
|
||||||
explicitRegistry := (strings.Count(image, "/") == 2)
|
|
||||||
if explicitRegistry {
|
|
||||||
registry = strings.Split(image, "/")[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
authDir := filepath.Join(userConfigDir, "auth.d")
|
|
||||||
if _, err := os.Stat(authDir); os.IsNotExist(err) {
|
|
||||||
if err := os.MkdirAll(authDir, 0600); err != nil {
|
|
||||||
glog.Errorf("rkt: Cannot create auth dir: %v", err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
config := fmt.Sprintf(dockerAuthTemplate, registry, creds.Username, creds.Password)
|
|
||||||
if err := ioutil.WriteFile(path.Join(authDir, registry+".json"), []byte(config), 0600); err != nil {
|
|
||||||
glog.Errorf("rkt: Cannot write docker auth config file: %v", err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ImageStats returns the image stat (total storage bytes).
|
|
||||||
func (r *Runtime) ImageStats() (*kubecontainer.ImageStats, error) {
|
|
||||||
var imageStat kubecontainer.ImageStats
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), r.requestTimeout)
|
|
||||||
defer cancel()
|
|
||||||
listResp, err := r.apisvc.ListImages(ctx, &rktapi.ListImagesRequest{})
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("couldn't list images: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, image := range listResp.Images {
|
|
||||||
imageStat.TotalStorageBytes = imageStat.TotalStorageBytes + uint64(image.Size)
|
|
||||||
}
|
|
||||||
return &imageStat, nil
|
|
||||||
}
|
|
@ -1,123 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2015 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 rkt
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/golang/glog"
|
|
||||||
|
|
||||||
rktapi "github.com/coreos/rkt/api/v1alpha"
|
|
||||||
"k8s.io/api/core/v1"
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
||||||
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
|
|
||||||
"k8s.io/kubernetes/pkg/kubelet/util/format"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
journalTimestampLayout = "2006-01-02 15:04:05 -0700 MST"
|
|
||||||
)
|
|
||||||
|
|
||||||
// processLines write the lines into stdout in the required format.
|
|
||||||
func processLines(lines []string, logOptions *v1.PodLogOptions, stdout, stderr io.Writer) {
|
|
||||||
msgKey := "MESSAGE="
|
|
||||||
|
|
||||||
for _, line := range lines {
|
|
||||||
msgStart := strings.Index(line, msgKey)
|
|
||||||
if msgStart < 0 {
|
|
||||||
glog.Warningf("rkt: Invalid log line %q, missing %q", line, msgKey)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
tss := strings.TrimSpace(line[:msgStart])
|
|
||||||
msg := strings.TrimPrefix(line[msgStart:], msgKey)
|
|
||||||
|
|
||||||
t, err := time.Parse(journalTimestampLayout, tss)
|
|
||||||
if err != nil {
|
|
||||||
glog.Warningf("rkt: Failed to parse the timestamp %q: %v", tss, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
var result string
|
|
||||||
if logOptions.Timestamps {
|
|
||||||
result = fmt.Sprintf("%s %s\n", t.Format(time.RFC3339), msg)
|
|
||||||
} else {
|
|
||||||
result = fmt.Sprintf("%s\n", msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := io.WriteString(stdout, result); err != nil {
|
|
||||||
glog.Warningf("rkt: Cannot write log line %q to output: %v", result, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetContainerLogs uses rkt's GetLogs API to get the logs of the container.
|
|
||||||
// By default, it returns a snapshot of the container log. Set |follow| to true to
|
|
||||||
// stream the log. Set |follow| to false and specify the number of lines (e.g.
|
|
||||||
// "100" or "all") to tail the log.
|
|
||||||
//
|
|
||||||
// TODO(yifan): This doesn't work with lkvm stage1 yet.
|
|
||||||
func (r *Runtime) GetContainerLogs(pod *v1.Pod, containerID kubecontainer.ContainerID, logOptions *v1.PodLogOptions, stdout, stderr io.Writer) error {
|
|
||||||
id, err := parseContainerID(containerID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var since int64
|
|
||||||
if logOptions.SinceSeconds != nil {
|
|
||||||
t := metav1.Now().Add(-time.Duration(*logOptions.SinceSeconds) * time.Second)
|
|
||||||
since = t.Unix()
|
|
||||||
}
|
|
||||||
if logOptions.SinceTime != nil {
|
|
||||||
since = logOptions.SinceTime.Unix()
|
|
||||||
}
|
|
||||||
|
|
||||||
getLogsRequest := &rktapi.GetLogsRequest{
|
|
||||||
PodId: id.uuid,
|
|
||||||
AppName: id.appName,
|
|
||||||
Follow: logOptions.Follow,
|
|
||||||
SinceTime: since,
|
|
||||||
}
|
|
||||||
|
|
||||||
if logOptions.TailLines != nil {
|
|
||||||
getLogsRequest.Lines = int32(*logOptions.TailLines)
|
|
||||||
}
|
|
||||||
|
|
||||||
stream, err := r.apisvc.GetLogs(context.Background(), getLogsRequest)
|
|
||||||
if err != nil {
|
|
||||||
glog.Errorf("rkt: Failed to create log stream for pod %q: %v", format.Pod(pod), err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for {
|
|
||||||
log, err := stream.Recv()
|
|
||||||
if err == io.EOF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
glog.Errorf("rkt: Failed to receive log for pod %q: %v", format.Pod(pod), err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
processLines(log.Lines, logOptions, stdout, stderr)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,92 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2015 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 rkt
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/coreos/go-systemd/dbus"
|
|
||||||
)
|
|
||||||
|
|
||||||
// systemdVersion is a type wraps the int to implement kubecontainer.Version interface.
|
|
||||||
type systemdVersion int
|
|
||||||
|
|
||||||
func (s systemdVersion) String() string {
|
|
||||||
return fmt.Sprintf("%d", s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s systemdVersion) Compare(other string) (int, error) {
|
|
||||||
v, err := strconv.Atoi(other)
|
|
||||||
if err != nil {
|
|
||||||
return -1, err
|
|
||||||
}
|
|
||||||
if int(s) < v {
|
|
||||||
return -1, nil
|
|
||||||
} else if int(s) > v {
|
|
||||||
return 1, nil
|
|
||||||
}
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// systemdInterface is an abstraction of the go-systemd/dbus to make
|
|
||||||
// it mockable for testing.
|
|
||||||
// TODO(yifan): Eventually we should move these functionalities to:
|
|
||||||
// 1. a package for launching/stopping rkt pods.
|
|
||||||
// 2. rkt api-service interface for listing pods.
|
|
||||||
// See https://github.com/coreos/rkt/issues/1769.
|
|
||||||
type systemdInterface interface {
|
|
||||||
// Version returns the version of the systemd.
|
|
||||||
Version() (systemdVersion, error)
|
|
||||||
// ListUnits lists all the loaded units.
|
|
||||||
ListUnits() ([]dbus.UnitStatus, error)
|
|
||||||
// StopUnits stops the unit with the given name.
|
|
||||||
StopUnit(name string, mode string, ch chan<- string) (int, error)
|
|
||||||
// RestartUnit restarts the unit with the given name.
|
|
||||||
RestartUnit(name string, mode string, ch chan<- string) (int, error)
|
|
||||||
// ResetFailedUnit resets the "failed" state of a specific unit.
|
|
||||||
ResetFailedUnit(name string) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// systemd implements the systemdInterface using dbus and systemctl.
|
|
||||||
// All the functions other then Version() are already implemented by go-systemd/dbus.
|
|
||||||
type systemd struct {
|
|
||||||
*dbus.Conn
|
|
||||||
}
|
|
||||||
|
|
||||||
// newSystemd creates a systemd object that implements systemdInterface.
|
|
||||||
func newSystemd() (*systemd, error) {
|
|
||||||
dbusConn, err := dbus.New()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &systemd{dbusConn}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Version returns the version of the systemd.
|
|
||||||
func (s *systemd) Version() (systemdVersion, error) {
|
|
||||||
versionStr, err := s.Conn.GetManagerProperty("Version")
|
|
||||||
if err != nil {
|
|
||||||
return -1, err
|
|
||||||
}
|
|
||||||
result, err := strconv.Atoi(strings.Trim(versionStr, "\""))
|
|
||||||
if err != nil {
|
|
||||||
return -1, err
|
|
||||||
}
|
|
||||||
return systemdVersion(result), nil
|
|
||||||
}
|
|
@ -1,111 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2015 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 rkt
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
rktapi "github.com/coreos/rkt/api/v1alpha"
|
|
||||||
|
|
||||||
utilversion "k8s.io/kubernetes/pkg/util/version"
|
|
||||||
)
|
|
||||||
|
|
||||||
type versions struct {
|
|
||||||
sync.RWMutex
|
|
||||||
binVersion *utilversion.Version
|
|
||||||
apiVersion *utilversion.Version
|
|
||||||
systemdVersion systemdVersion
|
|
||||||
}
|
|
||||||
|
|
||||||
func newRktVersion(version string) (*utilversion.Version, error) {
|
|
||||||
return utilversion.ParseSemantic(version)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *Runtime) getVersions() error {
|
|
||||||
r.versions.Lock()
|
|
||||||
defer r.versions.Unlock()
|
|
||||||
|
|
||||||
// Get systemd version.
|
|
||||||
var err error
|
|
||||||
r.versions.systemdVersion, err = r.systemd.Version()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), r.requestTimeout)
|
|
||||||
defer cancel()
|
|
||||||
// Example for the version strings returned by GetInfo():
|
|
||||||
// RktVersion:"0.10.0+gitb7349b1" AppcVersion:"0.7.1" ApiVersion:"1.0.0-alpha"
|
|
||||||
resp, err := r.apisvc.GetInfo(ctx, &rktapi.GetInfoRequest{})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get rkt binary version.
|
|
||||||
r.versions.binVersion, err = newRktVersion(resp.Info.RktVersion)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get rkt API version.
|
|
||||||
r.versions.apiVersion, err = newRktVersion(resp.Info.ApiVersion)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// checkVersion tests whether the rkt/systemd/rkt-api-service that meet the version requirement.
|
|
||||||
// If all version requirements are met, it returns nil.
|
|
||||||
func (r *Runtime) checkVersion(minimumRktBinVersion, minimumRktApiVersion, minimumSystemdVersion string) error {
|
|
||||||
if err := r.getVersions(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
r.versions.RLock()
|
|
||||||
defer r.versions.RUnlock()
|
|
||||||
|
|
||||||
// Check systemd version.
|
|
||||||
result, err := r.versions.systemdVersion.Compare(minimumSystemdVersion)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if result < 0 {
|
|
||||||
return fmt.Errorf("rkt: systemd version(%v) is too old, requires at least %v", r.versions.systemdVersion, minimumSystemdVersion)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check rkt binary version.
|
|
||||||
result, err = r.versions.binVersion.Compare(minimumRktBinVersion)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if result < 0 {
|
|
||||||
return fmt.Errorf("rkt: binary version is too old(%v), requires at least %v", r.versions.binVersion, minimumRktBinVersion)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check rkt API version.
|
|
||||||
result, err = r.versions.apiVersion.Compare(minimumRktApiVersion)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if result < 0 {
|
|
||||||
return fmt.Errorf("rkt: API version is too old(%v), requires at least %v", r.versions.apiVersion, minimumRktApiVersion)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
@ -31,7 +31,6 @@ const (
|
|||||||
dockerMinimumAPIVersion = "1.24.0"
|
dockerMinimumAPIVersion = "1.24.0"
|
||||||
|
|
||||||
dockerTypeName = "docker"
|
dockerTypeName = "docker"
|
||||||
rktTypeName = "rkt"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: The admission logic in this file is runtime-dependent. It should be
|
// TODO: The admission logic in this file is runtime-dependent. It should be
|
||||||
@ -72,14 +71,6 @@ func NewRuntimeAdmitHandler(runtime container.Runtime) (*runtimeAdmitHandler, er
|
|||||||
Message: "Docker API version before 1.24 does not support sysctls",
|
Message: "Docker API version before 1.24 does not support sysctls",
|
||||||
},
|
},
|
||||||
}, nil
|
}, nil
|
||||||
case rktTypeName:
|
|
||||||
return &runtimeAdmitHandler{
|
|
||||||
result: lifecycle.PodAdmitResult{
|
|
||||||
Admit: false,
|
|
||||||
Reason: UnsupportedReason,
|
|
||||||
Message: "Rkt does not support sysctls",
|
|
||||||
},
|
|
||||||
}, nil
|
|
||||||
default:
|
default:
|
||||||
// Return admit for other runtimes.
|
// Return admit for other runtimes.
|
||||||
return &runtimeAdmitHandler{
|
return &runtimeAdmitHandler{
|
||||||
|
@ -22,7 +22,6 @@ const (
|
|||||||
|
|
||||||
// different container runtimes
|
// different container runtimes
|
||||||
DockerContainerRuntime = "docker"
|
DockerContainerRuntime = "docker"
|
||||||
RktContainerRuntime = "rkt"
|
|
||||||
RemoteContainerRuntime = "remote"
|
RemoteContainerRuntime = "remote"
|
||||||
|
|
||||||
// User visible keys for managing node allocatable enforcement on the node.
|
// User visible keys for managing node allocatable enforcement on the node.
|
||||||
|
Loading…
Reference in New Issue
Block a user