Let's start by talking about Istio, what it is, how its resources work, and most importantly what it's used for.
Istio is an open-source project that handles routing problems arising in microservices-based applications.
Istio is the best-known embodiment of the Service Mesh concept making it possible to implement a Service Discovery, Load Balancing, traffic control, Canary Rollouts, Blue-green deployments, monitoring traffic between applications, and many other features. What does this pattern and its features provide?
First, security. Istio includes enforced encryption of traffic using mutual TLS (MTLS), providing authentication via certificate validation and authorization via access policies. In this way, both the development side and client services can exchange certificates, check for validity, and automatically update them, safe in the knowledge that they are secure.
The second is traffic management.
Istio enables fine-grained control over traffic routing in the service mesh. This includes features such as load balancing, traffic sharing, mirroring, and error management. These things improve the reliability and quality of service to customers by controlling traffic flow and smoothly introducing new features without disrupting users.
The third point is observability through tracing, monitoring, and logging, which provides deeper insight into application performance and user behavior, enabling data-driven decision-making and faster troubleshooting. Istio has a broad set of metrics, which allows you to observe traffic and identify anomalies.
A couple of words about installation in Kubernetes.
There are different installation options from the official documentation, which describes in detail how you can set up Istio. Choose the convenient option for you and let's get down to a more detailed analysis.
It would be long and probably inefficient to talk about all the features, so we will cover Istio within a few resources we have added support for in the nxs-universal-chart.
nxs-universal-chart is an open-source universal Helm. You can use it to deploy any of your applications to Kubernetes/OpenShift and other orchestrators compatible with the native Kubernetes API. Among the main features are support for Ingress controllers (Ingress Nginx, Traefik), different versions of K8s/Openshift, and convenient templating of custom resources with extraDeploy. And recently we've added Istio core resources: Istio Gateway, Virtual Service, and DestinationRule, which we'll get to directly now.
Schematic path of a packet to the final application
To understand how this works, let's talk about the packet passing scheme to the target application.
The packet arrives on the port of the external LoadBalancer, which sends it to the Kubernetes node port. At the node port, the packet goes to the Istio IngressGateway Service, from where it is redirected to the Istio IngressGateway Pod. This is where the Gateway and Virtual Service starts.
Istio Gateway
Gateway is a gateway that describes a load balancer and handles incoming or outgoing HTTP/TCP connections. It is a kind of “gateway” through which all external requests pass before reaching the inside of the Kubernetes cluster.
For example, the following nxs-universal-chart manifest sets the proxy to act as a load balancer by opening port 80 (HTTP).
---
# Source: universal-chart/templates/istiogateway.yml
apiVersion:
kind: Gateway
metadata:
name: nginx-gateway
namespace: "test"
labels:
app.kubernetes.io/name: test
app.kubernetes.io/instance: test
helm.sh/chart: universal-chart-2.8.0
app.kubernetes.io/managed-by: Helm
annotations:
spec:
selector:
istio: ingress
servers:
- hosts:
- nginx.example.com
port:
name: http
number: 80
protocol: HTTP
Thus, Gateway - defines ports and protocols: specifies on which ports and with which protocols (HTTP, HTTPS, etc.) to accept traffic, and also manages TLS settings: defines how to handle TLS connections, including the use of SSL certificates, redirect HTTP requests to HTTPS, TLS modes, etc.
VirtualService
VirtualService, the next instance to handle our traffic after Gateway, describes the routing rules for traffic that enter the cluster through Gateway. It defines how and where to send this traffic within the cluster.
VirtualService operates on a set of rules when accessing the host, which is used to establish: which services or pods to send traffic to, the need to run canary deployment or A/B testing, etc. The source of traffic can also be specified in routing rules. This allows routing to be customized for specific client contexts. In simpler terms, VirtualService describes a packet's routing to our application's desired Kubernetes Service.
In this example on Kubernetes, all HTTP traffic for the nginx.example.com host is by default routed to the nginx.example.com service subnets via nginx-gateway. In addition, rules with different paths starting with the prefix “/” can be set to HTTP requests.
---
# Source: universal-chart/templates/istiovirtualservice.yml
apiVersion:
kind: VirtualService
metadata:
name: nginx-virtualservice
namespace: "test"
labels:
app.kubernetes.io/name: test
app.kubernetes.io/instance: test
helm.sh/chart: universal-chart-2.8.0
app.kubernetes.io/managed-by: Helm
annotations:
spec:
hosts:
- "nginx.example.com"
gateways:
- "nginx-gateway"
http:
- name: ""
match:
- uri:
prefix: /
route:
- destination:
host: nginx-service.default.svc.cluster.local
port:
number: 80
After that, the Istio IngressGateway Pod sends the packet to the Service application.
DestinationRule
DestinationRule defines how to handle traffic that is already directed to specific services or pods using Virtual Service.
It specifies policies for traffic such as load balancing, distributing traffic between service instances, error management, fault tolerance policies (timeouts, retries, any other reliability measures), routing traffic to different versions of the application, etc. that will be applied to traffic destined to instances of this service.
In this nxs-universal-chart manifest, traffic going to the “nginx-service.default.svc.cluster.local” service will be subject to the following load balancing rules, depending on which subset the instance falls into. For this, each subset has its own labels and metrics.
---
# Source: universal-chart/templates/istiodestinationrule.yml
apiVersion:
kind: DestinationRule
metadata:
name: nginx-destinationrule
namespace: "test"
labels:
app.kubernetes.io/name: test
app.kubernetes.io/instance: test
helm.sh/chart: universal-chart-2.8.0
app.kubernetes.io/managed-by: Helm
annotations:
spec:
host: "nginx-service.default.svc.cluster.local"
trafficPolicy:
connectionPool:
http:
http1MaxPendingRequests: 500
maxRequestsPerConnection: 50
loadBalancer:
simple: ROUND_ROBIN
outlierDetection:
baseEjectionTime: 15s
consecutiveGatewayErrors: 3
interval: 5s
subsets:
- name: v1
labels:
app: "nginx"
trafficPolicy:
connectionPool:
tcp:
maxConnections: 200
loadBalancer:
simple: LEAST_CONN
- name: v2
labels:
version: "v2"
trafficPolicy:
connectionPool:
http:
http2MaxRequests: 2000
loadBalancer:
simple: RANDOM
exportTo:
- "."
- "another-namespace"
This is where DestinationRule's work ends. The decision on which instance (sub) to send the request to is made by Envoy in Ingress Gateway, it takes TCP and HTTP requests as input, processes them, and sends them to the Kubernetes service. The application service then sends the packet to the corresponding sub with the application.
Gateway, Virtual Service, and DestinationRule are the main resources of Istio, but in addition to them, there are Envoy Filter, ProxyConfig, Sidecar, and several others described in the official documentation. They all affect traffic management in one way or another, so we'd be interested to see how useful you find adding them to nxs-universal-chart!
We are happy to get your opinion and listen to the needs of the community, this will not only help us develop and improve the repo but also help us understand how useful these features are for you and what your needs are. What other development opportunities do you see? What options would you add? We're open to any questions or comments in Telegram chat, here in the comments, or on GitHub!
Top comments (0)