Customize Kubernetes YAMLs to target specific clusters

Move2Kube already supports targeting across multiple clusters includig: Kubernetes, Openshift, IBM-IKS, IBM-Openshift, Azure-EKS, Azure-AKS and GCP-GKS. There might be situations where you require generating Kubernetes YAMLs to target a particular cluster. In this tutorial we will see how we can use Konveyor Move2Kube to change the versions of existing Kubernetes resources to target a particular cluster. Move2Kube can also be customized to generate Kubernetes YAMLS deployable on a particular cluster.

Prerequisites

  1. Install the Move2Kube CLI tool.

  2. Install Kubectl.

  3. Use the kubernetes-to-kubernetes sample. This directory has some Kubernetes YAMLs that deploy a web app with multiple services. There are three services: a frontend website in PHP, a backend API in NodeJS, and a cache service using Redis.

Steps

  1. Collect data about the Kubernetes cluster using move2kube collect. Limit the collection to only cluster information using the -a k8s annotation flag.

Note: Before running the below command, log in to your target cluster. To check whether you are logged in to the target cluster run kubectl get pods.

$ move2kube collect -a k8s
INFO[0000] Begin collection
INFO[0000] [*collector.ClusterCollector] Begin collection
INFO[0006] [*collector.ClusterCollector] Done   
INFO[0006] [*collector.ImagesCollector] Begin collection
INFO[0006] [*collector.ImagesCollector] Done
INFO[0006] Collection done  
INFO[0006] Collect Output in [/Users/user/m2k_collect]. Copy this directory into the source directory to be used for planning.

The data we collected will be stored in a new directory called ./m2k_collect.

$ ls m2k_collect
cf

The ./m2k_collect/clusters directory contains the YAML file which has the cluster application information including the buildpacks that are supported, the memory, the number of instances and the ports that are supported. If there are environment variables, it collects that information too. The name of the cluster can be found in the metadata.name file, and can be renamed in the YAML file.

  • For this tutorial, we have already collected the move2kube collect output yaml file which contains the cluster related information and stored it here. We have renamed the cluster metadata.name as my-kubernetes-cluster in the yaml file.

  • We will use a custom configured version of the clusterselector transformer.

  1. Download the custom-cluster-selector transformer into the customizations sub-directory.
$ curl https://move2kube.konveyor.io/scripts/download.sh | bash -s -- -d custom-cluster-selector -r move2kube-transformers -o customizations

The customizations/custom-cluster-selector/transformer.yaml is the transformer configuration. There are two changes in the custom-cluster-selector/transformer.yaml compared to the built-in clusterselector/transformer.yaml :

  • The name of the custom transformer is CustomClusterSelector (see name field in the metadata section).
  • We are also specifying an override section which is asking Move2Kube to disable the transformer named ClusterSelector if CustomClusterSelector transformer is present.
  $ cat customizations/custom-cluster-selector/transformer.yaml
  apiVersion: move2kube.konveyor.io/v1alpha1
  kind: Transformer
  metadata:
    name: CustomClusterSelector
    labels:
      move2kube.konveyor.io/built-in: true
      move2kube.konveyor.io/kubernetesclusterselector: true
  spec:
    class: "ClusterSelectorTransformer"
    directoryDetect:
      levels: 0
    consumes:
      IR:
        merge: true
        mode: OnDemandPassThrough
      KubernetesOrgYamlsInSource:
        merge: false
        mode: OnDemandPassThrough
    produces:
      IR:
        disabled: false
      KubernetesOrgYamlsInSource:
        disabled: false
    override:
      matchLabels:
        move2kube.konveyor.io/name: ClusterSelector

To check what information did move2kube collect -a k8s collected for us, let’s see the content inside the my-kubernetes-cluster.yaml.

$ cat customizations/custom-cluster-selector/clusters/my-kubernetes-cluster.yaml
apiVersion: move2kube.konveyor.io/v1alpha1
kind: ClusterMetadata
metadata:
  name: my-kubernetes-cluster
spec:
  storageClasses:
    - default
    - ibmc-file-bronze
    - ibmc-file-bronze-gid
    - ibmc-file-custom
    - ibmc-file-gold
Click to see the rest of the yaml.

The my-kubernetes-cluster.yaml has information about the target cluster under the spec field, includin the storageClasses, Deployment, Service, Ingress and NetworkPolicy versions supported by the target cluster. Move2Kube will use this information and generate the Kubernetes YAMLs which are tailored for the given target cluster.

  1. Download the kubernetes-to-kubernetes sample.
$ curl https://move2kube.konveyor.io/scripts/download.sh | bash -s -- -d samples/kubernetes-to-kubernetes -r move2kube-demos
$ ls kubernetes-to-kubernetes/
api-deployment.yaml  api-service.yaml  redis-deployment.yaml  redis-service.yaml  web-deployment.yaml  web-ingress.yaml  web-service.yaml
  1. Generate a plan file. Here, we provide the custom-cluster-selector transformer which is inside the downloaded customizations folder to Move2Kube using the -c flag.
$ move2kube plan -s kubernetes-to-kubernetes -c customizations
INFO[0000] Configuration loading done
INFO[0000] Planning Transformation - Base Directory
INFO[0000] [CloudFoundry] Planning transformation
INFO[0000] [CloudFoundry] Done
INFO[0000] [DockerfileDetector] Planning transformation
INFO[0000] [DockerfileDetector] Done
INFO[0000] [ComposeAnalyser] Planning transformation
INFO[0000] [ComposeAnalyser] Done
INFO[0000] [Base Directory] Identified 0 named services and 0 to-be-named services
INFO[0000] Transformation planning - Base Directory done
INFO[0000] Planning Transformation - Directory Walk
INFO[0000] Identified 1 named services and 0 to-be-named services in .
INFO[0000] Identified 1 named services and 0 to-be-named services in .
INFO[0000] Transformation planning - Directory Walk done
INFO[0000] [Directory Walk] Identified 1 named services and 1 to-be-named services
INFO[0000] [Named Services] Identified 1 named services
INFO[0000] No of services identified : 1
INFO[0000] Plan can be found at [/Users/user/m2k.plan].
  1. View the generated plan file in YAML format. Notice Move2Kube has detected our custom-cluster-selector as customizationsDir which will be used during the Transform phase.
$ cat m2k.plan
apiVersion: move2kube.konveyor.io/v1alpha1
kind: Plan
metadata:
  name: myproject
spec:
  sourceDir: kubernetes-to-kubernetes
  customizationsDir: custom-cluster-selector
apiVersion: move2kube.konveyor.io/v1alpha1
kind: Plan
metadata:
   name: myproject
Click to see the rest of the yaml.
  1. Run the transformation using move2kube transform.
$ move2kube transform
INFO[0000] Detected a plan file at path /home/user/m2k.plan. Will transform using this plan.
? Select all transformer types that you are interested in:
ID: move2kube.transformers.types
Hints:
[Services that don't support any of the transformer types you are interested in will be ignored.]
  [Use arrows to move, space to select, <right> to all, <left> to none, type to filter]
> []  Maven
  [✓]  Rust-Dockerfile
  [✓]  Tomcat
  [✓]  ZuulAnalyser
  [✓]  CustomClusterSelector
  [✓]  Jboss
  [✓]  Parameterizer
  [✓]  ReadMeGenerator
  [✓]  WarRouter
  [✓]  DockerfileDetector
  [✓]  Gradle
  [✓]  Python-Dockerfile
  [✓]  WinConsoleApp-Dockerfile
  [✓]  Buildconfig
  [✓]  EarAnalyser
  [✓]  Knative
  [✓]  Nodejs-Dockerfile
  [✓]  WinSLWebApp-Dockerfile
  [✓]  ContainerImagesPushScriptGenerator
  [✓]  DockerfileImageBuildScript
  [✓]  Tekton
  [✓]  DotNetCore-Dockerfile
  [✓]  Liberty
  [✓]  DockerfileParser
  [✓]  Golang-Dockerfile
  [✓]  WinWebApp-Dockerfile
  [✓]  CloudFoundry
  [✓]  ComposeGenerator
  [✓]  Kubernetes
  [✓]  Ruby-Dockerfile
  [✓]  WarAnalyser
  [✓]  ComposeAnalyser
  [✓]  Jar
  [✓]  PHP-Dockerfile
  [✓]  EarRouter
  [✓]  KubernetesVersionChanger
  1. Accept the default by pressing the return or enter key.
? Select all services that are needed:
ID: move2kube.services.[].enable
Hints:
[The services unselected here will be ignored.]
  [Use arrows to move, space to select, <right> to all, <left> to none, type to filter]
> []  myproject
  1. Accept the detected service.
INFO[0017] Starting Plan Transformation
INFO[0017] Iteration 1  
INFO[0017] Iteration 2 - 1 artifacts to process
INFO[0017] Transformer CustomClusterSelector processing 1 artifacts
? Choose the cluster type:
ID: move2kube.target.clustertype
Hints:
[Choose the cluster type you would like to target]
  [Use arrows to move, type to filter]
  GCP-GKE
  IBM-IKS
  IBM-Openshift
  Kubernetes
> my-kubernetes-cluster
  Openshift
  AWS-EKS
  Openshift
  1. Select my-kubernetes-cluster as the target cluster type to deploy to.
INFO[0393] Transformer CustomClusterSelector Done   
INFO[0393] Transformer KubernetesVersionChanger processing 1 artifacts
INFO[0393] Transformer KubernetesVersionChanger Done
INFO[0393] Created 1 pathMappings and 1 artifacts. Total Path Mappings : 1. Total Artifacts : 1.
INFO[0393] Iteration 3 - 1 artifacts to process
INFO[0393] Transformer Parameterizer processing 1 artifacts
INFO[0393] Transformer Parameterizer Done   
INFO[0393] Plan Transformation done
INFO[0393] Transformed target artifacts can be found at [/Users/user/myproject].
  1. The transformation has completed and generated a directory called myproject.

Note: The name of the output directory is the same as the project name (by default myproject). The project name can be changed using the -n flag.

$ ls
customizations   kubernetes-to-kubernetes m2k.plan m2kconfig.yaml   m2kqacache.yaml  myproject

$ ls myproject/source
kubernetes-to-kubernetes-versionchanged   kubernetes-to-kubernetes-versionchanged-parameterized

The applications can now be deployed to Kubernetes using these generated artifacts.

Exploring the output

The full structure of the output directory can be seen by executing the tree command.

  $ tree myproject/
   myproject
  └── source
      ├── kubernetes-to-kubernetes-versionchanged
      │   ├── api-deployment.yaml
      │   ├── api-service.yaml
      │   ├── redis-deployment.yaml
      │   ├── redis-service.yaml
      │   ├── web-deployment.yaml
      │   ├── web-ingress.yaml
      │   └── web-service.yaml
      └── kubernetes-to-kubernetes-versionchanged-parameterized
          ├── helm-chart
          │   └── move2kube-transformers
          │       ├── Chart.yaml
          │       ├── templates
          │       │   ├── api-deployment.yaml
          │       │   ├── api-service.yaml
          │       │   ├── redis-deployment.yaml
          │       │   ├── redis-service.yaml
          │       │   ├── web-deployment.yaml
          │       │   ├── web-ingress.yaml
          │       │   └── web-service.yaml
          │       ├── values-dev.yaml
          │       ├── values-prod.yaml
          │       └── values-staging.yaml
          ├── kustomize
          │   ├── base
          │   │   ├── api-deployment.yaml
          │   │   ├── api-service.yaml
          │   │   ├── kustomization.yaml
          │   │   ├── redis-deployment.yaml
          │   │   ├── redis-service.yaml
          │   │   ├── web-deployment.yaml
          │   │   ├── web-ingress.yaml
          │   │   └── web-service.yaml
          │   └── overlays
          │       ├── dev
          │       │   ├── apps-v1-deployment-api.yaml
          │       │   ├── apps-v1-deployment-redis.yaml
          │       │   ├── apps-v1-deployment-web.yaml
          │       │   └── kustomization.yaml
          │       ├── prod
          │       │   ├── apps-v1-deployment-api.yaml
          │       │   ├── apps-v1-deployment-redis.yaml
          │       │   ├── apps-v1-deployment-web.yaml
          │       │   └── kustomization.yaml
          │       └── staging
          │           ├── apps-v1-deployment-api.yaml
          │           ├── apps-v1-deployment-redis.yaml
          │           ├── apps-v1-deployment-web.yaml
          │           └── kustomization.yaml
          └── openshift-template
              ├── parameters-dev.yaml
              ├── parameters-prod.yaml
              ├── parameters-staging.yaml
              └── template.yaml

  13 directories, 42 files

The myproject/source/kubernetes-to-kubernetes-versionchanged directory has the new Kubernetes YAMLs (deployment/service/ingress/etc.) which are tailored to meet the target cluster requirements.

Some other things we can observe:

  • The Helm chart in the source/kubernetes-to-kubernetes-versionchanged-parameterized/helm-chart directory.
  • The Kustomize YAMLs in the source/kubernetes-to-kubernetes-versionchanged-parameterized/kustomize directory.
  • The Openshift Template in the source/kubernetes-to-kubernetes-versionchanged-parameterized/openshift-template directory.

For more details on how to customize the parameterization look at the documentation.

Conclusion

First, run move2kube collect -a k8s after logging in to your cluster to collect the cluster-related information inside the m2k_collect folder. Then, copy-paste the generated YAML file inside m2k_collect/cluster/ to custom-cluster-selector/clusters/. While running move2kube plan -s src -c custom-cluster-selector (or transform move2kube transform -s src -c custom-cluster-selector), provide the customization folder to Move2Kube using the -c flag. Finally, select the target cluster in the QA during Transform phase. Move2Kube will generate the Kubernetes YAMLs for the target cluster.

Given Kubernetes YAMLs, we saw how Move2Kube can create/transform the Kubernetes YAMLs to target a specific cluster.