Skip to content

Commit 52e1b39

Browse files
lambdaiistio-testing
authored andcommitted
agent: rewrite readiness probe (istio#16336)
* pilot-agent: support filter chain inbound listener Signed-off-by: Yuchen Dai <[email protected]> * apply and add test Signed-off-by: Yuchen Dai <[email protected]> * lint Signed-off-by: Yuchen Dai <[email protected]> * improve test Signed-off-by: Yuchen Dai <[email protected]> * lint again Signed-off-by: Yuchen Dai <[email protected]> * apply and add test Signed-off-by: Yuchen Dai <[email protected]> * Address comment: 1.3 pilot agent assumes virtual inbound listener using filter chains Signed-off-by: Yuchen Dai <[email protected]> * remove env var Signed-off-by: Yuchen Dai <[email protected]> * not check inbound for sidecar proxy Signed-off-by: Yuchen Dai <[email protected]> * retore check virtual inbound Signed-off-by: Yuchen Dai <[email protected]> * check inbound listener only for router type envoy Signed-off-by: Yuchen Dai <[email protected]>
1 parent 37f66ed commit 52e1b39

File tree

4 files changed

+96
-24
lines changed

4 files changed

+96
-24
lines changed

pilot/cmd/pilot-agent/status/ready/probe.go

+11-10
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,20 @@ package ready
1717
import (
1818
"fmt"
1919

20-
"github.com/hashicorp/go-multierror"
21-
22-
"istio.io/istio/pilot/pkg/model"
23-
2420
admin "github.com/envoyproxy/go-control-plane/envoy/admin/v2alpha"
21+
"github.com/hashicorp/go-multierror"
2522

2623
"istio.io/istio/pilot/cmd/pilot-agent/status/util"
24+
"istio.io/istio/pilot/pkg/model"
2725
)
2826

2927
// Probe for readiness.
3028
type Probe struct {
29+
ApplicationPorts []uint16
3130
LocalHostAddr string
31+
NodeType model.NodeType
3232
AdminPort uint16
3333
receivedFirstUpdate bool
34-
ApplicationPorts []uint16
35-
NodeType model.NodeType
3634
}
3735

3836
// Check executes the probe and returns an error if the probe fails.
@@ -42,16 +40,19 @@ func (p *Probe) Check() error {
4240
return err
4341
}
4442

45-
// Envoy has received some configuration, make sure that configuration has been received for
46-
// all inbound ports.
47-
if err := p.checkInboundConfigured(); err != nil {
48-
return err
43+
// Envoy has received some listener configuration, make sure that configuration has been received for
44+
// any of the inbound ports.
45+
if p.NodeType == model.Router {
46+
if err := p.checkInboundConfigured(); err != nil {
47+
return err
48+
}
4949
}
5050

5151
return p.checkServerInfo()
5252
}
5353

5454
// checkApplicationPorts verifies that Envoy has received configuration for all ports exposed by the application container.
55+
// Notes it is used only by envoy in Router mode.
5556
func (p *Probe) checkInboundConfigured() error {
5657
if len(p.ApplicationPorts) > 0 {
5758
listeningPorts, listeners, err := util.GetInboundListeningPorts(p.LocalHostAddr, p.AdminPort, p.NodeType)

pilot/cmd/pilot-agent/status/ready/probe_test.go

+64-10
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,35 @@ import (
2121
"testing"
2222

2323
admin "github.com/envoyproxy/go-control-plane/envoy/admin/v2alpha"
24+
envoyapicore "github.com/envoyproxy/go-control-plane/envoy/api/v2/core"
2425
"github.com/gogo/protobuf/jsonpb"
2526
"github.com/gogo/protobuf/proto"
2627
. "github.com/onsi/gomega"
28+
29+
"istio.io/istio/pilot/pkg/model"
30+
networking "istio.io/istio/pilot/pkg/networking/core/v1alpha3"
2731
)
2832

2933
var (
3034
goodStats = "cluster_manager.cds.update_success: 1\nlistener_manager.lds.update_success: 1"
3135
liveServerInfo = &admin.ServerInfo{State: admin.ServerInfo_LIVE}
3236
initServerInfo = &admin.ServerInfo{State: admin.ServerInfo_INITIALIZING}
37+
listeners = admin.Listeners{
38+
ListenerStatuses: []*admin.ListenerStatus{
39+
{
40+
Name: networking.VirtualInboundListenerName,
41+
LocalAddress: &envoyapicore.Address{
42+
Address: &envoyapicore.Address_SocketAddress{
43+
SocketAddress: &envoyapicore.SocketAddress{
44+
PortSpecifier: &envoyapicore.SocketAddress_PortValue{
45+
PortValue: 15006,
46+
},
47+
},
48+
},
49+
},
50+
},
51+
},
52+
}
3353
)
3454

3555
func TestEnvoyStatsCompleteAndSuccessful(t *testing.T) {
@@ -164,19 +184,53 @@ func TestEnvoyInitializing(t *testing.T) {
164184
g.Expect(err).To(HaveOccurred())
165185
}
166186

167-
func createAndStartServer(statsToReturn string, serverInfo proto.Message) *httptest.Server {
168-
mux := http.NewServeMux()
169-
mux.HandleFunc("/stats", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
170-
// Send response to be tested
171-
rw.Write([]byte(statsToReturn))
172-
}))
173-
mux.HandleFunc("/server_info", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
187+
func TestEnvoyInitializingWithVirtualInboundListener(t *testing.T) {
188+
g := NewGomegaWithT(t)
189+
190+
funcMap := createDefaultFuncMap(goodStats, liveServerInfo)
191+
192+
funcMap["/listeners"] = func(rw http.ResponseWriter, _ *http.Request) {
174193
jsonm := &jsonpb.Marshaler{Indent: " "}
175-
infoJSON, _ := jsonm.MarshalToString(serverInfo)
194+
listenerBytes, _ := jsonm.MarshalToString(&listeners)
176195

177196
// Send response to be tested
178-
rw.Write([]byte(infoJSON))
179-
}))
197+
rw.Write([]byte(listenerBytes))
198+
}
199+
200+
server := createHTTPServer(funcMap)
201+
defer server.Close()
202+
probe := Probe{AdminPort: 1234, receivedFirstUpdate: true, NodeType: model.SidecarProxy}
203+
204+
err := probe.Check()
205+
206+
g.Expect(err).ToNot(HaveOccurred())
207+
}
208+
209+
func createDefaultFuncMap(statsToReturn string, serverInfo proto.Message) map[string]func(rw http.ResponseWriter, _ *http.Request) {
210+
return map[string]func(rw http.ResponseWriter, _ *http.Request){
211+
212+
"/stats": func(rw http.ResponseWriter, _ *http.Request) {
213+
// Send response to be tested
214+
rw.Write([]byte(statsToReturn))
215+
},
216+
"/server_info": func(rw http.ResponseWriter, _ *http.Request) {
217+
jsonm := &jsonpb.Marshaler{Indent: " "}
218+
infoJSON, _ := jsonm.MarshalToString(serverInfo)
219+
220+
// Send response to be tested
221+
rw.Write([]byte(infoJSON))
222+
},
223+
}
224+
}
225+
func createAndStartServer(statsToReturn string, serverInfo proto.Message) *httptest.Server {
226+
return createHTTPServer(createDefaultFuncMap(statsToReturn, serverInfo))
227+
}
228+
229+
func createHTTPServer(handlers map[string]func(rw http.ResponseWriter, _ *http.Request)) *httptest.Server {
230+
mux := http.NewServeMux()
231+
for k, v := range handlers {
232+
mux.HandleFunc(k, http.HandlerFunc(v))
233+
}
180234

181235
// Start a local HTTP server
182236
server := httptest.NewUnstartedServer(mux)

pilot/cmd/pilot-agent/status/server.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,13 @@ type KubeAppProbers map[string]*corev1.HTTPGetAction
6363

6464
// Config for the status server.
6565
type Config struct {
66-
LocalHostAddr string
67-
StatusPort uint16
68-
AdminPort uint16
6966
ApplicationPorts []uint16
67+
LocalHostAddr string
7068
// KubeAppHTTPProbers is a json with Kubernetes application HTTP prober config encoded.
7169
KubeAppHTTPProbers string
7270
NodeType model.NodeType
71+
StatusPort uint16
72+
AdminPort uint16
7373
}
7474

7575
// Server provides an endpoint for handling status probes.

pilot/cmd/pilot-agent/status/util/listeners.go

+18-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import (
2121

2222
admin "github.com/envoyproxy/go-control-plane/envoy/admin/v2alpha"
2323
"github.com/gogo/protobuf/jsonpb"
24-
multierror "github.com/hashicorp/go-multierror"
24+
"github.com/hashicorp/go-multierror"
2525

2626
"istio.io/istio/pilot/pkg/model"
2727
)
@@ -69,6 +69,23 @@ func GetInboundListeningPorts(localHostAddr string, adminPort uint16, nodeType m
6969
return ports, buf.String(), nil
7070
}
7171

72+
func HasListenerName(localHostAddr string, adminPort uint16, name string) error {
73+
buf, err := doHTTPGet(fmt.Sprintf("http://%s:%d/listeners?format=json", localHostAddr, adminPort))
74+
if err != nil {
75+
return multierror.Prefix(err, "failed retrieving Envoy listeners:")
76+
}
77+
listeners := &admin.Listeners{}
78+
if err := jsonpb.Unmarshal(buf, listeners); err != nil {
79+
return fmt.Errorf("failed parsing Envoy listeners %s: %s", buf, err)
80+
}
81+
for _, l := range listeners.ListenerStatuses {
82+
if l.Name == name {
83+
return nil
84+
}
85+
}
86+
return fmt.Errorf("no such listener name %s", name)
87+
}
88+
7289
func isLocalListener(l string) bool {
7390
for _, ipPrefix := range ipPrefixes {
7491
// In case of IPv6 address, it always comes in "[]", remove them so HasPrefix would work

0 commit comments

Comments
 (0)