Merge pull request #871 from virtual-kubelet/set-node-lease-owner
Set Node Leader Owner Reference
This commit is contained in:
75
node/node.go
75
node/node.go
@@ -206,8 +206,7 @@ func (n *NodeController) Run(ctx context.Context) error {
|
|||||||
return n.controlLoop(ctx)
|
return n.controlLoop(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
n.lease = newLease(n.lease)
|
n.lease = newLease(ctx, n.lease, n.n, n.pingInterval)
|
||||||
setLeaseAttrs(n.lease, n.n, n.pingInterval*5)
|
|
||||||
|
|
||||||
l, err := ensureLease(ctx, n.leases, n.lease)
|
l, err := ensureLease(ctx, n.leases, n.lease)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -347,7 +346,7 @@ func (n *NodeController) handlePing(ctx context.Context) (retErr error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (n *NodeController) updateLease(ctx context.Context) error {
|
func (n *NodeController) updateLease(ctx context.Context) error {
|
||||||
l, err := updateNodeLease(ctx, n.leases, newLease(n.lease))
|
l, err := updateNodeLease(ctx, n.leases, newLease(ctx, n.lease, n.n, n.pingInterval))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -601,7 +600,8 @@ func updateNodeStatus(ctx context.Context, nodes v1.NodeInterface, nodeFromProvi
|
|||||||
return updatedNode, nil
|
return updatedNode, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newLease(base *coord.Lease) *coord.Lease {
|
// This will return a new lease. It will either update base lease (and the set the renewal time appropriately), or create a brand new lease
|
||||||
|
func newLease(ctx context.Context, base *coord.Lease, node *corev1.Node, leaseRenewalInterval time.Duration) *coord.Lease {
|
||||||
var lease *coord.Lease
|
var lease *coord.Lease
|
||||||
if base == nil {
|
if base == nil {
|
||||||
lease = &coord.Lease{}
|
lease = &coord.Lease{}
|
||||||
@@ -610,23 +610,62 @@ func newLease(base *coord.Lease) *coord.Lease {
|
|||||||
}
|
}
|
||||||
|
|
||||||
lease.Spec.RenewTime = &metav1.MicroTime{Time: time.Now()}
|
lease.Spec.RenewTime = &metav1.MicroTime{Time: time.Now()}
|
||||||
|
|
||||||
|
if lease.Spec.LeaseDurationSeconds == nil {
|
||||||
|
// This is 25 due to historical reasons. It was supposed to be * 5, but...reasons
|
||||||
|
d := int32(leaseRenewalInterval.Seconds()) * 25
|
||||||
|
lease.Spec.LeaseDurationSeconds = &d
|
||||||
|
}
|
||||||
|
|
||||||
|
if lease.Name == "" {
|
||||||
|
lease.Name = node.Name
|
||||||
|
}
|
||||||
|
if lease.Spec.HolderIdentity == nil {
|
||||||
|
// Let's do a copy here
|
||||||
|
name := node.Name
|
||||||
|
lease.Spec.HolderIdentity = &name
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copied and pasted from: https://github.com/kubernetes/kubernetes/blob/442a69c3bdf6fe8e525b05887e57d89db1e2f3a5/pkg/kubelet/nodelease/controller.go#L213-L216
|
||||||
|
// Setting owner reference needs node's UID. Note that it is different from
|
||||||
|
// kubelet.nodeRef.UID. When lease is initially created, it is possible that
|
||||||
|
// the connection between master and node is not ready yet. So try to set
|
||||||
|
// owner reference every time when renewing the lease, until successful.
|
||||||
|
//
|
||||||
|
// We have a special case to deal with in the node may be deleted and
|
||||||
|
// come back with a different UID. In this case the lease object should
|
||||||
|
// be deleted due to a owner reference cascading deletion, and when we renew
|
||||||
|
// lease again updateNodeLease will call ensureLease, and establish a new
|
||||||
|
// lease with the right node ID
|
||||||
|
if l := len(lease.OwnerReferences); l == 0 {
|
||||||
|
lease.OwnerReferences = []metav1.OwnerReference{
|
||||||
|
{
|
||||||
|
APIVersion: corev1.SchemeGroupVersion.WithKind("Node").Version,
|
||||||
|
Kind: corev1.SchemeGroupVersion.WithKind("Node").Kind,
|
||||||
|
Name: node.Name,
|
||||||
|
UID: node.UID,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} else if l > 0 {
|
||||||
|
var foundThisNode, foundNode bool
|
||||||
|
for _, ref := range lease.OwnerReferences {
|
||||||
|
if ref.APIVersion == corev1.SchemeGroupVersion.WithKind("Node").Version && ref.Kind == corev1.SchemeGroupVersion.WithKind("Node").Kind {
|
||||||
|
foundNode = true
|
||||||
|
if node.UID == ref.UID && node.Name == ref.Name {
|
||||||
|
foundThisNode = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !foundThisNode && !foundNode {
|
||||||
|
log.G(ctx).Warn("Found that lease had owner references, but no nodes in owner references")
|
||||||
|
} else if foundNode {
|
||||||
|
log.G(ctx).Warn("Found that lease had owner references, but nodes in owner references that is not this node")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return lease
|
return lease
|
||||||
}
|
}
|
||||||
|
|
||||||
func setLeaseAttrs(l *coord.Lease, n *corev1.Node, dur time.Duration) {
|
|
||||||
if l.Name == "" {
|
|
||||||
l.Name = n.Name
|
|
||||||
}
|
|
||||||
if l.Spec.HolderIdentity == nil {
|
|
||||||
l.Spec.HolderIdentity = &n.Name
|
|
||||||
}
|
|
||||||
|
|
||||||
if l.Spec.LeaseDurationSeconds == nil {
|
|
||||||
d := int32(dur.Seconds()) * 5
|
|
||||||
l.Spec.LeaseDurationSeconds = &d
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateNodeStatusHeartbeat(n *corev1.Node) {
|
func updateNodeStatusHeartbeat(n *corev1.Node) {
|
||||||
now := metav1.NewTime(time.Now())
|
now := metav1.NewTime(time.Now())
|
||||||
for i := range n.Status.Conditions {
|
for i := range n.Status.Conditions {
|
||||||
|
|||||||
@@ -228,8 +228,7 @@ func TestEnsureLease(t *testing.T) {
|
|||||||
n := testNode(t)
|
n := testNode(t)
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
lease := newLease(nil)
|
lease := newLease(ctx, nil, n, 1*time.Second)
|
||||||
setLeaseAttrs(lease, n, 1*time.Second)
|
|
||||||
|
|
||||||
l1, err := ensureLease(ctx, c, lease.DeepCopy())
|
l1, err := ensureLease(ctx, c, lease.DeepCopy())
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
@@ -278,12 +277,13 @@ func TestUpdateNodeStatus(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestUpdateNodeLease(t *testing.T) {
|
func TestUpdateNodeLease(t *testing.T) {
|
||||||
leases := testclient.NewSimpleClientset().CoordinationV1beta1().Leases(corev1.NamespaceNodeLease)
|
|
||||||
lease := newLease(nil)
|
|
||||||
n := testNode(t)
|
|
||||||
setLeaseAttrs(lease, n, 0)
|
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
|
leases := testclient.NewSimpleClientset().CoordinationV1beta1().Leases(corev1.NamespaceNodeLease)
|
||||||
|
n := testNode(t)
|
||||||
|
|
||||||
|
lease := newLease(ctx, nil, n, time.Duration(0))
|
||||||
|
|
||||||
l, err := updateNodeLease(ctx, leases, lease)
|
l, err := updateNodeLease(ctx, leases, lease)
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.Equal(t, l.Name, lease.Name)
|
assert.Equal(t, l.Name, lease.Name)
|
||||||
@@ -304,6 +304,25 @@ func TestUpdateNodeLease(t *testing.T) {
|
|||||||
assert.Assert(t, cmp.DeepEqual(compare.Spec.HolderIdentity, lease.Spec.HolderIdentity))
|
assert.Assert(t, cmp.DeepEqual(compare.Spec.HolderIdentity, lease.Spec.HolderIdentity))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFixNodeLeaseReferences(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
n := testNode(t)
|
||||||
|
|
||||||
|
lease1 := newLease(ctx, nil, n, time.Second)
|
||||||
|
// Let's break owner references
|
||||||
|
lease1.OwnerReferences = nil
|
||||||
|
time.Sleep(2 * time.Nanosecond)
|
||||||
|
lease2 := newLease(ctx, lease1, n, time.Second)
|
||||||
|
|
||||||
|
// Make sure that newLease actually did its jobs
|
||||||
|
assert.Assert(t, lease2.Spec.RenewTime.Nanosecond() > lease1.Spec.RenewTime.Nanosecond())
|
||||||
|
|
||||||
|
// Let's check if owner references got set
|
||||||
|
assert.Assert(t, is.Len(lease2.OwnerReferences, 1))
|
||||||
|
assert.Assert(t, is.Equal(lease2.OwnerReferences[0].UID, n.UID))
|
||||||
|
assert.Assert(t, is.Equal(lease2.OwnerReferences[0].Name, n.Name))
|
||||||
|
}
|
||||||
|
|
||||||
// TestPingAfterStatusUpdate checks that Ping continues to be called with the specified interval
|
// TestPingAfterStatusUpdate checks that Ping continues to be called with the specified interval
|
||||||
// after a node status update occurs, when leases are disabled.
|
// after a node status update occurs, when leases are disabled.
|
||||||
//
|
//
|
||||||
|
|||||||
Reference in New Issue
Block a user