Второй из семи уровней мини-курса «Networking 20/80»: 20% сетевых знаний, которые закрывают 80% ежедневной работы DevOps. В нулевом уровне разобрали карту местности – на каком слое искать поломку. Сегодня спускаемся на уровень адресов: как из 10.25.1.100/24 за десять секунд достать сеть, broadcast и число хостов, не открывая калькулятор подсетей.

“IP-адресация – единственная часть сетей, где нужна арифметика. Хорошая новость: арифметика простая – степени двойки.”


Откуда это пошло

1981 – IPv4 (RFC 791). Jon Postel (ISI, один из отцов интернета) определяет формат: 32 бита, разделённые на 4 октета. 2^32 = ~4.3 миллиарда адресов. В 1981 году казалось, что хватит навсегда.

1993 – CIDR (RFC 1519). Оригинальная система классов (A, B, C) расходовала адреса неэффективно: класс B = 65 536 адресов, класс C = 256. CIDR (Classless Inter-Domain Routing) позволил делить сети произвольно: /24, /25, /22 – любой размер.

1996 – RFC 1918. Приватные диапазоны (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) + NAT. Решение проблемы нехватки адресов до прихода IPv6.

1998 – IPv6 (RFC 2460). 128 бит = 3.4 × 10^38 адресов. Достаточно, чтобы дать каждому атому на поверхности Земли несколько адресов. В 2026 году IPv6 всё ещё не вытеснил IPv4 полностью.


IPv4 – 32 бита, 4 октета

IP-адрес: 10.25.1.100

Десятичная:  10    .   25    .    1    .   100
Двоичная:  00001010.00011001.00000001.01100100
           └──────────────────────────────────┘
                       32 бита

Специальные адреса

АдресЧто значитПример использования
0.0.0.0“Все интерфейсы” (bind) или “нет адреса”listen_addresses = '0.0.0.0'
127.0.0.1Loopback (localhost)curl http://127.0.0.1:8080
255.255.255.255Broadcast (все в сети)DHCP discovery
169.254.x.xLink-local (DHCP не ответил)Проблема с сетью!

Приватные и публичные адреса

Приватные (RFC 1918) – НЕ маршрутизируются в интернете

ДиапазонCIDRРазмерГде видишь
10.0.0.0 – 10.255.255.25510.0.0.0/816.7M адресовAWS VPC, K8s pods, корпоративные сети
172.16.0.0 – 172.31.255.255172.16.0.0/121M адресовDocker bridge (172.17.0.0/16)
192.168.0.0 – 192.168.255.255192.168.0.0/1665K адресовДомашние роутеры

Где это видно в реальной работе

# Твоя машина (приватная сеть):
ip addr show eth0
# inet 10.25.1.100/24    ← приватный (10.x.x.x)

# K8s pod IP:
kubectl get pod -o wide
# NAME     IP            NODE
# api-xxx  10.244.1.15   worker-1    ← приватный (pod network)

# K8s service IP:
kubectl get svc
# NAME   CLUSTER-IP    PORT(S)
# api    10.96.45.12   8080/TCP      ← приватный (service network)

# Docker bridge:
docker inspect bridge | grep Subnet
# "Subnet": "172.17.0.0/16"          ← приватный

CIDR и маски подсети – главная математика

Что значит /24

IP:   10.25.1.100/24

/24 = первые 24 бита – адрес СЕТИ, остальные 8 бит – адрес ХОСТА

Сетевая часть:     10  . 25  .  1  .  ???
                   └──────────────┘  └───┘
                    24 бита (сеть)   8 бит (хост)

Маска подсети:  255.255.255.0
Двоичная:       11111111.11111111.11111111.00000000
                └────── единицы = сеть ──┘└─ нули = хост ─┘

Формула: сколько хостов в сети

Хостов = 2^(32 - prefix) - 2

Почему -2: сетевой адрес (все нули) + broadcast (все единицы)

/24: 2^(32-24) - 2 = 2^8 - 2 = 254 хоста
/16: 2^(32-16) - 2 = 2^16 - 2 = 65 534 хоста
/8:  2^(32-8)  - 2 = 2^24 - 2 = 16 777 214 хостов
/32: 2^0 - 2  = -1 → один конкретный адрес (host route)
/31: 2^1 - 2  = 0 → point-to-point линк (RFC 3021, два адреса)

Шпаргалка размеров

CIDRМаскаХостовТипичное использование
/32255.255.255.2551Один конкретный хост (host route)
/28255.255.255.24014Маленькая подсеть (DMZ)
/24255.255.255.0254Стандартная подсеть (одна команда, один VLAN)
/20255.255.240.04 094AWS subnet default
/16255.255.0.065 534Docker bridge, VPC
/12255.240.0.01 048 574Большая корпоративная сеть
/8255.0.0.016 777 21410.0.0.0/8 – весь приватный блок

Как считать: сеть и broadcast

Пример: 10.25.1.100/24

Шаг 1: /24 = маска 255.255.255.0
Шаг 2: Сетевой адрес = IP AND маска = 10.25.1.0
Шаг 3: Broadcast = сетевой + инверсия маски = 10.25.1.255
Шаг 4: Диапазон хостов = 10.25.1.1 – 10.25.1.254

Пример: 10.25.100.100/20

Шаг 1: /20 → в третьем октете 4 бита уходят под сеть → 11110000 = 240 → маска 255.255.240.0
        Под хост в третьем октете остаётся 4 бита
        Размер блока = 2^4 = 16 в третьем октете
Шаг 2: 100 в третьем октете → 100 / 16 = 6.25 → блок начинается с 6*16=96
        Сетевой адрес: 10.25.96.0
Шаг 3: Broadcast: 10.25.96.0 + 16 адресов в октете - 1 = 10.25.111.255
Шаг 4: Хосты: 10.25.96.1 – 10.25.111.254

NAT – как приватные сети выходят в интернет

Внутренняя сеть        NAT-роутер                 Интернет

10.0.0.5  ┐
10.0.0.6  ┼──→   внутри:  10.0.0.1    ──→    8.8.8.8
10.0.0.7  ┘      снаружи: 5.6.7.8

Роутер заменяет адрес источника:
10.0.0.5:54321  →  5.6.7.8:54321

Три типа NAT:

ТипЧто делаетГде видишь
SNAT (Source NAT)Заменяет src IPВыход из приватной сети в интернет
DNAT (Destination NAT)Заменяет dst IPPort forwarding, K8s NodePort
MasqueradeSNAT с автоопределением src IPiptables на роутере

NAT в K8s

# NodePort: внешний трафик → нода → pod
# DNAT: 10.25.1.10:30080 → 10.244.1.15:8080
kubectl get svc api -o yaml
# spec:
#   type: NodePort
#   ports:
#   - port: 8080         ← ClusterIP port
#     nodePort: 30080    ← DNAT на каждой ноде

IPv6 – минимум для DevOps

# IPv6-адрес:
ip -6 addr show
# inet6 fe80::1/64 scope link          ← link-local (аналог 169.254.x.x)
# inet6 2001:db8::1/64 scope global    ← глобальный

# Формат: 8 групп по 4 hex-цифры
# 2001:0db8:0000:0000:0000:0000:0000:0001
# Сокращение: 2001:db8::1 (нули можно убрать)

Что DevOps должен знать про IPv6:

  1. ::1 – loopback (аналог 127.0.0.1)
  2. fe80::/10 – link-local (есть на каждом интерфейсе)
  3. Docker и K8s поддерживают dual-stack (IPv4 + IPv6)
  4. Если сервис не слушает на [::] – IPv6-клиенты не подключатся
# Проверить, слушает ли сервис на IPv6:
ss -tlnp | grep 8080
# LISTEN  0.0.0.0:8080    ← только IPv4
# LISTEN  [::]:8080       ← IPv4 + IPv6 (dual-stack)

Подвохи для собеса

Подвох 1: “Сколько хостов в сети /24? А в /25?”

Ответ:

/24: 2^8 - 2 = 254 хоста
/25: 2^7 - 2 = 126 хостов

Почему -2:
  - Сетевой адрес (10.0.0.0) – не может быть назначен хосту
  - Broadcast (10.0.0.255) – не может быть назначен хосту

Ловушка: /31 → 2^1 - 2 = 0. Но RFC 3021 разрешает /31 для point-to-point
линков (два адреса, оба назначаются хостам, без broadcast).

/32 → один конкретный адрес. Используется в маршрутах (host route)
и security groups (разрешить трафик с одного IP).

На собесе: “254 хоста в /24. Минус два: сетевой адрес и broadcast. В /31 формально ноль, но RFC 3021 разрешает два – это используется на point-to-point линках между роутерами.”


Подвох 2: “Хосты 10.0.1.5/24 и 10.0.2.5/24 – в одной сети или нет?”

Ответ через маску:

10.0.1.5/24:  сеть = 10.0.1.0, хосты: 10.0.1.1 – 10.0.1.254
10.0.2.5/24:  сеть = 10.0.2.0, хосты: 10.0.2.1 – 10.0.2.254

Разные сети! Они не могут общаться напрямую – нужен маршрутизатор.

А если /16?

10.0.1.5/16:  сеть = 10.0.0.0, хосты: 10.0.0.1 – 10.0.255.254
10.0.2.5/16:  сеть = 10.0.0.0, хосты: 10.0.0.1 – 10.0.255.254

Одна сеть! Они видят друг друга напрямую (через switch, без router).

На собесе: “Маска определяет, в одной ли сети два хоста. Если после применения маски сетевая часть одинакова – одна сеть (L2, коммутация). Если разная – разные сети (L3, маршрутизация). Это фундаментальный принцип IP: маска определяет scope.”


Подвох 3: “Что такое CIDR и зачем он заменил классы?”

Ответ через историю:

До CIDR (до 1993) были классы:

Класс A: /8   – 16M адресов (IBM, Apple, MIT – каждый получил /8!)
Класс B: /16  – 65K адресов
Класс C: /24  – 256 адресов

Проблема: организации с 500 хостами получали класс B (65K) – 64 500 адресов впустую. С 300 хостами /24 не хватает, /16 – избыток.

CIDR: любой префикс /17, /20, /22 – точный размер под потребность.

На собесе: “CIDR – бесклассовая адресация, введённая в 1993. До неё были классы A/B/C с фиксированными размерами, что вело к расточительному использованию адресного пространства. CIDR позволяет /20 (4094 хоста) вместо выбора между /16 (65K) и /24 (254). Это отсрочило исчерпание IPv4 на десятилетия.”


Код-челлендж

Задача: тебе нужно спроектировать сеть для проекта с тремя окружениями:

  • prod: до 200 серверов
  • staging: до 50 серверов
  • dev: до 30 серверов

Базовая сеть: 10.100.0.0/16. Разбей её на подсети для каждого окружения.

Ответь: какой CIDR, сетевой адрес и диапазон хостов для каждого.

Решение
prod (до 200 серверов):
  Нужно: ≥ 202 адреса (200 + сеть + broadcast)
  /24 = 256 адресов (254 хоста) ✓
  Сеть: 10.100.0.0/24
  Хосты: 10.100.0.1 – 10.100.0.254

staging (до 50 серверов):
  Нужно: ≥ 52 адреса
  /26 = 64 адреса (62 хоста) ✓
  Сеть: 10.100.1.0/26
  Хосты: 10.100.1.1 – 10.100.1.62

dev (до 30 серверов):
  Нужно: ≥ 32 адреса
  /26 = 64 адреса (62 хоста) ✓
  Сеть: 10.100.1.64/26
  Хосты: 10.100.1.65 – 10.100.1.126

Проверка: подсети не пересекаются ✓
Осталось свободно: 10.100.2.0 – 10.100.255.255 (для будущих окружений)

Дальше → Уровень 2

Ты умеешь считать подсети, понимаешь разницу между приватными и публичными адресами, знаешь что такое NAT. Но в реальной работе ты пишешь curl http://api.example.com, а не curl http://93.184.216.34. Как имя api.example.com превращается в IP-адрес?

DNS – Domain Name System – одна из самых частых причин сетевых проблем в DevOps: “не резолвится”, “резолвится не туда”, “кеш DNS устарел”, “CoreDNS в K8s перегружен”. Понимание DNS – обязательный навык.

→ Уровень 2: DNS – как имена становятся адресами