1
0
mirror of https://github.com/openshift/openshift-docs.git synced 2026-02-06 15:46:57 +01:00
Files
openshift-docs/modules/ossm-routing.adoc
2020-10-07 13:27:48 -04:00

289 lines
12 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Module included in the following assemblies:
//
// * service_mesh/v1x/ossm-traffic-manage.adoc
// * service_mesh/v2x/ossm-traffic-manage.adoc
[id="ossm-routing_{context}"]
= Routing and managing traffic
Configure your service mesh by adding your own traffic configuration to {ProductName} with a custom resource definitions in a YAML file.
[id="ossm-routing-traffic-management-vs_{context}"]
== Traffic management with virtual services
You can route requests dynamically to multiple versions of a microservice through {ProductName} with a virtual service. With virtual services, you can:
* Address multiple application services through a single virtual service. If your mesh uses Kubernetes, for example, you can configure a virtual service to handle all services in a specific namespace. Mapping a single virtual service to many services is particularly useful in facilitating turning a monolithic application into a composite service built out of distinct microservices without requiring the consumers of the service to adapt to the transition.
* Configure traffic rules in combination with gateways to control ingress and egress traffic.
[id="ossm-routing-vs_{context}"]
=== Configuring virtual services
Requests are routed to a services within a service mesh with virtual services. Each virtual service consists of a set of routing rules that are evaluated in order. {ProductName} matches each given request to the virtual service to a specific real destination within the mesh.
Without virtual services, {ProductName} distributes traffic using round-robin load balancing between all service instances. With a virtual service, you can specify traffic behavior for one or more hostnames. Routing rules in the virtual service tell {ProductName} how to send the traffic for the virtual service to appropriate destinations. Route destinations can be versions of the same service or entirely different services.
The following example routes requests to different versions of a service depending on which user connects to the application. Use this command to apply this example YAML file, or one you create.
[source,terminal]
----
$ oc apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- match:
- headers:
end-user:
exact: jason
route:
- destination:
host: reviews
subset: v2
- route:
- destination:
host: reviews
subset: v3
EOF
----
[id="ossm-routing-config-v-host_{context}"]
== Configuring your virtual host
The following sections explain each field in the YAML file and explain how you can create a virtual host in a virtual service.
[id="ossm-routing-hosts_{context}"]
=== Hosts
The `hosts` field lists the virtual services user-addressable destination that these routing rules apply to. This is the address or addresses the client uses when sending requests to the service.
The virtual service hostname can be an IP address, a DNS name, or, depending on the platform, a short name that resolves to a fully qualified domain name.
[source,yaml]
----
spec:
hosts:
- reviews
----
[id="ossm-routing-routing-rules_{context}"]
=== Routing rules
The `http` section contains the virtual services routing rules, describing match conditions and actions for routing HTTP/1.1, HTTP2, and gRPC traffic sent to the destination specified in the hosts field. A routing rule consists of the destination where you want the traffic to go and zero or more match conditions, depending on your use case.
.Match condition
The first routing rule in the example has a condition and begins with the match field. In this example, this routing applies to all requests from the user `jason`. Add the `headers`, `end-user`, and `exact` fields to select the appropriate requests.
[source,yaml]
----
spec:
hosts:
- reviews
http:
- match:
- headers:
end-user:
exact: jason
----
.Destination
The `destination` field in the route section specifies the actual destination for traffic that matches this condition. Unlike the virtual services host, the destinations host must be a real destination that exists in the {ProductName} service registry. This can be a mesh service with proxies or a non-mesh service added using a service entry. In this example, the host name is a Kubernetes service name:
[source,yaml]
----
spec:
hosts:
- reviews
http:
- match:
- headers:
end-user:
exact: jason
route:
- destination:
host: reviews
subset: v2
----
[id="ossm-routing-dr_{context}"]
=== Destination rules
Destination rules are applied after virtual service routing rules are evaluated, so they apply to the traffics real destination. Virtual services route traffic to a destination. Destination rules configure what happens to traffic at that destination.
[id="ossm-routing-lb_{context}"]
==== Load balancing options
By default, {ProductName} uses a round-robin load balancing policy, where each service instance in the instance pool gets a request in turn. {ProductName} also supports the following models, which you can specify in destination rules for requests to a particular service or service subset.
* Random: Requests are forwarded at random to instances in the pool.
* Weighted: Requests are forwarded to instances in the pool according to a specific percentage.
* Least requests: Requests are forwarded to instances with the least number of requests.
.Destination rule example
The following example destination rule configures three different subsets for the `my-svc` destination service, with different load balancing policies:
[source,yaml]
----
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: my-destination-rule
spec:
host: my-svc
trafficPolicy:
loadBalancer:
simple: RANDOM
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
- name: v3
labels:
version: v3
----
[id="ossm-routing-gw_{context}"]
=== Gateways
You can use a gateway to manage inbound and outbound traffic for your mesh to specify which traffic you want to enter or leave the mesh. Gateway configurations are applied to standalone Envoy proxies that are running at the edge of the mesh, rather than sidecar Envoy proxies running alongside your service workloads.
Unlike other mechanisms for controlling traffic entering your systems, such as the Kubernetes Ingress APIs, {ProductName} gateways let you use the full power and flexibility of traffic routing. The {ProductName} gateway resource can layer 4-6 load balancing properties such as ports to expose, {ProductName} TLS settings. Instead of adding application-layer traffic routing (L7) to the same API resource, you can bind a regular {ProductName} virtual service to the gateway and manage gateway traffic like any other data plane traffic in a service mesh.
Gateways are primarily used to manage ingress traffic, but you can also configure egress gateways. An egress gateway lets you configure a dedicated exit node for the traffic leaving the mesh, letting you limit which services have access to external networks, or to enable secure control of egress traffic to add security to your mesh, for example. You can also use a gateway to configure a purely internal proxy.
.Gateway example
The following example shows a possible gateway configuration for external HTTPS ingress traffic:
[source,yaml]
----
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: ext-host-gwy
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- ext-host.example.com
tls:
mode: SIMPLE
serverCertificate: /tmp/tls.crt
privateKey: /tmp/tls.key
----
This gateway configuration lets HTTPS traffic from `ext-host.example.com` into the mesh on port 443, but doesnt specify any routing for the traffic.
To specify routing and for the gateway to work as intended, you must also bind the gateway to a virtual service. You do this using the virtual services gateways field, as shown in the following example:
[source,yaml]
----
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: virtual-svc
spec:
hosts:
- ext-host.example.com
gateways:
- ext-host-gwy
----
You can then configure the virtual service with routing rules for the external traffic.
[id="ossm-routing-se_{context}"]
=== Service entries
A service entry adds an entry to the service registry that {ProductName} maintains internally. After you add the service entry, the Envoy proxies can send traffic to the service as if it was a service in your mesh. Configuring service entries allows you to manage traffic for services running outside of the mesh, including the following tasks:
* Redirect and forward traffic for external destinations, such as APIs consumed from the web, or traffic to services in legacy infrastructure.
* Define retry, timeout, and fault injection policies for external destinations.
* Run a mesh service in a Virtual Machine (VM) by adding VMs to your mesh.
* Logically add services from a different cluster to the mesh to configure a multicluster {ProductName} mesh on Kubernetes.
* You dont need to add a service entry for every external service that you want your mesh services to use. By default, {ProductName} configures the Envoy proxies to passthrough requests to unknown services. However, you cant use {ProductName} features to control the traffic to destinations that arent registered in the mesh.
.Service entry examples
The following example mesh-external service entry adds the `ext-resource` external dependency to the {ProductName} service registry:
[source,yaml]
----
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: svc-entry
spec:
hosts:
- ext-svc.example.com
ports:
- number: 443
name: https
protocol: HTTPS
location: MESH_EXTERNAL
resolution: DNS
----
Specify the external resource using the hosts field. You can qualify it fully or use a wildcard prefixed domain name.
You can configure virtual services and destination rules to control traffic to a service entry in the same way you configure traffic for any other service in the mesh. For example, the following destination rule configures the traffic route to use mutual TLS to secure the connection to the `ext-svc.example.com` external service that is configured using the service entry:
[source,yaml]
----
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: ext-res-dr
spec:
host: ext-svc.example.com
trafficPolicy:
tls:
mode: MUTUAL
clientCertificate: /etc/certs/myclientcert.pem
privateKey: /etc/certs/client_private_key.pem
caCertificates: /etc/certs/rootcacerts.pem
----
[id="ossm-routing-sc_{context}"]
=== Sidecar
By default, {ProductName} configures every Envoy proxy to accept traffic on all the ports of its associated workload, and to reach every workload in the mesh when forwarding traffic. You can use a sidecar configuration to do the following:
* Fine-tune the set of ports and protocols that an Envoy proxy accepts.
* Limit the set of services that the Envoy proxy can reach.
* You might want to limit sidecar reachability like this in larger applications, where having every proxy configured to reach every other service in the mesh can potentially affect mesh performance due to high memory usage.
.Sidecar example
You can specify that you want a sidecar configuration to apply to all workloads in a particular namespace, or choose specific workloads using a `workloadSelector`. For example, the following sidecar configuration configures all services in the `bookinfo` namespace to only reach services running in the same namespace and the {ProductName} control plane (currently needed to use the {ProductName} policy and telemetry features):
[source,yaml]
----
apiVersion: networking.istio.io/v1alpha3
kind: Sidecar
metadata:
name: default
namespace: bookinfo
spec:
egress:
- hosts:
- "./*"
- "istio-system/*"
----