此教程已加入 Istio 系列:https://istio.whuanle.cn
5. Egress and Ingress Gateways
Istio can manage ingress and egress traffic in a cluster. When clients access applications within the cluster, Istio can implement load balancing, circuit breaking, and other features for traffic that passes through the istio-ingressgateway.
However, if an application within the cluster wants to access google.com, can we set up load balancing for all internal requests to google.com? The answer is yes. Istio provides the istio-egressgateway to achieve this functionality. When containers in a Pod need to access external networks, they will be intercepted by Envoy, which can easily analyze these requests and influence the behavior of the requests through various means.
In this chapter, we will briefly discuss istio-ingressgateway and istio-egressgateway.
istio-ingressgateway
The ingress gateway refers to the traffic flowing into the cluster via istio-ingressgateway, which requires the creation of a Gateway to bind the traffic.
Regarding istio-ingressgateway, you should be familiar with it from previous chapters.
The istio-ingressgateway consists of Pod and Service. The istio-ingressgateway itself is a gateway application, which you can think of as similar to Nginx, Apisix, or Kong. You can find concepts similar to istio-ingressgateway among various gateway applications.
As an application, it needs to expose some ports; istio-ingressgateway will only be effective when traffic passes through these ports. To expose ports in Kubernetes, istio-ingressgateway also has a Service object.
With istio-ingressgateway, we can monitor certain domain names or IP addresses through Istio Gateway and expose internal services of the cluster.
The concept of Gateway shares many similarities with Nginx.
For example, in terms of configuration, both Gateway and Nginx monitor particular ingress traffic as shown below:
Nginx:
server {
listen 80;
server_name example.org www.example.org;
#...
}
Gateway:
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- example.org
- www.example.org
These configurations specify which traffic the Gateway and Nginx will monitor.
Subsequently, when the specified ingress traffic is detected, it needs to be forwarded to applications within the cluster.
Nginx can set this directly in the same configuration file:
server {
listen 80;
server_name example.org www.example.org;
#...
}
location /some/path/ {
proxy_pass http://bookinfo:9080/;
}
While the Gateway needs to use VirtualService to specify where the traffic should be forwarded and can further filter based on the ingress address.
spec:
hosts:
- "www.example.org"
gateways:
# Bind to Gateway
- mygateway
http:
route:
- destination:
host: bookinfo
port:
number: 9080
To summarize, Istio's approach is to have the Gateway monitor ingress traffic, define the traffic entry strategy through VirtualService, and point to the Service. The DestinationRule then defines the strategy for traffic flowing to the Pods.
Deploying Services
Here, we will use the httpbin service as an example to explain how to configure external access to the httpbin service step-by-step.
First, deploy an httpbin service, which is quite simple and includes a Service and a Deployment.
httpbin.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: httpbin
---
apiVersion: v1
kind: Service
metadata:
name: httpbin
labels:
app: httpbin
service: httpbin
spec:
ports:
- name: http
port: 8000
targetPort: 80
selector:
app: httpbin
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin
spec:
replicas: 1
selector:
matchLabels:
app: httpbin
version: v1
template:
metadata:
labels:
app: httpbin
version: v1
spec:
serviceAccountName: httpbin
containers:
- image: docker.io/kennethreitz/httpbin
imagePullPolicy: IfNotPresent
name: httpbin
ports:
- containerPort: 80
kubectl -n bookinfo apply -f httpbin.yaml
Configure Gateway
Next, create a Gateway that specifies which ingress traffic to listen for.
httpbin_gw.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: httpbin-gateway
spec:
selector:
istio: ingressgateway # use Istio default gateway implementation
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "httpbin.s1.whuanle.cn"
- "*"
This step helps everyone understand the Gateway more intuitively through the domain name. You can modify
httpbin.s1.whuanle.cn
to your own domain.Then, on your computer, open
C:\Windows\System32\drivers\etc\hosts
and add a record to point the IP to your server.
kubectl -n bookinfo apply -f httpbin_gw.yaml
Now, we have configured istio-ingressgateway to monitor the address httpbin.s1.whuanle.cn. If anyone accesses httpbin.s1.whuanle.cn, the traffic will flow into httpbin-gateway.
Next, we will configure the service address for the Gateway and specify the allowed suffix for external access.
Configure VirtualService:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin
spec:
hosts:
- "*"
gateways:
- httpbin-gateway
http:
- match:
- uri:
prefix: /status
- uri:
prefix: /delay
route:
- destination:
port:
number: 8000
host: httpbin
When both Gateway and VirtualService only have one port, port binding is not necessary.
kubectl -n bookinfo apply -f httpbin_vs.yaml
Find the port exposed by istio-ingressgateway.
kubectl get svc istio-ingressgateway -n istio-system
httpbin is an HTTP testing program, and we can retrieve the corresponding HTTP request status using /status/{status_code}
.
For example:
If we do not want this service to be accessible externally, we can first remove /status
.
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin
spec:
hosts:
- "*"
gateways:
- httpbin-gateway
http:
- match:
- uri:
prefix: /delay
route:
- destination:
port:
number: 8000
host: httpbin
EOF
At this point, you will not be able to access the status
path; however, you can still access the /delay
path.
The /delay
path of httpbin is used to test the delay of HTTP request responses, and /delay/{seconds}
specifies how long the server will wait before returning a response.
For example, http://192.168.3.150:32309/delay/5
will respond after 5 seconds.
httpbin has many routing interfaces, and we can configure which paths to allow through VirtualService.
If you need to allow everything, you can use:
kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin
spec:
hosts:
- "*"
gateways:
- httpbin-gateway
http:
- match:
- uri:
prefix: /
route:
- destination:
port:
number: 8000
host: httpbin
subset: v1
EOF
Subversion
In Chapter 4, during routing experiments with versions, traffic can be directed to different versions.
kubectl -n bookinfo apply -f - <<EOF
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: httpbin
spec:
host: httpbin
subsets:
- name: v1
labels:
version: v1
EOF
First, we direct the DestinationRule to a Service:
host: httpbin
Of course, we can also write it as:
host: httpbin.bookinfo.svc.cluster.local
Through the host, we can identify the corresponding Kubernetes Service and obtain the list of all Pods from the Service's corresponding Endpoints.
By obtaining all Pods from the Endpoints, we can check the description of each Pod. When a request arrives, a suitable Pod is chosen based on the label selector in the DestinationRule.
- name: v1
labels:
version: v1
istio-egressgateway
istio-egressgateway is also a component in Istio that needs to be installed separately. The command to install istio-egressgateway is:
helm install istio-egressgateway istio/gateway -n istio-system
In a cluster, if application A accesses an address that belongs to other applications within the cluster, Istio can inject various behaviors into these requests to achieve load balancing and circuit breaking. However, if the application within the cluster needs to access an external service, such as aaa.com, how can we implement load balancing and circuit breaking for these requests?
Istio ServiceEntry is a resource that allows external services (i.e., services not in the Istio service mesh) to be incorporated into the Istio service mesh. By adding external services to the mesh, we can use Istio's traffic management and policy functionalities to control interactions with these external services.
Here is an example of a ServiceEntry that adds an external HTTP service www.google.com
to the Istio service mesh:
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: google
spec:
hosts:
- www.google.com
addresses:
- 192.168.1.1
ports:
- number: 80
name: http
protocol: HTTP
location: MESH_EXTERNAL
resolution: DNS
endpoints:
- address: "www.google.com"
ports:
http: 80
locality: "us-west1/zone1"
exportTo:
- "*"
In this example, we create a ServiceEntry resource named httpbin-ext
. The specified host is httpbin.org
, with a port of 80 and HTTP protocol. Additionally, we set resolution
to DNS
and location
to MESH_EXTERNAL
, indicating that the service is outside the mesh.
To apply this ServiceEntry to the cluster, save it to a YAML file (e.g., httpbin-ext.yaml
) and run the following command:
kubectl apply -f httpbin-ext.yaml
Now, when a service within the Istio service mesh accesses www.google.com
, it remains under the control of Istio's policies. For example, you can create a VirtualService for this ServiceEntry to apply traffic management rules or create a DestinationRule for configuring load balancing and connection pool settings.
spec
: Contains the specific configuration objects of the ServiceEntry.
hosts
: A list of fully qualified domain names (FQDN) of the external services to be imported. For example:["httpbin.org"]
.addresses
: (Optional) A list of virtual IP addresses associated with the external services. For example:["192.168.1.1"]
.ports
: A list describing the ports used by the external service. Each port has the following attributes:number
: Port number, for example: 80.name
: Name of the port, e.g.,http
.protocol
: The protocol used, e.g.,HTTP
,TCP
,HTTPS
, etc.
location
: The location of the service. Can beMESH_EXTERNAL
(indicating the service is outside the mesh) orMESH_INTERNAL
(indicating the service is inside the mesh but not part of any known service).resolution
: The method used to determine service instance addresses. It can beNONE
(default, indicating no address resolution),STATIC
(indicating the use of IP addresses from theaddresses
field),DNS
(indicating DNS resolution of the hostname), orMESH_EXTERNAL
.endpoints
: (Optional) A list of endpoints for the external service. Each endpoint has the following attributes:address
: The IP address or hostname of the endpoint.ports
: A mapping containing the port name and port number, for example:{"http": 8080}
.labels
: (Optional) Labels applied to the endpoint.locality
: (Optional) Geographic location of the endpoint, e.g.,us-west1/zone1
.
exportTo
: (Optional) A list containing namespace names that specify which namespaces can access this ServiceEntry.
. You can use an asterisk (*
) to represent all namespaces. The default value is *
.
subjectAltNames
: (optional) A list used to validate the server certificate's Subject Alternative Names (SANs).
Readers can learn more from the official documentation:
https://istio.io/latest/en/docs/tasks/traffic-management/egress/egress-control/
文章评论