Skip to content

Commit 9b53b93

Browse files
authored
Merge pull request kubernetes#92134 from mm4tt/network_revert
Revert "fix(e2e): access nodes via test container in LB network tests"
2 parents 7ac6b15 + af00593 commit 9b53b93

File tree

4 files changed

+57
-145
lines changed

4 files changed

+57
-145
lines changed

test/e2e/framework/network/utils.go

Lines changed: 29 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -160,12 +160,6 @@ type NetworkingTestConfig struct {
160160
Namespace string
161161
}
162162

163-
// NetexecDialResponse represents the response returned by the `netexec` subcommand of `agnhost`
164-
type NetexecDialResponse struct {
165-
Responses []string `json:"responses"`
166-
Errors []string `json:"errors"`
167-
}
168-
169163
// DialFromEndpointContainer executes a curl via kubectl exec in an endpoint container.
170164
func (config *NetworkingTestConfig) DialFromEndpointContainer(protocol, targetIP string, targetPort, maxTries, minTries int, expectedEps sets.String) {
171165
config.DialFromContainer(protocol, echoHostname, config.EndpointPods[0].Status.PodIP, targetIP, EndpointHTTPPort, targetPort, maxTries, minTries, expectedEps)
@@ -218,18 +212,6 @@ func (config *NetworkingTestConfig) EndpointHostnames() sets.String {
218212
return expectedEps
219213
}
220214

221-
func makeCURLDialCommand(ipPort, dialCmd, protocol, targetIP string, targetPort int) string {
222-
// The current versions of curl included in CentOS and RHEL distros
223-
// misinterpret square brackets around IPv6 as globbing, so use the -g
224-
// argument to disable globbing to handle the IPv6 case.
225-
return fmt.Sprintf("curl -g -q -s 'http://%s/dial?request=%s&protocol=%s&host=%s&port=%d&tries=1'",
226-
ipPort,
227-
dialCmd,
228-
protocol,
229-
targetIP,
230-
targetPort)
231-
}
232-
233215
// DialFromContainer executes a curl via kubectl exec in a test container,
234216
// which might then translate to a tcp or udp request based on the protocol
235217
// argument in the url.
@@ -250,19 +232,38 @@ func makeCURLDialCommand(ipPort, dialCmd, protocol, targetIP string, targetPort
250232
// pod and confirm it doesn't show up as an endpoint.
251233
func (config *NetworkingTestConfig) DialFromContainer(protocol, dialCommand, containerIP, targetIP string, containerHTTPPort, targetPort, maxTries, minTries int, expectedResponses sets.String) {
252234
ipPort := net.JoinHostPort(containerIP, strconv.Itoa(containerHTTPPort))
253-
cmd := makeCURLDialCommand(ipPort, dialCommand, protocol, targetIP, targetPort)
235+
// The current versions of curl included in CentOS and RHEL distros
236+
// misinterpret square brackets around IPv6 as globbing, so use the -g
237+
// argument to disable globbing to handle the IPv6 case.
238+
cmd := fmt.Sprintf("curl -g -q -s 'http://%s/dial?request=%s&protocol=%s&host=%s&port=%d&tries=1'",
239+
ipPort,
240+
dialCommand,
241+
protocol,
242+
targetIP,
243+
targetPort)
254244

255245
responses := sets.NewString()
256246

257247
for i := 0; i < maxTries; i++ {
258-
resp, err := config.GetResponseFromContainer(protocol, dialCommand, containerIP, targetIP, containerHTTPPort, targetPort)
248+
stdout, stderr, err := config.f.ExecShellInPodWithFullOutput(config.TestContainerPod.Name, cmd)
259249
if err != nil {
260-
continue
261-
}
262-
for _, response := range resp.Responses {
263-
trimmed := strings.TrimSpace(response)
264-
if trimmed != "" {
265-
responses.Insert(trimmed)
250+
// A failure to kubectl exec counts as a try, not a hard fail.
251+
// Also note that we will keep failing for maxTries in tests where
252+
// we confirm unreachability.
253+
framework.Logf("Failed to execute %q: %v, stdout: %q, stderr %q", cmd, err, stdout, stderr)
254+
} else {
255+
var output map[string][]string
256+
if err := json.Unmarshal([]byte(stdout), &output); err != nil {
257+
framework.Logf("WARNING: Failed to unmarshal curl response. Cmd %v run in %v, output: %s, err: %v",
258+
cmd, config.HostTestContainerPod.Name, stdout, err)
259+
continue
260+
}
261+
262+
for _, response := range output["responses"] {
263+
trimmed := strings.TrimSpace(response)
264+
if trimmed != "" {
265+
responses.Insert(trimmed)
266+
}
266267
}
267268
}
268269
framework.Logf("Waiting for responses: %v", expectedResponses.Difference(responses))
@@ -313,14 +314,14 @@ func (config *NetworkingTestConfig) GetEndpointsFromContainer(protocol, containe
313314
framework.Logf("Failed to execute %q: %v, stdout: %q, stderr: %q", cmd, err, stdout, stderr)
314315
} else {
315316
framework.Logf("Tries: %d, in try: %d, stdout: %v, stderr: %v, command run in: %#v", tries, i, stdout, stderr, config.HostTestContainerPod)
316-
var output NetexecDialResponse
317+
var output map[string][]string
317318
if err := json.Unmarshal([]byte(stdout), &output); err != nil {
318319
framework.Logf("WARNING: Failed to unmarshal curl response. Cmd %v run in %v, output: %s, err: %v",
319320
cmd, config.HostTestContainerPod.Name, stdout, err)
320321
continue
321322
}
322323

323-
for _, hostName := range output.Responses {
324+
for _, hostName := range output["responses"] {
324325
trimmed := strings.TrimSpace(hostName)
325326
if trimmed != "" {
326327
eps.Insert(trimmed)
@@ -333,34 +334,6 @@ func (config *NetworkingTestConfig) GetEndpointsFromContainer(protocol, containe
333334
return eps, nil
334335
}
335336

336-
// GetResponseFromContainer executes a curl via kubectl exec in a container.
337-
func (config *NetworkingTestConfig) GetResponseFromContainer(protocol, dialCommand, containerIP, targetIP string, containerHTTPPort, targetPort int) (NetexecDialResponse, error) {
338-
ipPort := net.JoinHostPort(containerIP, strconv.Itoa(containerHTTPPort))
339-
cmd := makeCURLDialCommand(ipPort, dialCommand, protocol, targetIP, targetPort)
340-
341-
stdout, stderr, err := config.f.ExecShellInPodWithFullOutput(config.TestContainerPod.Name, cmd)
342-
if err != nil {
343-
// A failure to kubectl exec counts as a try, not a hard fail.
344-
// Also note that we will keep failing for maxTries in tests where
345-
// we confirm unreachability.
346-
framework.Logf("Failed to execute %q: %v, stdout: %q, stderr: %q", cmd, err, stdout, stderr)
347-
return NetexecDialResponse{}, err
348-
}
349-
350-
var output NetexecDialResponse
351-
if err := json.Unmarshal([]byte(stdout), &output); err != nil {
352-
framework.Logf("WARNING: Failed to unmarshal curl response. Cmd %v run in %v, output: %s, err: %v",
353-
cmd, config.HostTestContainerPod.Name, stdout, err)
354-
return NetexecDialResponse{}, err
355-
}
356-
return output, nil
357-
}
358-
359-
// GetResponseFromTestContainer executes a curl via kubectl exec in a test container.
360-
func (config *NetworkingTestConfig) GetResponseFromTestContainer(protocol, dialCommand, targetIP string, targetPort int) (NetexecDialResponse, error) {
361-
return config.GetResponseFromContainer(protocol, dialCommand, config.TestContainerPod.Status.PodIP, targetIP, testContainerHTTPPort, targetPort)
362-
}
363-
364337
// DialFromNode executes a tcp or udp request based on protocol via kubectl exec
365338
// in a test container running with host networking.
366339
// - minTries is the minimum number of curl attempts required before declaring

test/e2e/framework/service/jig.go

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -260,36 +260,21 @@ func (j *TestJig) CreateLoadBalancerService(timeout time.Duration, tweak func(sv
260260
// GetEndpointNodes returns a map of nodenames:external-ip on which the
261261
// endpoints of the Service are running.
262262
func (j *TestJig) GetEndpointNodes() (map[string][]string, error) {
263-
nodes, err := j.ListNodesWithEndpoint()
263+
nodes, err := e2enode.GetBoundedReadySchedulableNodes(j.Client, MaxNodesForEndpointsTests)
264264
if err != nil {
265265
return nil, err
266266
}
267-
nodeMap := map[string][]string{}
268-
for _, node := range nodes {
269-
nodeMap[node.Name] = e2enode.GetAddresses(&node, v1.NodeExternalIP)
270-
}
271-
return nodeMap, nil
272-
}
273-
274-
// ListNodesWithEndpoint returns a list of nodes on which the
275-
// endpoints of the given Service are running.
276-
func (j *TestJig) ListNodesWithEndpoint() ([]v1.Node, error) {
277-
nodeNames, err := j.GetEndpointNodeNames()
267+
epNodes, err := j.GetEndpointNodeNames()
278268
if err != nil {
279269
return nil, err
280270
}
281-
ctx := context.TODO()
282-
allNodes, err := j.Client.CoreV1().Nodes().List(ctx, metav1.ListOptions{})
283-
if err != nil {
284-
return nil, err
285-
}
286-
epNodes := make([]v1.Node, 0, nodeNames.Len())
287-
for _, node := range allNodes.Items {
288-
if nodeNames.Has(node.Name) {
289-
epNodes = append(epNodes, node)
271+
nodeMap := map[string][]string{}
272+
for _, n := range nodes.Items {
273+
if epNodes.Has(n.Name) {
274+
nodeMap[n.Name] = e2enode.GetAddresses(&n, v1.NodeExternalIP)
290275
}
291276
}
292-
return epNodes, nil
277+
return nodeMap, nil
293278
}
294279

295280
// GetEndpointNodeNames returns a string set of node names on which the

test/e2e/network/service.go

Lines changed: 21 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
package network
1818

1919
import (
20+
"bytes"
2021
"context"
2122
"encoding/json"
2223
"errors"
@@ -3282,72 +3283,42 @@ var _ = SIGDescribe("ESIPP [Slow]", func() {
32823283
framework.Failf("Service HealthCheck NodePort still present")
32833284
}
32843285

3285-
epNodes, err := jig.ListNodesWithEndpoint()
3286+
endpointNodeMap, err := jig.GetEndpointNodes()
32863287
framework.ExpectNoError(err)
3287-
// map from name of nodes with endpoint to internal ip
3288-
// it is assumed that there is only a single node with the endpoint
3289-
endpointNodeMap := make(map[string]string)
3290-
// map from name of nodes without endpoint to internal ip
3291-
noEndpointNodeMap := make(map[string]string)
3292-
for _, node := range epNodes {
3293-
ips := e2enode.GetAddresses(&node, v1.NodeInternalIP)
3294-
if len(ips) < 1 {
3295-
framework.Failf("No internal ip found for node %s", node.Name)
3296-
}
3297-
endpointNodeMap[node.Name] = ips[0]
3298-
}
3288+
noEndpointNodeMap := map[string][]string{}
32993289
for _, n := range nodes.Items {
3300-
ips := e2enode.GetAddresses(&n, v1.NodeInternalIP)
3301-
if len(ips) < 1 {
3302-
framework.Failf("No internal ip found for node %s", n.Name)
3303-
}
3304-
if _, ok := endpointNodeMap[n.Name]; !ok {
3305-
noEndpointNodeMap[n.Name] = ips[0]
3290+
if _, ok := endpointNodeMap[n.Name]; ok {
3291+
continue
33063292
}
3293+
noEndpointNodeMap[n.Name] = e2enode.GetAddresses(&n, v1.NodeExternalIP)
33073294
}
3308-
framework.ExpectNotEqual(len(endpointNodeMap), 0)
3309-
framework.ExpectNotEqual(len(noEndpointNodeMap), 0)
33103295

33113296
svcTCPPort := int(svc.Spec.Ports[0].Port)
33123297
svcNodePort := int(svc.Spec.Ports[0].NodePort)
33133298
ingressIP := e2eservice.GetIngressPoint(&svc.Status.LoadBalancer.Ingress[0])
33143299
path := "/clientip"
3315-
dialCmd := "clientip"
3316-
3317-
config := e2enetwork.NewNetworkingTestConfig(f, false, false)
33183300

33193301
ginkgo.By(fmt.Sprintf("endpoints present on nodes %v, absent on nodes %v", endpointNodeMap, noEndpointNodeMap))
3320-
for nodeName, nodeIP := range noEndpointNodeMap {
3321-
ginkgo.By(fmt.Sprintf("Checking %v (%v:%v/%v) proxies to endpoints on another node", nodeName, nodeIP[0], svcNodePort, dialCmd))
3322-
_, err := GetHTTPContentFromTestContainer(config, nodeIP, svcNodePort, e2eservice.KubeProxyLagTimeout, dialCmd)
3323-
framework.ExpectNoError(err, "Could not reach HTTP service through %v:%v/%v after %v", nodeIP, svcNodePort, dialCmd, e2eservice.KubeProxyLagTimeout)
3324-
}
3325-
3326-
for nodeName, nodeIP := range endpointNodeMap {
3327-
ginkgo.By(fmt.Sprintf("checking kube-proxy health check fails on node with endpoint (%s), public IP %s", nodeName, nodeIP))
3328-
var body string
3329-
pollFn := func() (bool, error) {
3330-
// we expect connection failure here, but not other errors
3331-
3332-
resp, err := config.GetResponseFromTestContainer(
3333-
"http",
3334-
"healthz",
3335-
nodeIP,
3336-
healthCheckNodePort)
3337-
if err != nil {
3338-
return false, nil
3339-
}
3340-
if len(resp.Errors) > 0 {
3302+
for nodeName, nodeIPs := range noEndpointNodeMap {
3303+
ginkgo.By(fmt.Sprintf("Checking %v (%v:%v%v) proxies to endpoints on another node", nodeName, nodeIPs[0], svcNodePort, path))
3304+
GetHTTPContent(nodeIPs[0], svcNodePort, e2eservice.KubeProxyLagTimeout, path)
3305+
}
3306+
3307+
for nodeName, nodeIPs := range endpointNodeMap {
3308+
ginkgo.By(fmt.Sprintf("checking kube-proxy health check fails on node with endpoint (%s), public IP %s", nodeName, nodeIPs[0]))
3309+
var body bytes.Buffer
3310+
pollfn := func() (bool, error) {
3311+
result := e2enetwork.PokeHTTP(nodeIPs[0], healthCheckNodePort, "/healthz", nil)
3312+
if result.Code == 0 {
33413313
return true, nil
33423314
}
3343-
if len(resp.Responses) > 0 {
3344-
body = resp.Responses[0]
3345-
}
3315+
body.Reset()
3316+
body.Write(result.Body)
33463317
return false, nil
33473318
}
3348-
if pollErr := wait.PollImmediate(framework.Poll, e2eservice.TestTimeout, pollFn); pollErr != nil {
3319+
if pollErr := wait.PollImmediate(framework.Poll, e2eservice.TestTimeout, pollfn); pollErr != nil {
33493320
framework.Failf("Kube-proxy still exposing health check on node %v:%v, after ESIPP was turned off. body %s",
3350-
nodeName, healthCheckNodePort, body)
3321+
nodeName, healthCheckNodePort, body.String())
33513322
}
33523323
}
33533324

test/e2e/network/util.go

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -53,23 +53,6 @@ func GetHTTPContent(host string, port int, timeout time.Duration, url string) by
5353
return body
5454
}
5555

56-
// GetHTTPContentFromTestContainer returns the content of the given url by HTTP via a test container.
57-
func GetHTTPContentFromTestContainer(config *e2enetwork.NetworkingTestConfig, host string, port int, timeout time.Duration, dialCmd string) (string, error) {
58-
var body string
59-
pollFn := func() (bool, error) {
60-
resp, err := config.GetResponseFromTestContainer("http", dialCmd, host, port)
61-
if err != nil || len(resp.Errors) > 0 || len(resp.Responses) == 0 {
62-
return false, nil
63-
}
64-
body = resp.Responses[0]
65-
return true, nil
66-
}
67-
if pollErr := wait.PollImmediate(framework.Poll, timeout, pollFn); pollErr != nil {
68-
return "", pollErr
69-
}
70-
return body, nil
71-
}
72-
7356
// DescribeSvc logs the output of kubectl describe svc for the given namespace
7457
func DescribeSvc(ns string) {
7558
framework.Logf("\nOutput of kubectl describe svc:\n")

0 commit comments

Comments
 (0)