mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-03 01:06:27 +00:00
Match service ports when proxying to services
This commit is contained in:
parent
32c240b350
commit
9da769f90d
@ -284,6 +284,26 @@ func (rs *REST) ResourceLocation(ctx api.Context, id string) (*url.URL, http.Rou
|
|||||||
return nil, nil, errors.NewBadRequest(fmt.Sprintf("invalid service request %q", id))
|
return nil, nil, errors.NewBadRequest(fmt.Sprintf("invalid service request %q", id))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If a port *number* was specified, find the corresponding service port name
|
||||||
|
if portNum, err := strconv.ParseInt(portStr, 10, 64); err == nil {
|
||||||
|
svc, err := rs.registry.GetService(ctx, svcName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
found := false
|
||||||
|
for _, svcPort := range svc.Spec.Ports {
|
||||||
|
if svcPort.Port == int(portNum) {
|
||||||
|
// use the declared port's name
|
||||||
|
portStr = svcPort.Name
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
return nil, nil, errors.NewServiceUnavailable(fmt.Sprintf("no service port %d found for service %q", portNum, svcName))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
eps, err := rs.endpoints.GetEndpoints(ctx, svcName)
|
eps, err := rs.endpoints.GetEndpoints(ctx, svcName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
@ -308,15 +328,6 @@ func (rs *REST) ResourceLocation(ctx api.Context, id string) (*url.URL, http.Rou
|
|||||||
Scheme: svcScheme,
|
Scheme: svcScheme,
|
||||||
Host: net.JoinHostPort(ip, strconv.Itoa(port)),
|
Host: net.JoinHostPort(ip, strconv.Itoa(port)),
|
||||||
}, rs.proxyTransport, nil
|
}, rs.proxyTransport, nil
|
||||||
} else {
|
|
||||||
port, err := strconv.ParseInt(portStr, 10, 64)
|
|
||||||
if err == nil && int(port) == ss.Ports[i].Port {
|
|
||||||
ip := ss.Addresses[rand.Intn(len(ss.Addresses))].IP
|
|
||||||
return &url.URL{
|
|
||||||
Scheme: svcScheme,
|
|
||||||
Host: net.JoinHostPort(ip, portStr),
|
|
||||||
}, rs.proxyTransport, nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -462,6 +462,14 @@ func TestServiceRegistryResourceLocation(t *testing.T) {
|
|||||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||||
Spec: api.ServiceSpec{
|
Spec: api.ServiceSpec{
|
||||||
Selector: map[string]string{"bar": "baz"},
|
Selector: map[string]string{"bar": "baz"},
|
||||||
|
Ports: []api.ServicePort{
|
||||||
|
// Service port 9393 should route to endpoint port "p", which is port 93
|
||||||
|
{Name: "p", Port: 9393, TargetPort: intstr.FromString("p")},
|
||||||
|
|
||||||
|
// Service port 93 should route to unnamed endpoint port, which is port 80
|
||||||
|
// This is to test that the service port definition is used when determining resource location
|
||||||
|
{Name: "", Port: 93, TargetPort: intstr.FromInt(80)},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
redirector := rest.Redirector(storage)
|
redirector := rest.Redirector(storage)
|
||||||
@ -490,7 +498,7 @@ func TestServiceRegistryResourceLocation(t *testing.T) {
|
|||||||
t.Errorf("Expected %v, but got %v", e, a)
|
t.Errorf("Expected %v, but got %v", e, a)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test a name + port number.
|
// Test a name + port number (service port 93 -> target port 80)
|
||||||
location, _, err = redirector.ResourceLocation(ctx, "foo:93")
|
location, _, err = redirector.ResourceLocation(ctx, "foo:93")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unexpected error: %v", err)
|
t.Errorf("Unexpected error: %v", err)
|
||||||
@ -498,6 +506,18 @@ func TestServiceRegistryResourceLocation(t *testing.T) {
|
|||||||
if location == nil {
|
if location == nil {
|
||||||
t.Errorf("Unexpected nil: %v", location)
|
t.Errorf("Unexpected nil: %v", location)
|
||||||
}
|
}
|
||||||
|
if e, a := "//1.2.3.4:80", location.String(); e != a {
|
||||||
|
t.Errorf("Expected %v, but got %v", e, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test a name + port number (service port 9393 -> target port "p" -> endpoint port 93)
|
||||||
|
location, _, err = redirector.ResourceLocation(ctx, "foo:9393")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
if location == nil {
|
||||||
|
t.Errorf("Unexpected nil: %v", location)
|
||||||
|
}
|
||||||
if e, a := "//1.2.3.4:93", location.String(); e != a {
|
if e, a := "//1.2.3.4:93", location.String(); e != a {
|
||||||
t.Errorf("Expected %v, but got %v", e, a)
|
t.Errorf("Expected %v, but got %v", e, a)
|
||||||
}
|
}
|
||||||
|
@ -145,13 +145,19 @@ func proxyContext(version string) {
|
|||||||
}
|
}
|
||||||
expectations := map[string]string{
|
expectations := map[string]string{
|
||||||
svcProxyURL("", "portname1") + "/": "foo",
|
svcProxyURL("", "portname1") + "/": "foo",
|
||||||
|
svcProxyURL("", "80") + "/": "foo",
|
||||||
svcProxyURL("", "portname2") + "/": "bar",
|
svcProxyURL("", "portname2") + "/": "bar",
|
||||||
|
svcProxyURL("", "81") + "/": "bar",
|
||||||
|
|
||||||
svcProxyURL("http", "portname1") + "/": "foo",
|
svcProxyURL("http", "portname1") + "/": "foo",
|
||||||
|
svcProxyURL("http", "80") + "/": "foo",
|
||||||
svcProxyURL("http", "portname2") + "/": "bar",
|
svcProxyURL("http", "portname2") + "/": "bar",
|
||||||
|
svcProxyURL("http", "81") + "/": "bar",
|
||||||
|
|
||||||
svcProxyURL("https", "tlsportname1") + "/": "tls baz",
|
svcProxyURL("https", "tlsportname1") + "/": "tls baz",
|
||||||
|
svcProxyURL("https", "443") + "/": "tls baz",
|
||||||
svcProxyURL("https", "tlsportname2") + "/": "tls qux",
|
svcProxyURL("https", "tlsportname2") + "/": "tls qux",
|
||||||
|
svcProxyURL("https", "444") + "/": "tls qux",
|
||||||
|
|
||||||
podProxyURL("", "80") + "/": `<a href="` + podProxyURL("", "80") + `/rewriteme">test</a>`,
|
podProxyURL("", "80") + "/": `<a href="` + podProxyURL("", "80") + `/rewriteme">test</a>`,
|
||||||
podProxyURL("", "160") + "/": "foo",
|
podProxyURL("", "160") + "/": "foo",
|
||||||
@ -172,9 +178,8 @@ func proxyContext(version string) {
|
|||||||
subresourcePodProxyURL("https", "443") + "/": `<a href="` + subresourcePodProxyURL("https", "443") + `/tlsrewriteme">test</a>`,
|
subresourcePodProxyURL("https", "443") + "/": `<a href="` + subresourcePodProxyURL("https", "443") + `/tlsrewriteme">test</a>`,
|
||||||
subresourcePodProxyURL("https", "460") + "/": "tls baz",
|
subresourcePodProxyURL("https", "460") + "/": "tls baz",
|
||||||
subresourcePodProxyURL("https", "462") + "/": "tls qux",
|
subresourcePodProxyURL("https", "462") + "/": "tls qux",
|
||||||
|
|
||||||
// TODO: below entries don't work, but I believe we should make them work.
|
// TODO: below entries don't work, but I believe we should make them work.
|
||||||
// svcPrefix + ":80": "foo",
|
|
||||||
// svcPrefix + ":81": "bar",
|
|
||||||
// podPrefix + ":dest1": "foo",
|
// podPrefix + ":dest1": "foo",
|
||||||
// podPrefix + ":dest2": "bar",
|
// podPrefix + ":dest2": "bar",
|
||||||
}
|
}
|
||||||
@ -231,6 +236,8 @@ func doProxy(f *Framework, path string) (body []byte, statusCode int, d time.Dur
|
|||||||
d = time.Since(start)
|
d = time.Since(start)
|
||||||
if len(body) > 0 {
|
if len(body) > 0 {
|
||||||
Logf("%v: %s (%v; %v)", path, truncate(body, maxDisplayBodyLen), statusCode, d)
|
Logf("%v: %s (%v; %v)", path, truncate(body, maxDisplayBodyLen), statusCode, d)
|
||||||
|
} else {
|
||||||
|
Logf("%v: %s (%v; %v)", path, "no body", statusCode, d)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user