별칭을 추가한 후 물류 호스트 이름이 깨짐 (DNS 전환 제약)

작성자

카테고리:

← 피드로
DEV Community · QuintonShaw1483 · 2026-09-25 개발(SW)

Short answer: restore the hostname by removing the newly introduced CNAME or the other data at the same owner name, then wait for authoritative answers to become internally consistent before resuming the cutover. A CNAME is an alias boundary: except for DNSSEC-related records, it cannot coexist with other data at that name. At a zone apex, the mandatory SOA and NS records already occupy the name, so an ordinary CNAME is the wrong mechanism. For a logistics migration, the least complex safe option is usually to keep the apex as address data, delegate traffic through a separate hostname, and move one low-risk label before touching dispatch or tracking endpoints.

The page says tracking.example.test is down just after a registrar-API migration. The on-call sees a synthetic probe failing, but the first useful question is narrower: did the authoritative data become invalid, or are recursive resolvers still serving an older valid answer? Stop writes, preserve the last known-good zone, query every authoritative server directly, and compare record type, target, TTL, serial, and response code. Do not accelerate a cutover merely because one resolver already shows the desired value.

What broke the hostname after adding a DNS record?

The customer-visible page is late. By then, a scanner at a depot may be unable to resolve a tracking hostname, a carrier callback may be reaching the previous address, or different recursive resolvers may disagree. An HTTP availability check confirms impact, but it cannot distinguish an alias conflict from propagation, an application failure, or a stale cached answer.

DNS was the suspect, not yet the verdict.

The earlier signal belongs at the zone-change boundary. Before accepting a change, validate the entire resulting record set, not just the submitted row. A request to add a CNAME can look harmless in isolation while colliding with an existing A, AAAA, TXT, MX, NS, or other record at the same owner name. RFC 1034 states the governing rule: if a CNAME resource record is present at a node, no other data should be present. RFC 2181 sharpens the operational reading by saying an alias must not coexist with data of another type. DNSSEC introduces narrowly defined exceptions for records that prove the alias, not permission to mix ordinary service data beside it.

This is where registrar-specific APIs create avoidable blind spots. One API may model a zone as independent records, another may replace a record set, and an import/export path may normalize names or TTLs. The portable object is the intended DNS zone and its invariants, not the sequence of API calls used to construct it. A migration controller should therefore render the proposed final state, validate it, and only then translate it into provider operations.

Freeze the rollout.

The page should have been preceded by a rejected-change event carrying the owner name and conflicting types. If rejection is impossible because the external control plane accepts the write, emit a high-severity pre-cutover alert before traffic moves. One precise alert is cheaper than ten ambiguous endpoint alarms.

Trace the answer from authority to cache

Start with authoritative servers because they define the published state. Query each one directly for the affected name and for the relevant types; then query the zone’s SOA record and compare serial values. If authoritative servers disagree, the change has not converged within the authoritative system. If they agree while recursive resolvers differ, caches are the likely boundary, and the remaining wait depends on previously cached TTLs rather than the new TTL alone.

That last distinction catches teams under deadline pressure. Lowering a TTL immediately before a move does not shorten the lifetime of answers that resolvers cached earlier under the old, longer TTL. The useful sequence is to reduce TTL, wait long enough for the previous TTL horizon to pass, verify the lower TTL from independent recursive paths, and only then change the answer. Raising the TTL after stability restores cache efficiency.

There is no retroactive shortcut.

Negative answers deserve the same discipline. RFC 2308 defines negative caching using SOA data. A name that briefly returned NXDOMAIN during a delete-then-create sequence can remain negatively cached even after the desired record exists. Avoiding an empty intermediate state is therefore part of the cutover design, not housekeeping.

For an apex failure, inspect the shape before inspecting propagation. The apex has SOA and NS data by definition, which conflicts with an ordinary CNAME. Some DNS control planes offer provider-specific apex alias behavior, but that is not a CNAME resource record with standard wire semantics. Treat such behavior as a portability decision: document it explicitly, test export behavior, and decide whether faster apex cutovers justify a dependency that another authoritative implementation may not reproduce.

Put the invariant in the deployment path

The following Go check operates on a rendered zone snapshot. It deliberately rejects a CNAME alongside any other type at the same normalized owner name; a production validator can add DNSSEC-aware exceptions only if the signing design requires them. Keeping the default strict makes migration failures legible.

package main

import (
    "fmt"
    "strings"
)

type Record struct {
    Name string
    Type string
}

func validateAliases(records []Record) error {
    typesByName := map[string]map[string]bool{}
    for _, record := range records {
        name := strings.ToLower(strings.TrimSuffix(record.Name, "."))
        recordType := strings.ToUpper(record.Type)
        if typesByName[name] == nil {
            typesByName[name] = map[string]bool{}
        }
        typesByName[name][recordType] = true
    }

    for name, types := range typesByName {
        if types["CNAME"] && len(types) > 1 {
            return fmt.Errorf("%s mixes CNAME with other record types", name)
        }
    }
    return nil
}

func main() {
    zone := []Record{
        {Name: "tracking.example.test.", Type: "CNAME"},
        {Name: "tracking.example.test.", Type: "TXT"},
    }
    if err := validateAliases(zone); err != nil {
        panic(err)
    }
}

Enter fullscreen mode Exit fullscreen mode

Validation needs two passes. The static pass checks the rendered state for CNAME exclusivity, apex constraints, in-zone targets, and required records. The live pass queries every authority after publication and compares observed answers with the approved plan. Neither pass should infer success from a control-plane API returning success; that response proves acceptance of a request, not globally consistent DNS answers.

Instrument four moments: proposed state validated, authoritative write acknowledged, all authorities converged, and external recursive probes converged. Record elapsed time between them. The SLO should attach to the outcome the platform owns, such as authoritative convergence within the planned window, while recursive-cache observations remain a distribution with a deadline derived from prior TTLs. Otherwise the team promises a deterministic global propagation time for infrastructure it does not control.

Keep the evidence compact enough for an on-call to use at 03:00: change identifier, zone, owner name, old and new record-set hashes, authority list, SOA serials, and the last observation from each probe class. Avoid placing full zone contents in routine alerts; they add noise and may expose unrelated operational names.

Choose cutover speed without spending the error budget

The primary decision is propagation delay versus cutover speed, but the options do not buy the same risk. A logistics platform with two engineers carrying the DNS rotation should value reversible changes and bounded pages more heavily than a theoretically instant move. Fast is useful only when rollback is equally clear. My decision rule would favor a staged non-apex alias for tracking traffic because it permits parallel observation, while retaining an address-based apex when clients require the bare domain. The explicit trade-off is extra naming indirection and a longer planned overlap in exchange for a rollback that does not depend on replacing an invalid mixed record set during an incident.

Approach Cutover behavior On-call load Portability Decision rule Pre-stage a new hostname, then switch clients or an existing non-apex alias Allows observation before the final switch Lower; old and new paths can be checked in parallel High when it uses standard records Prefer for dispatch and tracking paths when clients can follow the indirection Change apex A and AAAA data Direct, but cached old addresses can overlap with new answers Moderate; both destinations must remain valid during the cache horizon High Use when the service exposes stable addresses and the overlap is safe Use provider-specific apex alias behavior Can simplify a dynamic apex target Higher during future moves because semantics and export behavior vary Lower Accept only with an explicit exit test and an owner for the dependency Operate authoritative DNS infrastructure Gives maximum policy control Highest; capacity, upgrades, abuse handling, DNSSEC, and 24-hour response become team work High at the data-model layer Build only when control requirements outweigh the durable on-call cost

This is a buy-versus-build decision, but invoice price is not the main variable. Capacity planning must include query peaks after cache expiry, the failure-domain layout of authorities, rollout concurrency across zones, and the human capacity to investigate partial convergence. A managed control plane can reduce routine operations while increasing API and behavior dependency; self-operation preserves control while moving reliability work onto the same team conducting the migration. Neither choice removes the CNAME invariant.

The staged approach has limitations. It is not suitable when clients have a hard-coded apex, when both destinations cannot safely serve overlapping traffic, or when changing the client-visible hostname is outside the team’s control. Address records avoid the alias collision but require stable service addresses and careful dual-serving during cache overlap. Provider-specific apex behavior can fit a dynamic target, yet its downside is a portability test that must be repeated before the next control-plane move. Those boundaries matter more than the convenience of the initial write.

For the logistics cutover, use a small canary zone or a noncritical label first, then advance in batches. A batch of one reveals model and translation errors. Larger batches become reasonable only after observed authoritative convergence and rollback time fit the change window. Freeze unrelated edits during each batch so the zone diff remains attributable.

When should the migration resume?

Resume only when the rendered zone passes the alias check, every authoritative server returns the approved record set and SOA state, and the old destination remains capable of serving traffic for the full cache horizon established before the change. A public recursive resolver returning the new answer is supporting evidence, not the gate by itself.

Rollback follows the same rule. Restore a complete known-good record set rather than attempting another isolated mutation, verify authorities, and keep both application destinations healthy until cached answers can no longer select the abandoned path. For mail-related labels, preserve TXT records such as DMARC at their specified owner names; RFC 7489 defines DMARC discovery and record placement, and an alias redesign must not casually erase that policy data.

The threshold for recursive-probe disagreement needs restraint. Page immediately on authoritative inconsistency or an invalid rendered zone. For recursive observations, alert only when disagreement persists beyond the TTL-derived expectation or correlates with user-visible failure; short-lived disagreement during a planned overlap is telemetry, not necessarily an incident.

Bad thresholds have a real capacity cost. Sampling many public resolvers every few seconds produces duplicate pages for normal cache behavior, trains responders to distrust DNS alerts, and consumes the same on-call attention needed for a genuine authority split. Sampling too slowly hides a bad publication behind the application alarm. Set probe frequency from the change window and error budget, retain enough samples to distinguish a trend from one resolver, and review the threshold after each migration batch.

The final guardrail is plain: a hostname move is complete when the DNS state is valid and observed across the boundaries named in the plan, not when the write API says it is done. That standard slows the first few minutes of a cutover. It also prevents an invalid alias from turning a fast migration into a long outage.

Further reading

원문에서 계속 ↗