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:
Filipe Brandenburger 2018-03-20 13:29:40 -07:00
parent 90c09c75d6
commit 8df9274e02
22 changed files with 107 additions and 6203 deletions

View File

@ -29,8 +29,6 @@ const (
// When these values are updated, also update test/e2e/framework/util.go
defaultPodSandboxImageName = "k8s.gcr.io/pause"
defaultPodSandboxImageVersion = "3.1"
// From pkg/kubelet/rkt/rkt.go to avoid circular import
defaultRktAPIServiceEndpoint = "localhost:15441"
)
var (
@ -54,7 +52,6 @@ func NewContainerRuntimeOptions() *config.ContainerRuntimeOptions {
DockerDisableSharedPID: true,
PodSandboxImage: defaultPodSandboxImage,
ImagePullProgressDeadline: metav1.Duration{Duration: 1 * time.Minute},
RktAPIEndpoint: defaultRktAPIServiceEndpoint,
ExperimentalDockershim: false,
}
}

View File

@ -196,7 +196,6 @@ pkg/kubelet/prober/results
pkg/kubelet/prober/testing
pkg/kubelet/qos
pkg/kubelet/remote
pkg/kubelet/rkt
pkg/kubelet/secret
pkg/kubelet/server
pkg/kubelet/server/portforward

View File

@ -74,7 +74,6 @@ go_library(
"//pkg/kubelet/prober:go_default_library",
"//pkg/kubelet/prober/results:go_default_library",
"//pkg/kubelet/remote:go_default_library",
"//pkg/kubelet/rkt:go_default_library",
"//pkg/kubelet/secret:go_default_library",
"//pkg/kubelet/server:go_default_library",
"//pkg/kubelet/server/portforward:go_default_library",
@ -281,7 +280,6 @@ filegroup(
"//pkg/kubelet/prober:all-srcs",
"//pkg/kubelet/qos:all-srcs",
"//pkg/kubelet/remote:all-srcs",
"//pkg/kubelet/rkt:all-srcs",
"//pkg/kubelet/secret:all-srcs",
"//pkg/kubelet/server:all-srcs",
"//pkg/kubelet/stats:all-srcs",

View File

@ -38,8 +38,6 @@ func (i *imageFsInfoProvider) ImageFsInfoLabel() (string, error) {
switch i.runtime {
case types.DockerContainerRuntime:
return cadvisorfs.LabelDockerImages, nil
case types.RktContainerRuntime:
return cadvisorfs.LabelRktImages, nil
case types.RemoteContainerRuntime:
// This is a temporary workaround to get stats for cri-o from cadvisor
// and should be removed.

View File

@ -75,7 +75,6 @@ func EphemeralStorageCapacityFromFsInfo(info cadvisorapi2.FsInfo) v1.ResourceLis
// https://github.com/kubernetes/kubernetes/issues/51798
// UsingLegacyCadvisorStats returns true if container stats are provided by cadvisor instead of through the CRI
func UsingLegacyCadvisorStats(runtime, runtimeEndpoint string) bool {
return runtime == kubetypes.RktContainerRuntime ||
(runtime == kubetypes.DockerContainerRuntime && goruntime.GOOS == "linux") ||
return (runtime == kubetypes.DockerContainerRuntime && goruntime.GOOS == "linux") ||
runtimeEndpoint == CrioSocket
}

View File

@ -67,16 +67,6 @@ type ContainerRuntimeOptions struct {
// CNIBinDir is the full path of the directory in which to search for
// CNI plugin binaries
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) {
@ -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.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.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.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).")
}

View File

@ -87,7 +87,6 @@ import (
"k8s.io/kubernetes/pkg/kubelet/prober"
proberesults "k8s.io/kubernetes/pkg/kubelet/prober/results"
"k8s.io/kubernetes/pkg/kubelet/remote"
"k8s.io/kubernetes/pkg/kubelet/rkt"
"k8s.io/kubernetes/pkg/kubelet/secret"
"k8s.io/kubernetes/pkg/kubelet/server"
serverstats "k8s.io/kubernetes/pkg/kubelet/server/stats"
@ -600,145 +599,104 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration,
var nl *NoOpLegacyHost
pluginSettings.LegacyRuntimeHost = nl
if containerRuntime == kubetypes.RktContainerRuntime {
glog.Warningln("rktnetes has been deprecated in favor of rktlet. Please see https://github.com/kubernetes-incubator/rktlet for more information.")
if containerRuntime == "rkt" {
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.
if containerRuntime != kubetypes.RktContainerRuntime {
// kubelet defers to the runtime shim to setup networking. Setting
// this to nil will prevent it from trying to invoke the plugin.
// It's easier to always probe and initialize plugins till cri
// becomes the default.
klet.networkPlugin = nil
// if left at nil, that means it is unneeded
var legacyLogProvider kuberuntime.LegacyLogProvider
// kubelet defers to the runtime shim to setup networking. Setting
// this to nil will prevent it from trying to invoke the plugin.
// It's easier to always probe and initialize plugins till cri
// becomes the default.
klet.networkPlugin = nil
// if left at nil, that means it is unneeded
var legacyLogProvider kuberuntime.LegacyLogProvider
switch containerRuntime {
case kubetypes.DockerContainerRuntime:
// Create and start the CRI shim running as a grpc server.
streamingConfig := getStreamingConfig(kubeCfg, kubeDeps)
ds, err := dockershim.NewDockerService(kubeDeps.DockerClientConfig, crOptions.PodSandboxImage, streamingConfig,
&pluginSettings, runtimeCgroups, kubeCfg.CgroupDriver, crOptions.DockershimRootDirectory,
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)
switch containerRuntime {
case kubetypes.DockerContainerRuntime:
// Create and start the CRI shim running as a grpc server.
streamingConfig := getStreamingConfig(kubeCfg, kubeDeps)
ds, err := dockershim.NewDockerService(kubeDeps.DockerClientConfig, crOptions.PodSandboxImage, streamingConfig,
&pluginSettings, runtimeCgroups, kubeCfg.CgroupDriver, crOptions.DockershimRootDirectory,
crOptions.DockerDisableSharedPID)
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
// For now, the CRI shim redirects the streaming requests to the
// kubelet, which handles the requests using DockerService..
klet.criHandler = ds
if cadvisor.UsingLegacyCadvisorStats(containerRuntime, remoteRuntimeEndpoint) {
klet.StatsProvider = stats.NewCadvisorStatsProvider(
klet.cadvisor,
klet.resourceAnalyzer,
klet.podManager,
klet.runtimeCache,
klet.containerRuntime)
} else {
klet.StatsProvider = stats.NewCRIStatsProvider(
klet.cadvisor,
klet.resourceAnalyzer,
klet.podManager,
klet.runtimeCache,
runtimeService,
imageService,
stats.NewLogMetricsService())
// 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
}
} else {
// rkt uses the legacy, non-CRI, integration. Configure it the old way.
// TODO: Include hairpin mode settings in rkt?
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,
)
// Create dockerLegacyService when the logging driver is not supported.
supported, err := ds.IsCRISupportedLogDriver()
if err != nil {
return nil, err
}
klet.containerRuntime = runtime
klet.runner = kubecontainer.DirectStreamingRunner(runtime)
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 {
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.cadvisor,
klet.resourceAnalyzer,
klet.podManager,
klet.runtimeCache,
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{})
@ -2108,34 +2066,30 @@ func (kl *Kubelet) updateRuntimeUp() {
glog.Errorf("Container runtime sanity check failed: %v", err)
return
}
// rkt uses the legacy, non-CRI integration. Don't check the runtime
// conditions for it.
if kl.containerRuntimeName != kubetypes.RktContainerRuntime {
if s == nil {
glog.Errorf("Container runtime status is nil")
return
}
// Periodically log the whole runtime status for debugging.
// TODO(random-liu): Consider to send node event when optional
// condition is unmet.
glog.V(4).Infof("Container runtime status: %v", s)
networkReady := s.GetRuntimeCondition(kubecontainer.NetworkReady)
if networkReady == nil || !networkReady.Status {
glog.Errorf("Container runtime network not ready: %v", networkReady)
kl.runtimeState.setNetworkState(fmt.Errorf("runtime network not ready: %v", networkReady))
} else {
// Set nil if the container runtime network is ready.
kl.runtimeState.setNetworkState(nil)
}
// TODO(random-liu): Add runtime error in runtimeState, and update it
// when runtime is not ready, so that the information in RuntimeReady
// condition will be propagated to NodeReady condition.
runtimeReady := s.GetRuntimeCondition(kubecontainer.RuntimeReady)
// If RuntimeReady is not set or is false, report an error.
if runtimeReady == nil || !runtimeReady.Status {
glog.Errorf("Container runtime not ready: %v", runtimeReady)
return
}
if s == nil {
glog.Errorf("Container runtime status is nil")
return
}
// Periodically log the whole runtime status for debugging.
// TODO(random-liu): Consider to send node event when optional
// condition is unmet.
glog.V(4).Infof("Container runtime status: %v", s)
networkReady := s.GetRuntimeCondition(kubecontainer.NetworkReady)
if networkReady == nil || !networkReady.Status {
glog.Errorf("Container runtime network not ready: %v", networkReady)
kl.runtimeState.setNetworkState(fmt.Errorf("runtime network not ready: %v", networkReady))
} else {
// Set nil if the container runtime network is ready.
kl.runtimeState.setNetworkState(nil)
}
// TODO(random-liu): Add runtime error in runtimeState, and update it
// when runtime is not ready, so that the information in RuntimeReady
// condition will be propagated to NodeReady condition.
runtimeReady := s.GetRuntimeCondition(kubecontainer.RuntimeReady)
// If RuntimeReady is not set or is false, report an error.
if runtimeReady == nil || !runtimeReady.Status {
glog.Errorf("Container runtime not ready: %v", runtimeReady)
return
}
kl.oneTimeInitializer.Do(kl.initializeRuntimeDependentModules)
kl.runtimeState.setRuntimeSync(kl.clock.Now())

View File

@ -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"],
)

View File

@ -1,3 +0,0 @@
approvers:
- euank
- yifan-gu

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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"

View File

@ -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
}

View File

@ -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
}

View File

@ -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

View File

@ -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
}

View File

@ -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
}

View File

@ -31,7 +31,6 @@ const (
dockerMinimumAPIVersion = "1.24.0"
dockerTypeName = "docker"
rktTypeName = "rkt"
)
// 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",
},
}, nil
case rktTypeName:
return &runtimeAdmitHandler{
result: lifecycle.PodAdmitResult{
Admit: false,
Reason: UnsupportedReason,
Message: "Rkt does not support sysctls",
},
}, nil
default:
// Return admit for other runtimes.
return &runtimeAdmitHandler{

View File

@ -22,7 +22,6 @@ const (
// different container runtimes
DockerContainerRuntime = "docker"
RktContainerRuntime = "rkt"
RemoteContainerRuntime = "remote"
// User visible keys for managing node allocatable enforcement on the node.