VM to Kubernetes migration

When migrating an existing workload to the mesh (and Kubernetes), you have to complete the following main steps:

  1. Add the virtual machine to the mesh, so the original workload that is running in the virtual machine is available in the mesh.
  2. Configure traffic shifting that will allow you to route traffic from the virtual machine to the Kubernetes workload.
  3. Add the Kubernetes workload that will replace the virtual machine.
  4. Shift traffic to Kubernetes gradually and test that the Kubernetes workload works properly, even under high load.
  5. Remove the virtual machine when you have successfully completed the migration.

Note: The configuration examples use the analytics-v1 workload of the demo application. Adjust them as needed for your environment.

Add the VM to the mesh

Complete the prerequisites and attach the virtual machine to the mesh as described in Add a virtual machine to the mesh.

Set up traffic shifting

The migration must be a controlled process, especially in case of a production system. This step ensures that the entire traffic goes to the virtual machine even when the Kubernetes workload is started. This method avoids service disruptions and allows you to test the Kubernetes workload, and transfer the traffic gradually. Otherwise, traffic would be split in round-robin fashion between the VM and the Pod.

For details on creating the routing rule, see Routing.

Make sure to set the weight of the routing rule corresponding to the virtual machine to 100.

traffic-shift traffic-shift

Alternatively, create and apply Kubernetes resources similar to the following:

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: analytics
  namespace: smm-demo
spec:
  host: analytics.smm-demo.svc.cluster.local
  subsets:
  - labels:
      version: v0
    name: v0
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: analytics-smm-demo-lmj7m
  namespace: smm-demo
spec:
  hosts:
  - analytics.smm-demo.svc.cluster.local
  http:
  - route:
    - destination:
        host: analytics.smm-demo.svc.cluster.local
        port:
          number: 8080
        subset: v0
      weight: 100

Add the Kubernetes workload

Now that you have guaranteed that the traffic will be still flowing to the virtual machine, you can deploy the new workload that is going to replace the virtual machine.

In this example we just upscale the analytics-v1 deployment (that was scaled down as part of Adding a VM to the mesh).

kubectl scale deploy -n smm-demo analytics-v1 --replicas=1

Wait until it’s up:

kubectl get pods -n smm-demo

The output should be similar to:

NAME                                READY   STATUS    RESTARTS   AGE
analytics-v1-7b96898ddc-9czpp       2/2     Running   0          18s
bombardier-66786577f7-tnjll         2/2     Running   0          18h
bookings-v1-7d8d76cd6b-68h6s        2/2     Running   0          18h
catalog-v1-5864c4b7d7-fvnqs         2/2     Running   0          18h
database-v1-65678c5dd6-lr2hh        2/2     Running   0          18h
frontpage-v1-776d76965-zbx67        2/2     Running   0          18h
movies-v1-6f7958c8c4-76ksk          2/2     Running   0          18h
movies-v2-568d4c4f4b-nrtkm          2/2     Running   0          18h
movies-v3-84b4887764-h2bzv          2/2     Running   0          18h
mysql-58458785-d4wx7                2/2     Running   0          18h
notifications-v1-544d6f77f7-jcdq6   2/2     Running   0          18h
payments-v1-7c955bccdd-l2czq        2/2     Running   0          18h
postgresql-75b94cdc9c-h6w64         2/2     Running   0          18h

Note: The workload will not show up on the topology view, as it does not receive any traffic yet.

For production systems, verify that the workload functions as expected before routing traffic to it.

Shifting traffic

Now that the new Kubernetes workload is functional, route a portion of the traffic to it, and verify that it is working as expected. For details on creating the routing rule, see Routing.

traffic-shift traffic-shift

Alternatively, adjust the related Kubernetes resources, for example:

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: analytics
  namespace: smm-demo
spec:
  host: analytics.smm-demo.svc.cluster.local
  subsets:
  - labels:
      version: v0
    name: v0
  - labels:
      version: v1
    name: v1
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: analytics-smm-demo-lmj7m
  namespace: smm-demo
spec:
  hosts:
  - analytics.smm-demo.svc.cluster.local
  http:
  - route:
    - destination:
        host: analytics.smm-demo.svc.cluster.local
        port:
          number: 8080
        subset: v0
      weight: 90
    - destination:
        host: analytics.smm-demo.svc.cluster.local
        port:
          number: 8080
        subset: v1
      weight: 10

Repeat this step to gradually increase the traffic to the Kubernetes workload.

Completing the migration

If you have verified that the mixed setup works, change the traffic shifting to route 100% of the traffic to the Kubernetes workload.

If the Kubernetes workload is handling 100% of the traffic without problems, you can: