diff --git a/mcp/Readme.md b/mcp/Readme.md index 68e04044171..d8b6db6fa12 100644 --- a/mcp/Readme.md +++ b/mcp/Readme.md @@ -1,13 +1,151 @@ -# Mesh Configuration Protocol Protos - -This folder contains the proto buffers used by the Mesh Configuration Protocol, -an [XDS](https://github.com/envoyproxy/data-plane-api/blob/master/XDS_PROTOCOL.md#streaming-grpc-subscriptions) -inspired protocol for transferring configuration among Istio components -during runtime. - -The protocol buffers in this folder are not used for configuring Istio. -Instead, they define an internal protocol through which the configuration proto -instances can be delivered to components, such as Mixer and Pilot. - -The server side of the protocol is implemented in Galley, Istio's config -aggregation and distribution component. +# Mesh Configuration Protocol (MCP) + +## Introduction + +This folder contains the proto buffers for the Mesh Configuration +Protocol (MCP). MCP is based on +[XDS](https://github.com/envoyproxy/data-plane-api/blob/master/XDS_PROTOCOL.md#streaming-grpc-subscriptions) +and maintains conceptual alignment with it, despite the specific +service and proto definitions being different. + +## Overview + +MCP is a subscription-based configuration distribution API. The +configuration consumer (i.e. sink) requests updates for collections of +resources from a configuration producer (i.e. source). The source +pushes resource updates to the sink when resources are added, updated, +or deleted. The sink positively ACK's the resource update, if it was +accepted, and NACK's if it was rejected, e.g. because a resource was +invalid. The source may push additional update once the previous +update was ACK/NACK'd. The source should only have one outstanding +update (per-collection) in flight at a time. + +MCP is a pair of bidirectional streaming gRPC API services +(`ResourceSource` and `ResourceSink`). + +* The `ResourceSource` service is used when the resource source is the +server and the sink is a client. By default, Galley implements the +`ResourceSource` service and Pilot/Mixer connect as clients. + +* The `ResourceSink` service is used when the resource source is a +client and the sink is the server. Galley can be configured to +optionally "dial-out" to a remote configuration sink, e.g. Pilot is in +another cluster where it cannot, as a client, initiate +connection to Galley. In this scenario, Pilot would implement the +`ResourceSink` service and Galley would connect as a client. + +ResourceSource and ResourceSink are semantically equivalent with +regards to the message exchange. The only meaningful difference is who +initiates the connection and opens the grpc stream. + +## Data model + +MCP is the mechanism of transport whereby Pilot and Mixer can be +configured by a manager component. MCP defines a common per-resource +metadata format and resource specific contents is defined elsewhere +(e.g. https://github.com/istio/api/tree/master/networking/v1alpha3). + +### Collections + +Resources of the same type are organization into named +collections. Istio API collection names are of the form +`istio///` where ``, ``, and `Created with Raphaël 2.2.0Client/SourceClient/SourceServer/SinkServer/Sinkconn := grpc.Dial(S)svc := mcp.NewResourceSinkService(conn)stream := mcp.EstablishResourceStream()stream establishedstream.Send(RequestResources)Resources := stream.Recv() \ No newline at end of file diff --git a/mcp/v1alpha1/diagrams/ResourceSource-connection-setup.svg b/mcp/v1alpha1/diagrams/ResourceSource-connection-setup.svg new file mode 100644 index 00000000000..71af7d3a034 --- /dev/null +++ b/mcp/v1alpha1/diagrams/ResourceSource-connection-setup.svg @@ -0,0 +1 @@ +Created with Raphaël 2.2.0Client/SinkClient/SinkServer/SourceServer/Sourceconn := grpc.Dial(S)svc := mcp.NewResourceSourceService(conn)stream := svc.EstablishResourceStream()stream establishedstream.Send(RequestResources)Resources := stream.Recv() \ No newline at end of file diff --git a/mcp/v1alpha1/diagrams/collection-full-state-update-success.svg b/mcp/v1alpha1/diagrams/collection-full-state-update-success.svg new file mode 100644 index 00000000000..0be0e75ed0d --- /dev/null +++ b/mcp/v1alpha1/diagrams/collection-full-state-update-success.svg @@ -0,0 +1 @@ +Created with Raphaël 2.2.0SinkSinkSourceSourceestablish streamRequestResources{collection=A,nonce=}Resources{collection=A,nonce=1,resource={(foo,v0),(bar,v0)}RequestResources{collection=A,nonce=1} (ACK)resources={(foo,v0),(bar,v0)}Resources{collection=A,nonce=2,resource={(foo,v0),(bar,v0),(baz,v0)}}RequestResources{collection=A,nonce=2} (ACK)resources={(foo,v0),(bar,v0),(baz,v0}Resources{collection=A,nonce=3,resource={(bar, v1),(baz, v0)}}RequestResources{collection=A,nonce=3} (ACK)resources={(bar,v1),(baz,v0)} \ No newline at end of file diff --git a/mcp/v1alpha1/diagrams/collection-incremental-update-success.svg b/mcp/v1alpha1/diagrams/collection-incremental-update-success.svg new file mode 100644 index 00000000000..7fa6d44ee53 --- /dev/null +++ b/mcp/v1alpha1/diagrams/collection-incremental-update-success.svg @@ -0,0 +1 @@ +Created with Raphaël 2.2.0SinkSinkSourceSourceestablish streamRequestResources{collection=A,nonce=}Resources{collection=A,nonce=1,resource={(foo,v0),(bar,v0)},incremental=true}RequestResources{collection=A,nonce=1,incremental=true} (ACK)resources={(foo,v0),(bar,v0)}Resources{collection=A,nonce=2,resource={(baz,v0)},incremental=true}RequestResources{collection=A,nonce=2,incremental=true} (ACK)resources={(foo,v0),(bar,v0),(baz,v0}Resources{collection=A,nonce=3,resource={(bar, v1)},removed={foo}incremental=true}RequestResources{collection=A,nonce=3,incremental=true} (ACK)resources={(bar,v1),(baz,v0)} \ No newline at end of file diff --git a/mcp/v1alpha1/diagrams/collection-update-error.svg b/mcp/v1alpha1/diagrams/collection-update-error.svg new file mode 100644 index 00000000000..8b4a86fbade --- /dev/null +++ b/mcp/v1alpha1/diagrams/collection-update-error.svg @@ -0,0 +1 @@ +Created with Raphaël 2.2.0SinkSinkSourceSourceestablish streamRequestResources{collection=A,nonce=}Resources{collection=A,nonce=1,resource={(foo,v0),(bar,v0)}RequestResources{collection=A,nonce=1} (ACK)resources={(foo,v0),(bar,v0)}Resources{collection=A,nonce=2,resource={(baz,v0)}RequestResources{collection=A,nonce=2,error="could not apply"} (NACK)resources={(foo,v0),(bar,v0)}Resources{collection=A,nonce=3,resource={(bar, v1)},remove={(foo,v0)}RequestResources{collection=A,nonce=3} (ACK)resources={(bar,v1),(baz,v0)} \ No newline at end of file