Второй из семи уровней мини-курса «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.1 | Loopback (localhost) | curl http://127.0.0.1:8080 |
255.255.255.255 | Broadcast (все в сети) | DHCP discovery |
169.254.x.x | Link-local (DHCP не ответил) | Проблема с сетью! |
Приватные и публичные адреса
Приватные (RFC 1918) – НЕ маршрутизируются в интернете
| Диапазон | CIDR | Размер | Где видишь |
|---|---|---|---|
10.0.0.0 – 10.255.255.255 | 10.0.0.0/8 | 16.7M адресов | AWS VPC, K8s pods, корпоративные сети |
172.16.0.0 – 172.31.255.255 | 172.16.0.0/12 | 1M адресов | Docker bridge (172.17.0.0/16) |
192.168.0.0 – 192.168.255.255 | 192.168.0.0/16 | 65K адресов | Домашние роутеры |
Где это видно в реальной работе
# Твоя машина (приватная сеть):
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 | Маска | Хостов | Типичное использование |
|---|---|---|---|
| /32 | 255.255.255.255 | 1 | Один конкретный хост (host route) |
| /28 | 255.255.255.240 | 14 | Маленькая подсеть (DMZ) |
| /24 | 255.255.255.0 | 254 | Стандартная подсеть (одна команда, один VLAN) |
| /20 | 255.255.240.0 | 4 094 | AWS subnet default |
| /16 | 255.255.0.0 | 65 534 | Docker bridge, VPC |
| /12 | 255.240.0.0 | 1 048 574 | Большая корпоративная сеть |
| /8 | 255.0.0.0 | 16 777 214 | 10.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 IP | Port forwarding, K8s NodePort |
| Masquerade | SNAT с автоопределением src IP | iptables на роутере |
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– loopback (аналог 127.0.0.1)fe80::/10– link-local (есть на каждом интерфейсе)- Docker и K8s поддерживают dual-stack (IPv4 + IPv6)
- Если сервис не слушает на
[::]– 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 – как имена становятся адресами