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 KMFfor 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 policystatement 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.
 
 
        Architecture diagram
Automation and scale
 
 
        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:
- 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 buildThe 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/kmfRun 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 DeployMigrating 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 DeployCleanup
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
- Creating an Amazon EKS Cluster
- Amazon EKS cluster authentication
- Create a kubeconfig for Amazon EKS
- Access Google Kubernetes Engine
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.