Add a virtual machine to the mesh

This guide shows you how to manually add a virtual machine to a workload, using the analytics-v1 workload of the Service Mesh Manager demo application as an example.

If you already understand the procedure and want to configure your virtual machine to be automatically added to the mesh, see Autoscaling VM groups.

Prerequisites

  • You already have a virtual machine available.
  • You have root access to the virtual machine.
  • You have completed the Prerequisites.
  • If you are using the different network approach make sure to set up your firewall.
  • If you want to exactly replicate the steps of this guide for testing purposes, install the Service Mesh Manager demo application on your cluster, and the jq tool on your computer.

If you are performing this procedure on a clean installation of the Service Mesh Manager demo application, the topology view of the smm-demo namespace should look similar to this:

Topology of the demo application running on a single cluster

Scale down the analytics service

Note: If you are not using the demo application to test VM integration, skip this step. You can install the demo application on your Service Mesh Manager cluster by running smm demoapp install

This step and the examples in other steps of this guide rely on the analytics-v1 workload of the Service Mesh Manager demo application.

  1. Scale it down to have zero replicas:

    kubectl scale deploy -n smm-demo analytics-v1 --replicas=0
    
  2. Verify that there are no pods belonging to the analytics deployment. The following command should return an empty response:

    kubectl get pods -n smm-demo | grep analytics
    

Add an external workload to the mesh

The attached machines will behave as Kubernetes workloads. This means that it will have a set of labels assigned that could be used by Services to match the machine. All Kubernetes Pods have a service account assigned (usually the default one in the namespace if not specified otherwise). The machine uses this service account to authenticate to the Istio control plane.

To add an external workload to the mesh, create a WorkloadGroup in the namespace where the machine will be attached to. This object represents a group of machines serving the same service. This is analogous to the Kubernetes concept of a Deployment.

For example, to add a virtual machine serving the analytics traffic in the demo application, use the following object:

apiVersion: networking.istio.io/v1alpha3
kind: WorkloadGroup
metadata:
  labels:
    app: analytics
    version: v0
  name: analytics-v0
  namespace: smm-demo
spec:
  metadata:
    labels:
      app: analytics
      version: v0
  probe:
    httpGet:
      path: /
      host: 127.0.0.1
      port: 8080
      scheme: HTTP
  template:
    network: vm-network-1
    ports:
      http: 8080
      grpc: 8082
      tcp: 8083
    serviceAccount: default

For details on these settings, see Exposing the Dashboard.

mTLS settings (optional)

After Istio is started on the virtual machine, Istio takes over the service ports defined in the WorkloadGroup resource. Depending on your settings, it will also start enforcing mTLS on those service ports.

If external (non-mesh) services communicate with the virtual machine, ensure that communication without encryption is permitted on the service ports. To do so, create a PeerAuthentication object in the smm-demo namespace. Make sure that the matchLabels selector only matches the WorkloadGroup, and not any other Kubernetes deployment, to avoid permitting unencrypted communication where it’s not needed. In the following example, the matchLabels selector includes both the app and the version labels.

apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: analytics
  namespace: smm-demo
spec:
  mtls:
    mode: PERMISSIVE
  selector:
    matchLabels:
      app: analytics
      version: v0

We recommend setting the mTLS mode to PERMISSIVE as it allows unencrypted traffic. The in-mesh traffic will use mTLS.

Note: In case of any compatibility issues, you can set the mode to DISABLE, but it this case all traffic will be un-encrypted.

Set up the virtual machine

Required packages on the virtual machines

In addition to the OS package dependencies prerequisites, this example requires python3. To install the python3 package, run the following command:

  • On Ubuntu:

    apt-get update && apt-get install -y python3
    
  • On RHEL:

    yum install -y python3
    

Executing the Example VM-based Service Workload

Before you can register the virtual machine, the workload must already be running on the VM. The following instructions start an example HTTP server workload on the virtual machine.

In the example using the demo application, open a terminal on the machine (for example, using SSH), and start a simple web server serving files from the empty-dir (the demo application requires only the availability of http://<pod-id>:8080/**).

Note: The nohup shell command keeps python3 and http.server running when the shell is logged out.

mkdir -p empty-dir
cd empty-dir
nohup python3 -m http.server 8080 &

Collect the required data

To attach the VM to the mesh, you’ll need the following information:

  • The URL of the dashboard
  • The namespace and name of the WorkloadGroup (smm-demo.analytics-v1 in the example)
  • The bearer token of the service account referenced in the .spec.template.serviceAccount of the WorkloadGroup
  • (Optional) The IP address that the clusters in the service mesh can use to access the VM. If this is the same as the IP the public internet sees for the VM, then Service Mesh Manager detects the VM’s IP automatically.

To acquire the bearer token of the ServiceAccount, complete the following steps.

  1. On Kubernetes 1.24 and newer, the token secrets for service accounts are not created automatically. Create the token manually. For details, see the Kubernetes documentation.

  2. Download and run the following script. This script fetches the bearer token for the service account in namespace SA_NAMESPACE with the name of SA_SERVICEACCOUNT and saves it into the ~/bearer-token file.

    
    

    Note: If you are running the script on a OpenShift ROSA cluster, at line 13 in the script, please replace the ‘jq’ output string with '.items[1].data.token | @base64d'

Prepare the virtual machine

To prepare the virtual machine to be attached to the mesh, complete the following steps.

  1. Open a terminal (for example, SSH) to the virtual machine.

  2. Install smm-agent on the virtual machine. The agent ensures that the machine’s Istio configuration is always up-to-date. Run the following command as the root user:

    curl http://<dashboard-url>/get/smm-agent | bash
    

    The output should be similar to:

    % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                    Dload  Upload   Total   Spent    Left  Speed
    100  1883  100  1883    0     0  13744      0 --:--:-- --:--:-- --:--:-- 13744
    Detecting host properties:
    - OS: linux
    - CPU: amd64
    - Packager: deb
    - SMM Base URL: http://a6bc8072e26154e5c9084e0d7f5a9c92-2016650592.eu-north-1.elb.amazonaws.com
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                    Dload  Upload   Total   Spent    Left  Speed
    100 20.3M    0 20.3M    0     0  22.2M      0 --:--:-- --:--:-- --:--:-- 22.2M
    Selecting previously unselected package smm-agent.
    (Reading database ... 63895 files and directories currently installed.)
    Preparing to unpack /tmp/smm-agent-package ...
    Unpacking smm-agent (1.9.1~snapshot.202203311042-SNAPSHOT-ab2e8684a) ...
    Setting up smm-agent (1.9.1~snapshot.202203311042-SNAPSHOT-ab2e8684a) ...
    Created symlink /etc/systemd/system/multi-user.target.wants/smm-agent.service → /lib/systemd/system/smm-agent.service.
    ✓ dashboard url set url=<dashboard-url>
    
  3. Specify which WorkloadGroup and namespace you want to attach the machine to by running the following command:

    smm-agent set workload-group <namespace> <workloadgroup>
    

    For example:

    smm-agent set workload-group smm-demo analytics-v0
    

    The output should be similar to:

    ✓ target workload group set namespace=smm-demo, name=analytics-v0
    
  4. Specify the bearer token you have acquired in a previous step (replace <token> with the actual token, not the filename):

    smm-agent set bearer-token <token>
    

    The output should be similar to:

    ✓ bearer token set
    
  5. (Optional) Set the IP address the service mesh should use to access the VM.

    smm-agent set node-ip <VM's IP>
    

    The output should be similar to:

    ✓ node-ip is set ip=<VM's IP>
    
  6. Validate the configuration of smm-agent by running the following command. If the configuration is invalid an error is shown.

    smm-agent show-config
    

    The output should be similar to:

    ✓ dashboard url=http://a6bc8072e26154e5c9084e0d7f5a9c92-2016650592.eu-north-1.elb.amazonaws.com
    ✓ target workload-group namespace=smm-demo, name=analytics-v0
    ✓ no additional labels set
    ✓ bearer token set
    ✓ node-ip is set
    ✓ configuration is valid
    

Attach the virtual machine to the mesh

Now that you have started the workload (HTTP server) and configured smm-agent, you can attach the VM to the mesh. To do so, run a reconciliation on this host. This step will:

  • configure and start Istio, so the virtual machine becomes part of the mesh
  • ensure that the cluster configuration is properly set
  • start smm-agent in the background so that the system is always up-to-date

Run the following command:

smm-agent reconcile

The output should be similar to:

✓ reconciling host operating system
✓ configuration loaded config=/etc/smm/agent.yaml
✓ install-pilot-agent ❯ downloading and installing OS package component=pilot-agent, platform={linux amd64 deb 0xc00000c168}
✓ install-pilot-agent ❯ downloader reconciles with exponential backoff downloader={pilot-agent {linux amd64 deb 0xc00000c168} true  0xc0002725b0}
...
✓ systemd-ensure-smm-agent-running/systemctl ❯ starting service args=[smm-agent]
✓ systemd-ensure-smm-agent-running/systemctl/start ❯ executing command command=systemctl, args=[start smm-agent], timeout=5m0s
✓ systemd-ensure-smm-agent-running/systemctl/start ❯ command executed successfully command=systemctl, args=[start smm-agent], stdout=, stderr=
✓ changes were made to the host operating system
✓ reconciled host operating system

Verify connectivity

If the attachment was successful, a new WorkloadEntry has been created for the new node in the namespace of the WorkloadGroup (if you followed the examples, in the smm-demo namespace). Verify it by completing the following steps.

  1. Check that the new WorkloadEntry exists:

    kubectl get workloadentries -n smm-demo
    

    The output should be similar to:

    NAME                                    AGE     ADDRESS
    analytics-v0-3.68.232.96-vm-network-1   2m40s   3.68.232.96
    
  2. Check the healthiness of the service:

    kubectl describe workloadentries analytics-v0-3.68.232.96-vm-network-1 -n smm-demo
    

    The output should be similar to:

    Name:         analytics-v0-3.68.232.96-vm-network-1
    Namespace:    smm-demo
    Labels:       app=analytics
    ...
    Status:
      Conditions:
        Last Probe Time:       2022-04-01T05:47:47.472143851Z
        Last Transition Time:  2022-04-01T05:47:47.472144917Z
        Status:                True
        Type:                  Healthy
    
    
  3. On the Service Mesh Manager dashboard, navigate to MENU > TOPOLOGY and verify that the VM is visible and that it is getting traffic. If you have performed this procedure on a clean installation of the Service Mesh Manager demo application, the difference on the topology view of the smm-demo namespace is that the analytics-v1 workload is now running on a virtual machine (indicated by the blue icon on the workload), and should look similar to this:

    Topology page with VMs