AWS Open Source Blog

Using Kubernetes Migration Factory (KMF) to migrate from Google Kubernetes Engine (GKE) to Amazon Elastic Kubernetes Service (Amazon EKS)

Kubernetes Migration Factory (KMF) is an open source tool (Apache 2.0) that can migrate Kubernetes resources from a cluster running on GKE to a cluster running on Amazon EKS. The KMF tool was developed by a group of consultants from AWS Professional Services for migrating Kubernetes resources from a Google Kubernetes Engine (GKE) cluster to Amazon Elastic Kubernetes Service (Amazon EKS). KMF is written in Golang and offers a command line interface (CLI). The tool can run on a server that can authenticate to the source Kubernetes cluster and target Kubernetes cluster — Amazon EKS in this case — to migrate resources. Additionally, KMF can migrate the container images from Google Container Registry (GCR) to Amazon Elastic Container Registry (Amazon ECR).

The KMF solution is an orchestration platform for migrating containers to Amazon EKS at scale. It is designed to coordinate and automate many of the manual processes, eliminating human error and speeding migration phases down to minutes from weeks of planning and data collection. With just a few inputs provided to the KMF CLI, customers will be able to migrate Kubernetes cluster workloads from GKE into Amazon EKS and container images from GCR to Amazon ECR.

KMF is built to understand the source platform implementation details, and then manipulate the obtained manifest files so that it is valid and accepted by the destination Kubernetes implementation, Amazon EKS. The solution is offered as an open source tool.

Prerequisites and limitations

  • This tool migrates from any Kubernetes cluster to Amazon EKS, so it needs a destination Amazon EKS Cluster. For more information, please refer to the creating an Amazon EKS Cluster documentation.
  • On the workstation where the KMF CLI will be used, setup the kubeconfig for the destination cluster. For more information on authenticating and accessing an Amazon EKS cluster, please refer to the cluster authentication documentation.
  • Set up kubeconfig file to access the Amazon EKS Cluster using the kubectl tool and the same setup is sufficient for KMF to get access. Please refer to the setting kubeconfig file for Amazon EKS cluster access documentation.
  • Similarly, set up the kubeconfig file for the source Kubernetes cluster. For Google Kubernetes Engine (GKE), you may refer to cluster access to GKE documentation, just like how you set up access for kubectl tool.
  • Download KMF for your platform from here. If your platform is not among the available releases, you can install Golang and setup the workspace. Please refer to the Golang Download and Install documentation for more information about installing Golang to your workstation.
  • The Amazon EKS Cluster used as the destination for migrating the Kubernetes workload should have access to the Docker registry used in the source. You may follow this Kubernetes documentation to learn how to pull an image from a private registry. If you create the secret for private registry access in the source Kubernetes cluster and also attach to all the container specifications in all resources, KMF will migrate that as well.
  • The KMF tool also helps to migrate images from third-party repositories, such as GCR, Docker Hub, and GitLab private registry to Amazon ECR. On the workstation where the KMF CLI will be used, be sure to setup your Docker login for Amazon ECR and also add your Docker login to the list of supported repositories (GCR, GitLab, Docker Hub) that are intended for migration prior to executing KMF.
  • The KMF tool uses AWS privileges assigned to the execution ID in order to create an Amazon Elastic Container Registry and push images to it. The following IAM policy statement is the minimum required permission. Here and throughout this post, remember to replace the placeholder account ID with your own account ID, and the word “region” with your own region.
  • {
    "Version":"2012-10-17",
    "Statement":[
    {
    "Sid":"ListImagesInRepository",
    "Effect":"Allow",
    "Action":[
    "ecr:ListImages"
    ],
    "Resource":"arn:aws:ecr:<region>:<AccountId>:repository/*"
    },
    {
    "Sid":"GetAuthorizationToken",
    "Effect":"Allow",
    "Action":[
    "ecr:GetAuthorizationToken"
    ],
    "Resource":"*"
    },
    {
    "Sid":"ManageRepositoryContents",
    "Effect":"Allow",
    "Action":[
    "ecr:BatchCheckLayerAvailability",
    "ecr:GetDownloadUrlForLayer",
    "ecr:GetRepositoryPolicy",
    "ecr:DescribeRepositories",
    "ecr:ListImages",
    "ecr:DescribeImages",
    "ecr:BatchGetImage",
    "ecr:InitiateLayerUpload",
    "ecr:UploadLayerPart",
    "ecr:CompleteLayerUpload",
    "ecr:PutImage"
    ],
    "Resource":"arn:aws:ecr:<region>:<AccountId>:repository/*"
    }
    ]
    }

Limitations

  • KMF will help to migrate container images from container registries like GCR, GitLab, and Docker Hub to Amazon ECR and update the deployment configuration with image location pointing to Amazon ECR, but it will not push the deployment file to your git repositories. That has to be done manually by administrators.

Architecture

Source technology stack

Google Kubernetes Engine — Google Kubernetes Engine (GKE) is a managed, production-ready environment for running containerized applications offered by Google Cloud.

Target technology stack

Amazon Elastic Kubernetes Service — Amazon Elastic Kubernetes Service (Amazon EKS) gives you the flexibility to start, run, and scale Kubernetes applications on AWS or on premises. Amazon EKS helps you provide highly available and secure clusters and automates key tasks such as patching, node provisioning, and updates.

KMF architecture diagram

Architecture diagram

Automation and scale

KMF tool workflow

KMF tool workflow

KMF is written in Golang, and the CLI can be used as a one-line command to migrate workloads to help automate migrations. The same one-liner can be included in an automation script. As shown in the workflow diagram, KMF tool uses the KubeConfig of GKE Kubernetes cluster to collect manifests of requested resources which is then modified to suit the Amazon EKS Kubernetes cluster before deploying it.

KMF CLI Setup

Using an already built binary:

Steps:

  1. Download KMF CLI for your operating system from GitHub to your workstation where you have authenticated to both source and destination clusters. There are compiled binaries for Mac OS, Linux, and Windows within the bin directory of the repository.
  • For Mac OS, the binary is available in bin/mac/kmf
  • For Linux OS, the binary is available in bin/linux/kmf
  • For Windows OS, the binary is available in bin/windows/kmf

2. Optional: Add the tool to your OS path.

Building the binary from source:

Steps:

1. Clone the aws-kubernetes-migration-factory repository.

git clone https://github.com/awslabs/aws-kubernetes-migration-factory

2. Change directory to aws-kubernetes-migration-factory.

cd aws-kubernetes-migration-factory/

3. Run this command to build the KMF CLI binary.

go build

The KMF CLI binary will be built within the current directory as a file named containers-migration-factory. If you want this to be a shorter name, like kmf, then run the build command like this:

go build -o ./bin/kmf

Run KMF CLI

Running with a Config file

From the operating system path from where you are making calls to ./bin/kmf, make sure that you have a file named config.ini and provide all the required information. A sample config.ini file is shared below, and a detailed explanation for each parameter can be found in the KMF documentation.

[COMMON]
# common configuration params required for migration.
# Local path where generated helm charts to be saved
HELM_CHARTS_PATH=/Users/username/kuberenetes-pocs/helm
RESOURCES=all
# Valid Value for ACTION Deploy/Delete
ACTION=Deploy
# Namespaces from which the resources need to migrated
# comma seperated list of namespace or "all"
NAMESPACES=all

# Source Cloud Provider valid values are GKE,AKE,KOPS
CLOUD=GKE
# Source kube config file
# Refer the documentation for the respective source cluster provider to create the kubeconfig file. For GKE, you may refer https://cloud.google.com/kubernetes-engine/docs/how-to/cluster-access-for-kubectl
KUBE_CONFIG=/Users/username/.kube/gcp.config
CONTEXT=<Kube-Context-Name>

[TARGET]
# Target Cloud Provider valid value is AWS only
CLOUD=AWS
# Target kube config file
# Refer the AWS documentation for creating the kubeconfig file https://docs.aws.amazon.com/eks/latest/userguide/create-kubeconfig.html
KUBE_CONFIG=/Users/username/.kube/config
CONTEXT=<Kube-Context-Name>

[MIGRATE_IMAGES]
# This section is used for passing values to the KMF CLI to perform container registry images migration to Amazon ECR and this is optional
# Do you wish to migrate images from 3rd party repositories to Amazon Elastic Container Registry? Supply either "Yes" or "No"
USERCONSENT=Yes
# Comma separated list of 3rd party registries. Tool supports migration from gcr, gitlab, dockerhub registries.
REGISTRY=GCR

Execution walkthrough

Here, we show the Kubernetes resources running in a GKS cluster and an Amazon EKS cluster prior to executing KMF migration.

GKE cluster

$ kubectl get ns
NAME              STATUS   AGE
appdev            Active   35m
appprod           Active   35m
default           Active   479d
infra             Active   35m
kube-node-lease   Active   479d
kube-public       Active   479d
kube-system       Active   479d
shared            Active   35m

Amazon EKS cluster

$ kubectl get ns
NAME              STATUS   AGE
default           Active   472d
kube-node-lease   Active   472d
kube-public       Active   472d
kube-system       Active   472d

Now, let’s look at a sample execution output to see how KMF performs a migration from a GKS cluster to an Amazon EKS Cluster.

Step 1. On your workstation, navigate to the path where the KMF repository is downloaded.

Step 2. Update kubeconfig.ini. In this example, we are performing a migration of all supported resources from GKS to Amazon EKS.

[COMMON]
# common configuration params required for migration.
# Local path where generated helm charts to be saved
HELM_CHARTS_PATH=/Users/username/kuberenetes-pocs/helm
RESOURCES=all
# Valid Value for ACTION Deploy/Delete
ACTION=Deploy
# Namespaces from which the resources need to migrated
# comma seperated list of namespace or "all"
NAMESPACES=all
[SOURCE]
# Source Cloud Provider valid values are GKE,AKE,KOPS
CLOUD=GKE
# Source kube config file
KUBE_CONFIG=/Users/username/.kube/gcp.config
CONTEXT=gke_cmf-aws_us-central1-c_cluster-1
[TARGET]
CLOUD=AWS
# Target kube config file
KUBE_CONFIG=/Users/username/.kube/config
CONTEXT=arn:aws:eks:us-east-1:12233344444:cluster/eksworkshop-eksctl
[MIGRATE_IMAGES]
# Do you wish to migrate images from 3rd party repositories to Amazon Elastic Container Registry? Supply either "Yes" or "No"
USERCONSENT=Yes
# Comma separated list of 3rd party registries. Tool supports migration from gcr, gitlab, dockerhub registries.
REGISTRY=GCR

Step 3. Execute the KMF binary. KMF will extract configuration details such as source cluster config, destination cluster config, resources list, and namespace from config.ini file.

Stage 1: Collect Kubernetes resource manifest from the source (GKE) cluster

KMF tool starts by connecting to the GKE cluster using the KubeConfig defined in config.ini and collecting the manifest of requested resources. In this case, we have selected all resources to be migrated from GKE to the Amazon EKS cluster.

[kubernetes-migrations-factory]# ./bin/kmf
Deploy
GKE Resources
GKE GetSourceDetails....
Namespace list entered as 'all' by user, hence all namespaces will be considered
Chart Name: webserver-dev
secrets: templates/NOTES.txt
secrets: templates/_helpers.tpl
secrets: templates/configmap-vhosts.yaml
secrets: templates/configmap.yaml
secrets: templates/deployment.yaml
secrets: templates/extra-list.yaml
secrets: templates/hpa.yaml
secrets: templates/ingress.yaml
secrets: templates/metrics-svc.yaml
secrets: templates/pdb.yaml
secrets: templates/prometheusrules.yaml
secrets: templates/servicemonitor.yaml
secrets: templates/svc.yaml
secrets: templates/tls-secrets.yaml
Files Name: .helmignore
Files Name: README.md
Files Name: files/README.md
Files Name: files/vhosts/README.md
Path : /app/helm/KMFHelmCharts/namespaces/appprod
Chart Name: webserver-prod
secrets: templates/NOTES.txt
secrets: templates/_helpers.tpl
secrets: templates/configmap-vhosts.yaml
secrets: templates/configmap.yaml
secrets: templates/deployment.yaml
secrets: templates/extra-list.yaml
secrets: templates/hpa.yaml
secrets: templates/ingress.yaml
secrets: templates/metrics-svc.yaml
secrets: templates/pdb.yaml
secrets: templates/prometheusrules.yaml
secrets: templates/servicemonitor.yaml
secrets: templates/svc.yaml
secrets: templates/tls-secrets.yaml
Files Name: .helmignore
Files Name: README.md
Files Name: files/README.md
Files Name: files/vhosts/README.md
GKE FormatSourceData....start
GKE FormatSourceData....End

Stage 2: Modify the manifest file to suit the Amazon EKS Cluster before deployment, and then deploy it.

KMF begins to deploy all collected resources in the Amazon EKS cluster. KMF starts by deploying global resources, such as mutating webhooks, which are not namespace specific. If the deployment is already present in the destination cluster then KMF will not override it.

EKS Deploying resources....
Creating MutatingWebhook:  cert-manager-webhook
mutatingwebhookconfigurations.admissionregistration.k8s.io "cert-manager-webhook" already exists
Creating MutatingWebhook:  neg-annotation.config.common-webhooks.networking.gke.io
mutatingwebhookconfigurations.admissionregistration.k8s.io "neg-annotation.config.common-webhooks.networking.gke.io" already exists
Creating MutatingWebhook:  pod-identity-webhook
Creating MutatingWebhook:  pod-ready.config.common-webhooks.networking.gke.io
mutatingwebhookconfigurations.admissionregistration.k8s.io "pod-ready.config.common-webhooks.networking.gke.io" already exists
Creating MutatingWebhook:  vpc-resource-mutating-webhook
mutatingwebhookconfigurations.admissionregistration.k8s.io "vpc-resource-mutating-webhook" already exists
Creating the namespace:  appdev
Creating the namespace:  appprod
Creating the namespace:  default
namespaces "default" already exists
Creating the namespace:  infra
Creating the namespace:  shared
Installing Chart  webserver-dev  on EKS cluster in namespace  appdev
 Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "kube-state-metrics" chart repository
...Successfully got an update from the "nginx-stable" chart repository
...Successfully got an update from the "jenkins" chart repository
...Successfully got an update from the "prometheus-community" chart repository
...Successfully got an update from the "bitnami" chart repository
Update Complete. ⎈Happy Helming!⎈
Saving 1 charts
Downloading common from repo https://charts.bitnami.com/bitnami
Deleting outdated charts

 Release "webserver-dev" has been upgraded. Happy Helming!
NAME: webserver-dev
LAST DEPLOYED: Fri Jul  1 15:15:54 2022
NAMESPACE: appdev
STATUS: deployed
REVISION: 2
TEST SUITE: None
NOTES:
CHART NAME: apache
CHART VERSION: 9.1.12
APP VERSION: 2.4.54

** Please be patient while the chart is being deployed **

1. Get the Apache URL by running:

** Please ensure an external IP is associated to the webserver-dev-apache service before proceeding **
** Watch the status using: kubectl get svc --namespace appdev -w webserver-dev-apache **

  export SERVICE_IP=$(kubectl get svc --namespace appdev webserver-dev-apache --template "{{ range (index .status.loadBalancer.ingress 0) }}{{ . }}{{ end }}")
  echo URL            : http://$SERVICE_IP/


WARNING: You did not provide a custom web application. Apache will be deployed with a default page. Check the README section "Deploying your custom web application" in https://github.com/bitnami/charts/blob/master/bitnami/apache/README.md#deploying-your-custom-web-application.

Installing Chart  webserver-prod  on EKS cluster in namespace  appprod
 Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "kube-state-metrics" chart repository
...Successfully got an update from the "nginx-stable" chart repository
...Successfully got an update from the "jenkins" chart repository
...Successfully got an update from the "prometheus-community" chart repository
...Successfully got an update from the "bitnami" chart repository
Update Complete. ⎈Happy Helming!⎈
Saving 1 charts
Downloading common from repo https://charts.bitnami.com/bitnami
Deleting outdated charts

 Release "webserver-prod" has been upgraded. Happy Helming!
NAME: webserver-prod
LAST DEPLOYED: Fri Jul  1 15:16:00 2022
NAMESPACE: appprod
STATUS: deployed
REVISION: 2
TEST SUITE: None
NOTES:
CHART NAME: apache
CHART VERSION: 9.1.12
APP VERSION: 2.4.54

** Please be patient while the chart is being deployed **

1. Get the Apache URL by running:

** Please ensure an external IP is associated to the webserver-prod-apache service before proceeding **
** Watch the status using: kubectl get svc --namespace appprod -w webserver-prod-apache **

  export SERVICE_IP=$(kubectl get svc --namespace appprod webserver-prod-apache --template "{{ range (index .status.loadBalancer.ingress 0) }}{{ . }}{{ end }}")
  echo URL            : http://$SERVICE_IP/


WARNING: You did not provide a custom web application. Apache will be deployed with a default page. Check the README section "Deploying your custom web application" in https://github.com/bitnami/charts/blob/master/bitnami/apache/README.md#deploying-your-custom-web-application.

=====================================================================
Operating on namespace:  appdev
=====================================================================
===============
Creating Secrets
Creating Secret:  sh.helm.release.v1.webserver-dev.v1
===============
Creating ConfigMap's
===============
Creating StorageClasses
===============
Creating PersistentVolumeClaims
===============
Creating Deployment
Creating Deployment:  webserver-dev-apache
===============
Creating Service
Creating Service:  webserver-dev-apache
===============
Creating Daemonset
===============
Creating Ingresses
===============
Creating Roles
===============
Creating Role Bindings
===============
Creating Secrets
Creating Secret:  sh.helm.release.v1.webserver-dev.v1
secrets "sh.helm.release.v1.webserver-dev.v1" already exists
===============
Creating StorageClasses
===============
Creating CronJob's
===============
Creating Job's
===============
Creating Cluster Roles
===============
Creating Cluster Role Bindings
===============
Creating HorizontalPodAutoscalers
===============
Creating Pod security policies
===============
Creating Service Account Job's
Creating Service Account:  default
serviceaccounts "default" already exists
=====================================================================
Operating on namespace:  appprod
=====================================================================
===============
Creating Secrets
Creating Secret:  sh.helm.release.v1.webserver-prod.v1
===============
Creating ConfigMap's
===============
Creating StorageClasses
===============
Creating PersistentVolumeClaims
===============
Creating Deployment
Creating Deployment:  webserver-prod-apache
===============
Creating Service
Creating Service:  webserver-prod-apache
===============
Creating Daemonset
===============
Creating Ingresses
===============
Creating Roles
===============
Creating Role Bindings
===============
Creating Secrets
Creating Secret:  sh.helm.release.v1.webserver-prod.v1
secrets "sh.helm.release.v1.webserver-prod.v1" already exists
===============
Creating StorageClasses
===============
Creating CronJob's
===============
Creating Job's
===============
Creating Cluster Roles
===============
Creating Cluster Role Bindings
===============
Creating HorizontalPodAutoscalers
===============
Creating Pod security policies
===============
Creating Service Account Job's
Creating Service Account:  default
serviceaccounts "default" already exists
=====================================================================
Operating on namespace:  default
=====================================================================
===============
Creating Secrets
Creating Secret:  example-app-tls
secrets "example-app-tls" already exists
===============
Creating ConfigMap's
Creating ConfigMap:  ingress-controller-leader-nginx
configmaps "ingress-controller-leader-nginx" already exists
Creating ConfigMap:  kube-root-ca.crt
configmaps "kube-root-ca.crt" already exists
Creating ConfigMap:  secure-config
configmaps "secure-config" already exists
Creating ConfigMap:  test
configmaps "test" already exists
Creating ConfigMap:  test1
configmaps "test1" already exists
===============
Creating StorageClasses
===============
Creating PersistentVolumeClaims
Creating PVC:  jenkins-data
persistentvolumeclaims "jenkins-data" already exists
Creating PVC:  myclaim
persistentvolumeclaims "myclaim" already exists
===============
Creating Deployment
Creating Deployment:  demo-deployment
deployments.apps "demo-deployment" already exists
Creating Deployment:  httpd
deployments.apps "httpd" already exists
Creating Deployment:  nginx
deployments.apps "nginx" already exists
===============
Creating Service
Creating Service:  demo-service
services "demo-service" already exists
Creating Service:  example-service
services "example-service" already exists
Creating Service:  httpd
services "httpd" already exists
Creating Service:  kubernetes
services "kubernetes" already exists
Creating Service:  nginx
services "nginx" already exists
Creating Service:  nginx-loadbalancer
services "nginx-loadbalancer" already exists
Creating Service:  test
services "test" already exists
===============
Creating Daemonset
===============
Creating Ingresses
===============
Creating Roles
Creating Roles:  pod-reader
roles.rbac.authorization.k8s.io "pod-reader" already exists
===============
Creating Role Bindings
Creating Role Bindings:  read-pods
rolebindings.rbac.authorization.k8s.io "read-pods" already exists
===============
Creating Secrets
Creating Secret:  example-app-tls
secrets "example-app-tls" already exists
===============
Creating StorageClasses
===============
Creating CronJob's
Creating CronJob:  hello
cronjobs.batch "hello" already exists
===============
Creating Job's
Creating Job's:  hello-1640030700
jobs.batch "hello-1640030700" already exists
Creating Job's:  hello-1640030760
jobs.batch "hello-1640030760" already exists
Creating Job's:  hello-1640030820
jobs.batch "hello-1640030820" already exists
Creating Job's:  hello-1640031000
jobs.batch "hello-1640031000" already exists
Creating Job's:  hello-1645046880
jobs.batch "hello-1645046880" already exists
Creating Job's:  hello-1645046940
jobs.batch "hello-1645046940" already exists
Creating Job's:  hello-1645047000
jobs.batch "hello-1645047000" already exists
Creating Job's:  hello-1645072740
jobs.batch "hello-1645072740" already exists
Creating Job's:  hello-1645072800
jobs.batch "hello-1645072800" already exists
Creating Job's:  hello-1645072860
jobs.batch "hello-1645072860" already exists
Creating Job's:  hello-1656688380
jobs.batch "hello-1656688380" already exists
Creating Job's:  hello-1656688440
jobs.batch "hello-1656688440" already exists
Creating Job's:  hello-1656688500
jobs.batch "hello-1656688500" already exists
Creating Job's:  pi
jobs.batch "pi" already exists
===============
Creating Cluster Roles
===============
Creating Cluster Role Bindings
===============
Creating HorizontalPodAutoscalers
===============
Creating Pod security policies
===============
Creating Service Account Job's
Creating Service Account:  default
serviceaccounts "default" already exists
=====================================================================
Operating on namespace:  infra
=====================================================================
===============
Creating Secrets
===============
Creating ConfigMap's
===============
Creating StorageClasses
===============
Creating PersistentVolumeClaims
===============
Creating Deployment
===============
Creating Service
===============
Creating Daemonset
===============
Creating Ingresses
===============
Creating Roles
===============
Creating Role Bindings
===============
Creating Secrets
===============
Creating StorageClasses
===============
Creating CronJob's
Creating CronJob:  hello
===============
Creating Job's
Creating Job's:  hello-1656688380
Creating Job's:  hello-1656688440
Creating Job's:  hello-1656688500
===============
Creating Cluster Roles
===============
Creating Cluster Role Bindings
===============
Creating HorizontalPodAutoscalers
===============
Creating Pod security policies
===============
Creating Service Account Job's
Creating Service Account:  default
serviceaccounts "default" already exists
=====================================================================
Operating on namespace:  shared
=====================================================================
===============
Creating Secrets
Creating Secret:  sharedaccesssecret
===============
Creating ConfigMap's
===============
Creating StorageClasses
===============
Creating PersistentVolumeClaims
===============
Creating Deployment
===============
Creating Service
===============
Creating Daemonset
===============
Creating Ingresses
===============
Creating Roles
===============
Creating Role Bindings
===============
Creating Secrets
Creating Secret:  sharedaccesssecret
secrets "sharedaccesssecret" already exists
===============
Creating StorageClasses
===============
Creating CronJob's
===============
Creating Job's
===============
Creating Cluster Roles
===============
Creating Cluster Role Bindings
===============
Creating HorizontalPodAutoscalers
===============
Creating Pod security policies
===============
Creating Service Account Job's
Creating Service Account:  default
serviceaccounts "default" already exists

Step 4: Verify the result in the Amazon EKS cluster

[kubernetes-migrations-factory]# kubectl get ns
NAME              STATUS   AGE
appdev            Active   14m
appprod           Active   14m
default           Active   472d
infra             Active   14m
kube-node-lease   Active   472d
kube-public       Active   472d
kube-system       Active   472d
shared            Active   14m

Running as one line

The KMF tool also takes in parameters as command line arguments. In that case, any CLI arguments take precedence over any definitions in config.ini.

Migrating all resources from all namespaces

Below is an example of how all KMF-supported Kubernetes resources can be migrated from all namespaces.

$ ./bin/kmf --source_kubeconfig  /Users/<user-name>/.kube/gcp.config \
--destination_kubeconfig /Users/<user-name>/.kube/aws.config \
--namespaces "all" \
--resources "all" \
--migrate_images "yes" \
--reg_names "gcr, dockerhub, gitlab" \
--source_context <source_kubernetes_context> \  
--destination_context <destination_kubernetes_context> \
--helm_path <local-file-system-path> \
--action Deploy

Migrating deployments and services from multiple namespaces

Below is an example of how selected Kubernetes resources can be migrated from all selected namespaces.

$ ./bin/kmf --source_kubeconfig  \
/Users/<user-name>/.kube/gcp.config --destination_kubeconfig \
/Users/<user-name>/.kube/aws.config \
--namespaces "dev,default" \
--resources "deployment,service" \
--migrate_images "yes" \
--reg_names "gcr, dockerhub, gitlab" \
--source_context <source_kubernetes_context>  \
--destination_context <destination_kubernetes_context> \
--helm_path <local-file-system-path> \
--action Deploy

Cleanup

To clean up KMF tool, simply remove the aws-kubernetes-migration-factory directory from the workstation where the repository is cloned. If you would like to delete migrated Kubernetes resources in the destination cluster, simply choose the action as “Delete” in the KMF configuration file. This will only delete migrated resources in the Amazon EKS Cluster, and it does not delete any resources in the GKE cluster.

Related resources

Conclusion

KMF can be used to quickly migrate your Kubernetes workloads from GKE to an Amazon EKS cluster. In this blog post, we provided an example of how KMF can be used from an operating system terminal. The KMF source code is available in our GitHub repository, and it is open source. Anyone in the community interested in this subject can contribute to it or reach out to us using GitHub issues.

Vasanth Jeyaraj

Vasanth Jeyaraj

Vasanth Jeyaraj is a Cloud Infra Architect with Amazon Web Services (AWS). He supports enterprise customers in building well architected infrastructure with a focus on Automation, Infrastructure as Code, and also focussed on helping customers speed their cloud-native adoption journey by modernizing their platform infrastructure, internal architecture using MicroServices Strategy, Containerization, DevOps. Outside of work, he loves spending time with family and traveling.

Kirankumar Chandrashekar

Kirankumar Chandrashekar

Kirankumar Chandrashekar is a Sr. Solutions Architect for Strategic Accounts at AWS. He focuses on leading customers in architecting DevOps, containers and container technologies to name a few. Kirankumar is passionate about DevOps, Infrastructure as Code, and solving complex customer issues. He enjoys music, as well as cooking and traveling.

Mahendra Revanasiddappa

Mahendra Revanasiddappa

Mahendra Siddappa is a DevOps Consultant with Amazon Web Services. He works with AWS customers on containers, kubernetes and DevOps ideas.