Add timeouts for docker queries
As these can otherwise block indefinitely due to docker issues. This is to fix https://github.com/kubernetes/kubernetes/issues/53207, where kubelet relies on cadvisor for gathering docker information as part of its periodic node status update.
This commit is contained in:
parent
7d11f4243f
commit
57e17d8be2
@ -23,26 +23,33 @@ import (
|
||||
dockertypes "github.com/docker/docker/api/types"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"time"
|
||||
|
||||
"github.com/google/cadvisor/info/v1"
|
||||
"github.com/google/cadvisor/machine"
|
||||
)
|
||||
|
||||
const defaultTimeout = time.Second * 5
|
||||
|
||||
func defaultContext() context.Context {
|
||||
ctx, _ := context.WithTimeout(context.Background(), defaultTimeout)
|
||||
return ctx
|
||||
}
|
||||
|
||||
func Status() (v1.DockerStatus, error) {
|
||||
client, err := Client()
|
||||
if err != nil {
|
||||
return v1.DockerStatus{}, fmt.Errorf("unable to communicate with docker daemon: %v", err)
|
||||
}
|
||||
dockerInfo, err := client.Info(context.Background())
|
||||
dockerInfo, err := client.Info(defaultContext())
|
||||
if err != nil {
|
||||
return v1.DockerStatus{}, err
|
||||
}
|
||||
return StatusFromDockerInfo(dockerInfo), nil
|
||||
return StatusFromDockerInfo(dockerInfo)
|
||||
}
|
||||
|
||||
func StatusFromDockerInfo(dockerInfo dockertypes.Info) v1.DockerStatus {
|
||||
func StatusFromDockerInfo(dockerInfo dockertypes.Info) (v1.DockerStatus, error) {
|
||||
out := v1.DockerStatus{}
|
||||
out.Version = VersionString()
|
||||
out.APIVersion = APIVersionString()
|
||||
out.KernelVersion = machine.KernelVersion()
|
||||
out.OS = dockerInfo.OperatingSystem
|
||||
out.Hostname = dockerInfo.Name
|
||||
@ -54,7 +61,18 @@ func StatusFromDockerInfo(dockerInfo dockertypes.Info) v1.DockerStatus {
|
||||
for _, v := range dockerInfo.DriverStatus {
|
||||
out.DriverStatus[v[0]] = v[1]
|
||||
}
|
||||
return out
|
||||
var err error
|
||||
ver, err := VersionString()
|
||||
if err != nil {
|
||||
return out, err
|
||||
}
|
||||
out.Version = ver
|
||||
ver, err = APIVersionString()
|
||||
if err != nil {
|
||||
return out, err
|
||||
}
|
||||
out.APIVersion = ver
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func Images() ([]v1.DockerImage, error) {
|
||||
@ -62,7 +80,7 @@ func Images() ([]v1.DockerImage, error) {
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to communicate with docker daemon: %v", err)
|
||||
}
|
||||
images, err := client.ImageList(context.Background(), dockertypes.ImageListOptions{All: false})
|
||||
images, err := client.ImageList(defaultContext(), dockertypes.ImageListOptions{All: false})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -95,14 +113,14 @@ func ValidateInfo() (*dockertypes.Info, error) {
|
||||
return nil, fmt.Errorf("unable to communicate with docker daemon: %v", err)
|
||||
}
|
||||
|
||||
dockerInfo, err := client.Info(context.Background())
|
||||
dockerInfo, err := client.Info(defaultContext())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to detect Docker info: %v", err)
|
||||
}
|
||||
|
||||
// Fall back to version API if ServerVersion is not set in info.
|
||||
if dockerInfo.ServerVersion == "" {
|
||||
version, err := client.ServerVersion(context.Background())
|
||||
version, err := client.ServerVersion(defaultContext())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to get docker version: %v", err)
|
||||
}
|
||||
@ -125,35 +143,43 @@ func ValidateInfo() (*dockertypes.Info, error) {
|
||||
}
|
||||
|
||||
func Version() ([]int, error) {
|
||||
return parseVersion(VersionString(), version_re, 3)
|
||||
ver, err := VersionString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return parseVersion(ver, version_re, 3)
|
||||
}
|
||||
|
||||
func APIVersion() ([]int, error) {
|
||||
return parseVersion(APIVersionString(), apiversion_re, 2)
|
||||
ver, err := APIVersionString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return parseVersion(ver, apiversion_re, 2)
|
||||
}
|
||||
|
||||
func VersionString() string {
|
||||
func VersionString() (string, error) {
|
||||
docker_version := "Unknown"
|
||||
client, err := Client()
|
||||
if err == nil {
|
||||
version, err := client.ServerVersion(context.Background())
|
||||
version, err := client.ServerVersion(defaultContext())
|
||||
if err == nil {
|
||||
docker_version = version.Version
|
||||
}
|
||||
}
|
||||
return docker_version
|
||||
return docker_version, err
|
||||
}
|
||||
|
||||
func APIVersionString() string {
|
||||
func APIVersionString() (string, error) {
|
||||
docker_api_version := "Unknown"
|
||||
client, err := Client()
|
||||
if err == nil {
|
||||
version, err := client.ServerVersion(context.Background())
|
||||
version, err := client.ServerVersion(defaultContext())
|
||||
if err == nil {
|
||||
docker_api_version = version.APIVersion
|
||||
}
|
||||
}
|
||||
return docker_api_version
|
||||
return docker_api_version, err
|
||||
}
|
||||
|
||||
func parseVersion(version_string string, regex *regexp.Regexp, length int) ([]int, error) {
|
||||
|
@ -340,7 +340,8 @@ func Register(factory info.MachineInfoFactory, fsInfo fs.FsInfo, ignoreMetrics c
|
||||
glog.Errorf("devicemapper filesystem stats will not be reported: %v", err)
|
||||
}
|
||||
|
||||
status := StatusFromDockerInfo(*dockerInfo)
|
||||
// Safe to ignore error - driver status should always be populated.
|
||||
status, _ := StatusFromDockerInfo(*dockerInfo)
|
||||
thinPoolName = status.DriverStatus[dockerutil.DriverStatusPoolName]
|
||||
}
|
||||
|
||||
|
@ -1343,8 +1343,14 @@ func getVersionInfo() (*info.VersionInfo, error) {
|
||||
|
||||
kernel_version := machine.KernelVersion()
|
||||
container_os := machine.ContainerOsVersion()
|
||||
docker_version := docker.VersionString()
|
||||
docker_api_version := docker.APIVersionString()
|
||||
docker_version, err := docker.VersionString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
docker_api_version, err := docker.APIVersionString()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &info.VersionInfo{
|
||||
KernelVersion: kernel_version,
|
||||
|
Loading…
Reference in New Issue
Block a user