Merge pull request #36438 from mwielgus/pdb-generation

Automatic merge from submit-queue

Use generation in pod disruption budget

Fixes #35324

Previously it was possible to use allowedDirsruptions calculated for the previous spec with the current spec. With generation check API servers always make sure that allowedDisruptions were calculated for the current spec. 

At the same time I set the registry policy to only accept updates if the version based on which the update was made matches to the current version in etcd. That ensures that parallel eviction executions don't use the same allowed disruption.

cc: @davidopp @kargakis @wojtek-t
This commit is contained in:
Kubernetes Submit Queue 2016-11-09 10:02:29 -08:00 committed by GitHub
commit 5d4d596667
19 changed files with 1669 additions and 1481 deletions

View File

@ -33876,11 +33876,11 @@
"v1beta1.PodDisruptionBudgetStatus": { "v1beta1.PodDisruptionBudgetStatus": {
"description": "PodDisruptionBudgetStatus represents information about the status of a PodDisruptionBudget. Status may trail the actual state of a system.", "description": "PodDisruptionBudgetStatus represents information about the status of a PodDisruptionBudget. Status may trail the actual state of a system.",
"required": [ "required": [
"disruptedPods",
"disruptionsAllowed", "disruptionsAllowed",
"currentHealthy", "currentHealthy",
"desiredHealthy", "desiredHealthy",
"expectedPods", "expectedPods"
"disruptedPods"
], ],
"properties": { "properties": {
"currentHealthy": { "currentHealthy": {
@ -33909,6 +33909,11 @@
"description": "total number of pods counted by this disruption budget", "description": "total number of pods counted by this disruption budget",
"type": "integer", "type": "integer",
"format": "int32" "format": "int32"
},
"observedGeneration": {
"description": "Most recent generation observed when updating this PDB status. PodDisruptionsAllowed and other status informatio is valid only if observedGeneration equals to PDB's object generation.",
"type": "integer",
"format": "int64"
} }
} }
}, },

View File

@ -1236,13 +1236,22 @@
"id": "v1beta1.PodDisruptionBudgetStatus", "id": "v1beta1.PodDisruptionBudgetStatus",
"description": "PodDisruptionBudgetStatus represents information about the status of a PodDisruptionBudget. Status may trail the actual state of a system.", "description": "PodDisruptionBudgetStatus represents information about the status of a PodDisruptionBudget. Status may trail the actual state of a system.",
"required": [ "required": [
"disruptedPods",
"disruptionsAllowed", "disruptionsAllowed",
"currentHealthy", "currentHealthy",
"desiredHealthy", "desiredHealthy",
"expectedPods", "expectedPods"
"disruptedPods"
], ],
"properties": { "properties": {
"observedGeneration": {
"type": "integer",
"format": "int64",
"description": "Most recent generation observed when updating this PDB status. PodDisruptionsAllowed and other status informatio is valid only if observedGeneration equals to PDB's object generation."
},
"disruptedPods": {
"type": "object",
"description": "DisruptedPods contains information about pods whose eviction was processed by the API server eviction subresource handler but has not yet been observed by the PodDisruptionBudget controller. A pod will be in this map from the time when the API server processed the eviction request to the time when the pod is seen by PDB controller as having been marked for deletion (or after a timeout). The key in the map is the name of the pod and the value is the time when the API server processed the eviction request. If the deletion didn't occur and a pod is still there it will be removed from the list automatically by PodDisruptionBudget controller after some time. If everything goes smooth this map should be empty for the most of the time. Large number of entries in the map may indicate problems with pod deletions."
},
"disruptionsAllowed": { "disruptionsAllowed": {
"type": "integer", "type": "integer",
"format": "int32", "format": "int32",
@ -1262,10 +1271,6 @@
"type": "integer", "type": "integer",
"format": "int32", "format": "int32",
"description": "total number of pods counted by this disruption budget" "description": "total number of pods counted by this disruption budget"
},
"disruptedPods": {
"type": "object",
"description": "DisruptedPods contains information about pods whose eviction was processed by the API server eviction subresource handler but has not yet been observed by the PodDisruptionBudget controller. A pod will be in this map from the time when the API server processed the eviction request to the time when the pod is seen by PDB controller as having been marked for deletion (or after a timeout). The key in the map is the name of the pod and the value is the time when the API server processed the eviction request. If the deletion didn't occur and a pod is still there it will be removed from the list automatically by PodDisruptionBudget controller after some time. If everything goes smooth this map should be empty for the most of the time. Large number of entries in the map may indicate problems with pod deletions."
} }
} }
}, },

View File

@ -814,6 +814,20 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">observedGeneration</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Most recent generation observed when updating this PDB status. PodDisruptionsAllowed and other status informatio is valid only if observedGeneration equals to PDB&#8217;s object generation.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">integer (int64)</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">disruptedPods</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">DisruptedPods contains information about pods whose eviction was processed by the API server eviction subresource handler but has not yet been observed by the PodDisruptionBudget controller. A pod will be in this map from the time when the API server processed the eviction request to the time when the pod is seen by PDB controller as having been marked for deletion (or after a timeout). The key in the map is the name of the pod and the value is the time when the API server processed the eviction request. If the deletion didn&#8217;t occur and a pod is still there it will be removed from the list automatically by PodDisruptionBudget controller after some time. If everything goes smooth this map should be empty for the most of the time. Large number of entries in the map may indicate problems with pod deletions.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">object</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">disruptionsAllowed</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">disruptionsAllowed</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Number of pod disruptions that are currently allowed.</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">Number of pod disruptions that are currently allowed.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
@ -841,13 +855,6 @@ span.icon > [class^="icon-"], span.icon > [class*=" icon-"] { cursor: default; }
<td class="tableblock halign-left valign-top"><p class="tableblock">integer (int32)</p></td> <td class="tableblock halign-left valign-top"><p class="tableblock">integer (int32)</p></td>
<td class="tableblock halign-left valign-top"></td> <td class="tableblock halign-left valign-top"></td>
</tr> </tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">disruptedPods</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">DisruptedPods contains information about pods whose eviction was processed by the API server eviction subresource handler but has not yet been observed by the PodDisruptionBudget controller. A pod will be in this map from the time when the API server processed the eviction request to the time when the pod is seen by PDB controller as having been marked for deletion (or after a timeout). The key in the map is the name of the pod and the value is the time when the API server processed the eviction request. If the deletion didn&#8217;t occur and a pod is still there it will be removed from the list automatically by PodDisruptionBudget controller after some time. If everything goes smooth this map should be empty for the most of the time. Large number of entries in the map may indicate problems with pod deletions.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">true</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">object</p></td>
<td class="tableblock halign-left valign-top"></td>
</tr>
</tbody> </tbody>
</table> </table>
@ -1395,7 +1402,7 @@ Examples:<br>
</div> </div>
<div id="footer"> <div id="footer">
<div id="footer-text"> <div id="footer-text">
Last updated 2016-11-06 12:57:24 UTC Last updated 2016-11-08 13:05:21 UTC
</div> </div>
</div> </div>
</body> </body>

File diff suppressed because it is too large Load Diff

View File

@ -40,17 +40,10 @@ type PodDisruptionBudgetSpec struct {
// PodDisruptionBudgetStatus represents information about the status of a // PodDisruptionBudgetStatus represents information about the status of a
// PodDisruptionBudget. Status may trail the actual state of a system. // PodDisruptionBudget. Status may trail the actual state of a system.
type PodDisruptionBudgetStatus struct { type PodDisruptionBudgetStatus struct {
// Number of pod disruptions that are currently allowed. // Most recent generation observed when updating this PDB status. PodDisruptionsAllowed and other
PodDisruptionsAllowed int32 `json:"disruptionsAllowed"` // status informatio is valid only if observedGeneration equals to PDB's object generation.
// +optional
// current number of healthy pods ObservedGeneration int64 `json:"observedGeneration,omitempty"`
CurrentHealthy int32 `json:"currentHealthy"`
// minimum desired number of healthy pods
DesiredHealthy int32 `json:"desiredHealthy"`
// total number of pods counted by this disruption budget
ExpectedPods int32 `json:"expectedPods"`
// DisruptedPods contains information about pods whose eviction was // DisruptedPods contains information about pods whose eviction was
// processed by the API server eviction subresource handler but has not // processed by the API server eviction subresource handler but has not
@ -64,6 +57,18 @@ type PodDisruptionBudgetStatus struct {
// If everything goes smooth this map should be empty for the most of the time. // If everything goes smooth this map should be empty for the most of the time.
// Large number of entries in the map may indicate problems with pod deletions. // Large number of entries in the map may indicate problems with pod deletions.
DisruptedPods map[string]unversioned.Time `json:"disruptedPods" protobuf:"bytes,5,rep,name=disruptedPods"` DisruptedPods map[string]unversioned.Time `json:"disruptedPods" protobuf:"bytes,5,rep,name=disruptedPods"`
// Number of pod disruptions that are currently allowed.
PodDisruptionsAllowed int32 `json:"disruptionsAllowed"`
// current number of healthy pods
CurrentHealthy int32 `json:"currentHealthy"`
// minimum desired number of healthy pods
DesiredHealthy int32 `json:"desiredHealthy"`
// total number of pods counted by this disruption budget
ExpectedPods int32 `json:"expectedPods"`
} }
// +genclient=true // +genclient=true

View File

@ -253,19 +253,10 @@ func (m *PodDisruptionBudgetStatus) MarshalTo(data []byte) (int, error) {
_ = l _ = l
data[i] = 0x8 data[i] = 0x8
i++ i++
i = encodeVarintGenerated(data, i, uint64(m.PodDisruptionsAllowed)) i = encodeVarintGenerated(data, i, uint64(m.ObservedGeneration))
data[i] = 0x10
i++
i = encodeVarintGenerated(data, i, uint64(m.CurrentHealthy))
data[i] = 0x18
i++
i = encodeVarintGenerated(data, i, uint64(m.DesiredHealthy))
data[i] = 0x20
i++
i = encodeVarintGenerated(data, i, uint64(m.ExpectedPods))
if len(m.DisruptedPods) > 0 { if len(m.DisruptedPods) > 0 {
for k := range m.DisruptedPods { for k := range m.DisruptedPods {
data[i] = 0x2a data[i] = 0x12
i++ i++
v := m.DisruptedPods[k] v := m.DisruptedPods[k]
msgSize := (&v).Size() msgSize := (&v).Size()
@ -285,6 +276,18 @@ func (m *PodDisruptionBudgetStatus) MarshalTo(data []byte) (int, error) {
i += n9 i += n9
} }
} }
data[i] = 0x18
i++
i = encodeVarintGenerated(data, i, uint64(m.PodDisruptionsAllowed))
data[i] = 0x20
i++
i = encodeVarintGenerated(data, i, uint64(m.CurrentHealthy))
data[i] = 0x28
i++
i = encodeVarintGenerated(data, i, uint64(m.DesiredHealthy))
data[i] = 0x30
i++
i = encodeVarintGenerated(data, i, uint64(m.ExpectedPods))
return i, nil return i, nil
} }
@ -368,10 +371,7 @@ func (m *PodDisruptionBudgetSpec) Size() (n int) {
func (m *PodDisruptionBudgetStatus) Size() (n int) { func (m *PodDisruptionBudgetStatus) Size() (n int) {
var l int var l int
_ = l _ = l
n += 1 + sovGenerated(uint64(m.PodDisruptionsAllowed)) n += 1 + sovGenerated(uint64(m.ObservedGeneration))
n += 1 + sovGenerated(uint64(m.CurrentHealthy))
n += 1 + sovGenerated(uint64(m.DesiredHealthy))
n += 1 + sovGenerated(uint64(m.ExpectedPods))
if len(m.DisruptedPods) > 0 { if len(m.DisruptedPods) > 0 {
for k, v := range m.DisruptedPods { for k, v := range m.DisruptedPods {
_ = k _ = k
@ -381,6 +381,10 @@ func (m *PodDisruptionBudgetStatus) Size() (n int) {
n += mapEntrySize + 1 + sovGenerated(uint64(mapEntrySize)) n += mapEntrySize + 1 + sovGenerated(uint64(mapEntrySize))
} }
} }
n += 1 + sovGenerated(uint64(m.PodDisruptionsAllowed))
n += 1 + sovGenerated(uint64(m.CurrentHealthy))
n += 1 + sovGenerated(uint64(m.DesiredHealthy))
n += 1 + sovGenerated(uint64(m.ExpectedPods))
return n return n
} }
@ -457,11 +461,12 @@ func (this *PodDisruptionBudgetStatus) String() string {
} }
mapStringForDisruptedPods += "}" mapStringForDisruptedPods += "}"
s := strings.Join([]string{`&PodDisruptionBudgetStatus{`, s := strings.Join([]string{`&PodDisruptionBudgetStatus{`,
`ObservedGeneration:` + fmt.Sprintf("%v", this.ObservedGeneration) + `,`,
`DisruptedPods:` + mapStringForDisruptedPods + `,`,
`PodDisruptionsAllowed:` + fmt.Sprintf("%v", this.PodDisruptionsAllowed) + `,`, `PodDisruptionsAllowed:` + fmt.Sprintf("%v", this.PodDisruptionsAllowed) + `,`,
`CurrentHealthy:` + fmt.Sprintf("%v", this.CurrentHealthy) + `,`, `CurrentHealthy:` + fmt.Sprintf("%v", this.CurrentHealthy) + `,`,
`DesiredHealthy:` + fmt.Sprintf("%v", this.DesiredHealthy) + `,`, `DesiredHealthy:` + fmt.Sprintf("%v", this.DesiredHealthy) + `,`,
`ExpectedPods:` + fmt.Sprintf("%v", this.ExpectedPods) + `,`, `ExpectedPods:` + fmt.Sprintf("%v", this.ExpectedPods) + `,`,
`DisruptedPods:` + mapStringForDisruptedPods + `,`,
`}`, `}`,
}, "") }, "")
return s return s
@ -982,9 +987,9 @@ func (m *PodDisruptionBudgetStatus) Unmarshal(data []byte) error {
switch fieldNum { switch fieldNum {
case 1: case 1:
if wireType != 0 { if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field PodDisruptionsAllowed", wireType) return fmt.Errorf("proto: wrong wireType = %d for field ObservedGeneration", wireType)
} }
m.PodDisruptionsAllowed = 0 m.ObservedGeneration = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 { if shift >= 64 {
return ErrIntOverflowGenerated return ErrIntOverflowGenerated
@ -994,69 +999,12 @@ func (m *PodDisruptionBudgetStatus) Unmarshal(data []byte) error {
} }
b := data[iNdEx] b := data[iNdEx]
iNdEx++ iNdEx++
m.PodDisruptionsAllowed |= (int32(b) & 0x7F) << shift m.ObservedGeneration |= (int64(b) & 0x7F) << shift
if b < 0x80 { if b < 0x80 {
break break
} }
} }
case 2: case 2:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field CurrentHealthy", wireType)
}
m.CurrentHealthy = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
m.CurrentHealthy |= (int32(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 3:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field DesiredHealthy", wireType)
}
m.DesiredHealthy = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
m.DesiredHealthy |= (int32(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 4:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field ExpectedPods", wireType)
}
m.ExpectedPods = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
m.ExpectedPods |= (int32(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 5:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field DisruptedPods", wireType) return fmt.Errorf("proto: wrong wireType = %d for field DisruptedPods", wireType)
} }
@ -1172,6 +1120,82 @@ func (m *PodDisruptionBudgetStatus) Unmarshal(data []byte) error {
} }
m.DisruptedPods[mapkey] = *mapvalue m.DisruptedPods[mapkey] = *mapvalue
iNdEx = postIndex iNdEx = postIndex
case 3:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field PodDisruptionsAllowed", wireType)
}
m.PodDisruptionsAllowed = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
m.PodDisruptionsAllowed |= (int32(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 4:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field CurrentHealthy", wireType)
}
m.CurrentHealthy = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
m.CurrentHealthy |= (int32(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 5:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field DesiredHealthy", wireType)
}
m.DesiredHealthy = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
m.DesiredHealthy |= (int32(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
case 6:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field ExpectedPods", wireType)
}
m.ExpectedPods = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowGenerated
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := data[iNdEx]
iNdEx++
m.ExpectedPods |= (int32(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
default: default:
iNdEx = preIndex iNdEx = preIndex
skippy, err := skipGenerated(data[iNdEx:]) skippy, err := skipGenerated(data[iNdEx:])
@ -1299,51 +1323,53 @@ var (
) )
var fileDescriptorGenerated = []byte{ var fileDescriptorGenerated = []byte{
// 728 bytes of a gzipped FileDescriptorProto // 758 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xb4, 0x94, 0xcf, 0x6e, 0xd3, 0x4e, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xb4, 0x94, 0xcf, 0x6f, 0xdb, 0x36,
0x10, 0xc7, 0xe3, 0x26, 0xe9, 0x2f, 0xbf, 0x6d, 0x52, 0x95, 0x85, 0x42, 0x88, 0x84, 0x8b, 0x72, 0x14, 0xc7, 0xad, 0xd8, 0xce, 0x3c, 0xc6, 0x0e, 0x32, 0x6e, 0xd9, 0x3c, 0x03, 0x53, 0x06, 0x9f,
0x6a, 0x05, 0x5d, 0x2b, 0x15, 0x48, 0x85, 0x43, 0xa5, 0x9a, 0x54, 0xa2, 0x12, 0x55, 0x2b, 0x17, 0x12, 0x6c, 0xa1, 0xe0, 0x60, 0x03, 0xb2, 0x1d, 0x02, 0x44, 0x73, 0xb0, 0x65, 0x58, 0xe0, 0x40,
0x09, 0x84, 0x04, 0x92, 0x63, 0x0f, 0xee, 0x12, 0xc7, 0xb6, 0x76, 0xd7, 0x81, 0xdc, 0x78, 0x04, 0x19, 0xb0, 0x61, 0xc0, 0x0a, 0xe8, 0xc7, 0xab, 0xc2, 0x5a, 0x16, 0x05, 0x92, 0x52, 0xeb, 0x5b,
0x0e, 0x3c, 0x05, 0xaf, 0xc1, 0xa5, 0xe2, 0xd4, 0x23, 0x17, 0x2a, 0x9a, 0xbe, 0x08, 0xf2, 0x66, 0xff, 0x84, 0x1e, 0xfa, 0x1f, 0xf5, 0x12, 0xf4, 0x94, 0x63, 0x2f, 0x0d, 0x1a, 0xe7, 0x7f, 0xe8,
0x93, 0xda, 0xf9, 0x53, 0x55, 0x2a, 0xdc, 0xbc, 0xbb, 0xf3, 0xf9, 0xce, 0x7c, 0x67, 0x67, 0x8d, 0xb9, 0x90, 0x44, 0x3b, 0x96, 0x7f, 0x04, 0x01, 0xd2, 0xde, 0x44, 0xf2, 0x7d, 0xbe, 0xdf, 0xf7,
0x9e, 0xb4, 0x37, 0x39, 0xa1, 0xa1, 0xd1, 0x8e, 0x5b, 0xc0, 0x02, 0x10, 0xc0, 0x8d, 0xa8, 0xed, 0x1e, 0x1f, 0x85, 0x7e, 0xe9, 0xef, 0x0b, 0x42, 0x99, 0xd1, 0x8f, 0x1d, 0xe0, 0x21, 0x48, 0x10,
0x19, 0x76, 0x44, 0xb9, 0x11, 0x85, 0x3e, 0x75, 0x7a, 0x46, 0xb7, 0xd1, 0x02, 0x61, 0x37, 0x0c, 0x46, 0xd4, 0xf7, 0x0d, 0x3b, 0xa2, 0xc2, 0x88, 0x58, 0x40, 0xdd, 0xa1, 0x91, 0x74, 0x1c, 0x90,
0x0f, 0x02, 0x60, 0xb6, 0x00, 0x97, 0x44, 0x2c, 0x14, 0x21, 0x5e, 0x1b, 0xa0, 0xe4, 0x02, 0x25, 0x76, 0xc7, 0xf0, 0x21, 0x04, 0x6e, 0x4b, 0xf0, 0x48, 0xc4, 0x99, 0x64, 0x78, 0x27, 0x47, 0xc9,
0x51, 0xdb, 0x23, 0x09, 0x4a, 0x06, 0x28, 0x51, 0x68, 0x6d, 0xdd, 0xa3, 0xe2, 0x28, 0x6e, 0x11, 0x2d, 0x4a, 0xa2, 0xbe, 0x4f, 0x52, 0x94, 0xe4, 0x28, 0x51, 0x68, 0x6b, 0xd7, 0xa7, 0xf2, 0x3c,
0x27, 0xec, 0x18, 0x5e, 0xe8, 0x85, 0x86, 0x54, 0x68, 0xc5, 0xef, 0xe5, 0x4a, 0x2e, 0xe4, 0xd7, 0x76, 0x88, 0xcb, 0x06, 0x86, 0xcf, 0x7c, 0x66, 0x64, 0x0a, 0x4e, 0xfc, 0x38, 0x5b, 0x65, 0x8b,
0x40, 0xb9, 0xb6, 0x31, 0xb3, 0x28, 0x83, 0x01, 0x0f, 0x63, 0xe6, 0xc0, 0x78, 0x35, 0xb5, 0xc7, 0xec, 0x2b, 0x57, 0x6e, 0xed, 0x2d, 0x4d, 0xca, 0xe0, 0x20, 0x58, 0xcc, 0x5d, 0x98, 0xcd, 0xa6,
0xb3, 0x99, 0x38, 0xe8, 0x02, 0xe3, 0x34, 0x0c, 0xc0, 0x9d, 0xc0, 0x1e, 0xce, 0xc6, 0xba, 0x13, 0xf5, 0xf3, 0x72, 0x26, 0x0e, 0x13, 0xe0, 0x82, 0xb2, 0x10, 0xbc, 0x39, 0xec, 0xc7, 0xe5, 0x58,
0x96, 0x6b, 0xeb, 0xd3, 0xa3, 0x59, 0x1c, 0x08, 0xda, 0x99, 0xac, 0xa9, 0x31, 0x3d, 0x3c, 0x16, 0x32, 0x57, 0x72, 0x6b, 0x77, 0x71, 0x34, 0x8f, 0x43, 0x49, 0x07, 0xf3, 0x39, 0x75, 0x16, 0x87,
0xd4, 0x37, 0x68, 0x20, 0xb8, 0x60, 0xe3, 0x48, 0xfd, 0x87, 0x86, 0x4a, 0x3b, 0x5d, 0xea, 0x08, 0xc7, 0x92, 0x06, 0x06, 0x0d, 0xa5, 0x90, 0x7c, 0x16, 0x69, 0xbf, 0xd6, 0x50, 0xed, 0x28, 0xa1,
0x1a, 0x06, 0xf8, 0x35, 0x2a, 0x75, 0x40, 0xd8, 0xae, 0x2d, 0xec, 0xaa, 0x76, 0x5f, 0x5b, 0x5d, 0xae, 0xa4, 0x2c, 0xc4, 0xff, 0xa2, 0xda, 0x00, 0xa4, 0xed, 0xd9, 0xd2, 0x6e, 0x6a, 0xdf, 0x6b,
0xd8, 0x58, 0x25, 0x33, 0x9b, 0x4e, 0xba, 0x0d, 0xb2, 0xdf, 0xfa, 0x00, 0x8e, 0xd8, 0x03, 0x61, 0xdb, 0x6b, 0x7b, 0xdb, 0x64, 0x69, 0xd3, 0x49, 0xd2, 0x21, 0x3d, 0xe7, 0x09, 0xb8, 0xf2, 0x04,
0x9b, 0xf8, 0xf8, 0x74, 0x25, 0xd7, 0x3f, 0x5d, 0x41, 0x17, 0x7b, 0xd6, 0x48, 0x0d, 0xbb, 0xa8, 0xa4, 0x6d, 0xe2, 0x8b, 0xab, 0xad, 0xd2, 0xe8, 0x6a, 0x0b, 0xdd, 0xee, 0x59, 0x13, 0x35, 0xec,
0xe2, 0x82, 0x0f, 0x02, 0xf6, 0xa3, 0x24, 0x13, 0xaf, 0xce, 0x49, 0xf9, 0x07, 0x97, 0xcb, 0x37, 0xa1, 0x86, 0x07, 0x01, 0x48, 0xe8, 0x45, 0xa9, 0x93, 0x68, 0xae, 0x64, 0xf2, 0x3f, 0xdc, 0x2d,
0xd3, 0x88, 0x79, 0xa3, 0x7f, 0xba, 0x52, 0xc9, 0x6c, 0x59, 0x59, 0xd1, 0xfa, 0xf7, 0x39, 0x74, 0xdf, 0x9d, 0x46, 0xcc, 0x2f, 0x46, 0x57, 0x5b, 0x8d, 0xc2, 0x96, 0x55, 0x14, 0x6d, 0xbf, 0x5a,
0xf3, 0x20, 0x74, 0x9b, 0x94, 0xb3, 0x58, 0x6e, 0x99, 0xb1, 0xeb, 0x81, 0xf8, 0xa7, 0xbe, 0x0a, 0x41, 0x5f, 0x9e, 0x32, 0xaf, 0x4b, 0x05, 0x8f, 0xb3, 0x2d, 0x33, 0xf6, 0x7c, 0x90, 0x9f, 0xb4,
0x3c, 0x02, 0x47, 0xd9, 0x31, 0xc9, 0x95, 0x47, 0x94, 0x4c, 0xa9, 0xf3, 0x30, 0x02, 0xc7, 0x2c, 0xae, 0x8a, 0x88, 0xc0, 0x55, 0xe5, 0x98, 0xe4, 0xde, 0x23, 0x4a, 0x16, 0xe4, 0x79, 0x16, 0x81,
0xab, 0x7c, 0x85, 0x64, 0x65, 0x49, 0x75, 0xec, 0xa3, 0x79, 0x2e, 0x6c, 0x11, 0xf3, 0x6a, 0x5e, 0x6b, 0xd6, 0x95, 0x5f, 0x25, 0x5d, 0x59, 0x99, 0x3a, 0x0e, 0xd0, 0xaa, 0x90, 0xb6, 0x8c, 0x45,
0xe6, 0x69, 0x5e, 0x33, 0x8f, 0xd4, 0x32, 0x17, 0x55, 0xa6, 0xf9, 0xc1, 0xda, 0x52, 0x39, 0xea, 0xb3, 0x9c, 0xf9, 0x74, 0x1f, 0xe8, 0x93, 0x69, 0x99, 0xeb, 0xca, 0x69, 0x35, 0x5f, 0x5b, 0xca,
0xbf, 0x34, 0x74, 0x67, 0x0a, 0xf5, 0x82, 0x72, 0x81, 0xdf, 0x4e, 0x74, 0xd2, 0xb8, 0xa4, 0x93, 0xa3, 0xfd, 0x56, 0x43, 0xdf, 0x2c, 0xa0, 0xfe, 0xa2, 0x42, 0xe2, 0xff, 0xe7, 0x3a, 0x69, 0xdc,
0xa9, 0x87, 0x40, 0x12, 0x5c, 0x36, 0x74, 0x49, 0xa5, 0x2d, 0x0d, 0x77, 0x52, 0xed, 0x74, 0x50, 0xd1, 0xc9, 0xa9, 0x87, 0x40, 0x52, 0x3c, 0x6b, 0xe8, 0x86, 0xb2, 0xad, 0x8d, 0x77, 0xa6, 0xda,
0x91, 0x0a, 0xe8, 0x24, 0xe3, 0x91, 0x5f, 0x5d, 0xd8, 0xd8, 0xba, 0x9e, 0x4f, 0xb3, 0xa2, 0x52, 0xe9, 0xa2, 0x2a, 0x95, 0x30, 0x48, 0xc7, 0xa3, 0xbc, 0xbd, 0xb6, 0x77, 0xf0, 0xb0, 0x3a, 0xcd,
0x15, 0x77, 0x13, 0x51, 0x6b, 0xa0, 0x5d, 0x3f, 0x9f, 0xee, 0x2f, 0xe9, 0x37, 0x3e, 0x42, 0xe5, 0x86, 0xb2, 0xaa, 0x1e, 0xa7, 0xa2, 0x56, 0xae, 0xdd, 0xbe, 0x59, 0x5c, 0x5f, 0xda, 0x6f, 0x7c,
0x0e, 0x0d, 0xb6, 0xbb, 0x36, 0xf5, 0xed, 0x96, 0x0f, 0xca, 0x23, 0x99, 0x51, 0x47, 0xf2, 0xb0, 0x8e, 0xea, 0x03, 0x1a, 0x1e, 0x26, 0x36, 0x0d, 0x6c, 0x27, 0x00, 0x55, 0x23, 0x59, 0x92, 0x47,
0xc8, 0xe0, 0x61, 0x91, 0xdd, 0x40, 0xec, 0xb3, 0x43, 0xc1, 0x68, 0xe0, 0x99, 0xb7, 0x54, 0xde, 0xfa, 0xb0, 0x48, 0xfe, 0xb0, 0xc8, 0x71, 0x28, 0x7b, 0xfc, 0x4c, 0x72, 0x1a, 0xfa, 0xe6, 0x57,
0xf2, 0x5e, 0x4a, 0xcb, 0xca, 0x28, 0xe3, 0x77, 0xa8, 0xc4, 0xc1, 0x07, 0x47, 0x84, 0x4c, 0x4d, 0xca, 0xb7, 0x7e, 0x32, 0xa5, 0x65, 0x15, 0x94, 0xf1, 0x23, 0x54, 0x13, 0x10, 0x80, 0x2b, 0x19,
0xcf, 0xa3, 0xab, 0x76, 0xd2, 0x6e, 0x81, 0x7f, 0xa8, 0x58, 0xb3, 0x9c, 0xb4, 0x72, 0xb8, 0xb2, 0x57, 0xd3, 0xf3, 0xd3, 0x7d, 0x3b, 0x69, 0x3b, 0x10, 0x9c, 0x29, 0xd6, 0xac, 0xa7, 0xad, 0x1c,
0x46, 0x9a, 0xf5, 0x6f, 0x05, 0x74, 0x77, 0xe6, 0xdd, 0xe3, 0x3d, 0x84, 0xdd, 0xd1, 0x09, 0xdf, 0xaf, 0xac, 0x89, 0x66, 0xfb, 0x7d, 0x05, 0x7d, 0xbb, 0xf4, 0xee, 0xf1, 0x9f, 0x08, 0x33, 0x47,
0xf6, 0xfd, 0xf0, 0x23, 0xb8, 0xd2, 0x6d, 0xd1, 0xbc, 0xa7, 0xaa, 0x5f, 0xce, 0xe0, 0xc3, 0x20, 0x00, 0x4f, 0xc0, 0xfb, 0x3d, 0xff, 0x23, 0x50, 0x16, 0x66, 0xd5, 0x96, 0xcd, 0x96, 0xca, 0x1e,
0x6b, 0x0a, 0x88, 0xb7, 0xd0, 0xa2, 0x13, 0x33, 0x06, 0x81, 0x78, 0x0e, 0xb6, 0x2f, 0x8e, 0x7a, 0xf7, 0xe6, 0x22, 0xac, 0x05, 0x14, 0x7e, 0xa9, 0xa1, 0x86, 0x97, 0xdb, 0x80, 0x77, 0xca, 0xbc,
0xd2, 0x52, 0xd1, 0xbc, 0xad, 0xa4, 0x16, 0x9f, 0x65, 0x4e, 0xad, 0xb1, 0xe8, 0x84, 0x77, 0x81, 0xf1, 0xed, 0xfd, 0xf3, 0x31, 0xa6, 0x94, 0x74, 0xa7, 0x95, 0x8f, 0x42, 0xc9, 0x87, 0xe6, 0xa6,
0x53, 0x06, 0xee, 0x90, 0xcf, 0x67, 0xf9, 0x66, 0xe6, 0xd4, 0x1a, 0x8b, 0xc6, 0x9b, 0xa8, 0x0c, 0x4a, 0xb0, 0x51, 0x38, 0xb3, 0x8a, 0x49, 0xe0, 0x13, 0x84, 0xbd, 0x89, 0xa4, 0x38, 0x0c, 0x02,
0x9f, 0x22, 0x70, 0x04, 0xb8, 0x07, 0xa1, 0xcb, 0xab, 0x05, 0x49, 0x8f, 0xae, 0x61, 0x27, 0x75, 0xf6, 0x14, 0xbc, 0xec, 0x01, 0x55, 0xcd, 0xef, 0x94, 0xc2, 0x66, 0xc1, 0x77, 0x1c, 0x64, 0x2d,
0x66, 0x65, 0x22, 0xf1, 0x57, 0x0d, 0x55, 0x94, 0x21, 0xc5, 0x16, 0xe5, 0xe8, 0xbd, 0xfa, 0x1b, 0x00, 0xf1, 0x01, 0x5a, 0x77, 0x63, 0xce, 0x21, 0x94, 0x7f, 0x80, 0x1d, 0xc8, 0xf3, 0x61, 0xb3,
0x4f, 0x8c, 0x34, 0xd3, 0xca, 0x3b, 0x81, 0x60, 0x3d, 0x73, 0x59, 0x15, 0x55, 0xc9, 0x9c, 0x59, 0x92, 0x49, 0x7d, 0xad, 0xa4, 0xd6, 0x7f, 0x2b, 0x9c, 0x5a, 0x33, 0xd1, 0x29, 0xef, 0x81, 0xa0,
0xd9, 0x22, 0x6a, 0x1d, 0x84, 0x27, 0x59, 0xbc, 0x84, 0xf2, 0x6d, 0xe8, 0xc9, 0x6b, 0xfa, 0xdf, 0x1c, 0xbc, 0x31, 0x5f, 0x2d, 0xf2, 0xdd, 0xc2, 0xa9, 0x35, 0x13, 0x8d, 0xf7, 0x51, 0x1d, 0x9e,
0x4a, 0x3e, 0xf1, 0x36, 0x2a, 0x76, 0x6d, 0x3f, 0x86, 0x2b, 0xfc, 0x4f, 0xd3, 0x23, 0xf4, 0x92, 0x45, 0xe0, 0x8e, 0x7b, 0xbc, 0x9a, 0xd1, 0x93, 0x49, 0x3b, 0x9a, 0x3a, 0xb3, 0x0a, 0x91, 0xad,
0x76, 0xc0, 0x1a, 0x90, 0x4f, 0xe7, 0x36, 0x35, 0x73, 0xed, 0xf8, 0x4c, 0xcf, 0x9d, 0x9c, 0xe9, 0x01, 0xc2, 0xf3, 0x4d, 0xc4, 0x1b, 0xa8, 0xdc, 0x87, 0x61, 0x76, 0xe5, 0x9f, 0x5b, 0xe9, 0x27,
0xb9, 0x9f, 0x67, 0x7a, 0xee, 0x73, 0x5f, 0xd7, 0x8e, 0xfb, 0xba, 0x76, 0xd2, 0xd7, 0xb5, 0xdf, 0x3e, 0x44, 0xd5, 0xc4, 0x0e, 0x62, 0xb8, 0xc7, 0xbf, 0x79, 0x7a, 0x1c, 0xff, 0xa6, 0x03, 0xb0,
0x7d, 0x5d, 0xfb, 0x72, 0xae, 0xe7, 0xde, 0xfc, 0xa7, 0xcc, 0xfe, 0x09, 0x00, 0x00, 0xff, 0xff, 0x72, 0xf2, 0xd7, 0x95, 0x7d, 0xcd, 0xdc, 0xb9, 0xb8, 0xd6, 0x4b, 0x97, 0xd7, 0x7a, 0xe9, 0xcd,
0xd0, 0x3c, 0x91, 0x46, 0xc1, 0x07, 0x00, 0x00, 0xb5, 0x5e, 0x7a, 0x3e, 0xd2, 0xb5, 0x8b, 0x91, 0xae, 0x5d, 0x8e, 0x74, 0xed, 0xdd, 0x48, 0xd7,
0x5e, 0xdc, 0xe8, 0xa5, 0xff, 0x3e, 0x53, 0xb7, 0xfe, 0x21, 0x00, 0x00, 0xff, 0xff, 0x59, 0x3e,
0xe1, 0xf8, 0x0d, 0x08, 0x00, 0x00,
} }

View File

@ -75,17 +75,10 @@ message PodDisruptionBudgetSpec {
// PodDisruptionBudgetStatus represents information about the status of a // PodDisruptionBudgetStatus represents information about the status of a
// PodDisruptionBudget. Status may trail the actual state of a system. // PodDisruptionBudget. Status may trail the actual state of a system.
message PodDisruptionBudgetStatus { message PodDisruptionBudgetStatus {
// Number of pod disruptions that are currently allowed. // Most recent generation observed when updating this PDB status. PodDisruptionsAllowed and other
optional int32 disruptionsAllowed = 1; // status informatio is valid only if observedGeneration equals to PDB's object generation.
// +optional
// current number of healthy pods optional int64 observedGeneration = 1;
optional int32 currentHealthy = 2;
// minimum desired number of healthy pods
optional int32 desiredHealthy = 3;
// total number of pods counted by this disruption budget
optional int32 expectedPods = 4;
// DisruptedPods contains information about pods whose eviction was // DisruptedPods contains information about pods whose eviction was
// processed by the API server eviction subresource handler but has not // processed by the API server eviction subresource handler but has not
@ -98,6 +91,18 @@ message PodDisruptionBudgetStatus {
// the list automatically by PodDisruptionBudget controller after some time. // the list automatically by PodDisruptionBudget controller after some time.
// If everything goes smooth this map should be empty for the most of the time. // If everything goes smooth this map should be empty for the most of the time.
// Large number of entries in the map may indicate problems with pod deletions. // Large number of entries in the map may indicate problems with pod deletions.
map<string, k8s.io.kubernetes.pkg.api.unversioned.Time> disruptedPods = 5; map<string, k8s.io.kubernetes.pkg.api.unversioned.Time> disruptedPods = 2;
// Number of pod disruptions that are currently allowed.
optional int32 disruptionsAllowed = 3;
// current number of healthy pods
optional int32 currentHealthy = 4;
// minimum desired number of healthy pods
optional int32 desiredHealthy = 5;
// total number of pods counted by this disruption budget
optional int32 expectedPods = 6;
} }

File diff suppressed because it is too large Load Diff

View File

@ -38,17 +38,10 @@ type PodDisruptionBudgetSpec struct {
// PodDisruptionBudgetStatus represents information about the status of a // PodDisruptionBudgetStatus represents information about the status of a
// PodDisruptionBudget. Status may trail the actual state of a system. // PodDisruptionBudget. Status may trail the actual state of a system.
type PodDisruptionBudgetStatus struct { type PodDisruptionBudgetStatus struct {
// Number of pod disruptions that are currently allowed. // Most recent generation observed when updating this PDB status. PodDisruptionsAllowed and other
PodDisruptionsAllowed int32 `json:"disruptionsAllowed" protobuf:"varint,1,opt,name=disruptionsAllowed"` // status informatio is valid only if observedGeneration equals to PDB's object generation.
// +optional
// current number of healthy pods ObservedGeneration int64 `json:"observedGeneration,omitempty" protobuf:"varint,1,opt,name=observedGeneration"`
CurrentHealthy int32 `json:"currentHealthy" protobuf:"varint,2,opt,name=currentHealthy"`
// minimum desired number of healthy pods
DesiredHealthy int32 `json:"desiredHealthy" protobuf:"varint,3,opt,name=desiredHealthy"`
// total number of pods counted by this disruption budget
ExpectedPods int32 `json:"expectedPods" protobuf:"varint,4,opt,name=expectedPods"`
// DisruptedPods contains information about pods whose eviction was // DisruptedPods contains information about pods whose eviction was
// processed by the API server eviction subresource handler but has not // processed by the API server eviction subresource handler but has not
@ -61,7 +54,19 @@ type PodDisruptionBudgetStatus struct {
// the list automatically by PodDisruptionBudget controller after some time. // the list automatically by PodDisruptionBudget controller after some time.
// If everything goes smooth this map should be empty for the most of the time. // If everything goes smooth this map should be empty for the most of the time.
// Large number of entries in the map may indicate problems with pod deletions. // Large number of entries in the map may indicate problems with pod deletions.
DisruptedPods map[string]unversioned.Time `json:"disruptedPods" protobuf:"bytes,5,rep,name=disruptedPods"` DisruptedPods map[string]unversioned.Time `json:"disruptedPods" protobuf:"bytes,2,rep,name=disruptedPods"`
// Number of pod disruptions that are currently allowed.
PodDisruptionsAllowed int32 `json:"disruptionsAllowed" protobuf:"varint,3,opt,name=disruptionsAllowed"`
// current number of healthy pods
CurrentHealthy int32 `json:"currentHealthy" protobuf:"varint,4,opt,name=currentHealthy"`
// minimum desired number of healthy pods
DesiredHealthy int32 `json:"desiredHealthy" protobuf:"varint,5,opt,name=desiredHealthy"`
// total number of pods counted by this disruption budget
ExpectedPods int32 `json:"expectedPods" protobuf:"varint,6,opt,name=expectedPods"`
} }
// +genclient=true // +genclient=true

View File

@ -67,11 +67,12 @@ func (PodDisruptionBudgetSpec) SwaggerDoc() map[string]string {
var map_PodDisruptionBudgetStatus = map[string]string{ var map_PodDisruptionBudgetStatus = map[string]string{
"": "PodDisruptionBudgetStatus represents information about the status of a PodDisruptionBudget. Status may trail the actual state of a system.", "": "PodDisruptionBudgetStatus represents information about the status of a PodDisruptionBudget. Status may trail the actual state of a system.",
"observedGeneration": "Most recent generation observed when updating this PDB status. PodDisruptionsAllowed and other status informatio is valid only if observedGeneration equals to PDB's object generation.",
"disruptedPods": "DisruptedPods contains information about pods whose eviction was processed by the API server eviction subresource handler but has not yet been observed by the PodDisruptionBudget controller. A pod will be in this map from the time when the API server processed the eviction request to the time when the pod is seen by PDB controller as having been marked for deletion (or after a timeout). The key in the map is the name of the pod and the value is the time when the API server processed the eviction request. If the deletion didn't occur and a pod is still there it will be removed from the list automatically by PodDisruptionBudget controller after some time. If everything goes smooth this map should be empty for the most of the time. Large number of entries in the map may indicate problems with pod deletions.",
"disruptionsAllowed": "Number of pod disruptions that are currently allowed.", "disruptionsAllowed": "Number of pod disruptions that are currently allowed.",
"currentHealthy": "current number of healthy pods", "currentHealthy": "current number of healthy pods",
"desiredHealthy": "minimum desired number of healthy pods", "desiredHealthy": "minimum desired number of healthy pods",
"expectedPods": "total number of pods counted by this disruption budget", "expectedPods": "total number of pods counted by this disruption budget",
"disruptedPods": "DisruptedPods contains information about pods whose eviction was processed by the API server eviction subresource handler but has not yet been observed by the PodDisruptionBudget controller. A pod will be in this map from the time when the API server processed the eviction request to the time when the pod is seen by PDB controller as having been marked for deletion (or after a timeout). The key in the map is the name of the pod and the value is the time when the API server processed the eviction request. If the deletion didn't occur and a pod is still there it will be removed from the list automatically by PodDisruptionBudget controller after some time. If everything goes smooth this map should be empty for the most of the time. Large number of entries in the map may indicate problems with pod deletions.",
} }
func (PodDisruptionBudgetStatus) SwaggerDoc() map[string]string { func (PodDisruptionBudgetStatus) SwaggerDoc() map[string]string {

View File

@ -154,11 +154,12 @@ func Convert_policy_PodDisruptionBudgetSpec_To_v1beta1_PodDisruptionBudgetSpec(i
} }
func autoConvert_v1beta1_PodDisruptionBudgetStatus_To_policy_PodDisruptionBudgetStatus(in *PodDisruptionBudgetStatus, out *policy.PodDisruptionBudgetStatus, s conversion.Scope) error { func autoConvert_v1beta1_PodDisruptionBudgetStatus_To_policy_PodDisruptionBudgetStatus(in *PodDisruptionBudgetStatus, out *policy.PodDisruptionBudgetStatus, s conversion.Scope) error {
out.ObservedGeneration = in.ObservedGeneration
out.DisruptedPods = *(*map[string]unversioned.Time)(unsafe.Pointer(&in.DisruptedPods))
out.PodDisruptionsAllowed = in.PodDisruptionsAllowed out.PodDisruptionsAllowed = in.PodDisruptionsAllowed
out.CurrentHealthy = in.CurrentHealthy out.CurrentHealthy = in.CurrentHealthy
out.DesiredHealthy = in.DesiredHealthy out.DesiredHealthy = in.DesiredHealthy
out.ExpectedPods = in.ExpectedPods out.ExpectedPods = in.ExpectedPods
out.DisruptedPods = *(*map[string]unversioned.Time)(unsafe.Pointer(&in.DisruptedPods))
return nil return nil
} }
@ -167,11 +168,12 @@ func Convert_v1beta1_PodDisruptionBudgetStatus_To_policy_PodDisruptionBudgetStat
} }
func autoConvert_policy_PodDisruptionBudgetStatus_To_v1beta1_PodDisruptionBudgetStatus(in *policy.PodDisruptionBudgetStatus, out *PodDisruptionBudgetStatus, s conversion.Scope) error { func autoConvert_policy_PodDisruptionBudgetStatus_To_v1beta1_PodDisruptionBudgetStatus(in *policy.PodDisruptionBudgetStatus, out *PodDisruptionBudgetStatus, s conversion.Scope) error {
out.ObservedGeneration = in.ObservedGeneration
out.DisruptedPods = *(*map[string]unversioned.Time)(unsafe.Pointer(&in.DisruptedPods))
out.PodDisruptionsAllowed = in.PodDisruptionsAllowed out.PodDisruptionsAllowed = in.PodDisruptionsAllowed
out.CurrentHealthy = in.CurrentHealthy out.CurrentHealthy = in.CurrentHealthy
out.DesiredHealthy = in.DesiredHealthy out.DesiredHealthy = in.DesiredHealthy
out.ExpectedPods = in.ExpectedPods out.ExpectedPods = in.ExpectedPods
out.DisruptedPods = *(*map[string]unversioned.Time)(unsafe.Pointer(&in.DisruptedPods))
return nil return nil
} }

View File

@ -126,10 +126,7 @@ func DeepCopy_v1beta1_PodDisruptionBudgetStatus(in interface{}, out interface{},
{ {
in := in.(*PodDisruptionBudgetStatus) in := in.(*PodDisruptionBudgetStatus)
out := out.(*PodDisruptionBudgetStatus) out := out.(*PodDisruptionBudgetStatus)
out.PodDisruptionsAllowed = in.PodDisruptionsAllowed out.ObservedGeneration = in.ObservedGeneration
out.CurrentHealthy = in.CurrentHealthy
out.DesiredHealthy = in.DesiredHealthy
out.ExpectedPods = in.ExpectedPods
if in.DisruptedPods != nil { if in.DisruptedPods != nil {
in, out := &in.DisruptedPods, &out.DisruptedPods in, out := &in.DisruptedPods, &out.DisruptedPods
*out = make(map[string]unversioned.Time) *out = make(map[string]unversioned.Time)
@ -139,6 +136,10 @@ func DeepCopy_v1beta1_PodDisruptionBudgetStatus(in interface{}, out interface{},
} else { } else {
out.DisruptedPods = nil out.DisruptedPods = nil
} }
out.PodDisruptionsAllowed = in.PodDisruptionsAllowed
out.CurrentHealthy = in.CurrentHealthy
out.DesiredHealthy = in.DesiredHealthy
out.ExpectedPods = in.ExpectedPods
return nil return nil
} }
} }

View File

@ -126,10 +126,7 @@ func DeepCopy_policy_PodDisruptionBudgetStatus(in interface{}, out interface{},
{ {
in := in.(*PodDisruptionBudgetStatus) in := in.(*PodDisruptionBudgetStatus)
out := out.(*PodDisruptionBudgetStatus) out := out.(*PodDisruptionBudgetStatus)
out.PodDisruptionsAllowed = in.PodDisruptionsAllowed out.ObservedGeneration = in.ObservedGeneration
out.CurrentHealthy = in.CurrentHealthy
out.DesiredHealthy = in.DesiredHealthy
out.ExpectedPods = in.ExpectedPods
if in.DisruptedPods != nil { if in.DisruptedPods != nil {
in, out := &in.DisruptedPods, &out.DisruptedPods in, out := &in.DisruptedPods, &out.DisruptedPods
*out = make(map[string]unversioned.Time) *out = make(map[string]unversioned.Time)
@ -139,6 +136,10 @@ func DeepCopy_policy_PodDisruptionBudgetStatus(in interface{}, out interface{},
} else { } else {
out.DisruptedPods = nil out.DisruptedPods = nil
} }
out.PodDisruptionsAllowed = in.PodDisruptionsAllowed
out.CurrentHealthy = in.CurrentHealthy
out.DesiredHealthy = in.DesiredHealthy
out.ExpectedPods = in.ExpectedPods
return nil return nil
} }
} }

View File

@ -669,7 +669,8 @@ func (dc *DisruptionController) updatePdbStatus(pdb *policy.PodDisruptionBudget,
pdb.Status.DesiredHealthy == desiredHealthy && pdb.Status.DesiredHealthy == desiredHealthy &&
pdb.Status.ExpectedPods == expectedCount && pdb.Status.ExpectedPods == expectedCount &&
pdb.Status.PodDisruptionsAllowed == disruptionsAllowed && pdb.Status.PodDisruptionsAllowed == disruptionsAllowed &&
reflect.DeepEqual(pdb.Status.DisruptedPods, disruptedPods) { reflect.DeepEqual(pdb.Status.DisruptedPods, disruptedPods) &&
pdb.Status.ObservedGeneration == pdb.Generation {
return nil return nil
} }
@ -685,6 +686,7 @@ func (dc *DisruptionController) updatePdbStatus(pdb *policy.PodDisruptionBudget,
ExpectedPods: expectedCount, ExpectedPods: expectedCount,
PodDisruptionsAllowed: disruptionsAllowed, PodDisruptionsAllowed: disruptionsAllowed,
DisruptedPods: disruptedPods, DisruptedPods: disruptedPods,
ObservedGeneration: pdb.Generation,
} }
return dc.getUpdater()(&newPdb) return dc.getUpdater()(&newPdb)

View File

@ -58,14 +58,16 @@ func (ps *pdbStates) Get(key string) policy.PodDisruptionBudget {
func (ps *pdbStates) VerifyPdbStatus(t *testing.T, key string, disruptionsAllowed, currentHealthy, desiredHealthy, expectedPods int32, func (ps *pdbStates) VerifyPdbStatus(t *testing.T, key string, disruptionsAllowed, currentHealthy, desiredHealthy, expectedPods int32,
disruptedPodMap map[string]unversioned.Time) { disruptedPodMap map[string]unversioned.Time) {
actualPDB := ps.Get(key)
expectedStatus := policy.PodDisruptionBudgetStatus{ expectedStatus := policy.PodDisruptionBudgetStatus{
PodDisruptionsAllowed: disruptionsAllowed, PodDisruptionsAllowed: disruptionsAllowed,
CurrentHealthy: currentHealthy, CurrentHealthy: currentHealthy,
DesiredHealthy: desiredHealthy, DesiredHealthy: desiredHealthy,
ExpectedPods: expectedPods, ExpectedPods: expectedPods,
DisruptedPods: disruptedPodMap, DisruptedPods: disruptedPodMap,
ObservedGeneration: actualPDB.Generation,
} }
actualStatus := ps.Get(key).Status actualStatus := actualPDB.Status
if !reflect.DeepEqual(actualStatus, expectedStatus) { if !reflect.DeepEqual(actualStatus, expectedStatus) {
debug.PrintStack() debug.PrintStack()
t.Fatalf("PDB %q status mismatch. Expected %+v but got %+v.", key, expectedStatus, actualStatus) t.Fatalf("PDB %q status mismatch. Expected %+v but got %+v.", key, expectedStatus, actualStatus)

View File

@ -5212,6 +5212,26 @@ var OpenAPIDefinitions *common.OpenAPIDefinitions = &common.OpenAPIDefinitions{
SchemaProps: spec.SchemaProps{ SchemaProps: spec.SchemaProps{
Description: "PodDisruptionBudgetStatus represents information about the status of a PodDisruptionBudget. Status may trail the actual state of a system.", Description: "PodDisruptionBudgetStatus represents information about the status of a PodDisruptionBudget. Status may trail the actual state of a system.",
Properties: map[string]spec.Schema{ Properties: map[string]spec.Schema{
"observedGeneration": {
SchemaProps: spec.SchemaProps{
Description: "Most recent generation observed when updating this PDB status. PodDisruptionsAllowed and other status informatio is valid only if observedGeneration equals to PDB's object generation.",
Type: []string{"integer"},
Format: "int64",
},
},
"disruptedPods": {
SchemaProps: spec.SchemaProps{
Description: "DisruptedPods contains information about pods whose eviction was processed by the API server eviction subresource handler but has not yet been observed by the PodDisruptionBudget controller. A pod will be in this map from the time when the API server processed the eviction request to the time when the pod is seen by PDB controller as having been marked for deletion (or after a timeout). The key in the map is the name of the pod and the value is the time when the API server processed the eviction request. If the deletion didn't occur and a pod is still there it will be removed from the list automatically by PodDisruptionBudget controller after some time. If everything goes smooth this map should be empty for the most of the time. Large number of entries in the map may indicate problems with pod deletions.",
Type: []string{"object"},
AdditionalProperties: &spec.SchemaOrBool{
Schema: &spec.Schema{
SchemaProps: spec.SchemaProps{
Ref: spec.MustCreateRef("#/definitions/unversioned.Time"),
},
},
},
},
},
"disruptionsAllowed": { "disruptionsAllowed": {
SchemaProps: spec.SchemaProps{ SchemaProps: spec.SchemaProps{
Description: "Number of pod disruptions that are currently allowed.", Description: "Number of pod disruptions that are currently allowed.",
@ -5240,21 +5260,8 @@ var OpenAPIDefinitions *common.OpenAPIDefinitions = &common.OpenAPIDefinitions{
Format: "int32", Format: "int32",
}, },
}, },
"disruptedPods": {
SchemaProps: spec.SchemaProps{
Description: "DisruptedPods contains information about pods whose eviction was processed by the API server eviction subresource handler but has not yet been observed by the PodDisruptionBudget controller. A pod will be in this map from the time when the API server processed the eviction request to the time when the pod is seen by PDB controller as having been marked for deletion (or after a timeout). The key in the map is the name of the pod and the value is the time when the API server processed the eviction request. If the deletion didn't occur and a pod is still there it will be removed from the list automatically by PodDisruptionBudget controller after some time. If everything goes smooth this map should be empty for the most of the time. Large number of entries in the map may indicate problems with pod deletions.",
Type: []string{"object"},
AdditionalProperties: &spec.SchemaOrBool{
Schema: &spec.Schema{
SchemaProps: spec.SchemaProps{
Ref: spec.MustCreateRef("#/definitions/unversioned.Time"),
},
},
},
},
},
}, },
Required: []string{"disruptionsAllowed", "currentHealthy", "desiredHealthy", "expectedPods", "disruptedPods"}, Required: []string{"disruptedPods", "disruptionsAllowed", "currentHealthy", "desiredHealthy", "expectedPods"},
}, },
}, },
Dependencies: []string{ Dependencies: []string{
@ -16998,6 +17005,26 @@ var OpenAPIDefinitions *common.OpenAPIDefinitions = &common.OpenAPIDefinitions{
SchemaProps: spec.SchemaProps{ SchemaProps: spec.SchemaProps{
Description: "PodDisruptionBudgetStatus represents information about the status of a PodDisruptionBudget. Status may trail the actual state of a system.", Description: "PodDisruptionBudgetStatus represents information about the status of a PodDisruptionBudget. Status may trail the actual state of a system.",
Properties: map[string]spec.Schema{ Properties: map[string]spec.Schema{
"observedGeneration": {
SchemaProps: spec.SchemaProps{
Description: "Most recent generation observed when updating this PDB status. PodDisruptionsAllowed and other status informatio is valid only if observedGeneration equals to PDB's object generation.",
Type: []string{"integer"},
Format: "int64",
},
},
"disruptedPods": {
SchemaProps: spec.SchemaProps{
Description: "DisruptedPods contains information about pods whose eviction was processed by the API server eviction subresource handler but has not yet been observed by the PodDisruptionBudget controller. A pod will be in this map from the time when the API server processed the eviction request to the time when the pod is seen by PDB controller as having been marked for deletion (or after a timeout). The key in the map is the name of the pod and the value is the time when the API server processed the eviction request. If the deletion didn't occur and a pod is still there it will be removed from the list automatically by PodDisruptionBudget controller after some time. If everything goes smooth this map should be empty for the most of the time. Large number of entries in the map may indicate problems with pod deletions.",
Type: []string{"object"},
AdditionalProperties: &spec.SchemaOrBool{
Schema: &spec.Schema{
SchemaProps: spec.SchemaProps{
Ref: spec.MustCreateRef("#/definitions/unversioned.Time"),
},
},
},
},
},
"disruptionsAllowed": { "disruptionsAllowed": {
SchemaProps: spec.SchemaProps{ SchemaProps: spec.SchemaProps{
Description: "Number of pod disruptions that are currently allowed.", Description: "Number of pod disruptions that are currently allowed.",
@ -17026,21 +17053,8 @@ var OpenAPIDefinitions *common.OpenAPIDefinitions = &common.OpenAPIDefinitions{
Format: "int32", Format: "int32",
}, },
}, },
"disruptedPods": {
SchemaProps: spec.SchemaProps{
Description: "DisruptedPods contains information about pods whose eviction was processed by the API server eviction subresource handler but has not yet been observed by the PodDisruptionBudget controller. A pod will be in this map from the time when the API server processed the eviction request to the time when the pod is seen by PDB controller as having been marked for deletion (or after a timeout). The key in the map is the name of the pod and the value is the time when the API server processed the eviction request. If the deletion didn't occur and a pod is still there it will be removed from the list automatically by PodDisruptionBudget controller after some time. If everything goes smooth this map should be empty for the most of the time. Large number of entries in the map may indicate problems with pod deletions.",
Type: []string{"object"},
AdditionalProperties: &spec.SchemaOrBool{
Schema: &spec.Schema{
SchemaProps: spec.SchemaProps{
Ref: spec.MustCreateRef("#/definitions/unversioned.Time"),
},
},
},
},
},
}, },
Required: []string{"disruptionsAllowed", "currentHealthy", "desiredHealthy", "expectedPods", "disruptedPods"}, Required: []string{"disruptedPods", "disruptionsAllowed", "currentHealthy", "desiredHealthy", "expectedPods"},
}, },
}, },
Dependencies: []string{ Dependencies: []string{

View File

@ -116,6 +116,9 @@ func (r *EvictionREST) Create(ctx api.Context, obj runtime.Object) (runtime.Obje
} }
func (r *EvictionREST) checkAndDecrement(namespace string, podName string, pdb policy.PodDisruptionBudget) (ok bool, err error) { func (r *EvictionREST) checkAndDecrement(namespace string, podName string, pdb policy.PodDisruptionBudget) (ok bool, err error) {
if pdb.Status.ObservedGeneration != pdb.Generation {
return false, nil
}
if pdb.Status.PodDisruptionsAllowed < 0 { if pdb.Status.PodDisruptionsAllowed < 0 {
return false, fmt.Errorf("pdb disruptions allowed is negative") return false, fmt.Errorf("pdb disruptions allowed is negative")
} }

View File

@ -91,8 +91,15 @@ func TestStatusUpdate(t *testing.T) {
if err := storage.Storage.Create(ctx, key, validPodDisruptionBudget, nil, 0); err != nil { if err := storage.Storage.Create(ctx, key, validPodDisruptionBudget, nil, 0); err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
obj, err := storage.Get(ctx, "foo")
if err != nil {
t.Fatalf("failed to get pdb: %v", err)
}
obtainedPdb := obj.(*policy.PodDisruptionBudget)
update := policy.PodDisruptionBudget{ update := policy.PodDisruptionBudget{
ObjectMeta: validPodDisruptionBudget.ObjectMeta, ObjectMeta: obtainedPdb.ObjectMeta,
Spec: policy.PodDisruptionBudgetSpec{ Spec: policy.PodDisruptionBudgetSpec{
MinAvailable: intstr.FromInt(8), MinAvailable: intstr.FromInt(8),
}, },
@ -104,7 +111,7 @@ func TestStatusUpdate(t *testing.T) {
if _, _, err := statusStorage.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update, api.Scheme)); err != nil { if _, _, err := statusStorage.Update(ctx, update.Name, rest.DefaultUpdatedObjectInfo(&update, api.Scheme)); err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
obj, err := storage.Get(ctx, "foo") obj, err = storage.Get(ctx, "foo")
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }

View File

@ -91,9 +91,10 @@ func (podDisruptionBudgetStrategy) ValidateUpdate(ctx api.Context, obj, old runt
return append(validationErrorList, updateErrorList...) return append(validationErrorList, updateErrorList...)
} }
// AllowUnconditionalUpdate is the default update policy for PodDisruptionBudget objects. // AllowUnconditionalUpdate is the default update policy for PodDisruptionBudget objects. Status update should
// only be allowed if version match.
func (podDisruptionBudgetStrategy) AllowUnconditionalUpdate() bool { func (podDisruptionBudgetStrategy) AllowUnconditionalUpdate() bool {
return true return false
} }
// PodDisruptionBudgetToSelectableFields returns a field set that represents the object. // PodDisruptionBudgetToSelectableFields returns a field set that represents the object.