Virtual Machines in Multi-Network Meshes

This example provides instructions to integrate a VM or a bare metal host into a multi-network Istio mesh deployed on Kubernetes using gateways. This approach doesn’t require VPN connectivity or direct network access between the VM, the bare metal and the clusters.

Prerequisites

  • One or more Kubernetes clusters with versions: 1.16, 1.17, 1.18.

  • Virtual machines (VMs) must have IP connectivity to the Ingress gateways in the mesh.

  • Services in the cluster must be accessible through the Ingress gateway.

Installation steps

Preparing the Kubernetes cluster for VMs

The first step when adding non-Kubernetes services to an Istio mesh is to configure the Istio installation itself, and generate the configuration files that let VMs connect to the mesh. Prepare the cluster for the VM with the following commands on a machine with cluster admin privileges:

  1. Create a Kubernetes secret for your generated CA certificates using a command similar to the following. See Certificate Authority (CA) certificates for more details.

    The root and intermediate certificate from the samples directory are widely distributed and known. Do NOT use these certificates in production as your clusters would then be open to security vulnerabilities and compromise.

    ZipZipZipZip

    $ kubectl create namespace istio-system $ kubectl create secret generic cacerts -n istio-system \ --from-file=@samples/certs/ca-cert.pem@ \ --from-file=@samples/certs/ca-key.pem@ \ --from-file=@samples/certs/root-cert.pem@ \ --from-file=@samples/certs/cert-chain.pem@

  2. For a simple setup, deploy Istio control plane into the cluster

    ` ``` $ istioctl install \

    1. -f manifests/examples/vm/values-istio-meshexpansion.yaml

    ``

    For further details and customization options, refer to the installation instructions.

Setting up the VM

Next, run the following commands on each machine that you want to add to the mesh:

  1. Copy the previously created cluster.env and *.pem files to the VM. For example:

    $ export GCE_NAME="your-gce-instance" $ gcloud compute scp --project=${MY_PROJECT} --zone=${MY_ZONE} {key.pem,cert-chain.pem,cluster.env,root-cert.pem} ${GCE_NAME}:~

  2. Install the Debian package with the Envoy sidecar.

    $ gcloud compute ssh --project=${MY_PROJECT} --zone=${MY_ZONE} "${GCE_NAME}" $ curl -L https://storage.googleapis.com/istio-release/releases/1.7.0/deb/istio-sidecar.deb > istio-sidecar.deb $ sudo dpkg -i istio-sidecar.deb

  3. Add the IP address of Istio gateway to /etc/hosts. Revisit the preparing the cluster section to learn how to obtain the IP address. The following example updates the /etc/hosts file with the Istiod address:

    $ echo "${GWIP} istiod.istio-system.svc" | sudo tee -a /etc/hosts

A better options is to configure the DNS resolver of the VM to resolve the address, using a split-DNS server. Using /etc/hosts is an easy to use example. It is also possible to use a real DNS and certificate for Istiod, this is beyond the scope of this document.

  1. Install root-cert.pem, key.pem and cert-chain.pem under /etc/certs/.

    $ sudo mkdir -p /etc/certs $ sudo cp {root-cert.pem,cert-chain.pem,key.pem} /etc/certs

  2. Install root-cert.pem under /var/run/secrets/istio/.

  3. Install cluster.env under /var/lib/istio/envoy/.

    $ sudo cp cluster.env /var/lib/istio/envoy

  4. Transfer ownership of the files in /etc/certs/ , /var/lib/istio/envoy/ and /var/run/secrets/istio/to the Istio proxy.

    $ sudo chown -R istio-proxy /etc/certs /var/lib/istio/envoy /var/run/secrets/istio/

  5. Start Istio using systemctl.

    $ sudo systemctl start istio

Send requests from VM workloads to Kubernetes services

After setup, the machine can access services running in the Kubernetes cluster or on other VMs.

The following example shows accessing a service running in the Kubernetes cluster from a VM using /etc/hosts/, in this case using a service from the Bookinfo example.

  1. Connect to the cluster service from VM as in the example below:

    $ curl -v ${GWIP}/productpage < HTTP/1.1 200 OK < content-type: text/html; charset=utf-8 < content-length: 1836 < server: istio-envoy ... html content ...

The server: istio-envoy header indicates that the sidecar intercepted the traffic.

Running services on the added VM

  1. Setup an HTTP server on the VM instance to serve HTTP traffic on port 8080:

    $ gcloud compute ssh ${GCE_NAME} $ python -m SimpleHTTPServer 8080

  2. Determine the VM instance’s IP address. For example, find the IP address of the GCE instance with the following commands:

    $ export GCE_IP=$(gcloud --format="value(networkInterfaces[0].networkIP)" compute instances describe ${GCE_NAME}) $ echo ${GCE_IP}

  3. Add VM services to the mesh

    $ istioctl experimental add-to-mesh external-service vmhttp ${VM_IP} http:8080 -n ${SERVICE_NAMESPACE}

    Ensure you have added the istioctl client to your path, as described in the download page.

  4. Deploy a pod running the sleep service in the Kubernetes cluster, and wait until it is ready:

    Zip

    $ kubectl apply -f @samples/sleep/sleep.yaml@ $ kubectl get pod NAME READY STATUS RESTARTS AGE sleep-88ddbcfdd-rm42k 2/2 Running 0 1s ...

  5. Send a request from the sleep service on the pod to the VM’s HTTP service:

    $ kubectl exec -it sleep-88ddbcfdd-rm42k -c sleep -- curl vmhttp.${SERVICE_NAMESPACE}.svc.cluster.local:8080

    You should see something similar to the output below.

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"><html> <title>Directory listing for /</title> <body> <h2>Directory listing for /</h2> <hr> <ul> <li><a href=".bashrc">.bashrc</a></li> <li><a href=".ssh/">.ssh/</a></li> ... </body>

Congratulations! You successfully configured a service running in a pod within the cluster to send traffic to a service running on a VM outside of the cluster and tested that the configuration worked.

Cleanup

Run the following commands to remove the expansion VM from the mesh’s abstract model.

$ istioctl experimental remove-from-mesh -n ${SERVICE_NAMESPACE} vmhttp Kubernetes Service "vmhttp.vm" has been deleted for external service "vmhttp" Service Entry "mesh-expansion-vmhttp" has been deleted for external service "vmhttp"

See also

Virtual Machine Installation

Deploy Istio and connect a workload running within a virtual machine to it.

Bookinfo with a Virtual Machine

Run the Bookinfo application with a MySQL service running on a virtual machine within your mesh.

Virtual Machines in Single-Network Meshes

Learn how to add a service running on a virtual machine to your single network Istio mesh.

DNS Certificate Management

Provision and manage DNS certificates in Istio.

Secure Webhook Management

A more secure way to manage Istio webhooks.

Demystifying Istio’s Sidecar Injection Model

De-mystify how Istio manages to plugin its data-plane components into an existing deployment.