Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
9ded52ac
Commit
9ded52ac
authored
May 08, 2015
by
Victor Marmol
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #7981 from yujuhong/reasons
Record failure reasons for image pulling
parents
8314fd9c
d185bfd5
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
129 additions
and
35 deletions
+129
-35
manager.go
pkg/kubelet/dockertools/manager.go
+31
-24
kubelet_test.go
pkg/kubelet/kubelet_test.go
+98
-11
No files found.
pkg/kubelet/dockertools/manager.go
View file @
9ded52ac
...
@@ -435,8 +435,6 @@ func (dm *DockerManager) GetPodStatus(pod *api.Pod) (*api.PodStatus, error) {
...
@@ -435,8 +435,6 @@ func (dm *DockerManager) GetPodStatus(pod *api.Pod) (*api.PodStatus, error) {
containerStatus
.
LastTerminationState
=
oldStatus
.
LastTerminationState
containerStatus
.
LastTerminationState
=
oldStatus
.
LastTerminationState
}
}
//Check image is ready on the node or not.
//Check image is ready on the node or not.
// TODO: If we integrate DockerPuller into DockerManager, we can
// record the pull failure and eliminate the image checking below.
image
:=
container
.
Image
image
:=
container
.
Image
// TODO(dchen1107): docker/docker/issues/8365 to figure out if the image exists
// TODO(dchen1107): docker/docker/issues/8365 to figure out if the image exists
_
,
err
:=
dm
.
client
.
InspectImage
(
image
)
_
,
err
:=
dm
.
client
.
InspectImage
(
image
)
...
@@ -475,19 +473,6 @@ func (dm *DockerManager) GetPodInfraContainer(pod kubecontainer.Pod) (kubecontai
...
@@ -475,19 +473,6 @@ func (dm *DockerManager) GetPodInfraContainer(pod kubecontainer.Pod) (kubecontai
return
kubecontainer
.
Container
{},
fmt
.
Errorf
(
"unable to find pod infra container for pod %v"
,
pod
.
ID
)
return
kubecontainer
.
Container
{},
fmt
.
Errorf
(
"unable to find pod infra container for pod %v"
,
pod
.
ID
)
}
}
func
(
dm
*
DockerManager
)
runContainerRecordErrorReason
(
pod
*
api
.
Pod
,
container
*
api
.
Container
,
opts
*
kubecontainer
.
RunContainerOptions
,
ref
*
api
.
ObjectReference
)
(
string
,
error
)
{
dockerID
,
err
:=
dm
.
runContainer
(
pod
,
container
,
opts
,
ref
)
if
err
!=
nil
{
errString
:=
err
.
Error
()
if
errString
!=
""
{
dm
.
reasonCache
.
Add
(
pod
.
UID
,
container
.
Name
,
errString
)
}
else
{
dm
.
reasonCache
.
Remove
(
pod
.
UID
,
container
.
Name
)
}
}
return
dockerID
,
err
}
func
(
dm
*
DockerManager
)
runContainer
(
pod
*
api
.
Pod
,
container
*
api
.
Container
,
opts
*
kubecontainer
.
RunContainerOptions
,
ref
*
api
.
ObjectReference
)
(
string
,
error
)
{
func
(
dm
*
DockerManager
)
runContainer
(
pod
*
api
.
Pod
,
container
*
api
.
Container
,
opts
*
kubecontainer
.
RunContainerOptions
,
ref
*
api
.
ObjectReference
)
(
string
,
error
)
{
dockerName
:=
KubeletContainerName
{
dockerName
:=
KubeletContainerName
{
PodFullName
:
kubecontainer
.
GetPodFullName
(
pod
),
PodFullName
:
kubecontainer
.
GetPodFullName
(
pod
),
...
@@ -1100,7 +1085,7 @@ func (dm *DockerManager) RunContainer(pod *api.Pod, container *api.Container, ne
...
@@ -1100,7 +1085,7 @@ func (dm *DockerManager) RunContainer(pod *api.Pod, container *api.Container, ne
return
""
,
err
return
""
,
err
}
}
id
,
err
:=
dm
.
runContainer
RecordErrorReason
(
pod
,
container
,
opts
,
ref
)
id
,
err
:=
dm
.
runContainer
(
pod
,
container
,
opts
,
ref
)
if
err
!=
nil
{
if
err
!=
nil
{
return
""
,
err
return
""
,
err
}
}
...
@@ -1323,10 +1308,25 @@ func (dm *DockerManager) computePodContainerChanges(pod *api.Pod, runningPod kub
...
@@ -1323,10 +1308,25 @@ func (dm *DockerManager) computePodContainerChanges(pod *api.Pod, runningPod kub
},
nil
},
nil
}
}
// updateReasonCache updates the failure reason based on the latest error.
func
(
dm
*
DockerManager
)
updateReasonCache
(
pod
*
api
.
Pod
,
container
*
api
.
Container
,
err
error
)
{
if
err
==
nil
{
return
}
errString
:=
err
.
Error
()
dm
.
reasonCache
.
Add
(
pod
.
UID
,
container
.
Name
,
errString
)
}
// clearReasonCache removes the entry in the reason cache.
func
(
dm
*
DockerManager
)
clearReasonCache
(
pod
*
api
.
Pod
,
container
*
api
.
Container
)
{
dm
.
reasonCache
.
Remove
(
pod
.
UID
,
container
.
Name
)
}
// Pull the image for the specified pod and container.
// Pull the image for the specified pod and container.
func
(
dm
*
DockerManager
)
pullImage
(
pod
*
api
.
Pod
,
container
*
api
.
Container
)
error
{
func
(
dm
*
DockerManager
)
pullImage
(
pod
*
api
.
Pod
,
container
*
api
.
Container
)
error
{
spec
:=
kubecontainer
.
ImageSpec
{
container
.
Image
}
spec
:=
kubecontainer
.
ImageSpec
{
container
.
Image
}
present
,
err
:=
dm
.
IsImagePresent
(
spec
)
present
,
err
:=
dm
.
IsImagePresent
(
spec
)
if
err
!=
nil
{
if
err
!=
nil
{
ref
,
err
:=
kubecontainer
.
GenerateContainerRef
(
pod
,
container
)
ref
,
err
:=
kubecontainer
.
GenerateContainerRef
(
pod
,
container
)
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -1337,7 +1337,6 @@ func (dm *DockerManager) pullImage(pod *api.Pod, container *api.Container) error
...
@@ -1337,7 +1337,6 @@ func (dm *DockerManager) pullImage(pod *api.Pod, container *api.Container) error
}
}
return
fmt
.
Errorf
(
"failed to inspect image %q: %v"
,
container
.
Image
,
err
)
return
fmt
.
Errorf
(
"failed to inspect image %q: %v"
,
container
.
Image
,
err
)
}
}
if
!
dm
.
runtimeHooks
.
ShouldPullImage
(
pod
,
container
,
present
)
{
if
!
dm
.
runtimeHooks
.
ShouldPullImage
(
pod
,
container
,
present
)
{
return
nil
return
nil
}
}
...
@@ -1399,20 +1398,28 @@ func (dm *DockerManager) SyncPod(pod *api.Pod, runningPod kubecontainer.Pod, pod
...
@@ -1399,20 +1398,28 @@ func (dm *DockerManager) SyncPod(pod *api.Pod, runningPod kubecontainer.Pod, pod
}
}
// Start everything
// Start everything
for
container
:=
range
containerChanges
.
ContainersToStart
{
for
idx
:=
range
containerChanges
.
ContainersToStart
{
glog
.
V
(
4
)
.
Infof
(
"Creating container %+v"
,
pod
.
Spec
.
Containers
[
container
])
container
:=
&
pod
.
Spec
.
Containers
[
idx
]
containerSpec
:=
&
pod
.
Spec
.
Containers
[
container
]
glog
.
V
(
4
)
.
Infof
(
"Creating container %+v"
,
container
)
if
err
:=
dm
.
pullImage
(
pod
,
containerSpec
);
err
!=
nil
{
err
:=
dm
.
pullImage
(
pod
,
container
)
glog
.
Warningf
(
"Failed to pull image %q from pod %q and container %q: %v"
,
containerSpec
.
Image
,
kubecontainer
.
GetPodFullName
(
pod
),
containerSpec
.
Name
,
err
)
dm
.
updateReasonCache
(
pod
,
container
,
err
)
if
err
!=
nil
{
glog
.
Warningf
(
"Failed to pull image %q from pod %q and container %q: %v"
,
container
.
Image
,
kubecontainer
.
GetPodFullName
(
pod
),
container
.
Name
,
err
)
continue
continue
}
}
// TODO(dawnchen): Check RestartPolicy.DelaySeconds before restart a container
// TODO(dawnchen): Check RestartPolicy.DelaySeconds before restart a container
namespaceMode
:=
fmt
.
Sprintf
(
"container:%v"
,
podInfraContainerID
)
namespaceMode
:=
fmt
.
Sprintf
(
"container:%v"
,
podInfraContainerID
)
_
,
err
:=
dm
.
RunContainer
(
pod
,
containerSpec
,
namespaceMode
,
namespaceMode
)
_
,
err
=
dm
.
RunContainer
(
pod
,
container
,
namespaceMode
,
namespaceMode
)
dm
.
updateReasonCache
(
pod
,
container
,
err
)
if
err
!=
nil
{
if
err
!=
nil
{
// TODO(bburns) : Perhaps blacklist a container after N failures?
// TODO(bburns) : Perhaps blacklist a container after N failures?
glog
.
Errorf
(
"Error running pod %q container %q: %v"
,
kubecontainer
.
GetPodFullName
(
pod
),
containerSpec
.
Name
,
err
)
glog
.
Errorf
(
"Error running pod %q container %q: %v"
,
kubecontainer
.
GetPodFullName
(
pod
),
container
.
Name
,
err
)
continue
}
}
// Successfully started the container; clear the entry in the failure
// reason cache.
dm
.
clearReasonCache
(
pod
,
container
)
}
}
return
nil
return
nil
...
...
pkg/kubelet/kubelet_test.go
View file @
9ded52ac
...
@@ -4054,38 +4054,125 @@ func TestGetPodStatusWithLastTermination(t *testing.T) {
...
@@ -4054,38 +4054,125 @@ func TestGetPodStatusWithLastTermination(t *testing.T) {
}
}
}
}
// TODO(vmarmol): Move this test away from using RunContainer().
func
TestGetPodCreationFailureReason
(
t
*
testing
.
T
)
{
func
TestGetPodCreationFailureReason
(
t
*
testing
.
T
)
{
testKubelet
:=
newTestKubelet
(
t
)
testKubelet
:=
newTestKubelet
(
t
)
testKubelet
.
fakeCadvisor
.
On
(
"MachineInfo"
)
.
Return
(
&
cadvisorApi
.
MachineInfo
{},
nil
)
kubelet
:=
testKubelet
.
kubelet
kubelet
:=
testKubelet
.
kubelet
fakeDocker
:=
testKubelet
.
fakeDocker
fakeDocker
:=
testKubelet
.
fakeDocker
waitGroup
:=
testKubelet
.
waitGroup
// Inject the creation failure error to docker.
failureReason
:=
"creation failure"
failureReason
:=
"creation failure"
fakeDocker
.
Errors
=
map
[
string
]
error
{
fakeDocker
.
Errors
=
map
[
string
]
error
{
"create"
:
fmt
.
Errorf
(
"%s"
,
failureReason
),
"create"
:
fmt
.
Errorf
(
"%s"
,
failureReason
),
}
}
fakeDocker
.
ContainerList
=
[]
docker
.
APIContainers
{}
pod
:=
&
api
.
Pod
{
pod
:=
&
api
.
Pod
{
ObjectMeta
:
api
.
ObjectMeta
{
ObjectMeta
:
api
.
ObjectMeta
{
UID
:
"12345678"
,
UID
:
"12345678"
,
Name
:
"
bar
"
,
Name
:
"
foo
"
,
Namespace
:
"new"
,
Namespace
:
"new"
,
},
},
Spec
:
api
.
PodSpec
{
Spec
:
api
.
PodSpec
{
Containers
:
[]
api
.
Container
{
Containers
:
[]
api
.
Container
{{
Name
:
"bar"
}},
{
Name
:
"foo"
},
},
},
}
// Pretend that the pod infra container has already been created, so that
// we can run the user containers.
fakeDocker
.
ContainerList
=
[]
docker
.
APIContainers
{
{
Names
:
[]
string
{
"/k8s_POD."
+
strconv
.
FormatUint
(
generatePodInfraContainerHash
(
pod
),
16
)
+
"_foo_new_12345678_0"
},
ID
:
"9876"
,
},
}
fakeDocker
.
ContainerMap
=
map
[
string
]
*
docker
.
Container
{
"9876"
:
{
ID
:
"9876"
,
HostConfig
:
&
docker
.
HostConfig
{},
Config
:
&
docker
.
Config
{},
},
},
}
}
pods
:=
[]
*
api
.
Pod
{
pod
}
pods
:=
[]
*
api
.
Pod
{
pod
}
kubelet
.
podManager
.
SetPods
(
pods
)
kubelet
.
podManager
.
SetPods
(
pods
)
kubelet
.
volumeManager
.
SetVolumes
(
pod
.
UID
,
kubecontainer
.
VolumeMap
{})
kubelet
.
volumeManager
.
SetVolumes
(
pod
.
UID
,
kubecontainer
.
VolumeMap
{})
// TODO: Move this test to dockertools so that we don't have to do the hacky
waitGroup
.
Add
(
1
)
// type assertion here.
err
:=
kubelet
.
SyncPods
(
pods
,
emptyPodUIDs
,
map
[
string
]
*
api
.
Pod
{},
time
.
Now
())
if
err
!=
nil
{
t
.
Errorf
(
"unexpected error: %v"
,
err
)
}
waitGroup
.
Wait
()
status
,
err
:=
kubelet
.
GetPodStatus
(
kubecontainer
.
GetPodFullName
(
pod
))
if
err
!=
nil
{
t
.
Errorf
(
"unexpected error %v"
,
err
)
}
if
len
(
status
.
ContainerStatuses
)
<
1
{
t
.
Errorf
(
"expected 1 container status, got %d"
,
len
(
status
.
ContainerStatuses
))
}
else
{
state
:=
status
.
ContainerStatuses
[
0
]
.
State
if
state
.
Waiting
==
nil
{
t
.
Errorf
(
"expected waiting state, got %#v"
,
state
)
}
else
if
state
.
Waiting
.
Reason
!=
failureReason
{
t
.
Errorf
(
"expected reason %q, got %q"
,
failureReason
,
state
.
Waiting
.
Reason
)
}
}
}
func
TestGetPodPullImageFailureReason
(
t
*
testing
.
T
)
{
testKubelet
:=
newTestKubelet
(
t
)
testKubelet
.
fakeCadvisor
.
On
(
"MachineInfo"
)
.
Return
(
&
cadvisorApi
.
MachineInfo
{},
nil
)
kubelet
:=
testKubelet
.
kubelet
fakeDocker
:=
testKubelet
.
fakeDocker
waitGroup
:=
testKubelet
.
waitGroup
// Initialize the FakeDockerPuller so that it'd try to pull non-existent
// images.
dm
:=
kubelet
.
containerRuntime
.
(
*
dockertools
.
DockerManager
)
dm
:=
kubelet
.
containerRuntime
.
(
*
dockertools
.
DockerManager
)
_
,
err
:=
dm
.
RunContainer
(
pod
,
&
pod
.
Spec
.
Containers
[
0
],
""
,
""
)
puller
:=
dm
.
Puller
.
(
*
dockertools
.
FakeDockerPuller
)
if
err
==
nil
{
puller
.
HasImages
=
[]
string
{}
t
.
Errorf
(
"expected error, found nil"
)
// Inject the pull image failure error.
failureReason
:=
"pull image faiulre"
puller
.
ErrorsToInject
=
[]
error
{
fmt
.
Errorf
(
"%s"
,
failureReason
)}
pod
:=
&
api
.
Pod
{
ObjectMeta
:
api
.
ObjectMeta
{
UID
:
"12345678"
,
Name
:
"foo"
,
Namespace
:
"new"
,
},
Spec
:
api
.
PodSpec
{
Containers
:
[]
api
.
Container
{{
Name
:
"bar"
,
Image
:
"realImage"
,
ImagePullPolicy
:
api
.
PullAlways
}},
},
}
}
// Pretend that the pod infra container has already been created, so that
// we can run the user containers.
fakeDocker
.
ContainerList
=
[]
docker
.
APIContainers
{
{
Names
:
[]
string
{
"/k8s_POD."
+
strconv
.
FormatUint
(
generatePodInfraContainerHash
(
pod
),
16
)
+
"_foo_new_12345678_0"
},
ID
:
"9876"
,
},
}
fakeDocker
.
ContainerMap
=
map
[
string
]
*
docker
.
Container
{
"9876"
:
{
ID
:
"9876"
,
HostConfig
:
&
docker
.
HostConfig
{},
Config
:
&
docker
.
Config
{},
},
}
pods
:=
[]
*
api
.
Pod
{
pod
}
kubelet
.
podManager
.
SetPods
(
pods
)
kubelet
.
volumeManager
.
SetVolumes
(
pod
.
UID
,
kubecontainer
.
VolumeMap
{})
waitGroup
.
Add
(
1
)
err
:=
kubelet
.
SyncPods
(
pods
,
emptyPodUIDs
,
map
[
string
]
*
api
.
Pod
{},
time
.
Now
())
if
err
!=
nil
{
t
.
Errorf
(
"unexpected error: %v"
,
err
)
}
waitGroup
.
Wait
()
status
,
err
:=
kubelet
.
GetPodStatus
(
kubecontainer
.
GetPodFullName
(
pod
))
status
,
err
:=
kubelet
.
GetPodStatus
(
kubecontainer
.
GetPodFullName
(
pod
))
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Errorf
(
"unexpected error %v"
,
err
)
t
.
Errorf
(
"unexpected error %v"
,
err
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment