mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 21:47:07 +00:00
Add runtime-request-timeout kubelet flag.
This commit is contained in:
parent
04fd079d09
commit
52ebd4ecf1
@ -85,6 +85,7 @@ func NewKubeletServer() *KubeletServer {
|
|||||||
CgroupRoot: "",
|
CgroupRoot: "",
|
||||||
ConfigureCBR0: false,
|
ConfigureCBR0: false,
|
||||||
ContainerRuntime: "docker",
|
ContainerRuntime: "docker",
|
||||||
|
RuntimeRequestTimeout: unversioned.Duration{Duration: 2 * time.Minute},
|
||||||
CPUCFSQuota: true,
|
CPUCFSQuota: true,
|
||||||
DockerExecHandlerName: "native",
|
DockerExecHandlerName: "native",
|
||||||
EventBurst: 10,
|
EventBurst: 10,
|
||||||
@ -227,6 +228,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.DurationVar(&s.RuntimeRequestTimeout.Duration, "runtime-request-timeout", s.RuntimeRequestTimeout.Duration, "Timeout of all runtime requests except long running request - pull, logs, exec and attach. When timeout exceeded, kubelet will cancel the request, throw out an error and retry later. Default: 2m0s")
|
||||||
fs.StringVar(&s.LockFilePath, "lock-file", s.LockFilePath, "<Warning: Alpha feature> The path to file for kubelet to use as a lock file.")
|
fs.StringVar(&s.LockFilePath, "lock-file", s.LockFilePath, "<Warning: Alpha feature> The path to file for kubelet to use as a lock file.")
|
||||||
fs.BoolVar(&s.ExitOnLockContention, "exit-on-lock-contention", s.ExitOnLockContention, "Whether kubelet should exit upon lock-file contention.")
|
fs.BoolVar(&s.ExitOnLockContention, "exit-on-lock-contention", s.ExitOnLockContention, "Whether kubelet should exit upon lock-file contention.")
|
||||||
fs.StringVar(&s.RktPath, "rkt-path", s.RktPath, "Path of rkt binary. Leave empty to use the first rkt in $PATH. Only used if --container-runtime='rkt'.")
|
fs.StringVar(&s.RktPath, "rkt-path", s.RktPath, "Path of rkt binary. Leave empty to use the first rkt in $PATH. Only used if --container-runtime='rkt'.")
|
||||||
|
@ -212,7 +212,7 @@ func UnsecuredKubeletConfig(s *options.KubeletServer) (*KubeletConfig, error) {
|
|||||||
ContainerRuntime: s.ContainerRuntime,
|
ContainerRuntime: s.ContainerRuntime,
|
||||||
CPUCFSQuota: s.CPUCFSQuota,
|
CPUCFSQuota: s.CPUCFSQuota,
|
||||||
DiskSpacePolicy: diskSpacePolicy,
|
DiskSpacePolicy: diskSpacePolicy,
|
||||||
DockerClient: dockertools.ConnectToDockerOrDie(s.DockerEndpoint),
|
DockerClient: dockertools.ConnectToDockerOrDie(s.DockerEndpoint, s.RuntimeRequestTimeout.Duration), // TODO(random-liu): Set RuntimeRequestTimeout for rkt.
|
||||||
RuntimeCgroups: s.RuntimeCgroups,
|
RuntimeCgroups: s.RuntimeCgroups,
|
||||||
DockerExecHandler: dockerExecHandler,
|
DockerExecHandler: dockerExecHandler,
|
||||||
EnableControllerAttachDetach: s.EnableControllerAttachDetach,
|
EnableControllerAttachDetach: s.EnableControllerAttachDetach,
|
||||||
|
@ -184,7 +184,7 @@ func TestExecutorLaunchAndKillTask(t *testing.T) {
|
|||||||
mockDriver = &MockExecutorDriver{}
|
mockDriver = &MockExecutorDriver{}
|
||||||
registry = newFakeRegistry()
|
registry = newFakeRegistry()
|
||||||
executor = New(Config{
|
executor = New(Config{
|
||||||
Docker: dockertools.ConnectToDockerOrDie("fake://"),
|
Docker: dockertools.ConnectToDockerOrDie("fake://", 0),
|
||||||
NodeInfos: make(chan NodeInfo, 1),
|
NodeInfos: make(chan NodeInfo, 1),
|
||||||
Registry: registry,
|
Registry: registry,
|
||||||
})
|
})
|
||||||
@ -387,7 +387,7 @@ func TestExecutorFrameworkMessage(t *testing.T) {
|
|||||||
kubeletFinished = make(chan struct{})
|
kubeletFinished = make(chan struct{})
|
||||||
registry = newFakeRegistry()
|
registry = newFakeRegistry()
|
||||||
executor = New(Config{
|
executor = New(Config{
|
||||||
Docker: dockertools.ConnectToDockerOrDie("fake://"),
|
Docker: dockertools.ConnectToDockerOrDie("fake://", 0),
|
||||||
NodeInfos: make(chan NodeInfo, 1),
|
NodeInfos: make(chan NodeInfo, 1),
|
||||||
ShutdownAlert: func() {
|
ShutdownAlert: func() {
|
||||||
close(kubeletFinished)
|
close(kubeletFinished)
|
||||||
@ -584,7 +584,7 @@ func TestExecutorShutdown(t *testing.T) {
|
|||||||
kubeletFinished = make(chan struct{})
|
kubeletFinished = make(chan struct{})
|
||||||
exitCalled = int32(0)
|
exitCalled = int32(0)
|
||||||
executor = New(Config{
|
executor = New(Config{
|
||||||
Docker: dockertools.ConnectToDockerOrDie("fake://"),
|
Docker: dockertools.ConnectToDockerOrDie("fake://", 0),
|
||||||
NodeInfos: make(chan NodeInfo, 1),
|
NodeInfos: make(chan NodeInfo, 1),
|
||||||
ShutdownAlert: func() {
|
ShutdownAlert: func() {
|
||||||
close(kubeletFinished)
|
close(kubeletFinished)
|
||||||
|
@ -75,7 +75,7 @@ func (m *MockExecutorDriver) SendFrameworkMessage(msg string) (mesosproto.Status
|
|||||||
|
|
||||||
func NewTestKubernetesExecutor() *Executor {
|
func NewTestKubernetesExecutor() *Executor {
|
||||||
return New(Config{
|
return New(Config{
|
||||||
Docker: dockertools.ConnectToDockerOrDie("fake://"),
|
Docker: dockertools.ConnectToDockerOrDie("fake://", 0),
|
||||||
Registry: newFakeRegistry(),
|
Registry: newFakeRegistry(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,7 @@ func (s *KubeletExecutorServer) runExecutor(
|
|||||||
exec := executor.New(executor.Config{
|
exec := executor.New(executor.Config{
|
||||||
Registry: registry,
|
Registry: registry,
|
||||||
APIClient: apiclient,
|
APIClient: apiclient,
|
||||||
Docker: dockertools.ConnectToDockerOrDie(s.DockerEndpoint),
|
Docker: dockertools.ConnectToDockerOrDie(s.DockerEndpoint, 0),
|
||||||
SuicideTimeout: s.SuicideTimeout,
|
SuicideTimeout: s.SuicideTimeout,
|
||||||
KubeletFinished: kubeletFinished,
|
KubeletFinished: kubeletFinished,
|
||||||
ExitFunc: os.Exit,
|
ExitFunc: os.Exit,
|
||||||
|
@ -398,6 +398,7 @@ root-dir
|
|||||||
run-proxy
|
run-proxy
|
||||||
runtime-cgroups
|
runtime-cgroups
|
||||||
runtime-config
|
runtime-config
|
||||||
|
runtime-request-timeout
|
||||||
save-config
|
save-config
|
||||||
scheduler-config
|
scheduler-config
|
||||||
scheduler-name
|
scheduler-name
|
||||||
|
@ -263,6 +263,9 @@ type KubeletConfiguration struct {
|
|||||||
CgroupRoot string `json:"cgroupRoot,omitempty"`
|
CgroupRoot string `json:"cgroupRoot,omitempty"`
|
||||||
// containerRuntime is the container runtime to use.
|
// containerRuntime is the container runtime to use.
|
||||||
ContainerRuntime string `json:"containerRuntime"`
|
ContainerRuntime string `json:"containerRuntime"`
|
||||||
|
// runtimeRequestTimeout is the timeout for all runtime requests except long running
|
||||||
|
// requests - pull, logs, exec and attach.
|
||||||
|
RuntimeRequestTimeout unversioned.Duration `json:"runtimeRequestTimeout,omitempty"`
|
||||||
// rktPath is the path of rkt binary. Leave empty to use the first rkt in
|
// rktPath is the path of rkt binary. Leave empty to use the first rkt in
|
||||||
// $PATH.
|
// $PATH.
|
||||||
RktPath string `json:"rktPath,omitempty"`
|
RktPath string `json:"rktPath,omitempty"`
|
||||||
|
@ -23,6 +23,7 @@ import (
|
|||||||
"path"
|
"path"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
dockerref "github.com/docker/distribution/reference"
|
dockerref "github.com/docker/distribution/reference"
|
||||||
"github.com/docker/docker/pkg/jsonmessage"
|
"github.com/docker/docker/pkg/jsonmessage"
|
||||||
@ -311,8 +312,11 @@ func getDockerClient(dockerEndpoint string) (*dockerapi.Client, error) {
|
|||||||
|
|
||||||
// ConnectToDockerOrDie creates docker client connecting to docker daemon.
|
// ConnectToDockerOrDie creates docker client connecting to docker daemon.
|
||||||
// If the endpoint passed in is "fake://", a fake docker client
|
// If the endpoint passed in is "fake://", a fake docker client
|
||||||
// will be returned. The program exits if error occurs.
|
// will be returned. The program exits if error occurs. The requestTimeout
|
||||||
func ConnectToDockerOrDie(dockerEndpoint string) DockerInterface {
|
// is the timeout for docker requests. If timeout is exceeded, the request
|
||||||
|
// will be cancelled and throw out an error. If requestTimeout is 0, a default
|
||||||
|
// value will be applied.
|
||||||
|
func ConnectToDockerOrDie(dockerEndpoint string, requestTimeout time.Duration) DockerInterface {
|
||||||
if dockerEndpoint == "fake://" {
|
if dockerEndpoint == "fake://" {
|
||||||
return NewFakeDockerClient()
|
return NewFakeDockerClient()
|
||||||
}
|
}
|
||||||
@ -320,7 +324,8 @@ func ConnectToDockerOrDie(dockerEndpoint string) DockerInterface {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Fatalf("Couldn't connect to docker: %v", err)
|
glog.Fatalf("Couldn't connect to docker: %v", err)
|
||||||
}
|
}
|
||||||
return newKubeDockerClient(client)
|
glog.Infof("Start docker client with request timeout=%v", requestTimeout)
|
||||||
|
return newKubeDockerClient(client, requestTimeout)
|
||||||
}
|
}
|
||||||
|
|
||||||
// milliCPUToQuota converts milliCPU to CFS quota and period values
|
// milliCPUToQuota converts milliCPU to CFS quota and period values
|
||||||
|
@ -49,14 +49,22 @@ import (
|
|||||||
// TODO(random-liu): Swith to new docker interface by refactoring the functions in the old DockerInterface
|
// TODO(random-liu): Swith to new docker interface by refactoring the functions in the old DockerInterface
|
||||||
// one by one.
|
// one by one.
|
||||||
type kubeDockerClient struct {
|
type kubeDockerClient struct {
|
||||||
client *dockerapi.Client
|
// timeout is the timeout of short running docker operations.
|
||||||
|
timeout time.Duration
|
||||||
|
client *dockerapi.Client
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure that kubeDockerClient implemented the DockerInterface.
|
// Make sure that kubeDockerClient implemented the DockerInterface.
|
||||||
var _ DockerInterface = &kubeDockerClient{}
|
var _ DockerInterface = &kubeDockerClient{}
|
||||||
|
|
||||||
|
// There are 2 kinds of docker operations categorized by running time:
|
||||||
|
// * Long running operation: The long running operation could run for arbitrary long time, and the running time
|
||||||
|
// usually depends on some uncontrollable factors. These operations include: PullImage, Logs, StartExec, AttachToContainer.
|
||||||
|
// * Non-long running operation: Given the maximum load of the system, the non-long running operation should finish
|
||||||
|
// in expected and usually short time. These include all other operations.
|
||||||
|
// kubeDockerClient only applies timeout on non-long running operations.
|
||||||
const (
|
const (
|
||||||
// defaultTimeout is the default timeout of all docker operations.
|
// defaultTimeout is the default timeout of short running docker operations.
|
||||||
defaultTimeout = 2 * time.Minute
|
defaultTimeout = 2 * time.Minute
|
||||||
|
|
||||||
// defaultShmSize is the default ShmSize to use (in bytes) if not specified.
|
// defaultShmSize is the default ShmSize to use (in bytes) if not specified.
|
||||||
@ -69,20 +77,26 @@ const (
|
|||||||
// is made for defaultImagePullingStuckTimeout, the image pulling will be cancelled.
|
// is made for defaultImagePullingStuckTimeout, the image pulling will be cancelled.
|
||||||
// Docker reports image progress for every 512kB block, so normally there shouldn't be too long interval
|
// Docker reports image progress for every 512kB block, so normally there shouldn't be too long interval
|
||||||
// between progress updates.
|
// between progress updates.
|
||||||
|
// TODO(random-liu): Make this configurable
|
||||||
defaultImagePullingStuckTimeout = 1 * time.Minute
|
defaultImagePullingStuckTimeout = 1 * time.Minute
|
||||||
)
|
)
|
||||||
|
|
||||||
// newKubeDockerClient creates an kubeDockerClient from an existing docker client.
|
// newKubeDockerClient creates an kubeDockerClient from an existing docker client. If requestTimeout is 0,
|
||||||
func newKubeDockerClient(dockerClient *dockerapi.Client) DockerInterface {
|
// defaultTimeout will be applied.
|
||||||
|
func newKubeDockerClient(dockerClient *dockerapi.Client, requestTimeout time.Duration) DockerInterface {
|
||||||
|
if requestTimeout == 0 {
|
||||||
|
requestTimeout = defaultTimeout
|
||||||
|
}
|
||||||
return &kubeDockerClient{
|
return &kubeDockerClient{
|
||||||
client: dockerClient,
|
client: dockerClient,
|
||||||
|
timeout: requestTimeout,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (k *kubeDockerClient) ListContainers(options dockertypes.ContainerListOptions) ([]dockertypes.Container, error) {
|
func (d *kubeDockerClient) ListContainers(options dockertypes.ContainerListOptions) ([]dockertypes.Container, error) {
|
||||||
ctx, cancel := getDefaultContext()
|
ctx, cancel := d.getTimeoutContext()
|
||||||
defer cancel()
|
defer cancel()
|
||||||
containers, err := k.client.ContainerList(ctx, options)
|
containers, err := d.client.ContainerList(ctx, options)
|
||||||
if ctxErr := contextError(ctx); ctxErr != nil {
|
if ctxErr := contextError(ctx); ctxErr != nil {
|
||||||
return nil, ctxErr
|
return nil, ctxErr
|
||||||
}
|
}
|
||||||
@ -93,7 +107,7 @@ func (k *kubeDockerClient) ListContainers(options dockertypes.ContainerListOptio
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *kubeDockerClient) InspectContainer(id string) (*dockertypes.ContainerJSON, error) {
|
func (d *kubeDockerClient) InspectContainer(id string) (*dockertypes.ContainerJSON, error) {
|
||||||
ctx, cancel := getDefaultContext()
|
ctx, cancel := d.getTimeoutContext()
|
||||||
defer cancel()
|
defer cancel()
|
||||||
containerJSON, err := d.client.ContainerInspect(ctx, id)
|
containerJSON, err := d.client.ContainerInspect(ctx, id)
|
||||||
if ctxErr := contextError(ctx); ctxErr != nil {
|
if ctxErr := contextError(ctx); ctxErr != nil {
|
||||||
@ -109,7 +123,7 @@ func (d *kubeDockerClient) InspectContainer(id string) (*dockertypes.ContainerJS
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *kubeDockerClient) CreateContainer(opts dockertypes.ContainerCreateConfig) (*dockertypes.ContainerCreateResponse, error) {
|
func (d *kubeDockerClient) CreateContainer(opts dockertypes.ContainerCreateConfig) (*dockertypes.ContainerCreateResponse, error) {
|
||||||
ctx, cancel := getDefaultContext()
|
ctx, cancel := d.getTimeoutContext()
|
||||||
defer cancel()
|
defer cancel()
|
||||||
// we provide an explicit default shm size as to not depend on docker daemon.
|
// we provide an explicit default shm size as to not depend on docker daemon.
|
||||||
// TODO: evaluate exposing this as a knob in the API
|
// TODO: evaluate exposing this as a knob in the API
|
||||||
@ -127,7 +141,7 @@ func (d *kubeDockerClient) CreateContainer(opts dockertypes.ContainerCreateConfi
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *kubeDockerClient) StartContainer(id string) error {
|
func (d *kubeDockerClient) StartContainer(id string) error {
|
||||||
ctx, cancel := getDefaultContext()
|
ctx, cancel := d.getTimeoutContext()
|
||||||
defer cancel()
|
defer cancel()
|
||||||
err := d.client.ContainerStart(ctx, id)
|
err := d.client.ContainerStart(ctx, id)
|
||||||
if ctxErr := contextError(ctx); ctxErr != nil {
|
if ctxErr := contextError(ctx); ctxErr != nil {
|
||||||
@ -138,7 +152,7 @@ func (d *kubeDockerClient) StartContainer(id string) error {
|
|||||||
|
|
||||||
// Stopping an already stopped container will not cause an error in engine-api.
|
// Stopping an already stopped container will not cause an error in engine-api.
|
||||||
func (d *kubeDockerClient) StopContainer(id string, timeout int) error {
|
func (d *kubeDockerClient) StopContainer(id string, timeout int) error {
|
||||||
ctx, cancel := getDefaultContext()
|
ctx, cancel := d.getTimeoutContext()
|
||||||
defer cancel()
|
defer cancel()
|
||||||
err := d.client.ContainerStop(ctx, id, timeout)
|
err := d.client.ContainerStop(ctx, id, timeout)
|
||||||
if ctxErr := contextError(ctx); ctxErr != nil {
|
if ctxErr := contextError(ctx); ctxErr != nil {
|
||||||
@ -148,7 +162,7 @@ func (d *kubeDockerClient) StopContainer(id string, timeout int) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *kubeDockerClient) RemoveContainer(id string, opts dockertypes.ContainerRemoveOptions) error {
|
func (d *kubeDockerClient) RemoveContainer(id string, opts dockertypes.ContainerRemoveOptions) error {
|
||||||
ctx, cancel := getDefaultContext()
|
ctx, cancel := d.getTimeoutContext()
|
||||||
defer cancel()
|
defer cancel()
|
||||||
err := d.client.ContainerRemove(ctx, id, opts)
|
err := d.client.ContainerRemove(ctx, id, opts)
|
||||||
if ctxErr := contextError(ctx); ctxErr != nil {
|
if ctxErr := contextError(ctx); ctxErr != nil {
|
||||||
@ -158,7 +172,7 @@ func (d *kubeDockerClient) RemoveContainer(id string, opts dockertypes.Container
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *kubeDockerClient) InspectImage(image string) (*dockertypes.ImageInspect, error) {
|
func (d *kubeDockerClient) InspectImage(image string) (*dockertypes.ImageInspect, error) {
|
||||||
ctx, cancel := getDefaultContext()
|
ctx, cancel := d.getTimeoutContext()
|
||||||
defer cancel()
|
defer cancel()
|
||||||
resp, _, err := d.client.ImageInspectWithRaw(ctx, image, true)
|
resp, _, err := d.client.ImageInspectWithRaw(ctx, image, true)
|
||||||
if ctxErr := contextError(ctx); ctxErr != nil {
|
if ctxErr := contextError(ctx); ctxErr != nil {
|
||||||
@ -174,7 +188,7 @@ func (d *kubeDockerClient) InspectImage(image string) (*dockertypes.ImageInspect
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *kubeDockerClient) ImageHistory(id string) ([]dockertypes.ImageHistory, error) {
|
func (d *kubeDockerClient) ImageHistory(id string) ([]dockertypes.ImageHistory, error) {
|
||||||
ctx, cancel := getDefaultContext()
|
ctx, cancel := d.getTimeoutContext()
|
||||||
defer cancel()
|
defer cancel()
|
||||||
resp, err := d.client.ImageHistory(ctx, id)
|
resp, err := d.client.ImageHistory(ctx, id)
|
||||||
if ctxErr := contextError(ctx); ctxErr != nil {
|
if ctxErr := contextError(ctx); ctxErr != nil {
|
||||||
@ -184,7 +198,7 @@ func (d *kubeDockerClient) ImageHistory(id string) ([]dockertypes.ImageHistory,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *kubeDockerClient) ListImages(opts dockertypes.ImageListOptions) ([]dockertypes.Image, error) {
|
func (d *kubeDockerClient) ListImages(opts dockertypes.ImageListOptions) ([]dockertypes.Image, error) {
|
||||||
ctx, cancel := getDefaultContext()
|
ctx, cancel := d.getTimeoutContext()
|
||||||
defer cancel()
|
defer cancel()
|
||||||
images, err := d.client.ImageList(ctx, opts)
|
images, err := d.client.ImageList(ctx, opts)
|
||||||
if ctxErr := contextError(ctx); ctxErr != nil {
|
if ctxErr := contextError(ctx); ctxErr != nil {
|
||||||
@ -297,7 +311,7 @@ func (d *kubeDockerClient) PullImage(image string, auth dockertypes.AuthConfig,
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
opts.RegistryAuth = base64Auth
|
opts.RegistryAuth = base64Auth
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := d.getCancelableContext()
|
||||||
defer cancel()
|
defer cancel()
|
||||||
resp, err := d.client.ImagePull(ctx, image, opts)
|
resp, err := d.client.ImagePull(ctx, image, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -326,7 +340,7 @@ func (d *kubeDockerClient) PullImage(image string, auth dockertypes.AuthConfig,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *kubeDockerClient) RemoveImage(image string, opts dockertypes.ImageRemoveOptions) ([]dockertypes.ImageDelete, error) {
|
func (d *kubeDockerClient) RemoveImage(image string, opts dockertypes.ImageRemoveOptions) ([]dockertypes.ImageDelete, error) {
|
||||||
ctx, cancel := getDefaultContext()
|
ctx, cancel := d.getTimeoutContext()
|
||||||
defer cancel()
|
defer cancel()
|
||||||
resp, err := d.client.ImageRemove(ctx, image, opts)
|
resp, err := d.client.ImageRemove(ctx, image, opts)
|
||||||
if ctxErr := contextError(ctx); ctxErr != nil {
|
if ctxErr := contextError(ctx); ctxErr != nil {
|
||||||
@ -336,8 +350,12 @@ func (d *kubeDockerClient) RemoveImage(image string, opts dockertypes.ImageRemov
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *kubeDockerClient) Logs(id string, opts dockertypes.ContainerLogsOptions, sopts StreamOptions) error {
|
func (d *kubeDockerClient) Logs(id string, opts dockertypes.ContainerLogsOptions, sopts StreamOptions) error {
|
||||||
// Don't set timeout for log calls
|
ctx, cancel := d.getCancelableContext()
|
||||||
resp, err := d.client.ContainerLogs(context.Background(), id, opts)
|
defer cancel()
|
||||||
|
resp, err := d.client.ContainerLogs(ctx, id, opts)
|
||||||
|
if ctxErr := contextError(ctx); ctxErr != nil {
|
||||||
|
return ctxErr
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -346,7 +364,7 @@ func (d *kubeDockerClient) Logs(id string, opts dockertypes.ContainerLogsOptions
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *kubeDockerClient) Version() (*dockertypes.Version, error) {
|
func (d *kubeDockerClient) Version() (*dockertypes.Version, error) {
|
||||||
ctx, cancel := getDefaultContext()
|
ctx, cancel := d.getTimeoutContext()
|
||||||
defer cancel()
|
defer cancel()
|
||||||
resp, err := d.client.ServerVersion(ctx)
|
resp, err := d.client.ServerVersion(ctx)
|
||||||
if ctxErr := contextError(ctx); ctxErr != nil {
|
if ctxErr := contextError(ctx); ctxErr != nil {
|
||||||
@ -359,7 +377,7 @@ func (d *kubeDockerClient) Version() (*dockertypes.Version, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *kubeDockerClient) Info() (*dockertypes.Info, error) {
|
func (d *kubeDockerClient) Info() (*dockertypes.Info, error) {
|
||||||
ctx, cancel := getDefaultContext()
|
ctx, cancel := d.getTimeoutContext()
|
||||||
defer cancel()
|
defer cancel()
|
||||||
resp, err := d.client.Info(ctx)
|
resp, err := d.client.Info(ctx)
|
||||||
if ctxErr := contextError(ctx); ctxErr != nil {
|
if ctxErr := contextError(ctx); ctxErr != nil {
|
||||||
@ -373,7 +391,7 @@ func (d *kubeDockerClient) Info() (*dockertypes.Info, error) {
|
|||||||
|
|
||||||
// TODO(random-liu): Add unit test for exec and attach functions, just like what go-dockerclient did.
|
// TODO(random-liu): Add unit test for exec and attach functions, just like what go-dockerclient did.
|
||||||
func (d *kubeDockerClient) CreateExec(id string, opts dockertypes.ExecConfig) (*dockertypes.ContainerExecCreateResponse, error) {
|
func (d *kubeDockerClient) CreateExec(id string, opts dockertypes.ExecConfig) (*dockertypes.ContainerExecCreateResponse, error) {
|
||||||
ctx, cancel := getDefaultContext()
|
ctx, cancel := d.getTimeoutContext()
|
||||||
defer cancel()
|
defer cancel()
|
||||||
resp, err := d.client.ContainerExecCreate(ctx, id, opts)
|
resp, err := d.client.ContainerExecCreate(ctx, id, opts)
|
||||||
if ctxErr := contextError(ctx); ctxErr != nil {
|
if ctxErr := contextError(ctx); ctxErr != nil {
|
||||||
@ -386,7 +404,7 @@ func (d *kubeDockerClient) CreateExec(id string, opts dockertypes.ExecConfig) (*
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *kubeDockerClient) StartExec(startExec string, opts dockertypes.ExecStartCheck, sopts StreamOptions) error {
|
func (d *kubeDockerClient) StartExec(startExec string, opts dockertypes.ExecStartCheck, sopts StreamOptions) error {
|
||||||
ctx, cancel := getDefaultContext()
|
ctx, cancel := d.getCancelableContext()
|
||||||
defer cancel()
|
defer cancel()
|
||||||
if opts.Detach {
|
if opts.Detach {
|
||||||
err := d.client.ContainerExecStart(ctx, startExec, opts)
|
err := d.client.ContainerExecStart(ctx, startExec, opts)
|
||||||
@ -410,7 +428,7 @@ func (d *kubeDockerClient) StartExec(startExec string, opts dockertypes.ExecStar
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *kubeDockerClient) InspectExec(id string) (*dockertypes.ContainerExecInspect, error) {
|
func (d *kubeDockerClient) InspectExec(id string) (*dockertypes.ContainerExecInspect, error) {
|
||||||
ctx, cancel := getDefaultContext()
|
ctx, cancel := d.getTimeoutContext()
|
||||||
defer cancel()
|
defer cancel()
|
||||||
resp, err := d.client.ContainerExecInspect(ctx, id)
|
resp, err := d.client.ContainerExecInspect(ctx, id)
|
||||||
if ctxErr := contextError(ctx); ctxErr != nil {
|
if ctxErr := contextError(ctx); ctxErr != nil {
|
||||||
@ -423,7 +441,7 @@ func (d *kubeDockerClient) InspectExec(id string) (*dockertypes.ContainerExecIns
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *kubeDockerClient) AttachToContainer(id string, opts dockertypes.ContainerAttachOptions, sopts StreamOptions) error {
|
func (d *kubeDockerClient) AttachToContainer(id string, opts dockertypes.ContainerAttachOptions, sopts StreamOptions) error {
|
||||||
ctx, cancel := getDefaultContext()
|
ctx, cancel := d.getCancelableContext()
|
||||||
defer cancel()
|
defer cancel()
|
||||||
resp, err := d.client.ContainerAttach(ctx, id, opts)
|
resp, err := d.client.ContainerAttach(ctx, id, opts)
|
||||||
if ctxErr := contextError(ctx); ctxErr != nil {
|
if ctxErr := contextError(ctx); ctxErr != nil {
|
||||||
@ -484,16 +502,23 @@ func (d *kubeDockerClient) holdHijackedConnection(tty bool, inputStream io.Reade
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getCancelableContext returns a new cancelable context. For long running requests without timeout, we use cancelable
|
||||||
|
// context to avoid potential resource leak, although the current implementation shouldn't leak resource.
|
||||||
|
func (d *kubeDockerClient) getCancelableContext() (context.Context, context.CancelFunc) {
|
||||||
|
return context.WithCancel(context.Background())
|
||||||
|
}
|
||||||
|
|
||||||
|
// getTimeoutContext returns a new context with default request timeout
|
||||||
|
func (d *kubeDockerClient) getTimeoutContext() (context.Context, context.CancelFunc) {
|
||||||
|
return context.WithTimeout(context.Background(), d.timeout)
|
||||||
|
}
|
||||||
|
|
||||||
// parseDockerTimestamp parses the timestamp returned by DockerInterface from string to time.Time
|
// parseDockerTimestamp parses the timestamp returned by DockerInterface from string to time.Time
|
||||||
func parseDockerTimestamp(s string) (time.Time, error) {
|
func parseDockerTimestamp(s string) (time.Time, error) {
|
||||||
// Timestamp returned by Docker is in time.RFC3339Nano format.
|
// Timestamp returned by Docker is in time.RFC3339Nano format.
|
||||||
return time.Parse(time.RFC3339Nano, s)
|
return time.Parse(time.RFC3339Nano, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getDefaultContext() (context.Context, context.CancelFunc) {
|
|
||||||
return context.WithTimeout(context.Background(), defaultTimeout)
|
|
||||||
}
|
|
||||||
|
|
||||||
// contextError checks the context, and returns error if the context is timeout.
|
// contextError checks the context, and returns error if the context is timeout.
|
||||||
func contextError(ctx context.Context) error {
|
func contextError(ctx context.Context) error {
|
||||||
if ctx.Err() == context.DeadlineExceeded {
|
if ctx.Err() == context.DeadlineExceeded {
|
||||||
|
@ -40,7 +40,7 @@ func NewConformanceImage(containerRuntime string, image string) (ci ConformanceI
|
|||||||
|
|
||||||
//TODO: do not expose kubelet implementation details after we refactor the runtime API.
|
//TODO: do not expose kubelet implementation details after we refactor the runtime API.
|
||||||
func dockerRuntime() kubecontainer.Runtime {
|
func dockerRuntime() kubecontainer.Runtime {
|
||||||
dockerClient := dockertools.ConnectToDockerOrDie("")
|
dockerClient := dockertools.ConnectToDockerOrDie("", 0)
|
||||||
pm := kubepod.NewBasicPodManager(nil)
|
pm := kubepod.NewBasicPodManager(nil)
|
||||||
dm := dockertools.NewDockerManager(
|
dm := dockertools.NewDockerManager(
|
||||||
dockerClient,
|
dockerClient,
|
||||||
|
Loading…
Reference in New Issue
Block a user