Skip to main content
Version: main 🚧

Istio

Enterprise-Only Feature

This feature is an Enterprise feature. See our pricing plans or contact our sales team for more information.

Istio integration

This guide shows how to set up Istio integration with your virtual cluster. This enables you to use one Istio installation from the host cluster instead of installing Istio in each virtual cluster.

This integration creates a Gateway per virtual cluster, which results in Waypoint proxy deployed in the virtual cluster host namespace.

You can include your virtual workloads in the mesh by setting istio.io/dataplane-mode=ambient label on the virtual Namespaces or Pods. You can exclude your virtual workloads from the mesh by setting istio.io/dataplane-mode=none label either on the Namespace or on the Pod.

Prerequisites​

  • Administrator access to a Kubernetes cluster: See Accessing Clusters with kubectl for more information. Your current kube-context must have administrative privileges, which you can verify with kubectl auth can-i create clusterrole -A

    info

    To obtain a kube-context with admin access, ensure you have the necessary credentials and permissions for your Kubernetes cluster. This typically involves using kubectl config commands or authenticating through your cloud provider's CLI tools.

  • helm installed: Helm v3.10 is required for deploying the platform. Refer to the Helm Installation Guide if you need to install it.

  • kubectl installed: Kubernetes command-line tool for interacting with the cluster. See Install and Set Up kubectl for installation instructions.

  • istio operator installed on your host cluster in ambient mode with DNS Capture disabled
  • Gateway (gateway.networking.k8s.io/v1) Custom Resource Definition installed on your host cluster
tip

To disable DNS capture, set values.cni.ambient.dnsCapture: false in your Istio configuration.

IMPORTANT

This integration works only with Istio in Ambient mode. Sidecar mode is not supported.

Enable the integration​

Enable the Istio integration in your virtual cluster configuration:

Enable istio integration
integrations:
istio:
enabled: true

This configuration:

  • Enables the integration.
  • Installs Resource Definitions for DestinationRules, Gateways and VirtualServices into the virtual cluster.
  • Creates Gateway (gateway.networking.k8s.io/v1) for Waypoint in the virtual cluster host namespace.
  • Exports DestinationRules, Gateways and VirtualServices from the virtual cluster to the host (and re-writes) service references to the services translated names in the host.
  • Adds istio.io/dataplane-mode label to the synced Pods based on the value of this label set in the virtual namespace.
IMPORTANT

Only DestinationRules, Gateways, and VirtualServices are synced to the host clusters. Other kinds are not yet supported.

Set up cluster contexts​

Setting up the host and virtual cluster contexts makes it easier to switch between them.

export HOST_CTX="your-host-context"
export VCLUSTER_CTX="vcluster-ctx"
export VCLUSTER_HOST_NAMESPACE="vcluster"
tip

You can find your contexts by running kubectl config get-contexts

Route request based on the version label of the app​

    Create virtual namespace with ambient mode enabled​

  1. First, you create test namespace:

    Create test namespace
    kubectl --context="${VCLUSTER_CTX}" create namespace test

    and label it with istio.io/dataplane-mode: ambient:

    Label test namespace
    kubectl --context="${VCLUSTER_CTX}" label namespace test istio.io/dataplane-mode=ambient
  2. Create two versions of your app​

  3. Next, you create 3 deployments: two of them are nginx server and the third one is to curl the other two.

    Create nginx deployments that will respond with different response body based on what's in the respective ConfigMaps:

    configmap1.yaml
    apiVersion: v1
    kind: ConfigMap
    metadata:
    name: nginx-configmap-v1
    namespace: test
    data:
    index.html: |
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx v1!</title>
    </head>
    <body>
    <h1>Hello from Nginx Version 1!</h1>
    </body>
    </html>
    deployment1.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: nginx-deployment-v1
    namespace: test
    labels:
    app: nginx
    version: v1
    spec:
    replicas: 1
    selector:
    matchLabels:
    app: nginx
    version: v1
    template:
    metadata:
    labels:
    app: nginx
    version: v1
    spec:
    containers:
    - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80
    volumeMounts:
    - name: nginx-index-v1
    mountPath: /usr/share/nginx/html/index.html
    subPath: index.html
    volumes:
    - name: nginx-index-v1
    configMap:
    name: nginx-configmap-v1
    Create v1 config map
    kubectl --context="${VCLUSTER_CTX}" create -f configmap1.yaml --namespace test
    Create v1 deployment
    kubectl --context="${VCLUSTER_CTX}" create -f deployment1.yaml --namespace test

    make sure that this nginx app is up and running:

    Wait for v1 pods
    kubectl --context="${VCLUSTER_CTX}" wait --for=condition=ready pod -l app=nginx --namespace test --timeout=300s

    then, create another nginx deployment that will respond with different body:

    configmap2.yaml
    apiVersion: v1
    kind: ConfigMap
    metadata:
    name: nginx-configmap-v2
    namespace: test
    data:
    index.html: |
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx v2!</title>
    </head>
    <body>
    <h1>Hello from Nginx Version 2!</h1>
    </body>
    </html>
    deployment2.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: nginx-deployment-v2
    namespace: test
    labels:
    app: nginx
    version: v2
    spec:
    replicas: 1
    selector:
    matchLabels:
    app: nginx
    version: v2
    template:
    metadata:
    labels:
    app: nginx
    version: v2
    spec:
    containers:
    - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80
    volumeMounts:
    - name: nginx-index-v2
    mountPath: /usr/share/nginx/html/index.html
    subPath: index.html
    volumes:
    - name: nginx-index-v2
    configMap:
    name: nginx-configmap-v2
    Create v2 config map
    kubectl --context="${VCLUSTER_CTX}" create -f configmap2.yaml --namespace test
    Create v2 deployment
    kubectl --context="${VCLUSTER_CTX}" create -f deployment2.yaml --namespace test

    make sure that this nginx app is up and running:

    Wait for v2 pods
    kubectl --context="${VCLUSTER_CTX}" wait --for=condition=ready pod -l app=nginx --namespace test --timeout=300s

    and create a Service that will match pods from both deployments:

    service.yaml
    apiVersion: v1
    kind: Service
    metadata:
    name: nginx-service
    namespace: test
    labels:
    app: nginx
    istio.io/use-waypoint: "waypoint"
    spec:
    ports:
    - port: 80
    targetPort: 80
    selector:
    app: nginx

    pay attention to the istio.io/use-waypoint: waypoint label. It is crucial, as it will tell Istio that we want to use proxy named waypoint in the same namespace (it is deployed automatically by vCluster to the vCluster host namespace).

    Create service
    kubectl --context="${VCLUSTER_CTX}" create -f service.yaml --namespace test

    last, but not least, you deploy a pod that you will use to curl the other two:

    client_deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: client
    namespace: test
    labels:
    app: client
    spec:
    replicas: 1
    selector:
    matchLabels:
    app: client
    template:
    metadata:
    labels:
    app: client
    spec:
    containers:
    - name: nginx
    image: nginx:latest
    ports:
    - containerPort: 80
    Create client deployment
    kubectl --context="${VCLUSTER_CTX}" create -f client_deployment.yaml --namespace test
  4. Configure your desired traffic routing using DestinationRule and VirtualService​

  5. Now, your can create DestinationRules and VirtualService in the virtual cluster.

    You create a pair that will route our request based on the request path:

    1. Requesting /v2 endpoint should route our request to pods with version=v2 label
    2. All other requests will be routed to version=v1 pods.

    Save this DestinationRule and VirtualService definition and apply it in the virtual cluster:

    destination_rule.yaml
    apiVersion: networking.istio.io/v1
    kind: DestinationRule
    metadata:
    name: nginx-destination
    namespace: test
    spec:
    host: nginx-service.test.svc.cluster.local # vCluster will translate it to the host service automatically
    subsets:
    - name: v1
    labels:
    version: v1
    - name: v2
    labels:
    version: v2
    virtual_service.yaml
    apiVersion: networking.istio.io/v1
    kind: VirtualService
    metadata:
    name: nginx-service
    namespace: test
    spec:
    hosts:
    - nginx-service.test.svc.cluster.local # vCluster will translate it to the host service automatically
    http:
    - name: "nginx-v2"
    match:
    - uri:
    prefix: "/v2"
    rewrite:
    uri: "/"
    route:
    - destination:
    host: nginx-service.test.svc.cluster.local # vCluster will translate it to the host service automatically
    subset: v2
    - name: "nginx-v1"
    route:
    - destination:
    host: nginx-service.test.svc.cluster.local # vCluster will translate it to the host service automatically
    subset: v1

    then, create it in the virtual cluster:

    Create destination rule
    kubectl --context="${VCLUSTER_CTX}" create -f destination_rule.yaml
    Create virtual service
    kubectl --context="${VCLUSTER_CTX}" create -f virtual_service.yaml
  6. Verify that DestinationRule and VirtualService is synced to host cluster​

  7. Check destination rule in the host cluster
    kubectl --context="${HOST_CTX}" get destinationrules --namespace "${VCLUSTER_HOST_NAMESPACE}"
    Check virtual service in the host cluster
    kubectl --context="${HOST_CTX}" get virtualservices --namespace "${VCLUSTER_HOST_NAMESPACE}"

    you should see DestinationRule named nginx-destination-x-test-x-vcluster and VirtualService named nginx-service-x-test-x-vcluster

  8. Test traffic routing​

  9. Now, you can exec into the client pod, and check if you get a response containing "Hello from Nginx Version 2!" or "Hello from Nginx Version 1!" depending on request path:

    Query version 2
    kubectl --context="${VCLUSTER_CTX}" exec -it -n test deploy/client -- curl nginx-service/v2
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx v2!</title>
    </head>
    <body>
    <h1>Hello from Nginx Version 2!</h1>
    </body>
    </html>
    Query version 1
    kubectl --context="${VCLUSTER_CTX}" exec -it -n test deploy/client -- curl nginx-service
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx v1!</title>
    </head>
    <body>
    <h1>Hello from Nginx Version 1!</h1>
    </body>
    </html>

    seeing the same output means that request was intercepted by Istio and routed as we specified in the DestinationRule and VirtualService.

  10. Summary​

  11. Istio integration enables you to re-use one Istio instance from the host cluster for multiple virtual clusters. Virtual Cluster users can define their own Gateways, DestinationRules and VirtualServices without interfering with each other.

Config reference​

istio required object pro​

Istio syncs DestinationRules, Gateways and VirtualServices from virtual cluster to the host.

enabled required boolean false pro​

Enabled defines if this option should be enabled.

sync required object pro​

toHost required object pro​

destinationRules required object pro​
enabled required boolean true pro​

Enabled defines if this option should be enabled.

gateways required object pro​
enabled required boolean true pro​

Enabled defines if this option should be enabled.

virtualServices required object pro​
enabled required boolean true pro​

Enabled defines if this option should be enabled.