Skip to content

Commit

Permalink
Refactor daemonset controller and fetch upstream codebase
Browse files Browse the repository at this point in the history
Signed-off-by: FillZpp <[email protected]>
  • Loading branch information
FillZpp committed Feb 11, 2022
1 parent 586e2dc commit 80d2f86
Show file tree
Hide file tree
Showing 20 changed files with 2,523 additions and 2,462 deletions.
37 changes: 20 additions & 17 deletions apis/apps/defaults/v1alpha1.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,33 +260,36 @@ func SetDefaultsDaemonSet(obj *v1alpha1.DaemonSet) {

if obj.Spec.UpdateStrategy.Type == "" {
obj.Spec.UpdateStrategy.Type = v1alpha1.RollingUpdateDaemonSetStrategyType

// UpdateStrategy.RollingUpdate will take default values below.
obj.Spec.UpdateStrategy.RollingUpdate = &v1alpha1.RollingUpdateDaemonSet{}
}

if obj.Spec.UpdateStrategy.Type == v1alpha1.RollingUpdateDaemonSetStrategyType {
if obj.Spec.UpdateStrategy.RollingUpdate == nil {
obj.Spec.UpdateStrategy.RollingUpdate = &v1alpha1.RollingUpdateDaemonSet{}
}
if obj.Spec.UpdateStrategy.RollingUpdate.Partition == nil {
obj.Spec.UpdateStrategy.RollingUpdate.Partition = new(int32)
*obj.Spec.UpdateStrategy.RollingUpdate.Partition = 0

// Make it compatible with the predicated Surging
if obj.Spec.UpdateStrategy.RollingUpdate.Type == v1alpha1.DeprecatedSurgingRollingUpdateType {
if obj.Spec.UpdateStrategy.RollingUpdate.MaxSurge == nil {
maxSurge := intstr.FromInt(1)
obj.Spec.UpdateStrategy.RollingUpdate.MaxSurge = &maxSurge
}
if obj.Spec.UpdateStrategy.RollingUpdate.MaxUnavailable == nil {
maxUnavailable := intstr.FromInt(0)
obj.Spec.UpdateStrategy.RollingUpdate.MaxUnavailable = &maxUnavailable
}
}

// Default and convert to Standard
if obj.Spec.UpdateStrategy.RollingUpdate.Type == "" || obj.Spec.UpdateStrategy.RollingUpdate.Type == v1alpha1.DeprecatedSurgingRollingUpdateType {
obj.Spec.UpdateStrategy.RollingUpdate.Type = v1alpha1.StandardRollingUpdateType
}

if obj.Spec.UpdateStrategy.RollingUpdate.MaxUnavailable == nil {
maxUnavailable := intstr.FromInt(1)
obj.Spec.UpdateStrategy.RollingUpdate.MaxUnavailable = &maxUnavailable
}

if obj.Spec.UpdateStrategy.RollingUpdate.Type == "" {
obj.Spec.UpdateStrategy.RollingUpdate.Type = v1alpha1.StandardRollingUpdateType
}
// Only when RollingUpdate Type is SurgingRollingUpdateType, it need to initialize the MaxSurge.
if obj.Spec.UpdateStrategy.RollingUpdate.Type == v1alpha1.SurgingRollingUpdateType {
if obj.Spec.UpdateStrategy.RollingUpdate.MaxSurge == nil {
MaxSurge := intstr.FromInt(1)
obj.Spec.UpdateStrategy.RollingUpdate.MaxSurge = &MaxSurge
}
if obj.Spec.UpdateStrategy.RollingUpdate.MaxSurge == nil {
MaxSurge := intstr.FromInt(0)
obj.Spec.UpdateStrategy.RollingUpdate.MaxSurge = &MaxSurge
}
}

Expand Down
142 changes: 61 additions & 81 deletions apis/apps/v1alpha1/daemonset_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package v1alpha1

import (
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
Expand All @@ -26,11 +27,11 @@ import (
type DaemonSetUpdateStrategy struct {
// Type of daemon set update. Can be "RollingUpdate" or "OnDelete". Default is RollingUpdate.
// +optional
Type DaemonSetUpdateStrategyType `json:"type,omitempty" protobuf:"bytes,1,opt,name=type"`
Type DaemonSetUpdateStrategyType `json:"type,omitempty"`

// Rolling update config params. Present only if type = "RollingUpdate".
// +optional
RollingUpdate *RollingUpdateDaemonSet `json:"rollingUpdate,omitempty" protobuf:"bytes,2,opt,name=rollingUpdate"`
RollingUpdate *RollingUpdateDaemonSet `json:"rollingUpdate,omitempty"`
}

type DaemonSetUpdateStrategyType string
Expand All @@ -43,69 +44,76 @@ const (
// Replace the old daemons only when it's killed
OnDeleteDaemonSetStrategyType DaemonSetUpdateStrategyType = "OnDelete"

// StandardRollingUpdateType replace the old daemons by new ones using rolling update i.e replace them on each node one after the other.
// this is the default type for RollingUpdate.
// StandardRollingUpdateType is the Standard way that update pods with recreation that sames to the upstream DaemonSet.
StandardRollingUpdateType RollingUpdateType = "Standard"

// Replace container image without killing the pod.
// InplaceRollingUpdateType update container image without killing the pod if possible.
InplaceRollingUpdateType RollingUpdateType = "InPlaceIfPossible"

// SurgingRollingUpdateType replaces the old daemons by new ones using rolling update i.e replace them on each node one
// after the other, creating the new pod and then killing the old one.
SurgingRollingUpdateType RollingUpdateType = "Surging"
// DeprecatedSurgingRollingUpdateType is a depreciated alias for Standard.
// Deprecated: Just use Standard instead.
DeprecatedSurgingRollingUpdateType RollingUpdateType = "Surging"
)

// Spec to control the desired behavior of daemon set rolling update.
type RollingUpdateDaemonSet struct {
// Type is to specify which kind of rollingUpdate.
Type RollingUpdateType `json:"rollingUpdateType,omitempty" protobuf:"bytes,1,opt,name=rollingUpdateType"`
Type RollingUpdateType `json:"rollingUpdateType,omitempty"`

// The maximum number of DaemonSet pods that can be unavailable during the
// update. Value can be an absolute number (ex: 5) or a percentage of total
// number of DaemonSet pods at the start of the update (ex: 10%). Absolute
// number is calculated from percentage by rounding up.
// This cannot be 0.
// This cannot be 0 if MaxSurge is 0
// Default value is 1.
// Example: when this is set to 30%, at most 30% of the total number of nodes
// that should be running the daemon pod (i.e. status.desiredNumberScheduled)
// can have their pods stopped for an update at any given
// time. The update starts by stopping at most 30% of those DaemonSet pods
// and then brings up new DaemonSet pods in their place. Once the new pods
// are available, it then proceeds onto other DaemonSet pods, thus ensuring
// that at least 70% of original number of DaemonSet pods are available at
// all times during the update.
// +optional
MaxUnavailable *intstr.IntOrString `json:"maxUnavailable,omitempty" protobuf:"bytes,2,opt,name=maxUnavailable"`
// can have their pods stopped for an update at any given time. The update
// starts by stopping at most 30% of those DaemonSet pods and then brings
// up new DaemonSet pods in their place. Once the new pods are available,
// it then proceeds onto other DaemonSet pods, thus ensuring that at least
// 70% of original number of DaemonSet pods are available at all times during
// the update.
// +optional
MaxUnavailable *intstr.IntOrString `json:"maxUnavailable,omitempty"`

// The maximum number of nodes with an existing available DaemonSet pod that
// can have an updated DaemonSet pod during during an update.
// Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%).
// This can not be 0 if MaxUnavailable is 0.
// Absolute number is calculated from percentage by rounding up to a minimum of 1.
// Default value is 0.
// Example: when this is set to 30%, at most 30% of the total number of nodes
// that should be running the daemon pod (i.e. status.desiredNumberScheduled)
// can have their a new pod created before the old pod is marked as deleted.
// The update starts by launching new pods on 30% of nodes. Once an updated
// pod is available (Ready for at least minReadySeconds) the old DaemonSet pod
// on that node is marked deleted. If the old pod becomes unavailable for any
// reason (Ready transitions to false, is evicted, or is drained) an updated
// pod is immediatedly created on that node without considering surge limits.
// Allowing surge implies the possibility that the resources consumed by the
// daemonset on any given node can double if the readiness check fails, and
// so resource intensive daemonsets should take into account that they may
// cause evictions during disruption.
// This is beta field and enabled/disabled by DaemonSetUpdateSurge feature gate.
// +optional
MaxSurge *intstr.IntOrString `json:"maxSurge,omitempty"`

// A label query over nodes that are managed by the daemon set RollingUpdate.
// Must match in order to be controlled.
// It must match the node's labels.
Selector *metav1.LabelSelector `json:"selector,omitempty" protobuf:"bytes,3,opt,name=selector"`
Selector *metav1.LabelSelector `json:"selector,omitempty"`

// The number of DaemonSet pods remained to be old version.
// Default value is 0.
// Maximum value is status.DesiredNumberScheduled, which means no pod will be updated.
// +optional
Partition *int32 `json:"partition,omitempty" protobuf:"varint,4,opt,name=partition"`
Partition *int32 `json:"partition,omitempty"`

// Indicates that the daemon set is paused and will not be processed by the
// daemon set controller.
// +optional
Paused *bool `json:"paused,omitempty" protobuf:"varint,5,opt,name=paused"`

// Only when type=SurgingRollingUpdateType, it works.
// The maximum number of DaemonSet pods that can be scheduled above the desired number of pods
// during the update. Value can be an absolute number (ex: 5) or a percentage of the total number
// of DaemonSet pods at the start of the update (ex: 10%). The absolute number is calculated from
// the percentage by rounding up. This cannot be 0. The default value is 1. Example: when this is
// set to 30%, at most 30% of the total number of nodes that should be running the daemon pod
// (i.e. status.desiredNumberScheduled) can have 2 pods running at any given time. The update
// starts by starting replacements for at most 30% of those DaemonSet pods. Once the new pods are
// available it then stops the existing pods before proceeding onto other DaemonSet pods, thus
// ensuring that at most 130% of the desired final number of DaemonSet pods are running at all
// times during the update.
// +optional
MaxSurge *intstr.IntOrString `json:"maxSurge,omitempty" protobuf:"bytes,7,opt,name=maxSurge"`
Paused *bool `json:"paused,omitempty"`
}

// DaemonSetSpec defines the desired state of DaemonSet
Expand All @@ -117,7 +125,7 @@ type DaemonSetSpec struct {
// Must match in order to be controlled.
// It must match the pod template's labels.
// More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors
Selector *metav1.LabelSelector `json:"selector" protobuf:"bytes,1,opt,name=selector"`
Selector *metav1.LabelSelector `json:"selector"`

// An object that describes the pod that will be created.
// The DaemonSet will create exactly one copy of this pod on every node
Expand All @@ -126,28 +134,28 @@ type DaemonSetSpec struct {
// More info: https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller#pod-template
// +kubebuilder:pruning:PreserveUnknownFields
// +kubebuilder:validation:Schemaless
Template corev1.PodTemplateSpec `json:"template" protobuf:"bytes,2,opt,name=template"`
Template corev1.PodTemplateSpec `json:"template"`

// An update strategy to replace existing DaemonSet pods with new pods.
// +optional
UpdateStrategy DaemonSetUpdateStrategy `json:"updateStrategy,omitempty" protobuf:"bytes,3,opt,name=updateStrategy"`
UpdateStrategy DaemonSetUpdateStrategy `json:"updateStrategy,omitempty"`

// The minimum number of seconds for which a newly created DaemonSet pod should
// be ready without any of its container crashing, for it to be considered
// available. Defaults to 0 (pod will be considered available as soon as it
// is ready).
// +optional
MinReadySeconds int32 `json:"minReadySeconds,omitempty" protobuf:"varint,4,opt,name=minReadySeconds"`
MinReadySeconds int32 `json:"minReadySeconds,omitempty"`

// BurstReplicas is a rate limiter for booting pods on a lot of pods.
// The default value is 250
BurstReplicas *intstr.IntOrString `json:"burstReplicas,omitempty" protobuf:"bytes,5,opt,name=burstReplicas"`
BurstReplicas *intstr.IntOrString `json:"burstReplicas,omitempty"`

// The number of old history to retain to allow rollback.
// This is a pointer to distinguish between explicit zero and not specified.
// Defaults to 10.
// +optional
RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty" protobuf:"varint,6,opt,name=revisionHistoryLimit"`
RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty"`
}

// DaemonSetStatus defines the observed state of DaemonSet
Expand All @@ -158,90 +166,62 @@ type DaemonSetStatus struct {
// The number of nodes that are running at least 1
// daemon pod and are supposed to run the daemon pod.
// More info: https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/
CurrentNumberScheduled int32 `json:"currentNumberScheduled" protobuf:"varint,1,opt,name=currentNumberScheduled"`
CurrentNumberScheduled int32 `json:"currentNumberScheduled"`

// The number of nodes that are running the daemon pod, but are
// not supposed to run the daemon pod.
// More info: https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/
NumberMisscheduled int32 `json:"numberMisscheduled" protobuf:"varint,2,opt,name=numberMisscheduled"`
NumberMisscheduled int32 `json:"numberMisscheduled"`

// The total number of nodes that should be running the daemon
// pod (including nodes correctly running the daemon pod).
// More info: https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/
DesiredNumberScheduled int32 `json:"desiredNumberScheduled" protobuf:"varint,3,opt,name=desiredNumberScheduled"`
DesiredNumberScheduled int32 `json:"desiredNumberScheduled"`

// The number of nodes that should be running the daemon pod and have one
// or more of the daemon pod running and ready.
NumberReady int32 `json:"numberReady" protobuf:"varint,4,opt,name=numberReady"`
NumberReady int32 `json:"numberReady"`

// The most recent generation observed by the daemon set controller.
// +optional
ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,5,opt,name=observedGeneration"`
ObservedGeneration int64 `json:"observedGeneration,omitempty"`

// The total number of nodes that are running updated daemon pod
UpdatedNumberScheduled int32 `json:"updatedNumberScheduled" protobuf:"varint,6,opt,name=updatedNumberScheduled"`
UpdatedNumberScheduled int32 `json:"updatedNumberScheduled"`

// The number of nodes that should be running the
// daemon pod and have one or more of the daemon pod running and
// available (ready for at least spec.minReadySeconds)
// +optional
NumberAvailable int32 `json:"numberAvailable,omitempty" protobuf:"varint,7,opt,name=numberAvailable"`
NumberAvailable int32 `json:"numberAvailable,omitempty"`

// The number of nodes that should be running the
// daemon pod and have none of the daemon pod running and available
// (ready for at least spec.minReadySeconds)
// +optional
NumberUnavailable int32 `json:"numberUnavailable,omitempty" protobuf:"varint,8,opt,name=numberUnavailable"`
NumberUnavailable int32 `json:"numberUnavailable,omitempty"`

// Count of hash collisions for the DaemonSet. The DaemonSet controller
// uses this field as a collision avoidance mechanism when it needs to
// create the name for the newest ControllerRevision.
// +optional
CollisionCount *int32 `json:"collisionCount,omitempty" protobuf:"varint,9,opt,name=collisionCount"`
CollisionCount *int32 `json:"collisionCount,omitempty"`

// Represents the latest available observations of a DaemonSet's current state.
// +optional
// +patchMergeKey=type
// +patchStrategy=merge
Conditions []DaemonSetCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,10,rep,name=conditions"`
Conditions []appsv1.DaemonSetCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`

// DaemonSetHash is the controller-revision-hash, which represents the latest version of the DaemonSet.
DaemonSetHash string `json:"daemonSetHash" protobuf:"bytes,11,opt,name=daemonSetHash"`
DaemonSetHash string `json:"daemonSetHash"`
}

type DaemonSetConditionType string

// TODO: Add valid condition types of a DaemonSet.

// DaemonSetCondition describes the state of a DaemonSet at a certain point.
type DaemonSetCondition struct {
// Type of DaemonSet condition.
Type DaemonSetConditionType `json:"type" protobuf:"bytes,1,opt,name=type,casttype=DaemonSetConditionType"`
// Status of the condition, one of True, False, Unknown.
Status corev1.ConditionStatus `json:"status" protobuf:"bytes,2,opt,name=status,casttype=k8s.io/api/core/v1.ConditionStatus"`
// Last time the condition transitioned from one status to another.
// +optional
LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty" protobuf:"bytes,3,opt,name=lastTransitionTime"`
// The reason for the condition's last transition.
// +optional
Reason string `json:"reason,omitempty" protobuf:"bytes,4,opt,name=reason"`
// A human readable message indicating details about the transition.
// +optional
Message string `json:"message,omitempty" protobuf:"bytes,5,opt,name=message"`
}

const (
// DefaultDaemonSetUniqueLabelKey is the default label key that is added
// to existing DaemonSet pods to distinguish between old and new
// DaemonSet pods during DaemonSet template updates.
DefaultDaemonSetUniqueLabelKey = ControllerRevisionHashLabelKey
)

// +genclient
// +k8s:openapi-gen=true
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// +kubebuilder:resource:shortName=daemon
// +kubebuilder:resource:shortName=daemon;ads
// +kubebuilder:printcolumn:name="DesiredNumber",type="integer",JSONPath=".status.desiredNumberScheduled",description="The desired number of pods."
// +kubebuilder:printcolumn:name="CurrentNumber",type="integer",JSONPath=".status.currentNumberScheduled",description="The current number of pods."
// +kubebuilder:printcolumn:name="UpdatedNumberScheduled",type="integer",JSONPath=".status.updatedNumberScheduled",description="The updated number of pods."
Expand Down
28 changes: 6 additions & 22 deletions apis/apps/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 80d2f86

Please sign in to comment.