Containers and services deployed in a cluster with boot logs

Technical log · service migration

Migrating a legacy service to containers: recurring mistakes

Assumptions about state, networking, and startup that break the first version

The container starts on the laptop without a hitch. You push it to the cluster and within minutes it begins restarting. It is almost never a runtime problem: it is the legacy service that took for granted things that no longer exist in a pod. Absolute paths pointing to a disk that is not mounted, a configuration file that was written to /var/lib/app and now lives in an ephemeral layer, or a connection to a database that was resolved by the old server's hostname.

Before exposing traffic, it is worth going through three fronts. First, state: check what the process writes to disk and whether that survives a pod restart. Second, networking: list every outbound dependency and confirm that it resolves inside the cluster, not through an inherited hosts file. Third, startup: measure how long the service takes to accept the first real request, not to open the port.

That last point is the one that causes the most headaches. Many legacy services open the socket before they finish loading caches, indexes, or connection pools. If the readiness probe only checks that the port responds, it will send traffic to a process that is not ready yet, and you will see intermittent errors that do not show up locally. Liveness, for its part, should not restart a slow startup: separate the timings and let readiness do the work of holding back traffic.

Environment configuration is another point where the image breaks. If the service reads environment variables, paths, or credentials embedded in the build, every change forces a rebuild. It is better to move everything that changes between environments into variables or a mounted volume, and leave in the image only what is the same everywhere. That way the same artifact goes through staging and production without surprises.

None of this is textbook theory: these are the patterns that show up again and again when a service that ran for years on a VM moves to a cluster. The verification sequence before exposing traffic saves most of the cascading restarts.

Migrating a legacy service to containers: recurring mistakes

Before going further, it is worth clarifying the scope. What follows are failure patterns that appear again and again when a service that ran on its own machine moves into a container inside a cluster. It is not a universal containerization manual nor a recipe that works the same on any stack. It is a list of assumptions that old code took for granted and that stop being true as soon as the runtime environment changes.

We are talking about services with years behind them, written without thinking about orchestrators: processes that write to disk, that read absolute paths, that assume the internal network is stable, or that take longer to start than a probe tolerates. If your case is a new service, designed from the start to run in containers, much of this will not apply to you. If you are moving something legacy, you will probably recognize more than one point.

Containers and services deployed in a cluster with startup logs

Migrating a legacy service to containers: recurring mistakes

Assumptions about state, networking, and startup that break the first version. These are the signals that appear again and again when the container works locally but the cluster restarts it without mercy.

Containers and services deployed in a cluster with startup logs Paths and state

The code wrote to /var/lib and now that disk is ephemeral

Screen with configuration files and highlighted change plan Startup

The liveness probe fires before the service finishes loading

Monitoring dashboard with metric charts and event logs Networking

Dependencies that assumed internal DNS and fixed host ports

Message flow diagram between producers and consumers Configuration

Rebuilding the image to change an environment variable

Migrating a legacy service to containers: mistakes that keep repeating

Independent technical log

This entry on migrating legacy services to containers is signed by the engineering team that maintains the log. There is no single named person behind each text: what gets published comes from real production work and is reviewed by several people before it goes up.

The rule is simple. If a configuration snippet, a dashboard screenshot, or a tool comparison was not tested in an environment with traffic, it does not go in. There is no sponsorship either: when a vendor is mentioned, it is because it was part of the scenario being documented, not because it paid for the space.

The topics covered most often are Kubernetes, Terraform, observability, message queues, instance costs, and the mistakes that keep repeating when moving legacy services to distributed architectures. The natural audience is platform teams, SREs, and backend developers who need concrete decisions rather than a theoretical introduction.

If you want to follow along, there is a weekly newsletter with new posts, and searching by tags such as networking, storage, or CI/CD helps you get straight to what interests you.

Cookie settings

We use cookies to keep the site stable, remember basic options, and understand which pages are useful. You can accept, reject, or review the settings before continuing.