Publishing applications using Istio
Application publishing with Istio is configured in two layers. The cluster administrator deploys the IngressIstioController (and related infrastructure) as described in “Istio Ingress Gateway”. Application developers create Gateway and VirtualService resources as shown below.
When deploying an application using Istio, choose one of the following options: “Publishing applications using Ingress NGINX” or “Publishing applications using Istio Ingress Gateway resource”.
Publishing applications using Ingress NGINX
To publish an application using Ingress NGINX, the cluster administrator must configure the Ingress controller by adding an Istio sidecar to it.
To publish an application, prepare an Ingress resource that references a Service. Set ingressClassName to the controller with the Istio sidecar (the administrator provides the value). Required annotations for the Ingress resource:
nginx.ingress.kubernetes.io/service-upstream: "true": With this annotation, the Ingress controller will send requests to the Service’s ClusterIP (from the Service CIDR range) instead of sending them directly to the application’s Pods. Theistio-proxysidecar container intercepts traffic only toward the Service CIDR range. All other requests are sent directly.nginx.ingress.kubernetes.io/upstream-vhost: productpage.bookinfo.svc: With this annotation, the sidecar can identify the application service the request is intended for.
Examples:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: productpage
namespace: bookinfo
annotations:
# Enables proxying traffic to the Service's ClusterIP via nginx instead of directly to Pod IPs.
nginx.ingress.kubernetes.io/service-upstream: "true"
# In Istio, all routing is based on the `Host:` request header.
# This avoids the need to inform Istio about the existence of the external domain `productpage.example.com`;
# the internal domain known to Istio is used instead.
nginx.ingress.kubernetes.io/upstream-vhost: productpage.bookinfo.svc
spec:
ingressClassName: nginx # IngressClass name of the controller with the Istio sidecar.
rules:
- host: productpage.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: productpage
port:
number: 9080
apiVersion: v1
kind: Service
metadata:
name: productpage
namespace: bookinfo
spec:
ports:
- name: http
port: 9080
selector:
app: productpage
type: ClusterIP
Publishing applications using Istio Ingress Gateway resource
To publish an application using the Istio Ingress Gateway, the cluster administrator must create an IngressIstioController resource.
To publish an application using the Istio Ingress Gateway resource, create a Gateway. In spec.selector, specify the label that references ingressGatewayClass and the Secret name provided by the cluster administrator:
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: gateway-app
namespace: app-ns
spec:
selector:
# Value of ingressGatewayClass provided by the cluster administrator.
istio.deckhouse.io/ingress-gateway-class: istio-hp
servers:
- port:
# Standard template for using the HTTP protocol.
number: 80
name: http
protocol: HTTP
hosts:
- app.example.com
- port:
# Standard template for using the HTTPS protocol.
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
# Secret with the certificate and key created by the administrator in the d8-ingress-istio namespace.
# Supported Secret formats: https://istio.io/latest/docs/tasks/traffic-management/ingress/secure-ingress/#key-formats.
credentialName: app-tls-secret
hosts:
- app.example.com
Then define routing rules with a VirtualService that links the Gateway to the service it serves:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: vs-app
namespace: app-ns
spec:
gateways:
- gateway-app # Name of the Gateway resource created above.
hosts:
- app.example.com
http:
- route:
- destination:
host: app-svc # Name of the service that should receive traffic.
Canary deployment with VirtualService
For a general overview of canary in Deckhouse Platform (DP), see “Canary deployment”. The example below uses VirtualService and DestinationRule.
To shift traffic gradually between application versions, use a DestinationRule with subsets and weights in the VirtualService. The example below sends 90% of traffic to the stable version and 10% to canary:
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: app-svc
namespace: app-ns
spec:
host: app-svc
subsets:
- name: stable
labels:
version: v1
- name: canary
labels:
version: v2
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: vs-app
namespace: app-ns
spec:
gateways:
- gateway-app
hosts:
- app.example.com
http:
- route:
- destination:
host: app-svc
subset: stable
weight: 90
- destination:
host: app-svc
subset: canary
weight: 10
Pods of each version must have the version: v1 and version: v2 labels that match the DestinationRule subsets. Before changing weights, confirm that both versions are selected by the app-svc Service.
After you apply the manifests, send a few requests to app.example.com and check that traffic is split roughly 90/10. To identify which version responded, use whatever the application itself exposes to distinguish stable from canary — for example, a value in the response body or a dedicated HTTP header:
for i in $(seq 1 20); do curl -s https://app.example.com/ | grep version; done \
| sort | uniq -c
Adjust the weights if needed and recheck.