Первый из семи уровней мини-курса «Networking 20/80»: 20% сетевых знаний, которые закрывают 80% ежедневной работы DevOps. Без зубрёжки семи слоёв OSI ради собеса – по делу. Сегодня карта местности: какие модели сети существуют и что на самом деле летает между твоим curl и ответом сервера.

“OSI – это не то, что нужно зубрить для собеса. Это карта, по которой ты ищешь, на каком уровне сломалось.”


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

1969 – ARPANET. Агентство DARPA (Министерство обороны США) финансирует сеть между четырьмя университетами: UCLA, Stanford, UCSB, University of Utah. 29 октября 1969 года Charley Kline пытается отправить слово “LOGIN” из UCLA в Stanford. Система падает после “LO”. Первое сообщение в истории интернета – “LO”. (Позже шутили: “Lo and behold” – “Вот и чудо”.)

1974 – Vint Cerf и Bob Kahn публикуют TCP. Проблема ARPANET: каждая сеть говорит на своём протоколе. TCP (позже разделённый на TCP + IP) решает задачу: один протокол для соединения РАЗНЫХ сетей. “Inter-net” – буквально “между сетей”.

1984 – OSI модель. ISO (Международная организация по стандартизации) публикует “идеальную” семиуровневую модель. К этому моменту TCP/IP уже работает в реальном мире 10 лет. OSI – теоретическая модель, TCP/IP – практическая. Победил практик, но модель OSI осталась как язык для описания сетевых проблем.


Две модели: OSI и TCP/IP

OSI – 7 уровней (для собеса)

#УровеньЧто на нём живётПростыми словами
7ApplicationHTTP, DNS, SSH, SMTP“что говорим”
6PresentationSSL/TLS, сжатие, кодировки
5Sessionуправление сессиями
4TransportTCP, UDP“кому и как надёжно”
3NetworkIP, ICMP, маршрутизация“по какому адресу”
2Data LinkEthernet, Wi-Fi, MAC-адреса“по какому проводу”
1Physicalкабели, сигналы, разъёмы“физика”

TCP/IP – 4 уровня (реальность)

Уровень TCP/IPЧто на нём живётСоответствие OSI
ApplicationHTTP, DNS, SSH, SMTP5–7
TransportTCP, UDP4
InternetIP, ICMP3
LinkEthernet, Wi-Fi1–2

Системное мышление: OSI и TCP/IP – не конкуренты. OSI – язык для обсуждения (“проблема на уровне 3”). TCP/IP – реальный стек протоколов. На собесе знай оба, но понимай, что TCP/IP – то, с чем работаешь каждый день.

Зачем DevOps-у знать уровни

Потому что уровень определяет инструмент диагностики:

УровеньСимптомИнструментПример
1-2 (Link)“Кабель выдернут”, no carrierip link, ethtoolInterface DOWN
3 (Network)“Нет маршрута”, destination unreachableip route, ping, traceroutePod не видит сервис
4 (Transport)“Connection refused”, “Connection timeout”ss, netstat, tcpdumpПорт не слушает
7 (Application)“502 Bad Gateway”, “TLS handshake failed”curl -v, openssl s_clientNginx не может до бэкенда

Инкапсуляция – как данные упаковываются

Когда ты делаешь curl http://api:8080/health, вот что происходит:

Ты:     "GET /health HTTP/1.1"
┌──────────────────────────────────────────────┐
│ HTTP Header: GET /health HTTP/1.1            │  ← Уровень 7: Application
│              Host: api:8080                  │
│ HTTP Body:   (пусто)                         │
├──────────────────────────────────────────────┤
│ TCP Header: src_port=54321, dst_port=8080    │  ← Уровень 4: Transport
│             SEQ=1, ACK=0, SYN                │
├──────────────────────────────────────────────┤
│ IP Header:  src=10.0.0.5, dst=10.0.0.10      │  ← Уровень 3: Network
│             TTL=64, Protocol=TCP             │
├──────────────────────────────────────────────┤
│ Ethernet:   src_mac=aa:bb:cc, dst_mac=dd:ee  │  ← Уровень 2: Link
│             Type=IPv4                        │
└──────────────────────────────────────────────┘
        [биты по проводу]                         ← Уровень 1: Physical

Аналогия с почтой:

  • Ты пишешь письмо (HTTP = текст письма)
  • Кладёшь в конверт, пишешь “Кому: Иванову” (TCP = надёжная доставка)
  • На конверте – индекс и адрес (IP = маршрутизация)
  • Конверт кладёшь в почтовый ящик (Ethernet = локальная доставка)
  • Почтальон несёт (Physical = провода)

Получатель распаковывает в обратном порядке: Ethernet → IP → TCP → HTTP.


“Что происходит, когда ты вводишь URL в браузер”

Это классический вопрос на собесе. Ответ должен пройти по всем уровням:

1. DNS (Уровень 7): браузер резолвит example.com → 93.184.216.34
   └─ Проверяет: кеш браузера → кеш ОС → /etc/hosts → DNS-сервер

2. TCP (Уровень 4): трёхстороннее рукопожатие
   └─ SYN → SYN-ACK → ACK (три пакета, ~30ms)

3. TLS (Уровень 5-6): если HTTPS – ещё одно рукопожатие
   └─ ClientHello → ServerHello → Certificate → Key Exchange (~50ms)

4. HTTP (Уровень 7): отправляет GET / HTTP/1.1
   └─ Заголовки: Host, User-Agent, Accept, Cookie

5. Сервер обрабатывает запрос
   └─ nginx → reverse proxy → backend → DB → ответ

6. HTTP Response: 200 OK + HTML
   └─ Заголовки: Content-Type, Content-Length, Set-Cookie

7. Браузер рендерит HTML
   └─ Парсит HTML → запрашивает CSS, JS, изображения (каждый – отдельный запрос)
   └─ Строит DOM → CSSOM → Layout → Paint

20/80: на собесе достаточно уверенно пройти шаги 1–6. Шаг 7 (рендеринг) – бонус для фронтендера, DevOps может пропустить.


Практика: инструменты Уровень 0

ip – вместо устаревшего ifconfig

# Показать сетевые интерфейсы:
ip addr show
# или короче:
ip a

# Результат:
# 1: lo: <LOOPBACK,UP> ...
#     inet 127.0.0.1/8
# 2: eth0: <BROADCAST,MULTICAST,UP> ...
#     inet 10.0.0.5/24
#     inet6 fe80::1/64

# Показать только IPv4:
ip -4 addr show

# Показать маршруты:
ip route show
# или:
ip r
# default via 10.0.0.1 dev eth0       ← шлюз по умолчанию
# 10.0.0.0/24 dev eth0 proto kernel   ← локальная сеть
# 172.17.0.0/16 dev docker0           ← Docker bridge network

Важно: ifconfig – deprecated с 2009 года (пакет net-tools). ip – современная замена (пакет iproute2). На собесе используй ip, не ifconfig.

ping – проверка связности (Уровень 3)

# Есть ли связь с хостом?
ping -c 4 8.8.8.8
# PING 8.8.8.8: 64 bytes from 8.8.8.8: icmp_seq=1 ttl=118 time=1.23 ms

# Что значит вывод:
# 64 bytes    – размер ответа
# ttl=118     – Time To Live (сколько маршрутизаторов осталось; начинал с 128, прошёл 10)
# time=1.23ms – Round Trip Time (туда и обратно)

traceroute – путь пакета

# Маршрут до хоста (каждый хоп = маршрутизатор):
traceroute 8.8.8.8
#  1  10.0.0.1      0.5 ms    ← шлюз (твой роутер)
#  2  172.16.0.1    2.1 ms    ← провайдер
#  3  * * *                    ← маршрутизатор не отвечает (firewall)
#  4  209.85.249.1  5.3 ms    ← Google
#  5  8.8.8.8       6.1 ms    ← цель

# Более быстрый вариант (использует ICMP вместо UDP):
traceroute -I 8.8.8.8

# Ещё быстрее (параллельные пробы):
mtr 8.8.8.8    # интерактивный traceroute + ping

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

# Проверка связности с твоим шлюзом:
ping 10.0.0.1

# Docker networking:
docker network ls
# NETWORK ID     NAME      DRIVER    SCOPE
# abc123         bridge    bridge    local     ← дефолтная сеть
# def456         host      host      local
# ghi789         none      null      local

# K8s Services:
kubectl get svc
# NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)
# kubernetes   ClusterIP   10.96.0.1     <none>        443/TCP
# api          ClusterIP   10.96.45.12   <none>        8080/TCP

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

Подвох 1: “Назовите 7 уровней OSI снизу вверх”

Ответ: Physical, Data Link, Network, Transport, Session, Presentation, Application.

Мнемоника: Please Do Not Throw Sausage Pizza Away.

Но! Не останавливайся на перечислении. Добавь:

“В реальной работе я использую модель TCP/IP (4 уровня), потому что Session и Presentation слоёв отдельно не существует – они встроены в Application layer. OSI полезна как язык коммуникации: когда я говорю коллеге “проблема на L3”, он понимает, что я про маршрутизацию, а не про HTTP.”

Системное мышление: OSI – это модель (абстракция для понимания), а не реализация (код, который работает). TCP/IP – реализация. Знай модель, работай с реализацией.


Подвох 2: “Чем отличается switch от router?”

Ответ через уровни:

Switch (коммутатор) – Уровень 2 (Data Link):
  - Работает с MAC-адресами
  - Соединяет устройства в ОДНОЙ сети (LAN)
  - Знает: "на порт 3 подключен MAC aa:bb:cc:dd:ee:ff"
  - Аналогия: почтальон внутри офисного здания

Router (маршрутизатор) – Уровень 3 (Network):
  - Работает с IP-адресами
  - Соединяет РАЗНЫЕ сети
  - Знает: "сеть 10.0.0.0/24 через интерфейс eth0, сеть 192.168.0.0/24 через eth1"
  - Аналогия: почтовое отделение, которое решает, в какой город отправить

На собесе: “Switch коммутирует фреймы по MAC-адресам внутри одной сети. Router маршрутизирует пакеты по IP-адресам между разными сетями. Ваш домашний “роутер” – на самом деле и router, и switch, и Wi-Fi access point в одном корпусе. В data center они разделены.”


Подвох 3: “Что такое loopback (127.0.0.1) и зачем он нужен?”

Ответ:

127.0.0.1 (и вся сеть 127.0.0.0/8) – виртуальный интерфейс lo, который никогда не покидает хост. Пакет, отправленный на 127.0.0.1, мгновенно “возвращается” обратно – не уходит в сеть, не проходит через сетевую карту.

# Loopback интерфейс:
ip addr show lo
# 1: lo: <LOOPBACK,UP,LOWER_UP>
#     inet 127.0.0.1/8 scope host lo

# Зачем нужен:
# 1. Тестирование: curl http://127.0.0.1:8080 – проверить, что сервис слушает
# 2. IPC: процессы общаются через TCP/UDP на localhost (PostgreSQL, Redis)
# 3. Безопасность: bind на 127.0.0.1 = доступ только с этой машины

Ловушка для DevOps:

# Сервис слушает на 127.0.0.1:
ss -tlnp | grep 5432
# LISTEN  127.0.0.1:5432    ← PostgreSQL слушает ТОЛЬКО localhost

# Другая машина не сможет подключиться:
psql -h 10.0.0.5 -p 5432    # → Connection refused!

# Решение: bind на 0.0.0.0 (все интерфейсы):
# postgresql.conf: listen_addresses = '*'

На собесе: “127.0.0.1 – loopback. 0.0.0.0 – все интерфейсы. Сервис на 127.0.0.1 виден только локально. Сервис на 0.0.0.0 доступен с любого IP хоста. Частая ошибка – приложение слушает на 127.0.0.1 в Docker-контейнере, и к нему невозможно подключиться снаружи, потому что контейнер – это отдельный network namespace.”


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

Задача: на любой Linux-машине выполни диагностику сети и ответь на вопросы:

  1. Какой IP-адрес у eth0?
  2. Какой шлюз по умолчанию (default gateway)?
  3. Сколько хопов до 8.8.8.8?
  4. Какие Docker-сети существуют и какие у них подсети?
Решение
# 1. IP eth0:
ip -4 addr show eth0 | grep inet
# inet 10.0.0.5/24

# 2. Default gateway:
ip route | grep default
# default via 10.0.0.1 dev eth0

# 3. Хопы до 8.8.8.8:
traceroute -I -m 15 8.8.8.8 | tail -1
# Номер последней строки = количество хопов

# 4. Docker-сети:
docker network ls
docker network inspect bridge | grep -A5 IPAM
# "Subnet": "172.17.0.0/16", "Gateway": "172.17.0.1"

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

Ты понимаешь модель: данные путешествуют по уровням, каждый уровень добавляет свой заголовок. Ты знаешь, что ip addr показывает адреса, ip route – маршруты, ping – связность.

Но откуда берутся эти адреса? Почему 10.0.0.5/24 – приватный, а 93.184.216.34 – публичный? Что значит /24? Сколько хостов поместится в сеть /16? Как разбить одну сеть на подсети для разных окружений (dev, staging, prod)?

IP-адресация – это математика DevOps. Её не нужно “понимать глубоко” – нужно уметь считать.

→ Уровень 1: IP-адреса и подсети – математика DevOps