Kubernetes manifest development: Deployment, Service, Ingress, Secret

Manual editing of resources directly in the cluster leads to discrepancies: environments differ, rollout breaks, and it takes hours to find the cause. We develop Kubernetes manifests turnkey — declaratively, with checks and a clear update order. This reduces rollout time and eliminates a whole class of failures as load grows.

Our competencies:

Frequently Asked Questions

Latest works

  • Development of a web application for FEEDME
    Development of a web application for FEEDME
    1365
  • Development of an online store for the company FURNORO
    Development of an online store for the company FURNORO
    1330
  • B2B Advance company logo design
    B2B Advance company logo design
    776
  • Development of a web application for Enviok
    Development of a web application for Enviok
    1077
  • AIDER company logo development
    AIDER company logo development
    1022
  • CRM development for Chasseurs
    CRM development for Chasseurs
    1113

Why Kubernetes manifests break during scaling

A rollout that passed without remarks in the test environment fails in production at the very first step.

Formally these are the same Kubernetes manifests from the repository, but the cluster returns an error: limits do not match the actual load, Service selectors do not find pods, and Ingress points to a class that does not exist in this environment. A rollout failure looks accidental, although the cause accumulated in advance.

Environment drift starts with small things. In the test environment there are fewer replicas, softer limits, Secret assembled from a different set of keys, Ingress rules trimmed to a single host.

Kubernetes does not compare environments with each other — it faithfully executes what is described, so different values for Deployment and Service diverge silently, until the first real traffic.

Then manual resource edits appear. Someone edits limits directly in the cluster to resolve an incident, someone adds an annotation, someone changes the image to a previous one. The cluster becomes the only source of truth, and the repository becomes an outdated copy.

Environment reproducibility is lost: a new environment cannot be brought up from the same files, and rollback to the previous release is impossible because the previous description was not saved.

The cost of such a scheme is a growing number of rollout failures and the time spent investigating divergences instead of working on the product.

We break down how this is closed: a single resource description, manifest validation before application, and drift control between environments.

Measurable effects of managed configuration

Declarative resource description changes not the convenience of work, but measurable operational metrics. Rollout time decreases because the new state is applied as a whole, rather than assembled step by step from manual commands.

The same set of descriptions goes through the same path in test and production environments, so environment drift stops being a source of surprises.

Rollback speed depends not on the on-call engineer's composure, but on the availability of the previous working revision.

When configuration is versioned together with code, rollback is one predictable action: the saved description is applied, and the cluster itself brings resources to the required state. This way the share of successful rollbacks grows through procedure, not heroics.

The share of manual errors falls where a change is first validated for correctness and only then reaches the cluster.

A typo in an object name, a forgotten parameter, an extra "in-place" edit via the console — this class of failures simply disappears because the description remains the source of truth, not the engineer's live memory.

Environment stability rests on reproducibility: identical descriptions produce the same result on repeated deployment, not an "approximately similar" one.

Hence the impact on downtime cost — what goes away is not recovery time as such, but an entire class of incidents related to undiscovered configuration drift.

This can be checked by four numbers: rollout time, time to return to the previous revision, share of changes that passed validation before application, and number of incidents caused by manual edits.

These are the exact metrics we record before and after moving resources to a declarative form — so the effect is visible in numbers, not feelings.

Resource description options: comparison of approaches

While there is one service and one environment, any resource description method works the same. The difference appears with dozens of services and two or three environments: it becomes important where truth comes from and what will happen on the next change. Therefore the approach is chosen by maintenance cost, not by the convenience of the first rollout.

Alternatives that teams actually choose between:

Option When it fits Limitations of the approach
Manual files and kubectl apply one or two services, one environment, one-off tasks copy-paste between environments, changes are not reproducible, description templates are not fixed
Templates with substitutions many similar services, different environments, versions and rollback needed branching logic in templates, debugging only through a test render, readability drops
Overlays and patches on top of a base configuration a standard base plus per-environment differences patches overlap each other, the order of overlay is kept in one's head
Generation from a single description source many services, standard resource composition requires a custom generator and its maintenance, non-standard cases are still written manually

In practice, a hybrid wins: the standard set — Deployment, Service, Ingress — is generated from a single description source, while special cases such as a Secret from an external store remain separate files.

There is one rule: each resource must have a single source, otherwise manual maintenance returns, and divergences between environments become a matter of time.

Implementation order: from audit to handover

The work proceeds sequentially: each stage relies on the result of the previous one, so a skipped inventory surfaces already in production — through resource conflicts and manual edits.

Below is the order in which manifests become managed configuration rather than a set of files "for the current release."

  1. Resource audit. We collect the actual state of the cluster: which Deployment, Service, Ingress, and Secret exist, what was created manually, where duplicates are, how limits and probes are set. The output is a resource map marked with what is transferred to the declarative description and what is decommissioned.
  2. Environment scheme. We mark out environments and their differences: which values are moved out separately, what is overridden by overlay, where secrets are stored. This removes copying manifests between environments and the divergences that accumulate during manual edits.
  3. Policy setup. We define naming and label rules, resource requests and limits, access separation, and manifest validation before application — in the repository and at cluster entry, with the scope calculated individually.
  4. Build and review of manifests. We describe Deployment, Service, Ingress, and Secret as versioned files, run static checks and change review: configuration changes go through the same path as code.
  5. Validation in the test environment. We roll out the full set in the test environment, check update without downtime, rollback to the previous revision, and behavior when a node is unavailable. We catch configuration errors here, not in production.
  6. Handover of maintenance. We hand over the repository, the environment scheme description, and the change procedure, and train the team: how to add a service, how to release and roll back a release, where to look during a failure.

After handover, you are left with a reproducible configuration and a team that can change it without us.

Deliverables: configurations, diagrams, access policies

Manifests without an accompanying package quickly turn into archaeology: six months later no one remembers why the Deployment has exactly these limits, where the namespace came from, and who is allowed to edit the Secret.

Therefore the deliverables package is not only YAML files, but a package by which your team deploys the environment from scratch and maintains it without us.

  • Resource descriptions — Deployment, Service, Ingress, ConfigMap, Secret, HorizontalPodAutoscaler: arranged in directories without duplicates, with comments on non-obvious parameters — update strategy, readiness probes, requests, and limits.
  • Environment scheme — which namespaces exist, how dev differs from stage and prod, where shared resources live, and how configurations are separated between environments.
  • Access policies — RBAC roles and bindings, network isolation rules between services, namespace quotas: described who can change what in the cluster.
  • Secret management — where values come from, how they get into the cluster, how they are rotated, and who has read permission.
  • Update procedure — rollout order, image versioning, conditions for rollback to the previous revision, and system behavior during a failed update.
  • Documentation — a brief architecture description, instructions for deployment and typical operations: pod diagnostics, scaling, connecting a new service.

Case: rollout time and the class of eliminated failures

The customer is a product team with a dozen services: Kubernetes manifests were edited manually for each environment, and rollout went step by step from a local console.

A release took 40–50 minutes, divergences between environments accumulated unnoticed and surfaced already in production. Returning to the previous state was a separate 15–20 minute operation, and it had to be done in a hurry when something was already broken.

What the review showed

Half of the failures were configuration drift: edits made directly in the cluster lived in parallel with the files and diverged from them. A quarter were the absence of readiness checks, because of which traffic reached a service that had not yet started. The rest were secrets with different values in the development environment and production.

What was changed

Descriptions moved to the repository, shared values were separated from environment-specific ones, and secrets went into a managed store by reference instead of copies.

Readiness and liveness checks were added, rollout became staged with automatic stop when metrics deviate, and rollback became a return to the previous set of descriptions.

Release time decreased from 40–50 minutes to 6, and return to the previous state to a minute and one operation.

Configuration drift disappeared as a class: any change now goes through the repository and validation.

The share of releases requiring manual intervention dropped to isolated cases per quarter, and an incomplete rollout stopped being a failure — it completes normally with rollback on its own.

How does declarative resource description differ from manual editing in the cluster?

Kubernetes manifests are a declarative description of the desired state of a resource: how many replicas to keep, which image to use, which ports to open, and which Secret to connect.

The cluster compares the description with the actual state and brings it to the required form itself — manual intervention is not required and is even harmful.

Manual editing works the opposite way. An engineer changes a live object via the command line, and the cluster state begins to be assembled from a set of changes that are not in any file.

Then either the controller returns the resource to the manifest and the edit "flickers," or the divergence remains — and surfaces when the environment is recreated, when the required annotations and parameters disappear.

The difference between the approaches comes down to where the source of truth is. With a declarative description, it is a file in the version control system: a change goes through editing, validation, and application, and the cluster remains derived from the description.

With manual editing, the cluster itself becomes the source of truth, and no one knows exactly what settings have accumulated there and why.

In operations this changes two things. Drift stops being a mystery: the divergence is visible when comparing the description with the fact, and recovery after a failure comes down to applying the same files.

The change history answers who changed the configuration and when, and rollback goes to the previous version of the description, not to the on-call engineer's memory.

Common technical concerns about Kubernetes manifests

Technical concerns before bringing order to Kubernetes manifests almost never concern syntax. The customer is worried about the cost of an error: what will happen to already running workloads, who will see the secrets, whether access policies will have to be rewritten. Below are four questions that come up in every review and how we address them.

Secrets are stored directly in descriptions — what happens during migration?

Values are moved into separate objects and connected by references — only names remain in the repository and change history. We grant access to them by roles, enable encryption in the cluster store and rotation, and every read is recorded in the audit log.

Can production be migrated without downtime?

The update proceeds gradually: new application copies start receiving traffic only after a successful readiness check, and the old ones are terminated afterwards. Rollback is returning the previous set of descriptions from the repository; a maintenance window is not required.

The environments have diverged — the test does not replicate production?

We remove divergences with a shared description base: environments differ only in parameters — number of copies, limits, addresses — and not in object structure. Automatic reconciliation in the build catches drift immediately, not a month later.

What will happen to existing roles and access policies?

Roles and bindings are transferred declaratively, without expanding permissions; we describe already running objects and gradually bring them to a common form without stopping them.

Before handover, we compare the set of permissions for each environment with the current state and separately record anything excessive.

Let's discuss the task: order of starting work

The first conversation is not a presentation, but a reconciliation of inputs: without them, any estimate turns into guesswork.

To calculate the scope of work for Kubernetes manifests, we need to see the entire landscape — from environments to how a release currently reaches the cluster.

  • List of environments and clusters: dev, stage, prod, differences by namespaces, resource limits, and access policies.
  • How deployment is set up today: manual application, build pipeline, Helm, or declarative management from a repository — the scope of work directly depends on this.
  • Requirements for secrets and configuration: where values come from, whether integration with an external store is needed, who gets access and how.
  • Network landscape: domains, certificates, routing rules, who issues them, and how they are updated.
  • Requirements for updates and rollback: rollout strategy, readiness checks, acceptable service unavailability window.
  • Who on the customer side confirms decisions and how quickly test environments are available for validation.

Based on these inputs, we come back not with an approximate range, but with a plan: team composition, stages, timelines for each, and what will be required from you at each step. Describe the task — we will come back with an estimate and a plan.