kubelet/rkt: add support for different stage1 image.

Also enable grace stop for service files.
This commit is contained in:
Yifan Gu 2015-08-31 19:25:26 -07:00
parent c0d0ef6dd1
commit e7b9c50ba1
6 changed files with 309 additions and 284 deletions

View File

@ -119,6 +119,7 @@ type KubeletServer struct {
ResolverConfig string ResolverConfig string
ResourceContainer string ResourceContainer string
RktPath string RktPath string
RktStage1Image string
RootDirectory string RootDirectory string
RunOnce bool RunOnce bool
StandaloneMode bool StandaloneMode bool
@ -189,6 +190,7 @@ func NewKubeletServer() *KubeletServer {
RegistryBurst: 10, RegistryBurst: 10,
ResourceContainer: "/kubelet", ResourceContainer: "/kubelet",
RktPath: "", RktPath: "",
RktStage1Image: "",
RootDirectory: defaultRootDir, RootDirectory: defaultRootDir,
SyncFrequency: 10 * time.Second, SyncFrequency: 10 * time.Second,
SystemContainer: "", SystemContainer: "",
@ -254,6 +256,7 @@ func (s *KubeletServer) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&s.CgroupRoot, "cgroup-root", s.CgroupRoot, "Optional root cgroup to use for pods. This is handled by the container runtime on a best effort basis. Default: '', which means use the container runtime default.") fs.StringVar(&s.CgroupRoot, "cgroup-root", s.CgroupRoot, "Optional root cgroup to use for pods. This is handled by the container runtime on a best effort basis. Default: '', which means use the container runtime default.")
fs.StringVar(&s.ContainerRuntime, "container-runtime", s.ContainerRuntime, "The container runtime to use. Possible values: 'docker', 'rkt'. Default: 'docker'.") fs.StringVar(&s.ContainerRuntime, "container-runtime", s.ContainerRuntime, "The container runtime to use. Possible values: 'docker', 'rkt'. Default: 'docker'.")
fs.StringVar(&s.RktPath, "rkt-path", s.RktPath, "Path of rkt binary. Leave empty to use the first rkt in $PATH. Only used if --container-runtime='rkt'") fs.StringVar(&s.RktPath, "rkt-path", s.RktPath, "Path of rkt binary. Leave empty to use the first rkt in $PATH. Only used if --container-runtime='rkt'")
fs.StringVar(&s.RktStage1Image, "rkt-stage1-image", s.RktStage1Image, "image to use as stage1. Local paths and http/https URLs are supported. If empty, the 'stage1.aci' in the same directory as '--rkt-path' will be used")
fs.StringVar(&s.SystemContainer, "system-container", s.SystemContainer, "Optional resource-only container in which to place all non-kernel processes that are not already in a container. Empty for no container. Rolling back the flag requires a reboot. (Default: \"\").") fs.StringVar(&s.SystemContainer, "system-container", s.SystemContainer, "Optional resource-only container in which to place all non-kernel processes that are not already in a container. Empty for no container. Rolling back the flag requires a reboot. (Default: \"\").")
fs.BoolVar(&s.ConfigureCBR0, "configure-cbr0", s.ConfigureCBR0, "If true, kubelet will configure cbr0 based on Node.Spec.PodCIDR.") fs.BoolVar(&s.ConfigureCBR0, "configure-cbr0", s.ConfigureCBR0, "If true, kubelet will configure cbr0 based on Node.Spec.PodCIDR.")
fs.IntVar(&s.MaxPods, "max-pods", 40, "Number of Pods that can run on this Kubelet.") fs.IntVar(&s.MaxPods, "max-pods", 40, "Number of Pods that can run on this Kubelet.")
@ -364,6 +367,7 @@ func (s *KubeletServer) KubeletConfig() (*KubeletConfig, error) {
ResolverConfig: s.ResolverConfig, ResolverConfig: s.ResolverConfig,
ResourceContainer: s.ResourceContainer, ResourceContainer: s.ResourceContainer,
RktPath: s.RktPath, RktPath: s.RktPath,
RktStage1Image: s.RktStage1Image,
RootDirectory: s.RootDirectory, RootDirectory: s.RootDirectory,
Runonce: s.RunOnce, Runonce: s.RunOnce,
StandaloneMode: (len(s.APIServerList) == 0), StandaloneMode: (len(s.APIServerList) == 0),
@ -789,6 +793,7 @@ type KubeletConfig struct {
ResolverConfig string ResolverConfig string
ResourceContainer string ResourceContainer string
RktPath string RktPath string
RktStage1Image string
RootDirectory string RootDirectory string
Runonce bool Runonce bool
StandaloneMode bool StandaloneMode bool
@ -851,6 +856,7 @@ func createAndInitKubelet(kc *KubeletConfig) (k KubeletBootstrap, pc *config.Pod
kc.CgroupRoot, kc.CgroupRoot,
kc.ContainerRuntime, kc.ContainerRuntime,
kc.RktPath, kc.RktPath,
kc.RktStage1Image,
kc.Mounter, kc.Mounter,
kc.DockerDaemonContainer, kc.DockerDaemonContainer,
kc.SystemContainer, kc.SystemContainer,

View File

@ -325,6 +325,7 @@ func (ks *KubeletExecutorServer) createAndInitKubelet(
kc.CgroupRoot, kc.CgroupRoot,
kc.ContainerRuntime, kc.ContainerRuntime,
kc.RktPath, kc.RktPath,
kc.RktStage1Image,
kc.Mounter, kc.Mounter,
kc.DockerDaemonContainer, kc.DockerDaemonContainer,
kc.SystemContainer, kc.SystemContainer,

View File

@ -1,274 +1,275 @@
accept-hosts accept-hosts
accept-paths accept-paths
account-for-pod-resources account-for-pod-resources
admission-control admission-control
admission-control-config-file admission-control-config-file
advertise-address advertise-address
advertised-address advertised-address
algorithm-provider algorithm-provider
all-namespaces all-namespaces
allocate-node-cidrs allocate-node-cidrs
allow-privileged allow-privileged
api-burst api-burst
api-prefix api-prefix
api-rate api-rate
api-servers api-servers
api-token api-token
api-version api-version
authorization-mode authorization-mode
authorization-policy-file authorization-policy-file
auth-path auth-path
basic-auth-file basic-auth-file
bench-pods bench-pods
bench-quiet bench-quiet
bench-tasks bench-tasks
bench-workers bench-workers
bind-address bind-address
bind-pods-burst bind-pods-burst
bind-pods-qps bind-pods-qps
cadvisor-port cadvisor-port
cert-dir cert-dir
certificate-authority certificate-authority
cgroup-root cgroup-root
chaos-chance chaos-chance
cleanup-iptables cleanup-iptables
client-ca-file client-ca-file
client-certificate client-certificate
client-key client-key
cloud-config cloud-config
cloud-provider cloud-provider
cluster-cidr cluster-cidr
cluster-dns cluster-dns
cluster-domain cluster-domain
cluster-name cluster-name
cluster-tag cluster-tag
concurrent-endpoint-syncs concurrent-endpoint-syncs
configure-cbr0 configure-cbr0
contain-pod-resources contain-pod-resources
container-port container-port
container-runtime container-runtime
cors-allowed-origins cors-allowed-origins
create-external-load-balancer create-external-load-balancer
current-release-pr current-release-pr
current-replicas current-replicas
default-container-cpu-limit default-container-cpu-limit
default-container-mem-limit default-container-mem-limit
delay-shutdown delay-shutdown
deleting-pods-burst deleting-pods-burst
deleting-pods-qps deleting-pods-qps
deployment-label-key deployment-label-key
dest-file dest-file
disable-filter disable-filter
docker-endpoint docker-endpoint
docker-exec-handler docker-exec-handler
dockercfg-path dockercfg-path
driver-port driver-port
dry-run dry-run
duration-sec duration-sec
e2e-output-dir e2e-output-dir
enable-debugging-handlers enable-debugging-handlers
enable-horizontal-pod-autoscaler enable-horizontal-pod-autoscaler
enable-server enable-server
etcd-config etcd-config
etcd-prefix etcd-prefix
etcd-server etcd-server
etcd-servers etcd-servers
event-burst event-burst
event-qps event-qps
event-ttl event-ttl
executor-bindall executor-bindall
executor-logv executor-logv
executor-path executor-path
executor-suicide-timeout executor-suicide-timeout
experimental-keystone-url experimental-keystone-url
experimental-prefix experimental-prefix
external-hostname external-hostname
external-ip external-ip
failover-timeout failover-timeout
file-check-frequency file-check-frequency
file-suffix file-suffix
forward-services forward-services
framework-name framework-name
framework-weburi framework-weburi
func-dest func-dest
fuzz-iters fuzz-iters
gce-project gce-project
gce-zone gce-zone
gke-cluster gke-cluster
google-json-key google-json-key
grace-period grace-period
ha-domain ha-domain
healthz-bind-address healthz-bind-address
healthz-port healthz-port
horizontal-pod-autoscaler-sync-period horizontal-pod-autoscaler-sync-period
hostname-override hostname-override
host-network-sources host-network-sources
http-check-frequency http-check-frequency
http-port http-port
ignore-not-found ignore-not-found
image-gc-high-threshold image-gc-high-threshold
image-gc-low-threshold image-gc-low-threshold
insecure-bind-address insecure-bind-address
insecure-port insecure-port
insecure-skip-tls-verify insecure-skip-tls-verify
iptables-sync-period iptables-sync-period
ir-data-source ir-data-source
ir-dbname ir-dbname
ir-influxdb-host ir-influxdb-host
ir-password ir-password
ir-user ir-user
jenkins-host jenkins-host
jenkins-jobs jenkins-jobs
km-path km-path
kubectl-path kubectl-path
kubelet-cadvisor-port kubelet-cadvisor-port
kubelet-certificate-authority kubelet-certificate-authority
kubelet-client-certificate kubelet-client-certificate
kubelet-client-key kubelet-client-key
kubelet-docker-endpoint kubelet-docker-endpoint
kubelet-host-network-sources kubelet-host-network-sources
kubelet-https kubelet-https
kubelet-network-plugin kubelet-network-plugin
kubelet-pod-infra-container-image kubelet-pod-infra-container-image
kubelet-port kubelet-port
kubelet-root-dir kubelet-root-dir
kubelet-sync-frequency kubelet-sync-frequency
kubelet-timeout kubelet-timeout
kube-master kube-master
label-columns label-columns
last-release-pr last-release-pr
legacy-userspace-proxy legacy-userspace-proxy
log-flush-frequency log-flush-frequency
long-running-request-regexp long-running-request-regexp
low-diskspace-threshold-mb low-diskspace-threshold-mb
manifest-url manifest-url
manifest-url-header manifest-url-header
masquerade-all masquerade-all
master-service-namespace master-service-namespace
max-concurrency max-concurrency
max-connection-bytes-per-sec max-connection-bytes-per-sec
maximum-dead-containers maximum-dead-containers
maximum-dead-containers-per-container maximum-dead-containers-per-container
max-log-age max-log-age
max-log-backups max-log-backups
max-log-size max-log-size
max-outgoing-burst max-outgoing-burst
max-outgoing-qps max-outgoing-qps
max-pods max-pods
max-requests-inflight max-requests-inflight
mesos-authentication-principal mesos-authentication-principal
mesos-authentication-provider mesos-authentication-provider
mesos-authentication-secret-file mesos-authentication-secret-file
mesos-cgroup-prefix mesos-cgroup-prefix
mesos-executor-cpus mesos-executor-cpus
mesos-executor-mem mesos-executor-mem
mesos-master mesos-master
mesos-role mesos-role
mesos-user mesos-user
minimum-container-ttl-duration minimum-container-ttl-duration
minion-max-log-age minion-max-log-age
minion-max-log-backups minion-max-log-backups
minion-max-log-size minion-max-log-size
minion-path-override minion-path-override
min-pr-number min-pr-number
min-request-timeout min-request-timeout
namespace-sync-period namespace-sync-period
network-plugin network-plugin
network-plugin-dir network-plugin-dir
node-instance-group node-instance-group
node-monitor-grace-period node-monitor-grace-period
node-monitor-period node-monitor-period
node-startup-grace-period node-startup-grace-period
node-status-update-frequency node-status-update-frequency
node-sync-period node-sync-period
no-headers no-headers
num-nodes num-nodes
oidc-ca-file oidc-ca-file
oidc-client-id oidc-client-id
oidc-issuer-url oidc-issuer-url
oidc-username-claim oidc-username-claim
oom-score-adj oom-score-adj
output-version output-version
out-version out-version
path-override path-override
pod-cidr pod-cidr
pod-eviction-timeout pod-eviction-timeout
pod-infra-container-image pod-infra-container-image
pod-running pod-running
policy-config-file policy-config-file
poll-interval poll-interval
portal-net portal-net
private-mountns private-mountns
prom-push-gateway prom-push-gateway
proxy-bindall proxy-bindall
proxy-logv proxy-logv
proxy-port-range proxy-port-range
public-address-override public-address-override
pvclaimbinder-sync-period pvclaimbinder-sync-period
read-only-port read-only-port
really-crash-for-testing really-crash-for-testing
reconcile-cooldown reconcile-cooldown
reconcile-interval reconcile-interval
register-node register-node
register-retry-count register-retry-count
registry-burst registry-burst
registry-qps registry-qps
reject-methods reject-methods
reject-paths reject-paths
repo-root repo-root
report-dir report-dir
required-contexts required-contexts
resolv-conf resolv-conf
resource-container resource-container
resource-quota-sync-period resource-quota-sync-period
resource-version resource-version
rkt-path rkt-path
root-ca-file rkt-stage1-image
root-dir root-ca-file
run-proxy root-dir
runtime-config run-proxy
scheduler-config runtime-config
secure-port scheduler-config
service-account-key-file secure-port
service-account-lookup service-account-key-file
service-account-private-key-file service-account-lookup
service-address service-account-private-key-file
service-cluster-ip-range service-address
service-node-port-range service-cluster-ip-range
service-node-ports service-node-port-range
service-sync-period service-node-ports
session-affinity service-sync-period
show-all session-affinity
shutdown-fd show-all
shutdown-fifo shutdown-fd
skip-munges shutdown-fifo
sort-by skip-munges
source-file sort-by
ssh-keyfile source-file
ssh-user ssh-keyfile
static-pods-config ssh-user
stats-port static-pods-config
storage-version stats-port
streaming-connection-idle-timeout storage-version
suicide-timeout streaming-connection-idle-timeout
sync-frequency suicide-timeout
system-container sync-frequency
target-port system-container
tcp-services target-port
tls-cert-file tcp-services
tls-private-key-file tls-cert-file
token-auth-file tls-private-key-file
ttl-secs token-auth-file
type-src ttl-secs
unix-socket type-src
update-period unix-socket
upgrade-target update-period
use-kubernetes-cluster-service upgrade-target
user-whitelist use-kubernetes-cluster-service
watch-cache user-whitelist
watch-only watch-cache
whitelist-override-label watch-only
www-prefix whitelist-override-label
retry_time www-prefix
file_content_in_loop retry_time
cpu-cfs-quota file_content_in_loop
cpu-cfs-quota

View File

@ -164,6 +164,7 @@ func NewMainKubelet(
cgroupRoot string, cgroupRoot string,
containerRuntime string, containerRuntime string,
rktPath string, rktPath string,
rktStage1Image string,
mounter mount.Interface, mounter mount.Interface,
dockerDaemonContainer string, dockerDaemonContainer string,
systemContainer string, systemContainer string,
@ -331,6 +332,7 @@ func NewMainKubelet(
case "rkt": case "rkt":
conf := &rkt.Config{ conf := &rkt.Config{
Path: rktPath, Path: rktPath,
Stage1Image: rktStage1Image,
InsecureSkipVerify: true, InsecureSkipVerify: true,
} }
rktRuntime, err := rkt.New( rktRuntime, err := rkt.New(

View File

@ -23,6 +23,8 @@ import "fmt"
type Config struct { type Config struct {
// The absolute path to the binary, or leave empty to find it in $PATH. // The absolute path to the binary, or leave empty to find it in $PATH.
Path string Path string
// The image to use as stage1.
Stage1Image string
// The debug flag for rkt. // The debug flag for rkt.
Debug bool Debug bool
// The rkt data directory. // The rkt data directory.

View File

@ -27,7 +27,6 @@ import (
"path" "path"
"strconv" "strconv"
"strings" "strings"
"syscall"
"time" "time"
appcschema "github.com/appc/spec/schema" appcschema "github.com/appc/spec/schema"
@ -42,6 +41,7 @@ import (
"k8s.io/kubernetes/pkg/credentialprovider" "k8s.io/kubernetes/pkg/credentialprovider"
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
"k8s.io/kubernetes/pkg/kubelet/prober" "k8s.io/kubernetes/pkg/kubelet/prober"
kubeletUtil "k8s.io/kubernetes/pkg/kubelet/util"
"k8s.io/kubernetes/pkg/probe" "k8s.io/kubernetes/pkg/probe"
"k8s.io/kubernetes/pkg/securitycontext" "k8s.io/kubernetes/pkg/securitycontext"
"k8s.io/kubernetes/pkg/types" "k8s.io/kubernetes/pkg/types"
@ -467,7 +467,7 @@ func (r *runtime) makePodManifest(pod *api.Pod, pullSecrets []api.Secret) (*appc
volumeMap, ok := r.volumeGetter.GetVolumes(pod.UID) volumeMap, ok := r.volumeGetter.GetVolumes(pod.UID)
if !ok { if !ok {
return nil, fmt.Errorf("cannot get the volumes for pod %q", kubecontainer.GetPodFullName(pod)) return nil, fmt.Errorf("cannot get the volumes for pod %q", kubeletUtil.FormatPodName(pod))
} }
// Set global volumes. // Set global volumes.
@ -533,7 +533,7 @@ func serviceFilePath(serviceName string) string {
// preparePod will: // preparePod will:
// //
// 1. Invoke 'rkt prepare' to prepare the pod, and get the rkt pod uuid. // 1. Invoke 'rkt prepare' to prepare the pod, and get the rkt pod uuid.
// 2. Creates the unit file and save it under systemdUnitDir. // 2. Create the unit file and save it under systemdUnitDir.
// //
// On success, it will return a string that represents name of the unit file // On success, it will return a string that represents name of the unit file
// and the runtime pod. // and the runtime pod.
@ -566,6 +566,9 @@ func (r *runtime) preparePod(pod *api.Pod, pullSecrets []api.Secret) (string, *k
// Run 'rkt prepare' to get the rkt UUID. // Run 'rkt prepare' to get the rkt UUID.
cmds := []string{"prepare", "--quiet", "--pod-manifest", manifestFile.Name()} cmds := []string{"prepare", "--quiet", "--pod-manifest", manifestFile.Name()}
if r.config.Stage1Image != "" {
cmds = append(cmds, "--stage1-image", r.config.Stage1Image)
}
output, err := r.runCommand(cmds...) output, err := r.runCommand(cmds...)
if err != nil { if err != nil {
return "", nil, err return "", nil, err
@ -596,6 +599,8 @@ func (r *runtime) preparePod(pod *api.Pod, pullSecrets []api.Secret) (string, *k
// This makes the service show up for 'systemctl list-units' even if it exits successfully. // This makes the service show up for 'systemctl list-units' even if it exits successfully.
newUnitOption("Service", "RemainAfterExit", "true"), newUnitOption("Service", "RemainAfterExit", "true"),
newUnitOption("Service", "ExecStart", runPrepared), newUnitOption("Service", "ExecStart", runPrepared),
// This enables graceful stop.
newUnitOption("Service", "KillMode", "mixed"),
} }
// Check if there's old rkt pod corresponding to the same pod, if so, update the restart count. // Check if there's old rkt pod corresponding to the same pod, if so, update the restart count.
@ -615,7 +620,7 @@ func (r *runtime) preparePod(pod *api.Pod, pullSecrets []api.Secret) (string, *k
} }
units = append(units, newUnitOption(unitKubernetesSection, unitRestartCount, strconv.Itoa(restartCount))) units = append(units, newUnitOption(unitKubernetesSection, unitRestartCount, strconv.Itoa(restartCount)))
glog.V(4).Infof("rkt: Creating service file %q for pod %q", serviceName, pod.Name) glog.V(4).Infof("rkt: Creating service file %q for pod %q", serviceName, kubeletUtil.FormatPodName(pod))
serviceFile, err := os.Create(serviceFilePath(serviceName)) serviceFile, err := os.Create(serviceFilePath(serviceName))
if err != nil { if err != nil {
return "", nil, err return "", nil, err
@ -674,7 +679,7 @@ func (r *runtime) generateEvents(runtimePod *kubecontainer.Pod, reason string, f
// RunPod first creates the unit file for a pod, and then // RunPod first creates the unit file for a pod, and then
// starts the unit over d-bus. // starts the unit over d-bus.
func (r *runtime) RunPod(pod *api.Pod, pullSecrets []api.Secret) error { func (r *runtime) RunPod(pod *api.Pod, pullSecrets []api.Secret) error {
glog.V(4).Infof("Rkt starts to run pod: name %q.", pod.Name) glog.V(4).Infof("Rkt starts to run pod: name %q.", kubeletUtil.FormatPodName(pod))
name, runtimePod, prepareErr := r.preparePod(pod, pullSecrets) name, runtimePod, prepareErr := r.preparePod(pod, pullSecrets)
@ -684,7 +689,7 @@ func (r *runtime) RunPod(pod *api.Pod, pullSecrets []api.Secret) error {
for i, c := range pod.Spec.Containers { for i, c := range pod.Spec.Containers {
ref, err := kubecontainer.GenerateContainerRef(pod, &c) ref, err := kubecontainer.GenerateContainerRef(pod, &c)
if err != nil { if err != nil {
glog.Errorf("Couldn't make a ref to pod %v, container %v: '%v'", pod.Name, c.Name, err) glog.Errorf("Couldn't make a ref to pod %q, container %v: '%v'", kubeletUtil.FormatPodName(pod), c.Name, err)
continue continue
} }
if prepareErr != nil { if prepareErr != nil {
@ -800,8 +805,11 @@ func (r *runtime) KillPod(pod *api.Pod, runningPod kubecontainer.Pod) error {
r.containerRefManager.ClearRef(id) r.containerRefManager.ClearRef(id)
} }
// TODO(yifan): More graceful stop. Replace with StopUnit and wait for a timeout. // Since all service file have 'KillMode=mixed', the processes in
r.systemd.KillUnit(serviceName, int32(syscall.SIGKILL)) // the unit's cgroup will receive a SIGKILL if the normal stop timeouts.
if _, err := r.systemd.StopUnit(serviceName, "replace"); err != nil {
return err
}
// Remove the systemd service file as well. // Remove the systemd service file as well.
return os.Remove(serviceFilePath(serviceName)) return os.Remove(serviceFilePath(serviceName))
} }
@ -961,7 +969,7 @@ func (r *runtime) IsImagePresent(image kubecontainer.ImageSpec) (bool, error) {
// SyncPod syncs the running pod to match the specified desired pod. // SyncPod syncs the running pod to match the specified desired pod.
func (r *runtime) SyncPod(pod *api.Pod, runningPod kubecontainer.Pod, podStatus api.PodStatus, pullSecrets []api.Secret, backOff *util.Backoff) error { func (r *runtime) SyncPod(pod *api.Pod, runningPod kubecontainer.Pod, podStatus api.PodStatus, pullSecrets []api.Secret, backOff *util.Backoff) error {
podFullName := kubecontainer.GetPodFullName(pod) podFullName := kubeletUtil.FormatPodName(pod)
if len(runningPod.Containers) == 0 { if len(runningPod.Containers) == 0 {
glog.V(4).Infof("Pod %q is not running, will start it", podFullName) glog.V(4).Infof("Pod %q is not running, will start it", podFullName)
return r.RunPod(pod, pullSecrets) return r.RunPod(pod, pullSecrets)
@ -1036,6 +1044,8 @@ func (r *runtime) SyncPod(pod *api.Pod, runningPod kubecontainer.Pod, podStatus
// //
// In rkt runtime's implementation, per container log is get via 'journalctl -M [rkt-$UUID] -u [APP_NAME]'. // In rkt runtime's implementation, per container log is get via 'journalctl -M [rkt-$UUID] -u [APP_NAME]'.
// See https://github.com/coreos/rkt/blob/master/Documentation/commands.md#logging for more details. // See https://github.com/coreos/rkt/blob/master/Documentation/commands.md#logging for more details.
//
// TODO(yifan): If the rkt is using lkvm as the stage1 image, then this function will fail.
func (r *runtime) GetContainerLogs(pod *api.Pod, containerID string, tail string, follow bool, stdout, stderr io.Writer) error { func (r *runtime) GetContainerLogs(pod *api.Pod, containerID string, tail string, follow bool, stdout, stderr io.Writer) error {
id, err := parseContainerID(containerID) id, err := parseContainerID(containerID)
if err != nil { if err != nil {
@ -1072,6 +1082,7 @@ func (r *runtime) GarbageCollect() error {
// Note: In rkt, the container ID is in the form of "UUID:appName", where // Note: In rkt, the container ID is in the form of "UUID:appName", where
// appName is the container name. // appName is the container name.
// TODO(yifan): If the rkt is using lkvm as the stage1 image, then this function will fail.
func (r *runtime) RunInContainer(containerID string, cmd []string) ([]byte, error) { func (r *runtime) RunInContainer(containerID string, cmd []string) ([]byte, error) {
glog.V(4).Infof("Rkt running in container.") glog.V(4).Infof("Rkt running in container.")
@ -1092,6 +1103,7 @@ func (r *runtime) AttachContainer(containerID string, stdin io.Reader, stdout, s
// Note: In rkt, the container ID is in the form of "UUID:appName", where UUID is // Note: In rkt, the container ID is in the form of "UUID:appName", where UUID is
// the rkt UUID, and appName is the container name. // the rkt UUID, and appName is the container name.
// TODO(yifan): If the rkt is using lkvm as the stage1 image, then this function will fail.
func (r *runtime) ExecInContainer(containerID string, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool) error { func (r *runtime) ExecInContainer(containerID string, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool) error {
glog.V(4).Infof("Rkt execing in container.") glog.V(4).Infof("Rkt execing in container.")
@ -1150,7 +1162,7 @@ func (r *runtime) findRktID(pod *kubecontainer.Pod) (string, error) {
f, err := os.Open(serviceFilePath(serviceName)) f, err := os.Open(serviceFilePath(serviceName))
if err != nil { if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
return "", fmt.Errorf("no service file %v for pod %q, UID %q", serviceName, pod.Name, pod.ID) return "", fmt.Errorf("no service file %v for runtime pod %q, ID %q", serviceName, pod.Name, pod.ID)
} }
return "", err return "", err
} }
@ -1179,6 +1191,7 @@ func (r *runtime) findRktID(pod *kubecontainer.Pod) (string, error) {
// - should we support nsenter + socat in a container, running with elevated privs and --pid=host? // - should we support nsenter + socat in a container, running with elevated privs and --pid=host?
// //
// TODO(yifan): Merge with the same function in dockertools. // TODO(yifan): Merge with the same function in dockertools.
// TODO(yifan): If the rkt is using lkvm as the stage1 image, then this function will fail.
func (r *runtime) PortForward(pod *kubecontainer.Pod, port uint16, stream io.ReadWriteCloser) error { func (r *runtime) PortForward(pod *kubecontainer.Pod, port uint16, stream io.ReadWriteCloser) error {
glog.V(4).Infof("Rkt port forwarding in container.") glog.V(4).Infof("Rkt port forwarding in container.")