Anatomy of Istio architecture

Istio is an open source service grid that provides the basic operation and management elements required for distributed microservice architecture. As organizations increasingly adopt cloud platforms, developers must use microservices to design architectures to achieve portability, and operations and maintenance personnel must manage large-scale distributed applications that include hybrid cloud deployment and multi-cloud deployment. Istio uses a consistent way to protect, connect, and monitor microservices, reducing the complexity of managing microservice deployment.
From the perspective of architecture design, the Istio service grid is logically divided into two parts: the control plane and the data plane. Among them, the control plane Pilot is responsible for managing and configuring proxies to route traffic, and configuring Mixer to implement policies and collect telemetry data; the data plane consists of a set of intelligent proxies (Envoy) deployed in a Sidecar manner, which can regulate and control microservices And all network communications between Mixer.


Istio architecture

953963b6e643f577eb666b9508dd0b1a.png


As a proxy, Envoy is very suitable for service mesh scenarios, but to maximize the value of Envoy, it needs to be closely matched with the underlying infrastructure or components. Envoy constitutes the data plane of the service grid, and the supporting components provided by Istio create the control plane.

962af6ecac3cc3fd8da30573ba422a61.png

Pilot and Envoy data plane
On the one hand, we have seen in Envoy that a set of service proxies can be configured using a static configuration file or a set of discovery services to discover listeners, endpoints, and clusters at runtime. Istio implements the xDS API of these Envoy proxies in Pilot.
On the other hand, Envoy's service discovery relies on a certain service registry to discover service endpoints. Istio Pilot implements this API, but also abstracts Envoy from any specific service registration implementation. When Istio is deployed on Kubernetes, the service registry of Kubernetes is used by Istio for service discovery. Other registries can also be used like HashiCorp's Consul. The Envoy data plane is completely unaffected by these implementation details.

378756db0e15ba56f779715f82a10c97.png

Mixer architecture
In addition, the Envoy proxy can send out many metrics and telemetry data. Where these telemetry data are sent depends on the configuration of Envoy. Istio provides the telemetry receiver Mixer as part of its control plane, and Envoy proxy can send these data to Mixer. Envoy also sends distributed tracing data to an open tracing engine (following the Open Tracing API). Istio can support a compatible open tracking engine and configure Envoy to send its tracking data to that location.


Anatomy of the Istio control plane

953963b6e643f577eb666b9508dd0b1a.png


Istio's control plane and Envoy's data plane together form a compelling service mesh implementation. Both have thriving and vibrant communities, and are geared toward next-generation service architectures. Istio is platform-independent and can run in various environments, including cross-cloud, on-premises, Kubernetes, Mesos, etc. You can deploy Istio on Kubernetes or on Nomad with Consul. Istio currently supports services deployed on Kubernetes, services registered with Consul, and services deployed on virtual machines.
Among them, the control plane part includes four components: Pilot, Mixer, Citadel, and Galley. The Pilot component of
Pilot
Istio is used to manage traffic, and can control traffic flow and API calls between services. Through Pilot, traffic can be better understood so that problems can be discovered before they occur. This makes the call more reliable, the network stronger, and the application is rock solid even in adverse conditions. With Istio's Pilot, you can configure service-level properties such as fuses, timeouts, and retries, and set up common continuous deployment tasks such as canary releases, A/B testing, and phased releases based on percentage split traffic. Pilot provides service discovery functions for Envoy proxy, and traffic management functions for intelligent routing and elastic capabilities (such as timeouts, retries, fuses, etc.). Pilot converts the advanced routing rules that control traffic behavior into Envoy proxy-specific configurations and propagates them to Envoy at runtime. In addition, Istio provides powerful out-of-the-box failure recovery functions, including timeouts, retry mechanisms that support timeout budgets and variable jitter, concurrent connections sent to upstream services and restrictions on the number of requests, and for each member of the load balancing pool Periodic active health check and passive health check performed.
Pilot abstracts the platform-specific service discovery mechanism and synthesizes it into a standard format. Any Sidecar that conforms to the data plane API can use this standard format. This loose coupling allows Istio to run in multiple environments (such as Kubernetes, Consul, Nomad), while maintaining the same interface for traffic management.
Mixer
Istio's Mixer component provides policy control and telemetry collection functions, isolating the rest of Istio from the implementation details of each back-end infrastructure. Mixer is a platform-independent component that is responsible for executing access control and usage policies on the service grid, and collecting telemetry data from Envoy proxy and other services. The agent extracts request-level attributes and sends them to Mixer for evaluation.
Mixer includes a flexible plug-in model that enables it to connect to a variety of host environments and back-end infrastructure, abstracting Envoy proxy and Istio managed services from these details. With Mixer, you can finely control all interactions between the grid and the back-end infrastructure.
Unlike the Sidecar agent, which must save memory, Mixer runs independently, so it can use a fairly large cache and output buffer, acting as a highly scalable and highly available secondary cache for Sidecar.
Mixer aims to provide high availability for each instance. Its local cache and buffer can reduce latency and also help shield back-end infrastructure from back-end failures, even if the back-end is not responding.
Citadel
Istio Citadel security features provide powerful authentication functions, strong policies, transparent TLS encryption, and authentication, authorization, and audit (AAA) tools for protecting services and data. Envoy can terminate or initiate to services in the grid. TLS traffic. For this, Citadel needs to support the creation, signing and rotation of certificates. Istio Citadel provides application-specific certificates that can be used to establish mutual TLS to protect traffic between services.

5bda5bd27525230af6dd685457b919ea.png

The Istio Citadel architecture
uses Istio Citadel to ensure that services containing sensitive data can only be accessed from strictly authenticated and authorized clients. Citadel provides powerful inter-service and end-user authentication through built-in identity and credential management. It can be used to upgrade unencrypted traffic in the service grid and provide operation and maintenance personnel with the ability to enforce policies based on service identification rather than network control. Istio's configuration policy configures platform authentication on the server side, but does not enforce the policy on the client side, and allows you to specify the authentication requirements of the service. Istio's key management system can automatically generate, distribute, rotate and revoke keys and certificates.
Istio RBAC provides namespace-level, service-level, and method-level access control for services in the Istio grid, including easy-to-use role-based semantics, service-to-service, and end-user-to-service authorization, and is tied to roles and roles. Provide flexible custom attribute support in certain aspects.
Istio can enhance the security of microservices and their communication (including service-to-service and end-user-to-service communication) without changing the service code. It provides a powerful role-based identity mechanism for each service to achieve cross-cluster and cross-cloud interactive operations.
Galley
Galley is used to verify the Istio API configuration written by the user. Over time, Galley will take over Istio's top-level responsibility for obtaining configuration, processing and distributing components. It is responsible for isolating other Istio components from the details of obtaining user configuration from the underlying platform (such as Kubernetes).
All in all, through Pilot, Istio can help you simplify traffic management as the deployment scale gradually expands. With Mixer, with robust and easy-to-use monitoring functions, problems can be detected and repaired quickly and effectively. Through Citadel, the security burden is reduced, allowing developers to focus on other critical tasks.
There are several key goals in the architecture design of Istio, which are essential for the system to deal with large-scale traffic and high-performance service processing.
  • Maximize transparency: To adopt Istio, operations and developers should be able to obtain real value from it at a very low cost. To this end, Istio automatically injects itself into all network paths between services. Istio uses Envoy proxies to capture traffic and, where possible, automatically program the network layer to route traffic through these proxies without requiring too many or even any changes to the deployed application code. In Kubernetes, the Envoy proxy is injected into the pod, and traffic is captured through iptables rules. Once the Envoy proxy is injected into the pod and the routing rules are modified, Istio can regulate all traffic. This principle also applies to performance. When using Istio for deployment, operations and maintenance personnel can find that the additional resource overhead to provide these functions is very small. All components and APIs must be designed with performance and scale in mind.

  • Scalability: As operation and maintenance personnel and developers increasingly rely on the functions provided by Istio, the system will inevitably grow with their needs. As we continue to add new features, what is most needed is the ability to expand the strategy system, integrate other strategies and control sources, and propagate grid behavior signals to other systems for analysis. The strategy runtime supports a standard extension mechanism for insertion into other services. In addition, it allows the vocabulary to be expanded to allow enforcement of policies based on new signals generated by the grid.

  • Portability: The ecosystem that uses Istio is different in many ways. Istio must be able to run in any cloud or local environment at the least cost. It should be easy to migrate Istio-based services to a new environment, and it is also feasible to use Istio to deploy a service to multiple environments at the same time. For example, it can be deployed on a hybrid cloud to achieve redundant disaster recovery.

  • Policy consistency: The policy is applied to API calls between services, which can well control grid behavior. But for resources that do not need to be expressed at the API level, applying strategies to resources is equally important. For example, applying a quota to the number of CPUs consumed by a machine learning training task is more useful than applying a quota to the call that starts the job. Therefore, Istio maintains the policy system as a unique service with its own API instead of putting it in a proxy, which allows services to integrate directly with it as needed.


Anatomy of the Istio data plane

953963b6e643f577eb666b9508dd0b1a.png


When introducing the concept of service grid, it mentioned the concept of service proxy and how to use proxy to build a service grid to regulate and control all network communication between microservices. Istio uses Envoy proxies as the default out-of-the-box service proxies. These Envoy proxies run with all application instances participating in the service grid, but are not in the same container process, forming the data plane of the service grid. As long as the application wants to communicate with other services, it will do so through the service proxy Envoy. It can be seen that Envoy proxy is a key component in the data plane and the entire service grid architecture.
Envoy proxy
Envoy was originally developed by Lyft to solve some complex network problems that arise when building distributed systems. It was provided as an open source project in September 2016 and joined the Cloud Native Computing Foundation (CNCF) a year later. Envoy is implemented in C++ language, with high performance, and more importantly, it is also very stable and reliable under high load. The network should be transparent to the application. When there is a problem with the network and the application, it should be easy to determine the source of the problem. It is based on such a design concept that Envoy is designed as a seven-layer proxy and communication bus with a service-oriented architecture.
In order to better understand Envoy, we need to figure out a few basic terms:
  • Out of Process architecture: Envoy is an independent process. A transparent communication grid is formed between Envoy. Each application sends or receives messages to or from the local host, but does not need to care about the network topology.

  • Single-process multi-threaded model: Envoy uses a single-process multi-threaded architecture model. A main thread manages various trivial tasks, and some worker sub-threads are responsible for performing monitoring, filtering, and forwarding functions.

  • Downstream: The host that connects to Envoy and sends the request and receives the response is called the downstream host, which means that the downstream host represents the host that sent the request.

  • Upstream: As opposed to downstream, the host receiving the request is called the upstream host.

  • Listener: The listener is a named network address, including port, unix domain socket, etc., which can be connected by downstream hosts. Envoy exposes one or more listeners to connect to downstream hosts. Each listener is independently configured with some network level (that is, three or four layers) filters. When the listener receives a new connection, the configured local filter will be instantiated and begin processing subsequent events. Generally speaking, the listener architecture is used to perform most different proxy tasks, such as rate limiting, TLS client authentication, HTTP connection management, MongoDB sniffing, raw TCP proxy, etc.

  • Cluster (Cluster): A cluster refers to a group of logically identical upstream hosts connected by Envoy.

  • xDS protocol: In Envoy, the xDS protocol represents multiple discovery service protocols, including Cluster Discovery Service (CDS), Listener Discovery Service (LDS), and Route Discovery Service (RDS) ), Endpoint Discovery Service (EDS), and Secret Discovery Service (SDS).


cced08e324b6ca9d11638203e855e0c1.png

Envoy proxy
Envoy proxy has many functions that can be used for inter-service communication. For example, it exposes one or more listeners to downstream host connections, and exposes them to external applications through ports; defines routing rules to process the traffic transmitted in the listeners, and The traffic is directed to the target cluster, and so on. The following chapters will further analyze the roles and functions of these discovery services in Istio.
After understanding the terminology of Envoy, you may want to know as soon as possible what role Envoy plays?
First of all, Envoy is a proxy that acts as an intermediary in the network architecture. It can add additional functions to traffic management in the network, including providing security, privacy protection, or policies. In the scenario of calling between services, the proxy can hide the topological details of the service back-end for the client, simplify the complexity of the interaction, and protect the back-end service from overload. For example, a back-end service is actually a group of identical instances running, and each instance can handle a certain amount of load.
Secondly, the cluster in Envoy essentially refers to a logically identical group of upstream hosts that Envoy connects to. So how does the client know which instance or IP address to use when interacting with the back-end service? Envoy acts as a proxy for routing selection. Through service discovery (SDS, Service Discovery Service), Envoy proxy discovers all members in the cluster, and then determines the health status of the cluster members through active health checks, and according to the health status, through the load The balancing strategy determines which cluster member to route the request to. In the Envoy proxy process of load balancing across service instances, the client does not need to know any details of the actual deployment.
Envoy's startup configuration
Envoy currently provides two versions of the API, namely v1 and v2. Since Envoy 1.5.0, there has been a v2 API. In order to allow users to smoothly migrate to the v2 version of the API, a parameter-v2 is set when Envoy is started -conf?ig-only. Through this parameter, you can clearly specify the protocol that Envoy uses v2 API. Fortunately, the v2 API is a superset of v1 and is compatible with the v1 API. In the current version after Istio 1.0, it is clearly specified that it supports v2 API. By looking at the container startup command that uses Envoy as the Sidecar proxy, you can see similar startup parameters as follows, where the parameter --v2-conf?ig-only is specified:
$ /usr/local/bin/envoy -c /etc/istio/proxy/envoy-rev0.json --restart-epoch 0 --drain-time-s 45 --parent-shutdown-time-s 60 --service-cluster ratings --service-node sidecar~172.33.14.2~ratings-v1-8558d4458d-ld8x9.default~default.svc.cluster.local --max-obj-name-len 189 --allow-unknown-fields -l warn --v2-config-only


Among them, the parameter -c represents the path of the boot configuration file based on version v2, the format is JSON, and other formats such as YAML, Proto3, etc. are also supported. It will first be parsed as a version v2 boot configuration file. If the parsing fails, it will be parsed as a version v1 JSON configuration file according to the [--v2-conf?ig-only] option. Other parameters are explained as follows, so that readers can understand the configuration information when Envoy proxy starts:

  • Restart-epoch represents the hot restart period. The default is 0 for the first startup, and it should be increased after each hot restart.

  • service-cluster defines the name of the local service cluster that Envoy runs.

  • service-node defines the name of the local service node where Envoy runs.

  • drain-time-s indicates the time (in seconds) that Envoy will drain connections during a warm restart. The default is 600 seconds (10 minutes). Usually the exhaustion time should be less than the parent process shutdown time set by the --parent-shutdown-time-s option.

  • parent-shutdown-time-s represents the time (in seconds) that Envoy waits before shutting down the parent process during a hot restart.

  • max-obj-name-len describes the maximum length of the name field in the cluster cluster, route configuration route_conf?ig, and listener listener, in bytes. This option is usually used in scenarios where the cluster name is automatically generated, which usually exceeds the internal limit of 60 characters. The default is 60.


Envoy's startup configuration file is divided into two ways: static configuration and dynamic configuration. The specific performance is:
  • The static configuration is to put all the information in the configuration file and load it directly at startup.

  • Dynamic configuration needs to provide an Envoy server, which is used to dynamically generate the service discovery interface required by Envoy, which is generally called xDS. The configuration information is dynamically adjusted by discovering services. Istio implements the xDS API of v2.


Envoy static and dynamic configuration
Envoy is an intelligent proxy driven by configuration files in JSON or YAML format. For users who are already familiar with Envoy or Envoy configuration, I believe they should already know that there are different versions of Envoy configuration. The initial version v1 is the original way to configure Envoy when Envoy starts. This version has been deprecated to support the v2 version of Envoy configuration. Envoy's reference document (https://www.envoyproxy.io/docs) also provides a clear distinction between v1 and v2 documents. This book will only focus on the v2 configuration because it is the latest version and the version used by Istio.
The configuration API of Envoy version v2 is built on gRPC. An important feature of the v2 API is that it can use the streaming function when calling the API to reduce the time required for Envoy proxy aggregation configuration. In fact, this also eliminates the drawbacks of the polling API, allowing the server to push updates to the Envoy proxy instead of polling the proxy periodically.
Envoy's architecture makes it possible to use different types of configuration management methods. The method used in deployment will depend on the needs of the implementer. Simple deployment can be achieved through fully static configuration, and more complex deployments can be incrementally added with more complex dynamic configurations. Mainly divided into the following situations:
  • Full static: In a fully static configuration, the implementer provides a set of listener and filter chains, clusters, and optional HTTP routing configuration. Dynamic host discovery can only be discovered through DNS-based services. The configuration reload must be performed through the built-in hot restart mechanism.

  • SDS/EDS only: On top of static configuration, Envoy can discover members in upstream clusters through this mechanism.

  • SDS/EDS and CDS: Envoy can discover the upstream cluster used by this mechanism.

  • SDS/EDS, CDS and RDS: RDS can discover the entire routing configuration for HTTP connection manager filters at runtime.

  • SDS/EDS, CDS, RDS and LDS: LDS can discover the entire listener at runtime. This includes all filter stacks, including HTTP filters with applications embedded in RDS.


For static configuration,
we can use Envoy's configuration file to specify listeners, routing rules, and clusters. The following example provides a very simple Envoy configuration:
static_resources:  listeners:  - name: httpbin-demo    address:      socket_address: { address: 0.0.0.0, port_value: 15001 }    filter_chains:    - filters:      - name: envoy.http_connection_manager        config:          stat_prefix: egress_http          route_config:            name: httpbin_local_route            virtual_hosts:            - name: httpbin_local_service              domains: ["*"]              routes:              - match: { prefix: "/" }                route:                  auto_host_rewrite: true                  cluster: httpbin_service          http_filters:          - name: envoy.router  clusters:    - name: httpbin_service      connect_timeout: 5s      type: LOGICAL_DNS      # Comment out the following line to test on v6 networks      dns_lookup_family: V4_ONLY      lb_policy: ROUND_ROBIN      hosts: [{ socket_address: { address: httpbin, port_value: 8000 }}]


In this simple Envoy configuration file, we declare a listener, which opens a socket on port 15001 and attaches a filter chain to it. The filter http_connection_manager uses routing instructions in the Envoy configuration (the simple routing instructions seen in this example are wildcards matching all virtual hosts) and route all traffic to the httpbin_service cluster. The last part of the configuration defines the connection properties of the httpbin_service cluster. In this example, we specify that the type of endpoint service discovery is LOGICAL_DNS, and the load balancing algorithm when communicating with the upstream httpbin service is ROUND_ROBIN.
This is a simple configuration file to create incoming traffic from the listener and route all traffic to the httpbin cluster. It also specifies the settings of the load balancing algorithm to be used and the connection timeout configuration to be used.
You will notice that many configurations are clearly specified, such as which listeners are specified, what are the routing rules, and which clusters we can route to. This is an example of a completely static configuration file.
For an explanation of more information about these parameters, please refer to Envoy's documentation (http://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/service_discovery#logical-dns).
In the previous section, we pointed out that Envoy can dynamically configure its various settings. The following will introduce the dynamic configuration of Envoy and how Envoy uses the xDS API for dynamic configuration.
Dynamic configuration
Envoy can utilize a set of APIs for configuration updates without any downtime or restart. Envoy only needs a simple boot configuration file, which points the configuration to the correct discovery service API, and the rest is dynamically configured. Envoy's APIs for dynamic configuration are generally collectively referred to as xDS services, which include the following:

  • Listener Discovery Service (LDS): A mechanism that allows Envoy to query the entire listener. Known listeners can be dynamically added, modified, or deleted by calling this API; each listener must have a unique name. If no name is provided, Envoy will create a UUID.

  • Route Discovery Service (RDS): Envoy dynamically obtains the routing configuration mechanism. The routing configuration includes HTTP header modification, virtual hosts, and individual routing rules contained in each virtual host. Each HTTP connection manager can independently obtain its own routing configuration through API. RDS configuration is part of the listener discovery service LDS, a subset of LDS, used to specify when static and dynamic configurations should be used, and specify which route to use.

  • Cluster Discovery Service (CDS): An optional API that Envoy will call to dynamically obtain cluster management members. Envoy will also coordinate cluster management based on API responses, adding, modifying or deleting known clusters as needed. Any clusters statically defined in the Envoy configuration cannot be modified or deleted through the CDS API.

  • Endpoint Discovery Service (EDS): A mechanism that allows Envoy to obtain cluster members, based on gRPC or RESTJSON API, which is a subset of CDS; cluster members are called Endpoints in Envoy terminology. For each cluster, Envoy gets the endpoint from the discovery service. EDS is the preferred service discovery mechanism.

  • Key Discovery Service (SDS): API used to distribute certificates; the most important benefit of SDS is to simplify certificate management. Without this feature, in Kubernetes deployment, the certificate must be created as a key and mounted in the Envoy proxy container. If the certificate expires, the key needs to be updated and the agent container needs to be redeployed. Use the key discovery service SDS, then the SDS server will push the certificate to all Envoy instances. If the certificate expires, the server only needs to push the new certificate to the Envoy instance, and Envoy will immediately use the new certificate without redeployment.

  • Aggregate Discovery Service (ADS): The serialized stream of all the changes of the above other APIs; you can use this single API to get all the changes in sequence; ADS is not an xDS in the actual sense, it provides an aggregation function, When multiple simultaneous xDS accesses, ADS can be completed in one stream.


The configuration can use one of the above services or a combination of several of them, not all of them. One thing to note is that Envoy's xDS API is built on the premise of eventual consistency, and the correct configuration will eventually converge. For example, Envoy may eventually get RDS updates using a new route that routes traffic to clusters that have not yet been updated in CDS. This means that routing may introduce routing errors until the CDS is updated. Envoy introduced the aggregation discovery service ADS to solve this problem, while Istio implemented the aggregation discovery service ADS and used ADS for proxy configuration changes.
For example, if the Envoy proxy wants to dynamically discover the listener, you can use the following configuration:
dynamic_resources:  lds_config:    api_config_source:      api_type: GRPC      grpc_services:        - envoy_grpc:            cluster_name: xds_clusterclusters:- name: xds_cluster  connect_timeout: 0.25s  type: STATIC  lb_policy: ROUND_ROBIN  http2_protocol_options: {}  hosts: [{ socket_address: { address: 127.0.0.3, port_value: 5678 }}]


Through the above configuration, we do not need to explicitly configure each listener in the configuration file. We tell Envoy to use the LDS API to find the correct listener configuration values ​​at runtime. However, we need to explicitly configure a cluster. This cluster is where the LDS API is located, which is the cluster xds_cluster defined in this example.
On the basis of static configuration, the information provided by each discovery service is displayed more intuitively.

5b2f70432276f44c7c3666a99d406bce.png

On
the basis of static configuration, xDS service information visually shows the information provided by each discovery service.


Guess you like

Origin blog.51cto.com/14992974/2552137