Skip to content
This repository has been archived by the owner on Jul 11, 2023. It is now read-only.

Commit

Permalink
envoy/permissive-mode: use cluster service discovery and routing (#1450)
Browse files Browse the repository at this point in the history
When operating in permissive traffic policy mode, OSM relies on native
kubernetes networking to route traffic to services. Since Kubernetes
is already aware of how to discover and route traffic to services,
rely on this instead of the control plane to explicitly program and
discover endpoints. This change makes the controller logic simpler for
permissive mode and is an optimization over the current implementation.

Resolves #1403
  • Loading branch information
shashankram authored Aug 7, 2020
1 parent ca000a3 commit 15f41bc
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 29 deletions.
27 changes: 19 additions & 8 deletions pkg/envoy/cds/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/golang/protobuf/ptypes/wrappers"

"github.com/openservicemesh/osm/pkg/catalog"
"github.com/openservicemesh/osm/pkg/configurator"
"github.com/openservicemesh/osm/pkg/constants"
"github.com/openservicemesh/osm/pkg/envoy"
"github.com/openservicemesh/osm/pkg/service"
Expand All @@ -23,27 +24,37 @@ const (
)

// getRemoteServiceCluster returns an Envoy Cluster corresponding to the remote service
func getRemoteServiceCluster(remoteService, localService service.MeshService) (*xds_cluster.Cluster, error) {
func getRemoteServiceCluster(remoteService, localService service.MeshService, cfg configurator.Configurator) (*xds_cluster.Cluster, error) {
clusterName := remoteService.String()
marshalledUpstreamTLSContext, err := envoy.MessageToAny(
envoy.GetUpstreamTLSContext(localService, remoteService.GetCommonName().String()))
if err != nil {
return nil, err
}

return &xds_cluster.Cluster{
Name: clusterName,
ConnectTimeout: ptypes.DurationProto(clusterConnectTimeout),
LbPolicy: xds_cluster.Cluster_ROUND_ROBIN,
ClusterDiscoveryType: &xds_cluster.Cluster_Type{Type: xds_cluster.Cluster_EDS},
EdsClusterConfig: &xds_cluster.Cluster_EdsClusterConfig{EdsConfig: envoy.GetADSConfigSource()},
remoteCluster := &xds_cluster.Cluster{
Name: clusterName,
ConnectTimeout: ptypes.DurationProto(clusterConnectTimeout),
TransportSocket: &xds_core.TransportSocket{
Name: wellknown.TransportSocketTls,
ConfigType: &xds_core.TransportSocket_TypedConfig{
TypedConfig: marshalledUpstreamTLSContext,
},
},
}, nil
}

if cfg.IsPermissiveTrafficPolicyMode() {
// Since no traffic policies exist with permissive mode, rely on cluster provided service discovery.
remoteCluster.ClusterDiscoveryType = &xds_cluster.Cluster_Type{Type: xds_cluster.Cluster_ORIGINAL_DST}
remoteCluster.LbPolicy = xds_cluster.Cluster_CLUSTER_PROVIDED
} else {
// Configure service discovery based on traffic policies
remoteCluster.ClusterDiscoveryType = &xds_cluster.Cluster_Type{Type: xds_cluster.Cluster_EDS}
remoteCluster.EdsClusterConfig = &xds_cluster.Cluster_EdsClusterConfig{EdsConfig: envoy.GetADSConfigSource()}
remoteCluster.LbPolicy = xds_cluster.Cluster_ROUND_ROBIN
}

return remoteCluster, nil
}

// getOutboundPassthroughCluster returns an Envoy cluster that is used for outbound passthrough traffic
Expand Down
44 changes: 44 additions & 0 deletions pkg/envoy/cds/cluster_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package cds

import (
xds_cluster "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"

"github.com/openservicemesh/osm/pkg/configurator"
"github.com/openservicemesh/osm/pkg/tests"
)

var _ = Describe("Cluster configurations", func() {

localService := tests.BookbuyerService
remoteService := tests.BookstoreService
Context("Test getRemoteServiceCluster", func() {
It("Returns an EDS based cluster when permissive mode is disabled", func() {
cfg := configurator.NewFakeConfiguratorWithOptions(
configurator.FakeConfigurator{
PermissiveTrafficPolicyMode: false,
},
)

remoteCluster, err := getRemoteServiceCluster(remoteService, localService, cfg)
Expect(err).ToNot(HaveOccurred())
Expect(remoteCluster.GetType()).To(Equal(xds_cluster.Cluster_EDS))
Expect(remoteCluster.LbPolicy).To(Equal(xds_cluster.Cluster_ROUND_ROBIN))
})

It("Returns an Original Destination based cluster when permissive mode is enabled", func() {
cfg := configurator.NewFakeConfiguratorWithOptions(
configurator.FakeConfigurator{
PermissiveTrafficPolicyMode: true,
},
)

remoteCluster, err := getRemoteServiceCluster(remoteService, localService, cfg)
Expect(err).ToNot(HaveOccurred())
Expect(remoteCluster.GetType()).To(Equal(xds_cluster.Cluster_ORIGINAL_DST))
Expect(remoteCluster.LbPolicy).To(Equal(xds_cluster.Cluster_CLUSTER_PROVIDED))
})
})
})
2 changes: 1 addition & 1 deletion pkg/envoy/cds/response.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func NewResponse(_ context.Context, catalog catalog.MeshCataloger, proxy *envoy.
continue
}

remoteCluster, err := getRemoteServiceCluster(dstService, proxyServiceName)
remoteCluster, err := getRemoteServiceCluster(dstService, proxyServiceName, cfg)
if err != nil {
log.Error().Err(err).Msgf("Failed to construct service cluster for proxy %s", proxyServiceName)
return nil, err
Expand Down
2 changes: 1 addition & 1 deletion pkg/envoy/cds/response_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ var _ = Describe("CDS Response", func() {
It("Returns a remote cluster object", func() {
localService := tests.BookbuyerService
remoteService := tests.BookstoreService
remoteCluster, err := getRemoteServiceCluster(remoteService, localService)
remoteCluster, err := getRemoteServiceCluster(remoteService, localService, cfg)
Expect(err).ToNot(HaveOccurred())

expectedClusterLoadAssignment := &xds_endpoint.ClusterLoadAssignment{
Expand Down
23 changes: 7 additions & 16 deletions pkg/envoy/lds/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ func newOutboundListener(cfg configurator.Configurator) (*xds_listener.Listener,
},
},
},
ListenerFilters: []*xds_listener.ListenerFilter{
{
// The OriginalDestination ListenerFilter is used to redirect traffic
// to its original destination.
Name: wellknown.OriginalDestination,
},
},
}

if cfg.IsEgressEnabled() {
Expand Down Expand Up @@ -95,8 +102,6 @@ func updateOutboundListenerForEgress(outboundListener *xds_listener.Listener, cf
return err
}
outboundListener.FilterChains = append(outboundListener.FilterChains, egressFilterChain)
listenerFilters := buildEgressListenerFilters()
outboundListener.ListenerFilters = append(outboundListener.ListenerFilters, listenerFilters...)

return nil
}
Expand Down Expand Up @@ -163,20 +168,6 @@ func buildEgressFilterChain() (*xds_listener.FilterChain, error) {
}, nil
}

func buildEgressListenerFilters() []*xds_listener.ListenerFilter {
return []*xds_listener.ListenerFilter{
{
// The OriginalDestination ListenerFilter is used to redirect traffic
// to its original destination.
Name: wellknown.OriginalDestination,
},
{
// The TlsInspector ListenerFilter is used to examine the transport protocol
Name: wellknown.TlsInspector,
},
}
}

func parseCIDR(cidr string) (string, uint32, error) {
var addr string

Expand Down
10 changes: 7 additions & 3 deletions pkg/envoy/lds/listener_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ var _ = Describe("Construct inbound and outbound listeners", func() {
Expect(listener.FilterChains[1].FilterChainMatch).Should(BeNil())

// Test ListenerFilters
expectedListenerFilters := []string{wellknown.OriginalDestination, wellknown.TlsInspector}
expectedListenerFilters := []string{wellknown.OriginalDestination}
Expect(len(listener.ListenerFilters)).To(Equal(len(expectedListenerFilters)))
for _, filter := range listener.ListenerFilters {
Expect(containsListenerFilter(expectedListenerFilters, filter.Name)).To(BeTrue())
Expand All @@ -70,8 +70,12 @@ var _ = Describe("Construct inbound and outbound listeners", func() {
Expect(len(listener.FilterChains)).To(Equal(1)) // Filter chain for in-mesh
Expect(listener.FilterChains[0].FilterChainMatch).Should(BeNil())

// Test that the ListenerFilters for egress don't exist
Expect(len(listener.ListenerFilters)).To(Equal(0))
// Test ListenerFilters
expectedListenerFilters := []string{wellknown.OriginalDestination}
Expect(len(listener.ListenerFilters)).To(Equal(len(expectedListenerFilters)))
for _, filter := range listener.ListenerFilters {
Expect(containsListenerFilter(expectedListenerFilters, filter.Name)).To(BeTrue())
}
Expect(listener.TrafficDirection).To(Equal(xds_core.TrafficDirection_OUTBOUND))
})
})
Expand Down

0 comments on commit 15f41bc

Please sign in to comment.