Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support readiness checks #4048

Merged
merged 4 commits into from
Feb 10, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions cmd/integration/integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ func (fakeKubeletClient) GetPodStatus(host, podNamespace, podID string) (api.Pod
r.Status.PodIP = "1.2.3.4"
m := make(api.PodInfo)
for k, v := range r.Status.Info {
v.Ready = true
v.PodIP = "1.2.3.4"
m[k] = v
}
Expand Down
104 changes: 61 additions & 43 deletions pkg/api/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -339,10 +339,11 @@ type Container struct {
Ports []Port `json:"ports,omitempty"`
Env []EnvVar `json:"env,omitempty"`
// Compute resource requirements.
Resources ResourceRequirements `json:"resources,omitempty"`
VolumeMounts []VolumeMount `json:"volumeMounts,omitempty"`
LivenessProbe *Probe `json:"livenessProbe,omitempty"`
Lifecycle *Lifecycle `json:"lifecycle,omitempty"`
Resources ResourceRequirements `json:"resources,omitempty"`
VolumeMounts []VolumeMount `json:"volumeMounts,omitempty"`
LivenessProbe *Probe `json:"livenessProbe,omitempty"`
ReadinessProbe *Probe `json:"readinessProbe,omitempty"`
Lifecycle *Lifecycle `json:"lifecycle,omitempty"`
// Optional: Defaults to /dev/termination-log
TerminationMessagePath string `json:"terminationMessagePath,omitempty"`
// Optional: Default to false.
Expand Down Expand Up @@ -380,27 +381,16 @@ type Lifecycle struct {

// The below types are used by kube_client and api_server.

// PodPhase is a label for the condition of a pod at the current time.
type PodPhase string
type ConditionStatus string

// These are the valid statuses of pods.
// These are valid condition statuses. "ConditionFull" means a resource is in the condition;
// "ConditionNone" means a resource is not in the condition; "ConditionUnknown" means kubernetes
// can't decide if a resource is in the condition or not. In the future, we could add other
// intermediate conditions, e.g. ConditionDegraded.
const (
// PodPending means the pod has been accepted by the system, but one or more of the containers
// has not been started. This includes time before being bound to a node, as well as time spent
// pulling images onto the host.
PodPending PodPhase = "Pending"
// PodRunning means the pod has been bound to a node and all of the containers have been started.
// At least one container is still running or is in the process of being restarted.
PodRunning PodPhase = "Running"
// PodSucceeded means that all containers in the pod have voluntarily terminated
// with a container exit code of 0, and the system is not going to restart any of these containers.
PodSucceeded PodPhase = "Succeeded"
// PodFailed means that all containers in the pod have terminated, and at least one container has
// terminated in a failure (exited with a non-zero exit code or was stopped by the system).
PodFailed PodPhase = "Failed"
// PodUnknown means that for some reason the state of the pod could not be obtained, typically due
// to an error in communicating with the host of the pod.
PodUnknown PodPhase = "Unknown"
ConditionFull ConditionStatus = "Full"
ConditionNone ConditionStatus = "None"
ConditionUnknown ConditionStatus = "Unknown"
)

type ContainerStateWaiting struct {
Expand Down Expand Up @@ -434,6 +424,8 @@ type ContainerStatus struct {
// TODO(dchen1107): Should we rename PodStatus to a more generic name or have a separate states
// defined for container?
State ContainerState `json:"state,omitempty"`
// Ready specifies whether the conatiner has passed its readiness check.
Ready bool `json:"ready"`
// Note that this is calculated from dead containers. But those containers are subject to
// garbage collection. This value will get capped at 5 by GC.
RestartCount int `json:"restartCount"`
Expand All @@ -446,6 +438,44 @@ type ContainerStatus struct {
ContainerID string `json:"containerID,omitempty" description:"container's ID in the format 'docker://<container_id>'"`
}

// PodPhase is a label for the condition of a pod at the current time.
type PodPhase string

// These are the valid statuses of pods.
const (
// PodPending means the pod has been accepted by the system, but one or more of the containers
// has not been started. This includes time before being bound to a node, as well as time spent
// pulling images onto the host.
PodPending PodPhase = "Pending"
// PodRunning means the pod has been bound to a node and all of the containers have been started.
// At least one container is still running or is in the process of being restarted.
PodRunning PodPhase = "Running"
// PodSucceeded means that all containers in the pod have voluntarily terminated
// with a container exit code of 0, and the system is not going to restart any of these containers.
PodSucceeded PodPhase = "Succeeded"
// PodFailed means that all containers in the pod have terminated, and at least one container has
// terminated in a failure (exited with a non-zero exit code or was stopped by the system).
PodFailed PodPhase = "Failed"
// PodUnknown means that for some reason the state of the pod could not be obtained, typically due
// to an error in communicating with the host of the pod.
PodUnknown PodPhase = "Unknown"
)

type PodConditionKind string

// These are valid conditions of pod.
const (
// PodReady means the pod is able to service requests and should be added to the
// load balancing pools of all matching services.
PodReady PodConditionKind = "Ready"
)

// TODO: add LastTransitionTime, Reason, Message to match NodeCondition api.
type PodCondition struct {
Kind PodConditionKind `json:"kind"`
Status ConditionStatus `json:"status"`
}

// PodInfo contains one entry for every container with available info.
type PodInfo map[string]ContainerStatus

Expand Down Expand Up @@ -516,8 +546,8 @@ type PodSpec struct {
// PodStatus represents information about the status of a pod. Status may trail the actual
// state of a system.
type PodStatus struct {
Phase PodPhase `json:"phase,omitempty"`

Phase PodPhase `json:"phase,omitempty"`
Conditions []PodCondition `json:"Condition,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not clear to me why this is an array?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per @bgrant0607's suggestion, this is intended to be like NodCondition as he expects to add more conditions in the future. I stopped short of creating the PodCondition struct but I could in order to fully mirror NodeCondition api. Until more PodConditions are added, Ready bool would be a functional substitute for Conditions. So I guess it comes down to whether we want to add PodCondition to the api now or hold off until later.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to add PodCondition now. I'm ok we initially omit some fields, such as LastTransitionTime, Reason, and Message.

// A human readable message indicating details about why the pod is in this state.
Message string `json:"message,omitempty"`

Expand Down Expand Up @@ -759,25 +789,13 @@ const (
NodeReady NodeConditionKind = "Ready"
)

type NodeConditionStatus string

// These are valid condition status. "ConditionFull" means node is in the condition;
// "ConditionNone" means node is not in the condition; "ConditionUnknown" means kubernetes
// can't decide if node is in the condition or not. In the future, we could add other
// intermediate conditions, e.g. ConditionDegraded.
const (
ConditionFull NodeConditionStatus = "Full"
ConditionNone NodeConditionStatus = "None"
ConditionUnknown NodeConditionStatus = "Unknown"
)

type NodeCondition struct {
Kind NodeConditionKind `json:"kind"`
Status NodeConditionStatus `json:"status"`
LastProbeTime util.Time `json:"lastProbeTime,omitempty"`
LastTransitionTime util.Time `json:"lastTransitionTime,omitempty"`
Reason string `json:"reason,omitempty"`
Message string `json:"message,omitempty"`
Kind NodeConditionKind `json:"kind"`
Status ConditionStatus `json:"status"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for doing this refactoring.

FYI, I'm going to try to merge #4241 first, since we're having a bunch of problems in that area right now.

LastProbeTime util.Time `json:"lastProbeTime,omitempty"`
LastTransitionTime util.Time `json:"lastTransitionTime,omitempty"`
Reason string `json:"reason,omitempty"`
Message string `json:"message,omitempty"`
}

// NodeResources is an object for conveying resource information about a node.
Expand Down
12 changes: 12 additions & 0 deletions pkg/api/v1beta1/conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,9 @@ func init() {
if err := s.Convert(&in.Phase, &out.Status, 0); err != nil {
return err
}
if err := s.Convert(&in.Conditions, &out.Conditions, 0); err != nil {
return err
}
if err := s.Convert(&in.Info, &out.Info, 0); err != nil {
return err
}
Expand All @@ -194,6 +197,9 @@ func init() {
if err := s.Convert(&in.Status, &out.Phase, 0); err != nil {
return err
}
if err := s.Convert(&in.Conditions, &out.Conditions, 0); err != nil {
return err
}
if err := s.Convert(&in.Info, &out.Info, 0); err != nil {
return err
}
Expand Down Expand Up @@ -489,6 +495,9 @@ func init() {
if err := s.Convert(&in.LivenessProbe, &out.LivenessProbe, 0); err != nil {
return err
}
if err := s.Convert(&in.ReadinessProbe, &out.ReadinessProbe, 0); err != nil {
return err
}
if err := s.Convert(&in.Lifecycle, &out.Lifecycle, 0); err != nil {
return err
}
Expand Down Expand Up @@ -569,6 +578,9 @@ func init() {
if err := s.Convert(&in.LivenessProbe, &out.LivenessProbe, 0); err != nil {
return err
}
if err := s.Convert(&in.ReadinessProbe, &out.ReadinessProbe, 0); err != nil {
return err
}
if err := s.Convert(&in.Lifecycle, &out.Lifecycle, 0); err != nil {
return err
}
Expand Down
66 changes: 42 additions & 24 deletions pkg/api/v1beta1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,10 +281,11 @@ type Container struct {
// Optional: Defaults to unlimited.
CPU int `json:"cpu,omitempty" description:"CPU share in thousandths of a core"`
// Optional: Defaults to unlimited.
Memory int64 `json:"memory,omitempty" description:"memory limit in bytes; defaults to unlimited"`
VolumeMounts []VolumeMount `json:"volumeMounts,omitempty" description:"pod volumes to mount into the container's filesystem"`
LivenessProbe *LivenessProbe `json:"livenessProbe,omitempty" description:"periodic probe of container liveness; container will be restarted if the probe fails"`
Lifecycle *Lifecycle `json:"lifecycle,omitempty" description:"actions that the management system should take in response to container lifecycle events"`
Memory int64 `json:"memory,omitempty" description:"memory limit in bytes; defaults to unlimited"`
VolumeMounts []VolumeMount `json:"volumeMounts,omitempty" description:"pod volumes to mount into the container's filesystem"`
LivenessProbe *LivenessProbe `json:"livenessProbe,omitempty" description:"periodic probe of container liveness; container will be restarted if the probe fails"`
ReadinessProbe *LivenessProbe `json:"readinessProbe,omitempty" description:"periodic probe of container service readiness; container will be removed from service endpoints if the probe fails"`
Lifecycle *Lifecycle `json:"lifecycle,omitempty" description:"actions that the management system should take in response to container lifecycle events"`
// Optional: Defaults to /dev/termination-log
TerminationMessagePath string `json:"terminationMessagePath,omitempty" description:"path at which the file to which the container's termination message will be written is mounted into the container's filesystem; message written is intended to be brief final status, such as an assertion failure message; defaults to /dev/termination-log"`
// Optional: Default to false.
Expand Down Expand Up @@ -352,6 +353,18 @@ type TypeMeta struct {
Annotations map[string]string `json:"annotations,omitempty" description:"map of string keys and values that can be used by external tooling to store and retrieve arbitrary metadata about the object"`
}

type ConditionStatus string

// These are valid condition statuses. "ConditionFull" means a resource is in the condition;
// "ConditionNone" means a resource is not in the condition; "ConditionUnknown" means kubernetes
// can't decide if a resource is in the condition or not. In the future, we could add other
// intermediate conditions, e.g. ConditionDegraded.
const (
ConditionFull ConditionStatus = "Full"
ConditionNone ConditionStatus = "None"
ConditionUnknown ConditionStatus = "Unknown"
)

// PodStatus represents a status of a pod.
type PodStatus string

Expand Down Expand Up @@ -400,6 +413,7 @@ type ContainerStatus struct {
// TODO(dchen1107): Should we rename PodStatus to a more generic name or have a separate states
// defined for container?
State ContainerState `json:"state,omitempty" description:"details about the container's current condition"`
Ready bool `json:"ready" description:"specifies whether the container has passed its readiness probe"`
// Note that this is calculated from dead containers. But those containers are subject to
// garbage collection. This value will get capped at 5 by GC.
RestartCount int `json:"restartCount" description:"the number of times the container has been restarted, currently based on the number of dead containers that have not yet been removed"`
Expand All @@ -412,6 +426,21 @@ type ContainerStatus struct {
ContainerID string `json:"containerID,omitempty" description:"container's ID in the format 'docker://<container_id>'"`
}

type PodConditionKind string

// These are valid conditions of pod.
const (
// PodReady means the pod is able to service requests and should be added to the
// load balancing pools of all matching services.
PodReady PodConditionKind = "Ready"
)

// TODO: add LastTransitionTime, Reason, Message to match NodeCondition api.
type PodCondition struct {
Kind PodConditionKind `json:"kind"`
Status ConditionStatus `json:"status"`
}

// PodInfo contains one entry for every container with available info.
type PodInfo map[string]ContainerStatus

Expand Down Expand Up @@ -440,8 +469,9 @@ type RestartPolicy struct {

// PodState is the state of a pod, used as either input (desired state) or output (current state).
type PodState struct {
Manifest ContainerManifest `json:"manifest,omitempty" description:"manifest of containers and volumes comprising the pod"`
Status PodStatus `json:"status,omitempty" description:"current condition of the pod, Waiting, Running, or Terminated"`
Manifest ContainerManifest `json:"manifest,omitempty" description:"manifest of containers and volumes comprising the pod"`
Status PodStatus `json:"status,omitempty" description:"current condition of the pod, Waiting, Running, or Terminated"`
Conditions []PodCondition `json:"Condition,omitempty" description:"current service state of pod"`
// A human readable message indicating details about why the pod is in this state.
Message string `json:"message,omitempty" description:"human readable message indicating details about why the pod is in this condition"`
Host string `json:"host,omitempty" description:"host to which the pod is assigned; empty if not yet scheduled"`
Expand Down Expand Up @@ -604,25 +634,13 @@ const (
NodeReady NodeConditionKind = "Ready"
)

type NodeConditionStatus string

// These are valid condition status. "ConditionFull" means node is in the condition;
// "ConditionNone" means node is not in the condition; "ConditionUnknown" means kubernetes
// can't decide if node is in the condition or not. In the future, we could add other
// intermediate conditions, e.g. ConditionDegraded.
const (
ConditionFull NodeConditionStatus = "Full"
ConditionNone NodeConditionStatus = "None"
ConditionUnknown NodeConditionStatus = "Unknown"
)

type NodeCondition struct {
Kind NodeConditionKind `json:"kind" description:"kind of the condition, one of reachable, ready"`
Status NodeConditionStatus `json:"status" description:"status of the condition, one of full, none, unknown"`
LastProbeTime util.Time `json:"lastProbeTime,omitempty" description:"last time the condition was probed"`
LastTransitionTime util.Time `json:"lastTransitionTime,omitempty" description:"last time the condition transit from one status to another"`
Reason string `json:"reason,omitempty" description:"(brief) reason for the condition's last transition"`
Message string `json:"message,omitempty" description:"human readable message indicating details about last transition"`
Kind NodeConditionKind `json:"kind" description:"kind of the condition, one of reachable, ready"`
Status ConditionStatus `json:"status" description:"status of the condition, one of full, none, unknown"`
LastProbeTime util.Time `json:"lastProbeTime,omitempty" description:"last time the condition was probed"`
LastTransitionTime util.Time `json:"lastTransitionTime,omitempty" description:"last time the condition transit from one status to another"`
Reason string `json:"reason,omitempty" description:"(brief) reason for the condition's last transition"`
Message string `json:"message,omitempty" description:"human readable message indicating details about last transition"`
}

// NodeResources represents resources on a Kubernetes system node
Expand Down
12 changes: 12 additions & 0 deletions pkg/api/v1beta2/conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,9 @@ func init() {
if err := s.Convert(&in.LivenessProbe, &out.LivenessProbe, 0); err != nil {
return err
}
if err := s.Convert(&in.ReadinessProbe, &out.ReadinessProbe, 0); err != nil {
return err
}
if err := s.Convert(&in.Lifecycle, &out.Lifecycle, 0); err != nil {
return err
}
Expand Down Expand Up @@ -423,6 +426,9 @@ func init() {
if err := s.Convert(&in.LivenessProbe, &out.LivenessProbe, 0); err != nil {
return err
}
if err := s.Convert(&in.ReadinessProbe, &out.ReadinessProbe, 0); err != nil {
return err
}
if err := s.Convert(&in.Lifecycle, &out.Lifecycle, 0); err != nil {
return err
}
Expand Down Expand Up @@ -475,6 +481,9 @@ func init() {
if err := s.Convert(&in.Info, &out.Info, 0); err != nil {
return err
}
if err := s.Convert(&in.Conditions, &out.Conditions, 0); err != nil {
return err
}
out.Message = in.Message
out.Host = in.Host
out.HostIP = in.HostIP
Expand All @@ -488,6 +497,9 @@ func init() {
if err := s.Convert(&in.Info, &out.Info, 0); err != nil {
return err
}
if err := s.Convert(&in.Conditions, &out.Conditions, 0); err != nil {
return err
}
out.Message = in.Message
out.Host = in.Host
out.HostIP = in.HostIP
Expand Down