<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Ttl on DevOps Way - Практические гайды</title>
    <link>https://devopsway.ru/tags/ttl/</link>
    <description>Recent content in Ttl on DevOps Way - Практические гайды</description>
    <image>
      <title>DevOps Way - Практические гайды</title>
      <url>https://devopsway.ru/images/devopsway-og.png</url>
      <link>https://devopsway.ru/images/devopsway-og.png</link>
    </image>
    <generator>Hugo -- 0.164.0</generator>
    <language>ru</language>
    <lastBuildDate>Thu, 16 Jul 2026 19:04:25 +0300</lastBuildDate>
    <atom:link href="https://devopsway.ru/tags/ttl/feed.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Networking 20/80, уровень 2: DNS – как имена становятся адресами</title>
      <link>https://devopsway.ru/posts/networking-02-dns/</link>
      <pubDate>Thu, 16 Jul 2026 12:00:00 +0300</pubDate>
      <guid>https://devopsway.ru/posts/networking-02-dns/</guid>
      <description>Третий уровень мини-курса по сетям для DevOps: иерархия DNS и порядок резолвинга на Linux, ключевые типы записей, TTL, dig и CoreDNS в Kubernetes (включая ловушку ndots:5). Три подвоха с собеседования и чеклист диагностики &amp;#39;почему не резолвится&amp;#39;.</description>
      <content:encoded><![CDATA[<p>Третий из семи уровней мини-курса &quot;Networking 20/80&quot;. На прошлом уровне научились считать подсети и адреса. Но в реальной работе ты пишешь <code>curl http://api.example.com</code>, а не голый IP. Сегодня – как имя превращается в адрес (кеш браузера → <code>/etc/hosts</code> → кеш ОС → DNS-сервер)<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>, почему это одна из самых частых причин инцидентов и как за минуту находить, где именно порвалось.</p>
<blockquote>
<p>&quot;DNS – это телефонная книга интернета. Но в отличие от телефонной книги, она распределена по миллионам серверов и обновляется каждую секунду. И когда она ломается – ломается всё.&quot;</p>
</blockquote>
<hr>
<h2 id="откуда-это-пошло">Откуда это пошло</h2>
<p><strong>1973 – HOSTS.TXT.</strong> Весь ARPANET – несколько сотен компьютеров. Все имена и адреса хранятся в одном файле <code>HOSTS.TXT</code> на сервере SRI-NIC (Stanford Research Institute). Каждый администратор скачивает этот файл по FTP, чтобы обновить таблицу имён. Работает, пока хостов мало.</p>
<p><strong>1983 – Проблема масштаба.</strong> ARPANET растёт. HOSTS.TXT обновляется раз в несколько дней. Конфликты имён. Один файл не масштабируется.</p>
<p><strong>1983 – Paul Mockapetris (USC) изобретает DNS (RFC 882, 883).</strong> Идея: иерархическая распределённая система. Вместо одного файла – дерево серверов. Каждый отвечает за свою зону. <code>.com</code> знает про <code>example.com</code>, <code>example.com</code> знает про <code>api.example.com</code>.</p>
<p><strong>Наследие:</strong> файл <code>/etc/hosts</code> – прямой потомок HOSTS.TXT. ОС до сих пор проверяет его ПЕРЕД DNS-запросом.</p>
<hr>
<h2 id="иерархия-dns">Иерархия DNS</h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">                    . (root)
</span></span><span class="line"><span class="cl">                    │
</span></span><span class="line"><span class="cl">        ┌───────────┼───────────┐
</span></span><span class="line"><span class="cl">        │           │           │
</span></span><span class="line"><span class="cl">       com         org         ru
</span></span><span class="line"><span class="cl">        │           │           │
</span></span><span class="line"><span class="cl">    ┌───┴───┐   ┌──┴──┐    ┌──┴──┐
</span></span><span class="line"><span class="cl"> example  google  wiki   yandex  yadro
</span></span><span class="line"><span class="cl">    │       │      │       │       │
</span></span><span class="line"><span class="cl">   api    mail    en      mail     hr
</span></span></code></pre></div><h3 id="как-резолвится-apiexamplecom">Как резолвится <code>api.example.com</code></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">1. Приложение: &#34;мне нужен IP для api.example.com&#34;
</span></span><span class="line"><span class="cl">   └─ Проверяет свой кеш (браузер/приложение) → не найдено
</span></span><span class="line"><span class="cl">   └─ Проверяет /etc/hosts → не найдено
</span></span><span class="line"><span class="cl">   └─ Проверяет кеш ОС (резолвер: systemd-resolved / nscd) → не найдено
</span></span><span class="line"><span class="cl">   └─ Отправляет запрос DNS-серверу из /etc/resolv.conf
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">2. Recursive resolver (обычно 8.8.8.8 или провайдер):
</span></span><span class="line"><span class="cl">   └─ Кеш? Нет → спрашивает root server (.)
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">3. Root server (.): &#34;я не знаю api.example.com,
</span></span><span class="line"><span class="cl">   но .com обслуживают серверы a.gtld-servers.net&#34;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">4. TLD server (.com): &#34;я не знаю api.example.com,
</span></span><span class="line"><span class="cl">   но example.com обслуживают ns1.example.com (93.184.216.1)&#34;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">5. Authoritative server (ns1.example.com):
</span></span><span class="line"><span class="cl">   &#34;api.example.com = 93.184.216.34, TTL=300&#34;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">6. Recursive resolver кеширует на 300 секунд,
</span></span><span class="line"><span class="cl">   возвращает ответ приложению.
</span></span></code></pre></div><h3 id="порядок-резолвинга-на-linux">Порядок резолвинга на Linux</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">/etc/nsswitch.conf:
</span></span><span class="line"><span class="cl">hosts: files dns        ← СНАЧАЛА файл (/etc/hosts), ПОТОМ DNS
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">/etc/hosts:             ← Проверяется первым!
</span></span><span class="line"><span class="cl">127.0.0.1   localhost
</span></span><span class="line"><span class="cl">10.0.0.5    api.local   ← Этот адрес вернётся БЕЗ DNS-запроса
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">/etc/resolv.conf:       ← DNS-серверы
</span></span><span class="line"><span class="cl">nameserver 8.8.8.8
</span></span><span class="line"><span class="cl">nameserver 8.8.4.4
</span></span><span class="line"><span class="cl">search example.com      ← При запросе &#34;api&#34; дополнит до &#34;api.example.com&#34;
</span></span></code></pre></div><hr>
<h2 id="типы-dns-записей--20-покрывают-80">Типы DNS-записей – 20% покрывают 80%</h2>
<table>
	<thead>
			<tr>
					<th>Тип</th>
					<th>Что хранит</th>
					<th>Пример</th>
					<th>Когда используется</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td><strong>A</strong></td>
					<td>IPv4-адрес</td>
					<td><code>api.example.com → 93.184.216.34</code></td>
					<td>Основная запись</td>
			</tr>
			<tr>
					<td><strong>AAAA</strong></td>
					<td>IPv6-адрес</td>
					<td><code>api.example.com → 2606:2800:220:1:...</code></td>
					<td>IPv6</td>
			</tr>
			<tr>
					<td><strong>CNAME</strong></td>
					<td>Алиас → другое имя</td>
					<td><code>www.example.com → example.com</code></td>
					<td>Перенаправление</td>
			</tr>
			<tr>
					<td><strong>MX</strong></td>
					<td>Mail-сервер</td>
					<td><code>example.com → mail.example.com (pri 10)</code></td>
					<td>Почта</td>
			</tr>
			<tr>
					<td><strong>TXT</strong></td>
					<td>Текст</td>
					<td><code>example.com → &quot;v=spf1 ...&quot;</code></td>
					<td>SPF, DKIM, верификация</td>
			</tr>
			<tr>
					<td><strong>NS</strong></td>
					<td>DNS-сервер зоны</td>
					<td><code>example.com → ns1.example.com</code></td>
					<td>Делегирование</td>
			</tr>
			<tr>
					<td><strong>SRV</strong></td>
					<td>Сервис + порт</td>
					<td><code>_http._tcp.example.com → 0 5 8080 api.example.com</code></td>
					<td>Обнаружение сервисов (service discovery)</td>
			</tr>
			<tr>
					<td><strong>PTR</strong></td>
					<td>Обратная запись (IP → имя)</td>
					<td><code>34.216.184.93 → api.example.com</code></td>
					<td>Обратный DNS (reverse DNS)</td>
			</tr>
			<tr>
					<td><strong>SOA</strong></td>
					<td>Start of Authority</td>
					<td>Serial, refresh, retry, expire</td>
					<td>Метаданные зоны</td>
			</tr>
	</tbody>
</table>
<hr>
<h2 id="dig--главный-инструмент-dns-диагностики">dig – главный инструмент DNS-диагностики</h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Базовый запрос:</span>
</span></span><span class="line"><span class="cl">dig api.example.com
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># ;; ANSWER SECTION:</span>
</span></span><span class="line"><span class="cl"><span class="c1"># api.example.com.  300  IN  A  93.184.216.34</span>
</span></span><span class="line"><span class="cl"><span class="c1">#                    │        │  └── IP-адрес</span>
</span></span><span class="line"><span class="cl"><span class="c1">#                    │        └── тип записи</span>
</span></span><span class="line"><span class="cl"><span class="c1">#                    └── TTL (секунд до протухания кеша)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Короткий формат (только ответ):</span>
</span></span><span class="line"><span class="cl">dig +short api.example.com
</span></span><span class="line"><span class="cl"><span class="c1"># 93.184.216.34</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Конкретный тип записи:</span>
</span></span><span class="line"><span class="cl">dig MX example.com
</span></span><span class="line"><span class="cl">dig TXT example.com
</span></span><span class="line"><span class="cl">dig NS example.com
</span></span><span class="line"><span class="cl">dig AAAA api.example.com
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Конкретный DNS-сервер:</span>
</span></span><span class="line"><span class="cl">dig @8.8.8.8 api.example.com
</span></span><span class="line"><span class="cl">dig @1.1.1.1 api.example.com    <span class="c1"># Cloudflare DNS</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Reverse DNS (IP → имя):</span>
</span></span><span class="line"><span class="cl">dig -x 93.184.216.34
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Трассировка (весь путь от root до ответа):</span>
</span></span><span class="line"><span class="cl">dig +trace api.example.com
</span></span><span class="line"><span class="cl"><span class="c1"># .                   NS    a.root-servers.net</span>
</span></span><span class="line"><span class="cl"><span class="c1"># com.                NS    a.gtld-servers.net</span>
</span></span><span class="line"><span class="cl"><span class="c1"># example.com.        NS    ns1.example.com</span>
</span></span><span class="line"><span class="cl"><span class="c1"># api.example.com.    A     93.184.216.34</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Все записи:</span>
</span></span><span class="line"><span class="cl">dig ANY example.com
</span></span></code></pre></div><h3 id="nslookup--старый-инструмент-но-спрашивают-на-собесе">nslookup – старый инструмент (но спрашивают на собесе)</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">nslookup api.example.com
</span></span><span class="line"><span class="cl"><span class="c1"># Server:    8.8.8.8          ← какой DNS отвечал</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Address:   93.184.216.34    ← результат</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">nslookup -type<span class="o">=</span>MX example.com
</span></span></code></pre></div><blockquote>
<p><strong>20/80:</strong> используй <code>dig</code>, не <code>nslookup</code>. <code>dig</code> показывает TTL, раздел авторитетных серверов (authority section), время запроса (query time) – всё, что нужно для диагностики (troubleshooting). <code>nslookup</code> – устаревший (deprecated), но знай его для собеса.</p>
</blockquote>
<hr>
<h2 id="ttl--time-to-live">TTL – Time To Live</h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">dig +short api.example.com
</span></span><span class="line"><span class="cl"><span class="c1"># 93.184.216.34</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">dig api.example.com <span class="p">|</span> grep -A1 <span class="s2">&#34;ANSWER&#34;</span>
</span></span><span class="line"><span class="cl"><span class="c1"># api.example.com.  300  IN  A  93.184.216.34</span>
</span></span><span class="line"><span class="cl"><span class="c1">#                    ^^^</span>
</span></span><span class="line"><span class="cl"><span class="c1">#                    TTL = 300 секунд = 5 минут</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Через 5 минут кеш протухнет, resolver спросит authoritative заново.</span>
</span></span></code></pre></div><h3 id="почему-ttl-важен-для-devops">Почему TTL важен для DevOps</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Сценарий: миграция api.example.com на новый сервер
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Старый IP: 10.0.0.5
</span></span><span class="line"><span class="cl">Новый IP:  10.0.0.50
</span></span><span class="line"><span class="cl">TTL: 86400 (24 часа)
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Проблема: после смены DNS-записи – 24 ЧАСА часть клиентов
</span></span><span class="line"><span class="cl">          ходит на старый сервер (кеш не протух).
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Решение: ЗА ДЕНЬ до миграции снизить TTL до 60 секунд.
</span></span><span class="line"><span class="cl">         После миграции – вернуть TTL обратно.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Порядок:
</span></span><span class="line"><span class="cl">1. TTL = 86400 → 60 (и подождать 24 часа, пока старый кеш протухнет)
</span></span><span class="line"><span class="cl">2. Изменить A-запись: 10.0.0.5 → 10.0.0.50
</span></span><span class="line"><span class="cl">3. Подождать 60 секунд (новый TTL)
</span></span><span class="line"><span class="cl">4. Проверить: dig +short api.example.com → 10.0.0.50
</span></span><span class="line"><span class="cl">5. TTL = 60 → 3600 (вернуть нормальное значение)
</span></span></code></pre></div><hr>
<h2 id="dns-в-kubernetes--coredns">DNS в Kubernetes – CoreDNS</h2>
<h3 id="как-k8s-резолвит-имена">Как K8s резолвит имена</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Pod → /etc/resolv.conf внутри pod-а:
</span></span><span class="line"><span class="cl">  nameserver 10.96.0.10          ← CoreDNS ClusterIP
</span></span><span class="line"><span class="cl">  search default.svc.cluster.local svc.cluster.local cluster.local
</span></span><span class="line"><span class="cl">  ndots:5
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Из pod-а можно обращаться к сервису по короткому имени:</span>
</span></span><span class="line"><span class="cl">curl http://api:8080           <span class="c1"># → api.default.svc.cluster.local</span>
</span></span><span class="line"><span class="cl">curl http://api.prod:8080      <span class="c1"># → api.prod.svc.cluster.local</span>
</span></span><span class="line"><span class="cl">curl http://api.prod.svc:8080  <span class="c1"># → api.prod.svc.cluster.local</span>
</span></span></code></pre></div><h3 id="формат-dns-имён-в-k8s">Формат DNS-имён в K8s</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">&lt;service&gt;.&lt;namespace&gt;.svc.cluster.local
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Примеры:
</span></span><span class="line"><span class="cl">api.default.svc.cluster.local         → ClusterIP сервиса api в namespace default
</span></span><span class="line"><span class="cl">postgres.database.svc.cluster.local   → ClusterIP postgres в namespace database
</span></span></code></pre></div><h3 id="ndots5--ловушка-для-devops">ndots:5 – ловушка для DevOps</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Внутри pod-а: curl http://api.example.com</span>
</span></span><span class="line"><span class="cl"><span class="c1"># ndots:5 означает: если в имени меньше 5 точек – добавь search domain</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># &#34;api.example.com&#34; содержит 2 точки (&lt; 5) →</span>
</span></span><span class="line"><span class="cl"><span class="c1"># K8s сначала попробует:</span>
</span></span><span class="line"><span class="cl"><span class="c1">#   api.example.com.default.svc.cluster.local    ← промах</span>
</span></span><span class="line"><span class="cl"><span class="c1">#   api.example.com.svc.cluster.local            ← промах</span>
</span></span><span class="line"><span class="cl"><span class="c1">#   api.example.com.cluster.local                ← промах</span>
</span></span><span class="line"><span class="cl"><span class="c1">#   api.example.com.                             ← успех!</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Это 4 лишних DNS-запроса! На высоконагруженных сервисах – bottleneck.</span>
</span></span></code></pre></div><p><strong>Решение:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Добавить точку в конце (FQDN – Fully Qualified Domain Name):</span>
</span></span><span class="line"><span class="cl">curl http://api.example.com.     <span class="c1"># ← точка = &#34;не добавляй search domains&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Или в K8s pod spec:</span>
</span></span><span class="line"><span class="cl">spec:
</span></span><span class="line"><span class="cl">  dnsConfig:
</span></span><span class="line"><span class="cl">    options:
</span></span><span class="line"><span class="cl">      - name: ndots
</span></span><span class="line"><span class="cl">        value: <span class="s2">&#34;2&#34;</span>
</span></span></code></pre></div><hr>
<h2 id="диагностика-dns-troubleshooting--чеклист">Диагностика DNS (troubleshooting) – чеклист</h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># 1. Резолвится ли имя вообще?</span>
</span></span><span class="line"><span class="cl">dig +short api.example.com
</span></span><span class="line"><span class="cl"><span class="c1"># Пусто = не резолвится</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 2. Какой DNS-сервер используется?</span>
</span></span><span class="line"><span class="cl">cat /etc/resolv.conf
</span></span><span class="line"><span class="cl"><span class="c1"># nameserver 10.96.0.10</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 3. Отвечает ли DNS-сервер?</span>
</span></span><span class="line"><span class="cl">dig @10.96.0.10 api.example.com
</span></span><span class="line"><span class="cl"><span class="c1"># ;; connection timed out → DNS-сервер недоступен</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 4. Authoritative сервер знает запись?</span>
</span></span><span class="line"><span class="cl">dig +trace api.example.com
</span></span><span class="line"><span class="cl"><span class="c1"># Покажет, на каком уровне обрыв</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 5. Кеш устарел? Проверить TTL:</span>
</span></span><span class="line"><span class="cl">dig api.example.com <span class="p">|</span> grep TTL
</span></span><span class="line"><span class="cl"><span class="c1"># Подождать TTL секунд и проверить снова</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 6. /etc/hosts перебивает DNS?</span>
</span></span><span class="line"><span class="cl">getent hosts api.example.com
</span></span><span class="line"><span class="cl"><span class="c1"># Показывает финальный результат (hosts + DNS)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 7. CoreDNS в K8s работает?</span>
</span></span><span class="line"><span class="cl">kubectl -n kube-system get pods -l k8s-app<span class="o">=</span>kube-dns
</span></span><span class="line"><span class="cl">kubectl -n kube-system logs -l k8s-app<span class="o">=</span>kube-dns --tail<span class="o">=</span><span class="m">20</span>
</span></span></code></pre></div><hr>
<h2 id="подвохи-для-собеса">Подвохи для собеса</h2>
<h3 id="подвох-1-чем-a-запись-отличается-от-cname">Подвох 1: &quot;Чем A-запись отличается от CNAME?&quot;</h3>
<p><strong>Ответ:</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">A-запись: имя → IP-адрес
</span></span><span class="line"><span class="cl">  api.example.com  →  93.184.216.34
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">CNAME: имя → другое имя (алиас)
</span></span><span class="line"><span class="cl">  www.example.com  →  example.com  →  93.184.216.34
</span></span><span class="line"><span class="cl">                       (ещё один lookup!)
</span></span></code></pre></div><p><strong>Ограничения CNAME:</strong></p>
<ol>
<li>CNAME <strong>нельзя</strong> ставить на корень домена (apex, <code>example.com</code> без www). Только на поддомены. Причина: CNAME конфликтует с SOA и NS записями на корне (apex).</li>
<li>CNAME – дополнительный DNS-запрос, а значит задержка (latency)</li>
</ol>
<p><strong>Альтернатива:</strong> AWS Route53 и Cloudflare поддерживают ALIAS/ANAME – работают как CNAME, но на корне домена (apex).</p>
<p><strong>На собесе:</strong> &quot;A-запись возвращает IP напрямую. CNAME – перенаправление на другое имя, требующее дополнительного разрешения (resolve). CNAME нельзя на корень домена (apex). Для балансировки – используют несколько A-записей (циклическая выдача, round-robin) или ALIAS.&quot;</p>
<hr>
<h3 id="подвох-2-почему-после-смены-dns-записи-часть-пользователей-видит-старый-адрес">Подвох 2: &quot;Почему после смены DNS-записи часть пользователей видит старый адрес?&quot;</h3>
<p><strong>Ответ:</strong> TTL кеширования.</p>
<p>DNS – система с согласованностью в конечном счёте (<strong>eventually consistent</strong>). Запись кешируется на TTL секунд:</p>
<ul>
<li>В резолвере (resolver, 8.8.8.8): до TTL</li>
<li>В ОС: до TTL (или перезагрузки)</li>
<li>В браузере: до TTL (Chrome кеширует до 60 секунд)</li>
<li>В Java приложении: <strong>НАВСЕГДА</strong> (по умолчанию JVM кеширует DNS бесконечно!)</li>
</ul>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Проверить текущий TTL:</span>
</span></span><span class="line"><span class="cl">dig api.example.com <span class="p">|</span> grep -E <span class="s2">&#34;^api&#34;</span>
</span></span><span class="line"><span class="cl"><span class="c1"># api.example.com.  127  IN  A  93.184.216.34</span>
</span></span><span class="line"><span class="cl"><span class="c1">#                    ^^^ осталось 127 секунд до протухания</span>
</span></span></code></pre></div><p><strong>На собесе:</strong> &quot;DNS кешируется на каждом уровне: резолвер (resolver), ОС, приложение. TTL определяет, как долго кеш жив. После смены записи нужно ждать TTL – или заранее снизить его. Особый случай – JVM, который по умолчанию кеширует DNS навсегда: нужен <code>networkaddress.cache.ttl=30</code> в политике безопасности (security policy).&quot;</p>
<hr>
<h3 id="подвох-3-что-произойдёт-если-dns-сервер-недоступен">Подвох 3: &quot;Что произойдёт, если DNS-сервер недоступен?&quot;</h3>
<p><strong>Ответ:</strong></p>
<ol>
<li><strong>Кешированные записи</strong> продолжат работать (до истечения TTL)</li>
<li><strong>Новые запросы</strong> к неразрешённым именам – ошибка (fail)</li>
<li><strong>Ошибки:</strong> <code>getaddrinfo: Name or service not known</code>, <code>NXDOMAIN</code> (или таймаут)</li>
<li><code>/etc/hosts</code> записи работают всегда (не зависят от DNS)</li>
</ol>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Симуляция: заблокировать DNS</span>
</span></span><span class="line"><span class="cl">sudo iptables -A OUTPUT -p udp --dport <span class="m">53</span> -j DROP
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Кеш ещё работает:</span>
</span></span><span class="line"><span class="cl">dig +short api.example.com    <span class="c1"># ответ из кеша</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Новый домен – fail:</span>
</span></span><span class="line"><span class="cl">dig +short new-service.example.com    <span class="c1"># timeout!</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Восстановить:</span>
</span></span><span class="line"><span class="cl">sudo iptables -D OUTPUT -p udp --dport <span class="m">53</span> -j DROP
</span></span></code></pre></div><p><strong>На собесе:</strong> &quot;Если DNS-сервер недоступен, кешированные записи продолжают работать до истечения TTL. Новые DNS-запросы будут отваливаться по таймауту. Поэтому в продакшене (production) всегда два DNS-сервера в resolv.conf. В K8s – CoreDNS с несколькими репликами.&quot;</p>
<hr>
<h2 id="код-челлендж">Код-челлендж</h2>
<p><strong>Задача:</strong> выполни DNS-диагностику и ответь:</p>
<ol>
<li>Какие DNS-серверы настроены на твоей машине? (<code>/etc/resolv.conf</code>)</li>
<li>Какой IP у <code>kubernetes.default.svc.cluster.local</code>? (из pod-а)</li>
<li>Сколько A-записей у <code>google.com</code>? (round-robin)</li>
<li>Какой MX-сервер у <code>gmail.com</code>?</li>
<li>Какой TTL у A-записи <code>github.com</code>?</li>
</ol>
<details>
<summary>Решение</summary>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># 1. DNS-серверы:</span>
</span></span><span class="line"><span class="cl">cat /etc/resolv.conf
</span></span><span class="line"><span class="cl"><span class="c1"># nameserver 10.96.0.10</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 2. kubernetes ClusterIP (из pod-а):</span>
</span></span><span class="line"><span class="cl">dig +short kubernetes.default.svc.cluster.local
</span></span><span class="line"><span class="cl"><span class="c1"># 10.96.0.1</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 3. A-записи google.com:</span>
</span></span><span class="line"><span class="cl">dig +short google.com
</span></span><span class="line"><span class="cl"><span class="c1"># Обычно 1 IP, но может быть несколько (anycast)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 4. MX gmail.com:</span>
</span></span><span class="line"><span class="cl">dig MX gmail.com +short
</span></span><span class="line"><span class="cl"><span class="c1"># 5 gmail-smtp-in.l.google.com.</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 10 alt1.gmail-smtp-in.l.google.com.</span>
</span></span><span class="line"><span class="cl"><span class="c1"># ...</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 5. TTL github.com:</span>
</span></span><span class="line"><span class="cl">dig github.com <span class="p">|</span> grep -E <span class="s2">&#34;^github&#34;</span>
</span></span><span class="line"><span class="cl"><span class="c1"># github.com.  60  IN  A  140.82.121.3</span>
</span></span><span class="line"><span class="cl"><span class="c1"># TTL = 60 секунд</span>
</span></span></code></pre></div></details>
<hr>
<h2 id="дальше--уровень-3">Дальше → Уровень 3</h2>
<p>Ты понимаешь DNS: иерархию, типы записей, dig для диагностики, CoreDNS в K8s. Ты знаешь, что <code>curl http://api:8080</code> сначала резолвит имя через DNS, потом подключается по IP.</p>
<p>Но что значит &quot;подключается&quot;? Когда ты видишь &quot;Connection refused&quot; – что именно не сработало? Когда &quot;Connection timeout&quot; – почему ждать 30 секунд, а не получить ошибку сразу?</p>
<p>Ответ – в протоколе TCP: трёхстороннее рукопожатие, порты, состояния соединения. Понимание TCP – это понимание <em>почему</em> вообще работает сетевое общение между программами.</p>
<p><strong>→ Уровень 3: TCP и UDP – анатомия соединения</strong></p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>Порядок канонический – так резолвит <code>systemd-resolved</code> (и это ответ, который ждут на собесе). Краевой случай: <code>nscd</code> кеширует сам результат NSS-запроса, включая <code>files</code>, и может &quot;встать&quot; перед <code>/etc/hosts</code>, так что точный порядок зависит от резолвера.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
  </channel>
</rss>
