cmd/kube-controller-manager

This commit is contained in:
Chao Xu
2016-11-18 12:50:17 -08:00
parent 48536eaef9
commit 7eeb71f698
109 changed files with 4380 additions and 4153 deletions

View File

@@ -26,11 +26,13 @@ import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/meta"
"k8s.io/kubernetes/pkg/api/unversioned"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/api/validation"
"k8s.io/kubernetes/pkg/apis/extensions"
extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
"k8s.io/kubernetes/pkg/client/cache"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/release_1_5"
"k8s.io/kubernetes/pkg/client/record"
"k8s.io/kubernetes/pkg/conversion"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util/clock"
@@ -363,11 +365,11 @@ const (
// created as an interface to allow testing.
type PodControlInterface interface {
// CreatePods creates new pods according to the spec.
CreatePods(namespace string, template *api.PodTemplateSpec, object runtime.Object) error
CreatePods(namespace string, template *v1.PodTemplateSpec, object runtime.Object) error
// CreatePodsOnNode creates a new pod according to the spec on the specified node.
CreatePodsOnNode(nodeName, namespace string, template *api.PodTemplateSpec, object runtime.Object) error
CreatePodsOnNode(nodeName, namespace string, template *v1.PodTemplateSpec, object runtime.Object) error
// CreatePodsWithControllerRef creates new pods according to the spec, and sets object as the pod's controller.
CreatePodsWithControllerRef(namespace string, template *api.PodTemplateSpec, object runtime.Object, controllerRef *api.OwnerReference) error
CreatePodsWithControllerRef(namespace string, template *v1.PodTemplateSpec, object runtime.Object, controllerRef *v1.OwnerReference) error
// DeletePod deletes the pod identified by podID.
DeletePod(namespace string, podID string, object runtime.Object) error
// PatchPod patches the pod.
@@ -382,7 +384,7 @@ type RealPodControl struct {
var _ PodControlInterface = &RealPodControl{}
func getPodsLabelSet(template *api.PodTemplateSpec) labels.Set {
func getPodsLabelSet(template *v1.PodTemplateSpec) labels.Set {
desiredLabels := make(labels.Set)
for k, v := range template.Labels {
desiredLabels[k] = v
@@ -390,18 +392,18 @@ func getPodsLabelSet(template *api.PodTemplateSpec) labels.Set {
return desiredLabels
}
func getPodsFinalizers(template *api.PodTemplateSpec) []string {
func getPodsFinalizers(template *v1.PodTemplateSpec) []string {
desiredFinalizers := make([]string, len(template.Finalizers))
copy(desiredFinalizers, template.Finalizers)
return desiredFinalizers
}
func getPodsAnnotationSet(template *api.PodTemplateSpec, object runtime.Object) (labels.Set, error) {
func getPodsAnnotationSet(template *v1.PodTemplateSpec, object runtime.Object) (labels.Set, error) {
desiredAnnotations := make(labels.Set)
for k, v := range template.Annotations {
desiredAnnotations[k] = v
}
createdByRef, err := api.GetReference(object)
createdByRef, err := v1.GetReference(object)
if err != nil {
return desiredAnnotations, fmt.Errorf("unable to get controller reference: %v", err)
}
@@ -409,15 +411,15 @@ func getPodsAnnotationSet(template *api.PodTemplateSpec, object runtime.Object)
// TODO: this code was not safe previously - as soon as new code came along that switched to v2, old clients
// would be broken upon reading it. This is explicitly hardcoded to v1 to guarantee predictable deployment.
// We need to consistently handle this case of annotation versioning.
codec := api.Codecs.LegacyCodec(unversioned.GroupVersion{Group: api.GroupName, Version: "v1"})
codec := api.Codecs.LegacyCodec(unversioned.GroupVersion{Group: v1.GroupName, Version: "v1"})
createdByRefJson, err := runtime.Encode(codec, &api.SerializedReference{
createdByRefJson, err := runtime.Encode(codec, &v1.SerializedReference{
Reference: *createdByRef,
})
if err != nil {
return desiredAnnotations, fmt.Errorf("unable to serialize controller reference: %v", err)
}
desiredAnnotations[api.CreatedByAnnotation] = string(createdByRefJson)
desiredAnnotations[v1.CreatedByAnnotation] = string(createdByRefJson)
return desiredAnnotations, nil
}
@@ -430,11 +432,11 @@ func getPodsPrefix(controllerName string) string {
return prefix
}
func (r RealPodControl) CreatePods(namespace string, template *api.PodTemplateSpec, object runtime.Object) error {
func (r RealPodControl) CreatePods(namespace string, template *v1.PodTemplateSpec, object runtime.Object) error {
return r.createPods("", namespace, template, object, nil)
}
func (r RealPodControl) CreatePodsWithControllerRef(namespace string, template *api.PodTemplateSpec, controllerObject runtime.Object, controllerRef *api.OwnerReference) error {
func (r RealPodControl) CreatePodsWithControllerRef(namespace string, template *v1.PodTemplateSpec, controllerObject runtime.Object, controllerRef *v1.OwnerReference) error {
if controllerRef == nil {
return fmt.Errorf("controllerRef is nil")
}
@@ -450,7 +452,7 @@ func (r RealPodControl) CreatePodsWithControllerRef(namespace string, template *
return r.createPods("", namespace, template, controllerObject, controllerRef)
}
func (r RealPodControl) CreatePodsOnNode(nodeName, namespace string, template *api.PodTemplateSpec, object runtime.Object) error {
func (r RealPodControl) CreatePodsOnNode(nodeName, namespace string, template *v1.PodTemplateSpec, object runtime.Object) error {
return r.createPods(nodeName, namespace, template, object, nil)
}
@@ -459,7 +461,7 @@ func (r RealPodControl) PatchPod(namespace, name string, data []byte) error {
return err
}
func GetPodFromTemplate(template *api.PodTemplateSpec, parentObject runtime.Object, controllerRef *api.OwnerReference) (*api.Pod, error) {
func GetPodFromTemplate(template *v1.PodTemplateSpec, parentObject runtime.Object, controllerRef *v1.OwnerReference) (*v1.Pod, error) {
desiredLabels := getPodsLabelSet(template)
desiredFinalizers := getPodsFinalizers(template)
desiredAnnotations, err := getPodsAnnotationSet(template, parentObject)
@@ -472,8 +474,8 @@ func GetPodFromTemplate(template *api.PodTemplateSpec, parentObject runtime.Obje
}
prefix := getPodsPrefix(accessor.GetName())
pod := &api.Pod{
ObjectMeta: api.ObjectMeta{
pod := &v1.Pod{
ObjectMeta: v1.ObjectMeta{
Labels: desiredLabels,
Annotations: desiredAnnotations,
GenerateName: prefix,
@@ -483,13 +485,15 @@ func GetPodFromTemplate(template *api.PodTemplateSpec, parentObject runtime.Obje
if controllerRef != nil {
pod.OwnerReferences = append(pod.OwnerReferences, *controllerRef)
}
if err := api.Scheme.Convert(&template.Spec, &pod.Spec, nil); err != nil {
return nil, fmt.Errorf("unable to convert pod template: %v", err)
clone, err := conversion.NewCloner().DeepCopy(&template.Spec)
if err != nil {
return nil, err
}
pod.Spec = *clone.(*v1.PodSpec)
return pod, nil
}
func (r RealPodControl) createPods(nodeName, namespace string, template *api.PodTemplateSpec, object runtime.Object, controllerRef *api.OwnerReference) error {
func (r RealPodControl) createPods(nodeName, namespace string, template *v1.PodTemplateSpec, object runtime.Object, controllerRef *v1.OwnerReference) error {
pod, err := GetPodFromTemplate(template, object, controllerRef)
if err != nil {
return err
@@ -501,7 +505,7 @@ func (r RealPodControl) createPods(nodeName, namespace string, template *api.Pod
return fmt.Errorf("unable to create pods, no labels")
}
if newPod, err := r.KubeClient.Core().Pods(namespace).Create(pod); err != nil {
r.Recorder.Eventf(object, api.EventTypeWarning, FailedCreatePodReason, "Error creating: %v", err)
r.Recorder.Eventf(object, v1.EventTypeWarning, FailedCreatePodReason, "Error creating: %v", err)
return fmt.Errorf("unable to create pods: %v", err)
} else {
accessor, err := meta.Accessor(object)
@@ -510,7 +514,7 @@ func (r RealPodControl) createPods(nodeName, namespace string, template *api.Pod
return nil
}
glog.V(4).Infof("Controller %v created pod %v", accessor.GetName(), newPod.Name)
r.Recorder.Eventf(object, api.EventTypeNormal, SuccessfulCreatePodReason, "Created pod: %v", newPod.Name)
r.Recorder.Eventf(object, v1.EventTypeNormal, SuccessfulCreatePodReason, "Created pod: %v", newPod.Name)
}
return nil
}
@@ -522,18 +526,18 @@ func (r RealPodControl) DeletePod(namespace string, podID string, object runtime
}
glog.V(2).Infof("Controller %v deleting pod %v/%v", accessor.GetName(), namespace, podID)
if err := r.KubeClient.Core().Pods(namespace).Delete(podID, nil); err != nil {
r.Recorder.Eventf(object, api.EventTypeWarning, FailedDeletePodReason, "Error deleting: %v", err)
r.Recorder.Eventf(object, v1.EventTypeWarning, FailedDeletePodReason, "Error deleting: %v", err)
return fmt.Errorf("unable to delete pods: %v", err)
} else {
r.Recorder.Eventf(object, api.EventTypeNormal, SuccessfulDeletePodReason, "Deleted pod: %v", podID)
r.Recorder.Eventf(object, v1.EventTypeNormal, SuccessfulDeletePodReason, "Deleted pod: %v", podID)
}
return nil
}
type FakePodControl struct {
sync.Mutex
Templates []api.PodTemplateSpec
ControllerRefs []api.OwnerReference
Templates []v1.PodTemplateSpec
ControllerRefs []v1.OwnerReference
DeletePodName []string
Patches [][]byte
Err error
@@ -551,7 +555,7 @@ func (f *FakePodControl) PatchPod(namespace, name string, data []byte) error {
return nil
}
func (f *FakePodControl) CreatePods(namespace string, spec *api.PodTemplateSpec, object runtime.Object) error {
func (f *FakePodControl) CreatePods(namespace string, spec *v1.PodTemplateSpec, object runtime.Object) error {
f.Lock()
defer f.Unlock()
f.Templates = append(f.Templates, *spec)
@@ -561,7 +565,7 @@ func (f *FakePodControl) CreatePods(namespace string, spec *api.PodTemplateSpec,
return nil
}
func (f *FakePodControl) CreatePodsWithControllerRef(namespace string, spec *api.PodTemplateSpec, object runtime.Object, controllerRef *api.OwnerReference) error {
func (f *FakePodControl) CreatePodsWithControllerRef(namespace string, spec *v1.PodTemplateSpec, object runtime.Object, controllerRef *v1.OwnerReference) error {
f.Lock()
defer f.Unlock()
f.Templates = append(f.Templates, *spec)
@@ -572,7 +576,7 @@ func (f *FakePodControl) CreatePodsWithControllerRef(namespace string, spec *api
return nil
}
func (f *FakePodControl) CreatePodsOnNode(nodeName, namespace string, template *api.PodTemplateSpec, object runtime.Object) error {
func (f *FakePodControl) CreatePodsOnNode(nodeName, namespace string, template *v1.PodTemplateSpec, object runtime.Object) error {
f.Lock()
defer f.Unlock()
f.Templates = append(f.Templates, *template)
@@ -596,13 +600,13 @@ func (f *FakePodControl) Clear() {
f.Lock()
defer f.Unlock()
f.DeletePodName = []string{}
f.Templates = []api.PodTemplateSpec{}
f.ControllerRefs = []api.OwnerReference{}
f.Templates = []v1.PodTemplateSpec{}
f.ControllerRefs = []v1.OwnerReference{}
f.Patches = [][]byte{}
}
// ByLogging allows custom sorting of pods so the best one can be picked for getting its logs.
type ByLogging []*api.Pod
type ByLogging []*v1.Pod
func (s ByLogging) Len() int { return len(s) }
func (s ByLogging) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
@@ -613,18 +617,18 @@ func (s ByLogging) Less(i, j int) bool {
return len(s[i].Spec.NodeName) > 0
}
// 2. PodRunning < PodUnknown < PodPending
m := map[api.PodPhase]int{api.PodRunning: 0, api.PodUnknown: 1, api.PodPending: 2}
m := map[v1.PodPhase]int{v1.PodRunning: 0, v1.PodUnknown: 1, v1.PodPending: 2}
if m[s[i].Status.Phase] != m[s[j].Status.Phase] {
return m[s[i].Status.Phase] < m[s[j].Status.Phase]
}
// 3. ready < not ready
if api.IsPodReady(s[i]) != api.IsPodReady(s[j]) {
return api.IsPodReady(s[i])
if v1.IsPodReady(s[i]) != v1.IsPodReady(s[j]) {
return v1.IsPodReady(s[i])
}
// TODO: take availability into account when we push minReadySeconds information from deployment into pods,
// see https://github.com/kubernetes/kubernetes/issues/22065
// 4. Been ready for more time < less time < empty time
if api.IsPodReady(s[i]) && api.IsPodReady(s[j]) && !podReadyTime(s[i]).Equal(podReadyTime(s[j])) {
if v1.IsPodReady(s[i]) && v1.IsPodReady(s[j]) && !podReadyTime(s[i]).Equal(podReadyTime(s[j])) {
return afterOrZero(podReadyTime(s[j]), podReadyTime(s[i]))
}
// 5. Pods with containers with higher restart counts < lower restart counts
@@ -639,7 +643,7 @@ func (s ByLogging) Less(i, j int) bool {
}
// ActivePods type allows custom sorting of pods so a controller can pick the best ones to delete.
type ActivePods []*api.Pod
type ActivePods []*v1.Pod
func (s ActivePods) Len() int { return len(s) }
func (s ActivePods) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
@@ -651,20 +655,20 @@ func (s ActivePods) Less(i, j int) bool {
return len(s[i].Spec.NodeName) == 0
}
// 2. PodPending < PodUnknown < PodRunning
m := map[api.PodPhase]int{api.PodPending: 0, api.PodUnknown: 1, api.PodRunning: 2}
m := map[v1.PodPhase]int{v1.PodPending: 0, v1.PodUnknown: 1, v1.PodRunning: 2}
if m[s[i].Status.Phase] != m[s[j].Status.Phase] {
return m[s[i].Status.Phase] < m[s[j].Status.Phase]
}
// 3. Not ready < ready
// If only one of the pods is not ready, the not ready one is smaller
if api.IsPodReady(s[i]) != api.IsPodReady(s[j]) {
return !api.IsPodReady(s[i])
if v1.IsPodReady(s[i]) != v1.IsPodReady(s[j]) {
return !v1.IsPodReady(s[i])
}
// TODO: take availability into account when we push minReadySeconds information from deployment into pods,
// see https://github.com/kubernetes/kubernetes/issues/22065
// 4. Been ready for empty time < less time < more time
// If both pods are ready, the latest ready one is smaller
if api.IsPodReady(s[i]) && api.IsPodReady(s[j]) && !podReadyTime(s[i]).Equal(podReadyTime(s[j])) {
if v1.IsPodReady(s[i]) && v1.IsPodReady(s[j]) && !podReadyTime(s[i]).Equal(podReadyTime(s[j])) {
return afterOrZero(podReadyTime(s[i]), podReadyTime(s[j]))
}
// 5. Pods with containers with higher restart counts < lower restart counts
@@ -687,11 +691,11 @@ func afterOrZero(t1, t2 unversioned.Time) bool {
return t1.After(t2.Time)
}
func podReadyTime(pod *api.Pod) unversioned.Time {
if api.IsPodReady(pod) {
func podReadyTime(pod *v1.Pod) unversioned.Time {
if v1.IsPodReady(pod) {
for _, c := range pod.Status.Conditions {
// we only care about pod ready conditions
if c.Type == api.PodReady && c.Status == api.ConditionTrue {
if c.Type == v1.PodReady && c.Status == v1.ConditionTrue {
return c.LastTransitionTime
}
}
@@ -699,7 +703,7 @@ func podReadyTime(pod *api.Pod) unversioned.Time {
return unversioned.Time{}
}
func maxContainerRestarts(pod *api.Pod) int {
func maxContainerRestarts(pod *v1.Pod) int {
maxRestarts := 0
for _, c := range pod.Status.ContainerStatuses {
maxRestarts = integer.IntMax(maxRestarts, int(c.RestartCount))
@@ -708,8 +712,8 @@ func maxContainerRestarts(pod *api.Pod) int {
}
// FilterActivePods returns pods that have not terminated.
func FilterActivePods(pods []*api.Pod) []*api.Pod {
var result []*api.Pod
func FilterActivePods(pods []*v1.Pod) []*v1.Pod {
var result []*v1.Pod
for _, p := range pods {
if IsPodActive(p) {
result = append(result, p)
@@ -721,9 +725,9 @@ func FilterActivePods(pods []*api.Pod) []*api.Pod {
return result
}
func IsPodActive(p *api.Pod) bool {
return api.PodSucceeded != p.Status.Phase &&
api.PodFailed != p.Status.Phase &&
func IsPodActive(p *v1.Pod) bool {
return v1.PodSucceeded != p.Status.Phase &&
v1.PodFailed != p.Status.Phase &&
p.DeletionTimestamp == nil
}
@@ -733,7 +737,7 @@ func FilterActiveReplicaSets(replicaSets []*extensions.ReplicaSet) []*extensions
for i := range replicaSets {
rs := replicaSets[i]
if rs != nil && rs.Spec.Replicas > 0 {
if rs != nil && *(rs.Spec.Replicas) > 0 {
active = append(active, replicaSets[i])
}
}
@@ -744,12 +748,12 @@ func FilterActiveReplicaSets(replicaSets []*extensions.ReplicaSet) []*extensions
// It's used so we consistently use the same key scheme in this module.
// It does exactly what cache.MetaNamespaceKeyFunc would have done
// except there's not possibility for error since we know the exact type.
func PodKey(pod *api.Pod) string {
func PodKey(pod *v1.Pod) string {
return fmt.Sprintf("%v/%v", pod.Namespace, pod.Name)
}
// ControllersByCreationTimestamp sorts a list of ReplicationControllers by creation timestamp, using their names as a tie breaker.
type ControllersByCreationTimestamp []*api.ReplicationController
type ControllersByCreationTimestamp []*v1.ReplicationController
func (o ControllersByCreationTimestamp) Len() int { return len(o) }
func (o ControllersByCreationTimestamp) Swap(i, j int) { o[i], o[j] = o[j], o[i] }
@@ -779,10 +783,10 @@ type ReplicaSetsBySizeOlder []*extensions.ReplicaSet
func (o ReplicaSetsBySizeOlder) Len() int { return len(o) }
func (o ReplicaSetsBySizeOlder) Swap(i, j int) { o[i], o[j] = o[j], o[i] }
func (o ReplicaSetsBySizeOlder) Less(i, j int) bool {
if o[i].Spec.Replicas == o[j].Spec.Replicas {
if *(o[i].Spec.Replicas) == *(o[j].Spec.Replicas) {
return ReplicaSetsByCreationTimestamp(o).Less(i, j)
}
return o[i].Spec.Replicas > o[j].Spec.Replicas
return *(o[i].Spec.Replicas) > *(o[j].Spec.Replicas)
}
// ReplicaSetsBySizeNewer sorts a list of ReplicaSet by size in descending order, using their creation timestamp or name as a tie breaker.
@@ -792,8 +796,8 @@ type ReplicaSetsBySizeNewer []*extensions.ReplicaSet
func (o ReplicaSetsBySizeNewer) Len() int { return len(o) }
func (o ReplicaSetsBySizeNewer) Swap(i, j int) { o[i], o[j] = o[j], o[i] }
func (o ReplicaSetsBySizeNewer) Less(i, j int) bool {
if o[i].Spec.Replicas == o[j].Spec.Replicas {
if *(o[i].Spec.Replicas) == *(o[j].Spec.Replicas) {
return ReplicaSetsByCreationTimestamp(o).Less(j, i)
}
return o[i].Spec.Replicas > o[j].Spec.Replicas
return *(o[i].Spec.Replicas) > *(o[j].Spec.Replicas)
}