Skip to content

Commit 1f2afb4

Browse files
authored
Merge pull request #831 from cybozu-go/fix-eps-ops
Confirm EndpointSlice in mtest
2 parents c768a33 + c42ac14 commit 1f2afb4

File tree

4 files changed

+107
-17
lines changed

4 files changed

+107
-17
lines changed

mtest/kubernetes_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,8 @@ func testKubernetes() {
317317
Expect(err).NotTo(HaveOccurred(), "stderr=%s", stderr)
318318
_, stderr, err = kubectl("-n", "kube-system", "get", "endpoints/cke-etcd")
319319
Expect(err).NotTo(HaveOccurred(), "stderr=%s", stderr)
320+
_, stderr, err = kubectl("-n", "kube-system", "get", "endpointslices/cke-etcd")
321+
Expect(err).NotTo(HaveOccurred(), "stderr=%s", stderr)
320322
})
321323

322324
It("can output audit log to journal log", func() {

mtest/operators_test.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@ import (
1111
. "github.com/onsi/ginkgo/v2"
1212
. "github.com/onsi/gomega"
1313
corev1 "k8s.io/api/core/v1"
14+
discoveryv1 "k8s.io/api/discovery/v1"
1415
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
1516
kubeletv1beta1 "k8s.io/kubelet/config/v1beta1"
17+
"k8s.io/utils/ptr"
1618
)
1719

1820
func testOperators(isDegraded bool) {
@@ -76,6 +78,44 @@ func testOperators(isDegraded bool) {
7678
Expect(ep.Subsets[0].NotReadyAddresses).Should(BeEmpty())
7779
}
7880

81+
By("Testing default/kubernetes EndpointSlices")
82+
out, _, err = kubectl("get", "-o=json", "endpointslices/kubernetes")
83+
Expect(err).NotTo(HaveOccurred())
84+
var eps discoveryv1.EndpointSlice
85+
err = json.Unmarshal(out, &eps)
86+
Expect(err).NotTo(HaveOccurred())
87+
if isDegraded {
88+
Expect(eps.Endpoints).To(ConsistOf(
89+
discoveryv1.Endpoint{
90+
Addresses: []string{node1},
91+
Conditions: discoveryv1.EndpointConditions{Ready: ptr.To(true)},
92+
},
93+
discoveryv1.Endpoint{
94+
Addresses: []string{node2},
95+
Conditions: discoveryv1.EndpointConditions{Ready: ptr.To(false)},
96+
},
97+
discoveryv1.Endpoint{
98+
Addresses: []string{node3},
99+
Conditions: discoveryv1.EndpointConditions{Ready: ptr.To(false)},
100+
},
101+
))
102+
} else {
103+
Expect(eps.Endpoints).To(ConsistOf(
104+
discoveryv1.Endpoint{
105+
Addresses: []string{node1},
106+
Conditions: discoveryv1.EndpointConditions{Ready: ptr.To(true)},
107+
},
108+
discoveryv1.Endpoint{
109+
Addresses: []string{node2},
110+
Conditions: discoveryv1.EndpointConditions{Ready: ptr.To(true)},
111+
},
112+
discoveryv1.Endpoint{
113+
Addresses: []string{node3},
114+
Conditions: discoveryv1.EndpointConditions{Ready: ptr.To(true)},
115+
},
116+
))
117+
}
118+
79119
By("Stopping etcd servers")
80120
// this will run:
81121
// - EtcdStartOp
@@ -129,6 +169,36 @@ func testOperators(isDegraded bool) {
129169
Expect(ep.Subsets[0].NotReadyAddresses).Should(BeEmpty())
130170
}
131171

172+
By("Testing default/kubernetes EndpointSlices")
173+
out, _, err = kubectl("get", "-o=json", "endpointslices/kubernetes")
174+
Expect(err).NotTo(HaveOccurred())
175+
eps = discoveryv1.EndpointSlice{}
176+
err = json.Unmarshal(out, &eps)
177+
Expect(err).NotTo(HaveOccurred())
178+
if isDegraded {
179+
Expect(eps.Endpoints).To(ConsistOf(
180+
discoveryv1.Endpoint{
181+
Addresses: []string{node1},
182+
Conditions: discoveryv1.EndpointConditions{Ready: ptr.To(true)},
183+
},
184+
discoveryv1.Endpoint{
185+
Addresses: []string{node3},
186+
Conditions: discoveryv1.EndpointConditions{Ready: ptr.To(false)},
187+
},
188+
))
189+
} else {
190+
Expect(eps.Endpoints).To(ConsistOf(
191+
discoveryv1.Endpoint{
192+
Addresses: []string{node1},
193+
Conditions: discoveryv1.EndpointConditions{Ready: ptr.To(true)},
194+
},
195+
discoveryv1.Endpoint{
196+
Addresses: []string{node3},
197+
Conditions: discoveryv1.EndpointConditions{Ready: ptr.To(true)},
198+
},
199+
))
200+
}
201+
132202
By("Adding a new node to the cluster as a control plane")
133203
// this will run AddMemberOp as well as other boot/restart ops.
134204

mtest/reboot_test.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
. "github.com/onsi/gomega"
1313
appsv1 "k8s.io/api/apps/v1"
1414
corev1 "k8s.io/api/core/v1"
15+
discoveryv1 "k8s.io/api/discovery/v1"
1516
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1617
"k8s.io/utils/ptr"
1718
)
@@ -581,7 +582,6 @@ func testRebootOperations() {
581582
Expect(apiServerInProgress).Should(BeNumerically("<=", 1), "API servers should be processed one by one")
582583

583584
// Both default/kubernetes and kube-system/cke-etcd Endpoints should have no less than two endpoints during API server reboots.
584-
// (Check for EndpointsSlices is omitted since their members are same as Endpoints)
585585
epNames := []struct {
586586
name string
587587
namespace string
@@ -605,6 +605,23 @@ func testRebootOperations() {
605605
Expect(ep.Subsets).Should(HaveLen(1))
606606
Expect(len(ep.Subsets[0].Addresses)).Should(BeNumerically(">=", 2))
607607
}
608+
for _, epName := range epNames {
609+
out, _, err := kubectl("get", "endpointslices", "-n", epName.namespace, epName.name, "-o=json")
610+
Expect(err).NotTo(HaveOccurred())
611+
612+
var eps discoveryv1.EndpointSlice
613+
err = json.Unmarshal(out, &eps)
614+
Expect(err).NotTo(HaveOccurred())
615+
Expect(eps.Endpoints).To(HaveLen(3))
616+
617+
readyCount := 0
618+
for _, e := range eps.Endpoints {
619+
if *e.Conditions.Ready {
620+
readyCount++
621+
}
622+
}
623+
Expect(readyCount).To(BeNumerically(">=", 2))
624+
}
608625

609626
if apiServerRemain == 0 {
610627
break

server/strategy.go

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package server
22

33
import (
4+
"slices"
45
"time"
56

67
"github.com/cybozu-go/cke"
@@ -14,6 +15,7 @@ import (
1415
corev1 "k8s.io/api/core/v1"
1516
discoveryv1 "k8s.io/api/discovery/v1"
1617
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
18+
"k8s.io/utils/ptr"
1719
)
1820

1921
// DecideOps returns the next operations to do and the operation phase.
@@ -441,6 +443,17 @@ func decideEpEpsOps(expect *endpointParams, actualEP *corev1.Endpoints, actualEP
441443
ops = append(ops, epOp)
442444
}
443445

446+
ready := make(map[string]bool)
447+
for _, ip := range expect.readyIPs {
448+
ready[ip] = true
449+
}
450+
for _, ip := range expect.notReadyIPs {
451+
ready[ip] = false
452+
}
453+
addrs := slices.Concat(expect.readyIPs, expect.notReadyIPs)
454+
slices.Sort(addrs)
455+
addrs = slices.Compact(addrs)
456+
444457
eps := &discoveryv1.EndpointSlice{}
445458
eps.Namespace = expect.namespace
446459
eps.Name = expect.name
@@ -449,23 +462,11 @@ func decideEpEpsOps(expect *endpointParams, actualEP *corev1.Endpoints, actualEP
449462
"kubernetes.io/service-name": expect.serviceName,
450463
}
451464
eps.AddressType = discoveryv1.AddressTypeIPv4
452-
eps.Endpoints = make([]discoveryv1.Endpoint, len(expect.readyIPs)+len(expect.notReadyIPs))
453-
readyTrue := true
454-
for i := range expect.readyIPs {
465+
eps.Endpoints = make([]discoveryv1.Endpoint, len(addrs))
466+
for i, ip := range addrs {
455467
eps.Endpoints[i] = discoveryv1.Endpoint{
456-
Addresses: expect.readyIPs[i : i+1],
457-
Conditions: discoveryv1.EndpointConditions{
458-
Ready: &readyTrue,
459-
},
460-
}
461-
}
462-
readyFalse := false
463-
for i := range expect.notReadyIPs {
464-
eps.Endpoints[len(expect.readyIPs)+i] = discoveryv1.Endpoint{
465-
Addresses: expect.notReadyIPs[i : i+1],
466-
Conditions: discoveryv1.EndpointConditions{
467-
Ready: &readyFalse,
468-
},
468+
Addresses: []string{ip},
469+
Conditions: discoveryv1.EndpointConditions{Ready: ptr.To(ready[ip])},
469470
}
470471
}
471472
eps.Ports = []discoveryv1.EndpointPort{

0 commit comments

Comments
 (0)