Recently, we helped a large healthcare company move 3,000 applications from its existing cloud platform to Kubernetes. They were already using Kubernetes along with another cloud platform, so it wasn't a big effort to convince them to move to Kubernetes. Their goal was to centralize everything by running solely on Kubernetes. And from a financial perspective, this migration would save the customer approximately $10 million in licensing—a substantial saving.
This article describes how the migration went. It's based on a presentation I gave at a Konveyor community meetup, where practitioners share their experience and open source tools around migrating to Kubernetes. You can watch my full presentation, if you'd like.
Exploring migration challenges for operations and application teams
More than the technology, the key challenge in a cloud migration is the people you are working with and how open they are to leaving their existing cloud platform and moving to Kubernetes.
The cloud operations team tends to be the focus when it comes to this type of migration. This team knows the current platform in and out, but they will come to understand and own a new platform when you provide training and support. But there's a bigger issue: The cloud operations team probably owns the platform, but they don't control the development team, which is also impacted by this change.
In our case, we had a team that owns the platform and was interested in moving to Kubernetes. But we had an application team asking, "Why would we want to change our code and move to Kubernetes?"
To address the situation, we suggested that the cloud team provide leadership and a sponsor. We also advised them to share the timeline, mitigation, and migration plans, and stick to them. For example, they could inform the app dev team, "If you don't move your cloud application to Kubernetes by mid-2022, your app will no longer be supported. You have to move." They also provided support and documentation to help the dev team move to Kubernetes.
Some reasons the cloud operations team was looking to migrate to Kubernetes were the cost of the existing platform's license, a desire for a hardware refresh, and an immature and unclear product plan for the existing platform. They wanted to move to an industry-standard way of doing things.
[ Before you start your cloud journey, read Accelerating to the cloud: 4 important things to know. ]
Their executive sponsor was interested in saving money. If they were open to paying for both a Kubernetes platform and their existing platform (which carries a considerable cost), they might be open to consolidating—saving costs with one operations team and one platform.
Another factor to consider was that most of the organization was looking at a cloud-first strategy. They wanted to know how they could deploy workloads into a solution that they can move to the cloud quickly.
We recommended that the executive team stand up a migration team, enforce the migration plan, and stick to the timeline. The migration team's job was to look at the current cloud platform's code and handle the top issue with the application team: getting the first version moved to Kubernetes. They would help the app dev team deploy their first version of the application on Kubernetes, have them own it, and provide them with the documentation and support they need. The application team liked this plan because it meant they didn't need to learn Kubernetes extensively to move the application and rearchitect their solutions.
Creating the migration plan
A successful cloud migration starts with an assessment phase to determine gaps and dependencies. After the assessment phase, you can begin creating a pilot. The pilot's objective is to get one or two candidates moved completely to Kubernetes with continuous integration/continuous development (CI/CD) pipeline tools already set up.
With this migration, we recommended starting the pilot by moving the most complex application to Kubernetes. That's contrary to what we have previously recommended in the Konveyor community, which is that your quick win should be the easiest one. In this case, your quick win should be the most complex one because success will defeat any arguments from the team.
[ Compare Red Hat OpenShift and Kubernetes ... what's the difference? ]
Once you migrate the most complex application and see how it looks, explain what you did and what you migrated. Then look at setting up migration tools and best practices for the future to create a migration factory to scale the subsequent applications—which was 3,000 applications in this case.
Choosing an application migration strategy
We considered three strategies for migration:
- Rehosting or lifting and shifting as-is
- Replatforming, lifting, and adjusting
- Refactoring, rewriting, and decoupling the application
When you have 3,000 applications, it's hard to think about refactoring. That would take years and years of refactoring, decoupling, and rewriting. So we focused on two migration strategies: rehosting and replatforming.
The assessment phase
The assessment phase is critical because it helps you understand the dependencies you have and what you need to do to migrate the applications to Kubernetes. We choose a bottom-up approach, where you look at the cloud applications, their manifest config files, and the REST APIs, and try to gather all the needed applications for the dependencies and configuration. Then, you compile all the dependencies and try to map them.
Automating the analysis and identification of the dependencies and complexity on the applications was vital, as 3,000 was too many for a human to manage. With a team of 10 people, it would take too much time to manually go through this many and uncover the dependencies on all of them. Just coming up with the assessment would be challenging.
[Download this free whitepaper to learn how to take a layered approach to container and Kubernetes security. ]
We looked at how we could automate the whole process. Consequently, we developed the Cedrus migration tool. This tool automates looking at the different patterns from a dependencies perspective through all configuration manifest files and generates a report. This report provides the first level of information to start analyzing the applications, as well as the application groupings to begin understanding gaps in terms of services between the existing cloud platform and Kubernetes.
This is an example report. It shows the app names, the services, how they do autoscaling, complexity, libraries used, stack, unpack, plugins, and dependencies from a server's perspective.
To use the tool, you have to configure some of the rules to determine what it should look at from a pattern perspective.
Dependencies revealed by the assessment
We looked at this from a platform perspective. All 3,000 applications were using some common services—some hosted on the existing cloud platform and some external. The good news is the externals don't need to change. The bad news is that the current cloud platform services must be replaced with a Kubernetes service or equivalent services. And that requires refactoring the code to use the new services.
Some of the applications and services were being used from the current cloud platform's marketplace. They were initiated as an instance and shared credentials through the cloud platform's manifest and environment variables.
They also had built a very complex custom authentication layer to generate authentication tokens for their external applications. This was a built-in application on top of the cloud platform. It was a complex application, and it was the biggest challenge we had for migration because most of the 3,000 applications were using it somehow; it was included as a library in most of them.
This appeared to be a good candidate for our pilot because it was the most complex application. Migrating this first set us on the path for any other challenging kind of deployment on the platform.
Handling dependencies
Next, we took all of our findings and tried to map them to Kubernetes. We decided to move the custom authentication into Kubernetes. We used external services again but added some of the services that were built into the cloud platform to the external services. We created them as external servers using an operator in Kubernetes and changed the code to use the service.
[ Benchmark yourself against your competitors. Read Kubernetes adoption, security, and market trends report 2021. ]
From there, we could build the CI/CD pipeline and have the entire automation happen on top of Kubernetes. That was the gap analysis we did from a platform perspective and for identifying the service, which is the most critical part from an assessment perspective for moving to Kubernetes.
CI/CD pipeline
We didn't find a traditional, straightforward CI/CD pipeline in the existing cloud platform. They had so many integrations with Jira and other ticket systems, quality assurance tools, and release management solutions. From an enterprise perspective, the objective is to have all the control points to be able to control the deployment.
To facilitate this goal, we needed the same control points in Kubernetes. We shifted to a Kubernetes-native CI/CD solution, thinking through the stages in a new way.
We mapped the CI/CD pipeline from a Kubernetes perspective to what they had before while also creating the gateways they have from an approval perspective.
Key takeaways
We learned many things through this migration, but our top lessons were:
- Automation is key for the assessment and migration of large numbers of applications.
- Creating a migration factory with more automation tools is very important.
- Early success, which is moving one application to a pilot, showing it to the architects, and explaining it, opens new ways of looking at things and is the key to migrating more applications.
If you'd like to learn more about migrating large numbers of applications to Kubernetes, watch my full presentation to the Konveyor community.