Text
                    O'REILLY*
Как освоить современный Linux
Полный справочник: от новичка до профессионала
astoQi international publishing
Майкл Хаузенблас
O’REILLY*
Книги по программированию
Learning Modern Linux
A Handbook for the Cloud Native Practitioner
Michael Hausenbias
Как освоить современный linux
Полный справочник: от новичка до профессионала
Майкл Хаузенблас
УДК 004.4
ЬБК .32.973.26-018.2
Х26
Michael Hausenbias
Learning Modern Linux: A Handbook for the Cloud Native Practitioner
© 2026 “Astana International Publishing” LLP Authorized Russian translation of the English edition of Learning Modern Linux ISBN 978T 098'08946
© 2022 Michael Hausenbias. This translation is published and sold by permission of O’Reilly Media, Inc., which owns or controls all rights to publish and sell the samee.
Хаузенблас, Майкл.
X26 Как освоить современный Linux Полный справочник: от новичка до профессионала / Майкл Хаузенблас : [перевод с английского А. Пескова]. — Алматы : Астана ипострал ная пресса, 2026. — 304 с. — (O’Reilly. Книги по программированию).
ISBN 978-601-12-4679-8
Linux — это универсальная рабочая среда для разработчиков, архитекторов и специ алистоь по облачным технологиям.
Автор выстраивает ясный и гюследовательный маршрут: от понимания ключевых компонентов — ядра, оболочек, файловых систем — до уверенной работы с се гевым стеком, контейнерами и инструментами мониторинга. Особое внимание уделено безопасности, управлению зависимостями и организации процессов, что делает книгу ценным источником знаний для специалистов, которым важны надежность и масштабируемость решений.
Это не сухая энциклопедия команд, а практическое руководство, коюрое показывает, как Linux может стать основой продуктивной разработки и эксплуатации современной систем
УДК 004.4
ББК 32.973.26-С18.2
ISBN 978-6CL-12-4679-8
© Песков А. Ю., перевод на русский язык, 2026
© Издание на русском языке, оформление.
ТОО «Издательство «Астана иностранная пресса», 2026
Оглавление
Предисловие ... ...	....................... ... ...........  9
Для кого эта книга........................................... 10
Как пользоваться книгой...................................... 10
Условные обозначения......................................... 11
Использование примеров кода ................................. 12
благодарности ............................................... 13
Глава 1. Введение в Linux ..................................... 14
Что такое современные среды?................................. 14
История Linux (далекая от завершения)........................ 16
Так зачем же нужна операционная система? .................... 17
Дистрибутивы Linux........................................... 19
Видимость ресурсов .......................................... 19
Linux с высоты птичьего полета ...............................22
Заключение....................................................23
Глава 2. Ядро Linux	25
Архитектура Linux.............................................25
Архитектуры процессоров ......................................27
Компоненты ядра...............................................31
Расширения ядра...............................................43
Заключение....................................................47
Глава 3. Оболочки и скрипты.................................... 50
Основы	 51
Удобные для работы оболочки...................................69
Терминальный мультиплексор ...................................78
Сценарии......................................................85
Заключение................................................... 94
Глава 4. Управление доступом..................................  97
Основы .....................................................  97
Пользователи .........	  ЮС
Оглавление | 5
Разрешения................................................ 106
Расширенное управление разрешениями ...................... 1J3
Полезные советы........................................... 116
Заключение................................................ 117
Глава 5. Файловые системы ................................... 119
Основы.................................................... 120
виртуальная файловая система ...........................   124
Псевдофайловые системы	   132
Обычные файлы.........................................     137
Заключение.....	   143
Глава 6. Приложения, управление пакетами и контейнеры ....... 145
Основы.................................................    146
systemd................................................... 149
Цепочки поставок приложений в Linux....................... 155
Пакеты и менеджеры пакетов................................ 158
Контейнеры ............................................... 164
Современные менеджеры пакетов............................. 180
Заключение .	  181
Глава 7. Сетевое взаимодействие ..............................183
Основы.........	  183
Стек TCP/IP.............................................   185
DNS......................................................  206
Сетевое взаимодействие на прикладном уровне................215
Дополнительная информация о сетевом взаимодействии ........226
Заключение................................................ 231
Глава 8. Наблюдаемость.....	.......... . .	. 233
Основы ....................................................234
Журналирование.............................................238
Наблюдение (мониторинг) ...................................245
Углубимся в наблюдаемость................................. 254
Заключение.................................................261
Глава 9. Углубленные темы ....................................263
Межпроцессное взаимодействие ..............................263
Виртуальные машины.........................................268
6 | Опквление
Современные дистрибутивы Linux ............................271
Избранное в области безопасности...........................274
Другие современные и перспективные возможности ............275
Заключение	 278
Приложение А. Полезные примеры.............................. 281
Сбор системной информации................................. 281
Работ а с пользователями и процессами .................... 282
Сбор информации о файлах.................................. 283
Работа с файлами и каталогами............................. 283
Работа с перенаправлением и конвейерами	.	 284
Работа с датой и временем..................................285
Работа с Git ............................................. 286
Производительность системы.................................287
Приложение Б. Инструментарий современной Linux.............. 288
Об авторе.................................................  ..	299
Животное на обложке . ................................       291
Алфавитный указатель ....................................... 292
Предисловие
Добро пожаловать на страницы книги «Как освоить современный Linux»! С большой радостью составлю вам компанию в недолгом совместном путешествии. Эта книга окажется вам полезной, если вы только познакомились с Linux и искали упорядоченное практическое руководство для более глубокого изучения, или вы опытный пользователь, но хотите подсказок и советов, чтобы отточить навыки работы с этой операционной системой для разработки или профессиональной деятельности.
Мы сосредоточимся на повседневном использовании Linux — от написания скриптов до решения офисных задач, — оставив в стороне вопросы администрирования. Графическому интерфейсу мы предпочтем командную строку. И пусть 2022 год считается годом настольного Linux, но, избрав терминал средством общения с операционной системой, вы получите дополнительное преимущество: вы сможете применить знания в самых различных конфигурациях, включая Raspberry Pi и виртуальные машины облачного провайдера.
Прежде чем мы начнем, я поделюсь с вами этапами собственного развития: первой операционной системой, с которой я познакомился, был не Linux. В конце 80-х годов прошлого века мне довелось поработать с AmigaOS, а позже, в техническом колледже, я использовал MS DOS и свежевышсдшую Microsoft Windows для создания событийных систем и графичес ких интерфейсов. В университетской лаборатории в конце 90-х мы использовали основанную на Unix операционную систему Solaris и рабочие станции Silicon Graphics. Полноценное знакомство с Linux состоялось лишь во втором десятилетии 2000-х, когда я занялся статистической обработкой больших данных (bigdata) и стал применять в работе контейнеры: сна чала Apache Mesos (в 2015, когда я работал в Mesosphere), а затем Kubernetes (в составе команды OpenShift в Red Hat, а позже в команде разработки контейнерных сервисов в AWS). Именно тогда я понял, что добиться успеха в моей области можно только освоив Linux. Он особенный Он уникален своей гибкостью, универсальностью, историей развития и мировой поддержкой сообщества.
У Linux интересная и растущая экосистема разработчиков и поставщиков ПО с открытым исходным кодом. Эту операционную систему можно запустить на чем угодно, от Raspberry Pi за 50 долларов до виртуальных машин вашего провайдера, и даже на марсоходе. За 30 лет разработки Linux ничуть не сдал позиций, так что самое время взглянуть на него поближе.
Предисловие | 9
Для начала выделим несколько правил и условностей. В предисловии я рас скажу, как извлечь из книги максимальную пользу, и затрону организационные вопросы, касающихся того, где и как можно попракгиковатпся в темах, которые мы будем изучать сообща.
Для кого эта книга
Эта книга пригодится тем, кто хочет или должен использовать Linux профессионально; разработчикам, архитекторам ПО, инженерам по. тестированию, DevOps, SRE и другим похожим специалистам. Если вы любитель и столкнулись с Linux при решении задач, связанных с 3D печатью или обустройством умного дома, то, вероятно, мало знаете об операционных системах вообще, и семействе UNIX/Linux в частности. В таком случае вам стоит прочитать книгу от начала и до конца: главы, как правило, последовательно дополняют друг друга. Если же вы знакомы с Linux, эта книга заменит хороший справочник.
Как пользоваться книгой
Этот курс скорее научит нас работать с Linux, чем администрировать его. Вопросы администрирования затронуты в бромном количестве других прекрасных книг.
Прочитав эту книгу, вы узнаете, что такое Linux (глава 1), и из каких компонентов она состоит (главы 2 и 3). Вы освоите механизмы управления доступом (глава 4), оцените роль файловых систем как основных кирпичиков Linux (гла за 5) и поймете, что такое приложения (глава 6).
Вы также получите практический навык работы с сетевым стеком и его инструментами (глава 7), ознакомитесь с современными возможностями наблюдения за ОС (глава 8) и научитесь управлять рабочей нагрузкой.
Вы узнаете о современных способах запуска приложений Linux в кентейне рах или в неизменяемых дистрибутивах (таких как Bottlerocket), сможете безопасно работать с сетью, скачивагь файлы или обмениваться данными через «защищенную оболочку» (Secure Shell, или SSH), познакомитесь с расширенным инструментарием для одноранговой (peer-to-peer, или р2р) и облачной синхронизации (глава 9).
Ниже я да м несколько советов по пра ктической подготовке к процессу обучения (и рекомендую вам не пренебрегать ими, поскольку освоение Linux очень похоже на изучение иностранного языка — чем больше практики, гем лучше).
10 | Предисловие
—	Найдите компьютер или ноутбук. У меня, к примеру, замечательная машинка с названием StarBook от компании StarLabs. Можно взять ноутбук с устаревшей версией Windows, которая больше не обновляется, и установить Linux на него.
—	Если вы хотите запустить Linux внутри другой операционной среды — скажем, у вас MacBook или iMac, — используйте виртуальную машину (VM)1. Для macOS есть замечательная Linux-on-Mac2.
—	Можно развернуть виртуальную машину на базе Linux в сети у вашего облачного провайдера.
—	Если вы любите мастерить и хотите испробовать процессор с архитектурой, отличной or Intel (к примеру, ARM), можете купить одноплатный компьютер. Советую замечательный Raspberry Pi.
В любом случае полезно не просто читать, а иметь под рукой настроенную среду и практике г.гться. Выполняйте команды и экспериментируйте Пробуйте «сломать» программу, подавая на вход странные данные. Перед запуском команды попробуйте представить, какой получите результат.
И еще совет: всегда задавайте вопросы и докапывайтесь до сути. Глядя на команду или результат выполнения, подумайте, как он был сформирован и какой базовый компонент за это отвечал.
Условные обозначения
В этой книге используется следующая типографская маркировка:
Курсив
Отмечает новые термины, адреса в интернете, имена файлов и их расширения.
Блок фиксированной ширины
Используется для отображения программного кода, а также внутри параграфов, где упоминаются определенные программные элементы: переменные, названия функций, базы данных, типы данных, переменные окружения, операторы, константы и ключевые слова
1 Для современных компьютеров на базе Windows можно развернуть виртуаль ную маши -ну Linux в VirtualBox, либо установито WS (Прим, ред.)
2 Репозиторий Lima (Linux-on-Mac) на Github: https://github.com/lima-vm/kima.
Предисловие | 11
Курсив в блоках с фиксированной шириной
Отмечает текст, который следует заменить на ваше или подстановочное зна чепие.
Этот элемент означает подсказку или предложение.
Этот элемент означает общее примечание.
Этот элемент означает предупреждение или предостережение.
Использование примеров кода
Сопроводительные материалы (в том числе примеры программного кода и упражнения) доступны для загрузки по адресу: https://oreil.ly/learning~inodern iinuxcode.
Если у вас возникли технические вопросы или затруднения при использовании примеров кода, пожалуйста, свяжитесь с нами по электронному адресу: mbockquestionstaJcreillycom.
Эта книга должна помочь зам в работе. Примеры из нее можно использова т ь в вашей программе или документации. Вам не нужно запрашивать разрешения до тех пор, пока вы не воспроизводите значительную часть кода. К примеру, если вы написали программу, включив в нес код из книги, разрешений не требуется. А для продажи и распространения примеров из книг издательства О Reilly разрешения нужны. Ответ на вопрос путем цитирования выдержек из книги или примеров не требует разрешений. А на включение значительного объема примеров из этой книги в вашу документацию нужно их получить.
12 | Предисловие
Благодарности
Прежцс всего я хочу поблагодарить замечательных рецензентов: Криса Негуса, Джена Бонесио и Павла Крупу. Без их отзывов книга была бы и вполовину не так хороша и полезна.
Также благодарю родителей, которые дали мне образование, заложив основы моего характера и профессии. Огромное спасибо моей старшей сестре Монике за то, что вдохновила пойти в IT.
Выражаю глубочайшую признательность своей замечательной семье за поддержку: детям — Сапфире, Ранье и Янкису; моей невероятно умной и веселой жене Аннелизе; Снупи — лучшей из всех собак, и коту Чарли, новому члену нашей семьи.
На пути знакомства с Unix и Linux я встретил огромное количество людей, оказавших влияние на мое мышление и многому меня научивших. С некоторыми мне выпала честь и счастье работать и плотно общаться (и перечислены далеко не все): Жером Нетацони. Джесси Фразель, Брендан Грегг, Джасгин Гаррисон, Макд Керриск и Дуглас Макилрой.
И последнее, но не менее важное: я благодарю всю команду издательства O’Reilly, в особенности моего технического редактора, Джеффа Блейла, за опеку
и помощь в написании книги.
ГЛАВА 1
Введение в Linux
Linux — одна из самых популярных операционных систем, используемых везде и повсюду, от мобильных устройств до облачных вычислений.
Возможно, вы не знакомы с концепцией ОС или работаете в Microsoft Windows, не вдаваясь в детали. Возможно, вы новичок в Linux. Чтобы настроить вас на нужный лад и дать некоторое представление об операционных системах, в том числе и Linux, мы начнем издалека.
Для начала обсудим, что значит слово «современная» в названии книги, и приглядимся к общей предыстории Linux с важными вехами ее развития за последние 30 лет. Затем в этой главе вы узнаете, какова роль ОС в целом и как с ней справляется Linux, В заключение рассмотрим, что такое дистрибутивы Linux и что означает термин «видимость ресурсов».
Если операционные системы и Linux для пас в новинку, прочитайте главу от начала и до конпа. Если вы знакомы с Linux, можете сразу перейти к разделу «Linux с высоты птичьего полета» и рисунку, сопоставляющему архитектуру Linux с главами книги.
Перед тем как углубиться в технические детали, отступим на шаг и подумаем о том, что понимается под выражением «современная Linux». Как ни стран но, это не такой уж банальный вопрос.
Что такое современные среды?
Так что кроется за словом «современная» в названии книги? Ну что же, в здеш нем контексте — все что угодно, от облачных вычислений до Raspberry Pi. А не давний взлет платформы контейнеризации Docker и связанных с ней инноваций кардинально изменил расстановку сил для разработчиков и связанных с инфраструктурой инженеров.
Давайте же подробнее рассмотрим некоторые из современных сред, и место, которое занимает в них Linux
14 |	Глава 1. Введение в Linux
Мобильные устройств а
Когда я упоминаю «мобильный телефон» при детях, они спрашивают; «А что, бывают другие?» В наши дни большинство устройств — больше 80%, в зависимости от того, у кого вы спросите, — это телефоны и планшеты на базе Android, системы, которая, в свою очередь, является вариацией Linux3. К мобильным средам выдвигаются самые жесткие требования по энергопотреблению и надежности, ведь мы зависим ст них постоянно. Если вам интересно создание приложений для Android, посетите специализированные ресурсы для разработчиков Android4.
Облачные вычисления
Ту же картину, что с мобильными и микросредами, только в более крупном масштабе, мы наблюдаем и в облаке Здесь наряду с новыми, мощными, безопасными, энергосберегающими процессорными архитектурами, такими как Graviton на базе ARM (крайне успешное предложение от AWS), обитают усто явшиеся и зарекомендовавшие себя продукты по делегированию тяжелых вычислений облачным провайдерам, особенно в рамках ПО с открытым исходным кодом.
Интернет («умных») вещей
Вам наверняка встречались проекты и продукты, связанные с интернетом вещей (Internet of things, или 1оТ), от всевозможных датчиков до дронов. Сегодня мало кого удивляют умные домашние приборы и даже автомобили. Б средах интернета вещей требования к энергопотреблению еще жестче, чем у мобильных уст ройств. Очень часто умные устройства должны работать не постоянно, а включаться по расписанию только раз в день, чтобы передать порцию данных. Однако и способность работать в реальном времени5— немаловажный фактор для этих сред. Если вам интересно поп робовать Linux в связке с 1оТ, обратите внимание на IoT EduKit6, который предлагает AWS
Разнообразие процессорных архитектур
Очень долгое время, порядка 30 лет, Intel была ведущим производителем центральных процессоров (ЦП, CPU). Она доминировала на рынке персональных
3 Is Android really just Linux? https:// www.androidauthority.com/android-linux-784964.
1 Сайт разработчиков на Android; https://develope: .android.com/: hl=ru.
5 Real-TimeLinux (Linux ь реальном времени): rttpsv/dcvdcpcr.toradcx.com^sottwarc/rea.1-time/real-time-linux/.
6 lol EduKit otAV/S: https://awsamazon.com/ru/iot/edukit/content.
Что такое соьремечные среды? | 15
и микрокомпьютеров, а архитектура Intel х86 считалась золотым стандартом. Открытый подход, к которому прибегла IBM, опубликовав спецификации и разрешив производителям предлагать совместимые устройства, оправдал ожидания и привел к появлению клонов х86: они тоже использовали процессоры Intel, хотя бы на начальном этапе.
Хотя процессоры Intel широко используются в настольных компьютерах и ноутбуках, с ростом популярности мобильных устройств наблюдается активное распространение архитектуры ARM и совсем недавней RISC-V. Креме того, в моду стремительно входят кросс-архитектурные языки программирования, такие как Go или Rust со своими инструментариями, и вносят в экосистему настоящий хаос.
Упомянутые выше среды я считаю «современными». Большинство из них, если не все, так или иначе работают с Linux или используют ее.
Теперь, когда мы узнали о современных (аппаратных) системах, можно задаться вопросом: как возникла и развилась сама Linux.
История Linux (далекая от завершения)
В 2021 году Linux отпраздновала свое тридцатилетие. Развитие проекта, в кото рый вовлечены миллиарды пользователей и тысячи разработчиков, без сомнения можно считать всемирной историей успеха (спасибо открытому исходному коду). Но как же все начиналось и как пришло к сегодняшней славе?
1990-е
Точкой отсчета для проекта Linux, по крайней мере исходя из общедоступной информации, можно считать электронное письмо от 25 августа 1991 года, отправленное Линусом Торвальдсом в новостную группу conp.os.minix. Любительский проект заметили сразу: он выгодно отличался количеством строк кода и простотой внедрения. Не прошло и трех лет, как свет увидела Linux 1.0.0- в ней насчитывалось более 176 000 строк кода. Изначальная цель — возможность запуска большинства программ Unix/GNU — к тому моменту была достигнута. Тогда же появился и первый коммерческий дистрибутив: Red Hat Linux.
20G0 2010 годы
В «подростковом» возрасте Linux не только продолжал наращивать базу предлагаемых функций и список совместимою оборудования, но превзошел по возможностям и саму UNIX. Система привлекла и интерес, и признание
16 | Глава 1. Введение в Linux
таких крупных игроков, как Google, Amazon, IBM и многих других. Вскоре наступил пик войны дистрибутивов, в результате которою целые предприятия меняли направление деятельности.
с 2GJ0 года по настоящее время
Linux зарекомендовал себя в качестве «рабочей лошадки» в дата-центрах, в облаке, на бесчисленных типах 1оТ устройств и телефонах. В каком-то смысле закончилась даже война дистрибутивов (в наши дни большинство коммерческих систем основаны либо на Red Hat, либо на Debian), и немалую роль в этом сыграло развитие контейнерных технологий (с 2014/15 и по наши дни).
После сверхбыстрого исторического обзора, который задал тон и прояснил, как подбирались темы для книги, перейдем к невинному на первый взгляд вопросу: для чего нужна Linux и ОС в целом?
Так зачем же нужна операционная система?
Представьте, что ОС у вас нет или она недоступна. Практически все вам придется делась самому: управлять памятью, обрабатывать прерывания, взаимодействовать с устройствами ввода/вывода (I/O), заботиться о файдах и настройках, обеспечивать взаимодействие с сетевым стеком — список длинный.
С технической точки зрения операционная система не обязательна. Есть системы, обычно крошечные и самодостаточные, где ОС не требуется. Представьте себе 1оТ-маячок. В нем не хватит ресурсов ни для чего, кроме единственной специфичной программы. К примеру, используя язык Rusl и подключив лишь его ядро и стандартную библиотеку, вы можете запустить любое приложение прямо на голом железе.
ОС берет на себя всю неявную и сложную работу, отделяя вас от аппаратных компонентов и предоставляя (как правило) чистый и понятно оформленный программный интерфейс для взаимодействия с приложениями (Application Programm Interface, или API). Такой API есть и у ядра Linux; его мы рассмотрим в главе 2. Обращения к предоставленному системой API называют «системны ми вызовами» (systemcall s, для краткости syseal Is). Языки верхнего уровня (Go, Rust, Python или Java) построены поверх т аких вызовов и выполняют их «под капотом» своих библиотек.
Так зачем же нужна операционная сиг гема? | 17
Благодаря этому вы можете сосредоточиться на бизнес-логике и забыть о самостоятельном управлении ресурсами или различиях в оборудовании, на котором будет запускаться приложение.
Рассмотрим конкретный пример системного вызова. Допустим, вы хотите узнать (и вывести на экран) ID текущего пользователя.
Для качала посмотрим на справку системного вызова getuid(2):
getuid() returns the real user ID of the calling process.
Отлично, getuid можно вызвать из кода своей библиотеки. Системные вызовы Linux мы подробно обсудим в одноименном разделе.
Возможно, вам интересно, что значит (?) в getuid(2) Утили та man (воспринимайте ее как встроенную справку) использу ет цифру 2 для определения раздела, который закреплен за командой в справке, — как почтовый индекс или код страны. Перед нами один из примеров очевидного наследия Unix. Узнать, откуда иоги растут, вы можете в Руководстве программиста Unix (Unix Programmer’s Manual), седьмое издание, том I7 от 1979 года.
В командной строке (в оболочке) мы можем вызвать равноценную команду id, которая сама выполнит системный вызов getuid:
$ id --user
638114
Теперь, когда вы представляете, почему использовать операционную систему имеет смысл, перейдем к теме различных дистрибутивов Linux.
7 UNIX PROGRAMMER’S MANUAL, Seventh Edition, Volume 1, January 1979: https://web. archive.org/web/201706C I C64537/http://plan9.beU-labs.corn/71hF.dMan/v7voll. pdf.
18 | Глава 1. Введение в Linux
Дистрибутивы Linux
Иногда при упоминании Linux можно запутаться в терминологии. В этой книге мы будем говорить «ядро Linux», или просто «ядро» (kernel), подразумевал набор системных вызовов и драйверов устройств. А под разными дистрибутивами мы будем понимать сборку для определенного ядра и связанных с ним компонентов, включая систему управления пакетами, структуру файловой системы, систему запуска и предварительно выбранную командную оболочку.
Конечно, все можно сделать самому: скачать и скомпилировать ядро, выбрать менеджер пакетов и т. д., чтобы собрать свой собственный дистрибутив. Изначально многие так и поступали. Но с годами люди уяснили, что упаковку (и уста новку исправлений безопасности) куца лучше доверить частным и коммерче ским специалистам и скачивать готовый дистрибутив Linux.
Если вы твердо решили создать собственную сборку, потому что вы мастер на все руки или вас вынуждают к этому определенные ограничения бизнеса, рекомендую присмотреться к ArchLinux. Он позволит вам полностью контролировать процесс создания дистрибутива при минимальных усилиях.
Чтобы получить представление о необъятности пространства дистрибути вов, загляните на DistroWatch, где представлены классические (Ubuntu, Red Hat Enterprise Linux [RUEL], CentOS, некоторые мы рассмотрим в главе 6), и современные дистрибутивы (Bottlerocket или Flatcar, см. главу 9).
Разобравшись с дистрибутивами, затронем иную тему — ресурсы, их видимость и изоляцию.
Видимость ресурсов
По умолчанию в Linux (в лучших традициях UNIX) все ресурсы видны глобально. Но что такое глобальная видимость (и по сравнению с чем)? И что за ресурсы?
Зачем мы вообще подняли тему видимости ресурсов? Основ  ная цель — повысить вашу осведомленность и настроить на правильный лад для пшружения в одну из важнейших тем современной Linux — гему контейнеров Не переживайте, если вы не поймете все сразу: мы будем периодически возвращаться к этой главе на протяжении всей книги, особенно
Дистрибутивы Linux | 19
из главы 6, где подробно обсудим контейнеры и их строитель ные блоки.
Возможно, вы уже слышали присказку о том, что в Unix (а значит, и в Linux) «все есть файл» В этой книге мы будем считать ресурсами все, что может способствовать выполнению программного кода. Сюда входит оборудование и его абстракции (процессор, оперативная память и файлы), файловая система, жесткие диски, твердотельные накопители (SSD), процессы, сетевые компоненты, а также устройства или таблицы маршрутизации и учетные данные пользователей.
Ресурсы в Linux не обязательно файлы или представлены через файловый интерфейс. Однако существуют системы типа Plan 98, где это требование поставлено во главу утла.
Рассмотрим некоторые ресурсы в Linux на примере. Сначала запросим глобальное свойство (версию Linux), а затем специфичную информацию о процес сорах (вывод отредактирован, чтобы влезал на страницу):
$ cat /proc/version О
Linux version 5.4.0-81-generic (builddglgwOl amdC4-051)
(gcc version 7.5.0 (Ubuntu 7.5.C1 3ubuntul~18,94))
#91-18.64.1-Ubuntu SMP Fri Jul 23 13:36:29 UTC 2021
$ cat /proc/cpuinfo j grep "model name" ®
model name	:	Intel	Cere	Processor	(Haswell,	no	T5X,	IBRS)
model nene	:	Intel	Core	Processor	(Haswell,	no	TSX,	IBRS)
model name	:	Intel	Core	Processor	(Haswell,	no	TSX,	IBRS)
model name	:	Intel	Core	Processor	(Haswell,	no	TSX,	IBRS)
О Отобразить версию Linux.
® Отобразить информацию о процессорах с фильтром по названию модели.
Из вывода команды мы узнали, что в распоряжении нашей системы четыре ядра процессора Intel i7. Как вы думаете, другой пользователь, вошедший в сис тему, увидит то же количество ядер?
3 Flan9 from Bell Labs: https://9p.io/plan9/.
20 | Глава 1. Введение в Linux
Рассмотрим другой тип ресурса: файлы. Если пользователь troy создаст файл /tnp/nyf fie, имея на это все разрешения (см. «Разрешения»), сможет ли другой пользователь, worf, увидеть этот файл или даже записать в него данные?
Или возьмем процесс, то есть iipoi рамму, которая загружена в память, и имеет доступ ко всем необходимым ресурсам — ЦП и памяти. Linux идентифицирует процессы по специальному ID процесса, для краткости PID (см. «Управление процессами»).
$ cat /ргос/SS/status | head -пб О Name: bash
Unask: 0002
State: S (sleeping)
Tgid: 2056
Ngid: 0
Pid: 2Э56
О Отобразить статус процесса (сведения о текущем процессе), ограничив вывод шестью строками.
что за $$?
Вы, вероятно, заметили значок $$ и заинтересовались, что он означает? Так называется специальная переменная, которая указывает на текущий процесс (подробнее см. «Переменные»). Обратите внимание, что в командной оболочке (такой как bash) $$ указывает на ID процесса самой оболочки, внутри которой выполняется команда.
А может ли в Linux существовать несколько процессов с одинаковым РЮ? Вопрос, который кажется бессмысленным и даже глупым, положен в основу контейнеризации (см. «Контейнеры»). Ответ — да, процессы с одинаковым РЮ могут существовать, но только в разных контекстах, которые в Linux называются пространствами имен (см. «Пространства имен Linux»).
Каждый отдельный процесс может считать себя особым, если имеет РЮ 1. В более традиционной конфигурации он зарезервирован для корня дерева процессов пользовательского пространства (подробности см. в разделе «Процесс загрузки в Linux»).
Наблюдения приводят нас к выводу, что отдельно взятый ресурс может быть виден глобально (два пользователя найдут один и тот же файл по одному и тому же пути) и локально, а также виртуально, как в примере с процессами. Возникает новый вопрос: а все ли в Linux глобально по умолчанию? Ответ — нет. Рассмотрим подробнее.
Видимость ресурсов | 21
Отчасти иллюзия многопользовательского доступа или параллельной работы нескольких процессов обеспечивается за счет (ограниченной) видимости ресурсов. За локальную видимость (отдельных поддерживаемых) ресурсов в Linux отвечают пространства имен.
Второе независимое измерение — это изоляция. Используя термин «изоляция», я не всегда подразумеваю его прямой смысл, тс есть не делаю выводов о полноте изоляции. К примеру, один из способов изолировать процесс — ограничить ему потребление памяти так, чтобы он не отбирал ресурсы у остальных. Представим, что я выделил приложению 1 Гб оперативной памяти. Если ему потребуется больше, процесс приложения аварийно завершится из-за нехватки памяти, что дает определенную степень защиты. За изоляцию такого типа в Linux отвечают контрольные группы (cgroups) (см. «Контрольные группы Linux»).
С другой стороны, полностью изолированная среда создает для приложения видимость того, что оно единственное и сбособленное. Для полной изоляции можно использовать виртуальную машину (VM, см. «Виртуальные машины»).
Linux с высоты птичьего полета
О-о, через какие дебри мы продрались. Пора немного передохнуть и снова сосредоточиться. На рисунке 1 -1 я попытался представить вам общий обзор операционной системы Linux, сопоставленный с главами книги.
Углубленные темы
Гл. 9
Приложения
Гл. б
Командные оболочки Гл.З
Сетевой стек	Наблюдаемость
Гл.7	Гл.8
Управление доступом Гл. 4
Файловые СИС1еМЫ Гл. 5
Ядро
Гл. 2
Рисунок 1-1. Сопоставление операционной системы Linux с главами книги
Б основе любой сборки Linux лежит ядро. Оно предоставляет API, на котором строится все остальное. Три гемы — файлы, сетевые функции и наблюдаемость — будут встречаться вам повсеместно. Рассматривайте их как основные
22 | Глава 1. Введение в Linux
блоки, выстроенные поверх ядра. А в обычной работе вы скоро заметите, что чаще всего имеете дело либо с оболочкой («В какой файл приложение пыгружа-ет данные?»), либо с доступами («Почему приложение упало? A-а, точно, каталог только для чтения!»).
Кстати, в главе 9 я собрал несколько интересных тем, в которых затронул виртуальные машины и современные дистрибутивы. Я назвал главу « Углубленные темы », поскольку она не такая уж и обязательная Вы прекрасно обойдетесь без нее Однако, если вы хотите воспользоваться всеми возможностями современной Linux, я настоятельно рекомендую вам с ней ознакомиться. Разумеется, остальные главы, с 2 по 8, следует изучить внимательно, применяя знания по мере продвижения.
ПЕРЕНОСИМЫЙ ИНТЕРФЕЙС ОПЕРАЦИОННЫХ СИСТЕМ (POSIX)
Время от времени в книге будет встречаться термин POSIX (сокращение от Portable Operating System Interface, или «переносимый интерфейс операционных систем»). Официально POSIX — это IEEE-стандарт, определяющий интерфейсы служб для операционных систем UNIX, созданный в стремлении обеспечить переносимость между отдельными реализациями. Видя фразу «POSIX-совмесгимо», воспринимайте ее как набор спецификаций, важных при официальных закупках, и куда меньше — в по вседневной работе.
Linux изначально создавался с учетом соответствия стандартам POSIX и спецификациям UNIX System V Inteface Definition (SVID). Чувствуется аромат старины, напоминающий о UNIX времен AT&T, в отличие от систем в стиле Berkeley Software Distribution (BSD).
Если вы заинтересовались POSIX, то для лучшего освоения темы ознакомьтесь с книгой «Абстракции POSIX в современных операционных системах: старые, новые и утраченные»9, с прекрасным введением и замечательными комментариями.
Заключение
Под словом «современный» мы подразумеваем Linux в современных средах, включая телефоны, дата-центры (у общественных облачных провайдеров) и встраиваемые системы, например, Raspberry Pi.
9 POSIX Abstractions in Modern Operating Systems: The Old, the New, and the Missing. VaggcLs Atkdakis, Jeremy Andrus, Roxana Geambasu, Dimitris Mitropoulos, and Jason Nieh. Columbia University: http./7nsl.cs.colu mbia.edu/papers/2016/posix.eurosysl6.pdf.
Заключение | 23
R этой главе я представил вам беглый обзор предыстории Linux. Мы выяснили, что роль операционных систем — отделять приложения от оборудования и предоставлять им базовый набор функций для работы с процессами, памятью, файлами и сетью, и посмотрели, как с этой ролью справляется Linux, особенно в отношении видимости ресурсов.
Следующие отсылки помогут вам идти в ногу со временем и глубже погрузиться в концепции этой главы.
Изданные O’Reilly
—	Карла Шредер, «Linux. Книга рецептов»'0.
—	Daniel Р. Bovet and Marco Cesati, «Understanding the Linux Kernel»".
—	Дэниэл Джей Барретт, «Linux. Командная строка. Лучшие практики»10 11 12.
—	Роберт Лав, «Linux. Системное программирование»13.
Другие ресурсы
—	Расширенное программирование в среде UNIX14 15 — полный курс, предлагающий вводный материал и практические упражнения.
—	«Рождение UNIX»13 с Брайаном Керниганом — отличный ресурс для изучения изначальной Linux и разъясняющий многие оригинальные концепции UNIX.
Ну а теперь начнем путешествие в современную Linux от самой основы, то есть от ядра.
10 Linux Cookbook, 2nd Edition by Carla Schroder (O’RcJly Media). 2021.
https://www.oreilly.com/library/view/linux-cookbook-2iid/9781492087151/. Русский перевод: Карла Шредер, «Linux. Книга рецептов» (Питер). 2022. https:/iwvrw.piter.com/coUection/ linux/product/linux-kniga-reiseptov-2-eizd.
11 «Understanding the Linux Kernel, 3-rd edition» by Daniel P. Bovet and Marco Cesati (O’Reilly Media) (Понимание ядра Linux, 3 издание).
https://www.or eilly com/Lbrary'vicw/understand ing-the-Enux/0596005652/.
12 «Efficient Linux at the Command Line» by Daniel J. Barrett (O’Reilly Media), 2022.
https://www.oreillycom/library/view/efficient-lmux-at/9781098113391/. Русский перевод: Дэниэл Джей Барретт, «Linux. Командная строка. Лучшие практики» (Питер). 2025. https://www.piter.com/collection/all/product/linux-komandnaya-stroka-lvchshLe-praktiki.
13 Linux System Programming by Robert Love (O’Reilly Media). 2013.
https.//www.orei.ly.corn/library/view/linux system •programming/9781449341527/. Русский перевод: Роберт Лав, «Linux, Системное программирование. 2-е издание» (Питер). 2018.
14 Advanced Programming in the UNIX Environment. https://stevens.netmeister.org-'631/.
15 «Ihe Birth of UNIX» with Brian Kernighan; https://corecursive.com/brian-kernighar.- unix-bell-labsl/.
ГЛАВА 2
Ядро Linux
Из раздела «Зачем нужна операционная система?» мы узнали, что задача операционной системы — абстрагироваться от аппаратной части и предоставить API, которое позволит писать приложения, не заботясь о том, где и как они будут запускаться. Если коротко, ядро предоставляет API для программ.
В этой глазе мы обсудим, что такое ядро Linux и как воспринимать его в связке с отдельными компонентами. Вы познакомитесь с архитектурой Linux и той существенной ролью, которая возложена на ядро. К концу главы вы поймете, что хотя ядро выполняет основные функции, это еще не вся операционная система, а лишь его центральная часть.
Для начала кратко изучим, как ядро вписывается в базовое оборудование и взаимодействует с ним. Затем рассмотрим вычислительный центр, различные архитектуры центрального процессора и их связи с ядром. Потом подробнее разберем отдельные компоненты ядра и API, которое предоставляется запускаемым программам. И, наконец, обсудим настройку и расширение ядра Linux.
Эта глава снабдит вас необходимой терминологией, познакомит с интерфейсами между программами и ядром, а также даст общее представление о его функциональности. Усвоенная информация не превратит вас в разработчика ядра или системного администратора, который настраивает и собирает ядра, но если вам интересна эта тема, в конце главы я дам несколько полезных ссылок.
Перейдем к сути — архитектуре Linux и ключевой роли, отведенной ядру.
Архитектура Linux
При беглом взгляде архитектура Linux выглядит так, как показано на рисунке 2-1. Выделим три основные группы:
Аппаратная часть
Все «железо», от процессоров и основной памяти до дисковых накопителей, сетевых интерфейсов и периферии, включая устройства ввода и мониторы
Архитектура Ьпих | 25
Ядро
Основная тема г сей главы. Между ядром и пользовательским пространст вом можно расположить ряд других компонентов — систему инициализации, системные службы (сеть и т. д.), — которые, строго говоря, не являются частью ядра.
Пользовательское пространство
Здесь работает большинство приложений, включая такие компоненты операционной системы, как оболочки (shells, обсудим в главе 3), утилиты вроде ps или ssh, а также графический пользовательский интерфейс — например, рабочий стол на основе оконного менеджера X.
В этой книге мы сосредоточимся на двух верхних слоях из рисунка 2-1 — на ядре и пользовательском пространстве. Аппаратный слой мы поверхностно затронем здесь и в паре других глав.
Оболочка
Display server
Терминал
Пользовательское пространство
Рисунок 2 1. Обзор архитектуры Linux
Интерфейсы для верхних слоев четко описаны и входят в поставку ОС Linux. За взаимодействия между ядром и пользовательским пространством отвечает уже знакомый вам интерфейс системных вызовов (syscalls). Подробнее мы рассмотрим его в разделе «Системные вызовы».
26 | Глава 2. Ядро Linux
А вог интерфейсы для взаимодействий ядра с аппаратной частью уже не так монолитны. Обычно это целая коллекция интерфейсов, сгруппированных по типам устройств.
1.	Интерфейсы центральных процессоров (см. «Архитектуры процессоров»)
2.	Интерфейсы оперативной памяти (рассмотрены в «Управление памятью»)
3.	Сетевые интерфейсы и драйверы, проводные и беспроводные (см. «Сетевое взаимодействие»).
4.	Интерфейсы драйверов файловой системы и блочных устройств (см. «Файловые системы»).
5.	Символьные устройства, аппаратные прерыватели, драйверы устройств ввода, го есть клавиатур, терминалов, и прочих устройств ввода/вывода (см. «Драйверы устройств»)
Как видите, множество программ, которые обычно считаются частью ОС Linux — оболочки или утилиты вроде grep, Find или ping, на самом деле нс часть ядра, а часть пользовательского пространства, как и загружаемые приложения.
Применительно к пользовательским программам вы будете часто слышать или читать о пользовательском режиме и режиме ядра. Речь о тем, насколько привилегированным будет доступ к оборудованию и насколько ограниченными доступные абстракции.
В целом режим ядра означает быстрое выполнение, но урезанные интерфей сы, а в пользовательском режиме — сравнительно медленные, зато безопасные и удобные для вас. Если вы не разработ чик ядра16, го режим ядра можете смело игнорировать: ваши приложения будут всегда запускаться в пользовательском пространстве. С другой стороны, умение обращаться к ядру напрямую (см. «Системные вызовы») — важнейший навык, который нас, безусловно, интересует.
Закончив общий обзор архитектуры, перейдем к аппаратному обеспечению.
Архитектуры процессоров
Прежде чем обсуждать компоненты ядра, давайте рассмотрим общую концепцию взаимозаменяемых компьютерных архитектур, или семейства процессоров. Способность Linux запускаться на процессорах разных архитектур, возможно, одна из причин ее популярности.
16 HOWTO do Linux kernel development (Как разрабатывать ядро Linux)- https-//www kernel <;rg/doc/h tml/v4.10/process/howto.html
Архитектура процессоров | 27
Помимо универсального кода и драйверов, в ядро Linux отдельно включают специфичный код для процессорных архитектур. Благодаря этому можно легко портировать и запускать Linux на новом оборудовании.
Определить, какой процессор использует ваша Linux, можно множеством способов.
BIOS и UEFI
Традиционно и UNIX, и Linux для собственной загрузки использовали «базовую систему ввоца/вывода» (Basic I/O System, или BIOS). При нажатии кнопки питания ваш ноутбук с Linux полностью контролировался аппаратно. Первым делом система проводила самодиагностику (Power-On Self-lest. или POST), которая входила в BIOS. Она позволяла подтвердить, что все оборудование (оперативная память и пр.) работает штатно. Подробнее этот механизм рассмотрен d разделе «Процесс загрузки в Linux».
В современных средах функционал BIOS заменен «унифицирован кым расширяемым микропрограммным интерфейсом» (Unified Extensible Firmware Interface, или UEFI)17 — общедоступная спецификация которого описывает программный интерфейс для взаимодействия между операционной системой и прошивкой платформы. Поскольку в документации или статьях вы по-прежнему будете натыкаться на аббревиатуру B1OS, предлагаю вам мысленно заменять ее на UEFI и двигаться дальше
Один из способов — использовать утилиту dnidecode, которая взаимодей ствует с BIOS. Если она не вернет результат, можно попробовать другой способ (вывод урезан):
s Iscpu
Architecture:
CPU ср mode(s):
Byte Order:
Address sizes:
CPU(s):
On-line CPU(s) list:
Thread(s) per core:
Core(s) per socket:
Socket(s):
NUMA node(s):
x86_64 О
32-bit, 64-bit
Little Endian
46 bits physical, 48 bits virtual
4 ©
e з
i
4
1
1
17 UEFI Wiki: https://en.wikipedia.org/wki/Unified_Extensible_Finnware_Interface.
28 | Глава 2. Ядро Linux
Vendor ID:	Genutnelntel
CPU farily:	6
Model:	60
Model na^ie:	Intel Core Processor (Haswell, no TSX, IBRS)
Stepping:	1
CPU MHz:	2592.094
О Мы видим архитектуру х86_64.
® Похоже, доступны четыре процессорных ядра.
® Название модели процессора: Intel Core Processor (Haswell).
При выполнении команды мы выяснили, что архитектура процессора определяется как х86_ 64, а модель называется Intel Core Processor (Haswell). Скоро мы узнаем, что это значит.
Еще один способ получить схожую информацию — использовать команду cat /ргос/сриinfo, или, если вас интересует только архитектура процессора, просто набрать ипапе -п.
Мы научились запрашивать информацию об архитектуре в Linux. Теперь разберем результат.
Архитектура х8б
х8618 19— это семейство наборов инструкций, первоначально разработанное Intel и позже лицензированное AMD (Advanced Micro Devices). В ядре х64 соотносится с 64-битпыми процессорами Intel, х8б — с 32-битиыми процессорами Intel, и adm64 — с 64 -битными процессорами AMD.
Сегодня процессоры семейства х86 часто встречаются в домашних компьютерах и ноутбуках. Они широко используются и в серверах — в частности, эти процессоры формируют основу общественного облака. Архитектура х86 мощ ная и широкодоступная, однако не слишком энергоэффективная. Поскольку она сильно зависима от внеочередности исполнения (out-of-order execution), в последнее время она часто привлекает к себе внимание из-за проблем с безопас иостью (уязвимость Meltdown)1’.
18 х86 Wiki: https://en.wikipedia.org/w<ki/X86.
19 Mettdown Attack: https://mehdownattack.com/.
Архиенуры процессоров | 29
Подробную информацию о протоколе загрузки Linux/x86 или специфичную для Intel и AMD вы найдете в документации к ядру, связанной с х8620 * 22 2Э.
Архитектура ARM
Семейству архитектур ARM21 больше тридцати лет. Оно использует вычислитель с набором упрощенных команд (Reduced Instruction Set Computing, или RISC), который обычно состоит из множества процессорных регистров общего назначения и небольшого набора быстрых инструкций.
Проектировщики Acorn (компании, которая стоит за ARM) постарались минимизировать энергопотребление, поэтому чипы на базе ARM можно обнаружить в портативных устройствах — в iPhone и большинстве телефонов с Android, — а также во встраиваемых 1оТ системах, таких как Raspberry Pi.
Поскольку чипы ARM быстрые, дешевые и выделяют меньше тепла по сравнению с х86, не стоит удивляться, что и в дата-центрах тоже все чаще мелькают процессоры на базе ARM — например, AWS Graviton22 Архитектура ARM про ще х86, но тоже подвержена уязвимостям (например, Spectre23). Если интересно, загляните в документацию к ядру, связанную с ARM24.
Архитектура RISCV
RISC-V (произносится как «риск пять»)25 — это подающий надежды открытый стандарт RISC, изначально разработанный Калифорнийским университе том в Беркли. На 2021 год известно много реализаций: от Alibaba Group, Nvidia и разных стартапов, например, SiFive. Это перспективное, но (пока) не слишком распространенное семейство процессоров. Если вы хотите получить представ ление о том, как работает технология, и разузнать о ней побольше, — хорошим началом будет статья Шаи Эриссон «Linux на RISC-V» 26 27
Дополнительные сведения ищите в документации к ядру, связанной с RISC-V2’
20 х86 specific kernel documentation: https://w4-w.kernel.oqt/doc/htrrJ/next/x86/indcx.html.
11 ARM Wiki: https://ea.wikipedia.org/wiki/ARM_architecture_family;
22 AWS Graviton: https://aws.amazon.com/ru/ec2/graviton/.
23 Spectre Attack. https://mcltaownattack.com/.
24 ARM Architecture: https://www.kernel.org/doc/html/next/arm/index.html.
25 Иногда встречается вариант произношения «риск-фа йь». (Прим, ред.)
26 Linux on RISC-V by Shae Erisson: https://shapi.github.io/posts/2019-06-08-riscv-linux.hlml.
27 RISC-V architecture: https://www.kernek.org/doc/htmi/nexi/riscv/index.html
30 | (тава 2. Ядро Linux
Компоненты ядра
Мы познакомились с архитектурами процессоров, и теперь самое время заглянуть в ядро Linux. Хотя оно монолитное, и все обсуждаемые компоненты помещены в один двоичный файл, в кодовой базе можно выделить функциональные области и приписать км специальные обязанности. Как обсуждалось в разделе «Архитектура Linux», место ядра — между оборудованием и приложениями, которые вы собираетесь запускать. Вог основные функциональные блоки, которые можно выделить из кодовой базы:
—	Управление процессами, то есть запуск процесса на основе исполняемого файла,
—	Управление памятью, то есть выделение памяти для процесса или отображение файла в память.
—	Сетевые функции, то есть управление сетевыми интерфейсами или предоставление сетевого стека.
—	Файловые системы, обеспечивающие управление файлами с поддержкой создания и удаления.
—	Управление символьными устройствами и драйверами устройств.
Зачастую эти компоненты так сильно завязаны друг на друга, что не нарушать девиз разработчиков ядра28 «Ядро не лезет в пользовательское пространство» становится по-настоящему непростой задачей.
Рассмотрим поближе каждый из компонентов.
Управление процессами
Множество частей в кодовой базе ядра связаны с управлением процессами. Одни касаются материй, специфичных для архитектуры ЦП (например, прерываний), другие отвечают за запуск и планирование программ.
Прежде чем перейти к специфике Linux, отметим, что отдельный процесс — это сущность, видимая пользователю и базирующаяся на исполняемой программе (или двоичном файле). Поток, в свою очередь, — это сущность, исполняемая внутри процесса. Зозмсжно, вы уже сталкивались с термином «многопоточность»; это значит, что в одном процессе запущено несколько параллельных выполнений, возможно, использующих разные ЦП.
18 «Kernel never breaks usei land»: https.//yarchive.net/comp/linux/gcc .vs kernel stability.html.
Компонен1ыядра | 31
Если мы разобрались с терминологией, давайте посмотрим, как работает с процессами Linux. От комплексного к простому
Сессии
Содержат одну или несколько групп процесссв и представляет собой высокоуровневый пользовательский блок с опционально подключенным tty. Ядро определяет сессию по номеру, который называется идентификатором сессии (Session ID или SID).
Группы процессов
Включают в себя один или несколько процессов с единственной 1руппой процессов переднего плана в сессии. Ядро определяет группу процессов по номеру, который называется идентификатором группы процессов (Process Group ID, или PGID).
Процессы
Абстракции, объединяющие несколько ресурсов (адресные пространства, один или больше потоков, сокеты и т. д.), которые ядро предоставляет вам через /proc/seZ/для текущего процесса. Ядро идентифицирует процессы по номеру, который называется идентификатором процесса (Process ID, или P1D).
Потоки
Реализуются ядром в виде процессов. Жестких структур для представления потоков не существует, и их можно рассматривать как процессы, к< >торые используют определенные ресурсы (память или обработчики сигналов) совместно с другими потоками. Ядро идентифицирует потоки через ID потока (Thread ID, или TID) и ID группы иотоков (Thread Group ID, или TGID), с семантикой, в которой общий TGID означает многопоточный процесс (в пользовательском простран стве. Бывают еще потоки ядра, но они выходят за рамки нашего обсуждения).
Задачи
Специальная структура данных в ядре с названием task_struct (объявлена в sched.h29). Она формирует основу реализации для процессов и потоков. В этой структуре собирается информация о планировании: идентификаторы (такие как PID или TGID), обработчики ситналов, данные, связанные с безопасностью или производительностью. Иными словами, все упомянутое проистекает и/или закрепляется в задачах, ко сами задачи за пределами ядра не представлены.
29 schec hsource code: https //elix.r i>ooLir com/luiux/v6.13.6/sonrre/include/linux/schedh#L661.
32 | Inaea 2. Ядро Linux
Мы проследим за работой сессий, групп процессов и самих процессов, когда доберемся до главы 6, а в главе 9 при изучении контейнеров вернемся к ним снова.
Давайте взглянем па эти концепции предметно:
$ ps -j
PID	PGID	SID	TTY	TIME	CMD
67S6	6756	67S6	pts/0	00:00:00	bash О
6790	6790	6756	pts/0	00.00:00	ps ®
О PID, PG1D и SID процесса оболочки bash равны 6756. Из команды Is -al I proc/6756/task/67 56/ мы можем почерпнуть информацию на уровне задачи.
® PID/PGID процесса ps равен 6790, a SID такой же, как у оболочки.
Ранее упоминалось, что структура данных задачи в Linux держит наготове связанную с планированием информацию. Это значит, что в любой момент времени процесс находится в каком-то определенном состоянии из тех, что показаны на рисунке 2-2.
Рисунок 2-2. Состояния процессов в Linux
На самом деле состояния процессов немного сложнее. К примеру, Linux разделяет прерываемый и непрерываемый сон, есть еще состояние зомби (когда утерян родительский процесс). Если вам интересны подробности, ознакомьтесь со статьей «Состояния процессов в Linux»30.
и Статья -'Process States in Linux»: https:/,'kerneltalks. cora/Enux/process -states-in-linux/.
Компоненты ядра | 3?
Возникновение событий приводит к смене состояний. Например, запущенный процесс может перейти в состояние ожидания, если он выполнял какую-нибудь операцию ьвода/вывода (читал данные из файла) и не может продолжать (недоступен ЦП).
После краткого обзора процессов рассмотрим смежную тему — память.
Управление памятью
Виртуальная память создает видимость, что у вашей системы больше памяти! чем есть физически. Каждому процессу выделяется большой объем (виртуаль ной) памяти. Вот как это работает: и физическая, и виртуальная намять разбивается на фрагменты фиксированной длины, которые называют страницами.
На рисунке 2-3 показаны виртуальные адресные пространства двух процессов, каждый со своей таблицей страниц. Эти таблицы обеспечивают наложение виртуальных страниц процесса на физические страницы в оперативной памяти (RAM).
Физическая память (ОЗУ)
Рисунок 2-3. Обзор управления виртуальной памятью
Разные виртуальные страницы могут указывать на одни и те же физические страницы через соответствующие им таблицы страниц па уровне процесса В пе котором смысле это и есть управление памятью — эффективно создавать для процесса иллюзию того, что ею страница существует в оперативной памяти, оптимально используя имеющееся пространство
Каждый раз, когда ЦП обращается к виртуальной странице процесса, ему нужно преобразовать виртуальный адрес, который использует процесс, в соответствующий ему физический адрес. Чтобы ускорить преобразование — а оно может быть многоуровневым, и значит, медленным, — процессоры современных архитектур поддерживают встроенный внутренний поиск, так называемый
34 | Глава 2. Ядро Linux
буфер ассоциативной трансляции (Translation Lookaside Buffer, или TLB31)- Фак тически TLB — эго маленький кэш; после того, как ЦП обращается к таблице страниц процесса и вычисляет адрес физической страницы, он сохраняет или обновляет его в TLB,
Традиционно размер страницы з Linux составлял 4 Кб, но начиная с версии ядра V2.6.3 появилась поддержка больших страниц (huge pages32) для лучшего соответствия современным архитектурам и рабочим нагрузкам. К примеру, 64 битный Linux позволяет использовать в общей сложности до 128 ТБ виртуального адресного пространства (где виртуальное — это теоретически доступное для адресации число адресов памяти) на процесс и приблизительно 64 ТБ физической памяти (где под физической понимается объем оперативкой памяти вашего компьютера).
Ладно, теории было предостаточно. Давайте посмотрим с более практической точки зрения. Интерфейс /proc/meninfo — крайне полезный инструмент для выяснения информации о памяти, в частности, о доступном количестве RAM
$ grep Мег:Total /ргос/nehtnfo О
MenTotal:	4014636 ke
$ grep VnallocTotal /proc/ne«T.nfo в
VnallocTotal:	34359738367 kB
$ grep Huge /proc/nemirfo •
ArtonHugePages:	0 kB
ShnemHugePages: FtleHugePages: HvgePages.Total: HugePages.Free: HugePages Jlsvc:	0 kB 0 kB 0 0 0
riugePages_Surp: Hugepagestze:	0 7948 kB
Hugetlb:	0 kB
О Подробности о физической памяти (RAM): всего 4 ГБ
в Подробности о виртуальной памяти: чуть больше 34 ТБ
© Информация о больших страницах: судя по всему, размер страницы 2 МБ.
Далее переходим к следующей функции ядра: сетевому взаимодействию.
31 Translation Looka side Buffer (TLB): https://en.wikipedia.org/wiki/Translation_lookaside_buffer.
32 Huge pages: https://wiki, de bi an.org/Hugepages.
Компоненты ядра | 35
Взаимодействие с сетью
Обеспечение сетевого взаимодействия — одна из самых важных функций ядра. Просматриваете ли вы страницы или копируете данные в удаленную систему, вы зависите от сети.
У сетевого стека Linux mhoiоуровневая структура.
Сокеты
Для абстрактной коммуникации
Протокол управления передачей (TCP) и протокол пользовательских датаграмм (UDP)
Для соединения с подтверждением и без подтверждения данных соответственно.
Межсетевой протокол (1Р)
Для обрашения к компьютерам.
Ядро заботится только об этих трех действиях. Протоколы прикладного уровня, такие как HTTP или SSH, обычно реализуются на уровне пользовательского пространства.
Вог как получить список доступных сетевых интерфейсов (вывод урезан):
$ ip link
1: io: «LOOPBACK, UP, LOWER_UP> mtu 6E536 qdtsc requeue state UNKNOWN node DEFAULT group default qlen 1000 link/loopback 00:00:60:30:00:60 brd 00:00:00:00:00:09
2: enp0sl: «BROADCAST, MULTICAST, UP, LOWER_UP> mtu 1500 qdtsc fq coael state UP mode DEFAULT group default qlen 1003 link/ether 52:54:00:12:34:56 brd ff:ff:ff:ff:ff:ff
Команда iproute предоставляет сведения о маршрутизации. Сети отведена целая глава (глава 7), где мы углубимся в сетевой стек, поддерживаемые протоколы и типичные операции. А сейчас обратимся к следующему компоненту ядра — блочным устройствам и файловым системам.
36 | Глава 2. Ядро Linux
Файловые системы
С помощью файловых систем Linux упорядочивает файлы и каталоги на устрой ствах хранения — жестких дисках (HDD), твердотельных накопителях (SSD) или флеш-накопителях. Доступны системы различных типов, к примеру, ext4, btrfs или NTFS. Можно использовать несколько экземпляров той же файловой системы одновременно.
Виртуальная файловая система (VFS) изначально предлагалась для поддержки множества типа а файловых систем и их экземпляров. Верхний уровень абстракции VFS предоставляет API для основных функций: открытие, закрытие, чтение и запись. Нижний — абстракции, называемые расширениями (или плагинами) для конкретных файловых систем.
Подробнее файловые системы и операции с файлами мы рассмотрим в гла ве 5.
Драйверы устройств
Драйвером называют часть кода, которая работает в ядре. Ею задача — управлять устройством, которое может быть как настоящим оборудованием (клавиатурой, мышью или жестким диском), так и пссвдоустройством, таким как псевдотерминал в /dev/pts/ (физического устройства нет, но система считает его таковым).
Другой интересный класс оборудования — графические процессоры (GPU)33, которые с давних пор помогали ускорять вывод графики, снижая нагрузку на центральный процессор. В последние годы GPU нашли новое применение в области машинною обучения34, и их больше нельзя считать актуальными только для домашних компьютеров.
Драйвер может быть статически включен в само ядро или собран как модуль ядра (см. «Модули») и динамически загружаться по мерс надобности.
Если вам интересен интерактивный способ изучения драйве • ров и взаимодействия компонентов ядра, ознакомьтесь с картой ядра Linux35.
33 Graphics processing unit (GPU). https://en.wikipedia.org/wiki/Grapbics_processing_unit.
34 Machine learning on GPU; https.//www.tensorflow.org,'guide/gpu?hl=ru.
35 Linux Kernel Map; https://makelinux.github.io/kernel/inap/.
Компоненты ядра | 37
Драйверная модель36 ядра сложна и выходит за рамки этой книги. Однако дальнейших подсказок по взаимодействию с ней должно хватить, чтобы вы сориентировались самостоятельно.
Обзор устройств в вашей системе Linux можно получить с помощью Is:
$ Is -al /sys/devices/ total 0
drwxr-xr-x 15	root root 0 Aug 17 15:53.
dr-xr-xr-x 13	root root 0 Aug 17 15:53 ..
drwxr-xr-x $	root root 0 Aug 17 15:53 LNXSYSTM:0O
drwxr-xr-x 3	root root 0 Aug 17 15:53 breakpoint
drwxr-xr-x 3	root root 0 Aug 17 17:41 isa
drwxr-xr-x 4	root root 0 Aug 17 15:53 kprobe
drwxr-xr-x 5	root root 0 Aug 17 15:53 nsr
drwxr-xr-x 15	root root О Aug 17 15:53 pci0000:00
drwxr-xr-x 14	root root 0 Aug 17 15.53 platform
drwxr-xr-x 8	root root 0 Aug 17 15:53 pnp0
drwxr-xr-x 3	root root 0 Aug 17 15:53 software
drwxr-xr-x 10	.oot root 0 Aug 17 15:53 system
drwxr-xr-x 3	root root 0 Aug 17 15:53 tracepoint
drwxr-xr-x 4	root root 0 Aug 17 15:53 eprobe
drwxr-xr-x 18	root root 0 Aug 17 15:53 virtual
А с помощью mount можно узнать, какие устройства смонтированы:
$ mount
sysfs on /sys type sysfs (rw, nosuid, nodev, noexec, relatime)
proc on /proc type proc (rw, nosuid, nodev, noexec, relatime) devpts on /dev/pts type devpts (rw, ncsuio, noexec, relatime, \ gld=5, mode=520, ptmxnode-000)
tmpfs on /run/snapd/ns type tnpfs (rw, nosutd, nodev, noexec, \
relative, size=401464k, node=755, inode64)
nsfs on /run/snapd/ns/lxd.mnt type nsfs (rw)
Мы заканчиваем с компонентами ядра Linux и переходим к интерфейсу взаимодействия между ядром и пользовательским пространством.
36 Driver Model: https://www.ken.el.org/doc/html/latest/driver-api/ariver-iiiodel/index.htmJ
38 | Глава 2. Ядро Linux
Системные вызовы (syscalls)
Неважно, печатаете вы в консоли touchtest txt, или ваше приложение загружает файл из удаленной системы. Все сводится к тому, что вы просите Linux превратить высокоуровневую инструкцию «создать файл» или «прочитать все байты с адреса такого-то», в набор конкретных шагов, зависящих от архитектуры Иными словами, обращение из пользовательского пространства к предостав ленному ядром служебному интерфейсу превращается в череду системных вызовов (сокращенно syscalls37).
В Linux множество системных вызовов — порядка трехсот, в зависимости от семейства ЦП. Обычно вы или ваши программы вызываете их не напрямую, а через стандартную библиотеку С. Она предоставляет функции-обертки, и доступна в различных реализациях, например, giibc38 или musl39.
Библиотеки с обертками выполняют важную задачу — берут на себя низкоуровневую обработку повторяющихся системных вызовов. Системные вызовы реализованы через программные прерывания: они выбрасывают исключения, которые передают управление обработчику исключений. Для каждого системного вызова необходимо выполнить ряд действий, которые показаны на рисунке 2-4.
Рисунок 2-4. Этапы выполнения системного вызова в Linux
1.	Ядро использует так называемые «таблицы системных вызовов», которые определяются в syscal.h и дополнительных файлах для конкретных архитектур. По сути, это загруженный в память (в переменную
37 syscalls man: https://man7.org/linux/man-pages,'ir.an2/sysualls.2.html.
38 glibc: https://wi4w.gnu.org/software/kbc/.
39 musl: https://musl.libc.org/.
Компоненгь ядра | 39
sys_call_table) массив указателей на функции для отслеживания системных вызовов и соответствующих им обработчиков.
2.	Функция systepi_call() играет роль мультиплексора системных вызо вов. Сначала она сохраняет в стек аппаратный контекст, потом выполняет проверки (не запущена ли трассировка, к примеру), а после переходит к функции, на которую указывает цифровой индекс системного вызова в sys_call_table.
3.	После того как системный вызов завершается sysexit, библиотека-обертка постанавливает аппаратный контекст, и выполнение программы возобновляется в пользовательском пространстве.
В описанных выше шагах примечательно переключение из режима ядра в пользовательский режим; такая операция занимает некоторое время.
Да, суховато получилось, много теории. Для наглядной иллюстрации рабо ты системных вызовов лучше рассмотрим конкретный пример. Чтобы заглянуть за кулисы, мы воспользуемся утилитой strece40 — полезной для устранения неполадок в случаях, когда исходный код приложения вам недоступен, но вы хотите узнать, чем оно занимается.
Предположим, вам интересно, какие системные вызовы задействует невип ная на первый взгляд команда 1s. Вот как выяснить это с помощью strace:
$ strace Is О
execve("/usr/bin/ls", ["Is"], 0x7ffe292S4910 /* 24 vars */) = 0 ®
brk(NULL)	= 6x5595e5a3c000 C
access("/etc/ld.so preload", R_OK) = -1 CNOENT (No such file or \ directory) О
openat(AT_FDCWD, "/etc/ld.so cache”, O_RDONL\|O_CLOEXEC) = 3 ®
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\9 \
p\0\e\0\9\0\0"..., 832) = 832 Ф
® Запуская stracels, мы просим strace перехватить системный вызов, который использует Is. Заметьте, что я отредактировал вывод, поскольку на моем компьютере strace генерирует около 162 строк (количество варьируется в зависимости от дистрибутива, архитектуры и прочих факторов). Кроме того,
40 strace: b.ttps:"strace.io/.
40 | Глава 2. Ядро Linux
результат получен из stderr, Если вы хотите перенаправить его, в конце нужно добавить 2>. Подробнее об этом в главе 3
© Системный вызов execve41 выполняет lusr/bin/ls, вызывая замену процесса оболочки,
© Системный вызов brk42 — это устаревший способ выделения памяти Безопаснее и лучше для переносимости использовать nalloc. Отмечу, что nalloc — это функция, а не системный вызов, и она вызывает nallocopt, чтобы в зависимости от объема доступной памяти определить, какой системный вызов использовать: brk или ппар.
О Системный вызов access проверяет, разрешен ли процессу доступ к файлу.
© Системный вызов openat открывает файл /etc/ld. so.cache относительно дескриптора файла каталога (первый аргумент AT TDCWD, то есть текущий каталог) с использованием флагов O_RDONLV|O_CLOEXFX (последний аргумент).
Ф Системный вызов read считывает из файлового дескриптора (первый аргумент, 3) 832 байта (последний аргумент) в буфер (второй аргумент).
strace полезен, когда нужно отследить, какие именно системные вызовы были произведены, в каком порядке и с какими аргументами. Утилита эффективно подключается к живому потоку событий между пользовательским пространством и ядром. Она отлично подходит для диагностики производитель ности. Давайте посмотрим, на что команда curl тратит большую часть времени (вывод урезан):
$ strace -с \ ©
curl -s https://пЬаи5епЫа5.тсР- > /dev/null ©
% tine	seconds	usecs/call	calls	errors	syscall
26.75	J.031965	148	215		map
17.52	0.020935	136	153	3	read
10.15	0.012124	175	69		rt_stgactton
8.06	0.009561	147	65	1	openat
7.61	0.009098	126	72		close
6.00	0.000000	0	1		prltnit64
100.60	0.119476	141	843	11	total
41 execve: https,//www.man7.org?iinux,'maii-pages/man2.'execve.2.htini.
42 brk: https://www.man7.org,'linux/man-pa.ges/man2,'brk.2.html.
Компоненты ядра | 41
О Добавляем опцию -с, чтобы вывести общую статистику использованных системных вызовов.
в Результаты выполнения curl отбрасываем в /dev/null.
Примечательно, что команда curl потратила почти половину времени на системные вызовы тиар и read, а системный вызов connect занял всею 0,3 миллисекунды — неплохо.
Чтобы дать вам некоторое представление о масштабе, я составил таблицу 2-1, в которой перечислил популярные системные вызовы, как из компонентов ядра, так и общесистемные. Полную информацию о системных вызовах, включая описание входных параметров и возвращаемых значений, вы найдете в разделе 2 страниц справки43.
Таблица 2-1. Примеры системных вызовов
Категория	Примеры системных вызовов
Управление	clone, fork, exeeve, wait, exit, getpi d, setuid, setns, getrusage,
процессами	capset, ptrace
Управление памятью brk, mmap, munmap, mremap, mlock, mlncore
socket, setsockopt, getsockopr, bind, listen, accept, connect, shutdown, reevf rom, reevmsg, sendto, sethostname, bpf
	open, openat, close, mknoc, rename, truncate, mkdir, rmdir,
Файловые системы	getewd, chdir, chr oot, getdents, link, symlink, unlink, umask, stat,chmod, utime, access, ioctL, flock, read, write, Iseek, sync, select, poll, mount
Время	time, clock settime, timer_create, alarm, nancsleep
Сигналы	Kill, pause, signalfd, eventfd
Глобальные	uname, sysinfo, syslog, acct, _sysctl, iopl, reboot
В интернете доступна удобная интерактивна я таблица системных вызовов44 со ссылками на исходный код.
43 Linux manual pages; section 2 hrtps.//www.man7.org,'Linux/man-pages/dir_sectior._2.html.
44 SyscaJs table: https7/fi lppo.io/linux-syscaJ- table/.
42 | Глава 2. Ядро Linux
Теперь, когда мы познакомились с ядром, его компонентами и интерфейсом, давайте разберемся, как можно его расширить.
Расширения ядра
В этом разделе мы сосредоточимся на способах расширения ядра. Честно говоря, эта информация продвинутого уровня. Она не обязательна и вряд ли пригодится вам в повседневной работе.
Настройка и сборка собственного ядра Linux выходит за рамки книги. Чтобы научиться этому, я рекомендую вам прочитать книгу «Linux Kernel in a Nutshell» Грега Кроа-Хартмана45 46, одного из главных сопровождающие разработчиков Linux и руководителя проекта. Грег охватил весь спектр задач, от загрузки исходного кода до этапов настройки и установки, включая подстройку параметров ядра во время выполнения.
Начнем с простого: как узнать, какую версию ядра вы используете?
Выполните такую команду:
$ ипаие -згм
Linux 5.11.0 25 generic х86_64 О
О Из результата выполнения ипа.зе видно, что на м< >мент написания статьи я использую ядро v5.11 “ на компьютере х8ь.,64 (см. «Архитектура х86»).
Зная версию ядра, можно рассмотреть вопрос о его расширении за пределы дерева, то есть без добавления функций в исходный код и без пересборки. Для подобного расширения используются модули. Давайте выясним, что это такое.
Модули
Если коротко, то модули — это программы, которые загружаются в ядро по требованию. Не нужно перекомпилировать ядро и даже перезагружать машину.
45 Linux Kernel in a Nutshell by Greg Kroal: -Hartman (O'Reilly .Media, Inc) 2006: https://www. orcilly.com/library/view/linux-kemel-in/0596100795/.
46 Active kernel releases: bttps://www.kemel.org/releases.html.
Расширения ядра | 43
В настоящее время Linux автоматически обнаруживает большую часть оборудования и подключает требуемые модули. Однако иногда модуль требуется за грузить вручную. Например, ядро обнаружило видеокарту и загрузило универсальный модуль. Но производитель видеокарты предлагает лучший модуль, недоступный в ядре Linux.
Для получения списка доступных модулей выполните следующую команду (я обрезал вывод, потому что в моей системе выводится больше тысячи строк):
5 find /lib/modules/$(uname -г) -type f -name '*.ko*'
/lib/nodules/5.11.0-25-generic/kernel/ubuntu/ubuntu-host/ ubuntu-host.ko
/lib/modules/5.11.0-25-generic/kernet/fs/nls/nls_iso8859-1. ko
/1 ib/modutes/5.11. 8-25-generic/kernel/fs/ceph/ceph. ko
/llb/modules/5.11.0-25 generic/kernel/fs/nfsd/nfsd.ko
/llb/modules/5.11.0 25-generic/kernel/net/Lpv6/esp€.ko
/llb/modules/5.11.0 25 generic/kernel/net/ipv6/ip6vti.ko
/lib/i'iodules/5.il.0-25-generic/kernel/net/sctp/sctp_diag ko
/lib/modules/5.11.0- 25-gencric/kernel/net/sctp/sctp. ko
/lib/modules/5.11.0-25generic/kernel/net/netrom/netrom.ko
Прекрасно! Но какие модули ядро уже загрузило? Давайте выясним (вывод урезан):
$ Isnod Module	Size	Used by
linear	20480	0
crctl0dif_pclmul	16384	1
crc32_pclnul	16364	0
ghash_clmilni_intel	16364	0
vtrtto_net	57344	0
net_failover	20480	1 vtrtio_net
ahet	40960	0
aesni_intel	372736	0
crypt t._simd	16384	1 aesni_intel
crypto	24576	2 crypto_simd, ghash_clmulni_intel-
glue_helper	16384	1 aesni_intel
44 | Глава L Ядре Lirux
Отмечу, что информация получена через /ргос/nodules. Спасибо ядру, которое предоставило ее через интерфейс псевдофайловой системы (подробнее см. б главе 6).
Хотите больше узнать о модуле или заполучить удобный способ манипулировать модулями ядра? Ваш друг — команда oocprcbe. Вот, например, список зависимостей:
$ ncdprobe --show-depends asyncjnerccpy
insmod /lib/modiLes/5 11.0 25 •qeneric/kernel/crypto/asyr.c_tx/async_tx. kc
insmod /lib/mcdules/5 .11.0- 25 -generi.c/kernel./crypto/async_tx/async_niencpy. ko
Теперь рассмотрим более современный способ расп ирить функционал ядра.
Современный способ расширить ядро: eBPF
Набирает популярность расширение функционала ядра через eBPF. Этот про ект ядра и технология изначально назывались BPF (Berkeley Packet Filter, или «фильтр пакетов Беркли»), но со временем прижилось название eBPF (без специальной расшифровки).
Технически eBPF — эт о подсистема ядра Linux (версии не ниже 3.15), которая позволяет безопасно и эффективно расширить функционал ядра через системный вызов bpf47 48. eBPF реализован как встроенная в ядро виртуальная машина со специальным 64-битным набором инструкций RISC.
Если хотите узнать о возможностях eBPF в различных вереи ях ядра, загляните в документацию репозитория iovisor/bcc на GitHub.
На рисунке 2-5 представлен общий обзор, взятый из книги Брендана Грегга «ВРР. Профессиональная оценка производительности» (Addison Wesley)43.
47 b pf(2) — Linux manual page: https://man7.org/linux/man pa.ges/man2/bpf.2.htmi
48 Brendan Gregg’s book BPF Performance Tools: Linux System and Application Observability (Addison Wesley) 2019: https://wwwbrendangregg.com/bpf-perfbrmance-tools-book.html. Русский перевод: Брендан Грегг, «BPF. профессиональная сценка производительности» (Питер) 2025-https://www.piter сот/prod act/bpf-professiondnaya-otsenka-proizvoditclnosti.
Расширения ядра | 45
Рисунок 2-5. Обзор eBPF в ядре Linux
cBPF используется в ряде мест и решает разные задачи
В качестве CNI плагина для добавления сетеного обмена между модулями Kubern etes К примеру, в Cilium49 и Project Calico Также для масштабируемости сервиса.
Для наблюдаемости
При трассировке ядра Linux, например, с помощью iovisor/bpftrace50, и в кластерах с Hubble51 (см. главу 8).
Для контроля безопасности
Например, для сканирования контейнера в реальном времени, как это сделано в проектах с CNCF Falco52.
Для балансировки сетевой нагрузки Как в библиотеке L4 katran53.
В середине 2021 года, когда консорциум Linux Foundation объявил, что несколько компаний объединяются для создания eBPF Foundation54, у проекта появился постоянный дом без предпочтений определенному поставщику. Следите за обновлениями!
Если хотите оставаться в курсе событий, загляните на ebpf.io55.
49 Cilium Github repository: https://github. com/cilium/ciliam.
50 Bpttrace Github repository: https://github.com/bpftrace/bpftiace
51 Hubble Github repository: nttps://github.com/cilium/hubble.
52 Falco — cloud native securit у tool: https://falco.org/.
53 Katran repository: https://github.coni/facebookincubator/katran.
34 eBPF Finds a Home with a New Foundation: https://thenewstack.io/ebpf-finds-a-home-witli-a-new-foundation/.
55 eBPF site: https://ebpf.io/.
46 | Глава 2. Ядро Linux
Заключение
Ядро Linux — это сердце операционной системы. Е каком бы дистрибутиве, в какой бы среде вы ии использовали Linux, на настольном компьютере или в облаке, вы будете иметь представление о его компонентах и функциях.
В этой главе мы рассмотрели архитектуру Linux, роль ядра и его интерфейсов Подытожим, ядро абстрагируется от аппаратных различий в архитектуре ЦП и периферийных устройствах, что способствует легчайшей переносимости Linux. Основной интерфейс — это интерфейс системных вызовов, через который ядро реализует любой функционал, будь то открытие файлов, выделение памяти или вывод списка сетевых интерфейсов.
Мы слегка углубились во внутреннюю работу ядра, рассмотрели модули и еВРЕ Если вы заинтересовались расширением ядра для высокопроизводительных задач (управляемых из пространства пользователя), то eBPF определенно стоит внимания
Для погружения в аспекты работы ядра хорошей отправной точкой послужат эти ресурсы:
Общие.
—	Майкл Керриск «Linux API. Исчерпывающее руководство» (Питер). 2025.
—	Обучение ядру Linux56 предлагает отличное введение и углубленные материалы по всем направлениям.
—	«Анатомия ядра Linux»57 дает краткое обзорное введение.
—	«Ядра операционных систем»58 предлагает хороший обзор и сравнение подходов к проектированию ядер.
—	KernclNcwbies5’ — огличный ресурс для углубления в практические гемы — kernelstats60 периодически выкатывает интересные вещи.
—	Карта ядра Linux61 — визуальное представление компонентов ядра с его зависимостями.
56 Linux Kernel Teaching: iittps-.'/linux -kernel labs.github.io/refs/heads/ master/lectures/mtro.html.
57 An atomy of the Linux kernel. https://developer.ibm.com/ar1 icles/l-linux-kernel/.
58 «Operating System Kernels» presentation: htips://www.cs.cornelledu/courses/cs614/2007fa/
SKdes/kernel%20architectures.pdf
” Kernel newbies: https:/.'kernelnewoies.org/.
№ kernelstats repository: https://github.com/udoprog/kernelstats.
61 Linux Kernel Map: https://makelinux.github.io/kernel/map/.
Заключение | 47
Управление памятью
—	Вникая в менеджер управления виртуальной памятью62.
—	«Аллокатор памяти Slab з ядре Linux»63.
—	Документация ядра64.
Драйверы устройств
—	Джонатан Корбет., «Драйверы устройств Linux» (свободное распространение по лицензии CCBY-S А 2.0)65.
—	«Как установить драйвер устройства в Linux»66.
—	Драйверы символьных устройств67 * 69.
—	Драйверы устройств Linux: Учебное пособие по разработке драйверов Linux66.
Системные вызовы
—	«Прерывания Linux: основные концепции»64.
—	Ядро Linux: системные вызовы70.
—	Таблица системных вызовов Linux71.
—	Исходный код syscalls h72.
—	Обзор системных вызовов для х86 и х86_6473.
62 Understanding the Linux Virtual Memory Manager; https://www.kernel.org/doc/gormati/pdf/ understand pdf.
61 The Slab Allocator in the Linux Kernel: https://hammertux.github.io/slab-aliocator.
64 Kernel docs: https://www.kernel.org/doc/htrul/latestzadi nin-guide/mm/mdex.html.
65 Linux Device Drivers by Jonathan Corbet (Creative Commons Attribution-ShareAiike 2.0 license): https:/71wn.net/Kernel/LDD3/. Русский перевод (авторский); https:,'/drmlvdv.narod. ru/Translate/LDD3/J.inux_Device_Drivers_3_ru.pdf.
66 How to Install a Dev.ce Driver on Linux: https://opensource.eom/article/18/l 1/how-install-device- driver-lie ux.
67 Character Device Drivers: https://linux-kernel-labs.github.io/refs/heads/mastet/labs/device_ drivers.html.
“ Linux Device Drivers: Tutorial for Linux Driver Development; https://www.apriorit.com/dev-blog/195 simple driver for linux-os.
69 Linux Interrupts: The Basic Concepts: https://www.cs.montana.edu/courses/spring2005/518/ Hypertextbook/ jjn/media/interrup:s_on_linux.pd:.
70 The Linux Kernel: System Calls: https://linux-kernel-labs.github.io/refs/heads/master/lectures/ syscalls.html.
71 Linux System Call Table: https://faculty.iips.efiu/cseagle/assembiy/sys_call.htm).
72 syscalls.h source code: https://elixir.bootlin.com/linux/v6.13 6/source/include/liriux/syscalls h
73 syscall lookup for x8fc and x86_64:1 ittps://filippo. io/linux-sysca/Ltable/.
48 | Глава 2. Ядре Linux
eBPF
—	«Введение в еВРР»от Мэтта Осзальта’4.
-	Документация по еВРР-маппингу74 75.
Вооруженные этими знаниями, мы шагаем на следующую ступеньку лестницы абстракций и обращаемся к основному интерфейсу пользователя, рассмотренному в книге: к командной оболочке (shell) — в режиме ручного использования и с автоматизацией с помощью скриптов.
74 «Introduction to eBPF» by Matt Oswalt: https://oswaltdev/2021/Ol/introdjction-tc ebpf/.
75 eBPF maps documentation: https://protorype-kerne1.readthedocs.:c/en/latest/bpf/cbpf_maps. html.
ГЛАВА 3
Оболочки и скрипты
Эту главу мы посвятим работе через терминал, а именно — взаимодействию с Linux из специальной оболочки (shell), текстовая среда которой называется интерфейсом командной строки (CLI). Решая повседневные задачи, важно использовать оболочку эффективно, поэтому немалое внимание мы уделим удобству работы.
Для начала выделим общие понятия и мягко погрузимся в основы работы с оболочкой. Затем рассмотрим современные и комфортные для человека обо лочки (например, Fish), их настройку и примеры решения повседневных задач. Научимся эффективно использовать CLI с терминальным мультиплексором, освоим работу с локальными и удаленными сеансами. В конце главы мы сменим курс и сосредоточимся на автоматизации задач с помощью скриптов, ознакомимся с лучшими практиками их безопасных, надежных и переносимых спосо бов написания, а также как выполнять форматирование (линтинг) и тестирование.
Взаимодействовать с Linux с точки зрения CLI можно двумя способами. Первый — используя ручной ввод, то есть сидя перед терминалом, набирая команды в интерактивном режиме и изучая полученный результат. Именно так вы будете общаться с системой при решении большинства повседневных задач, включая:
—	Изучение списка каталогов, поиск файлов или определенного содержимого в них.
-	Копирование файлов из каталога в каталог и на удаленные машины.
—	Чтение писем и новостных лент или отправку сообщений в социальные сети из терминала.
Чуть позже мы научимся легко и действенно работать с несколькими параллельными сеансами оболочки.
Другой режим работы — автоматизированный запуск последовательности команд, записанных в специальный файл (скрипт), который оболочка разберет и выполнит. Этот режим обычно называют режимом работы со сценариями, или скриптингом (scripting). Для решения повторяющихся задач всегда разумнее написать скрипт: на них базируются многие настройки и установки. Скрипты
50 | Глава 3. Оболочки и скрипты
очень удобны, но и опасны при неосмотрительном подходе. Собираясь писать скрипт, вспоминайте комикс от XKCD с рисунка 3-1.
«Я потратил кучу всремени на эту задачу! Напишу-ка программу для ее автоматизации!»
ОЖИДАНИЕ:
НАПИСАНИЕ КОДА Л
РАБОТА НАД ОСНОВНОЙ ЗАДАЧЕЙ
ДАЛЬШЕ ВСЕ АВТОМАТИЗИРОВАНО
СВОБОДНОЕ ВРЕМЯ
ВРЕМЯ
РЕАЛЬНОСТЬ'

ОТЛАДКА
НАПИСАНИЕ	/
КОДА к/
7 ПЕРЕОСМЫСЛЕНИЕ ,	л
_______У _________-------НА ОСНОВНУЮ ЗАДАЧУ ВРЕМЕНИ
НЕ ОСТАЛОСЬ
ВРЕМЯ
Рисунок 3-1. XKCD про автоматизацию76. Права принадлежат
Рэндаллу Манро (распространяется по лицензии СС BY-NC 2 5)
Еще раз настоятельно рекомендую завести компьютер с Linux, чтобы практиковаться по ходу изучения. Итак, готовы к (взаимо)действию? Если да, то начнем с терминологии и основ использования оболочки.
Основы
Прежде чем мы погрузимся з различные опции и настройки, давайте выделим основные термины, такие как терминал и оболочка (shell). Я объясню вам их значения и покажу, как выполнять в оболочке повседневные задачи. Так же я дам обзор современных команд, а вы увидите их в действии.
76 «Автоматизация» httpf:'/xkcd.oom,'1319/.
Основы | 51
Терминалы
Начнем с терминала, или эмулятора терминала, или иротраммнсго терминала — программы, которая предоставляет интерфейс для текстового ввода от пользователя. Иначе говоря, терминал поддерживает чтение символов с клавиатуры и отображает их на экране. В стародавние времена такие устройства были объединенными (клавиатура вместе с экраном), но сегодня терминалы — это обычные приложения.
В дополнение к посимвольному вводу и выводу термина,ты поддерживают так называемые escape последовательности, или escape коды77 для управления экраном, курсором, и поддержки цветовых схем. Нажатие Ctrl+H, например, приведет к возврату курсора на одну позицию с удалением символа слева.
Переменная окружения TERM указывает на текущий эмулятор терминала, а его настройки можно получить через inf остр следующим образом (вывод урезан):
$ infостр О
# Reconstructed via infocnp from file: /lib/terninfo/s/screen-2S6color scre&n-256color|CNII Screen with 256 colors, am, kn, mir, rasgr, xenl, colors#0xl(?0, cols#80, tt#8, lines#24, pairs#0x!0O00, acsc=+-i-\,\,-. .00 aaffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz
{{I ID",
Ье1-ЛС, blink=\E[5m, bold=\E[lm, cbt=\E[Z, civls=\Er?25l, clear=\E[H\E[J, cncrm-\E[34h\E[?25h, cr=\r,
О Результат выполнения inf остр нелегко переварить. Если хотите узнать о всех возможностях подробнее, обратитесь к базе данных terminfo78. В моем случае терминал поддерживает отображение 80 столбцов (cols#80) и 24 строк (Lines#24) в 256 цветах (color sfrOxl90, в шестнадцатеричной системе счисления)
В пример можно привести не только xterm, rxvt и Gnome terminator, по и новое поколение терминалов, которые используют графический процессор: Alcaritty79, kilty80 и warp81.
Мы вернемся к терминалам в разделе «Терминальный мультиплексор».
77	escape sequences, escape codes: https://en.wiki pedia.org/wiki.-ANSI_escape. code.
78	terminfo database: https://www.man7.org/linux/rnan-pages/man5/terminfo.5.html.
79	Alacrity repository: https://gitbub.com/alacritty/alacritty.
80	kitty: https://sw.kovidgoyal.net/kitty/.
81	warp: https://www warp.dev/.
52 | Глава 3. Оболоч ки и скрипты
Оболочки
Далее следует оболочка (или she 11), которая работает как интерпретатор команд внутри терминала. Оболочка занимается обработкой ввода и вывода через потоки {streams), поддерживает переменные, имеет несколько готовых к исполь зованию встроенных команд и, как правило, допускает работу в двух режимах — с интерактивным использованием и через скрипты (см. «Сценарии»), Официально оболочка определена в sh82, и мы часто сталкиваемся с выражением «POSIX shell»’3, что будет важно при обсуждении сценариев и портируемости.
Изначально была только Bourne shell sh, названная по имени ее разработчика Стивена Борна, но в наши дни ее часто заменяют оболочкой bash84 (название стало результатом игры слов от «Bourne/Born Again Shell», или «Переродившаяся Bourne shell»), которую все чаще используют по умолчанию.
Выяснить, какую именно оболочку используете вы, можно командой file -h /bin/sb, а если не получится, наберите echo $0 или echo SSHELL.
Б этом разделе мы будем всегда подразумевать оболочку bash, если явно не указана другая.
Существует множество реализаций sh и других оболочек, которые вышли из моцы: например, Korn shell ksh или оболочка на С csh. Мы рассмотрим современные альтернативы bash в разделе «Удобные для работы оболочки».
Начнем изучение работы с оболочкой с двух фундаментальных понятий: потоков {streams) и переменных {var iables).
Потоки введа/вывода
Начнем с темы, касающейся потоков ввода и потоков вывода, для краткости I/O. Как передать программе входные данные? Как контролировать выходной поток — вывести его в терминал или перенаправить в файл?
Прежде всего, оболочка снабжает каждый процесс тремя файловыми дескрипторами (FD) для ввода и вывода:
—	stdin (FD 0);
—	stdout (FD 1);
—	stderr (FD 2).
82 sh(Ip) man: https://www.man7.Org/linax/rnai:-pages/manl/sh.lp.html.
83 POSIX Shell: https7/drewdevaul:.com/2018/02/C5/Introduction to POSIX shell.html
84 bash: https://en.wikipedia.org/wiki/Bash_%28Uinix_sheE%29.
Осноеы | 53
По умолчанию эти дескрипторы подключены к вашей клавиатуре и экрану, как показано на рисунке 3-2. Это значит, что, если не указано иное, команда, которую вы вводите в оболочке, получит входные данные с вашей клавиатуры (stdin) и выведет их на экран (stdout).
Проиллюстрируем это стандартное поведение:
$ cat
Здесь я что-то печатал и сам же читалЛС
В примере с использованием cat вы видите значения по умолчанию в действии. Обратите внимание, что я нажал Ctrl+C (показано как Л£), чтобы завершить выполнение.
Рисунок 3-2. Стандартные для оболочки потоки ввода/вывода
Если вы хотите изменить стандартное поведение оболочки — например, вы вести stderr в файл, а нс на экран, — то можете перенаправить85 потоки.
Выходной лоток процесса перенаправляется стрелкой: $F0> или <$FD, где $FD заменяется на файловый дескриптор. Например, 2> означает перенаправление потока stderr. Обратите внимание, записи > и 1> равнозначны, поскольку stdout (FD 1) — это значение по умолчанию. Если вы хотите перенаправить и stdout,
85 Перенаправление потоков: https:/,'teaching.idaJlen com,'cst8207/L9w/.
54 | Глава 3 Оболочки и скрипты
и stderr, используйте &>, а если хотите совсем заглушить поток, перенаправьте его в /dev/null.
Давайте посмотрим, как это работает, на примере загрузил содержимого HTML-страницы утилитой curl:
$ curl https://exanple.coe &> /dev/null О
$ curl https://example com > /tmp/сопtent.txt 2s /tnp/curl-status ®
$ head -3 /tmp/content.txt
<!doctype html>
<html>
<head>
$ cat /tnp/curl-status
% Total % Received % Xferd Average Speed Тиче Tire Tire Current Dload	Upload Total Spent Left Speed
100 1256 102 12S6 0	0	3187	0	3195
$ cat > /tmp/interactive-input.txt ©
$ tr < /tnp/curl-status [A-Z] [a-z] ®
% Lotal % received % xferd average speed tine time time current dload upload total spent left speed
100 1256 1Э0 1256 Э 0	3187	0	3195
О Заглушить вывод, перенаправив stdout и stderr в/dev/null.
® Перенаправить данные и статус в разные файлы.
ю Интерактивный ввод данных и сохранение в файл; используйте Ctrl-D, чтобы остановить захват и сохранить содержимое
О Перевод всех слов в нижний регистр с помощью команды tr, которая считывает данные с stdin.
Обычно оболочки понимают некоторые специальные символы:
Амперсанд (&)
Помещенный в конец команды, заставляет ее выполняться в фоновом режиме (см. «Управление заданиями»).
Обратный спеш (|)
Используется для продолжения команды на следующей строке (для лучшей читаемости длинных команд)
Основы | 55
Вертикальная черта (I)
Ее еще называют конвейером. Соединяет stdout одного процесса со stdin следующего, позволяя передавать данные без необходимости их промежуточно го сохранения.
ФИЛОСОФИЯ КОНВЕЙЕРОВ В UNIX
Хотя на первый взгляд конвейеры не слишком интересны, в них скрыт мощный потенциал. Однажды я приятно побеседовал с Цугом Макилроем, создателем конвейеров. Я опубликовал статью под названием «Пересмотр философии Unix в 2018 году»86, в которой провел параллели между UNIX и микросервисами. Кто-то оставил комментарий, который заставил Дута написать мне письмо (очень неожиданно, я даже не поверил сначала) — и прояснить некоторые детали.
Давайте снова претворим теорию в практику. Выясним, сколько строк содер жит HTML-файл, сначала загрузив его через curl, а затем передав содержимое в инструмент wc:
$ curl https://exaople.con 2> /dev/null | \ О wc -I е
46
О Используем сиг! для загрузки содержимого с URL-адреса и отбросим статус, который выводится в stderr. (Замечу, что на практике вы использовали бы curl с опцией - s, но мы же хотим научиться применять с трудом добытые знания, так ведь?)
® Направляем stdout от curl на stdin для wc, который подсчитает количество строк с параметром -I.
Вооружившись общими знаниями о командах, потоках и перенаправлении, перейдем к другой главной особенности оболочек — обработке переменных.
Переменные
Переменная (variable) — очень частый термин в работе с оболочками Когда вы не хотите или не можете задать значение сразу, вы используете переменные
’6 Revisiting the Unix Philosophy in 2018: https://opens.ource.eom/article/18/l 1/rev.siting-umx philosophy-2018.
56 | Глава 3. Оболочки и скрипты
для временного хранения или подстановки данных. Переменные используются в следующих случаях;
— Когда требуется обработать элементы конфигурации Linux. К примеру, путь, по которому оболочка ищет исполняемые файлы, хранится в переменной $РАТН. Это своего рода интерфейс, через который переменная может быть прочитана или записана.
— Когда нужно интерактивно запросить значение у пользователя — например, при отработке скрипта.
— Когда вы хотите сократить количество вводимого текста, определив значение всего один раз — например, длинную часть интернет-адреса для HTTP API. Этот вариант похож на использование констант (const) в языках оро-раммирования, поскольку объявленная переменная уже не меняется.
Различают два вида переменных:
Переменные окружения
Переменные на уровне оболочки; их список можно взывать командой env.
Переменные оболочки
Действительны только в рамках текущего выполнения (отображаются с помощью команды set в bash). Подпроцессам такие переменные не видны.
Переменная окружения задается в bash командой export. Чтобы затем прочитать значение, подставьте знак доллара $ перед ее названием, а чтобы избавиться от нее, используйте unset.
Но хватит теории, перейдем к практике (в bash):
$ set MY_VAR=42 О
$ set | grep MY_VAR ®
_=MY_VAR=42
$ export W_GLCBAL_vAR-' забавы ради' ®
$ set | grep ’MY_*' ®
MY_GL9BAL_VAR='забавы ради'
=MY VAR-42
$ env | grep 'MY_*' ©
MY_CL0BAl_VAR=3a6aed ради
Основы | 57
$ bash Ф
$ echo $MY GLOBAL_VAR Ф Забавы ради
$ set | grep MY_*' Ф MY_GLOBAL_VAR='забавы ради'
$ exit Ф
$ unset $MY_VAR
$ set | grep 'MY_*'
KY_GlOBAL_VAR='забавы ради'
О Создать переменную оболочки с именем MY_VAR и присвоить ей значение 42 ® Вывести список переменных оболочки и отфильтровать переменную MY_VAR.
Обратите внимание: _= значит, что она не экспортируется.
Ф Создать переменную окружения MY_GI OBAl_VAR.
О Вывести список переменных оболочки и отфильтровать начинающиеся с 4Y_.
Как и ожидалось, видны обе переменные, созданные на предыдущих шагах Ф Вывести список переменных окружения.
Ф Создать новый сеанс оболочки, который будет дочерним процессом текущего сеанса оболочки и не унаследует mY_VAR.
в Запросить переменную окружения MY_ClOBAl_VAR,
© Вывести список переменных оболочки, который покажет нам только MY_ CLOBAL_VAR, поскольку мы находимся в дочернем процессе
Ф Завершить дочерний процесс, удалить переменную оболочки MY_VAR и вывести переменные оболочки. Как и ожидалось, MY_VAR исчезла.
В таблице 3-1 я собрал стандартные переменные оболочки и окружения. Эти переменные доступны почти везде, их важно понимать и использовать. Значение любой переменной можно посмотреть через echo $ХХХ, где XXX — ее имя.
Таблица 3-1. Стандартные переменные оболочки и окружения
Переменная Тип	Объяснение
EDITOR
Окружение Путь к программе по умолчанию, используемой длг редактирования
файлов
НОМЕ
HOSTNAME
IFS
POSIX Путь к домашнему каталогу текущего пользователя
Оболочка bash Текущее имя хоста
POSIX	Список символов для ра ’деления полей; используется, когда оболочка
разделяет слова при оасширег ии
53 | Глава 3. Оболочки и скрипты
PATH	POSIX	Содержит список катало) ов, з которых оболочка ищет исполняемые программы (двоичные файлы или скрипты)
PSI	Окружение	Используемый вид строки приглашения
PWD	Окружение	Полный путь к рабочему каталогу
OLDPWD	Оболочка bash	Полный путь к каталогу перед последним вызовом команды cd
RANDOM	Оболочка bash	Случа йное целое число от 0 до 32767
SHELL	Окружение	Содержит имя основной оболочка
TERM	Окружение	Тил основного эмулятора терминала
UlD	Окружение	Уникальный ID текущею пользователя (целое число)
USER	Окружение	Имя текущего пользователя
		Оболочка bash	Последнк й аргумент предыдущей команды, выполненной интерактивно
?	Оболочка bash	Статус выхода (см. «Статус выхода»)
$	Оболочка bash	ID текущею процесса (целое число)
0	Оболочка bash	Имя текущего процесса
Также ознакомьтесь с полным списком переменных, специфичных для bash, Обратите внимание, что переменные из таблицы 3-1 снова пригодятся вам в контексте «Сценариев».
Статус выхода
Оболочка сообщает вызывающей стороне о завершении выполнения с помощью гак называемого статуса выхода. В общем случае ожидается, что команда Linux обязательно вернет статус при своем завершении, которое может быть нормальным (все успешно) или аварийным (что-то пошло не так). Статус выхода 6 означает, что команда отработала без ошибок, а любое ненулевое значение от 1 до 255 сигнализирует об ошибке Запросить статус выхода можно командой echo $?
Будьте внимательны с обработкой статуса ьыхода в конвейерах: некоторые оболочки предоставляют доступ только к последнему статусу. Обойти зто ограничение можпо с помощью $PIPESTATUSS7.
Встроенные команды
Оболочки содержат ряд встроенных команд. Зот несколько полезных: yes, echo, cat или read (в зависимости от сборки Linux некоторые из таких команд могут быть не встроенными, а располагаться в /usr/Ып). Список встроенных команд вызывается командой help. Однако помните, что остальные команды — внешние по отношению к ободочке программы, которые обычно можно найти в /usr/ bin (для пользовательских команд) или в /usr/sbin (для административных).
Как узнать, где находится исполняемый файл? Вот пара способов
” using pipestatus: https://www.shellscript.sh/exair.ples/pipestatus/.
Основы | 59
$ which is
/usr/btn/ls
$ type is
is is aliased to Is --color=auto'
Один из технических рецензентов книги справедливо отметил, что whi ch не POSI: это внешняя программа, которая не всегда доступна. Он предложил использовать command -v вместо which для нахождения пути к программе и/или определения псевдонима/функции оболочки. За подробностями обратитесь также к документации shellcheck”.
Управление заданиями
Большинство оболочек поддерживает управление заданиями (jobcontrol)™. По умолчанию запущенная команда берет под контроль экран и клавиатуру; это называется запуском на переднем плане. Но что делать, если вы не хотите запускать программу интерактивно, или, как в случае с сервером, ввода от stdin нет вообще? Используйте управление заданиями и фоновые задания: чтобы запустить процесс в фоне, добавьте в конце &, или отправьте процесс переднего плана в фоновый режим, нажав Ctrl+Z.
Следующий пример даст вам представление о том, как это работает:
$ watch -п 5 "Is" & О
$ jobs ® Job Сгоьр	CPU	State	Command
1	3021	0%	stopped watch -n 5 "Is" &
$ fg © Every 5.0s: Is		Sat Aug 26 11:34:32 2021
Dockerfile
app.yaml
example.json
main,go
script.sh test
•' she llcheck docs: bttps://gi1 hub.com/ koa laman/sbellcheck/wiki/SC2230.
89 job control: https^/wwwrdigitalocean.com/cominunity/tutorials/hovv to-use-bash-s-job-control-to-manage- foreground -and-backgroun d-processes.
60 | Глава 3. Обоьочкч и скрипты
О Добавив в конце команды &, мы запускаем ее в фоновом режиме.
® Выводим список заданий.
® Командой fg переводим процесс на передний план. Чтобы выйти из команды watch, используйте Ctrl+C.
Если хотите, чтобы фоновый процесс продолжал работать даже после закрытия оболочки, добавьте команду nohup. А для уже запущенного процесса, который не был помечен как nohup, зы можете использовать команду disown постфактум, чтобы добиться того же эффекта. Наконец, чтобы избавиться от запущенного процесса, используйте команду kilt с различными уровнями воздействия (подробнее см. в разделе «Сигналы»).
Вместо управления заданиями я рекомендую мультиплексоры терминалов, описанные в разделе «Терминальный мультиплексор». Программы этого тина берут на себя большинство распространенных задач (закрытие оболочки, координацию нескольких запущенных процессов), а также умеют работать с удаленными системами.
Давайте обсудим современные замены для часто используемых команд.
Современные команды
Несколько команд вы будете использовать ежедневно и постоянно, среди них навигация по каталогам (cd), обзор списка файлов (is), поиск файлов (find) и отображение их содержимого (cat, less).
Учитывая такую повторяемость, действовать следует эффективно: каждое нажатие клавиши имеет значение.
Для некоторых таких команд есть более современные аналоги. Одни работают точно так же, другие добавляют новый функционал. Все они предлагают значения по умолчанию для частых операций, улучшенный вывод, который легко читается, и, как правило позволяют меньше печатать для выполнения той же задачи. Работать с оболочкой становится приятнее и удобнее. Если вы хотите узнать больше о современных инструментах, загляните в Приложение Б. Хочу сра зу оправдаться, особенно если вы собираетесь использовать эти рекомендации в корпоративной среде- я не заинтересован в рекламе ни одного из этих инструментов и рекомендую их потому, что считаю полезными сам. Хороший способ установить и ознакомиться с любым инструментом — использовать ту версию, которая проверена выбранным вами дистрибутивом Linux.
Основы | 61
Вывод содержимого каталога с помощью еха
Когда вы хотите узнать, что содержится в каталоге, вы используете команду Is или ее вариацию с параметрами. Например, в bash я создал для связки Is -GAhltr простой псевдоним I. Однако есть способ получше — еха*’, современная замена Is, написанная на Rust, со встроенной поддержкой Git и отрисовкой дерева Как вы думаете, какую команду используют чаще всего после просмотра содержимого каталога? По моему опыту, очистку экрана, для которой набирают команду clear — пять букв и нажатие ENTER. Тот же эффект можно получить гораздо быстрее, просто нажав Ctrl+L.
Просмотр содержимого файла с помощью bat
Представим, что вы вывели список файлов и хотите просмотреть один из них Вероятно, вы используете cat, но присмотритесь к более удобной альтернативе: bat90 91 92. Как показано на рисунке 3 3, эта команда умеет подсвечивать синтаксис, показывать непечатаемые символы, поддерживает Gil и постраничный просмотр файлов, содержимое которых не помеш ается на экран.
Поиск содержимого и файлах с помощью rg
Традиционно для поиска содержимого в файлах используется grep. Однако есть более современная, быстрая и мощная альтернатива — команда гд9\
В следую!цем примере сравним гд с комбинацией команд find и grep для поиска YAML файлов, в которых есть строка «sample»:
$ find, -type f -name '"*.yaml" -exec grep "sample" '{}' \; -print О app: sample app- sample
./app.yaml
$ rg -t "yaml" sample ® app.уami
9:	app: sample
14:	app: sample
О Поиск строки в файлах YAML комбинацией find и grep.
® Использование гд для той же задачи.
90 Утилита еха на замену Is: https:/,/exa.ai/.
91 Утилита bat на замену cat: https://github.com/sharkdp/bat.
92 Утилита rg на замену grep: https://github.com/BurntSushi/ripgrep.
62 | Глава?. Оболочки и скрипты
Если сравнить команды и результат выполнения, гд проще в использовании и информативнее (ока предоставляет дополнительную информацию — номер строки).
File: main.go
package main
import (
"fmt"
"net/http" )
func main() {
http.HandleFunc(, HelioServer)
http.ListenAndServe(":8080", nil) }
func HelloServer(w http.Responsewriter, r >http.Request) { fmt.Fprintf(w, "Hello, %s!", r.URL.Path[l:])
}
File: app.yaml
apiVersion: apps/vl
kina: Deployment
metadata:
name: something
namespace: xample
spec:
selector:
matchLabels: app: sample replicas: 2 template: metadata: labels:
app: sample
spec:
contai ners:
- name: example
image: public.ecr.aws/mhausenblas/exampIe:stable
Рисунок 3-3. Отображение файла Go (вверху) и файла YAML (внизу) с помощью bat
Основы | 63
Обработка данных JSON с помощью jq
А теперь бонус. Команда jq не замена, а скорее специализированный инструмент для работы с JSON — популярным форматом текстовых данных, который можно обнаружить повсюду — от HTTP АР] до файлов конфигурации.
Давайте используем jq91 вместо awk или sed, чтобы выбрать определенные значения. С помощью генератора случайных {SON-данных* 94 я получил файл exanple.json размером 2 4 Кб, который выглядит примерно так (показана только первая запись);
[ { "_id": "612297a64aG57a3fa3a56fcf”, "latitude": -25.750679, "longitude": 130.044327, "friends"; [ { "id": 0, "name": "Tara Holland" }, { "id": 1, "name": "Giles Glover” }, { "id": 2, "name": "Pennington Shannon" } ], "favoriteFruit": "strawberry" },
Допустим, нас интересуют все «первые» друзья, то есть записи с индексом О в массиве друзей, любимый фрукт у которых клубника. С помощью jq можно сделать следующее:
” jq цля обработки JSON: https: 7jqlang.org/.
94 JSON generator: https://jsor generator com/.
64 | Глава 3. Оболочкк и скрипты
$ jq select(.[].favpriteFrutt=="strawberry") (
.[].fг tends[3].name' example.j son
"Tara Holland"
"Christy Mullins"
"Snider Thornton"
"Jana Clay"
"Wilma King’
Повеселились с командной строкой, не так ли? Если вас заинтересовали современные команды и многообещающие альтернативы, загляните в репозиторий modern-unix95 96. Теперь давайте рассмотрим задачи посложнее с особенностями их выполнения.
Повседневные задачи
Многие задачи приходится выполнять настолько часто, что для них придумали особые способы оптимизации. Давайте перечислим их и посмотрим, как облег чить себе жизнь.
Сокращайте часто используемые команды
Главный принцип взаимодействия с интерфейсами сводится к тому, чтобы команды, которыми вы пользуетесь часто, требовали наименьших усилий для ввода. Применимо к оболочке вместо инструкции gitdiff - -color-moved я набираю d (всего один символ), поскольку просматриваю изменения в своих репозиториях по сотне раз в день. В зависимости от оболочки есть разные способы добиться такого эффекта: в bash это называется псевдонимами (alias95), а в Fish Shell — сокращениями (abbreviations97).
Используйте навигацию
При вводе текста d командной строке вам может понадобиться подвинуть курсор (например, переместить его в начало) или исправить строку (например, удалить все левее курсора). В таблице 3-2 представлен список распространенных комбинаций клавиш для таких действий.
95 Репози горий modern unix: hl tps:/,'github com/ibraheemdev/mocern-unjc.
96 Псевдонимы в shell (alias): hrrps:/,'ss64.com/bash/alias.htiril.
97 Сокращения в FishShell (abbreviations): hitps://fishshell.com/docs/current/cmds/abbr.litml.
Основы | 65
Таблица 3-2. Комбинации клавиш для навигации и редактирования
Действие	Команда	Описание	1
1 ереместить курсор к началу строки	Ctrl + А	-
Переместить курсор к концу строки	Ctrl + E	-
Передвинуть курсор ьа один символ вперед	Ctrl + F	-
Передвинуть курсор из один символ назад	Ctrl + В	-
Передвинуть курсор к следующему слову	Alt + F	Только левый Alt
Передвинуть курсор к предыдущему слову	Alt + B	-
Удалить символ под курсором.	Ctrl + D	
Удали ib символ слева о г курсора	Ctrl + H	-
Удали гь слово слева ст ку рсора	Ctrl+W	-
Удалить все справа от курсора	Ctrl + К	-
Удалить все слева от курсор?	Ctrl + U	-
Очистить экран	Ctrl +1	-
Семенить команду	Ctrl + C	-
Отменить предыдущее действие	Ctrl+_	Только bash
Поиск в истории	Ctrl + R	He все оболочки
Отменить поиск	Ctrl + G	He все оболочки
Обратите внимание, что в оболочках могут не поддерживаться определенные сочетания клавиш, а некоторые действия (вроде управления историей) реализованы по-разному. Также указанные сочетания основаны на схеме клавиш редактирования Emacs. Если вы предпочитаете vi, добавьте set -ovi з файл .bashre и управляйте командной строкой в стиле vi. Опираясь на таблицу, изучите, что умеет ваша оболочка и как настроить ее под себя.
Работа с содержимым файлов
Не всегда хочется запускать редактор вроде vi, чтобы добавить одну строку текс та. А иногда и невозможно — например, при написании скрипта (см. «Сценарии»).
Как же в таком случае манипулировать текстовым содержимым? Давайте по смотрим:
$ ecno "First line" > /tmp/sonething О
$ cat /tmp/something ©
First line
$ echo "Second line" » /tmp/something && \ ©
cat /tmp/something
66 | Глава 3. Оболочки и скрипты
First line
Second line
$ sed 's/line/LINE/' /tmp/sopething First LINE
Second LINE
$ cat « 'EOF' > /tfnp/another © First line
Second line
Third line
EOF
$ diff -y /tnp/soRething /tnp/another Ф First line
First line
Second line
Second line
Third line
О Создать файл, перенаправив вывод echo.
® Просмотреть содержимое файла.
О Добавьте строку с помощью оператора » и просмотреть содержимое.
О Заменить содержимое файла с помощью sed и вывести на stdout.
© Создать файл, используя специальный блок «встроенный документ» (here-document”).
Ф Посмотреть различия между двумя созданными файлами.
От знакомства с основными приемами редактирования файлов перейдем к продвинутым способам их просмотра.
П эосмотр длинных фа илов
Для длинных файлов, строки которых не умещаются на один экран, можно использовать пейджеры, такие как less или bat (в bat эта функция встроена). Программа разбивает вывод на страницы, каждая по размеру экрана, и добавляет некоторые команды для навигации (переход к следующей или предыдущей странице и т. д.)
Еще один способ — отображать только выбранную область файла, напри мер, первые несколько строк. Для этого предназначены две удобные команды — head и tail.
98 Специальный блок heredocument: https://tldp.0rg/IDP/abs/html/here-d0cs.htrr.l.
Основы | 67
Например, вот так можно отобразить начало файла:
$ for i in {1..100}; do echo $i » /tnrp/longfile; done ©
$ head -5 /ti-ip/longfile в
1
2
3
4
5
® Создать длинный файл (здесь 100 строк).
© Отобразить первые пять строк длинного файла.
Показывать свежие данные из файла, который постоянно дописывается, можно таким образом:
$ sudo tail -f /var/log/Xorg.0.log О
[36065.098] (II) eventl4 - ALPS01;00 0911:5283 house: device is a pointer
[36065.900] (II) eventl5 - ALPS61:00 0911:5288 Touchpad: device is a touchpad
[36065.901] (II) event4 - Intel HID events: is tagged by udev as: Keyboard
[36065.901] (II) event4 - Intel HID events: device is a keyboard
О Отобразить окончание лог-файла с помощью tail (опция -f отвечает за отслеживание и автоматическое обновление).
В завершение мы рассмотрим работу с датой и временем.
Работа с датой и временем
Команда date может оказаться полезна при создании уникальных имен для файлов. Опа позволяет генерировать даты в различных форматах, включая временную метку Unix (Unixtimestamp99), и выполняет преобразования между разными форматами даты и времени.
59 Время Unix: https://en.wikipedia.org/wiki/Unix_time.
68 | Глава 3. Обол очки и скрипи >i
$ date +%s О
1629582883
$ date -d @1629742883 '+%n/%d/%Y:%H:%M:%S' в 08/21/2021:21:54:43
О Создать временную метку UNIX.
® Преобразовать временную метку UNIX в понятную человеку дату.
Время эпохи UNIX
Время эпохи UNIX (или просто время UNIX) — это количество секунд, прошедших с 1970-01 -01T00:00:00Z.. Согласно времени UNIX каждый день равен 86400 секунд.
Имея дело с ПО, которое хранит время UNIX в виде 32-битного целого числа со знаком (signed 32-bit integer), вам следует учитывать это, поскольку 19.01.2038 счетчик переполнится, что приведет к проблеме 2038 года100.
Для более сложных операций можно использовать онлайн-конверте-ры101, поддерживающие перевод в микро- и миллисекунды.
На этом мы завершаем знакомство с основами работы в оболочке. Вы узна ли, что такое терминалы и оболочки, и как использовать их для выполнения по вседневных задач — для навигации по файловой системе, поиска файлов и прочих. Перейдем к теме оболочек, удобных для работы человека.
Удобные для работы оболочки
Хотя оболочка bash102, вероятно, по-прежнему самая популярная, она не обязательно самая удобная для работы103. Эта оболочка существует с конца 1980-х годов, и возраст иногда дает о себе знать. Есть целый ряд современных и дружелюбных к человеку альтернатив, которые я настоятельно рекомендую вам опробовать и использовать вместо bash.
Для начала мы подробно рассмотрим конкретный пример современной, удобной для человека оболочки под названием Fish shell, а затем затронем другие,
100 Проблема 2038 года: https://eiL.wikipedia.org/wiki/Year_2038 problem.
101 Онлайн конвертер дат: https://www.epochconvener.com/.
102 Оболочка bash: https.//en.wikipedia.org/wiki/Bash_%28Unix_shell%29.
103 На большинстве встреченных вами удаленных машинах будет bash. (Прим, рей.)
Удоб иые для работы оболочки | 69
чтобы дать вам представление о палитре выбора. Мы завершим раздел краткой рекомендацией и постараемся ответить на вопрос «Какую оболочку мне выбрать?»
Fish Shell
Fish:w описывает себя как умную и дружественную к пользователю оболочку командной строки. Рассмотрим несколько примеров ее использования, а после за тронем настройки.
Основные способы использования
При выполнении многих повседневных задач вы не заметите особых отличий от bash в плане ввода данных; большинство команд, упомянутых в таблице 3-2, поддерживаются и здесь. Однако есть две области, в которых fish выгодно отличается от bash:
Здесь нет явного управления историей.
Начните печатать и тут же получите подсказку ио предыдущим командам.
Можно использовать клавиши вверх и вниз, чтобы выбрать нужный вариант (см. рисунок 3-4).
I—> $ еха j-long --all —git
app.yaml Dockerfile example.json main.go script.sh test
Рисунок 3-4. Работа с историей команд в Fish
-1 -а -А -а -В
-Ь -С -с -d -е
-F -f -G -g -Н -h
-i -k
(List one entry per line) (for -I: Display extended attributes) (Show hidden except . and ,.) (Show hidden entries) (Octal escapes for non-graphic characters) (C escapes for non-graphic characters) (Force multi-column output) (Sort (-t) by modified time and show time (-1)) (List directories, not their content) (for -I: Print ACL associated with file, if present) (Append indicators, dir/ exec* linkS) socket= fifo| whiteoutX) (Unsorted output, enables -a) (Enable colorized output) (Show group instead of owner in long format) (Follow symlink given on commandline) (Human-readable sizes) (Show inode numbers for files) (for -s: Display sizes in kB, not blocks) (Follow all symlinks Cancels -P option)
-l -m уП -° -0 -₽
-p -q -R
-s
-5 -T -t -u -u
-w
-w
-X
(Long listing format) (Comma-separated format, fills across screen) (Long format, numerical UIDs and GIDs) (for -I: Show file flags) (Long format, omit group names) (Don't follow symlinks) (Append directory indicators) (Replace non-graphic characters with '?') (Recursively list subdirectories) (Reverse sort order) (Sort by size) (Show file sizes) (for -I: Show complete date and time) (Sort by modification time, most recent first) (Sort <-t) by creation time and show time (-1)) (Sort (-t) by access time and show time (-1)) (Display whiteouts when scanning directories) (Force raw printing of non-printable characters) (Multi-column output, horizontally listed)
Рисунок 3-5. Автоподсказки в Fish *
104 Оболочка Fish: https://fishshell.com/.
70 | Глава 3 Оболочки и скрипты
Для многих команд доступны автоподсказки.
Это показано на рисунке 3-5. Кроме того, при нажатии Tab оболочка Fish попытается угадать команду, аргумент или путь, предлагая вам визуальные подсказки (например, окрашивая ввод в красный), если распознала команду.
В таблице 3-3 перечислены некоторые из основных команд fish. Обратите внимание, как обрабатываются переменные окружения.
Таблица 3-3. Справочник по оболочке Fish
Задача	Команда
Зксг ортировзть переменную окружения KEY со значением VAL	set-xKEYVAL
Удалить переменную окружен ия KEY	set-е KEY
Зада ib переменную окружения KFY для команды cmd «на лету»	envKEY=VALcmd
Изменить длину пути на 1	set -g fish .prompt _pwd_ dir_length 1
Управлять сокращениям н	abbr
Управлять функциями	Functions и fined
В отличие от других оболочек, fish хранит статус завершения последней ко манды в переменной Sstatus, а не в $?.
Если вы переходите с bash, то вам может пригодиться раздел часто задаваемых вопросов Fish105, где уже естп ответы на большинство вопросов.
Настройка
Чтобы настроить оболочку Fish106, просто введите команду fish_config (в зависимости от дистрибутива, возможно, понадобится добавить подкоманду browse), fish запустит сервер по адресу http://localhost:8000 и автоматически откроет в вашем привычном браузере привлекательный пользовательский интерфейс, показанный на рисунке 3-6, в котором можно просмотреть и изменить настройки.
Чтобы переключить привязки клавиш со стиля vi на Emacs (по умолчанию), используйте fish_vi_key_bindings для запуска режима vi или fish_defauit_key_bindings для сброса его обратно в Emacs Изменения вступят в силу немедленно и во всех активных сеансах
105 FishShell: часто задаваемые вопросы: https://fislishell.coiri/docs/current/iaq.html.
106 Конфигурация FishShell: https //fishshell.com/docs/cuk rent/incex.html#cor.flguration.
Удобные для работы оболочки | 71
Рисунок 3-6. Настройка оболочки Fish в браузере
Давайте посмотрим, как я настроил свою среду. Мой config.fish довольно короткий:
set -х FZF_DEFAULT_OPTS "-m --bind='ctrl-o; execute(nvim {})+abort'"
set -x FZF_DEFAULT_COMMAND 'rg --files'
set -x EDITOR nvin
set -x KUBE_E?ITOR nvim
set -ge fish_user_paths /usr/local/bin
Настройка подсказок в fish_prompt.fish выглядит следующим образом:
function fish.pronpt set -I retc red test $status = 0; and set retc blue
set -q ___fish_git_prompt_showi,pstrean
or set g ____ftsh_git_prcnpt_showupstrearf auto
function _nin_pronpt_wrapper
set retc $argv[l]
set field_name $aigv[2]
set field_value $argv[3]
72 |	Гпава 3. Обо; очки и <криi пы
set.color normal set_cclor $retc echo -n
set_color -o blue echo n '[' set_color normal test -n $field„name
and echo -n $field_name;
set_color $retc
echo -n $field„value set_color -o blue echo -n ']'
end
set_color $ietc
echo -n '7—'
set_color -0 blue
echo -n [
set_color normal
set_color С07933
echo -n (prompt_pwd)
set_color -o blue
echo -n ']'
#	Virtual Environment
set -q VIRTUAL_ENV_DISABLE_PROMPT
or set -g VIR~UAL_ENV_DISABLE_PROMPr true
set -q VIRTUAL_ENV
and _nim_prompt„wrapper $retc V (basename "$VIRTUAL_ENV")
#	git
set prompt_git (fish_git_pronpt | string trim -c ' ()’)
test -n "$pror4pt_git"
and _nim_prompt_wrapper $retc G $prompt_git
#	Neu line
echo
#	Background Jobs
set_color normal
Удобные для работы оболочки | 73
fur job tn (jobs) set_color $retc echo -n '| 1 set„color brown echo $job
end
blue
echo -n ' ^-> 1
set_color • о blue echo n '$ ' set_<.olor normal
end
Результат показан на рисунке 3-7. Обратите внимание на разницу между каталогом, содержащим репозиторий Git, и тем, который его не содержит, визуальная подсказка повышает удобство работы. Также обратите внимание на текущее время с правой стороны.
т-Ы
L-? $ cd tmp
T-[~/tmp]-[G:master]
Ц> $ |	14:09: !
Рисунок 3-7. Подсказки в Fish
Настройки для сокращений (воспринимайте их как замену псевдонимам, которые используются в других оболочках) выглядят так:
$ abbr
abbr -a -U -- :q exit
abbr -a U cat bat
abbr -a -U -• d 'git diff --color-moved1
abbr -a -U -- g git
abbr -a -U -- grep 'greo --color=auto' abbr -a и -- k kubectl
abbr a U -- I 'exa --long --all -git'
abbr -a -U -- ll 'Is -GAhltr'
abbr -a -U -- m make
abbr -a -I) -- p 'git push'
abbr -a -U -- pu git puli'
74 | Глава). Оболочки и скрипты
abbr a -U s 'git status' abbr -a -U -- stat 'stat -x' abbr -a -U -- vi nvin
abbr -a -U -- wyet 'wget -c'
Новые сокращения добавляются командой abbr --add Сокращения удобны для простых команд, не требующих аргументов. Но что, если вы хотите сократить более сложную конструкцию? Допустим, последовательность, включающую вызов git, для которой тоже требуются аргументы. Знакомьтесь с функциями Fish.
Рассмотрим пример функции из файла с. fish. Команду functions мы можем использовать для получения списка всех определенных функций, function — для создания новой, a f unctionc — для редактирования имеющейся:
function с
git add -аП
git commit -m "$argv" end
На этом мы заканчиваем раздел, в котором вы научились работать с оболочкой Fish и получили советы по ее настройке Кратко затронем и другие совре мепные оболочки.
Z-shell
Z-shell107, или zsh, — это оболочка классического Bourne-shell типа с мощной системой аьтозавершения108 * и богатой поддержкой тем. С пакетом «Oh Му Zsh»10’ вы сможете детально настроить zsh, и пользоваться им так же, как fish, сохраняя широкую обратную совместимость с bash.
zsh использует пять файлов запуска, показанных ниже (обратите внимание, что если SZDOTDIR не задан, zsh использует $НОНЕ):
$ZDOTDIR/.zshenv О
$ZDCTDIR/.zprofile ©
$ZDOTDIR/.zshrc ©
107 Z-Shell: https://zsh.sourceforge.io/Doc/.
108 Автозавершекие в Z-SheL: http://bewatermyfriend.Org/p/2012/003/.
1М Oh Му Zsh: https://ohmyz.sh/.
Удобные для реботы оболочки | 75
$ZQOTDIR/.zlogin О
$ZDOTDIR/.zlogout ©
О Подключается при всех вызовах оболочки. Должен содержать команды для установки пути поиска и других пажных переменных окружения. Не может содержать команд, которые производят вывод или предполагают, что оболочка подключена к tty.
® Предлагается как альтернатива zlogin для поклонников ksh (эти два файла не предназначены для совместного использования). Похож на .zlogih, толь ко подключается до .zshrc.
© Подключается в интерактивных оболочках. Должен содержать команды для настройки псевдонимов, функций, опций, сочетаний клавиш и прочего.
О Подключается в оболочках входа. Должен содержать команды, предназначенные только для оболочек входа. Обратите внимание, что .zlogtn — неправильное место для определения псевдонимов, опций, настроек переменных окружения и прочего.
© Подключается при выходе из оболочек входа.
Много плагинов для zsh можно найти в репозитории awesome zsh-plugins110 на GitHub. Если вы хотите освоить zsh, изучите монографию «Введение в Z Shell»111 112 Пола Фалье гада и Баса де Баккера.
Другие современные оболочки
Помимо fish и zsh, существует ряд других интересных, но не всегда совместимых с bash оболочек. Когда будете изучать их, обращайте внимание на основ • ную направленность (интерактивное или сценарное использование оболочки) и на активность сообщества вокруг них.
Вот несколько современных оболочек для Linux, с которыми я имел дело, и готов порекомендовать к ознакомлению:
Oil shell1’2
Нацеливается на любителей Python и JavaScript. Сосредоточена на сценарном использовании, а не на интерактивном.
110 Репозиторий плагинов Z Shell; https://github.com/unixorn/av-eseme-zsh-plugins.
111 <-An Introduction to the Z Shell» by Paul Falstad and Bas de Baxker: https;//www.ee.torontornu. ca/guides/zsh intro pdf.
112 Оболочка Oilshel": https://www.oitshell.org/.
76 | Глава 3. Оболочки и скрипты
miirex113
POSlX-обо.ючка с интересными функционалом, встроенной средой тестирования, типизированными конвейерами и событийно-ориентированным программированием.
Nushell"4
Новаторская экспериментальная парадигма оболочки с табличным выводом и мощным языком запросов. Узнайте больше в подробной документации Nu Book115 116.
PowerShell1'6
Кроссплатформенная оболочка (изначально ответвление WindowsPowerShell), которая предлагает отличный от POSIX-оболочек набор семантики и взаимодействий.
Есть множество и других вариантов; ищите и выбирайте лучшее. Попробуйте выйти за рамки bash и оптимизировать его под себя.
Какую оболочку выбрать?
На сегодня любая современная оболочка, кроме bash, кажется хорошим выбором с точки зрения удобства. Ненавязчивое аьтозаполнение, простая настройка и интеллектуальные среды — не роскошь в 2022 году. Учитывая количество времени, которое вы проводите з командной строке, вам следует испробовать разные оболочки и выбрать ту, которая вам по душе. Лично я использую Pish, но многие мои коллеги очень хвалят Z-shell.
У вас могут возникнуть затруднения, из-за которых трудно решиться на отказ от bash:
— Вы работаете удаленно и/или не можете уста новить собстве! шую оболоч ку.
— Вы остаетесь с bash из-за совместимости и/или мышечной памяти. От некоторых привычек трудно избавиться.
— Почти вся документация (хоть и неявно) предполагает bash. Например, вы встречаете инструкции вроде exportFOO=BAR, которые специфичны для bash
113 Оболочка murex:https://rnurex.rocks/.
Оболочка Nushell: https://wwwnushell.sh/.
115 Документация NushelL htrps7/www.nusbeil.sh/book/.
116 Оболочка PowerShell- https://github.com/powersheil/powersheLl.
Удобные для работы оболочки | 77
Если приглядеться, эти проблемы не так уж и актуальны для большинства пользователей. Возмож1 то, вам и придется иногда использовать bash в удаленной системе, ко большую часть времени вы проводите в средах, которые полностью под вашим контролем. Да, порог вхождения придется преодолеть, но оно того стоит.
А теперь давайте сосредоточимся на другом способе повышения производительности в терминале — мультиплексоре.
Терминальный мультиплексор
Мы познакомились с терминалами в самом начале этой главы в разделе «Тер-миналы». Теперь рассмотрим, как повысить производительность вашего терми нала, опираясь на простую и эффективную концепцию мультиплексирования.
Думайте об этом так: большинство ваших задач поддается группировке. Вы можете работать нац проектом с открытым исходным кодом, писать блог или документацию, удаленно подключаться к серверу и тестировать HTTP API. Для каждой задачи может потребоваться одно или несколько окон терминала, а иногда вам нужно выполнять потенциально зависимые задачи в двух окнах одновременно. Вот вам примеры:
—	Вы задействуете команду watch для наблюдения за списком файлов с периодическим обновлением и параллельно редактируете файл.
—	Вы запускаете серверный процесс (веб-сервер или сервер приложений) и хотите, чтобы он работал на переднем плане (см. также «Управление за даниями»), чтобы приглядывать за логами.
—	Вы хотите редактировать файл с помощью vi и одновременно использовать git для запроса статуса и фиксации изменений.
—	У вас есть виртуальная машина, запушенная в облаке, и вы хотите подключиться к ней по ssh, сохранив возможность работать с файлами локально.
Посмотрите на эти примеры как на логически, связанные, которые могут выполняться быстро (за несколько минут) или на длительном отрезке времени (дни и недели). Группировка подобных задач обычно называется сессией.
Итак, если вы собрались сгруппировать задачи, потребуется найти ряд ответов:
—	Зам требуется несколько окон. Одно из решений — запустить несколько терминалов или экземпляров (вкладок), если позволяет пользовательский интерфейс.
78 | Глава 3. Оболочки и скрипты
—	Лучше держать эти окна и настроенные пути под рукой, даже если вы закроете терминал или пропадет соединение с удаленной стороной
—	Вы хотите разворачивать окна или менять масштаб, сосредоточиваясь на отдельных задачах, но не теряя обзора всех сеансов и возможности перемещаться между ними.
При решении этих проблем в чьей то светлой голове возникла идея наложить на терминал несколько окон (и сеансов, чтобы группировать окна) — иными словами, мультиплексировать I/O терминала.
Кратко рассмотрим исходную реализацию терминального мультиплексирования — screen, подробно изучим самую популярную — tnux, а закончим обзором других предложений.
screen
screen117 — это изначальный терминальный мультиплексор, которым пользуются до сих пор Но если вы не в удаленной среде, где есть только screen и нет возможности установить другой мультиплексор, то вам, вероятно, не захочется его использо вать. Его перестали активно развивать, он не очень гибкий, и в нем отсутствует ряд функций, которые есть у современных терминальных мультиплексоров.
tmux
tmux118 — это гибкий мультиплексор терминалов с богатым функционалом, который легко настроить под свои нужды. Как видно из рисунка 3- 8 (от большото к малому), в tmux вам предстоит взаимодействовать с тремя основными элементами.
Сеансы
Логическая единица, которую можно рассматривать как рабочую среду, предназначенную дня отдельно взятой задачи, например, «работа над проектом А» или «написание статьи для блога Б». Это общий контейнер для всех остальных единиц.
Окна
Думайте об окнах как о вкладке в браузере, принадлежащей сеансу. Их использование необязательно, и зачастую у вас есть только одно окно на сеанс.
117 Мультиплексор терминалов screen: https://www.gnii.org/software/screenz.
1;“ Мультиплексор терминалов tmux: https://github.ccm/tmux/tmux.
Терминальный мультиплексор | 79
Панели
Это ваши рабочие лошадки, фактически один запущенный экземпляр оболочки. Панель — часть окна, и ее легко можно делить на несколько по вертикали или горизонтали, сворачивать или разворачивать (то есть масштабиро вать), а также закрыть открытые панели по мере необходимости.
Рисунок 3 8. Элементы tnux: сеансы, окна и панели
Как и в screen, в tnux вы можете прикреплять и от соединять сеанс. Предположим, что мы начинаем с нуля. Давайте запустим tnux с сеансом, который называется test:
$ tnux new -s test
Теперь tnux работает как сервер, а вы оказываетесь в настроенной для tiwx оболочке, подключенной как клиент. Клиент-серверная модель позволяет вам создавать, входить, выходить и уничтожать сеансы, а также использовать обе дочки, запущенные внутри tnux, не заботясь о выполняющихся (или аварийно завершающихся) в них процессах.
Сочетание клавиш Ctrl + В (по умолчанию) в tnux называется префиксом или триггером. Чтобы вывести список всех окон, нужно нажать Ctrl + В, а затем W. Чтобы развернуть текущую (активную) панель, нужно нажать Ctrl + В, а затем Z.
—Ctrl + В в tnux — это триггер, настроенный по умолчанию. В стремлении облет чить себе жизнь я переназначил триггер на неиспользуемую кнопку, чтобы хватало одного нажатия. Я задал кла вишу Ноше в tnux, а затем соединил ее с кл авишей CapsLock, изменив привязку в /usr/sbure/Xll/xkb/synbols/pc key<CADS> {[Hone]};.
80 | Piaua З.Обогочки и скрипты
Я был вынужден совершить этот обходной маневр с двойным сопоставлением, но вам, в зависимости от выбранной клавиши или терминала, возможно, и не придется. В любом случае я рекомендую вам сопоставить Ctrl + В с неиспользуемой клавишей, до которой вы легко дотянетесь, потому что нажимать ее вам придется по сотне раз в день.
Теперь вы можете опробовать любую из команд, перечисленных в таблице 3-4, для управления сеансами, окнами и панелями. Кроме того, при нажатии Ctrl + В + D вы сможете отсоединить сеансы. При этом trnux фактически перейдет в фоновый режим.
Если затем запустить новый экземпляр терминала или, скажем, подключиться по ssh к своей машине из удаленного места, можно присоединиться к имеющемся сеансу. Давайте подключимся к сеансу test, который мы создали ранее:
$ tmux attach -t test О
О Присоединиться к существующему сеансу с название м test. Заметьте, что от -соединить сеанс от его предыдущего терминала можно, указав параметр d.
В таблице 3-4 перечислены основные команды tmux, сгруппированные по обсужденным единицам, от самой широкой области действия (сеанс) до самой узкой (панель).
Таблица 3-4 Команды tmux
Область	Задача	Команда
Сеанс	Создать новь й	: new -s КАМЕ
Сеанс	Переименовать	трипер 3- $
Сеанс	Вывести список	триггер + s
Сеанс	Закрыть	триггер
Окнг	Создать новое	триггер + с
Окно	Переименовать	триггер +,
Окне	Перектючиться на	триггер +1... 9
Окно	Вывести список	триггер + w
Окно	Закрыть	триггер+ &
Панель	Разделить по горизонтали	триггер +"
Панель	Разделить по вертикали	триггер + %
Панель	Переключить	триггер + z
Панель	Закрыть	триггер+х
Герминальный мультиплексор | 81
Мы научились работать с tmux; теперь разберемся, как настроить ею под личные предпочтения. Вот как выглядит мой .tmux.conf:
Unbind C-b О
set -gprefixHome bind Homo send-prefix bind г source-file -/.tmux.conf \; display "tmux config reloadec:)" в bind \\ split-window -h -c "#{pane_current_patli}" ® bind -- split -window -v -c "#{pare_current_path}” bina X confirm-before kill-session в set -s escape-time 1 © set-option -g mouse on Ф
set -g default-terminal "screen-256color" В set-option -g status-position top © set -g status-bg rolourl03 set -g status-fg colour215 set -g status right length 120 set -g status-left-length 50
set -g window-status-style fg=colour215
set -g pane-active-burder-stylefg=colour215
set -g (dplogin 'tmux-pljgins/tmux-resurrect' Ф
set -g @plugin 'tmux plugins/tmux continuum' set -g Qcontinuum-restore 'on' run '-/.tmux/plugins/tpm/tpm'
6 Эта и следующие две строки переназначают триггер на Ноте.
® Перезагрузка настроек через trigger + г.
Ф В этой и следующей строке переопределяется разделение панелей с сохранением каталога текущей панели.
О Добавление ярлыков для создания и завершения сеансов.
© Ьез задержек.
Ф Включить выбор мышью.
9 Установить для терминала 256-цветный режим но умолчанию.
© Настройка темы (следующие шесть строк).
Ф С этой строки и до конца: подключение расширений.
Сначала установите tpm — менеджер расширений tmux, затем нажмите trigger + I для отображени я всех расширений. Я использовал такие:
82 |	Глава 1. Обшгочки и скриптн
tmux-ressurect119
Позволяет восстанавливать сеансы с помощью Ctrl + S (сохранить) и Ctrl + R (восстановить).
tmux-continuum120 121
Автоматически сохраняет/восстанавливает сеанс (с интервалом в 15 минут).
На рисунке 3-9 показан мой терминал Alacrilty с запущенным tmux. В левом верхнем углу ьы видите сеансы с ярлыками от 0 до 9.
(0) + zzz: 1 windows
(1)	+ _home: 1 windows
(2)	+ cortex: 2 windows
(3)	+ launches: 2 windows
(4)	+ olly-apps: 4 windows
(5)	+ olly-recipes: 2 windows
(6)	+ potty: 1 windows
(7)	+ prometheus: 1 windows
'&) « sandbox: 2 windows (attachpd)
(9j + rlLIiig: 3 windows
Рисунок 3-9. Пример экземпляра tmux в действии, показывающий доступные сеансы
tmux, безусловно, отличный выбор, но помимо него есть и другие мультиплексоры.
Другие мультиплексоры
Предлагаю вашему вниманию следующие терминальные мультиплексоры.
tmuxinator'21
Мета-инсгрумепт, позволяющий гибко управлять сессиями Imux.
115 Расширение tmux-ressurect: https://github.com/tmux-plugins/tmux-resurrect.
120 Расширение tmux continuum: https:,7github.com/tmux-plugins/tmuA-continuum.
121 Мультиплескср терминалов tmuxinator. https://github.ccm/tmuxinator/tmwanator.
Терминальный мультиплексор | 83
Byobu'22
Обертка над screen или tnux. Особо заинтерес уст тех, кто использует дистрибутивы Linux на базе Ubuntu или Debian.
Zellij122 123
Позиционирует себя герминальным рабочим пространством, написан на Rust и по функционалу превосходит tnux, предлагая движок компоновки и мощную систему плагинов.
dvtm124
Привносит в терминал концепцию управления окнами в виде плиток. Мощный инструмент, но с высоким порогом вхождения, как и tnux,
Зтих125
Простой терминальный мультиплексор, написанный на Go. Легко использо вать, но он уступает tnux.
После краткого обзора давайте поговорим о выборе.
СОБИРАЕМ ВСЕ ВМЕСТЕ: ТЕРМИНАЛ,TMUX И ОБОЛОЧКУ
В качестве терминала я использую Alacritty. Он быстрый, и что самое замечательное, настраивается через YAML, который я могу поместить в Git, и разворачивать терминал на любой целевой системе за считаныс секунды. В файле alacritty .ynl определены все мои личные настройки, от цветов до привязок клавиш и размера шрифтов.
Большинство параметров применяются сразу (hot-reload), остальные — после сохранения файла. Параметр shell определяет интеграцию терминального мультиплексора (у меня tnux) и оболочки (у меня fish):
shell:
program: /usr/locai/bin/fish
args:
-	-I
122 Мультиплескор терминалов Byobu: https://www.byobu.org/.
123 Мультиплексор терминалов Zelij: https://zellij.dcv/3b0ut/.
124 Мультиплексор терминалов dvtm: https7/gitrvb com/"nartanne/dvtm
125 Мультиплексор терминалов 3mux: https://github.com/aaronjanse/3mux.
84 I Глава 3. Оболочки и скрипты
	i
с
-	"tmux new-session -A -s zzz"
В приведенном фрагменте Alacrilty настроен на использование оболочки fish как стандартной, но при запуске терминал автоматически восстанавливает указанный мной сеанс. Вместе с плагином tnux-continuu"! это дарит мне душевное спокойствие. Даже после внезапной перезагрузки компьютера я найду терминал со всеми сеансами, окнами и панелями (почти) в том же состоянии, что и до сбоя. Пропадут разве что локальные переменные.
Какой мультиплексор выбрать?
В отличие от выбора оболочек, для мультиплексора у меня есть однозначная рекомендация — tnux. Причин множество; он проверенный, стабильный, многофункциональный (с богатым выбором плагинов) и гибкий. Он популярен, поэтому вы без труда найдете и полезные советы, и помощь. Другие мультиплексоры тоже интересны, но пока слишком молоды или же, как screen, безнадежно устарели.
Надеюсь, я соблазнил вас использовать терминальный мультиплексор, чтобы работа с терминалом и оболочкой была удобной, выполнение задач — продуктивным, а удовольствие от процесса — максимальным. Пора перейти к последней теме этой главы — автоматизации задач с помощью сценариев.
Сценарии
В предыдущих разделах мы рассуждали о ручном (или интерактивном) использовании оболочки. Если к одной задаче вы возвращаетесь снова и снова, то са мое время задуматься о ее автоматизации. Здесь на помощь приходят сценарии.
Мы будем писать скрипты на языке bash, и для этого есть две причины:
— Сегодня большинство скриптов написаны на bash, поэтому вы легко найдете множество примеров и полезную информацию.
— Из-за того, что вероятность обнаружить bash в любой целевой системе достаточно высока, с позиции клис-нтоориентированности выгоднее использовать его, чем любую другую, пусть мощную, но экзотическую или непопулярную альтернативу.
Сценария | 85
Дня справки: скрипты могут содержать до нескольких тысяч строк кода126. Я не призываю вас стремиться к этому, наоборот, если ваш скрипт разрастается, спросите себя, не лучше ли выбрать другой язык, скажем, Python или Ruby?
Отступим от темы и разработаем короткий, но полезный пример. Представим, что вы автоматизируете задачу по выводу ка экран строки с годом регистрации и полным именем пользователя, полученным из GitHub API, примерно в таком формате:
ХХХХ ХХХХХ joined GitHub in YYYY
Как автоматизировать такую задачу с помощью сценария? Мы начнем с азов, затронем понятие переносимости и закончим «бизпес-логикой» нашего сценария.
Азы написания сценариев
Могу вас обрадовать: интерактивно используя оболочку, вы познакомились с большинством необходимых терминов и подходов. В дополнение к переменным, перенаправлению потоков и основным командам оболочки вам придется освоить всего несколько навыков.
Расширенные типы данных
Хотя оболочки интерпретируют любые данные, как строки (а значит, использовать скрипты для сложных числовых вычислений — не лучшая идея), они все же поддерживают некоторые расширенные типы данных — например, массивы
Рассмотрим массив на примере:
os=('Linux' 'macOS' 'Windows') О
echo "${os[e]}" ®
nunberofos="${#os[g]}" Ф
О Определяем массив из трех элементов.
8 Выводим первый элемент (в нашем случае это Linux).
® Получаем длину массива, в результате чего nunberofos становится равен 3.
126 Самые длинные shell-скрипты в мире: https://github.com/oils-for-unix/oils/wiki/ lhe Biggest -Shell-Programs- in-the-World.
86 | Глава 3. ООолочкк и скриггы
Контроль потока передачи данных
Контроль потека позволяет разветвлять (if) или зацикливать (for и while) вы поименно скрипта в зависимости от условий.
Вот несколько примеров использования:
for afile in /trip/’; de О echo "$afile"
done
for i in {1..10-; de © echo "$i"
done
while true; do
done ©
О Обычный цикл, который перебирает файлы каталога и выводит имя каждого файла.
© Цикл в заданном диапазоне.
© Бесконечный цикл; прервать его можно с помощью Ctrl + С.
Функции
Функции позволяют писать более модульные и универсальные скрипты. Функцию необходимо определить до ее использования; оболочка интерпретирует скрипт сверху вниз.
Пример простой функции:
sayhi() { О
echo " Лривет$1, надеюсь у тебя все хорошо!"
}
sayhi " 1*айкл" ©
О Определение функции с неявной передачей параметров $п.
О Вызов функции. Результат. «Привет, Майкл, надеюсь, у тебя все хорошо!»
Сценарии | 87
Расширенный ввод/вывод
С помощью read вы можете прочитать пользовательский ввод из stdin прямо во время исполнения — например, из меню с несколькими вариантами. Кроме гою, вместо echo я предлагаю вам присмотреться к printf: он позволяет лучше контролировать формат вывода, включая цвета, и более переносим.
Вот пример расширенного ввода/вывода:
read папе О
printf "hello Xs" "$папе" ®
О Читаем значение, которое ввел пользователь.
® Выводим прочитанное значение на экран.
Вам доступны и более сложные концепции, например, сигналы и trap127. Учи тывая, что здесь только общий обзор и введение в тему написания скриптов, о г сылаю вас к замечательной шпаргалке bash Scripting Cheatsheet128 для всестороннего изучения возможных конструкций. Если вы серьезно настроены научиться писать скрипты, рекомендую вам книгу bash Cookbook129 с массой отличных при меров. Используйте их в качестве отправной точки.
Написание переносимых скриптов на bash
Теперь научимся писать переносимые скрипты в bash, Но погодите. Что кроется за словом «переносимые» и почему это должно нас так волновать?
В начале раздела «Оболочки» мы разъяснили понятие POSIX, так что будем отталкиваться от него. Под словом «переносимые» я подразумеваю, что не нужно забивать голову тем, в какой среде будет выполняться скрипт. Если он переносимый, то его можно запустить во мнших системах (оболочках, дистрибутивах Linux).
Но не забывайте, что даже при явном указании типа ободочки (в нашем слу чае bash), код не всегда будет отрабатывать одинаково в разных ее версиях. Все сводится к количеству сред, где вы можете протестировать скрипт.
127 bash: сигналы и ловушки: https://Lnuxcoafig.org/hoW' to modify scripts oehavior-on-signals-using-bash-traps.
128 Подсказки по сценариям и bash: https://devhints.io/bash.
125 «bash Cookoook» by Carl Albing, JP Vossen, Cameron Newham, (O’Reilly Media, Inc.), 2007: https://www.oreillycom/libraryMew/bash cookbook/059652S784/.
88 | Глава 3. Оболочки и скрипты
Запуск переносимых скриптов
Скрипты — это обычные текстовые файлы, которым даже расширение присваивать не обязательно, хотя и принято добавлять .sh. Одна ко, чтобы скрипт запу стился в оболочке, нужно выполнить два непременных условия.
В первой строке необходимо объявить интерпретатор, используя конструкцию, которая называется she-bang130 (или hashbang), и записывается как #! (см. первую строку приведенного ниже шаблона).
Необходимо назначить скрипт исполняемым либо через chnod +х, что разрешит запускать его всем, либо через chrrod 7S0. Это лучше соответствует принципу наименьших привилегий, поскольку запускать его смогут только связан ные с ним пользователь и труппа. Мы подробнее рассмотрим эту тему в главе 4.
Теперь создадим шаблон, который можно использовать как отправную точку.
Универсальный шаблон
Простейший шаблон для написания переносимых bash-скриптов выглядит так:
#!/usr/bin/env bash О set -о errexit О set о nounset ® set -о pipefail О
firstargunent="${l:-somedefauLtvalue}" ®
echo "$firstargument"
О hashbang131 сообщает загрузчику, что для интерпретации этого скрипта будет использоваться bash.
в Указываем, что в случае ошибки выполнение скрипта должно остановиться.
© Указываем, что неустановленные переменные должны считаться ошибкой (чтобы снизить вероятность «тихого» отказа скрипта).
О Указываем, что ошибку в любой части конвейера следует считать ошибкой всего конвейера. Это также помогает избежать «тихого» отказа.
© Пример параметра из командной строки со заданным значением по умолчанию.
Далее мы воспользуемся этим шаблоном, когда будем реализовывать наш информационный скрипт для GitHub.
:м she-bang (hashbarg); https://linuxize.com/post/bash-shebang/.
131 hashbang: https://en.wikipedia.org/ wiki/Shebang_(Unix).
Сценарии | 89
Полезные советы
Я назвал эти советы полезными, а не лучшими, реализация вашей задумки всегда зависит от ситуации и того, насколько далеко вы хотите зайти. Одно дело — писать скрипт для себя, и совсем другое — для тысяч пользователей сообщест ва. В общем случае оптимальные практики выглядят так:
«Падайте» быстро и громко
Избегайте «тихих» отказов, а при ошибке сразу же прерывайте исполнение. К вашим услугам такие инструменты, как pipefail и errexit. По умолчанию bash склонен к «тихим» отказам, поэтому немедленное завершение с инфор мированием об ошибке всегда полезно.
Соблюдайте конфиденциальность
Не записывайте в скрипт никаких конфиденциальных данных вроде паролей. Такая информация должна поступать извне — через ввод от пользователя или через вызов API. Кроме того, учтите, что ps легко раскроет аргументы программы и другую информацию, которая может стать причиной утечки.
Проверяйте входные данные
Всегда, когда это возможно, задавайте или предоставляйте разумные значе ния по умолчанию для любых переменных, и проверяйте данные, полученные от пользователей иди из других источников. Например, предоставленное заранее или запрошенное через read значение избавит вас от ситуации, в которой невинно выглядящая команда гп -rf "$PROJECThOME/" сотрет все на вашем диске просто потому, что переменная не была задана.
Проверяйте зависимости
Не полагайтесь на доступность инструмента или команды, за исключением случаев, когда они стандартны или вы пишете скрипт для заранее известной среды. То, что сиг! установлен на вашей машине, не значит, что он устапов лен везде. Предусмотрите варианты обхода — например, использование wget при недоступности curl.
Обрабатывайте ошибки
Когда ваш скрипт откажет (и вопрос не «если», а «где и когда»), предоставьте пользователям понятные инструкции. Вместо Ошибка 123 сообщите, что привело к сбою и как вашему пользователю исправить ситуацию, например: не удалось записать в /project/xyz/, похоже, доступ только для чтения.
9'J | Глава 3. Оболочки и скрипты
Документируйте
Снабдите основные блоки скрипта комментариями о том, что они делают (# Комментарий начинается с решетки), и старайтесь придерживаться ширины в 80 столбцов для удобства чтения и сравнения.
Версионируйте
Рассмотрите возможность добавить скрипт в систему контроля версий Git.
Тестируйте
Автоматизируйте анализ ваших скриптов, заботьтесь об их читаемости, тестируйте их. Это крайне важная практика, на которой мы остановимся подробнее.
Давайте повысим надежность и безопасность наших скриптов, анализируя их при разработке и тестируя перед распространением.
Анализ и тестирование скриптов
В процессе разработки вы наверняка захотите проанализировать свой скрипт па предмет ошибок в написании команд и вызовах инструкций. Отличный спо  соб — использовать программу SheLlCheck132 (показана на рисунке 3-10), доступную как для скачивания и локального использования, так и в онлайн-варианте на сайте shellcheck.net133. Можно отформатировать код утилитой shfmt134. Она автоматически исправит те ошибки, которые позже нашла бы sheHcheck.
Перед загрузкой вашего скрипта в репозиторий, протестируйте его с помощью bats135 (сокращение от BashAutofiatecIestingSystern — автоматизированная система тестирования для bash). Утилита позволяет создавать bash-скрипты со специальным синтаксисом, предназначенным для тестирования различных ситуаций. Каждая ситуация описана простой bash-функцией с комментарием, а запуск тестов обычно встраивается в процесс CI — например, в качестве реакции на событие в GitHub.
Ну а теперь применим оптимальные практики для написания, анализа и тестирования скрипта, который мы задумали в начале раздела.
132 Тестирование скриптов ShellCheck: https://blog.davidjeddy.com,'2018/1 l/27/using-shelkheck-to-lint-your- bash- sh-scripts/.
133 Онлайн-вариант инструмента SheilChcck: https://www.shellcheck.net/.
134 Ути71ита shfmt: https://github.com/mvdan/sh.
135 Bash Automated Testing System — bats: https://github.com/sstepherson/bats.
Сценарии | 91
ShellCheck
finds bugs in your shell scripts.
You can c«b*i, apt, dnf, pkg or br*w install it locally right now.
Paste a script to try it out
b	Your Editor (Ace)	T ▲
Load 1 2 3 4 5 6 7 1 8
random example
«Т/usr/bin/env bash
set -o errexit set -o errtrace set -o nounset set -o pipefail
echo You ore using the $SHELL shell.
*	ShellCheck Output
$ sheliahftfrk tnyscript
 oho You use using the SSHELI. shell.
*	— S£^.ft2£: Double quote to prevent globbing and word splitting.
Old you mean:	.-.ш, »я>:у лХ.
echo Yon are using the "SSHELL" shell.
ShellCheck is...
•	GPLv3: free as in freedom
•	available on GitHub (as Is this website)
•	already packaged for your distro or package manager
•	supported as an integrated linter in major editors
•	available in CodeClimate, Codacy and CodeFactor to auto-check your GitHub repo
•	written in Haskell, if you're into that sort of thing.
Рисунок 3-10. Оыгайн-утилита ShellCheck в работе
От начала до конца. Скрипт для вывода информации о пользователе GitHub
В этом комплексном примере мы объединяем все упомянутые советы и инструменты для реализации скрипта, который принимает идентификатор пользовате ля и выводит информацию с полным именем и годом его появления на GitHub.
Вот так выглядит программа, в которой учтены все лучшие практики. Сохраните ее в файл с именем gh-user info.sh и сделайте его исполняемым:
#!/usr/btn/env bash
set  errexit
set c errtrace
92 | Глава 3. Оболочки и скрипты
set -о nounset
set -о pipefail
ft#» Command line parameter: targetuser='${1: rchausenblas}" О
### Check if our dependencies are met: if! [-x "$(ccrmand -v jq)"] then
echo'jq че установлен">&2 exitl
fi
### Main:
githubapi="https://арх.github.con/users/" trnpuserdunp="/tmp/ghuserdump_$targetuser- json"
result=$(curl -s $gitl>uDapi$targetuser) ® echo $result > $twDuserdunp
name-$(jq .nane $trtpuserdump r) ®
created_at-$(jq .created„at $tmpuserdump -r)
joinyear=$(echo$created_at| cut -fl -d"-") ® echo Snare подключился к CitHub в $joir.year Ф
О Предусматриваем значение по умолчанию, если не передано ожидаемое.
® С помощью curl скачиваем из GitHub API информацию о пользователе в виде JSON-файла, который сохраняем во временный файл (следующая строка).
Ф Используя jq, вытаскиваем нужные моля. Учтите, что дата в моле created_at выглядит примерно так: 2009-£!2-O7T16:07:32Z.
© Используя cut, извлекаем год из поля created_at в JSON-файле.
Ф Формируем сообщение и выводим его на экран.
Запустим скрипт со значением по умолчанию (не передавая своего):
$ ./gh user -info.sh
Michael Hausenbias joired CitHub in 2009
Сценарии | 93
Поздравляю, вы вооружены всеми необходимыми навыками для использования оболочки в интерактивном режиме с командной строкой и через скрипты. Перед тем как мы закончим, поразмышляйте над несколькими вопросами, связанными со скриптом gh-user-i.nfo.sh;
— Что будет, если GitHub API вернет не JSON? Или вообще ничего не вер нет, и мы получим ошибку HTTP 500? Возможно, сообщение «Попробуйте позже» окажется полезным для пользователя, даже если он ничего не в силах исправить самостоятельно.
— Чтобы скрипт работал как надо, требуется доступ к сети, иначе curl не сможет получить данные. Но что сделать, если доступа к сети нет? Можно сообщить об этом пользователю и предложить ему проверить соединение.
— Подумайте, как улучшить проверку зависимостей. Мы надеемся, что сиг! установлен. Но что. если ввести переменную индикатор, и по ее состоя нию, если надо, воспользоваться wget?
— Как насчет добавления справки? Чтобы скрипт, вызванный с параметром -h или - - help, показывал пример использования и список параметров, которые влияют на выполнение (в идеале — отобразил пользователю даже значения по умолчанию).
Как видите, наш скрипт хорош и работоспособен, но далек от совершенства. Всегда можно что-то улучшить, в том числе повысить надежность и информативность за счет сообщений об ошибках, на которые можно отреат ировать. Для улучшения модульности рассмотрите использование фреймворков — например, bashing1’6, rerun-’7 или rr1M.
Заключение
В этой главе мы изучили работу с Linux в терминале, через текстовый интерфейс пользователя. Мы перечислили связанные с оболочками понятия, проверили оболочки в деле, узнали, как решить типичные задачи и повысить удобство работы с помощью более современных команд (таких как еха на замену 1s).
Затем мы рассмотрели современные и удобные оболочки, в частности fish, их настройку и использование, изучили терминальный мультиплексор на наглядном примере tmux, в котором поддерживаются несколько локальных или удаленных
136 Мини-фреймворк bashing: https://github.com/xsc/bashing.
137 Фреймворк скриптов rerun: https://github сот/rerun/rerun.
13" rr: shell script multi-tool: https://t«arr.com/
94 | Глава 3. Оболочкл и скрипты
сеансов. Современные оболочки и мультиплексоры сильно упрощают жизнь при работе с командной строкой, поэтому я настоятельно рекомендую вам их освоить.
В конце мы научились автоматизировать задачи и писать безопасные переносимые скрипты, а затем анализировать и тестировать их. Помните, что все оболочки — это интерпрет аторы команд, и свободное владение ими, как и освоен ие язы ков, требует долгой практики. Однако теперь вы вооружены навыками работы в командной строке и уже можете работать с большинством систем на базе Linux — от одноплатного компьютера до облачной виртуальной машины. И везде вам понадобится лишь терминал и возможность выполнять в нем команды, вручную или из скриптов.
'Гем, кто хочет глубже погрузиться в обсужденные темы, я дам дополнительные ссылки:
Терминалы
«Анатомия эмулятора терминалов»139.
«Развенчание мифа о TTY»140.
«Терминал, консоль, оболочка — что это?»141.
«Что такое TTY в Linux? (и как использовать команду tty)»142.
«Ваш терминал нс терминал: введение в потоки»143.
Оболочки
«Оболочки Unix: bash, Fish, ksh tesh- zsh»144.
«Сравнение командных оболочек»145.
Тема «bash vs zsh» на reddit146.
«Ghost In The Shell — Часть 7 — Настройка ZSH»147.
139 Блог «Anatomy of a Terminal Emulator»: https://poor.dev/blog,'terminai-ana;oniy/.
140 «The TTY Demystified»: https://www.linusakesson.net/programmiitg/tty/.
141 «The Terminal, the Console and the Shell — What Are They?»: https://unixdigest.com/articles/ the terminal the console and-the-shell-what are they.html.
142 «What Is a TTY on Linux? (and How to Use the tty Command)»: https.//www.howtogeek. com/428174 /what-is- a- tty-on-iinux-and-how-to-use-the-tty-command/.
143 «Your terminal is not a terminal; An Introduction to Streams»: https://lucastcosta.com/ 2019/04/07/streams-introduction.html.
144 «Unix Shells: bash, Fish, ksh, tesh, zsh»: https://hyperpolygiot.org/unix-shells.
145 Comparison of command shells: https://en. wikiped ia.org,'wikl/Companson_of_command_sheIls.
146 «bash vs zsh» thread on reddit: https://www.reddit.eom/r/linux/comments/lcsl7e/hash_vs_ zsh/?rdt-36305.
147 «Ghost in the Shell — Part 7 — ZSH Setup»: https-//vermaden.wordpress.com/2021/09/19/ ghost-in-the-shell-part-7-zsh-setup/ (заголовок статьи отсылает к аниме, известному читателю под названием «Призрак в доспехах»).
Заключение | 95
Терминальный мультиплексор
«Исчерпывающий курс по tmux»148.
«Краткое и понятное введение в tmux»14’
«Как использовать tmux в Linux (и почему он лучше, чем screen)»150.
«'The Tao of tmux» by Tony Narlock (free to read online)151.
«tmux 2: Productive Mouse-Free Development» by Brian R Hogan (The Pragmatic
Programmers), 2016152.
Подсказки no Trnux153.
Скрипты
«Стиль программирования Shell»154.
«Стиль программирования bash»155,
«bash-скрипты — лучшие практики» -56.
«bash-скрипты — шпаргалка»157.
«Пишем bash не только для bash — ищем башизмы, тестируем в Dash»158.
Вооружившись умением работать в оболочке, мы переходим к контролю до ступа и способам обеспечить его соблюдение в Linux.
148 «А tmux Crash Course»: https://thoiightbot.coni/blog/a-tmux crash course.
149 «А Quick and Easy Guide to tmux»: https://hamvocke.eom/blog/a quick-and easy-guide to-ttrux/.
150 «How to Use tmux on Linux (and Why It’s Better Than screen)»: https://www.howtogeek. com/671422/how-to-use-tmux- on-linux-and-why its-better than screen/.
151 Книга Топи Тарлока «Дао tmux» (открыта для чтения в сети): https://icar.pub.com/the-tao-of tmux/read.
152 «tmux 2: Productive Mouse-Free Development» by Brian P. Hogan (The Pragmatic Programmers), 2016. https://pragprog.com/litles/bhtmjx2/tmux-2/. Есть авторский пере вод В. Айсича: https://akawali.ru/linux/tmux2.html.
153 Tmux Cheat Sheet & Quick Reference website: https://tmuxcheatsneet.com/.
154 Shell Style Guide: https7/google.gitbub.io/styLeguide/shellguide.htmL.
155 Bash Style Guide: https://gitbub.coin/bahamaslG7bash-sty.e-guiae.
154 Bash best practices: https://bertw.github.io/cheat-sheets/Bash.httrl.
157 Bash scripting <heatsneer: https://devhints.io/bash.
158 Writing Bash Scripts that are not only Bash: Checking for Bashisms and testing with Dash: https://devto/bowinanjd/writing-bash-scripts-that-are-not-only-bash-checking for bashisms and-testing-with-dash- Ibli.
ГЛАВА 4
Управление доступом
В предыдущей главе мы изучили оболочки и сценарии, а теперь сосредоточимся на одном важном аспекте безопасности. В этой главе обсудим пользователей в Linux и способы управления доступом к ресурсам системы, в частности, к файдам.
Первый вопрос, который возникает в многопользовательской среде, касается принадлежности и владения. Пользователь может быть владельцем файла. Ему разрешено читать, записывать и даже удалять его. Учитывая, что пользователь не один, как разобраться, что позволено другим? Кто определяет это и как обеспечивает? А ведь действия пользователя не всегда связаны с файлами. Кому-то может быть разрешено (или нет) менять сетевые настройки.
Чтобы разобраться с этим вопросом, сначала рассмотрим фундаментальные связи между пользователями, процессами и файлами с точки зрения доступа к ним. Изучим модели управления доступами и режим песочницы. Далее разберемся, что такое пользователи Linux, что они могут делать и как управлять ими локально или централизованно.
После этою мы затронем тему разрешений и узпаем, как регулировать доступы и какой эффект их ограничение оказывает на процессы.
В конце главы мы обсудим дополнительные возможности Linux для управления доступом, включая привилегии, профили secco^p и ACL. В завершение, как обычно, предложим несколько полезных рекомендаций по безопасности, связанных с разрешениями и управлением доступом.
Итак, перейдем к теме пользователей и правами над ресурсами, заложив основы для остальной части главы.
Основы
Немного отступим и взглянем на тему с высоты птичьего полета. Это поможет установить основные понятия и прояснить их связи друг с другом.
Основы | 97
Ресурсы и владение
Linux — многопользовательская операционная система, и концепцию пользователей (см. «Пользователи») опа унаследовала от UNIX. Каждая учетная запись связана с идентификатором (UIE?), по которому может быть разрешен доступ к программам, файлам, устройствам и прочим ресурсам. Пользователь может войти в систему под учетной записью, а процесс можно запустить от имени учетной записи. Еще есть ресурсы (будем называть их файлами), которые предосзявляют пользователю аппаратные или программные компоненты. Мы будем подразумевать под ресурсами файлы во всех случаях, за исключением тех, где явно укажем на доступ к ресурсам другого типа, — например, через системные вызовы. Рисунок 4-1 с последующим комментарием объясняет связь между пользо вателями, процессами и файлами в Linux.
Рисунок 4-1. Пользователи, процессы и файлы в Linux
Пользователи
Запускают процессы и владеют файлами. Процесс — это программа (испол няемый файл), которую ядро загрузило в основную память и выполняет
Файлы
Принадлежат владельцам. По умолчанию владелец — пользователь, который создал файл.
Процессы
Используют фай, Пэ! для обмена данными и сохранения состояний. Разумеется, пользователи тоже используют файлы, ко опосредованно и через процессы.
Описание связей между пользователями, процессами и файлами, конечно, упрощенное. Но оно дает представление об о сновных действующих лицах и взаимоотношениях — и пригодится нам позже, когда мы остановимся на взаимодействии между этими игроками.
Но сначала рассмотрим выполнение процесса через призму О1раничений. Когда речь заходит о доступе к ресурсам, довольно часто мелькает слово «песочница»
93 | Глава 4. Управление доступом
Песочница
У термина «песочнииа» кет однозначного определения, Это скорее набор методов, от изолятора до контейнеров и виртуальных машин, которыми можно управлять как в ядре, так и в пользовательском пространстве. Что нибудь всегда запускается в песочнице — обычно это приложение, — и надзорный механизм обеспечивает необходимую изоляцию между процессом внутри и внешней средой. Если для вас это звучит слишком сухо, прошу вас немного потерпеть. Мы посмотрим на песочницу в действии чуть позже в этой же главе в разделе «Про фили seccomp» и вспомним о ней в главе 9, когда будем говорить о виртуальных машинах и контейнерах.
С начальным пониманием ресурсов, владения ими и доступов к ним давайте кратко обсудим несколько путей управления доступами.
Модели управления доступами
Один из аспектов управления доступами характеризуется самим словом. Есть ли у пользователя или процесса прямой доступ к ресурсу, возможно, даже неограниченный? А есть ли четкий набор правил, который определяет, к каким ресурсам (файлам или системным вызовам) процесс может иметь доступ, и при каких обстоятельствах? А, может, даже факт доступа может быть записан?
Концептуальных моделей! управления доступом несколько. Две наиболее важных и соответствующих пашей теме — это избирательная и мандатная.
Избирательная модель управления доступом
Идея избирательною управления доступом (DAC, его еще называют дискреционным) — разграничение доступа к ресурсам на основе личности пользователя. В дискреционной модели пользователь, у которого есть те или иные разрешения, имеет право назначать их другим пользователям.
Мандатная модель управления доступом
Мандатное управление доступом (МАС, его еще называют обязательным) основано на иерархии, представляющей уровни безопасности. Пользователям назначается уровень допуска, а ресурсам — метка безопасности. Поль зователи получают доступ только к тем ресурсам, которые соответствуют (равны или ниже) уровню их допуска. Все разрешения контролирует администратор. В мандатной модели пользователи не могут устанавливать разрешения сами, даже если владеют ресурсом.
Основы | 99
Вдобавок Linux традиционно придерживается принципа «все или ничего». Либо вы суперпользователь и делаете все что заблагорассудится, либо просто пользователь, и ваш доступ ограничен. Изначально не было простого и гибкого способа присвоить пользователю или процессу специальные полномочия. Например, чтобы разрешить «процессу X изменять сетевые настройки», нужно было предоставить ему root. Естественно, это критически влияло на взломан ную систему, злоумышленник легко получал полный доступ.
Чтобы немного прояснить отношение «все или ничего»: по умолчанию в большинстве систем Linux разрешен доступ на чтение почти ко всем файлам и программам для «других», то есть для всех пользователей в системе. А если включить SELinux, мандатное управление не даст доступа никуда, кроме тех ресурсов, которым заданы разрешения; зсб-сервер будет использовать только порты 80 и 443, делиться файлами и скриптами из определенных каталогов, писать логи в строго отведенные места и т. д.
Мы вернемся к этой теме в разделе «Расширенное управление разрешениями» и посмотрим, как современные функции Linux помогают преодолеть этот черно-белый взгляд на мир, допуская более тонкий контроль над полномочиями.
Вероятно, одна из самых известных реализаций мандатного управления для Linux — это SELinux-5’. Его разрабатывали исходя из высоких требований к безопасности государственных учреждений. Обычно там его и используют, поскольку от всех строгих правил сильно пострадало удобство. Другой вариант мандатного управления доступом, который входит ь ядро Linux начиная с версии V2.6.36, и очень популярен в семействе Linux Ubuntu, — это AppArmor159 160.
Теперь обратимся к геме пользователей и управления ими в Linux.
Пользователи
С точки зрения предназначения или предполагаемого использования в Linux ча -сто различают два типа учетных записей:
159 Мандатное управление доступом; SeLinax; https://selinuxproject.oig/page/Main_Page.
160 Мандатное управление доступом: AppArmor: https://www.apparmor.net/.
100 | Глава 4. Управление доступом
Так называемые системные пользователи, или системные учетные записи
Этот тип учетных записей обычно используют программы (иногда их называют демонами) для запуска фоновых процессов. Службы, предоставляемые такими программами, могут быть частью операционной системы (например, sshd — демон для ssh), или запускаться на прикладном уровне (например, mysql — известная реляционная база данных).
Обычные пользователи
Например, пользователь-человек, который использует Linux в интерактивном режиме через оболочку.
Разница между системным и обычным пользователем больше организационная, чем техническая. Чтобы объяснить это утверждение, сначала придется ввести понятие идентификатора пользователя (UID) — 32 битного числового значения, управляемого Linux.
Linux распознает пользователей через их UID. Каждый пользователь входит в одну или несколько групп, которые распознаются через собственный идентификатор (G1D). Есть особый вид пользователя с UID 0 — его обычно называют root. Этот «суперпользователь» может делать все что угодно, и никакие ограничения к нему не применяются. В нормальных условиях работать из-под root — это очень плохая затея. Слишком много власти Любым неосторожным движением можно разрушить всю систему (и поверьте, я знаю, о чем говорю) Мы вернемся к этому вопросу чуть позже.
Разные дистрибутивы Linux предлагают разные способы управления диапазоном UID. В сборках на базе systend (см. «systemd») принято такое соглашение (упрощенно);
U ID О
Это root.
UID 1-999
Этот диапазон зарезервирован для системных пользователей.
UID 65534
Пользователь nobody («никто») нужен, в частности, для сопоставления удаленно подключенною пользователя с известным ID, как в случае с «Сетевой файловой системой».
U1D1000-65533 и 65536 4294967294
Обычные пользователи.
Пользователи | 101
Чтобы узнать свой UID, можете вызывать команду (сюрприз!) id следующим образом:
$ id -и
2016796723
Теперь, когда вы знаете, что такое пользователи Linux, посмотрим, как ими управлять.
Локальное управление пользователями
Первый и традиционно единственный по умолчанию вариант управления пользователями — локальный. Вся информация хранится на текущем компьютере, а данные пользователей не распространяются по сети на другие машины.
В Linux для локального управления пользователями используется простой файловый интерфейс с немного запутанной схемой именования, которая сложилась исторически и с которой, к сожалению, придется смириться. В таблице 4-1 перечислены четыре файла, на которых реализовано управление пользователями.
Таблица 4-1. Список файлов для управления локальными пользователями
Назначение	Файл	1
База данных с пользователями	/etc/passwd
База данных с группам и	/etc/group
Пароли пользователей	/eta'shadow
Пароли групп	/etc/gshadow
Воспринимайте /etc/passwd как своего рода миниатюрную базу данных, в ко торой хранятся имена пользователей, UID, членство в группах и дополнительная информация, такая как домашний каталог и используемая оболочка входа (для обычных пользователей). На конкретном примере:
$ cat /etc/passwd О
root: х 3:0: root:/root:/bin/bash
daemon: x:l 1: caemon:/ijsr/sbin:/usr/sbin/rologin ®
bin: x:2:2: bin:/t>in:/usr/sbin/nologin
sys: x:3:3: sys /dev:/usr/sbin/nclogin
nobody: x:65534 65534: nobody:/nonexistent:/usr/sbin/nologin
sysiog: x:104:110:;/hone/syslog:/usr/sbi n/nologi n
nh9: x:lG60;1001: :/hone/nrh9:/usr/bin/fish Ф
102 | Глава 4. Управление доступом
О Пользователь root, UID 0.
® Это системная учетная запись (ее выдает nologin; подробнее см. ниже).
О Моя учетная запись.
Посмотрим поближе на одну из строк в /etc/passwd, чтобы детально понять структуру записи для отдельно взятого пользователя:
root: х: 0:0:root:/root:/bin/bash
I	Illi	I	c
I	Illi	•— ®
I I *— ® I *—® >— ©
| L— Ф
>— Ф
О Заданная оболочка входа. Чтобы предотвратить интерактивный вход, используется /sbin/nologln.
® Домашний каталог пользователя; по умолчанию /.
в Информация о пользователе, полное имя или контактные данные, такие как телефон. Его часто называют поле GF.COS161. Обратите внимание, что форматирование GECOS не используется. Зачастую в поле хранится только полное имя человека, связанного с учетной записью.
О GID основной группы пользователя; см. также /etc/group.
9 UID. Помнит е, что UID меньше 1000 зарезервированы для системных целей.
© Пароль пользователя. Атрибут х означает, что пароль (в зашифрованном виде) хранится в /etc/shade*. В наши дни это поведение по умолчанию.
® Имя пользователя до 32 символов длиной.
Единственное, чего мы не обнаружили в /etc/passwd (хотя и ожидали, исходя из названия), — эго паролей. Исторически сложилось так, что пароли хранятся в файле с именем I etc/shadow, и если каждый пользователь может просмотреть /etc/passwd, то для чтения /etc/shadow обычно нужны права root.
Для добавления пользователя выполните команду adduser162 следующим
образом:
5 sudo adduser mh9
Adding user >h9' ...
161 Поле GECOS; https.//en.wikpedia.org/wiki/Gecos_field.
162 Команда adduser: littps://linux.die.net/maii/8/adduser.
Пользователи | 103
Adding new group nh9' (1061) ...
Adding new user 'nh9' (Ш00) with group 'mh9' ... ®
Creating hone directory /hom₽/mh9' ...
Copying files fro") /etc/skel' ... ®
New password: ®
Retype new password:
passwd: password updated successfully
Changing the user information for mh9
Enter the new value, or press ENTER for the default О
Full Name []: Michael riausenblas
Roon Number []:
Work Phone (]:
Home Phone []:
Othe^ []:
Is the information correct? [Y/n] Y
О Команда adduser создаст домашний каталог.
® В дом ашний каталог также колируется ря ц стандартных конфигурационных файлов.
® Требуется указать пароль.
О Можно предоставить необязательную информацию для GECOS поля.
Если вы хотите создать системную учетную запись, вызывайте команду с параметром -г. Это отключит оболочку входа и предотвратит создание домашнего каталога. В файле /etc/adduser.conf вы найдете и другие настройки, включая диапазон UID/GID, который будет использован.
Помимо пользователей, в Linux существуют и группы. В некотором смысле группа — эго всего лишь набор из одгюго или нескольких пользователей. Каждый ноль зоватсль входит хотя быв олну группу по умолчанию, но может входить и в другие. Подробности о группах и их сопоставлении смотрим в файле /etc/group.
$ cat /etc/group ®
root: х:0:
daemon: х:1:
bin: х:2:
sys: х:3:
adm: х:4: syslog
ssh: x:114:
104 | Глава 4 Управление доступом
landscape: х:115:
admin: x:116:
netdev: x:117:
Ixd: x:118:
systend-ccredump: x:999. nh9: x:1061: ®
О Выводим содержимое файла с сопоставлением групп.
® Пример группы моего пользователя с GID 1001. Заметьте, что после двоеточия в конце можно добавить разделенный запятыми список имен пользова телей, к которым вы хотите применить разрешения группы.
Вооружившись базовыми знаниями, переходим к способу управлять пользователями в профессиональной среде. Он более мощный и допускает масштабирование.
Централизованное управление пользователями
Если в вашем ведении несколько машин или серверов — например, в корпоративной среде, — то вручную управлять пользователями на каждом компьютере быстро надоедает. Требуется централизованный подход, при котором все пользователи управляются локально только-на одной специальной машине. В зависимости от требований и имеющихся у вас ресурсов (включая время), вам доступно несколько способов:
На основе каталогов
Набор протоколов облеченного доступа к каталогам LDAP (Lightweight Directory Access Protocol’63), который существует уже несколько десятилетий и формализован в стандартах 1ETF. Он определяет способы доступа и управления распределенным каталогом через IP. Можно запустить собственный сервер LDAP (например, с помощью проекта Keycloak* 164) или довериться облачному решению, такому как Azure Active Directory.
Через сеть
В этом случае проверка подлинности (аутентификация пользователей) происходит через Kerberos. Подробнее в разделе «Kerberos».
161 Протокол LDAP (Lightweight Directory Access Protocol): https://en.wikipedLa.org/wiki/ Lightweight_Directory_Access_Protocol.
164 Проект Keycloak. https://www.keydoak org/
Пользовагели | 105
Через систему управления конфигурациями
Такие системы, включая Ansible, Chef, Puppet или SaltStack, мсгут использоваться для создания и поддержки актуальности списка пользователей на группе машин.
Способ зачастую навязан самим окружением. Если ваша организация уже использует LDAP, то выбор у вас невелик. Сравнение различных подходов с их ин-дивидуальпыми плюсами и минусами выходит за рамки этой книги.
Разрешения
В этой части мы сначала углубимся в детали разрешений на доступ к файлам (в Linux это г^ектральная концепция управления доступом), а затем затронем разрешения, связанные с процессами: как они работают в реальном времени и как наследуются от разрешений файлов.
Разрешения файлов
Разрешения файлов -  это ядро всей идеи доступа к ресурсам в Linux: как мы помним, в той или иной степени в Linux «все есть файл». Давайте сначала определимся с терминологией, а потом посмотрим, какая информация связана с до стулом к файлам и разрешениями.
Существуют три типа, или три области действия разрешений (от более узких к широким):
Пользователь
Владелец файла.
Группа
Включает в себя одного или нескольких участников.
Другие
Категория, в которую входят «все остальные».
Кроме этого, есть три типа доступов:
Чтение (г)
Такое разрешение на обычном файле значит, что пользователь может просматривать его содержимое, а на каталоге, что пользователь может увидеть имена файлов.
106 | Глава 4. Управление доступом
Запись (ш)
На обычном файле разрешает пользователю редактирование и удаление, а на каталоге — создавать переименовывать и удалять в нем файлы.
Исполнение (х)
Такое разрешение на обычном файле позволяет запустить его, если у пользователя также есть разрешение па чтение. На каталоге позволяет запрашивать информацию о файдах, фактически разрешай входить в него (cd) или просматривать содержимое (Is).
ДРУГИЕ ФЛАГИ ДОСТУПА К ФАЙЛАМ
Я перечислил г/w/x как три типа доступа к файлам, но на практике вы увидите и другие, если выполните 1s:
•	s - - это разрешение setuid/setgid, применяемое к исполняемому файлу. Пользователь, который его запустил, наследует фактические полномочия владельца или группы файла.
•	t — «липкий биг», актуален для каталогов. Когда уст ановлен, запрещает пользователям (всем кроме root) удалять каталог и файлы, если они не владельцы.
Есть и другие специальные настройки, доступные через команду chattr (изменить атрибут), но мы не будем разбирать их в этой главе.
Давайте посмотрим на разрешения в действии (для читаемости я немного расширил пробелы в выводе Is);
$ Is -al
total Э
-rw-r--r-- 1 nh9 devs 9 Apr 12 11:42 test
I >- ®
>— ©
1— ф
О Имя файла.
® Время последнего изменения.
Разрешения | 107
® Размер фай,за в байтах.
О Группа, к которой принадлежит файл.
© Владелец файла.
Ф Количество жестких ссылок165.
О Режим доступа.
Если поближе рассмотреть режим — тип файла и назначенные ему разрешения из предыдущего примера. — можно разделить его на следующие поля:
. TWX rwx rwx
III1—®
II *— •
I >— ®
>— О
О Разрешения для «других».
® Разрешения для группы.
® Разрешения для владельца.
О Тип файла (таблица 4-2).
Первый сих вол в режиме указывает на ти п файла (см. таблицу 4- 2), а в ос галь ных закодированы разрешения для различных условий — для владельца, группы и «других», как указано в таблице 4 3.
Таблица 4-2. Типы, как они указываются в режиме файла
Символ Разъяснение
06 ычный. фз йл (например, когда вы выполняете команду touch abc)
b	Специальный блочный файл
с	Специальный символьный фа йл
С	Зысс копроиз водительный файл (непрерывные данные)
d	Каталог
I	Символическая ссылка
р	Именованный канал (созданный ткАГо)
s	Сокет
?	Другой (г еизвестный) ти п файла
16S hard links (жесткие ссылки): https://ltnuxaiia.com/howto/countirg and-list'.ng-hard-links-on-linux.
138 | Глава 4. Управление досолом
На другие (выведенные из обращения или устаревшие) символы в начальной позиции, такие как М или Р, вы можете не обращать внимания. Если вам интересно, что они означают, запустите команду infols -n "What information is listed".
В совокупности эти права в файловом режиме определяют, какие действия разрешены для каждого элемента целевого набора (пользователь, группа, все остальные), как показано в таблице 4-3. Проверка и принудительное применение этих правил осуществляется через механизм контроля доступа.
Таблица 4-3. Разрешения файла
Комбинация	Действующие разрешения	Десятичное представление
	Не установлено	0
—X	Запуск	1
-W-	Запись	2
-WX	Запись и запуск	3
г-	Чтение	4
Г X	Чтение и запуск	5
rw-	Чтение изапись	6
rwx	Чтение, запись, запуск	7
Рассмотрим несколько примеров
755
Полный доступ для владельца; чтение и запуск для всех остальных.
706
Полный доступ для владельца; никакого для всех остальных.
664
Чтение/запись для владельца и группы, только чтение для остальных.
644
Чтение/запись для владельца; чтение для всех остальных.
40G
Только чтение для владельца.
В моей системе 664 имеет особое значение. Эго разрешение по умолчанию, которое назначается файлам при создании. Проверяется командой urask166, которая в моем случае возвращает 9002.
*“ umask: https.//man7.org/lfnux/man-pages/rnan2/umask.2.btml.
Разрешения | >09
Разрешения setuid сообщают системе, что нужно запустить исполняемый файл от имени владельца и с его разрешениями. И если владелец root, это может привести к неприятным последствиям.
Разрешения для файла можно установить с помощью chnod. Параметры ука зываются явно (например, 644), или комбинацией символов (например, +х, чтобы сделать файл исполняемым). Но как это выглядит на практике?
Сделаем файл исполняемым, используя chnod:
S is -al /tnp/nasktest
-rw-г--г-- 1 nh9 dev 0 Aug 28 13:67 /tnp/nasktest О
$ chnod +x /tnp/nasktest ®
$ is al /tnp/nasktest
-гихг-хг-х 1 nh9 dev Э Aug 28 13:07 /tnp/nasktest ©
О Начальные разрешения: г/w для владельца и только чтение для всех остальных (или 644).
© Назначаем файл исполняемым.
О Теперь разрешения: r/w/x для владельца и г/х для остальных (или 755).
На рисунке 4-2 показано, что происходит под капотом Учтите, что вы вряд ли захотите, чтобы файл выполняли все и каждый, поэтому лучше было бы задать chnod 744, предоставив разрешения только владельцу, не затрагивая всех остальных. Мы обсудим эту тему подробнее в разделе «Оптимальные практики».
chmcd +х
1 1 1110 1
Рисунок 4-2. Как изменяются разрешения файла при назначении его исполняемым
rwx: г —х
110 | Глава 4. Управление доступом
Сменить владельца можно командой chown (и chgrp для группы).
$ touch nyfile
$ Is -al nyfile
-rw-rw-r-- 1 nh9 nh9 0 Sep 4 09:26 nyfile О
$ sudo chown root nyfile ®
rw-rw-r-- 1 root nh9 0 Sep 4 09:26 nyfile
О Файл nyfile, который я создал и для которого я владелец.
S После выполнения chown владельцем файла стал root.
Обсудив основы управления разрешениями, рассмотрим более серьезные 1 ехники.
Разрешения процессов
До сих пор мы рассматривали только пользователей-людей и доступ к файлам на основе заданных разрешений. Теперь обратим внимание на процессы. В разделе «Ресурсы и владение» упоминалось, что пользователи владеют файлами, а процессы эти файлы используют. Возникает вопрос: а как обстоят дела с разрешениями для процессов?
Как указано в разделе credentials(7)167 справки пап, в реальном времени (при выполнении процесса) имеют значение несколько разных UID:
Реальный UID
Реальный LTD — это ID пользователя, который запустил процесс. По этому идентификатору оценивается владение процессом с позиции пользователя человека. Сам процесс получает доступ к реальному UID через getuid(2)168, а вы можете запросить его в оболочке командой stat -с "%и %д" /ргос/Spid/
Эффективный UID
Ядро Linux использует эффективный U1D, когда определяет разрешения для доступа к общим ресурсам, например, очередям сообщений. Традиционно в системах UNIX эффективный UID используется также при доступе к файлам. Но в Linux раньше для этой цели служил обособленный U1D
167 credentials (7): https://man7.0rg/linux/man-pages/nTan7/credentiaIs.7.html.
168 geniid (2): Iittps://man7.org/limix/man-pages/man2/getiud.2.html.
Разрешения | 111
файловой системы (см. чуть ниже), и для совместимости это поведение все еще поддерживается Процесс запрашивает свой эффективный UID через geteuia(2):6\
Сохраненный set-user-ID
Этот идентификатор нужен в случаях с sutd, чтобы процесс имел возможность присваивать привилегии, меняя эффективный UID с реального UID на сохраненный set-user-ID и обратно Например, чтобы использовать опре деленные сетевые порты (см. «Порты»), процессу необходимы повышенные права (запуск от имени root). Процесс получает доступ к сохраненному set -user-ID через getresuid(2)* 170.
U1D файловой системы
Этот идентификатор, характерный только для Linux, используется для определения прав при доступе к файлам. Изначально его вводили, чтобы в случаях, когда файловый сервер запущен от имени обычного пользователя, изолировать запущенный процесс от сигналов этого пользователя. Как правило, программы не манипулируют LTD файловой системы напрямую. Ядро следит за изменениями эффективного U1D, и меняет U1D файловой системы вслед за ним (так что обычно они совпадают), Однако U1D файловой системы может быть изменен через setfsuid(2)171. Обратите внимание, что технически UID файловой системы не нужен начиная с версии ядра v2.C, но для совместимости он по прежнему поддерживается.
Дочерние процессы, созданные с помощью fork(2), наследуют копии UID своего родителя. При системных вызовах execve(2) оставляет реальный UID нетронутым, а эффективный LTD и сохраненный set-user-ID могут меняться.
К примеру, когда dm запускаете команду passwd, эффективный UID равен вашему UID (скажем, 1000). Теперь, для passwd включен suid — это значит, что, когда вы его запустите, ваш эффективный UID будет равен 0 (то есть root). Есть и другие способы повлиять на эффективный UTD — например, через команду chroot и другие методы песочницы.
и» ge-euicJ (2); https .//man7.org/Enux/man pages/man2/geteaid.2.html.
170 getresuid (2): https://man7.org,'linux/man-pages/man2/getresi;id.2.htmE
171 setfsuid (2): https://maii7.Org/Enux/man-pages/man2/settsuid.2.html.
112 | Глава 4. Управление доступом
Для потоков POSIX172 необходимо, чтобы учетные данные всех потоков в процессе были одинаковыми. Но на уровне ядра Linux допускает разные идентификаторы пользователя и группы для отдельных потоков.
Кроме разрешений на доступ к файлам, ядро использует UID процессов и для других целей:
— Для установки разрешений на отправку сигналов — например, чтобы определить последствия выполнения kill. -9 для процесса с определенным ID. Подробнее об этом в главе 6.
—	При обслуживании разрешений для планирования и приоритетов (например, nice).
—	Для проверки ограничений ресурсов. Мы рассмотрим это при обсуждении контейнеров в главе 9.
Пока мы рассуждаем об эффективном UID в рамках sued, все кажется понятным. Но как только на сцене появляются привилегии, все становится немного сложнее.
Расширенное управление разрешениями
Хотя мы до сих пор рассматривали только распространенные методы управления разрешениями, информация в этом разделе более серьезная. Она вряд ли заинтересует вас для общего развития или хобби. Но в профессиональной сфере — на производстве, в условиях критически важных нагрузок — вам определенно пригодятся знания о расширенных возможностях
Привилегии
В Linux, как традиционно во всех UNIX-системах, процессы, запущенные пользователем root, ничем не ограничиваются. Иными словами, ядро различает только два случая:
—	Привилегированные процессы с эффективным UID 0 (он же root), которые минуют ьсс проверки разрешений.
172 POSIX threads: https://en.wTkipedia.crg,'wikj/Pthreads.
Расширенное управление разрешениями | 113
— Непривилегированные процессы с ненулевым эффективным UID, для которых ядро выполняет проверку разрешений, как описано в разделе «Раз решения процессов».
С появлением привилегий (системный вызов capabilities173 в ядре, начиная с версии v2.2) это черно-белое мировоззрение изменилось: полномочия, тра дицилнно связанные с root, теперь могут быть разбиты на отдельные единицы и назначены отдельным потокам.
На практике, если у процесса нет привилегий, то он контролируется обычными разрешениями, как описано в предыдущем разделе. Привилегии можно назначить как исполняемым файлам (двоичным или скриптам), так и процессам, постепенно расширяя нужные для выполнения задачи полномочия (см. в разделе «Оптимальные практики»).
Предостерегу вас: привилегии, как правило, актуальны только для задач си с темного уровня. Иными словами, большую часть времени вы не будете на них полагаться.
В таблице 4-4 описаны некоторые из самых распространенных привилегий.
Таблица 4-4. Распространенные привилегии
Привилегия	Описание
CAP_CHCWN CAPJULL	Разрешает пользователю произвольно меня it UtD/GID файлов Разрешает отпрг вля’ь сигналы процессам, которые принадлежат другим пользователям
САР_ SETUID CAP_SETPCAF CAP_NET_ADMIN CAP_NET_RAW CAP_SYS_CHROOT CAP. SYS. ADMIN	Позволяет и вменять JID Разрешает настраи вать привилегии на запущенных процессах Разрешает действия, связанные с сетью, например, настройку интерфейса Разрешает использовать сокеты RAW и PACKET Раз решает в ызывать ch root Разрешает операции системного администратора, в *ом сисле монти рева ть файловые системы
CAP.SYS. PTRACE CAP_SYS_MODULE	Разрешает использовать strace для отладки г роцессов Разрешает загружать модули ядра
Давайте оценим, как они работают. Для начала, чтобы просмотреть все привилегии, используйте следующие команды (вывод урезан, чтобы влезал на страницу):
173 capabilities (7): https://ma.ri7 org/linux/man pages/roan7/capabilities.7.html.
114 | Глава 4. Управление доступом
$ capsh --print О Current: = Bounding set -cap_chown, cap_dac.override, cap_cac_read. search, cap fowner, cap_fsetid, cap. kill, cap .setgid, cap_setuid, cap_setpcap,
$ grep Cap /proc/$$/status ©
Caplnh: 9996066600000000
CapPrn: 0960666000090630
CapEff: 00006060006 00006
CapBnd: 000001ffffffffff
CapAnb; 0000066000000030
О Список всех привилегий в системе.
© Привилегии для текущего процесса, то есть для оболочки.
Вы можете тонко (на уровне отдельных файлов) настраивать привилегии с помощью getcap174 и setcap175. Подробности и дельные советы по этой теме выходят за рамки главы.
Привилегии помогают преодолеть подход «все или ничего» и настраивать полномочия на уровне файлов. Перейдем к следующей теме — расширенному управлению доступом в технике песочницы seccomp.
Профили seccomp
Режим безопасных вычислений (seccomp)176 — это функция ядра Linux, доступная с 2005 года. Ее основная идея в том, чтобы с помощью обособленного системного вызова seccomp(2) ограничить системные вызовы, которые может ис пользовать процесс.
Непосредственное управление seccorp может показаться вам неудобным, но его можно использовать без особых хлопот, например, в рамках контейнеров (см. «Контейнеры»). И Docker177, и Kubemetes178 поддерживают seccomp из коробки.
174 gexap (Ь): https://www.man7.0rg/linux/man-pagcs/marS/gctcap.8.html.
175 setcap (8): https://www.man7.Org/linux/man-pages/man8/setcap.8.html.
176 seccomp (2): https://man7.Org/linux/man-pages/inan2/seccomp.2.htnil.
177 Seccomp security profiles for Docker: https://docs.docker.cc-m/enginc/security /seccomp/.
178 Kubernetes: Restrict a Container's Syscalls with seccomp: https://kubernetes.io/docs/tutorials/ security/seccomp /.
Расширенное управление разрешениями | 115
А теперь взглянем на дополнение к традиционной модели файловых разрешений.
Списки управления доступом
Списки управления доступом (AccessContrulLists, или ACL) добавляют в Linux гибкую механику разграничения прав, которая используется поверх или в добавление к «классической» модели разрешений, рассмотренной в разделе «Разрешения файлов». ACL сглаживают недостаток стандартной модели, позволяя назначать разрешения пользователям или группам, которые изначально не входят в список групп пользователя.
Чтобы проверить, поддерживается ли ACL в вашей сборке, наберите grep -i act /boot/config* и попробуйте найти в выводе строку, похожую на POSIX_ACL=Y. Использование ACL для файлоьой системы необходимо разрешить во время монтирования с помощью параметра act. В документации к ас!179 вы найдете много полезных подробностей.
Подробно разбирать ACL мы не будем, это не вписывается в формат книги, но знание о существовании такой механики и ее принципах может пригодиться вам, если вы столкнетесь со списками управления доступом в реальной жизни.
Итак, переходим к полезным советам по управлению разрешениями.
Полезные советы
Вот несколько «лайфхаков», применимых для большинства случаев управления разрешениями. Хотя некоторые, скорее, профессиональные, знать о них полез ко всем.
Соблюдайте принцип наименьших прав
Б сокращенном виде принцип наименьших прав гласит, что человек или процесс должны иметь только те разрешения, которые необходимы для выполнения задачи. Если приложение не пишет в файл, ему досгаточ но доступа толь ко на чтение. В плане управления разрешениями вы можете соблюсти этот принцип двумя путями:
— В разделе «Разрешения файлов» мы видели результат выполнения cheiod +х. Кроме разрешений, которые вы собирались задать, команда назначила их
179 acl (5): https://man7.org/Iinux/man -pages/man5/acl.5.html.
116 | Глава 4. Управление доступом
и всем остальным. Указывать разрешения в числовом виделучше, чем в символьном. Пусть символьный режим более понятен, зато куда менее строг.
— Максимально избегайте работы из-под г oot. Когда вам нужно что то уста новить, используйте sudo, а не входите гоос-пользоватеием.
Не забывайте использовать политику SELinux при написании приложения, запирая его в пределах избранных файлов, каталогов и возможностей. Пом ните, что модель, примененная в Linux по умолчанию, может предоставить вашему приложению доступ к любым файлам, оставшимся открытыми в системе.
Избегайте setuid
Лучше назначьте привилегии, но не полагайтесь на наследование UID. Setuid как кувалда, он предоставит злоумышленникам прекрасный способ захватить вашу систему.
Проводите аудит
Идея аудита в том, чтобы фиксировать все действия (и тех, кто их выполнил) в лог, который нельзя подменить. Позже из этого доступно! о только для чтения лога можно узнать, кто, когда и что делал. Мы углубимся в эту тему в главе 8.
Заключение
Вы узнали, как Linux управляет пользователями, файлами и доступом к ресурсам. Теперь у ва с есть все, чтобы выполнять повседневные задачи надежно и безопасно
Работая в многопользовательской операционной среде, такой как Linux, всегда помните о связях между пользователями, процессами и файлами. Это критически важное для безопасности и надежности знание поможет вам избежать катастрофы.
Мы рассмотрели разные модели управления разрешениями, узнали, что такое пользователи Linux, что они могут и как управлять ими локально или централизованно. Тема управления доступом к файлам могла показаться сложной, но ее освоение — лишь вопрос тренировки.
Расширенные техники управления разрешениями, включая привилегии и профили seccomp, чрезвычайно пригодятся нам при изучении контейнеров.
В последнем разделе вы получили несколько полезных рекомендаций в области безопасности и управления доступом и узнали о принципе наименьших прав.
Заключение | 117
Для тех, кто хочет глубже погрузиться в темы, которые обсуждались в этой главе, я дам несколько полезных отсылок:
Общее
—	«Исследование политик управления доступом»’80 от Аманды Кроуэлл.
—	Lynis180 181, инструмент аудита и проверки соответствия.
Привилегии
—	«Привилегии Linux на примерах»182
—	«Привилегии Linux — как заставить их работать»183 184 *.
seccomp
—	«Обзор seccomp»:м.
—	«Песочница в Linux и ноль строк кода»,65.
Списки управления доступом
—	«POSIX-совместимые списки управления доступом в Linux»186.
—	«Списки управления доступом» 187от ArchLinux.
—	«Введение в списки управления доступом (ACL) Linux»188 от Red Hat.
Помните, что безопасность — это непрерывный процесс, и приглядывайте за вашими пользователями и файлами. Мы обсудим эгот вопрос d главах 8 и 9, ку а пока переходим к теме файловых систем.
180 «А Survey of Access Control Policies» by Amanda Crowell: https://wwwcs.umd.edu/sites/ default/files/scholarly_papers/ACrowdl_l.pdf.
1,1 Lynis, an auditing and compliance testing tool: https://cisofy.com/lynis/.
«Linux Capabilities In Practice»: https.//blog.container-solutions,com/linax-capab;lities- inpractice.
183 «Linux Capabilities: making them work» by Serge E. Hallyn (IBM LTC) and Andrew G Morgan (Google Inc).: https.//www.kernel.org/doc/ols/2008/ols2008rl pages 163 172.pdf.
184 «А seccomp overview»: https://lwn.net/Articles/656307/.
,8S «Sandboxing in Linux with zero lines of code» https://blog.cloudflare.ccm/sandboxing in-
linux with zero lines of-code/.
184 «POSIX Access Control Lists on Linux»: https://www.usenix.oi g/legacy/publications/library; proceedings/usenix03/tech/freenix03/full_papers/gruenbacher/gruenbacher. html/main.html. Access Control Lists via ArchLinux; https://wiki archlinux.org/title/Acc.ess Control_Lists.
188 An introduction to Linux Access Control Lists (ACLs) via RedHat: https://www.redhat.com/en/ biog/lin ax-access-contrcl -lists.
ГЛАВА 5
Файловые системы
В этой главе мы разберемся с файлами и файловыми системами. Концепция UNIX «все есть файл» живет и в Linux, где большинство ресурсов (пусть и не все сто процентов) — действительно файлы. Файлом может быть что угодно, и черновик письма для коллег, и картинка, которую вы скачиваете (с безопасного и падежного сайта, конечно).
Другие сущности тоже представлены в виде файлов — устройства и псевдо-устройства, как echo «Привет, сообщество современного Linux»>/dev/pts/0, которое выведет на экран строку «Привсг, сообщество современною Linux». Вам не обязательно считать их файлами, но доступ к ним производится теми же методами и инструментами, которые знакомы вам по работе с обычными файлами. Вспомните ядро, которое предоставляет в реальном времени информацию о работающем процессе (см. «Управление процессами») — его PID и программу, которая использовалась для запуска.
Общее лишь одно — строгий интерфейс с универсальными методами для файлов: открытие, сбор информации, запись и пр. В Linux такой интерфейс предоставляют файловые системы1”. Благодаря им и тому, чт о Linux рассматривает файл как поток двоичных данных без определенной структуры, становится возможным создание инструментов для работы с файлами любого типа.
Благодаря универсальности файлового интерфейса можно не забивать голову лишними знаниями, и осваивать Linux быстрей.
В начале в этой главы мы выделим общие понятия. Затем рассмотрим, как Linux реализует абстракцию «все есть файл» и затронем специальные файловые системы, с помощью которых ядро предоставляет информацию о процес сах и устройствах Потом обратимся к обычным файлам и файловым системам, которые вы привыкли ассоциировать с документами, данными и программами Сравним файловые системы и обсудим общие для них операции.
Файловые системы в ядре Linux: https.//VTvw.kernej.org/doc/html/latest/ftlesystems/
Заключение | 119
Основы
Прежде чем мы перейдем к предметной терминологии, давайте прольем свет на смутные догадки и ожидания.
— За редким исключением большинство современных файловых систем иерархические. Они предоставляют пользователю единое дерево файлов, которое начинается с корня (/),
— В дереве файловой системы вы обнаружите два типа объектов: каталоги и файлы. Воспринимайте каталоги как организационную единицу, позво ляющую объединять файлы в группы. Если хотите применить аналогию с деревом, то каталоги — это вегви, на которых растут и листья-файлы, и другие каталоги.
— Вы можете перемещаться по файловой системе, изучая список содержимого каталога (Is), переходя внутрь него (cd) и используя путь к текущему рабочему каталогу (pwd).
— Разрешения уже встроены. Как обсуждалось ранее в разделе «Разреше ния», один из главных атрибутов, которые использует файловая система — это владение. Доступ к файлам и каталогам обеспечивается на основе владельца и заданных разрешений.
— Обычно файловые системы реализованы в ядре.
Реализация файловых систем в ядре обусловлена производи-тельностыо, но никто не запрещает реализовывать их и в поль-уЧк	зоватеяьсксм пространстве. См. документацию проек га «Фай -
левые системы в пол ьзовательском пространстве» Filesystem i n Userspace (FUSE)19C и репозиторий проекта libfuse1’1.
Закончив с вольной трактовкой, сосредоточимся на четких определениях, которые необходимо усвоить:
Диск
Это (физическое) блочное устройство, например, жесткий диск (HDD) или твердотельный накопитель (SSD). Б условиях виртуальной машины диск можно эмулировать — например, /dev/sda (устройство SCSI) или /dev/sdb (устройство SATA) или /dev/hda (устройство IDE).
1’° Filesystems in Userspacc: https://www.kerncl.org/doc/html/latest/iilesystems/ftise.html.
1,1 libfuse: https://github.com/libftise/.
120 | Глава 5, Файловые см темы
Раздел
На диске можно логически выделить наборы секторов хранения — разделы. Если создать два раздела на вашем HDD. они будут отображаться как /dev/ sdbl и /dev/sdb2.
Том
Том (или логический диск) похож на раздел, но он более гибкий, а также отформатирован для определенной файловой системы. Мы обсудим тома в разделе «Диспетчер логических томов».
Суперблок
При форматировании файловые системы выделяют специальную начальную секцию, в которой размешается информация о файловой системе, включая тин, статус, суммарное количество блоков и inode в блоке.
Индексные дескрипторы (Иноды)
Ичода (indexnodc или inode) — это специальная структура, которая хранит информацию о файле; размер, данные о владельце, расположение, метки времени, разрешения, но не имена файлов и не данные. Их хранят каталоги — специальный подвид файлов, сопоставляющих иноды с именами файлов
Перейдем к практическому знакомству с темой. Для начала выведем информацию о дисках, разделах и томах в вашей системе:
$ Xsbtk --exclude 7 О
NAME	MAJ:MIN	RM	SIZE	RO TYPE MOUMPJINTS
sda	8:0	0	223.6G	0 disk	®
|—sdal	8:1	0	512M	0 part /boot/efi	©
*—sda2	8:2	0	223.1G	0 part	О
petenertary	-- vg-root 253:0	0	222.1G	9 ivn /
L-elenertary	vg swap_l 253:1	0	976M	0 ivm [SHAP]
О Вывести все блочные устройства, исключая псевдо- (петлевые) устройства.
в У нас есть диск с названием sda общим объемом около 223 ГБ.
® Есть два раздела; загрузочный — sdal.
О Второй раздел, sda2, содержит два тома (подробности см. «Диспетчер логических томов»).
Основы | 121
Поручив информацию о логических и физических устройствах» рассмотрим подробнее используемые файловые системы:
$ findnnt -D -t nosquashfs О
SOURCE	TSTYPE	SIZE	USED	AVAIL USEX TARGET		
udev	devtnpfs	3.8G	0	3 8G	0X	/dev
tnpfs	tnpfs	778.9M	1.6M	777.3M	f)%	/run
/dev/tapper/еlenencary--vg- root	ext4	217.6G	13.8G	192.7G	6X	/
tnpfs	tnpfs	3.8G	19.2M	3.8G	ex	/dev/shn
tnpfs	tnpfs	SM	4K	5M	ox	/run/lock
tnpfs	tnpfs	3.8G	0	3.8G	ex	/sys/fs/
						cgroup
/dev/sdal	vfat	SUM	6M	504.9M	IX	/boot/e*i
tnpfs	tnpfs	778.9M	76K	778.8M	ex	/run/
user/1000
® Вывести список файловых систем, исключив тип squashfs192 (специальная файловая система со сжатием и только для чтения, изначально созданная для CD, а сегодня используемая и для снимков состояний).
Сделаем следующий шаг и рассмотрим отдельные объекты файловой смет е-мы — каталоги или файлы:
$ stat ну file
File: nyfile
Size:0	Blocks: 0	10 Block: 4096 regular enpty file О
Device: fc01h/64513d Inode: 555036	Links:1 ©
Access: (0664/-rw-rw-r--) Uid: (1000/ nh9) Cid: (16Э1/ nh9)
Access: <021-08-29 09:26:36.638447261 30000
Modify: 2021-0829 09:26:36.638447261 +0000
Change: 2021 68 29 09:26:36.638447261 +0000
Birth: 2021-08-29 09:26:36.638447261 +0000
О Информация о типе файла.
© Информация об устройстве и иноды.
1,2 Squashfs 4.0 Filesystem; https://www.kernel.org/doc/htntVlatest/filesystems/squashfs.html.
122 j Глава 5. Файловые системы
Если использовать предыдущую команду так: stat, (обратите внимание на точку), то мы получим информацию о файле каталога, включая его иноду, количество блоков и т.д.
В таблице 5-1 я привел несколько основных команд, которые помогут вам углубиться в изученные концепции.
Таблица 5-1. Выборка низкоуровневых команд для работы с файловыми системами и блочными устройствами
Команда	Назначение
Isblk	Получение списка всех блочных устройств
fdisk, parted	Управление разделами диска
blk/d	Вывод атрибутов блочного устройства, например UUlВ
hwinfc	Вывод информации об оборудовании
file -s	Вывод информации с файловой системе и разделах
stat,df-i, Is-i	Вывод и перечисление информации об инодах
Еще одно понятие, которое встретится вам при работе с файловыми системами, — это ссылки. Иногда требуется сослаться на файл с другим именем, или предоставить для него ярлык. В Linux существуют два типа ссылок:
Жесткая ссылка
Ссылка на иноду. Жесткие ссылки недоступны для каталога и не работают между двумя файловыми системами.
Символическая ссылка, или «симлинк» (synlinks™)
Иногда называют «мягкой» ссылкой. Это специальные файлы, содержимое которых — строка, в которой предоставлен путь к другому файлу.
Давайте посмотрим, как работают ссылки (вывод частично урезан):
$ Ln rnyfile somealias О
$ Ln -s nryftle somescftalias ®
$ Ls -aL ’alias Ф
-гиги Г-- 2 nh9 mh9 0 Sep 5 12:15 sonealias
Irwxrwxrux 1 nh9 m*i9 6 Sep 5 12:45 somesoftaltas -> myfile
1,3 symlink(7): https://man7.org/linux/man-pages/man7/symlirk7.htni).
Основы | 123
$ stat somealias
File: somealias ©
Size: 0
Blocks: О
Device: fd00h/64768d Inode: 6332071
10 Block: 4096 resular empty file Links: 2
$ stat somesoftalias ©
File: somesoftalias -> nyfile
Size: 6	Blocks: 0
IC Block: 4096 synodic link
Device: fd00h/64763d Inode: 6303340 Links: 1
О Создание жесткой ссылки на myfi le.
е Создание мя гкой ссылки i ta этот же файл (обратите внимание на параметр - s)
© Показать файлы. Обратите внимание на различие типов и отображение имени. Можно было бы вызвать Is -ali *alias и убедиться, что у обоих имен, связанных жесткой ссылкой, одинаковые иноды.
О Вывести сведения о файле жесткой ссылки.
© Вывести сведения о файле мягкой ссылки.
Основная терминология ясна. Теперь узнаем, каким образом Linux позволяет обращаться к любому виду ресурсов как к файду
Виртуальная файловая система
Linux обеспечивает файловый доступ к различным типам ресурсов (в памяти, локальным, из сетевых хранилищ) через абстракцию, которую называют вирту альной файловой системой (VFS)194. Идея в гом, чтобы создать непрямую прослойку между клиентами (системные вызовы) и файловыми системами, которые работают с устройствами или другими типами ресурсов. Таким образом, VFS выступает в роли посредки ка между стандартными операциями (открытие, чтение, поиск) и их специфичными реализациями.
VTS — это абстракция на уровне ядра, которая предоставляет клиентам универсальный способ обращаться к ресурсам на основе файловой парадигмы. Файл в Linux не имеет структуры, это поток двоичных данных, и клиент сам ре шает, как его интерпретировать. VFS предоставляет абстракцию для файловых систем различных типов (рисунок 5 1).
1,4 VFS: https.//elixir.bcotlin.com/linux/v6.13.6/source/Dccumentation/fJesystems.Ms.rst.
124 | Глава 5. Файловые системы
локальные файловые системы, например ext3, XFS, FAT и NTFS
Такие файловые системы используют драйверы для доступа к локальным блочным устройствам, например HDD или SSD.
Файловые системы в памяти, например tnpfs. Не поддерживают долговременного хранения, но могут работать в оперативной памяти (RAM)
Обе категории мы рассмотрим в разделе «Обычные файлы».
Псевдофайловые системы, например procfs. Их мы обсудим в разделе «Псевдо файловые системы»
По своей природе это тоже файловые системы в памяти. Используются для обращения к ядру и абстракциями устройств.
Сетевые файловые системы, например, NFS, Samba, Netware (ранее Novell), и другие Эти файловые системы также используют драйверы, но хранилища данных подключены не локальные, а удаленные Очевидно, в этих драйверах задей ствуются сетевые операции. По этой причине мы рассмотрим их в главе 7.
Рисунок 5-1. Обзор VFS в Linux
Описать состав VFS непросто: для работы с файлами предусмотрено более ста системных вызовов. Однако можно выделить основные группы, которые я привел в таблице 5-2.
Виртуальная файловая система | 125
Таблица 5-2, Группы системных вызовов, составляющих интерфейс VFS
Категория	Примеры системных вызовов
Иноды	chnod, chown, stat
Файлы	pen, close, seek, truncate, read, write
Каталоги	chdtr, gercwd, link, unlink, renare, synlink
Файловые системы	nount, flush, chroot
Другое	map, poll, sync, flock
Одни системные вызовы перенаправляются к внешним реализациям, другим достаточно ст андартных в VFS Кроме того, специально для VFS в ядре обълвле ны структуры данных (см. inclwcte/linux/fs.h199), например;
inode
Основной объект файловой системы, хранящий данные о владельце, разре шения, ссылки, указатели на блоки с содержимым файла, статистику создания и доступа, и многое другое.
file
Объект для открытого файла (включает путь, текущую позицию и inode).
dentry (directoryentry)
Объект, представляющий каталог, хранит информацию о родителе и потомках
super_ block
Объект с данными о файловой системе, включая информацию о монтировании.
Другие объекты
Включая vfsnocnt и file_systen .type.
Теперь рассмотрим управление томами, операции с файловыми системами и их составные компоненты 195
195 fs.h source code: https;//elixjr boot'in.com/jinvx/v6.13.6/source/include/linux/fs.h.
126 | Глава 5 Файловые системы
Диспетчер логических томов
Ранее мы обсуждали разделение дисков на разделы. И хотя эго допустимо, работать с разделами сложно, особенно когда требуется изменить их размер (объем дискового пространства).
Диспетчер логических томов (LVM) вводит дополнительный слой абстракции между физическими сущностями (дисками или разделами) и файловой системой, позволяя без риска и «на лету» расширять или автоматически подстраивать обьемы хранилищ за счет объединения ресурсов. Подход LVM показан на рисунке 5-2, а в последующем комментарии разъяснены основные понятия.
Файловая система А
Т
Логический том1 +
Файловая система В
Логический том 2 _3
Группа томов 2
I руппа томов 1
Рисунок 5-2. Обзор LVM в Linux
Физические тома (PV)
Могут быть разделами, жесткими дисками целиком или другими устройствами.
Логические тома (LV)
Блочные устройства, созданные из групп томов. Сопоставимы с разделами и требуют, чтобы перед использованием на них была создана файловая система. Можно изменить их размер в процессе использования.
Груты томов (V(j)
Посредники между наборами физических и логических томов. Можно воспринимать как совокупность физических томов, совместно предоставляющих ресурсы.
Виртуальная файловая система | 127
Для управления томами через LVM196 нужен ряд инструментов, но они понятно названы и достаточно просты в использовании.
Инструменты для управления физическими томами
— Ivmdiskscan
—	pvdisplay
—	pvcreate
—	pvscan
Инструменты для управления группами томов
—	vgs
—	vgdisplay
—	vgcreate
—	vgextend
Инструменты для управления логическими томами
—	IvS
—	Ivscan
—	Ivcreate
Давайте посмотрим, как работают команды LVM в конкретном окружении:
$ sudo Ivscan О
ACTIVE	/dev/elementary-vg/root' [<222.10 CiB] inherit
ACTIVE $ sudi vgs в VC	'/dev/elcmentary-vg/swap_l' [976.00 MiB] inherit #LV #SN Attr	VSiee VFree
elementary-vg	1	2	0 wz -- n- <223.07g 16.00m
$ sudo pvdisplay ©
--- Physical volume ---
PV Name	/dev/sda2
VC Name	elenentary-vg
PV Size	<223.07 CiB / not usable 3.00 MiB
Allocatable	yes
PE Size	4.00 MiB
1,6 Manage volumes with LVM: http://wwl.unixufils.com/lvm-cheat-sheet quick-reference/Tusid =20&utid=l5T 79406494.
128 | Глава 5. Файловые сиаемы
Total PE Free PE Allocated PE PV UUTD
57105
4
57101
20rEfB-77zU-jun3 aGXOQtJH-erDP-lujfAM
О Вывести список логических томов. У нас два тома (root и зыар_1) в группе elementary-vg.
в Вывести группы томов. У нас одна — elementary-vg.
© Показать физические тома. У нас opwr./dev/sda?, он связан с группой томоь elementary-vg.
Не важно, где будет создаваться файловая система, на разделе или логическом томе. Перед ее использованием нужно выполнить еще два шага, о которых я расскажу дальше.
Операции над файловой системой
Далее вы научитесь работать с байтовой системой на разделе или логическом томе (созданном с помощью LVM). Подготовительный процесс состоит из двух шагов: сначала файловую систему нужно создать (в системах, от личных от Linux, этот шаг иногда называется форматированием), а затем монтировать, то есть встроить в общее дерево.
Создание файловой системы
Первый шаг сводится к тому, чтобы собрать вместе настройки будущей структуры и передать одним из входных параметров раздел или том. Если вы не уверены, как подготовить входные данные, изучите таблицу 5-1, а затем запустите mkfs”7 для создания файловой системы.
mkfs принимает на вход два обязательных параметра: тип файловой системы (выберите из вариантов, обсужденных л разделе «Основные модели организации файловых систем») и устройство, на котором вы хотите ее создать (например. логический том):
mkfs -t ext4 \ О
/dev/sone_vg/sofie_lv ©
© Создание файловой системы с типом ext4.
в Создание файловой системы на логическом томе /dev/some_ vg/some_ I v. 157
157 mkfs(8): https7/www,man7.org/linux/rnan-pages/man8/mkfs.8.htm!.
Виртуальная файловая система | 129
Как видите, все не так уж и сложно, главное, понимать, какой тип файловой системы вам нужен.
Файловую систему, созданную через mkfs, можно сделать доступной в дереве каталогов и файлов.
Монтирование файловой системы
Монтировать файловую систему — значит встроить ее в общее дерево каталогов и файлов (которое начинаетеч с корня в /). Для монтирования используют команду mount198, которой необходимо предоставить два обязательных параметра: присоединяемое устройство и место в дереве. Можно передать дополнительные параметры для монтирования (через -о), например, «только чтение», и привязки (через - -bind) для встраивания каталогов. К последнему параметру мы вернемся при изучении контейнеров.
Вы можете опробовать mount самостоятельно. Вот как вывести список смонтированных устройств.
$ mount -t ext4, tnpfs О
tnpfs on /run type tnpfs (rw, nosuid, noexec, relative. size=797596k, mode-755)
/dev/napper/elcnentary -- vg-root on / type ext4 (rw, relatine, errors=renount-ro) •
tnpfs on /dev/shn type tmpfs (rw, nosuid, nodev)
tnpfs on /run/lock type tnpfs (rw, nosuid, nodev, noexec, relattne, size=S120k)
tnpfs on /sys/fs/egroup type tnpfs (ro, nosuid, nodev, noexec, node-755)
О Показать список смонтированных файловых систем с фильтрацией по типу (в данном случае только ext4 и tmpfs).
® Пример: LVMVG (группа томов) /dev/napper/elementary -- vg-root (тип ext4, смонтирована к корню).
Файловая система должна монтироваться с тем же типом, с каким создавалась. Если вы хотите смонтировать SD-карту командой mount -tvfat /dev/sdX2 /media, удостоверьтесь, что она отформатирована с помощью vfat. Указав параметр -а, вы можете позволить mount перебрать все типы файловых систем и найти подходящий самостоятельно.
jnount(8): https //n’.an7.erg/linux/mar.-pages'm?n8/mount.8.html.
130 | Глава 5. Файловые системы
Учтите, что монтирование не сохранится после перезапуска системы. Чтобы сделать его постоянным, нужно использовать файл fstab (/etc/fstaby99. Вот как это делается (вывод слегка урезан, чтобы вписывался):
$ cat /etc/fstab
#	/etc/fstab: static file system informatics
№
it Use 'bikid' to print the universally unique iaentifier fcr a
it device; this may be used with UUIO= as a more robust way tc папе devices
#	that works even if disks are added and removed. See fstab(S).
a
#	<file system» <mount paint» <type> <opticns» <dump» •pass»
/dev/mapper/elementary -- vg-root / ext4 errors=reincijnt-ro 0 1
#	/boot/efi was on /dev/sdal during installation
UUID=2A11-27CO /boot/efi vfat umask=0077 0 1
/	dev/napper/elenentary -- vq swap_l none swap sw 0 0
Вы узнали, как управлять разделами, томами и файловыми системами. Теперь изучим распространенные модели организации файловых систем.
Основные модели организации файловых систем
После подключения файловой системы вы, вероятно, задумаетесь, как организовать содержимое. Вам захочется, чтобы программы, конфигурационные файлы, системные и пользовательские данные хранились упорядоченно Такая организация каталогов и файлов называется структурой файловой системы. Существует официальный стандарт иерархии файловой системы (FHS)199 200, который определяет список рекомендованных каталогов и подкаталогов вместе с их содержимым. Linux Foundation поддерживает FHS, поскольку это отличная отправная точка для организации дистрибутивов Linux.
Хотя начинание FHS всячески приветствуется, в реальности иерархия фай ловой системы зачастую диктуется конкретным дистрибутивом Linux. Я настоятельно рекомендую вам ознакомиться со структурой, принятой в вашей системе, запустив команду manhier.
Чтобы дать вам примерное представление о том, чего ожидать, в таблице 5-3 я представил список самых распространенных каталогов верхнего уровня.
199 Документация fstab на ArchLinax: htt>s;//wlki.archlinLui.org/title/Fstab.
200 FHS: Filesystem ICerarcby Standard: https:/./refspecsJinuxfoundation.org.'FHS _3.0/fhs/index.htm.
Виртуальная файловая система | 131
Таблица 5-3. Распространенные каталоги верхнего уровня
Категория Примеры системных вызовов
bin, sbin boot dev	Системные программы и команды (обычно здесь ссылки на /usr/btn и /usr/sbin) Образы ядра и сопутствующие компоненты Устройства (терминалы, диску и т. д.)
etc home lib mat, media opt proc, sys tmp usr	Файлы кон4 игурацик системы Домашние каталоги пользователей Общесистемные библиотеки Точки монтирования для сменных носителей (например, USB флешек) Зависит от дистрибутива; межет размещать файлы менеджера пакетов Интерфейсы ядра (см. «Псевдофайловые системы») Каталог для временных файлов Программы пользователя (обычно только для чтении)
var	Пре । раммы пользователя (логи, резе рвные коп ни, сетевые кэши и г. д.)
Теперь давайте рассмотрим специфичные виды файловых систем.
Псевдофайловые системы
Файловые системы — отличный способ организовать удобный доступ к информации. Вы наверняка уже усвоили девиз Linux «все есть файл». В разделе «Виртуальная файловая система» мы рассматривали единый файловый интерфейс, который Linux предоставляет через VFS. Теперь посмотрим на случаи, когда за реализацией VFS скрывается не блочное устройство, как SD или SSD-нако-питель, а совершенно иное.
Встречайте псевдофайловые системы. Они лишь притворяются файловыми, чтобы мы могли взаимодействовать с ними привычным образом (Is, cd, cet), но скрывают под собой обертку для некого интерфейса ядра. Интерфейс может быть каким угодно, включая следующие:
—	Информация о процессах.
—	Взаимодействие с устройствами, например, с клавиатурой.
—	Утилиты, например специальные устройства, которые используются в качестве источников или приемников данных.
Рассмотрим три основные псевдофайловые системы Linux. Начнем с самой старой.
132 | Глава 5. Файловые системы
procfs
Linux унаследовал файловую систему /р*-ос (proems)201 от UNIX, Изначально с ее помощью предполагалось передавать из ядра информацию о процессах; чтобы сделать ее пригодной для таких системных команд, как os или free. В ней нет почти никаких требований к структуре, разрешен доступ на чтение и запись, и со временем в нее добавили еще много всего, но в общем случае вы встретите два типа информации.
— Информация по каждому процессу через /ргос/РТО/. Информацию о про цессах ядро предоставляет через каталоги с именами, совпадающими с PID процессов. Подробнее смотрите в таблице 5-4.
— Другая информация, например, сведения о монтировании, сетевая информация, драйверы TTY, информация о памяти, версия системы и время без отказной работы.
Вы может е вытащить информацию по каждому процессу, используя cat или похожие команды. Скорее всего, у вас будет доступ только на чтение (возмож ность записи диктуется ресурсом). См. таблицу 5-4.
Таблица 5-4. Информация в procfs по каждому процессу (наиболее значимая)
Входная точка	Тип	Объяснение	J
attr	Каталог	Атрибуты безопасности
egroup	Файл	Контрольные группы
ста line	Файл	Командная строка
cwd	Ссылка	Текущий рабочий каталог
environ	Файл	Перемени ые окружения
exe	Ссылка	Исполняемый файл процесса
fd	Каталог	Дескрипторы файлов
io	Файл	Хранилище 1/0 (байты/символы, прочитанные и записанные)
limits	Файл	Ограни нения для ресурсов
men	Файл	Используемая память
mounts	Файл	Текущие монтирования
net	Каталог	Сетевая статистика
stat	Файл	Сга*ус процесса
syscall	Файл	Использование системных вызовов
task	Каталог	Информация о каждой задаче (потоке)
timers	Файл	Таймеры
attr	Каталог	Атрибуты безопасности
201 The /proc Filesystem: https://www.kernel.org/doc/iitml/latest/filesystenis/proc.btml.
Г севдофайловые системы | 133
Для практики проверим статус процесса Вместо stat мы будем использовать status, вывод понятен человеку;
$ cat /ргос/self/status | head -10 О Nane: cat Unask: 0СО2
State: R (running) ©
Tgid: 12011
Ngid: 0 Pid: 12011 © PPid: 3421 ©
TracerPtd: 0
Uid: LOE© 1000 1000 1090
Cid: 1000 1600 10O6 1060
О Получить статус процесса для запрошенной команды и отобразить первые 10 строк,
© Текущее состояние (работает, использует ЦП).
© PID текущего процесса.
в Идентификатор родительского процесса (процесса команды). В данном еду чае — оболочка, где я выполнил cat.
Вот другой пример использования procfs, на этот раз для сбора сетевой информации:
$ cat/pror/self/net/arp
IP address	HW type	Flags	HU address	Mask	Device
192.168.178.1	0x1	0x2	3c:a6:2f:8e:66:b3	*	wlplsC
192.168.178.37	0X1	0x2	dc:54:d7:ef:99:9e	*	wlplsO
Как вы видите, ARP информацию о текущем процессе мы получаем из специального файла /ргос/self/net/arp.
С procfs крайне удобно заниматься низкоуровневой отладкой202 или разработкой системных инструментов. Он довольно путаный, поэтому держите под рукой документацию ядра, а лучше исходный код, чтобы понять, за что отвечает каждый файл и как вытащить полезную информацию.
202 low-level debugging: https:,'/tanelpodercom/2013/02/2’/peeking-into-linux-kernel-land-using-proc-filesystem- for-quickndirty Troubleshooting/.
134 | Глава 5. Файловые системы
Давайте рассмотрим другой, более современный и упорядоченный способ получить информацию из ядра.
sysfs
Если procfs — это в каком-то смысле Дикий Запад, то файловая система /sys20’ (sysfs) — это присущий только Linux способ по предоставлению информации из ядра (например, устройства) в стандартней структуре.
Вот каталоги в sysfs:
block/
Содержит символические ссылки на обнаруженные блочные устройства.
bus/
В этом каталоге вы обнаружите подкаталоги для каждого типа физической шины, поддерживаемого в ядре.
class/
Содержит классы устройств.
dev/
Содержит два подкаталога для устройств в системе (block/ для блочных, char/ едя символьных), структурированных по ma jor - ID: mirror - ID.
devices/
Через этот каталог ядро предоставляет доступ к дереву устройств.
firmware/
Интерфейс взаимодействия с атрибутами прошивки.
fs/
Содержит подкаталоги для некоторых файловых систем.
module/
Содержит подкаталоги для каждою модуля, загруженного в ядро. 203
203 sysfs(5). https://man7.Org/ltoux/man-pages/man5/sysfs.5.html.
Псевдофайл оеые сипемы | 135
В sysfs больше подкаталогов, но некоторые новые и/или плохо документированы. Определенная информация из sysfs доступна и в procfs, а другую (например, информацию о памяти) можно получить только в p^ocfs.
Взглянем на sysfs в действии (вывод урезан, чтобы влезал);
$ Is -al /sys/block/sda/ | head -7 ® total 0
drwxr-xr-x 11	root	root	0	Sep	7	11:49.
drwxr-xr-x 3	root	root	0	Sep	7	11:49 ..
-	Г--Г--Г-- 1	root	root	4096	Sep	8	16:22 alignment,offset
Irwxrwxrwx	1	root	root	0	Sep	7	11:51	bdt ->	/virtual/bdi/8:t*	8
-	Г--Г--Г--	1	root	root	4095	Sep	8	16:22	capability	Ф
-	Г--Г--Г--	1	root	root	4096	Sep	7	11:49	dev О
О Вывести информацию с	блочном устройстве sda	(только первые семь строк)
8 Ссылка backing_dev_inft в формате MAJOR: MINOR.
® Отображает возможности234 устройства — например, является ли оно съемным. ® Содержит старший (major) и младший (minor) номер устройства (8:0). В справочнике по драйверам блоч: i ых уст ройств204 205 мож1 ю уз нать, что они означают.
Следующие в нашем кратком обзоре псевдофайлозых систем — устройства.
devfs
В файловой системе /dev206 (devfs) содержатся специальные файлы, которые представляют весь спектр устройств: от физических до генератора случайных чисел или приемника данных, открытого только на запись.
Устройства, доступные и управляемые через devfs:
Блочные устройства
Обрабатывают данных в блоках — например, устройства хранения (диски).
Симе олы ше устройства
Обрабатывают данные посимвольно — например, терминал, клавиатура или мышь.
204 Возможности ядра: https.//www.kernel.org/doc/html/next/block/capability.html.
205 Block Device Drivers: https://linux-kernel-laos.github.io/refs/heads/master/’.abs/block_device_ diivers.htrrJ.
206 /dev (devfs): https://! Idp.org'LDP/Linux-Fi'.esystem-Hierarcliy/html/dev.html.
136 | Глаьа 5. Файловые системы
Специальные. устройства
Генерируют данные или допускают манипуляции с ними — например, знаменитые /dev/null или /dev/random.
Посмотрим на devfs в действии. Предположим, что вам нужна случайная строка.
Вы можете выполнить такую команду:
tr -de A-Za-zO-9 < /dev/urandom | head -с 42
Предыдущая команда генерирует случайную последовательность из 42 символов, среди которых заглавные и строчные буквы, а также числа. И, хотя /dev/ urundon выглядит и может использоваться как файл, это на самом деле специальный файл, который на основе ряда источников генерирует (более или менее) случайный вывод.
А что вы думаете о такой команде?
Echo "какая-"io ерундистика" > /dev/tty
Верно! Строка «какая то ерундистика» появилась па вашем дисплее, как и задумано. /dev/tty представляет терминал, и с помощью этой команды мы отправили ему какую-то ерундистику (в буквальном смысле).
Получив неплохое представление о файловых системах и их возможностях, обратим внимание на файловые системы, которые можно использовать для управления обычными файлами, — например, документами и данными.
Обычные файлы
В этом разделе мы рассмотрим обычные файлы и файловые системы207 для них. В категорию обычных попадают большинство файлов, с которыми мы имеем дело в повседневной работе: офисные докумен ты, файлы конфигурации (YAML и ’SON), изображения (PNG, JPEG и т. д.), исходный код, текстовые заметки, и т. д.
Linux предоставляет богатый выбор. Мы поговорим о локальных файловых системах — как естественных для Linux, так и пришедших из других операционных систем (Windows/DOS), но, тем не менее, поддерживающихся. Сначала рассмогрим обычные.
207 filesystems(5): https://www.mcn7.org/Iir.ux/man-pages/man5/file.<!ystems.5.html.
Обычные файлы | 137
Обычные файловые системы
Понятие «обычная файловая система» не имеет четкого определения, это обо бщение для любых файловых систем, которые либо по умолчанию используются в различных дистрибутивах Linux, либо известны, потому что нашли приме нение в устройствах хранения данных — с ъемных носителях (USB-накопители и SD-карты) или устройствах только для чтения, таких как CD и DVD
В таблице 5-5 я привел сравнительный обзор нескольких обычных файловых систем, которые поддерживаются ядром. Некоторые из самых популярных мы чуть позже рассмотрим подробнее.
Таблица 5-5. Обычные, файловые системы для обычных файлов
Файловая система	Поддерживается в Linux	Размер файла	Объем тома	Количество файлов	Длина имени
ext2	1993	2 ТБ	32 ТБ	1018	255 символов
ext3	2001	2 ТБ	32 ТБ	беременное	255 символов
ext4	2008	16ТБ	1ЭБ	4 млрд	255 символов
btrfs	?009	16Э5	16 ЗБ	218	255 символов
XFS	2001	8ЭБ	8ЭБ	264	255 символов
ZES	2006	16ЭБ	2128 байт	1014 файлов на каталог	255 символов
NTFS	1997	16ТБ	256 ТБ	232	255 символов
vfat	1995	2 ГБ	—	216 на каталог	255 символов
Информация в таблице дает лишь приблизительное представ ление о файловых системах. Иногда сложно определить дату, когда поддержка файловой системы была официально включена в Linux, а иногда даты имеют смысл только в рамках определенных условностей — например, есть разница между теоретическими границами и реализацией.
А теперь давайте подробно остановимся на распространенных файловых системах для обычных файлов:
ext4208
Очень популярная файловая система, которая сегодня используется во многих дистрибутивах по умолчанию. Это эволюция ext3 с обратной
’°’ ext4 (ArchLinux): https://wiki.arch]inux.org/title/Ext4.
138 | Глава 5. Файловые системы
совместимостью. Как и cxt3, она предлагает журналирование — ведется лог изменений, и при форс-мажорах (отключили свет) все легко восстанавливается. См. руководство по ext4209.
XFS210 211
Файловая система с поддержкой журналов, которую в начале 1990-х годов разработала для своих рабочих станций Silicon Graphics (SGI). Она предлагает поддержку больших файлов и высокоскоростного I/O, и в паши дни используется, например, в семействе дистрибутивов Red Hat.
ZFS2n
ZFS разработана Sun Microsystems в 2001 году. Она объединяет функцио нальность файловой системы и менеджера томов. Хотя существует проект OpenZFS212, который развивается в рамках открытого исходного кода, есть некоторые спасения по поводу ее интеграции с Linux213 214.
FAT2'4
Эго действительно семейство файловых систем FAT для Linux, причем чаще всего используется vfat. Основная цель использования — взаимодействие с системами Windows и сменными носителями с FAT. Многие встроенные возможности к томам FAT не применимы.
Диски не единсгвенное место для хранения данных. Давайте рассмотрим варианты хранения в оперативной памяти.
In memory файловые системы
Существует множество файловых систем, хранящихся в памяти, от универсальных до очень специфических. Ниже перечислены самые распространенные (в алфавитном порядке),
204 ext4(5): https://www.man7.Org/linini/man-pages/nian5/exi4.5.html.
210 XFS (ArchLinux): https;//wiki.archlinux.org/title/XFS.
211 ZFS: https://enwikjpedia.org/wiki/ZFS.
212 Open-ZFS: https;//openzfs.github io/open?,fs-docs/.
213 ZFS for Linux: https://www.linuxjcurnal.com/content/zfs-linux.
214 FAT filesystem and Linux: https://en.wikipedia.org/wiki/FAT_filesysteni_and_LiTiux.
Обычные файлы | 139
debuyfs215 216
Специальная файловая система, используемая для отладки. Монтируется обычно так; mount -tdebugfsnone /sys/kernel/debug.
loopfs™
Позволяет представить файловую систему в блоках, а не устройствах. Загля ните при случае в посвященную ей почтовую ветку217.
pipefs
Специальная (псевдо)файловая система, смонтированная на pipe:, которая позволяет использовать конвейеры.
sockfs
Еше одна специальная (псевдо) файловая система заставляет сетевые сокеты выглядеть как файлы, встраиваясь между системными вызовами и сокетами218 *.
swapfsw
Используется для реализации подкачки (не монтируется).
tnpfs220
Файловая система общего назначения хранит файловые данные в кэшах ядра, быстрая, но нестойкая (при отключении питания данные потеряются)
Давайте рассмотрим специальную категорию файловых систем, особенно интересных в рамках темы «Контейнеров».
Файловые системы с поддержкой копирования при записи
Копирование при записи (copy-on-write, или СоК), это изящная концепция для увеличения скорости I/O с одновременным уменьшением используемого места. Как она работает, показано на рисунке 5-3 с последующим разъяснением.
215 debt.gfs: https.//www.kerneLorg/doc/html/iaiest/filesystems/dehugfs.html.
216 loopfs(4): https://man7.org/liiiux/man-pages/man4/loop 4.btml.
217 loopfs mailtbread: https://lkml.Org/lknu/2020/4/8/506.
218 sockct(3): https://linuxdic.net/nran/3/socket.
215 SWAPFS file system: https://linux.die.net/EVMSUl3/x3e63.html.
22C tmpfs: https://www.kernel.org/doc/html/latest/filesystems/tmpfs.html.
140 j Глава 5 . Файловые системы
Рисунок 5-3. Принцип CoW в действии
1. Исходный файл с именем Файл 1, состоящий из блоков А, В и С, копируется в файл с именем Файл 2. Вместо самих блоков копируются только метаданные (указатели на блоки). Это работает очень быстро и не требует много места, поскольку создаюгся только метаданные.
2. Когда изменяется Файл 2 — скажем, при изменениях в блоке С, — тогда, и только тогда, копируется весь блок С. Создается новый блок С', и, хотя Файл 2 по-прежнему обращается к неизмененным блокам А и В, теперь он использует блок С для хранения новых данных.
11ерсд тем как мы перейдем к рассмотрению реализаций, нужно осознать вторую концепцию в свете такой идеи, как объединенное монтирование221. Ее суть в том, что вы можете совмест ить (смонтироват ь) несколько каталогов в одну точ ку монтирования, а пользователю будет казаться, что полученный каталог содержит совмещенное содержимое (или объединение) из всех этих каталогов. При гаком подходе вы часто будете сталкиваться с понятиями «верхняя файловая система» и «нижняя файловая система», которые намекают на порядок монтирования. Вы найдете подробное объяснение в статье «Объединение файловых систем при объединенном монтировании».222
Однако дьявол кроется в деталях реализации такого объединения. Вам нужно придумывать поведение для случаев, когда один файл существует в разных местах, а также свои правила для записи или удаления файлов.
Рассмотрим несколько реализаций CoW для файловых систем Linux. К некоторым мы вернемся в главе 6, где подробнее обсудим их применение в качестве строительных блоков при создании контейнерных образов.
221 union mount: https://en.wikipedia.org/wiki/Union_moant.
222 «Unifying filesystems with union mounts»: https://lwn.net/Aitides/312641/.
Обычные файлы | 141
Unionfs223
Unionfs, разработанная в университете Стоуни-Брук, реализует объединенное монтирование для файловых систем с CoW Эта реализация позволяет прозрачно смешивать файлы и каталоги из разных файловых систем, используя приоритеты во время монтирования. Эта файловая система была популярна и часто использовалась для CD-ROM и DVD.
OverlayFS224
Эта реализация файловой системы с объединенным монтированием для Linux представлена в 2009 году, а в 2014 году добавлена в ядро. С OveilayFS после открытия файла все операции напрямую обрабатываются совмещенными (нижними или верхними) файловыми системами.
AUFS225 226
AUFS — расширенная многослойная объединенная файловая система (изначально AnotherllfnonFS) — еще одна попытка реализовать объединенное монтирование в ядре, но пока в него не включенная. Раньше использовалась как реализация по умолчанию в Docker (см. «Docker»), но в настоящее время Docker перешел на OverlayFS с драйвером хранилища overlay?.
btrfs22b
btrfs (сокращение от b-tree, произносится как «баттер-эф-эс» или «бет-тер-эф-эс») — это CoW, изначально разработанная корпорацией Oracle. Се годня свой вклад в ее развитие вносят Intel, SUSE, Red Hat и ряд других раз-
работчиков.
Опа поставляется с рядом дополнительных функций, включая моментальные снимки для программного RAID и автоматическую фиксацию скрытых ошибок в данных, что делает btrfs очень привлекательной для профессиональных сред, например, на серверах.
223 «Unionfs: A Stackable Unification File System»: https://unionfs.filesystems.org/.
224 «Overlay Filesystem»: https://www.kernel.org/doc/htrnl/latest/filesystems/overlayfs.html.
223 AUFS (advanced multilayered unification filesystem, originally AnotherUnionFS): https: //en.wikipedia.org/wiki/Aufs.
226 btrfs: https://archive.kernel.org/oldwi.kVbtrfs.wiki.kernel.org/index.php/Main_Page.lTtml.
142 | Глава 5 Файловые системы
Заключение
В этой главе обсуждались файлы и файловые системы в Linux. Файловые системы — удобный и гибкий способ организовать доступ к информации, представленной иерархически. В Linux много технологий и проектов, связанных с фай ловыми системами. Среди них есть и коммерческие, и с открытым исходным кодом.
Мы обсудили основные строительные,компоненты, от дисков до разделов и томов, а также узнали, что Linux реализует абстракцию «все есть файл» с помощью VFS, поддерживая как локальные, так и удаленные файловые системы практически любых видов.
С помощью псевдофайлозых систем в памяти, таких как /ргос и Ays, ядро предоставляет доступ к своему API, и отдает информацию о процессах или устройствах. Взаимодействовать с ними можно так же, как и с обычными файловыми системами для хранения файлов (например, ext4).
Затем мы рассмотрели обычные файлы и файловые системы и сравнили ба зовые параметры локальных файловых систем, а также изучили основы файловых систем в памяти и CoW. Всесторонняя поддержка в Linux позволяет ..ам использовать (как минимум для чтения) множество файловых систем, включая те, что пришли, к примеру, из Windows.
Вы можете глубже погрузиться в темы, затронутые в этой главе, если воспользуетесь следующими рес урсами:
Основы
—	«Файловые системы UNIX: как UNIX организует и получает доступ к файлам на диске»227 228 229 *.
—	«КНВ. Список литературы по файловым системам»226.
VPS
—	«Обзор виртуальной файловой системы Linux»22’.
—	«Введение в виртуальную файловую систему Linux (VFS)»2JC.
227 UNIX File Systems: How UNIX Organizes and Accesses Files on Disk: https://www.oakton.edu/ user/2/rjtaylor/CTS228'Slide/UKIX%20File%20Systems%202.pdf
228 KHB: A Filesystems reading list: https://lwn.net/Anicles/196292/.
229 Overview of the Linux Virtu al File Sys tern: https:// www.kernel org/doc/html/latest/filesystems/ vfs.htmi.
2M Introduction to the Linux Virtual Filesystem (VFS): https://www.starlab.io/blog/introducuon-to-the-linux-virtual-filesystem-vfs-part-i-a-high-level-tour.
Зак/юление | 143
—	«1УМ» на ArchWiki231.
—	«LVM2 Resource Page»232.
—	«Как использовать графический интерфейс инструментария LVM»233.
—	«Иерархия файловой системы Linux»234.
—	«Устойчивые объекты BPF»235.
Обычные фийлы
—	«Эффективность файловой системы — сравнение ЕХТ4, XFS, BTRFS и ZFS» на Reddit236.
—	«Тесты производительности файловой системы Linux»237.
—	«Сравнение файловых систем для SSD» на Linux.org"8.
—	«Kerne) Kerner — Unionfs: давайте объединим файловые системы»239.
—	«Начало работы с btrfs для Linux»240.
Добавив в копилку знания о файловых системах, вы готовы научиться управлять приложениями и запускать их.
231 LVM on Arch Wiki: https.7/wiki.archlinux.org/title/LVM.
232 LVM2 Resource Page: https:,7sourceware.org/lvm2/.
233 How To Use GUI LVM Tools: https://www.linuxjournal.conVcontent/review-gui-lvm-::ools.
234 Linux Filesystem Hierarchy https:7tldn.org/LDP/Llmix Filesystem Hierarchy/Linux Filesystem Hierarchy pdf.
235 Persistent BPF objects: https://lvm.net/Articles/664688/.
236 Filesystem Efficiency — Comparision of EXT4, XFS, BTRFS, and ZFS: https://www.reddit. com/r/DataHoarder/comments/f5uzv8/filesystem_effictancy_comparision_of_ext4_xfs/.
237 Linux Filesystem Performance Tests»: https://www.linux-magazine.com/Online/FeatiLres/ Filesystems-Bench marked
238 Comparison of File Systems for an SSD: https://www.linux.org/threads/comparison-of-file-systems-for-ar -ssd.28780/.
239 Kernel Kornet — Unionfs: Bringing Filesystems Together: https://www.linuxjournal.com/ article/77T4
240 Getting started with btrfs for Linux: https://opensource.eom/artide/20/l 1/btrfs-linux.
ГЛАВА 6
Приложения, управление пакетами и контейнеры
В этой главе мы поговорим о приложениях в Linux. Под словом «приложение» (часто встречается сокращение арр, от аррlication) можно подразу мевать и программы, и двоичные файлы, и исполняемый файл. В самом начале мы проясним различия и определим значения основных понятий, включая «приложение» и «пакет».
Мы обсудим, как запускается сам Linux и как запускает службы (эта последовательность действий называется процессом загрузки), а также уделим внимание системам инициализации, в особенности экосистеме, которая стала стандартом — systemd
Затем рассмотрим системы управления пакетами (менеджеры пакетов), начав с общих понятий о цепочке поставок приложений и их основных компонентов. Мы вспомним, как изначально распространялись и устанавливались приложения, чтобы лучше понимать современные механизмы и их проблемы. Сравним менеджеры пакетов в традиционных дистрибутивах Linux, от Red Hat до систем на базе Debian, затронув управление пакетами для отдельных языков програм ммрования, таких как Python или Rust.
В следующей части главы вы узнаете, что такое контейнеры и как они работают. Мы рассмотрим составные части, доступный инструментарий и оптимальные практики контейнеризации.
В конце я расскажу о современных способах управления приложениями, в том числе и в графической среде Linux. Большинство современных решений по управлению пакетами так или иначе используют контейнеры.
РАБОЧИЙ ПРИМЕР: GREETER
Для демонстрации обсуждаемых технологий я подготовил рабочий пример, который назвал greeter. Это простой скрипт, который выводит на экран сообщение с переданным именем или значение, заданное по умолчанию.
Заключение | 145
Если собираетесь повторять за мной, самое время вставить код bash скрипта в файл с именем greeter.sh и командой chmod 750 greeter. sh назначить его исполняемым. (Если вы подзабыли, зачем, то обратитесь к разделу «Разрешения файлов»):
#! /usr/btn/envbash
set -о errexit
set-о errtrace
set-о pipefail
nane="${l}"
if [-z Чпапе"]
then
printf "Вы великолепны!\n"
else
printf "Здравствуйте %s, вы великолепны!\n'' ${nane) fi
Итак, не откладывая в долгий ящик, проясним, что же такое приложение и какие понятия ему сопутствуют.
Основы
Прежде чем углубиться в нюансы управления приложениями, систему инициализации и контейнеры, давайте определим основные понятия этой главы. Мы занялись темой приложений только сейчас, потому что без знаний о ядре Linux, оболочке, файловых системах и аспектах безопасности нельзя в полной мере понять их работу. Теперь же мы приступаем:
Программа
Двоичный файл или скрипт, который Linux может загрузить в память и выполнить. Иными словами — исполняемый файл. От типа файла зависит, какой инструментарий будет отвечать за его выполнение: к примеру, интерпретацией и выполнением скрипта займется оболочка (см. «Оболочки»).
146 | Глава 6. Приложения, управление пакетами и контейнеры
Процесс
Исполняемая сущность, основанная на программе, которая загружена в память, и использует ЦП или I/O, если не находится d спящем состоянии. Загляните в «Управление процессами» и в главу 3.
Декон
Особый доковый процесс (иногда е^о называют службой), который предоставляет определенную функцию другим процессам. К примеру, демон печати позволяет вам распечатывать документы. Существуют демоны для вебсервисов, журналов, времени и других утилит, которыми вы пользуетесь ежедневно.
Приложение
Программа со своими зависимостями, обычно достаточно комплексная и с пользовательским интерфейсом. В понятие «приложение» часто укладывается и настройка программы, и работа с данными, и весь цикл от ее поиска и установки до обновления и удаления.
Пакет
Файл (архив) с программами и настройками. Используется для распространения программных приложений.
Менеджер пакетов
Программа для работы с пакетами, которая, в зависимости от указаний пользователя, устанавливает, обновляет или удаляет пакеты из окружения Linux.
Цепочка поставки
Коллекция производителей и поставщиков программного обеспечения, в которой вы можете найти подходящие приложения, собранные з пакеты (см. «Цепочки поставок приложений в Linux»).
Загрузка
Последовательность шагов с инициализацией оборудования, операционной системы, загрузкой ядра и запуском сервисов (демонов), чтобы привести Linux в состояние готовности к использованию (см. «Процесс загрузки в Linux»).
С багажом этих знаний мы буквально загружаемся заново. Давайте посмотрим, как Linux запускается сам и запускает демоны, необходимые для работы.
Основы | 147
Процесс загрузки в Linux
Загрузка в Linux — это многоступенчатый процесс, в котором оборудование и ядро начинают работать сообща.
На рисунке 6-1 показан полный процесс загрузки, разбитый на пять этапов.
Рисунок 6-1. Процесс загрузки Linux
1.	В современных средах конфигурация загрузки (с хранением в NVRAM) и сам загрузчик определяются так называемым унифицированным расши ряемым микропрограммным интерфейсом (UEFI). В старых средах на начальном этапе запускалась самодиагностика (POST), а затем базовая система ввода/вывода (BIOS) (см. «BIOS и UEFI») инициализировала оборудование, включая I/O порты и прерывания, и передавала управление загрузчику.
2.	Главная задача загрузчика — загрузить ядро. Процедура слегка различается в зависимости от носителя. Выбор загрузчиков большой, есть современные (GRUB 2, systemd boot, SYSL1NUX, rEFInd, и пр.) и уже устаревшие (L1LO или GRUB 1).
3.	Ядро в сжагом виде обычно хранится в каталоге /boot Сначала оно распаковывается и загружается в основную память. Затем после инициализации его подсистем, файловых систем и драйверов (как обсуждалось в тлаве 2 и в разделе «Монтирование файловой системы») ядро передает управление системе инициализации, на чем процесс загрузки можно считать успешно завершенным.
4.	Система инициализации о гвсчает за запуск общесистемных служб (демонов). Процесс init (с PID равным 1) — это корень иерархии всех процес сов, он не прекращает работу, пока машина не будет выключена. Помимо прочего, процесс с PID 1 традиционно отвечает за отслеживание «сирот» — процессов, у которых утеряна связь с родительским процессом.
143 | Глава 6. Приложен ия, управление пакетами и контейнеры
5.	Этот этап отвечает за инициализации на уровне пользовательского про странства;
—	В большинстве случаев инициализируются терминал, окружение и оболочка, как обсуждалось в главе 3.
—	В соответствии с настройками и предпочтениями пользователя запускаются экранный менеджер, графический сервер, в общем, рабочий стол с графическим интерфейсом.
Обзором запуска Linux мы завершаем вводную часть и переходим к важнейшему для пользователя компоненту: системе инициализации Знания, которые вы получите дальше (с пониманием 4 и 5 этапа загрузки), едва ли не самые полезные в книге, они позволят вам настраивать и расширять ваш Linux.
Отличный сравнительный анализ систем инициализации241 вы найдете в Gentoo wiki, мы же сосредоточимся на systemd, который сегодня используется в большинстве дистрибутивов Linux.
SYSTEM VINIT
Программы инициализации в стиле SystemV242 (сокращенно SysVinit) раньше были основной системой инициализации в Linux. Эта система, унаследованная от Unix, определяла некие уровни запуска (воспринимайте их, как состояния системы — остановка, однопользовательский режим, многопользовательский или графический режим) и хранила конфигурацию в /etc/init.d. Однако из-за последовательности запуска демонов и специфичной для дистрибутивов конфигурации этот вариант был не слишком переносимым.
Забавный факт: первым в 1984 году SisVinit задокументировал Крис, один из рецензентов этой книги (говорят, саму программу разработали за выходные).
Systemd
Изначально systemd243 была системой инициализации, заменившей tnttd, но со временем развилась в мощный супервизор с функционалом журналирования,
241 Comparison of init systems (Centoo wiki) https:,7wiki.gentoo,org/wikl/Comparison_of_init_ systems.
242 System V style init programs- https://savannah.nongnu.org/proiects/sysvinit
243 systemd: https://systemd.io/.
Systemd | 149
сетевыми настройками, синхронизации времени через интернет, гибко наст ра-иваемым и переносимым механизмом определения демонов с их зависимостями и единым интерфейсом для управления конфигурацией.
Сегодня systefnd используется почти во всех заметных дистрибутивах Linux, включая Fedora (с мая 2011 года), openSUSE (с сентября 2012 года), CentOS (с апреля 2014 года), RHEL (с июня 2014 года), SUSE Linux (с октября 2014 года), Debian (с апреля 2015 года) и Ubuntu (с апреля 2015 года).
Кроме прочего, systemd устраняет недостатки старых систем инициализации:
—	Предоставляет дистрибутивам единый способ управления запуском.
—	Реализует более быструю и с более разумную настройку служб.
—	Предлагает современный пакет управления с поддержкой мониторинга, контроля над использованием ресурсов (через egroups) и встроенным аудитом.
В то время как init запускает службы последовательно (в алфавитно-цифровом порядке), systemd может запустить любую службу сразу же после того, как определились ее зависимости. Эго потенциально уменьшает время запуска.
Чтобы сообщить system когда, что и как запускать, используются модули.
Модули
Модуль в systemd — это логическая группа наст роек, состав которой продиктован функционалом и назначением. В зависимости от ресурсов, для которых предназначен модуль, различают следующие типы:
модули служб (service units)
В них описываются настройки для служб или приложения.
целевь/е модули (target units)
Определяют зависимости.
модули монтирования (mount units)
Определяют точки монтирования.
модули таймеров (finer units)
Определяют настройки таймеров для заданий сгоп и т. п.
15С | Глава б. Приложения, управление пакетами и контейнеры
Другие, менее зажиме модули:
socket
Описывают сетевые сокеты и сокеты IPC.
device
Предназначены для файловых систем udev или sysfs.
autonount
Настраиваю! автоматическое монтирование.
SHOP
Определяют пространство подкачки.
path
Для активации на основе пути.
snapshot
Позволяют восстановить состояние системы после изменений.
slice
Связаны с cgrocps (см. «Контрольные группы Linux»)
scope
Управляет наборами системных процессов, созданных извне.
Чтобы system обнаружила и учла модуль, он должен быть выгружен в файл, systemd ищет файлы модулей в нескольких расположениях. Вот три наиболее важных пути:
/lib/syste'nd/system
Модули, установленные из пакетов.
/etc/systcmd/system
Модули, настроенные системным администратором.
/run/systemd/system
Временные динамические изменения.
Systemd | 151
Определив основную рабочую единицу systend (модуль), перейдем к управлению системой инициализации из командной «роки.
Управление с помощью systemctl
systenctl244 245 — это утилита для взаимодействия с systend, через которую настраиваются службы.
В таблице 6-1 я привел список часто используемых команд systemctl.
Таблица 6-1. Полезные команды для systemd
Команда	Использование
systenctl enable XXXXX.service	Включает службу; она готова к запуску
systenctl oaenon-reload	Перезагружает все файлы модулей и перестраивает дерево
	зависимостей
systenctl start XXXXX.service	Запускает службу
systenctl stop XXXXX.service	Останавливает службу
systenctl restart XXXXX.service	Останавливает и снова запускает службу
systenctl reloao XXXXX.service	Посылает службе команду на перезагрузку reload, и в случае
	неудачи restart
systenctl kill XXXXX.service	Останавливает выполнение службы
systenctl status XXXXX.service	Запрашивает краткую статистику работы службы, включая
несколько строк из лога
Учтите, что в systenctl гораздо больше команд: для управления зависимостями, опросов и даже контроля всей системы (например, перезагрузки).
В экосистему systend входят и другие полезные утилиты, о которых стоит знать. Вог краткий список:
bootctlM
Позволяет запрашивать статус загрузчика и управлять доступными загруз чиками.
timedatectl
Позволяет просматривать и настраивать дату и время246.
244 systemctl(l): bttps:;/man7.org/lirux/man-pages/manl/systeinctl. l.html.
245 bootctl(l): https://mar.7.org/Enux'man-pages/manl/boolc:l.l.html
246 Control your computer time and date with system: https://'opensource.com/an:de/20/6/time-d ate-systemd.
152 | Глава 6. Приложения, управление пакетами и контейнеры
coredumpctl
Позволяет обрабатывать сохраненные дампы ядра. Этот инструмент пригодится при устранении неполадок.
Мониторинг с помощью journalctl
Журнал — это компонент systemd (технически — двоичный файл, управляемый демоном systemd-journald), который обеспечивает централизованный сбор сообщений от других компонентов systemd. Мы подробно рассмотрим его в «jcurnalcti»; пока важно только то, что это инструмент для просмотра логов systend.
Пример: планирование запуска greeter
После теории предлагаю немного попрактиковаться с systemd. Допустим, мы хотим запускать наше приложение greeter (см. «Рабочий пример, greeter») каждый час.
Сначала создадим для systemd файл модуля с типом service (служба), а затем укажем systemd, как следует запускать наше приложение. Сохраните следующий код в файле greeter, service (в любом каталоге, файл временный):
[Unit]
Description=Moa служба приветствия О
[Se-vi.ce]
Type-oneshot
ExecStart=/home/mh9/greeter.sh ©
О Описание службы, которую мы увидим при запросе systemctlstatus.
® Путь к нашему приложению.
Теперь создадим модуль таймера247, настроенный на запуск службы greeter каждый час. Сохраните следующий код в файле с именем greeter, timer-.
[Unit]
Description=3anyci< службы приветствия в начале каждого часа
и’ systemd/Timers: https://wiki.archlinux.org/title/Systemd/Timers.
Systemd | 153
[Timer]
OnCalendar=hourly О
О Определяет расписание с форматом времени и даты2 *3, принятым для systema.
Теперь скопируем оба файла с модулями в /гип/systemd/system, чтобы их распознала systemd-
$ sudo Is -al /гип/systemd/system/
total 8
drwxr-xr-x	2	root	root	80	Sep	12	13:68.
drwxr-xr-x	21	root	root	590	Sep	12	13:69	..
rw-r--r--	1	root	root	117	Sep	12	13:68	greeter.service
-rw-r--r--	1	-oot	root	107	Sep	12	13:98	greeter.timer
Все расписание для greeter используется, и systemd автоматически подхватила модули, как только мы скопировали их в правильный каталог.
Системы на базе Debian (такие как Ubantu) включат и запустят службу сразу же. В системах семейства RedHat нужно явно запустить службу командой systemctlstartgreeter. timer. То же самое относится к включению служб при загрузке: в семействе Debian — автоматически и по умолчанию, в семействе RedHat — только после подтверждения через systemctlenable.
Давайте проверим состояние greeter. timer:
$ sudo systemctl status greeter.timer
• greeter.timer - Runs Greeting service at the top of the hour Loaded: Loaded (/run/systemd/system/greeter.timer; static; \ vendor preset: enabled)
Active: active (watting) since Sun 2021-09-12 13:10:3$ 1ST; 2s ago Trigger: Sen 2021-99-12 14:60:00 1ST; 49min left
Sep 12 13:19:35 starlite systemd[l]: \
Started Runs Greeting service at the top of the hour.
248 systemd time and date format: hnps:/7wwwfrecdesktop.org/software/systemd.'man/latest:/ systemd.time.html.
154 | Глава 6. Приложения, управление пакетами и контейнеры
Итак, Hysteria подтверждает, что знает о greeter и что он запланирован к запуску. Но как узнать, срабатывал ли запуск? Давайте проверим логи (учтите, я немного подправил вывод stdout, который идет напрямую в логи):
$ journalctl -f -и greeter.service О
 Logs begin at Sun 2021-01-24 14:36:30 GMT. --
Sep 12 14:00:01 starlite syste*sd[l]: Starting Моя служба приветствия..
Sep 12 14:00.01 starlite greeter.sh[21071]: Бы великолепны!
О Использование journalctl для обновляемого (-f) просмотра логов только для модуля greeter, service (фильтр с помощью -и).
От общего обзора systemd перейдем к изучению управления приложениями более традиционным способом, через многоцелевой менеджер пакетов. Но перед тем как углубиться в подробности работы с пакетами, отвлечемся и обсудим приложения, пакеты и их менеджеры в более широком формате, который называется цепочкой поставок.
Цепочки поставок приложений в Linux
Под цепочкой поставок249 мы понимаем систему организаций и лиц, поставляющих продукт потребителю. С цепочками поставок вы сталкиваетесь постоянно (даже если не замечаете), покупая еду и заправляя машину. В нашем случае вместо продуктов — созданные разработчиками приложения, а вместо потребителей — пользователи, которым нужно приложение, или программы, которые управляют приложениями от их имени.
На рисунке 6-2 приведена схематика типичных участников и этапов цепочки поставок приложений в Linux.
При поставке приложений выделяются три группы.
Поддержка программного продукта
Индивидуальные разработчики, проекты с открытым кодом и компании не • зависимых поставщиков (1SV), которые производят программные продукты и публикуют их в виде пакетов в репозиториях.
249 supply chain: https://eti.wi.kipedia.urg/wiki/Supply_cbain.
Цепочки поставок приложений в Linux | 155
Репозиторий
Предоставляют пакеты, в которых содержатся целые приложения или их части с дополнительными метаданными. Обычно в пакете фиксируются зависимости — другие пакеты, необходимые приложению для работы — библиотеки, различные экспортеры/импортеры, вспомогательные утилиты. Поддерживать зависимости в актуальном состоянии непростая задача.
Инструментарий (менеджер пакетов)
Из конечной системы ищет з репозитории информацию о пакетах и устанав ливает, обновляет или удаляет приложения по указанию пользователя. Учти те, что пакеты — это и сами приложения, и их зависимости.
При мелких различиях в дистрибутивах и средах (на сервере, настольном компьютере и т. д.) любые цепочки поставок содержат общие элементы, показанные на рисунке 6-2.
-Пакет
- Метаданные
Поставщики ПО Репози~орий
Рисунок 6 2. Цепочка поставок приложений в Linux
Пользователь
Конечная система
Способов управлять пакетами масса. Среди них и привычные менеджеры пакетов, и решения с контейнеризацией, и более современные подходы.
На рисунке 6-3 я попытался представить вам общий обзор, хоть и далекий от полной картины.
156 | Глава б. Приложения, управление пакетами и контейнеры
Рисунок 6-3. Вселенная управления пакетами Linux и зависимостями приложений
Несколько слов о каждом из трех вариантов управления пакетами и зависимости:
Классические менеджеры пакетов
Низкоуровневые инструменты тоже попадают в эту категорию. Однако, если менеджер пакетов может разрешать зависимости и предоставляет высокоуровневый интерфейс (установка, обновление, удаление), то он считается высокоуровневым.
Решения на основе контейнеров
Выходцы из сферы серверных и облачных вычислений. С учетом их возмож ностсй одним из вариантов использования (не обязательно главным) может быть и управление приложениями. Если вы разработчик, то непременно полюбите контейнеры, ведь они значительно упрощают и тестирование, и развертывание. Загляните в раздел «Контейнеры».
Современные решения по управлению пакетами
Берут начало в средах рабочего стола. Их главная задача — максимально упростить использование приложений для пользователя. См. также «Современные менеджеры пакетов».
Цепочки поставок приложение в Linux | 157
Пакеты и менеджеры пакетов
В этом разделе обсудим форматы пакетов и устоявшиеся менеджеры пакетов, некоторые из которых развивались десятилетиями. Как правило, все они пришли из двух основных семейств Linux: Red Hat (RHEL, Fedora, CentOS и др.) и Debian (Debian, Uountu и т. д.).
В наше обсуждение вписываются две концепции:
Сами пакеты
Технически это файлы, как правило, архивы, которые включают и метаданные.
Инструментарий (который и называется менеджерами пакетов)
Управляет пакетами в конечной системе, устанавливая и обслуживая приложения. Обычно менеджер пакетов работает с репозиторием от вашего имени и умеет сохранять (кэшировать) информацию о пакетах локально.
Конечной системой может быть и графическая среда вашего ноутбука, и сервер, развернутый на экземпляре виртуальной машины в облаке. В разных сре дах пакеты применяются по-разному; сомнительно, что на сервере вам нужно графическое приложение.
Менеджер пакетов RPM
Менедже р пакетов RPM25C (рекурсивный акроним для RPM Package Manager) изначально создавался в Red Hat, но теперь популярен в самых разных дистрибу гивах Формат .rppi поддерживается базой стандартов Linux и содержит бинарные файлы или исходный код. Пакеты могут быть подписаны криптографически и поддерживают исправления через патчи (patch, специальный макрос-заплатка).
Следующие менеджеры работают с RPM:
уют250 251
В Amazon Linux, CentOS, Fedora, и RHEL.
DNF252
В CentOS, Fedora и RHEL.
250 RPM (RPM Package Manager): btrps://en wikipedia.org/wikVRPM Package_Manager.
251 yum package manager, http.//yum.baseud.org/.
252 DNF Software Package Manager: https://docs.fedoraproject.org/en-US/quick-docs/dnf/.
158 | Глава 6. Приложена/. управление пакетами и кон'ейнеры
Zypper233
В openSUSE и SUSE Linux Enterprise.
Давайте попрактикуемся в использовании RPM. Предположим, у нас новая среда разработки, и мы хотим установить язык Go с помощью yum.
Сразу скажу, что вывод приведенных команд я обрезал, чтобы вписать на страницу (удалил строки, которые не относятся к делу).
Для начала найдем пакет для Go:
#	уип search до lang О
Loaded plug;ns: ovl, priorities
=----==========-=^/4 matched: goLang===-=======-=====
golang bin.x86_64: Golangcorecompilertools
golang - docs. noarch: Go langcompilerdccs
golang-googlecode net devel.noarch: Supplementary Go networking libraries
golang-googlecode-sqlite-devel.x86_64: Trivial sqltte3 binding for Go
О Поиск пакета для Go Обратите внимание: приглашение * показывает, что мы в системе из-под root. Лучше было бы использовать sod? yum
Разузнав о пакете, пробуем его установить:
#	yum install golang •
Loaded plugins: ovl, priorities
Resolving Dependencies в
-	-> Running transaction check
-	--> Package golang.x86_64 0:1.15.14-l.amzn2.0.1 will be installed
-	-> Processing Dependency: golang src = 1.15.14-1.arrznZ.0.1 for package:
golang-1.15.14-1.amzn2.0.1.x86_64
Transaction Summary
Install 1 Package (+101 Dependent packages)
Total download size: 183 M
Installed size: 624 M 253
253 Zypper (package manager) Cheat Sheet: https://en.opcnsjsc.org/imagcs/ 1/17/Zypper-cheat-sheel-l.pdf.
Пакеты и менеджеры пакетов | 159.
Is this ok [y/d/N]: у © Dependencies Resolved
Package	Arch	Version	Repository	Size
Installing:				
golang	x86_64	1.15.14-1.anzn2.0.1	anzn2-core	705 k
Installing for dependencies:				
acl	x86_64	2,2.51-14.anzn2	anzn2-core	82 k
apr	x86_64	1.6.3-5.anzn2 e 2	anzn2-core	118 k
Verifying: groff-base-1.22.2-8.amzn2.0.2.x86_64	101/102
Verifying: perl-Text-ParseWords-3.29-4.anzn2.noarch	102/182
Installed: О
golang.x86_64 0:1.15.14-l.arizn2.0.1
Dependency Installed:
acl.x8G 64 9:2.2.51-14.anzn2	apr.x86„64 0:1.6.3-5.anzn2.0.2
О Установка пакета Go.
® Первым делом yun определяет зависимости пакета.
® Здесь yun отдает общий список зависимостей, которые он обнаружил, и запрашивает подтверждение на их установку. Мне нужно самому ввести у. (В скрипте я бы включил автоматические подтверждения: yuninstallgoleng -у.)
© После установки зависимостей и основного пакета yun рапортует об успешном завершении.
И. последняя важная деталь — мы можем проверить, что и откуда установи лось-
#	уич info golang
Loaded plugins: ovl, priorities
Installed Packages
Mane	: golarg
Arch	: x86_64
160 | Глава 6 Приложения, управление пакетами и контейнеры
• 1.15.14
Version
Release	 l.amzn2.0.1
Size	: 7.8 M
Repo From repo Summary URL	: installed : amzrr2-core : The Go Programming Language : http://golang.org/
License	: BSD and Public Domain
Description	: The Co Programming Language.
Теперь рассмотрим другой известный менеджер, использующий пакеты Debian.
Debian deb
Пакеты deb254, как и формат файда .deb, происходят из дистрибутива Debian. Пакеты deb гоже могут включать в себя бинарные файлы, двоичные данные или исходный код. Пакеты deb используют несколько менеджеров пакетов как низкоуровневых и не требующих управления зависимостями (dbkg), так и высокоуровневых (apt-get, apt и aptitude). Учитывая, что дистрибутив Ubuntu основан на Debian, пакеты deb распространены и на настольных компьютерах, и на серверах.
Чтобы посмотреть на работу с пакетами deb, установим через apt утилиту curl, полезную для взаимодействия с HTTP API и загрузки файлов из сети. Снова предупрежу, что отредактировал вывод, оставив только важное.
Ищем пакет curl:
#	apt search carl О
Sorting... Done
Full Text Search... Done
curi/focal-updates, focal-security 7.68.0-lubuntu2,6 amd64
command line tool for transferring data with URL syntax
curlftpfs/focal 0.9.2 9buildl amd64
filesystem to access FTP hosts based on FUSE and cURL
flickcurl-doc/focal 1.26-5 all
utilities to call the Flickr API from command line -- documentation
254 Пакеты дистрибутивов Debian: https://wwwdebian.org/distrib/packages.
Пакет и менеджеры пакетов | 161
flickcurl-utils/focal 1.26-5 amd64
utilities to call the Flickr API from commano line
ganbas3-gb-net-curl/focal 3.14.3 2ubuntu3.1 amdb4
Cambas advanced networking component
О Поиск пакета curl через apt. Обратите внимание на массу дополнительных результатов, в основном библиотек и привязок для языков программирования (Python, Ruby, Go, Rust и т. д.).
Устанавливаем пакет curl:
# apt install curl О
Reading package lists... Done
Building dependency tree ®
Reading state information... Done
The following additional packages will be installed:
cacertificates krbS-locales libasnl-8-hetmdal libbrotlil ...
Suggested packages:
krbS-doc krbS-user libsasl2 modules-gssapi-mit ...
The following NEW packages will be installed:
ca-certificates curl krb5-locales libasnl-8-neimdal ...
0 upgraded, 32 newly installed, 0 to remove and 2 not upgraded.
Need io get 5447 kB of archives.
After this operation, 16.7 MB of additional disk space will be used.
Do you want to continue? [Y/n] ©
Cet:l http://archive.ubuntu.com/ubuntu focal-updates/main amd64
libssll 1 amd64 l.l.lf-lubuntu2.8 [1320 kB]
Cet:2 http://archive.ubunte.com/ubuntu focal-updates/main and64
openssl amd64 1.1.If-lubuntu2.fi [620 kB]
Fetched 5447 kB in Is (3882 kB/s)
Selecting previously unselected package libssll.1: amd64.
(Reading database ... 4127 files ano directories currently installed.) Preparing to unpack ..,/00-libssll.l_l.l.lf-lubuntu2.8_amd64.deb ... Unpacking libssll.1: and64 (1.1 lf-lubuntu2.8) ...
162 |	Глава 6. Приложения, управление пакетами и контейнеры
Setting up libkeyutilsl: amd64 (1.6-6ubuntul) ...
Processing triggers for ca-certificates (23212119-29.04.1) ...
Updating certificates in /etc/ssl/certs... 1 added, 0 removed; done. rt
Running hooks in /etc/ca-certificates/update.d... done.
О Установить curl.
® Сначала ept проверяет зависимости.
® Apt предоставляет сводку зависимостей и сообщает, что будет их устанавливать. Необходимо интерактивное подтверждение (в скрипте я бы включил автоматическое подтверждение, aptinstallcurl -у).
© После установки зависимостей и основного пакета ept рапортует об успешном завершении.
В конце проверяем установку пакета-
iff opt show curl
Package: curi
Version: 7.68.0-lubuntu2.6
Priority: optional Section: web Origin Ubuntu Maintainer: Ubuntu Developers ubuntu-devel-discuss@lists.ubuntu.com Original-Maintainer: Alessandro Ghedini <ghedo@debtan.org> Bugs: https://bugs.launchpad.net/ubuntu/+filebug Installed-Size; 411 kB
Depends: libc6 (>= 2.17), ltbcurl4 (= 7.68.0-lubuntu2.6), zliblg (>= 1:1.1.4) Homepage: http://curl.haxx.se
Task: server, cloud-image, ubuntu budgie desktop Down load-Size: 161 kB APT-Manual-Installed: yes
АРТ-Sources: http://archive.ubuntu.com(ubuntu focal-updates/main and64 Packages Description: command line tool for transferring data with URL syntax N: There is 1 additional record. Please use the '-a' switch to see it
Перейдем к менеджерам пакетов для специфичных языков программирования.
Пакеты а менеджеры пакетов | 163
Менеджеры пакетов для языков программирования
Как понятно из названия, существуют менеджеры пакетов для разных языков:
C/C++
Множество менеджеров пакетов25', включая Conan и vepkg.
Со
У Go есть встроенное управление пакетами (goget, gomoa).
Node.js
npn и другие.
Java
maven, nuts и др.
Python
pip и Ру PM.
Ruby
rubygems и Rails.
Rust
cargo.
Далее мы рассмотрим контейнеры и научимся управлять приложениями с их помощью.
Контейнеры
В этой книге мы называем контейнером группу процессов Linux, которая использует пространства имен (namespaces), контрольные группы (egreups) и в некото рых случаях файловые системы CoW для управления зависимостями на уровне приложений. Область применения контейнеров широка, от разработки и .текального тестирования до взаимодействия с распределенными системами — на пример, контейнерными микроссрвисами в Kubernetes.
255 СРР / C++ - Package Managers; hnps.//ca:orss.gi:hub ю,'С-Cpp-Notes; package-managers, html.
164 | Глава 6 Приложения, управление пакетами и контейнеры
Контейнеры очень полезны для разработчиков и системных администраторов, но обычным пользователям, скорее всего, будет проще управлять приложениями через инструменты белее высокого уровня. Их мы рассмотрим в разделе «Современные менеджеры пакетов».
ЭХ, БЫЛИ БЫ У МЕНЯ КОНТЕЙНЕРЫ
На предыдущей работе мне понадобилось собрать демонстрационный пример, где использовалась база данных influxDB для хранения временных рядов.
Настройка потребовала кучи приготовлений: создания каталогов, копирования данных, установки зависимостей. Когда дело дошло до передачи примера коллеге и демонстрации заказчику, мне пришлось написать подробнейший документ с перечислением всех шагов и проверок, просто чтобы убедиться, что все работает как планировалось.
Если бы в то время у меня под рукой оказалась технология Docker, я бы сэкономил себе и коллеге кучу времени, упаковав все в контейнер. Это не только упростило нам жизнь, но и гарантировало, что в его среде все будет работать точно так же, как на моем ноутбуке.
Технология контейнеров в Linux сама по себе не нова, однако широкое распространение контейнеры получили примерно с 2014 года, и именно благодаря Docker. Если раньше и наблюдались попытки внедрить контейнеры, то скорее для системных администраторов, чем для разработчиков:
—	Linux-VServer (200J)256.
-	OpenVZ (2005)257.
—	LXC (2008)258 259.
—	Let Me Contain That For You (Imctfy) (2013)25’.
Все эти решения объединяло одно — они использовали компоненты ядра Linux (пространства имен и контрольные группы), чтобы позволить пользователям запускать приложения.
Docker привнес два новаторских элемента: универсальный метод упаковки с помощью образов контейнере з и удобный пользователям интерфейс
256 Linux '/Server: https://en.wikipedia.org/wikl/Linax-VServer.
sr OpenVZ. https://openvz.org/.
2,8 LXC Container and virtualization took; https://linuxcontainers.org/.
259 Imctfy — Let Me Contain That For You: https://github.com/googJe/lmctty.
Контейнеры | 165
(например, dockerrun). Способ, которым образы контейнеров объявляются, рас пространяются и запускаются, лег в основу открытой спецификации, которая сейчас называется Open Container Initiative (OCI). Все контейнеры, упомянутые в этой книге, совместимы с OCI.
Вот три основные спецификации контейнеров ОС1:
Спецификация runtime
Описывает, что должна поддерживать среда выполнения реального времени (runtine), включая все операции и фазы жизненного цикла.
Спецификация формата образов
Описывает, как должны создаваться образы контейнеров на основе метаданных и слоев.
Спецификация распространения
Описывает, как должны поставляться образы контейнеров (то есть способ работы репозиториев в части, касающейся контейнеров).
Еще одна идея, связанная с контейнерами, - неизменяемость. После сборки конфигурации нельзя изменить время ее использования. Любые изменения потребуют создания новой (статической) конфигурации и нового ресурса (запуска процесса, например) на ее основе. Мы еще поговорим об этом, обсуждая образы контейнеров.
С общим представлением о контейнерах рассмотрим строительные компоненты OCl-совместимых контейнеров.
Пространства имен Linux
Как упоминалось в главе 1, Linux изначально рассматривает ресурсы как глобальные. Чтобы ограничить процессам область видимости на файловую систе му, сеть или даже пользователей, в Linux ввели пространства имен.
Иными словами, пространства имен Linux260 напрямую связаны с видимостью ресурсов и могут использоваться для изоляции тех или иных аспектов, затрагивающих ресурсы системы В нашем случае под изоляцией понимается видимость ресурсов для процесса, а не жесткие ограничения с позиции безопасности.
За создание пространств имен отвечают три определенных системных вызова.
260 namespaces(7): https;//man7.org/linux/man-pages/rrari7/namespaces.7.html.
16f | Глава б. Пзиложегия, управление пакетами и контейнеры
clone™1
Используется для создания дочернего процесса, который частично разделяет контекст выполнения с родительским процессом.
unshare™2
Используется для удаления из процесса общего с родителем контекста выполнения.
setns™
Используется для присоединения существующего процесса к существующему пространству имен.
Указанные системные вызовы принимают в качестве параметров ряд флагов, позволяющих тонко настроить пространства имен, которые вы хотите создать, к которым хотите присоединиться или которые хотите покинуть:
CLONE_NEHNS
Используется для точек монтирования файловой системы261 262 * 264 265 Виден через /proc/$PTD/mounts. Поддерживается начиная с Linux 2.4.19.
CLONE _NEUUTS
Используется для создания изоляции имени хоста и домена (NIS)245. Виден через ипапе -п и hostname -f. Поддерживается начиная с Linux 2.6.19.
CLONE_NEW1PC
Используется для изоляции ресурсов межпроцессного взаимодействия (1РС)266, например, объектов System V IPC или очередей сообщений POSIX. Виден через /proc/sys/fs/nqueue, /ргос/sys/kernel и /proc/sysvipc. Поддерживается начиная с Linux 2.6.19.
261 cione(2): https://mari7.org/linux/man- page s/man2/clone.2.html.
262 unshare(2): https://man7.Org/linux/man-pages/man2/unshare.2.himl.
20 setns(2): ftttps://man7.org/linux/man-pages/man2isetns.2.html.
264 mount_namespaccs(7): https://man/.org/lmnx/man-pages/man7/mount_namespaces.7.html.
265 «uts namespaces- Introduction»: https://lwn.net/Articles/17934b/.
IPC namespace: https://lwn.net/Articles/187274/.
Контейнеры j 167
CLONE, NEHPID
Используется для изоляции номерною пространства РЮ’67 (PID внутри/сна ружи пространства имен). Сведения можно собрать через /proc/$PID/status. Поддерживается начиная с Linux 2.6.24.
Cl.ONF_NEUNET
Используется для управления видимостью сетевых системных ресурсов26", например, сетевых устройств, IP-адресов, таблиц IP маршрутизации и номеров портов. Просмотреть можно через ipnetnslist, /proc/net и /sys/class/ net. Поддерживается начиная с Linux 2.6.29.
CLONEJWUSER
Используется для сопоставления идентификаторов пользователей и групп (UID+GID26’) внутри и вне пространства имен. Вы можете запросить U1D и GID и их сопоставления с помощью команды id и через /proc/$PID/uid_nap и /p-oc/$PID/gid_nap. Поддерживается начиная с Linux 3.8
CLONE_NEHCGROUP
Используется для управления egroups в пространстве имен267 * 269 270. Можно увидеть через /sys/fs/сдгоир, /proc/cgroups и /ргос/$РЮ/сдгоир. Поддсржива ется начиная с Linux 4.6.
Один из способов просмотра пространств имен в системе приведен ниже (вывод урезан):
$ sudo isns
NS	TYPE	NPROCS PID		USER	COMMAND
4026531835	сдгсср	251	1	root	/sbin/init splasn
4025531836	pid	245	1	root	/sbin/init splash
4026531837	user	245	1	root	/sbin/init splash
4026531838	uts	251	1	root	/sbin/init splash
4026531839	ipc	251	1	root	/sbin/init splash
<1026531840	nnt	241	1	root	/sbin/init splash
46265318G0	nnt	1	33	root	kdevteipfs
267 PID namespaces: https://lwn net/Articks/259217/,
M Network names races: https://lwn.net/Articles/2l9/94/.
269 User namespaces: https://lwn.net/Articles/578078/.
270 cgroup_namespaces(7): https://man7.org/linux/iJTan-pages/man7/cgroup_namespaces.7.html.
168 | Глава 6. Приложения, управление пакетами и контейнеры
4626531992	net	244	1	root	/sbin/trttt splash
4626532233	pint	1	432	root	/1 tb/systaid/systefid - udevd
4026532250	user	1	5319	mh9	/opt/google/chroeie/nacl_hel per
4626532316 not 1	684 systend tinesync /lib/systend/systend-tieiesyticd
Следующий строительный компонент контейнеров занимается ограничением потребления ресурсов и отчетами потреблении.
Контрольные группы Linux
Если пространства имен отвечают за видимость, го задача контрольных групп (cgroups271} — формировать группы процессов. Наряду с иерархической группировкой контрольные группы можно использовать для ограничения использования системных ресурсов. Кроме того, контрольные группы занимаются отслеживанием такого использования; они могут показать, сколько памяти или секунд процессорного времени использует процесс (или группа процессов). Вос принимайте контрольные группы как единицу выдачи данных, а сам контроллер — как часть кода ядра, которая ограничивает ресурсы или сообщает об их использовании.
На момент написания статьи в ядре доступны две версии cgroups: cgroups vl и cgroups v2. Первая версия по-прежнему распространена, но вторая рано или поздно вытеснит ее, так что сосредоточьтесь на v2.
cgroup v1
При развитии cgroupsvl272 сообществом практиковался спонтанный подход — новые контрольные группы и контроллеры добавлялись по мере надобности. Известны следующие контрольные группы и контроллеры (упорядочены от самых старых к новым; учтите, что документация разрозненная и непоследовательная);
CFS bandwidth control273
Регулирует пропускную способность CFS. Используется через сри cgroup. Поддерживается начиная с Linux 2.6.24.
271 cgroups(7): https://www.man7.org/lmux/man -pagt‘s/man7/cgroups.7.html.
272 cgroups vl; https7/wwwkerneLorg/doc/htrnl/latest/admin-guide/cgroup-vl?index.html
273 CFS Bandwidth Control; https://www.kernel.org/doc/Docu mentation/scheduler/sched-bwc txt.
Контейнеры | 169
CPU accounting controller274
Контроллер учета ЦП. Используется через cpuacct cgroup Поддерживается начиная с Linux 2.6.24.
cpusets cgroup275
Позволяет выделять ЦП и память задаче. Поддерживается начиная с Linux 2.6.24.
Memory resource controller276
Контроллер ресурсов памяти. Позволяет изолировать выделение памяти для задач. Поддерживается начиная с Linux 2.6.25.
Device whitelist controller277 278 279 280
Контроллер списка устройств. Описывает политики доступа к управлению устройствами. Поддерживается начиная с Linux 2.6.26.
freezer cgroup''6
Используется для управления пакетными заданиями. Поддерживается начиная с Linux 2.6.28.
Network classifier cgroup775
Классификатор сети. Используется для назначения сетевым пакетам разных приоритетов. Поддерживается начиная с Linux 2 6.29.
Block IO controller266
Позволяет регулировать I/O блочных устройств. Поддерживается начиная с Linux 2.6.33
perf event command26'
Позволяет собирать данные о производительности. Поддерживается начиная с Linux 2.6.39.
274 CPU Accounthig Controller; https.//www.kcmel.org/doc/Docunientation/cgroup-vl/cpuacCT.txt
275 CPUSETS: bttps://www.kernel .org/doc/Documentation/cgroup-vl/cpusets.txt.
270 N lemory Resource Controller https://www.kemel.org/dcKVDocumentation/cgroup-v] /memory.txt.
277 Device Whitelist Controller: https//www.Kernel.org/doc/Docurr er iauon/<.grovp-vl/dcvic.'’s.txt
278 freezer cgroup: https://www.kernel.org/doc/Documentation/cgroup-vl/freezer-subsystem.txt
279 freezer cgroup: https://'www.kernel.org/doc/Documentation/cgroup-vl/freezer-subsystemtxt.
280 Network classifier cgroup- https://www.kernel.org/doc/Documentation/cgroup-vl/net_cls.txt.
2,1 Block IO controller: https://www.kerael.org/doc/Documentalion/cgroijp-vl/blkio controller txt
170 | Глава 6. Приложения, управление пакетами и контейнеры
Network priority cgroup2*2
Позволяет динамически управлять приоритетом сетевого трафика. Поддерживается начиная с Linux 3.3.
HugeTLB controller™
Позволяет ограничивать использование HageTLB (ассоциативный кэш больших страниц). Поддерживается начиная с Linux 3.5.
Process number controller2^
Используется для разрешения иерархии контрольных групп перестать создавать процессы по достижении определенного предела. Поддерживается начиная с Linux 4.3.
cgroupv2
cgroup v2:8b, или вторая версия контрольных групп, — это полное переосмысление и работа над ошибками egroups vl. Настройка и использование стали более последовательными, документация — упорядоченной и внятной. В отличие от groupsvl, в egroupsv? единая иерархия, и все контроллеры управляются одинаково. Вот их список:
Контроллер ЦП
Регулирует распределение циклов ЦП, поддерживает несколько моделей (weight, max) и включает отчеты об использовании.
Контроллер памяти
Регулирует распределение памяти с помощью ряда параметров. Поддерживает память пользовательского пространства, структуры данных ядра (такие как dentrtes и inode) и буферы TCP-сокето з.
Контроллер I/O
Регулирует распределение ресурсов I/O с весовыми и абсолютными ограничениями пропускной способности или по числу операций ввода вывода в се кунду (IOPS), предоставляя отчеты о байтах и количестве IOPS чтения/записи. 282 283
282 pert -record: https://web.git.kei r el.org/pub/scm/linux/keme 1 zgit torvald s/linux.gr/plain/tools/ perf/Documentation/peif record, txt.
2,3 Network priority cgroup: https://www.kernel.org/doc/Documentation/egroup - v lZnet_prio.txt.
2M HugeTLB Controller: https://www.kernel.orgzcoc/Documentation.'cgroup-vl/hugetlb.txi.
283 Process Number Controller: https://www.kernet.org/doc/Documentation/cgroup-vl/pids.txt.
Контейнеры | 171
Контроллер PID
Работает так же, как аналогичный в vl.
Контроллер cpuset
Работает так же, как аналогичный в vl.
Контроллер device
Регулирует доступ к файлам устройств, реализован поверх еВРЕ
Контроллер rdmo
Регулирует распределение и ведет учет ресурсов удаленного прямого доступа к памяти (RDMA)2W.
Контроллер HugeTLB
Работает так же, как аналогичный в vl.
Во второй версии есть несколько контрольных групп Они устанавливают ограничения и отслеживают использование для единичных ресурсов, которые нельзя абстрагировать так же, как остальные.
Все контрольные группы v2 в вашей системе можно посмотреть в виде удоб ного дерева, выполнив команду systemctl, как показано ниже (вывод отредактирован и урезан для удобства);
$ systemctl status О
starlite
State: degraded
Jobs: 0 queued
Failed: 1 units
Since: Tue 2021 09-07 11:49:08 1ST; 1 weeks 1 days ago
CCrcup: /
|-22160 bpfilter_umh
|—user, slice
| *—user-1000.slice ®
!	|—user01060.service
]	| |—gvfs-goa-volunn-monitor.service
|	| | *—14497 /usr/lib/gv^s/gvfs-goa-volune-monitor
cgroup v2: https://www.kernel.org/doc/html/latest/admiri-guide/cgroup-v2.html.
172 | Глава 6 Приложения, управление пакетам» и контейче ры
О Запуск утилиты systemctl для от рисовки иерархии контрольных групп.
© Пример контрольной группы, которой управляет systemd.
Другой удобный вид отображения контрольных групп — интерактивная статистика использования, вызывается как показано ниже (вывод урезан):
$ systemd-cgtop
Control Croup	tasks	%CPU	Memory	Input/s Output/s	
/	623	15.7	5.8G		-
/docker	-	-	48.3M	-	
/system.slice	122	6.2	1.6G	-	-
/system.slice/ModemManager.ser vice	3	-	748.OK	-	-
/system.s Lice/rsyslog.service	4	-	420.OK	-	-
/system.slice/snapd.service	17	-	5. IM	-	-
Можно ожидать, что в ближайшем будущем, по мере выхода новых версий ядра, cgroups v2 станет стандартом. Некоторые дистрибутивы, такие как Arch, Fedora 31+ и Ubuntu 21.10, уже используют cgroups v2 по умолчанию.
Файловые системы CoW (с копированием при записи)
Третий строительный блок для контейнеров — это файловые системы CoW, которые обсуждались в разделе «Файловые системы с поддержкой копирования при записи». В процессе сборки они упаковывают приложение и все его зависимости в один автономный файл, готовый к распространению. Обычно файловые системы CoW' используют в сочетании с привязками монтирова пия297, чтобы эффективнее наслаивать содержимое различных зависимостей друг на друга.
Docker
Docker — удобная для использования человеком реализация контейнеров, разработанная Docker Inc. в 2014 году и активно продвигаемая. Этот продукт позволяет с легкостью упаковывать программы вместе с зависимостями, а потом запускать эти программы в разнообразных средах, от настольных компьютеров до облака. Уникальность Docker не в строительных компонентах: пространства 287
287 bind mounts: https://docs.dccker.corr/engine/sto’-age/bird-mounts/.
Контейнеры | 173
имен, контрольные группы, файловые системы CoW и привязки монтирования существовали задолго до его появления. Уникальность в том, что Docker сумел объединить все строительные компоненты так, что их стало ле1ко использовать, спрятав «под капотом» такую низкоуровневую работу, как управления пространствами имен и контрольными труппами.
Как показано на рисунке 6-4 с последующим объяснением, в основе Dockei два основных понятия: образ и запущенный контейнер.
$ docker run
$ docker build
Образ
контейнера
Рисунок 6-4. Обзор архитектуры Docker
Образ контейнера
Сжатый архив с метаданными в файлах JSON и слоями (фактически каталогами). По мере надобности демон Docker извлекает образы контейнеров из реестра контейнеров.
Контейнер как создаваемый во время выполнения артефакт (к примеру, приложение А/Б/В)
Вы можете стартовать, останавливать, принудительно останавливать (kill) и удалять контейнер. Взаимодействие с демоном Docker происходит через специальную CLI утилиту docker. Эта утилита передает команды демону, который выполняет соответствующую операцию, например, сборку или запуск контейнера.
Таблица 6-2 содержит краткий справочник самых используемых команд Docker CLI и охватывает фазы сборки и выполнения. Полный список команд с примерами вы можете найти в документации Docker.
174 | Глава 6. Пр сложения, у травление пакетами и контейнеры
Таблица 6 2. Часто используемые команды Docker
Команда	Тип	Объяснение
run	Запускает контейнер	Запустить NGINX как демон и удалить при выходе; docker run -d --rm nginx:1.21
ps	Список контейнеров	Показать все контейнеры (включая незапущенные): docker ps -а
inspect	Отображает низкоуровневую инфор-	Для получения Р контейнера: docker inspect -f
	мацню	'{{.Networ kSettings.IPAddress}}' <id>
build	Создает образ контейне ра пока/ ьно	Собрать контейнер на основе каталога и тега: docker build -t sone: tag .
	Отправка образа контейнера	Загрузить в реестр AWS: docker push
	в реестр	puDlic.ecr.aws/some: tag
	Скачивание образа контейнера	Извлечь из реестра AWS: docker pull
	из реестра	public.ecr.aws/some: tag
linages	Список локальных образов контей-	Вывести образы из определённого реестра:
	неров	docker images ubuntu
image	Управление образами контей неров	Удалить все неиспользуемые образы: docker image prune -а
Теперь подробнее рассмотрим динамический программный артефакт — образ контейнера Docker,
Образы контейнеров
Инструкция по сборке образа контейнера создается в обычном текстовом файле, который называется Dockerfile21’8.
При создании Dockerfile можно использовать ряд директив:
базовый образ
FROM; может быть несколько для фазы сборки/запуска.
Метаданные
LABEL для сопроводительной информации.
Параметры и переменные среды
ARGS, ENV.
Инструкции для динамической сборки
COPY. RUN, и другие, которые определяют, как будет собираться образ (слой за слоем).
2™ Dockerfile: https:,7docs.docker.com/reference/dockerfile/.
Контейнеры | 175
Инструкции времени выполнения
CMD и ENTRYPOINT, в которых определено, как контейнер будет запускаться.
Командой docker build на основе Dockerfile из набора файлов вашего приложения (в виде исходного кода или двоичных файлов) вы собираете образ контейнера. Полученный программный артефакт можно запустить самому или распространить, то есть отправить в реестр, откуда его смогут скачать для запуска другие пользователи.
Запуск контейнеров
Контейнеры можно запускать интерактивно (из терминала) или в виде демонов (в фоне). Команда docker run289 принимает на вход образ контейнера и динамические аргументы: переменные окружения, открываемые вовне порты, перечень volume. На основе предоставленных данных Docker создает необходимые пространства имен и контрольные группы, а в конце запускает приложение, определенное в образе контейнера через инструкцию CMD или ENTRYPOINT.
Ознакомившись с теорией использования Docker, перейдем к практике:
Пример: контейнеризация greeter
Давайте поместим в контейнер наше приложение с приветствием (см. «Рабочий пример greeter») и запустим его.
Прежде всего определим Dockertile с инструкциями по созданию образа коп тейнера:
FROM ubuntu:20.64 О
LABEL org.opencontainers.image.authors='Michael Hausenolas" ©
COPY greeter.sh /аор/ ©
WORKDIR /арр ©
RUN chown -R 1001:1 /app ©
USER 10Э1
ENTRYPOINT ["/app/greeter.sh"] ©
О Указываем базовый образ с явным указанием тега версии (20.64).
© Добавляем метаданные с помощью ярлыков2*3 (директива LABEL).
О Кс гпируем наш скрипт. Это может быть двоичный файл, JAR-файл или скрипт на Python.
289 docker run: hnps.//docs.docker.com/reference/cli/docker/conta:ner/run/.
29,1 Docker object labels: https://docs.docker.com/engine/manage-resources/labels/.
176	| Глгвг 6. Приложения, управление пакетами и контейнеры
® Устанавливаем рабочий каталог.
О Эта и следующая строки определяют пользователя для запуска приложения. Если не указать, то приложение без всякой надобности запустится от имени root.
Ф Определяем, что запускать: в нашем случае это скрипт оболочки. Поскольку мы используем ENTRYPOINT, то при запуске в контейнер можно будет передать параметр: docker run greeter:1 _SOME_PARAMETER_.
Собираем образ контейнера:
$ sudo docker build -t greeter:l. G
Sending build context to Docker daemon 3 3/2kB
Step 1/7: FROH ubuntu:20.94 Ф
20.04: Pulling from library/ubuntu
35807b77aS93: Pull complete
Digest: sha256:9d6a8699fb5c9c39cf08aG871bd6219f0400981c570894cd8cbea30d3424 a31f
Status: Downloaded newer image for ubuntu:20.04
> fb52e22aflb0
Step 2/7: LABEL org.opencontainers.image.authors="Michael Hausenbias"
-	--> Running in 6aaS21276c3b
Removing intermediate container 6aa921276c3b
> def717e3352b
Step 3/7: COPY greeter , sh /арр/
-	--> Sf3ebl60fea3
Step 4/7: WORKDIR /арр
-	--> Running in 698c29938a96
Removing intermediate container 698c29938a96
-	--> d73572886cl3
Step 5/7: RUN chown -R 1001:1 /арр
-	--> Running in 5b5eb5dl935a
Removing intermediate container 5b5ebSdl935a
-	-> 42c35a6c‘b6e2
Step 6/7: USER 1001
-	--> Running in bec92deaac6e
Removing intermediate container bec92deaac6e
-	--> b6eGe27f253b
Step 7/7: CMD ["/app/greeter.sh'']
-	--> Running in 6d3b439f7e50
Конейнеры | 177
Removing Intermediate container 6d3b439f7e50 - -> 433a5fl6d84e
Successfully built 433a5fl0d84e
Successfully tagged greeier:!
О Создаем образ контейнера и присваиваем ему метку (-t greeter:!). Точка в конце команды указывает на использование текущего каталога (и в нем дол жен быть Dockerfile).
® Эта и последующие строки: базовый образ извлекается из реестра и послойно достраивается.
Проверим, создался ли образ контейнера:
S sudo docker images
REPOSITORY	TAG	IMAGE ID	CREATED	SIZE
greeter	1	433a5f!0d84e	35 seconds ago	72.8MB
ubuntu	20.04	fbS2e22aflb0	2 weeks ago	72.8MB
Теперь можно запустить контейнер на основе образа greeter:!, как показано ниже:
$ sudo decker run greeter:!
Вы великолепны!
На этом мы завершаем введение в Docker. Теперь рассмотрим сопутствую щие инструменты.
Другой инструментарий для контейнеров
Докер — не единственный продукт для работы с контейнерами ОСТ Вы можете использовать связку инструментов, созданных и продвигаемых Red Hat: pod man291 и bu ildah292. С помощью этих не демонизируемых утилит можно создавать образы контейнеров (bu ildah) и запускать их (podfan).
Упростить работу с контейнерами ОС1, пространствами имен и контрольными группами могут и другие утилиты:
2,1 podman; https://podman.io/.
2’* 2 buildah: https://buildah.io/.
17S | Глава 6. Приложения, управление пакетами и контем еры
containerd291
Демон для управления жизненным циклом контейнера OCI, от передачи и хранения образов до контроля за работой контейнера.
skopeo29i
Утилита для работы с образами контейнеров (копирование, проверка манифеста и пр ).
systend-cgtop29’
Разновидность команды top (но с поддержкой контрольных труни) для интерактивного отображения статистики использования ресурсов.
nsenter* 294 * 296
Позволяет выполнять программу в указанном и существующем простран стве имен.
unshare297
Позволяет запускать программу с определенными пространствами имен (включаются через флаги).
isns29*
Выводит информацию о пространствах имен Linux.
cinf99
Выводит информацию о пространствах имен Linux и контрольных группах, связанных с идентификаторами процессов.
Мы завершили ознакомительный тур по контейнерам. Рассмотрим современные менеджеры пакетов, которые используют контейнеры для изоляции приложений.
2,3 containerd: https://containerd.io/.
294 scopeo: ht1ps://gi*Jiub.com/containers/skopeo.
2,5 system-cgtop(l): https:.'/www.manz.org/linux/man-pages/mani/systemd cgtop.l.html.
2,6 nsenter(l); https://man7.0rg/linux/man-pages/nianl/nsenter.l.html.
w unshare(l): https://linux.die.net/man/l/unshare.
2’“ lsns(8). https://wvw.man7.org/linjx-'man-pages/man8/lsns.8.htinl.
2” cinf: https://github.com/ndiauseablas/cinf.
Контейнера | 179
Современные менеджеры пакетов
Помимо привычных (как правило, привязанных к дистрибутиву) менеджеров пакетов, есть более современный подвид. Менеджеры, которые входят в пего, часто используют контейнеры и распространяют как кроссплатформенные приложения, так и приложения для конкретных сред. Например, они могут облег чить пользователям Linux Desktop поиск и установку программ с графическим интерфейсом.
Snap300
Система упаковки и развертывания программного обеспечения, разработанная и поддерживаемая Canonical Ltd. Поставляется с усовершенствованной песочницей301 и может использоваться в настольных, облачных и 1оТ-средах.
Flatpak302
Утилита, оптимизированная для настольных сред Linux. Использует контрольные группы, пространства имен, привязки монтирования и seccomp. Изначально была частью семейства дистрибутивов Red Hat, но сегодня доступна во множестве других дистрибутивов, включая Fedora, Mint, Ubuntu, Arch, Debian, openSUSE и Chrome OS.
Applmage303
Существует уже много лет и провозглашает идею «одно приложение - один файл». То есть у приложения не должно быть никаких зависимостей, кроме тех, что уже включены в целевую систему Linux. Со временем в Applmage по явились такие интересные функции, как эффективное обновление, интеграция с рабочим столом и коллекция приложений.
Homebrew304
Выходец из мира macOS, но доступен в Linux и пользуется растущей популярностью. Написан на Ruby и имеет мощный, но интуитивно понятный пользователю интерфейс.
'100 Snap: https://snapcraft.io/.
301 Security and sandboxing: https://ubiintu.com/core/docs/security-and-sandbcxlng.
302 Flatpack: https./: fiatpak.org/.
303 Applmage: https://appimage.org/ .
304 Homebrew on Linux: https://docs.brew.sh/IIomebrew-on-Linux.
180 | Глава 6. Приложения, управление пакетами и контейнеры
Заключение
В этой главе мы затронули множество тем, связанных с установкой, обслуживанием и использованием приложений в Linux.
Сначала мы определили терминологию для приложений, затем рассмотрели процесс запуска Linux и systend — способ управления запуском и компонентами, на сегодняшний день ставший стандартом.
Приложения в Linux распространяются с помощью пакетов и менеджеров пакетов. Мы изучили различные менеджеры и узнали, как использовать кон тейнеры для разработки, тестирования и управления зависимостями. Используя примитивы Linux (контрольные группы, пространства имен, файловые системы CoW), контейнеры Docker позволяют управлять зависимостями на уровне приложений (через образы контейнеров).
В конце мы рассмотрели одиночные решения для управления приложения ми. включая Snap и др.
Если вы ищете, что почитать по теме этой главы, ознакомьтесь со следующими ресурсами:
Процесс запуска и системы инициализации
—	«Анализируем процесс загрузки Linux»’05.
—	«Этапы загрузочного процесса в Linux»305 306.
—	«Как настроить службу Linux на автоматический запуск после сбоя или перезагрузки»307 * *.
Управление пакетами
—	«Анализ цепочек поставок ПО’08.
—	«Управление пакетами Linux»3Ci,
305 «Analyzing the Linux boot process»: https://opensource.com/article/18/l/anj;iyzing-hnux-boot process.
3,16 «Stages of Linux booting process»: https://www.crybit.com/lin'ix-boot-process/.
307 «How To Configure a Linux Service to Start Automatically After a Crash or Reboot». https://www.digitaiocean.com/community/tutorial-series/how-to -config ure-a-Enux- service-ro-start-automatically-after-a-crash-cr-reboot
30‘ «State of the Software Supply Chain» https://www.sonatype.com/state-of-the-software-supply-cham/I nt reduction.
”* «Linux Package Management»: https:'/www.linode.com/docs/gutdes/took-reference/linux-package-trtanagement/.
Заключение | 181
— «Вникаем в учебник по RPM»310.
— Пакеты Debian311.
Контейнеры
— «Практическое введение в терминологию контейнеров»312.
— «От Docker к OCI: что такое контейнер?»313.
— «Сборка контейнеров без Docker»314.
— «Почему Red Hat инвестирует в CR1O и Podman»315.
— «Разоблачение контейнеров»316.
— «Контейнеры без root»317 318.
— «Глубокое погружение: драйверы хранилищ Docker»319.
— «Dockerfile: в поисках идеала»319.
Теперь, вооруженные знаниями о работе с приложениями, перейдем от рассмотрения отдельной системы Linux к более широкой конфигурации и условию, которое для нее необходимо, — сетевому взаимодействию.
310 «Understanding RPM Package Management Tutorial»: https://access.redbat ccir./sites/defauh/ fijes/attacbments/rpm_tutorial_20120531 .pdf.
311 Debian packages: https://www.debian.org/distiib/packages.
312 «А Practical Introduction to Container Terminology»: https://devclopers.redhat.com/ blog/201S/02/22/с ontainer terminology-practical-introduction.
313 «ОС1 vs Docker: What is a container?» - https://cloud.theodo.eom/en/blog/contaihttps://cloud. theodo.ccm/en/blog/container-docker-ociner-docker-oci.
314 «Building containers without Docker»: https://blog.alexellis.io/building-cortainers without-docker/.
315 «Why Red Hat is investing in CRI-0 and Podman»: h1tps://www.redhat.com/en/blcg7why-rea-hat-investing-cri-o-and-podman.
316 «Demystifying Containers»: https://github.com/saschagrunert/demystifying-containers.
317 «Rootless Containers»: https://rootlesscon1aine.rs/.
318 «Deep dive into Docker storage drivers»: https.Z/jpetazzo githubio/assets/20L5-07-01deep dive-into-docker-storage-drivers.litml# 1.
3,9 «The hunt for a better Dockerfile»: https://matduggan.com/the-hunt-fcr-a-better-dockerfile'
ГЛАВА 7
Сетевое взаимодействие
В этой главе мы изучим сетевое взаимодействие в Linux. В современных средах компонент сетевого стека играет важнейшую роль. Без него мало что возможно. Зайти на сервер у облачного провайдера, посмотреть страницу, скачать новое приложение — для всего нужно сетевое подключение и способ взаимодействовать с ним.
Сначала мы определим общую базу понятий, связанных с сетевым оборудованием и пользовательскими компонентами, например, HTTP или SSH. Мы об судим сетевой стек, протоколы и интерфейсы. Уделим особое внимание цент ральной структуре именования сайтов, называемой системой доменных имен (DNS). К слову, DNS важна не только при широкомасштабном развертывании: это центральный компонент для обнаружения сервисов и в контейнерных сре • дах, таких как Kubernetes.
Затем настанет черед протоколов и инструментов прикладного уровня. Мы изучим обмен файлами, публикацию сайтов, сетевые файловые системы, затронем другие методы обмена данными по сети.
В последней части главы мы коснемся более сложных тем от географического картирования трафика до управления временем в сети.
Сразу ограничу ожидания от этой главы; тема сетей в Linux обширна, ее можно изучать очень долго, ей посвящены целые кпиги. Мы займем более прагматичную позицию, разбирая практические примеры с точки зрения пользователя, а вопросы администрирования сети и настройки сетевых устройств оставим за рамками книги.
Итак, сосредоточимся на основах сетевых технологий.
Основы
Для начала выясним, почему сетевые технологии так важны, и определим общую базу понят ий.
В современных средах сетевому взаимодействию отведена центральная роль. Сетевой обмен задействован при установке приложений, просмотре сай тов и чтении почты, при общении в соцсетях и работе с удаленными машинами
Основы | 183
(от одноплатных компьютеров, к которым можно подключиться по локальной сети, до серверов в центрах обработки данных у вашего провайдера) Учитывая множество компонентов, вовлеченных в работу сети, иногда сложно определить, кто виновник проблемы — оборудование или программный стек.
Другой тип затруднений в Linux связан с абстракциями. Многие решения из рассмотренных в этой главе предоставляют высокоуровневый пользователь ский интерфейс. Благодаря ему создается впечатление, что файлы с приложениями доступны и обрабатываются локально, хотя на самом деле они на удаленной машине в сети. При тестировании и устранении неполадок важно помнить, что хотя абстракции удобны и полезны, все сводится к битам, бегущим по проводам или в воздухе.
Рисунок 7-1 дает общее представление о работе сети в Linux. В самом низу сетевое оборудование (например, Ethernet или беспроводные карты), затем ком поненты ядра (например, стек TCP/IP) и, наконец, уже в пользовательском про странстве, ряд инструментов для настройки, опроса и пользования сетью.
С Пользовательское
С пространгво
Рисунок 7-1. Обзор сетевого взаимодействия в Linux
Пространство ядра
Оборудование
Давайте рассмотрим стек TCP/IP — основу сетевого взаимодействия в Linux.
।—В отличие от других областей Linux, где вы либо смотрите в исходный код, либо строите разумные догадки о функциях, изучая документацию интерфейсов, почти каждый протокол в сетевом просгрансл ве основан на общедоступных спецификациях. Инженерный совет интернета (Internet Engineering Task Force, или 1ЕТГ) выкладывает спецификации и рабочие
184 | Глава 7. Сетевое взаимодействие
предложения (Requests For Comments, или RFC) на сайте datatracker_ietf.orgJ2C.
Возьмите за правило просматривать RFC перед тем, как углубляться в детали реализаций. RFC написаны практиками и для практиков, в них выжимка опыта и полезные советы. Ознакомившись с ними, вы намного лучше поймете мотивацию, варианты использования и причины, по которым все сделано так, а не иначе.
Стек TCP/IP
Стек TCP/IP, показанный на рисунке 7-2, — многоуровневая сетевая модель, основанная на ряде протоколов и инструментов (большая часть их описана в спецификациях IETF). Каждый уровень должен общаться только с соседними. Информация упаковывается в пакет данных, а каждый уровень оборачивает пакет своими заголовками со специфичными данными. Таким образом, если приложению нужно отправить информацию, оно напрямую взаимодействует с верхним уровнем, который добавляет заголовок и отправляет пакет вниз по стеку (путь отправки на картинке). И наоборот, если приложение хочет получить данные, входной па кет поступит на нижний уровень, который обработает информацию из заголовков и отправит его на уровень выше (путь получения на картинке).
Рисунок 7-2. Совместная работа уровней TCP/IP для обеспечения связи
320 IF.TF Datatrackei: https://datatracker.ietf.org/.
СтекТСР/1Р | 185
В стеке TCP/IP четыре уровня (начиная снизу)321:
Канальный уровень
Самый нижний в стеке. Он обслуживает аппаратное обеспечение (Ethernet, WiFi) и драйверы ядра. Отвечает за то, как пакеты отправляются между физическими устройствами. Подробности см. в разделе «Канальный уровень».
Межсетевой уровень
Межсетевой уровень реализует IP протокол и отвечает за маршрутизацию, то есть поддерживает отправку пакетов между машинами по сети. Мы обсудим это б разделе «Межсетевой уровень».
Транспортный уровень
Этот уровень контролирует сквозную коммуникацию между виртуальными или физическими хостами с помощью протокола управления передачей в сеансе с надежным соединением (Transmission Control Protocol — TCP), или протокола пользовательских датаграмм для коммуникации без установки соединения (User Datagram Protocol — UDP). Транспортный уровень в ответе за передачу пакетов включая адресацию служб через определенные порты, и за соблюдение целостности данных. Кроме прочего, Linux поддерживает сокеты в качестве конечных точек коммуникации. См. «Транспортный уровень».
Прикладной уровень
Этот уровень взаимодействует с пользовательскими инструментами и приложениями, такими как web, SSH и mail. Мы обсудим его в разделах «DNS» и «Сетевое взаимодействие на прикладном уровне».
ИНТЕРНЕТ И 0SI
История интернета начинается в шестидесятых годах с проекта Министерства обороны США по созданию сети связи, устойчивой к разрушению. Интернет — это сеть сетей: множество локальных сетей объединены с общей инфраструктурой, которая обеспечивает связь между системами.
Рано или поздно вы столкнетесь с моделью взаимодействия открытых селей (Open Systems Interconnection, или OSI) — теоретической моделью
321 Помимо данной класс иоикации существует модель OSI, из которой и вырос стек TCP/IP. Модель OS1 имеет 7 разных уров ней. Уровни частично пересекаются между этими двумя моделями. OSI более академическая. Она упоминается ниже. (Прим, ред.)
186 | Глава 7.Сетевое взаимодействие
сети из семи уровней (прикладной уровень — самый верхний, седьмой).
В модели стека TCP/IP всего четыре уровня, и именно его используют везде на практике.
Не запутайтесь в нумерации уровней. Уровень оборудования счита ется первым, канальный — вторым, межсетевой — третьим, транспорт- • ный — четвертым, но прикладной уровень всегда седьмой (так сложилось исторически, чтобы соответствовать модели OS1).
благодаря разделению на уровни, заголовок и данные одного составляю! полезную нагрузку для следующего. Как показано на рисунке 7 -2, данные для межсетевого уровня — это заголовок (НТ) и полезная нагрузка транспортного уровня. Иными словами, межсетевой уровень принимает пакет транспортного уровня как цельный набор байтов, не разбирая его структуру, и выполняет лишь собственную работу — переправляет пакет на целевую машину.
Давайте рассмотрим все уровни стека TCP/IP, начиная с нижнею, канального.
Канальный уровень
Канальный уровень стека TCP/IP имеет дело с аппаратной и околоаппаратной частями — байтами, проводами, электромагнитными волнами, драйверами устройств и сетевыми интерфейсами. Вот какие понятия вы встретите на этом уровне:
Ethernet
Семейство сетевых технологий Ethernet (ether «эфир» и network «сеть») используют провода для соединения машин. Обычно этот термин касается локальных вычислительных сетей (Local Area Network., или LAN, часто сокращают и выкидывают из термина вычислительные).
Бесприводное соединение
Этот класс сетевых протоколов и методов (известный, как Wi-Fi) вместо проводов использует для передачи данных электромагнитные волны.
Физический МАС-адрес
МАС-адрес, или физический адрес (сокращение от media access control — «контроль доступа к среде») — это уникальный 48 битный идентификатор оборудования для определения отдельной машины (точнее, сетевого интерфейса; см. далее). Обычно в первых 24 битах закодирован идентификатор организации — производителя карты (OUI).
Стек1СР/1Р | 187
Сетевой интерфейс
Это само соединение в виде физического интерфейса (подробнее в разделе «Контроллер сетевого интерфейса»), или виртуального (программного), например, интерфейса обратной петли 1о
Ознакомившись с основами, рассмотрим межсетевой уровень.
Контроллер сетевого интерфейса
Контроллер сетевого интерфейса (NIC)322, иногда называемый интерфейсом сетевой карты, обеспечивает физическое подключение к сети либо через проводной стандарт (IEEE 802.3-2018 для локальной сети323), либо через один из бесчисленных беспроводных стандартов семейства IEEE 802.11324. Реализовав подключение, NIC преобразует цифровое представление байтов, которые нужно отправить, в электрические или электромагнитные импульсы, а поступающие физические сигналы, наоборот, в биты и байты, понят ные программному обеспечению.
Давайте посмотрим, как работает сетевая карта. По традиции, информацию обо всех каргах в системе можно запросить ныне глубоко устаревшей командой if config325 (мы приводим ее в целях обучения, но на практике лучше использовать ip, как показано далее):
$ ifconfig
io: fiags=73<Ut>, LOOPBACK, RUNNING* mtu 65536 О
tnet 127.6.0 1 netmask 255.0.0.0
inet6::l prefixlen 128 scopeid 6xl0<host> loop txqueuelen 1000 (local loopback) RX packets 7218 bytes 677714 (677.7 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 7218 bytes 677714 (677.7 KB) TX errors 0 dropped 0 overruns 6 carrier 0 collisions 0
wlpls0: flags=4163<UP, BROADCAST, RUNNING, MULTICAST* ntu 1500 ®
inet 192.168.178.40 netmask 255.255.255.0 broadcast 192.168.178.255
inet6 fe80:: be87: e6G07de7: e08f prefixlen 64 scopeid 0x20<link>
322 Network interface controller: https://en.wiKipedia.org/wiki/Network .interface controller.
323 IEEE Standard for Ethernet: https://standards.ieee org/ieee/802.3/7071/.
324 IEEE 802.11: https://ieee802.org/! 1/.
325 ipcontig(S): https://www.manZ.org/linux/man- pages/man8/ifconfig.8.html.
188 | Глава 7. Сетевое взаимодействие
ether 38: de: ad:37:32:0t txqueuelen 1B06 (Ethernet)
RX packets 2398756 bytes 3003287387 (3.0 GB)
RX errors 0 dropped 7 overruns 0 frame 6
TX packets 504Э87 bytes 85467550 (85.4 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
О Первый интерфейс lo, интерфейс локальней петли с IP адресом 127.0.0.1 (см, «IPv4»). Максимальная единица передачи (MTU), или максимальный раз мер пакета, в данном случае 65 536 байт (с повышением значения повышается пропускная способность). Традиционно для локальной сети размер MTU — .500, но вы можете использовать так называемые «гигантские кадры» (jambo frames326): их размер может превышать MTU и передавать до 9000 байт за раз.
® Второму найденному интерфейсу wlplsO присвоен IP 192.168.178.40. Это сетевая карта с МАС-адресом (ether 38: de: ad:37:32:0f). Судя по флагам («UP, BROADCAST, RUNNING, MULTICAST*), похоже, активная.
Для запроса информации об интерфейсах и их статусах есть и более современная команда ip327. В этой главе мы будем чаще работать с ней (вывод урезан, чтобы влезал на экран):
5 ip link show
1: lo: «LOOPBACK, UP, LOWERJJP* ntu 65536 qdisc noqueue О
state UNKNOWN nooe DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 bed 00.00:00:00:00:00
2: wlplsO: «BROADCAST, MULTICAST, UP, LOWER _L'P> mtu 1500 qdisc noqueue ® state UP node DORMANT group default qlen 1300
link/ether 38: de: ad:37:32:0f brd ff: ff: ff: ff: ff: ff
О Интерфейс локальной петли.
© Моя сетевая карта с MAC -адресом 38: de: ad: 37:32: 0f. Обратите внимание на информацию, которую можно почерпнуть из названия (wlplsO): беспроводной интерфейс (wl) на PCI-шине 1 (pl) в слоте 0 (s0). Такой вид имен более предсказуем, чем старый, который не гарантировал, что два сетевых интерфейса (скажем, eth0 и ethl) не поменяли бы названия при добавлении новой сетевой карты.
326 Linux Configure Jumbo Frames to Boost Network Performance; https://www.cy5erciti.biz/faq/ rhel-centos-dcbian-uburtu-jumbo-frames-configuration/.
327 ip(8): https://www.man7.Org/linux/man-pages/man8/ip.8.htmi.
СгекТСР/IP | 189
Если в выводе команд ifconfig и ip link вас заинтересовали флаги LOWER_L'P или MULTICAST, то разъяснения их значений вы найдете в разделе netdevice328 справки man.
Протокол определения адреса
Протокол определения адреса (ARP) связывает МАС-адрес с IP-адресами. В некотором смысле это мост между канальным и межсетевым уровнем.
Давайте посмотрим, как он работает:
$ агр О
Add-ess	HWtype	HWaddress
mh9 inac.fritz.box	ether	90:25:4b:9b:64:49
fritz.box	ether	3c: a6:2f:8e:66: b3
Flags Mask Iface
C	wlpls0
C	wlplsO
О Командой агр мы выведи динамическую таблицу сопоставления МАС адресов с именами хостов или IP-адресами. Если вы хотите исключить преобразование IP адресов в доменные имена, передайте дополнительный параметр: агр -п.
Современный подход с использованием команды ip:
$ ip neigh ®
192.168.178.34 dev wlpls0 lladdr 00:25:4b:9b:64:49 STALE
192.168.178.1 dev wlplsP lladdr 3c: a6:2f:8e:66: b3 REACHABLE
О Отображение текущей таблицы сопоставлений МАС адресов с IP-адресами с помощью команды ip.
Для изучения, настройки и устранения неполадок для беспроводных устройств использует ся команда ip, К примеру, мой беспроводной сетевой адаптер называется wlplsB, и я могу опросить его:
$ iw dev wlplst info О Interface wlpls© ifindex 2 и/dev 0x1
addr 38: de: ad:37:32:0f ssid FRITZ I box 7536 QJ ©
328 netdevive(7): https://www.man7.Org/linaA/man-pages/man7/netdevice.7.html.
190 | Глава 7. Сетевое взаимодействие
tjipe managed
wtphy 0
channel 5 (2432 MHz), width: 20 MHz, centerl: 2432 MHz ®
txpower 20.00 dBm
О Вывод основной информации о беспроводном интерфейсе wlplsG.
® Маршрутизатор, к которому подключен интерфейс (подробности в следующем примере).
® Частотный диапазон WiFi, в котором работает интерфейс.
Более того, я могу получить информацию о маршрутизаторе и трафике:
$ iw dev wlplsG link О
Connected to 74:42:7f:67: ca: b5 (on wlplsG)
SSID: FRITZ! Box 7530 QJ
freq: 2432
RX: 28903606 bytes (45821 packets) ®
TX: 4993-101 bytes (1S605 packets)
signal: -67 dBm
tx bitrate: 6S.0 •'Bit/s MCS 6 short GI
bss *lags: short-preamble snort slot-time
dtin period; 1 beacon int: 100
О Вывод информации о подключении беспроводного интерфейса wlplsG.
® В этой и следующей строке статистика отправки (ТХ означает «передача») и приема (RX), то есть количество отправленных и полученных через интерфейс байтов и пакетов.
Теперь, когда мы выяснили, что происходит на нижнем (канальном) уровне передачи данных, поднимемся выше по стеку TCP/IP.
Межсетевой уровень
Второй снизу уровень стека TCP/IP называется межсетевым уровнем. Он отвечает за передачу пакетов между машинами в сети. Межсетевой уровень разработан с учетом того, что конструкция сети ненадежна, а участники (узлы в сети и соединения между ними) часто меняются.
СтекТСР,1Р | 191
Межсетевой уровень работает по принципу «делаю что могу» (то есть без гарантий стабильной производительности) и рассматривает каждый пакет как отдельный и независимый. Забота о целостности данных — отслеживание порядка пакетов, перезапросы при необходимости, гарантированная доставка — ложится на плечи более высокого уровня (как правило, транспортного).
МАРШРУТИЗАЦИЯ ПО АНАЛОГИИ С ОБЫЧНОЙ ПОЧТОЙ
Представьте, что адрес межсетевого уровня — это обычный почтовый адрес. Он состоит из нескольких частей, от самого широкого охвата (код страны) до информации о конкретной улице с номером дома.
Адреса достаточно, чтобы я отправил вам открытку из любой точки мира. Подробности транспортировки меня не интересуют (поедет открыт ха поездом или самолетом и по какому маршруту), и соглашение довольно простое: если я укажу правильный адрес и заплачу необходимую сумму (наклеив марку), почтовое отделение обязуется доставить мою открытку.
Так и ваш компьютер идентифицируется межсетевым уровнем через определенную форму адреса.
Главный протокол для идентификации машин, который используется л интернете повсеместно, — это IP (интернет-протокол). Он реализован в двух ва риактах; IP версии 4 (IPv4) и IP версии 6 (IPv6)
IPv4
Протокол IPv4 идентифицирует хосты или процессы, выступающие конечной точкой в коммуникации TCP/IP, с помощью уникального 32-битного числа.
Чтобы записать 32-битный IPv4 адрес, можно разбить его на четыре 8-битных сегмента, разделенных точкой. Каждый сегмент в диапазоне 0 255 называется октетом (намек на 8 бит). Посмотрим на примере:
63.32.106.149
I	I	1---------------------------------- ®
I	1---------------------------------------------------- «
1-------------------------------------------------------------- О
О Первый октет в двоичной форме: 60111111.
® Второй октет в двоичной форме: 00100000.
© Третий октет в двоичной форме: ?1101О19.
© Четвертый октет в двоичной форме: 10010101.
192 | Глава 7. Сетевое взаимодействие
Полный набор нолей в заголовке IP (рисунок 7-3) определяется RFC 791329 и сопутствующими спецификациями IETF. Ниже приведены наиболее важные, о которых следует знать:
Адрес источника (32 бита)
IP-адрес отправителя.
Адрес назначения (32 бита)
IP-адрес получателя
Протокол (8 бит)
Тип полезной нагрузки (более высокого уровня) согласно RFC 79O 330, например, TCP, UDP или ICMP.
Время жизни, TTL (8 бит)
Максимальное время существования пакета.
Тип обслуживания, ToS (8 бит)
Может использоваться для обеспечения качества обслуживания (QoS).
0	12	3
0 12 3	4|5 6 7	8 9 С 1 2 3 4 5	6 7 8	9 0 12 3	4 5 6 7 8 9 0 1
Верш	Длина заголовка	Тип обслуживания (TOS)	Общая длина		
Идентификатор пакета			Флаги	Смещение фрагмента	
Врем.» жизни (П L)		Протокол	Контрольная сумма заголовка		
Адрес отправителя					
Адрес получателя					
Параметры					Заполнение
Рисунок 7-3. Формат заголовка IP (RPC 791)
Поскольку интернет — это сеть из сетей, кажется разумным различать подсети и отдельные машины (хосты). Диапазоны IP-адресов назначаются сетям, а внутри адреса распределяются по отдельным хостам.
RFC 791: https://datatracker.ietf.org/doc/b_tml/rfc791.
RFC 790: https://datatracker.ietf.org/doc/html/rfc790.
СгекТСР/IP | 193
На сегодняшний день IP-адреса выделяются с помощью единственного актуального метода бесклассовой адресации (CIDR)33'. Формат CIDR составляется из двух частей:
—	Первая часть — это сетевой адрес, который похож на обычный IP: например, 19.0 0.3
—	Вторая часть определяет, сколько бит (а значит, IP-адресов) входит в диапазон: например, /24.
Вот как выглядит пример диапазона CIDR в целом:
10.0.0.0/24
Три октета (как и в предыдущем примере) представляют сеть, а последние 8 бит (32 бита минус 24 бита для сети) — эго IP адреса, доступные для 256 хостоь (28). Первый IP в указанном диапазоне CIDR — 10.0.0.0, а последний — 10 0.0.2S5 (но хостам могут быть присвоены только адреса от 10.0.0.1 до 10,0.0.254, поскольку .О и .255 зарезервированы для специальных целей). Кроме того, иг первых 24 битов, представляющих сеть, можно сделать вывод, что маска сети 255.255.255.0.
Помнить всю эту математику не обязательно. Если вы работаете с диапазонами C1DR постоянно, вы считываете все значения автоматически, а если вы случайный пользователь, то всегда найдутся полезные инструменты. Для расчета диапазонов CIDR, или вычисления количества IP-адресов в диапазоне, обратите внимание на следующие-
—	Онлайн-инструменты, такие как https://cidr.xyz и https://ipaddressguide. com/cidr.
—	Инструменты командной строки, например, napetdr и cidrchk (от вашего покорного слуги).
Важно знать о некоторых зарезервированных адресах и диапазонах IPv4:
127.9.0.0
Подсеть зарезервирована для локальных адресов, и наиболее значимый — адрес обратной петли 127.0.0.1 (ваша машина).
331 Classless Inter-Dcmain Routing: https;//en.wikipedLa.org/wiki/Classless Inter-Domain Routing.
194 | Глава 7. Сетевое взаимодействие
169.254.0.0/16 (169.254.0.0-169.254.255.255)
Диапазок локальных адресов. Пакеты, отправляемые на них, не должны пересылаться в другие части сети. Облачные провайдеры, например, Amazon Web Services, иногда задействуют их для специальных служб (для метаданных).
224.0.0.0/24 (224,0.0.0-239 ."255.255.255)
Диапазон, зарезервированный для многоадресной рассылки
RFC 1918332 вводит понятие частных IP-диапазонов. Адреса частных диапазонов не маршрутизируются з общедоступный интернет. Их можно безопасно назначать во внут ренней сети (в сети вашей компании, например):
— 10.0.0.0-11! 255.255.255 (сетевой префикс 10/8)
— 172.16.0.0-172.31.255.255 (сетевой префикс 172.16/12)
— 192.168.0.0-192.168.255.255 (сетевой префикс 192.168/16)
Еще один адрес IPv4, достойный внимания, — 0.0.0.0. Трактовка и использо -вание этого немаршрутизируемого адреса зависит от задачи, но важно помнить то, что с точки зрения сервера 0.0.0.0 относится ко всем 1Ру4-адресам на маши не. Отлично подходит для команд типа «прослушивай все доступные IP-адреса».
Разбавим теорию практикой. Для начала запросим у нашего компьютера ин формацию об 1Р (вывод урезан)'
$ ip addг show О
1: ,1л: «LOOPBACK, UP, LOWERJJP* mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00.00:00:00 brd 00:30:00:09:00:00 inet 127.0.0.1/8 scope host lo ® valld_lft forever preferred^lft forever inet6::1/128 scope host valid_lft forever preferred_lft forever
2: wlplsC: «BROADCAST, MULTICAST, UP, LOWER_UP> ntu 1500 qdisc r.oqueue state UP group default qlen 1000 link/ether 38: de: ad:37:32:0f brd ff: ff: ff: ff: ff: ff
inet 192.168 178.40/24 brd 192.168.178.255 scope global dynamic ®
332 RFC 1918: hrtps://datatrackcr’etf.crg/doc/htm./rfcl9!8.
(тек TCP/IP | 195
nop^efixrcute wlplse
valid_lft 863625sec preferred_lft 863625sec
inet6 fe80:: be87: e600:7de7: e08f/64 scope link noprefixroute valid_lft forever preferred_lft forever
О Список адресов на всех интерфейсах
® IP- адрес интерфейса обратной петли (127.0.0.1, как и ожидалось)
© (Частный) IP-адрес беспроводной сетевой карты. Обрати те внимание, что это локальный адрес в локальной сети (из диапазона 192.168/16), и он не маршрутизируется в публичную сеть
Учитывая, что конечных точек сегодня гораздо больше, чем предполагали разработчики интернета (из-за мобильных устройств и интернета вещей), и пространство адресов IPv4 уже исчерпано, требуется новое устойчивое решение.
Проблема исчерпания адресов решается переходом на IPv6. Жаль только, что на момент написания книги экосистема пока не использует этот протокол в полной мере: не готова инфраструктура и нет инструментария с поддержкой IPv6 Значит, пока вам придется иметь дело с протоколом IPv4, с его ограничениями и костылями333.
Давайте же заглянем в (надеюсь, не столь отдаленное) будущее — IPv6.
IPv6
Интернет-протокол версии 6 (IPv6)334 идентифицирует конечные точки 128-битным числом. С помощью IPv6 можно раздать адреса порядка 1036 отдельным машинам (или устройствам). В отличие от IPv4, IPv6 использует шестнадцатеричное представление — восемь разделенных двоеточием (:) групп, каждая по 16 бит.
Адреса IPv6 поддерживают сокращенную запись. Для удаления начальных нулей и сжатия последовательных групп с нулями можно использовать два двоеточия (::). Например, адрес обратной петли335 в IPv6 можно записать как : :1 (в варианте IPv4:127.0.0.1).
333 Why аге IPv4 addresses running out?: https://networkengineenng stackexchange corn/ cuestions/53933/why-are-ipv4-addresses- running-out.
334 IPv6: https://en.wikipedia.org/wiki/IPv6.
335 ISpecial Use IPv6 Addresses: https://datatracker.ietf.org/doc/html/rfc5156.
196 | Глава 7. Соевое взаимодействие
Как и в IPv4, в IPv6 есть специальные и зарезервированные адреса; примеры см. в списке типов адресов IPv6334 от APNIC.
Важно отметить, что IPv4 и IPv6 несовместимы. Для использования IPv6 каждый участник сети, от периферийного устройства (такого как ваш телефон) до маршрутизаторов и серверного программного обеспечения, должен поддерживать этот протокол. И поддержка уже довольно широка (особенно в рамках Linux). Например, команда ipaddr, работу которой мы видели в разделе «IPv4», по умолчанию уже выводит 1Ркб-адреса.
Протокол межсетевых управляющих сообщений
В RFC 79233’ описан протокол межсетевых управляющих сообщений (ICMP), который компоненты нижнего уровня используют для отправки сообщений об ошибках и эксплуатационной информации, например, о доступности.
Давайте посмотрим, как работает ICMP, проверив доступность веб-сайта ко мандой ping:
$ ping mheusenblas.info
PINC mhausenblas.info (185.199,109.153): 56 data bytes
64 bytes	from	185.199.109.153:	tcmp_seq-0	ttl=38	ttme=23.140	ms
64 bytes	from	18b.199.109.153:	icmpseq=l	ttl=38	time=23.237	ms
64 bytes	from	185.199.109.153:	icmp_seq-2	ttl=38	cime=:23.989	ms
64 bytes	from	185 199.109.153:	icnp_seq=3	ttl=38	time=24.028	ms
64 bytes	from	185.199.109.153:	icmp_seq-4	ttl-38	time=24.826	ms
64 bytes	from	185.199.109.153:	icmp_seq=5	ttl=38	time-23.579	ms
64 bytes	fron	185.199.109.153:	icmp_seq-6	ttl-38	time-22.984	ms
AC
--- mhausenblas.info ping statistics ---
7 packets transmitted, 7 packets received, 0.0% packet loss round-trip min/avg/nax/stddev = 22.984/23 683/24.826/0.599 ms
В качестве альтернативы предлагаю команду gping336 337 338. Опа умеет опрашивать (пинговать) сразу несколько целей и строить графики прямо п командной сгро ке (см. рисунок 7-4).
336 IPv6 address types: https://www.apnic.net/get-ip.'faqs/what is an-ip-addiess^ipv6 address types/.
337 Internet Control Message Protocol (ICMP): littps://datatracker.ietf.org/doc/btml/rfc792.
33“ gping: https://github com/orf/gping.
(тек TCP/IP | 197
mhausenblas.info (185.19min 22.111ms	max 30.9ms	p95 26.148ms	timeout# 0
cncf.io (23.185.0.3) min 21.165ms	max 30.198ms	p95 26.279ms	timeout# 0
31.852ms
29.718ms
27.584ms	й . I	j, .
25.45ms	; . -ИИ i-H	J	H ; . \ ’>=' .H
23.316ms	. . ..	...	:	>•: '		< 9 V , . .	'••• •- ; •• . . / '< Г' ’’
21.182ms
19.048ms
19:32:01	19:32:16	19:32:31
Рисунок 7-4. Одновременная проверка двух веб сайтов с помощью gping
Обратите внимание, что для IPv6 доступен аналогичный инструмент с метким названием ping6339 340.
Маршрутизация
Помимо прочего, сетевой стек в Linux занимается маршрутизацией, то есть анализирует пакеты и доставляет их адресату. Получатель может быть и локальным процессом, и IP адресом на другой машине.
Хотя углубленное изучение реализации выходит за рамки главы, мы все же пройдем по верхам. Широко известный инструмент iptables140 позволяет мани аудировать таблицами маршрутизации (перенаправлять пакеты по условиям или реализовывать брандмауэр), используя для перехвата и управления пакетами netfi'ter341
Вам будет полезно знать, как запрашивать и отображать информацию о маршрутизации:
$ suao route -п О Kernel IP routing table
Destination	Gateway	Gennask	Flags Metric		Ref	Use	Iface
0.0 0.0	192.168.178.1	0.0.0.®	UG	600	0	e	wlplsS
169.254.0.0	0.0.0.0	255.255.0.0	U	1600	0	0	wlpls?
192.168.178.0	0.0.0 e	255.255.255.0	U	660	0	0	wlplsE
О Вызов г oute с параметром - п, чтобы принудительно выводить IР- адреса в числовом формате.
339 ping6(8): https://linux.die.net/mar./8f ping6.
340 iptables: https77jvns.ca/blog/2O17/O6/O7/iptables basics/.
341 netftiter: https:/7www.netfilter.org/'.
198 | Глава 7. Сетевое ваимодезствие
А вот что означает каждый столбец в таблице, которую выдает route:
Destination
IP-адрес назначения (Э. 0.0.0 — получатель не указан или неизвестен, потенциальная передача на шлюз).
Gateway
Адрес шлюза для пакетов из разных сетей.
Genmask
Маска используемой подсети.
Flags
Флаги UG значит, что сеть активна и работает шлюзом.
Iface
Сетевой интерфейс, который будет использовать пакет.
Современный способ с помощью команды ip:
$ sudo ip route
default via 192.168.178.1 dev wlplsO proto dhep metric 600
169.2S4.0.0/16 dev wlplsts scope link metric 1000
192.16Я.178.0/24 dev wlplsO proto kernel scape link arc 192.168.178.40 metric 600
He упало ли соединение? Можно проверить:
$ traceroute mhausenblas.info
traceroute to mhausenblas.info (185.199.108.153), 30 hops max, 60 byte packets
1 _gateway (192.168.5.2) 1 350 ms 1.306 ms 1.293 ms
Обратите внимание: в разделе «Наблюдение» мы обсудим связанные с J СР/ IP инструменты для устранения неполадок и повышения производительности
В заключение я упомяну протокол граничного шлюза (Border Gate way Protocol, или BGF3’2), определенный в RFC 4271342 343 и IETF-спецификациях. Вряд ли вам придется иметь с ним дело напрямую (если вы не работаете у сетевого провайде
342 Border Gateway Protocol IBGP). https;/7en.wikipedia.org/wikr/Bordt:r_Gateway_ProtocoL
143 A Border Gateway Protocol 4 (BGP-4): https://datatracker.ietf.org/doc/btml/rfc4271.
Стек TCP/IP | 199
ра и нс администрируете сеть), но вы должны знать о его существовании, и в общих чертах понимать, зачем он нужен.
Мы уже упоминали, что интернет — это сеть сетей. В терминологии BGP сеть называется автономной системой (AS). Для работы IP-маршрутизации все авто номные сети должны обмениваться данными о доступности, объявляя маршруты для доставки пакетов через интернет.
После знакомства с адресацией и маршрутизацией сделаем следующий шаг вверх по стеку.
Транспортный уровень
Этот уровень целиком и полностью посвящен связи между конечными точками. Здесь существуют протоколы с поддержкой соединения и протоколы без соединения. Надежность, QoS и порядок доставки — примеры решаемых задач
В протоколах современной разработки (НТТР/З344) предпри-пимаются попытки объединить функ> ртоиал и переложить ча сти TCP на протоколы более высокого уровня.
Порты
Порты — одна из главных концепций этого уровня. Порты нужны каждому выбранному протоколу. Номером порта (уникальным 16-битным числом) идеи тифицируется любая служба, доступная по IP. Думайте об этом так: на одной (виртуальной) машине может быть запущено несколько служб (см. «Сетевое взаимодействие на прикладном уровне»), и вам необходимо разделять обращения к ним в рамках одною IP-адреса.
Различаются следующие группы портов:
Зарезервированные порты (от 0 до 1023)
Предназначаются для демонов, папример SSH или веб серверов. Использова кие, или привязка к одному из указанных портов, требует повышенных приви легий (root, или CAP.NET..B1NDSEWICE, как обсуждалось в разделе «Привилегии»),
Зарегистрированные порты (от 1024 до 49151)
Этот диапазон управляется Администрац ией адресного пространства интернета (Internet Assigned Numbers Authority или IANA) через опубликование документации.
344 The state of QL'IC and HTTP/3: https://www.fastly.coin/blog/state-of-quic-and-http3-2020
20C | Глава 7. Сетевое взаимодейааие
Динамические порты (от 49152 до 65535)
Динамические (или эфемерные) порты нельзя зарегистрировать. Их можно использовать для автоматического ^ременного выделения (к примеру, вашему приложению нужен сервер, а серверу нужен порт для создания точки подключения), а также для внутренних служб вашей компании.
Посмотреть привязки портов можно в файле /etc/services. Кроме того, в сети есть исчерпывающий список зарегистрированных TCP и Ъ'ОРэ45-портов, с которым вы можете сверяться в случае сомнений.
Следующей командой можно узнать, какие порты открыты на вашей машине (не выполняйте этот запрос на чужой машине или к внешнему IP):
$ пиар -Л localhost О
Starting Nmap 7.66 (https://nnap.crg) at 7021-09-19 14:53 1ST
Мшар scan report for localhost (127.0.0.1)
Host is up (0.00025s latency).
Not shown: 99Э closed ports
PORT STATE SERVICE VERSION
631/tcp open ipp CUPS 2.2 ®
| http-methods:
|_ Potentially risky methods: PUT
| http robots.txt: 1 disallowed entry
_/
|_http-server-header: CUPS/2.2 IPP/2.1
|_http-title: Home - CUPS 2.2.7
Service detection performed. Please report any incorrect results at https;//nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 6.93 seconds
О Сканирование портов локального компьютера.
® Найден один открытый порт — 631 (протокол интернет-печати IPP).
Уяснив предназначение портов, давайте посмотрим, как они используются в разных протоколах транспортного уровня.
315 List of TCP ana UDP port numbers: https./7en.wik;pedia.org,'wiki/List_of_TCP_and_UDP_ port, numbers.
СтекТСР/Ф | 2C1
Протокол управления передачей (TCP)
Протокол управления передачей (Transmission Control Protocol, или TCP) — это протокол транспортного уровня с поддержкой соединения, который используется рядом протоколов высшего уровня, включая HTTP и SSH (см. «Сетевое взаимодействие на прикладном уровне») на основе сеанса с гарантией доставки и соблюдения очередности, а также возможностью повторной передачи пакетов при ошибках.
Согласно RFC 793м6 и связанным спецификациям IETF, заголовок TCP (рисунок 7-5) включает следующие из наиболее важных полей:
Порт отправителя (16 бит)
Порт, который использовался отправителем.
Порт назначения (16 бит)
Порт принимающей стороны.
Порядковый номер (32 бита)
Используется для поддержки очередности передачи.
Номер подтверждения (32 бита)
Это число вместе с флагами SYN и АСК составляет основу так называемого «трехстороннего рукопожатия» TCP/IP547.
Флаги (9 бит)
Самые важные биты: SYN (синхронизировать) и АСК (подтверждение).
Окно (16 бит)
Размер окна (буфера) приема.
Контрольная сумма (16 бит)
Контрольная сумма заголовка TCP для сверки ошибок.
Данные
Полезная нагрузка для транспортировки * 347
Transmission Control Protocol (TCP), https://datatracker.ietf.org/doc/html/rfc793.
347 TCP/IP three-way handshake. https://en.wikipedia.org/wiki/Transmission_Control_ Protocol#Connection_establishment.
202 | Глава 7. Сетевое взаимодействие
0	12	3
0 12 3	4 5 6 7 8 9	0	1	2	3	4	5	6 7 8 9 0 1 2 3	4 5 6 7 8 9 0 1
Номер порта отправителя								Номер порта получателя	
Порядковый номер									
Номер подтверждения									
Смещение данных	Зарезервировано	и R G	А С К	Р S н	R S Т	S Y N	F I N	Размер окна	
Контрольная сумма								Указатель срочности	
Параметры									Заполнение
Данные									
Рисунок 7-5. Заголовок TCP в формате RFC 793
TCP отслеживав! соединение от установки до завершения. При этом и отправителю, и получателю приходится согласовывать нюансы — от объема данных (размер окна TCP) до качества обслуживания (QoS).
С точки зрения безопасности TCP никак не защитен. Полезная нагрузка отправляется в виде обычного текста, поэтому любой узел между отправителем и получателем (а по замыслу таких узлов много) может разобрать пакет. (В разделе «Wireshark и tshark» вы узнаете, как проверять полезную нагрузку пакетов.) Для передачи шифрованных сообщений нужно использовать другой протокол — Transport Layer Security (TLS), в идеальном случае версии 1.3 согласно RFC 8446.
Теперь рассмотрим важнейший протокол транспортного уровня без отслеживания состояния — UOP.
Протокол пользовательских датаграмм (UDP)
Протокол пользовательских датаграмм (User Datagram Protocol, или UDP) — это протокол транспортного уровня, который позволяет слать сообщения (датаграммы) без первичных шагов для установки соединения (таких, как «рукопожатия» в TCP). Но и он поддерживает контрольные суммы для обеспечения целостности. UDP использует целый ряд протоколов на уровне приложений — NTP и DHCP (см. «Сетевое взаимодействие на прикладному уровне»), или DNS (см. «DNS»).
Стек TCP/IP | 203
На рисунке 7-6 показан формат заголовка UDP, Согласно определению RFC 768, различаются наиболее важные поля:
Исходный порт (16 бит)
Порт отправителя — необязательный, по умолчанию 0.
Порт назначения (16 бит)
Порт принимающей стороны.
Длина (16 бит)
Суммарная длина заголовка UDP и данных.
Контрольная сумма (16 бит)
При необходимости может исполвзоватося для проверки ошибок.
Данные
Полезная нагрузка датаграммы.
UDP — крайне простой протокол. Он создан с ожиданием, что протокол более высокого уровня позаботится обо всех нюансах, которые протокол TCP берет на себя. С другой стороны, пропускная способность UDP выше за счет небольших накладных расходов, и он проще в использовании (см. страницу руководства по UDP348).
148 udp(7): https://linux.die.net/man/7/udp.
204 | Глава7.Се1евоевзаймодейсгвие
Сокеты
Сокеты (от английского socket’49 — «разъем») — это предоставляемый Linux высокоуровневый интерфейс, который можно воспринимать как конечную точку, идентифицированную связкой из IP-адреса и TCP/UDP порта.
Вероятно, вы столкнетесь с сокетами, только если захотите разрабатывать сетевые инструменты и приложения, но, по крайней мере, вам будет полезно уметь их опрашивать. При работе с демоном Docker, например, вам нужно будет знать о необходимых разрешениях для сокета.
Давайте посмотрим, как запрашивать информацию о сокетах с помощью команды SS* 350.
Предположим, нас интересует обзор TCP сокетов в системе:
$ ss -s О
Total: 913 (kernel 0)
TCP: 10 (estab 4, closed 1, orphaned 0, synrecv 0, timewait 1/0), ports 0 ®
Transport Total		IP	IPv6 ®
*	0	-	-
RAN	1	0	1
UDP	10	8	2
TCP	9	8	1
WET	20	16	4
FRAG	0	0	0
® Командой ss опрашиваются порты (а с параметром -s мы получим сводку).
® Сводка no TCP — используется 10 сокетов.
© Детальная статистика с разбивкой по типу и версии IP.
A UDP? Можно ли запросить даже более подробную информацию с выводом IP-адресов на конечных точках? Да, ss может и это (вывод урезан):
$ ss -ulp О
State Recv-Q Send Q Local Address:Port Peer Address:Port
UNCONN 0	0	0.0.0.0:60360	0.0.0.0:*
UNCONN 0	e	12Z.e.0.S3%lc-:doinaTn	0.0.0.0:*
socket(7): bttps://wwv;.mar.7.org/lmux/man-pages/mar:7;sockei.7.htmL
350 ss(8): https://www.man7.org/linux/man-pages/Fnan8/ss.8.htm).
СтекТСР/IP | 205
UNCONN	0	в	0.0.0.Э: bootpc	0.0.0.0:*
UNCONN	0	0	0.0.0.0: ipp	0.0.0.0:*
UNCONN	0	0	0.0 9.0: mctns	0.0.0.0:*
UNCONN	0	0	[::]:ndns	[::]:*
UNCONN	0	0	[::]:38359	[::]=*
о Вызываем ss: параметр -и ограничивает сокеты протоколом UDP, -I выбирает прослушиваемые сокеты, а -р добавляет информацию о процессах (в нашем случае ее нет).
Другой инструмент, полезный в рамках сокетов и процессов, — Lsofзм. Проверим, какие UDP-сокеты использует Chrome на моей машине (вывод отредактирован):
$ Isof -c chrome -i		udp |	| head -5 О			
COMMAND	PID USER	FD	TYPE	DEVICE	NODE	NAMF
chrome	3131 mn9	cwd	DIR	0,5	265463	/ргос/5321/fdi.nfo
chrome	3131 mh9	rtd	DTR	0.5	265463	/proc/5321/fdinfo
chrome	3131 mh9	txt	REG	253,0	3673554	/opt/google/chrome/chromc
chrome	3131 r.h9	mem	REG	253,0	3673563	/opt/google/chrome/icudtl.dat
chrome	3131 mh9	mem	REG	253,0	12986737	/us r/lib/locale/locale-archive
О Запуск Isof с параметрами: -с для выбора конкретного процесса по имени,
-г для ограничения no UDP. Обратите внимание, что десятки строк вывода я урезал до пяти командой head -5, присоединенной в конвейер.
Итак, мы ознакомились с тремя нижними уровнями стека TCP/IP. На следующем уровне приложений происходит столько всего, что я отвел ему два раздела. Мы изучим глобальную систему именований, а после рассмотрим ряд протоколов и приложений прикладного (или седьмого) уровня — например, веб.
DNS
Мы уже знаем, что интернет-слой стека TCP/IP определяет IP-адреса, которыми идентифицируются виртуальные и физические машины. При рассмотрении «Контейнеров» мы даже назначали отдельным контейнерам IP-адреса. Однако *
551 lsof(8): https://man7.crg/linux/iiiaii- pages/ maa8/lsof.8.htmL
206 | Глава 7 Сетевое взаимодействие
с числовыми адресами (в любом формате, IPv4 или IPv6) связаны две особен ности:
—	Нам, людям, куда удобнее запоминать названия, чем числа (а тем более длинные) Когда вы рекомендуете другу веб-сайт, вы просите ею заглянуть на ietf.org, а не на 4.31.198.44
—	Интернет и его приложения устроены так, что IP-адреса часто меняются — при переназначении новых адресов обычному серверу, или при переносе современной контейнерной конфигурации на другой хост с автоматической сменой IP.
Итак, IP-адрес трудно запомнить, он может измениться, а название (имя сер вера или сервиса) останется прежним Проблема древняя, как интернет, и существует с тех пор, как UNIX стал поддерживать стек TCP/IP.
Изначальный способ решения состоял в том, чтобы локально (в рамках од ной машины) поддерживать сопоставление имен с IP-адресами через файл /etc/ hosts. А сетевой информационный центр (NIC) распространял файл HOSTS.TXT по FTP.
Очень скоро выяснилось, что такая централизация не успевает за разраста нием интернета, и в начале 1980 х была разработана распределенная система. Ее ведущим архитектором стал Пол Мокапетрис.
DNS — это общемировая иерархия названий хостов и служб в интернете. Хотя есть множество связанных с ней RFC, исходный RFC 1034зи и руководство по реализации RFC 1035352 353 по-прежнему актуальны. Я рекомендую вам ознакомиться с ними, чтобы узнать больше о начальной мотивации и замысле.
С DNS связано множество понятий, но среди них выделяются основные:
Пространство доменных имен
Это древовидная структура, с корнем в «.», в которой каждое ответвление и узел содержит информацию об определенном пространстве имен. Каждая метка (максимальная длина 63 байта) на пути от отдельного узла к корню известна нам под названием «полное доменное имя» (Fully Qualified Domain Name или FQDN). К примеру demo.mhausenblas.info. — это FQDN с так называемым «доменом верхнего уровня» .info. Обратите внимание, что самая правая точка, обозначающая общий корень, часто опускается.
352 Domain names — concepts and facilities: https://daUtracker.ietf org/doc/btml/rfcl034.
353 Domain names — implementation and specification: https://datatracker.ietf.org/doc/html/ rfclO35.
DNS | 207
Ресурсные записи
Информация в ответвлениях и узлах пространства доменных имен (см. «DNS-записи»).
Серверы имен
Серверные программы, которые хранят информацию о структуре дерева доменов. Сервер с полной информацией о пространстве называется доверенным сервером имен. Доверенная информация организуется в доменные зоны.
Резолверы
Резолвер (иногда DNS-резолвер, калька с английского resolver — «определи тень») — это локальная программа, которая в ответ на запрос клиента возвращает информацию, извлеченную из серверов имен. Явный протокол обмена с клиентом не определен. Очень часто резолверы поддерживают библиотечные вызовы для повторного разрешения DNS.
На рисунке 7-7 показана полная конфигурация системы DNS согласно RFC 1035, включая пользовате>1ьскую программу, резолвер и сервер(ы) имен. В про цессе запроса резолвер либо сам последовательно опрашивает доверенные сер веры имен (NS) начиная от корня, либо по возможности использует рекурсивный запрос, при котором NS опрашивает другие серверы от имени резолвера.
Рисунок 7-7. Полная конфигурация DNS
208 | Глава 7. Сетевое взаимодействие
Хотя конфигурация DNS-резолвера354 из /etc/resol v. con/по-прежнему поддерживается, в современных системах ее почти не используют, особенно при развернутом DHCP (см. «Протокол динамической конфигурации хоста»).
В основе иерархической системы имен 13 корневых серверов355 356 357 * *, управляющих записями для доменов верхнего уровня. Непосредственно под корнем находятся домены верхнего уровня (TLD)”6:
Инфраструктурный домен верхнего уровня
Управляется IANA от имени 1ETF и включает такие домены, как example и localhost.
Международные домены верхнего уровня (generic wiugTLD)
Международные (общие) домены верхнего уровня содержат от трех и более символов, например, org или .сот.
Национальные домены верхнего уровня (country-code или ccTI.D)
Для стран и территорий, которым присвоены двухбуквенные коды ISO557.
Спонсируемые домены верхнего уровня (sponsored, или sTLD)
Для закрытых агентств и организаций, которые сами устанавливают и обеспечивают соблюдение правил использования доменов верхнего уровня, например, aero и .gov
Давайте углубимся в механики DNS и примеры их использования.
DNS-записи
Сервер имен управляет записями, в которых фиксируется тип, целевая информация и дополнительные поля, включая время жизни (TTI. это период времени, после которого запись должна быть удалена). Если FQDN это адрес узла, то ресурсные записи (RR) — это данные, которые хранит узел.
DNS определяет целый ряд типов записей3”. Ниже представлены самые важные (в алфавитном порядке):
34 resolv.conf(5): https://www.man7.org/li nux/man-pages/man5/resolv coni.5.html.
355 Root Servers: https://www.iana.org/doniains/root/servers.
356 Top-level domain: https://en.wikipedia.org/wiki/Top-levef_comam.
357 Two-letter country codes defined in )SO 3166-1: https://en.wikipcdia.org/wiki/ISO_.3166-l_
alpha-2.
35# List of DNS record types: https:Л'еп. wikipedia.org/wiki/List_of_DNS_record_ .types.
DNS | 209
А-записи (RFC 1035) и АААА-записи (RFC 3596)
Этот тип записей (для IPv4 и IPv6 соответственно) обычно используется для сопоставления имен хостов с их 1Р-адресами.
Записи CNAHE (RFC 1035)
Канонические записи, представляющие псевдонимы для имеющихся имея.
Записи NS (RFC 1035)
Записи о серверах имен, делегирующих зону DNS для использования доверенных серверов имен.
Записи PTR (RFC 1035)
Записи-указатели, используемые для выполнения обратного поиска в DNS; противоположность записям А.
Записи SR7 (RFC 2782)
Записи локатора служб — с обоб11 щнным меха!  измом обнаружения, а не жест-ко указанные (как это обычно было в классических MX-записях для почтового обмена).
Записи TXT (RFC 1035)
Текстовые записи. Изначально предназначались для произвольных пометок, понятных человеку, но со временем нашли особое применение. Сегодня часто хранят инструкции для машин в рамках, связанных с безопасностью расширений DNS.
Записи с подстановочной меткой359, то есть с начальной звездочкой (*), например, *.mhausenblas.info, часто используется как универсальный способ сопоставлять запросы с потенциальными, но несуществующими именами.
Давайте взглянем на записи из реального мира. Записи DNS представлены в виде текста в файле зоны360, который сервер имен (например, bind36) считывает и включает в свою базу данных:
SORIGIN exanple.com. О
$TTL 3600 ® * 361
353 Wildcard DNS record: https://enMTkipedia.org/wiki/Wildcard_DNS_record.
160 DNS Zone file: https://en.wikipedia.org/wiki/Zone_file.
361 BIND 9 DNS Protocol: https://gitlab.isc.oig/isc-projects/bind9.
21G | Глгвг 7. Greece вза имодействие
@ SOA nse.example.com. nsmaster.example.cont. (
1234567890 ;		serial number
21600	*	refresh after 6 hours
3606	>	retry after 1 hour
604800	>	expire after 1 week
3600)	»	minimum TIL of 1 hour
example.com. IN	NS	nse Ф
example.com. IN	MX	10 mail.exanple.com. О
example.com. IN	A	1.2 3.4 ©
nse	IN	A	5.6.7.8 Ф
www	IN	CW.E	example.com. 9
mail	IN	A	9.0.0.9 ©
О Начало файла зоны в пространстве имен.
® Время жизни по умолчанию в секундах для всех RR, где TTL не определен спе -циально.
® Сервер имен для этого домена.
© Почтовый сервер для этого домена.
© Адреса IPv4 для этого домена.
Ф Адреса IPv4 для сервера имен.
9 Назначение www. example, соя псевдонимом для этого домена (для example.con).
G IPv4 адрес почтового сервера.
Объединив полученные знания, мы можем понять пример с рисунка 7-8. Там показана часть глобального пространства доменных имен с одним полным доменным именем (FQDN) — demo.mhousenblas. info:
. info
Общий домен верхнего уровня, управляемый компанией Afinas’62.
mhausenblos.info
Домен, коюрый я купил, и внутри доменной зоны которого волен назначать поддомены по своему усмотрению.
derno.ithausenblas. info
Поддомен, который я завел для примера.
162 Afilias: https://afilias.info.
DNS | 211
Рисунок 7-8. Пространство доменных имен с примером FQDN
Заметьте, что в моем случае Afalias и я заботились каждый о своей части без всякой координации. Чтобы создать демонстрационный поддомен, я лишь изменил настройки DNS для зоны, не запрашивая у Afilias помощи или разреше ний. Внешняя простота в основе децентрализованной природы DNS и делает эту технологию такой масштабируемой.
Познакомившись со структурой пространства доменных имен и его узлов, посмотрим, какую информацию мы можем извлечь.
DNS запросы
Имея под рукой инфраструктуру (преимущественно сервера имен и резолверы), рассмотрим выполнение DNS-запросов. В оценке финального результата много логики (описанной в RTC 1034 и 1035): выходящей за рамки книги, поэтому не будем слишком погружаться в детали.
Для запроса локальных (и глобальных) имен для преобразования их в IP-адреса, и наоборот, можно использовать команду host:
$ host -a localhost О
Trying "localhost.fritz.box"
Trying "localhost"
212 | Глава 7. Сегевое взаимодействие
;; -»HEADER«- opcode: QUERY, status: NOERROR, id: 4915®
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION: ; localhost.	IN ANY
;; ANSWER SECTION: localhost.	0	IN A	127,0.0.1
localhost.	0	IN aAAA	::1
Received 71 bytes from 127 0.0.53#53 in 0 ms
$ host mhausenblas,infо ®
mhausenblas.info has address 135.199.110.153
mhausenblas.info has address 185.199.109.153
mhausenblas.info has address 185.199.111.153
mhausenblas.info has address 185.199.108.153
$ host 185.199.110.153 ®
153.110.199.185.in-addr.arpa domain name pointer cdn-185-199-110-153.github.com.
® Определение локальных IP-адресов.
О Определение FQDN.
® Обратный поиск IP для нахождения FQDN (похоже, это один из GitHub CDN).
Куда удобнее отображать записи DNS командой dig-
$ dig mhausenblas.info О
; «» DiC 9.10.6 «» mhausenblas. inf о
;; global options: -emd
;; Got answer:
;; -»HEADER«- opcode: QUERY, status: NOERROR, id: 43159
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 2, ADDITIONAL: 5
;; OPT PSEUDOSECTION:
; EONS: version: 9, flags:; ucp: 1232
;; QUESTION SECTION:
; mhausenblas.info.	IN A
DNS | 213
;; ANSWER SECTION: ®
mhauseriblas.info.	1799	IN	A	185.199.111 153	
nhausenblas.info.	1799	IN	A		185.199.108.153
nhausenblas.info.	1799	IN	A		185.199.1Э9.153
nhausenblas.info.	1799	IN	A		185 199.110.153
;; AUTHORITY SECTION: ©				
nhausenblas.info.	180Э	TN	NS		dnsi.regtstrar-servers com.
nhausenblas.info.	1800	IN	NS		dns2.regtstrar-servers com.
;; ADDITIONAL SECTION:				
dnsl.registrar.servers.com.	47950	IN	A	156.154.132.200
dns2 .registrar-servers.com.	47950	IN	A	156.154.133.200
dnsl.registrar-servers.com.	28666	IN	AAAA	2610: al:1024::200
dns2.registrar-servers.com.	28666	IN	aAAA	2610: al:1025::200
;; Query time: 58 msec
;; SERVER: 172.16.173.64#53(172.16.173.64)
;; WHEN: Wed Sep 15 19:22:26 1ST 2021
;; MSC SIZE rcvd: 256
О Командой dig найти записи DNS для FQDN nhausenblas. info, ® А-записи DNS
Ф Доверенный сервер имен.
Есть и другие альтернативы команде dig, в частности dog и nslockup (см «Приложение Б»).
।—СЬ~т	Иы ве Ра-3 услышите такое высказывание: «Ой, да это всегда DNS».
Что бы оно значило? Речь о том, что при устранении неполадок важно помнить, что DNS — это распределенная база данных со множеством независимых частей. Отлаживая проблемы, принимайте в расчет TTL записей и помните о многочисленных кэ
шах, начиная с локальных в вашем приложении до кэшей распоз
навателя и всего, что находится между вами и серверами имен. В
В разделе «Записи DNS» мы упомянули тип SRV, который служит универсаль ным локатором. Вместо тою чтобы вводить в RFC отдельный тип записи для но вой службы, сообщество придумало универсальный метод адресации для любого
214 | Глава 7. Сетевое взаимодействи t
потенциального типа службы с помощью записей SRV, используемых для пере дачи IP-адреса и порта службы через DNS (этот механизм описан в RFC 278236’).
Взглянем на пример. Допустим, мы хотим узнать, какие службы чата, а тсч нее, службы расширяемого протокола обмена сообщениями и информацией о присутствии (Extensible Messaging and Presence Protocol (XMPP)) доступны и присутствуют ли вообще:
$ dig +short _xnpp-client._tcp.gmaU.coi4. SRV О
20 0 S222 alt3.xmpp.I.google.com.
5 0 5222 xr.pp.I.google.com ®
20 0 5222 alt4.xmpp.I.google.com.
20 0 52.22 alt2.xmpp.I.google.com.
20 0 5222 altl.xmpp.I.google.com.
О Выпол няем dig с опцией +sho rt, чтобы отобразить только интересующий раздел ответа. _хпрр-client. _tcp — это формат, предписанный RFC 2782, a SRV в конце команды указывает, какой тип записи нас интересует
в Имеются пять ответов. Экземпляр сервиса доступен по адресу; хтрр. I. google, сот:5222со временем жизни (TTL) 5 секунд. Если у вас естьХМРР, например, Jabber, вы можете использовать этот адрес для передачи конфигурации.
На этом мы заканчиваем разбор DNS и переходим к другим протоколам и инструментам прикладного уровня.
Сетевое взаимодействие на прикладном уровне
В этом разделе мы сосредоточимся на работе в пользовательском пространстве, или сетевых протоколах прикладного уровня, инструментах и приложениях. Как пользователь вы проводите массу времени, используя браузеры или почтовые клиенты при решении повседневных задач.
Интернет (Web)
Веб, изначально разработанный сэром Тимом Бернерсом-Ли в начале 1990 х годов, состоит из трех основных компонентов:
363 «А DNS RR for specifying the location of services (DNS SRV)»- https:/,'datatr acker ietf.org'doc/ html/rfc2782.
Сетевое взаимодействие на прикладном уровне | 215
Универсальный локатор ресурсов (Uniform Resource Locators - URL)
Согласно изначальному RFC 1738*4 и ряду обновленных связанных RFC, URL отвечает за идентификацию и определение местоположения ресурса в сети. Ресурс может быть и статической страницей, и процессом, который генерирует содержимое на лету.
Протокол передачи гипертекста (HyperText Transfer Protocol — HTTP)
В этом протоколе прикладного уровня описано, как взаимодействовать с содержимым, доступным через URL. В RFC 2616364 365 для HTTP vl.l, в более современном RFC 7540366 для НТТР/2, а также в черновике проекта НТТР/'З367 * (который на момент написания книти все еще разрабатывается), для HTTP определяются следующие основные понятия:
HTTP-методы
Вместе с GET для операций чтения и, среди прочих, с POST для операций запи си, методы определяют интерфейсы, подобные CRUD.
Именование ресурсов369
Правила для формирования URL-адресов.
Коды статусов HTTP370
Числовой диапазон 2хх соответствует успешному выполнению, Зхх — пере направлению, 4хх — ошибкам на стороне клиента, 5хх — ошибкам на сервере.
Язык гипертекстовой разметки (Hyper Text Markup Language — HTML)
Сегодня HTML (изначально определенный спецификацией W3C) — это жи-вой стандарт, публикуемый через WHATWG371. С гипертекстовой разметкой можно задавать элементы страницы, например заголовки или поля для ввода.
364 Uniform Resource Locators (URL): https://datatracker.kerf.org/doc/html/rfcl738.
365 Hypertext Transfer Protocol (НТТР/1.1): https://datatracker.ietf.org/doc/html/rfc2616/.
366 I lypertext Transfer Protocol Version 2 (HTTP/2): https://datatracker.ietf.org/doc/btn: l/rfc7 540.
мт h.TTP/3: https://datatracker.ietf.org/doc/html/rfc9114.
збя yiTTp Methods: https://www.restapitutoriaJ,com/introduction/httpmethods.
ж Resource naming: https://www.restapitutorial.com/introducticn/resourcenaming.
37C Http Status Cedes: https://www.restapitutorial.com/httpstatuscodes.
371 HTML: Living Standard: https://htm1.spec.what wg.org'multipage/.
216 | Глава 7. Сетевое взаимодействие
W3C И СТАНДАРТЫ
С технической точки зрения IETF и Консорциум интернета W3C не разрабатывают никаких стандартов. Они лишь формализуют процессы по созданию спецификаций, которые сообщество примет за фактические стандарты. Я настоятельно рекомендую вам ознакомиться с этими спецификациями и попробовать разобраться, что там происходит. Лично я серьезно погрузился в них только в 2006 году, после десяти лет пользования и создания сайтов, когда сам подключился к работе W3C. И отдача была колоссальной.
Взглянем на правила, по которым строятся URI (универсальные), и как эти правила (RFC 3986) согласуются с HTTP URL:
mi chaelh:123456 78@http://example.cor:4242/this/is/the/way ?oristt=reallyfranother
\ / \ / \ / \	/\	/ \	/ \ /
I	I	I V	V	V	I V	I V	I	I V	V
user password scheme	authority	path	query fragment
Компоненты:
Имя пользователя и пароль (user и password, оба необязательные)
Эти компоненты, изначально предназначенные для базовой аутентификации, устарели и не должны использоваться. Следует применять методы проверки подлинности371 372, совмещенные с шифрованием соединения (HTTPS373).
Схема (scheme)
Относится к определенной в спецификации IETF схеме URL374. Для IITTP схема называется http (на самом деле объединяя в себе целое семейство спецификаций HTTP, например, RFC 2616).
Полномочия (authority)
Иерархическая часть именования. Для HTTP включает в себя:
371 HTTP authentication: https://developer.mozUli.org/'rj./cocs.'Web/HTTP/Gj:des/A„thentica-
tion.
373 HTTPS: https://en.wikipedia.org/wiki/HTTPS.
374 Guidelines for new URL Schemes: https://datatracker.ietf.org/doc/html/rfc2718.
Сетевое взаимодействие на прикладном уровне | 217
Имя хоста
Полное доменное имя DNS или 1Р-адрес.
Порт
Значение по умолчанию равно 80 (записи example.com:80 и example.com равнозначны).
Путь (path)
Специфичный для схемы подробный путь к ресурсу.
Параметры запроса и фрагмент (query и fragment, оба необязательные)
Параметры запроса добавляю! ся после символа? для неиерархической информации (например, для ввода тегов или данных с формы), а фрагмент следует за символом # для вторичного ресурса (в рамках HTML это может быть раздел содержимого).
Интернет сильно вырос над скромными корнями из 1990 х, и ряд таких тех пологий, как JavaScript/ECMAScript375 (для динамического управления содержимым) или каскадные таблицы стилей GSS376 377 * 379 (для стилизации), стали ключевыми. Их развитие привело к появлению одностраничных приложений’77. Хотя эта тема выходит за рамки книги, знание основ (URL, HTTP и HTML) очень пригодится, когда вы будете вникать, как все работает, или устранять возни кающие неполадки.
Теперь посмотрим на веб-спецификации в действии, симулируя каждый шаг (начиная с конечной точки HTTP сервера). Запустить собственный НТТР-сервер, который обслуживает содержимое каталога, можно довольно просто, и даже двумя способами: с помощью Python778 или netcat (не)37’.
Чтобы запустить сервер на содержимом каталога с помощью Python, сделайте следующее:
$ python3 -и http.server О
Serving HTTP on :: port 8000 (http://[::]:8000/) ... ®
::ffff:127.0.0.1 - - [21/Sep/2621 08:53:53] "GET / HTTP/1.1" 200 - ®
375 JavaScript/ECMAScript: https://en.wikipedia.org/wiki/ECMAScript.
37C Cascading Style Sheets (CSS): https://www.w3.org/Style/CSS/Ovcrview.en.html.
377 Single-page application: https://en.wikipedka.org/wiki/Suigle page_application.
37‘ «How do you set up a local testing server?»: https-//developer.mozilla.org/docs/Learn_web_ devclopment/Howto/Tools_and_setup/sel_up_a Jocal_iesting_server.
379 «How to make a webserver with netcat (nc)»: https://jameshfisher.com/2018/12/31/how-to-make-a-webserver-wtth-netcat-nc/.
218 | Глава 7. Сетевое взаимодействие
О Используя встроенный в Python модуль http.server, запускает сервер с содержимым текущего каталога (иди каталога, из которого запущена команда). ® Получаем подтверждение, что сервер слушает на корту 8000. Это значит, что если вы введете в строке браузера http://localhosf.8000, то увидите содержимое своего каталога.
® Видим, что HTTP-запрос к корню (/) был отправлен и успешно обработан (код ответа HTTP 200).
Если хотите что-нибудь покруче обслуживания статических файлов в каталоге, посмотрите в сторону полноценного вебсервера. Например, вы можете запустить NGINX380 в Docker (см. «Docker»), используя следующую команду:
$ docker run --name mywebserver \ О
--rm -d \ ®
-v "$PWD":/usr/sharfc/ngi.nx/btml:ro \ ®
-p 8042:86 \ ©
nginx: 1.2.1 ®
О Вызываем работающий контейнер mywebserver (вы должны видеть его в списке работающих контейнеров при запуске dockerps).
® Параметр - - гл заставит контейнер удалиться при выходе, a -d превратит его в демон (отключит от терминала и переведет в фоновый режим)
® Монтируем текущий каталог ($PWD) в контейнер в качестве каталога содержимого для NGINX. Обратите внимание, что $PWD — это переменная bash для обращения к текущему каталогу. В Fish нужно использовать (pwd)
о Делаем внутренний порт контейнера 80 доступным через порт 8С42 на хосте. Это значит, что получить доступ к веб серверу можно через адрес: http.!ilocalhost:8042 на вашем компьютере.
© Используем образ контейнера (nginx: 1.21) из Dockerllub, поскольку явно не указали реестр.
’80 NGINX Documentation: https://docs.nginx.com/.
Сетевое взаимодействие на прикладном уровне | 219
Теперь с помощью curl’81 — мощного и популярного инструмента для взаимодействия с любыми URL-адресами — получим содержимое ст созданного нами веб-сервера (проверьте, что он еще работает, и запустите снова, если вы его уже закрыли):
$ curl localhost:8000
<! DOCrYPL HTML PUBlIC '4//W3C//DTD HTML 4.O1//LN"
"http://www.w3 org/TR/html4/strict.dtd">
<html>
<head>
<meta> http-equiv="Content-Type" content="text/html; charset-utf-8">
<title>Directory listing for /</title>
</head>
<body>
<hl>Directory listing for /</hl>
<hr>
<ul>
<li><a href=''app. ya-nl'Sapp.yanl</a></li>
<Ii><a href="Dockerfile">Dockerftle</ax/li>
<li><a h ref="exempte.j son"sexample.json</a></li>
<lixa href="gh-user-info. sh">gh-user-in*o.sb</ax/li>
<tixa href="nain go,l>piain.go</ax/li>
<lixa href=''script.sh">script.sh</ax/li>
<lixa href="test">test</ax/li>
</ul>
<hr>
</body>
</html>
В таблице 7-1 я перечислил основные параметры curl, которые могут оказаться полезными. Я выбирал их, исходя из собственного опыта в решении различ ных задач, от разработки до системного администрирования.
Если curl недоступен, можно воспользоваться wget’82. У него меньше воз можностей, но и он осилит простые взаимодействия с HTTP.
381 curl: https://curl.se/.
382 wget: https://www.gnu.org/software/wgey
220 | Глава 7. Сетевое взаимодействие
Таблица 7-1. Полезные параметры curl
Параметр	Длинная запись	Описание и случаи использования
-V	--verbose	Подробный вывод, используется для отладки
-s	- silent	Тихий curl: не выводить индикатор выполнен ия и сообщен ия сб ошибках
-L	--location	Следовать перенаправлениям (коды ответов HTTP ЗХХ)
-0	--output	По умолчанию результат отправляется на stdout. Если хотите направить в файл, укажите путь с помощью этого параметра
-m	--max-tine	Максимальное время (в секундах), которое вы готовы потратить на ожидание ответа
-I	--head	Извлечь только заголовки (осторожно: не каждый НТТР-сервер поддерживает метод HEAD с ука занием пути)
-k	--insecure	По умолчанию HTTPS-вызовы удосюверяются. Укажиго этот параметр, чтобы игнорировать ошибки, если проверка невозможна
Безопасная оболочка
Secure Shell (SSH)383— это криптографический сетевой протокол для безопасного предоставления сетевых услуг в незащищенной сети. Например, вместо telnet вы можете использовать ssh для входа на удаленную машину, или для безопасного перемещения данных между (виртуальными) машинами.
Посмотрим ка SSH в действии. Я подготовил виртуальную машину в облаке с IP-адресом 63.32.106.149, и именем пользователя по умолчанию — ес2 user. Войти на машину я могу с помощью команды (обратите внимание: вывод уре зан, и предполагается, что вы или кто-то другой заранее создали учетные данные в ~/.ssh/lnl.peei}-.
$ ssh \ О
-i ~/.ssh/lnl.pem \ ®
ес2 user@63.32.i06.149 ©
https://aws.emazon.com/anazon-ltnux 2/
11 package(s) needed for security, out of 35 available Run "sudo yen update" to apply all updates.
(ec2-user@ip-172-26-8-138 -]$ ® 382
382 Secure Shell (SSH): https://en.wik1pedia.org/wikf/Secare Shell.
Сетевое взаимодействие на прикладном уровне | 22'
О С помощью ssh входим на удаленную машину.
® Вместо пароля используем файл идентификации ~/.ssh/li4l.pen Принято явно указывать путь но в нашем случае это не обязательно, поскольку файл находится в каталоге по умолчанию -/• ssh.
Ф Адрес целевой для SSH машины в формате имя_лользоввтеля@хост.
® После успешного входа я могу пользоваться целевой машиной так же, как если бы она была локальной.
Несколько общих советов по использованию SSH:
—	Если вы используете SSH сервер (то есть позволяете другим подключаться к вашей машине по ssh), отключите вход по паролю384. Это заставит поль зователей создать пару ключей и поделиться с вами открытым ключом, который вы добавите в «/• ssh/authorized_keys, разрешив им входить только через этот механизм.
—	Используйте ssh -tt для принудительного выделения псевдотерминала.
—	При подключении по ssh выполните exportTFRM=xtern, чтобы избежать проблем с отображением.
—	Настройте таймауты для сеансов ssh в вашем клиенте. Для индивидуальных пользователей это обычно делается через ~/.ssh/config, где можно задать параметры ServerAlivelnterval и ServerAliveCountMax, чтобы под держивать соединения активными.
—	Если у вас возникли трудности, не связанн ые с локальными правами доступа к ключам, попробуйте запустить ssh с параметром -v, который предоставит зам подробную информацию о том, что происходит «под капотом» (v можно дублировать, vvv, чтобы получить еще больше отладочной информации).
SSH используется не только для прямого пользовательского взаимодействия, но и как внутренний структурный элемент — например, в инструментах пере дачи файлов.
Передача файлов
Передача файлов — едва ли не самая распространенная задача, связанная сетью. Вы можете отправить файл со своего компьютера на облачный сервер или на другую машину в локальной сети.
'м «Disable SSH Password Authentication for Specific User or Group»: https7/ostecF.nix.com/ Jisable-ssh-password-authentication-for-specific-user-or-group/.
222 | Глава 7. Сетевое взаимодействие
Для копирования файлов на удаленные системы и с них, можно использовать инструмент безопасного копирования sep (сокращение от secure сору)”5. По умолчанию он работает поверх SSH, так что убедитесь, что у вас есть пароль (а еще лучше — ключ для входа).
Предположим, есть удаленная машина с IPv4 адресом 63.32.106.149, и мы хо тим скопировать на нее файл с локального компьютера:
$ sep сорупе \ О
ес2 -user@63.32.166.149:/hone/ec2 user/ ®
сорупе	160%	0	0.6KB/S	60:06
О Источник — файл со репе в текущем каталоге.
в Место назначения — каталог /hone/ec2-user/ на компьютере 63.32.106.149.
С командой rsync* 386 файлы синхронизируются пампою удобнее и быстрее, чем с scd Под капотом rsync также использует SSH но умолчанию.
Давайте посмотрим, как использовать rsync для передачи файлов из каталога ~/dota/ локальной машины на хост с адресом 63.32.106.149:
$ rsync -avz \ О
-/data/ \ ®
nh9@63.32.196.149: ® building file list ... done • / example.txt
sent 155 bytes received 4S bytes 135.33 bytes/sec total size is 10 speedup is 3.05
$ ssh ec2-user@63.32.le6.149 -- Is Ф example.txt
Ф Значение параметров: -a — для архивации (инкрементная, сохраняющая), -V — для подробного анализа, чтобы мы могли увидеть обмен, -z — для использования сжатия.
3,5 scp(l): https://linuA.die.net/nian/l/scp.
386 rsync(l): https://www.man7.org/linux/maii pages/manl/rsync.l.html.
Сетевое взаимодействие на прикладном уровне | 223
® Исходные каталоги (-а автоматически включает - г, то есть рекурсивный обход вложенных каталогов).
® Место назначения в формате имя. пользователя@хост.
О Убеждаемся в результате, выполняя Is на удаленной машине. Следующая строка показывает, что все сработало — данные успешно прибыли.
Если вы не знаете, что сделает rsync, используйте параметр -dry-run в дополнение к другим, rsync покажет вам, что собирается делать, яе выполняя саму операцию, так что это безопасно.
Также rsync — отличный инструмент для резервного копирования каталогов: его можно настроить на копирование только новых или измененных файлов.
Ш'—----- Не забудьте двоеточие: после указания хоста! Без него rsync
с радостью интерпретирует источник или место назначения как локальный каталог. Команда отработает, вот только файлы вместо удаленной машины окажутся на вашей локальной. Например, источник userfgexanple. сот превратится в подкаталог с именем userQexanple.com/ в текущем каталоге.
И важное напоследок: вы довольно часто будете сталкиваться с ситуацией, когда кто-то предоставляет файлы Amazon S3 bucket. Скачать их можно с помо щью интерфейса командной строки AWS3"7 и подкомандой S3 (мы используем набор данных из реестра Open Data в публичном контейнере S3. Вывод урезан, чтобы влезал):
$ aws s3 sync \ О
s3://connoncrawl/contrtb/c4cnrpus/CC-MAIN-2016-O7/ \ ®
А ®
--no sign-request ©
download: s3://conmoncrawl/contrib/c4corpus/CC MAIN-2016 07/
Ltc_by-nc-nd_Lang_af_ NoBoilerplate_true_MinHtnl_true-г -00009.seg-00000.ware.gz \
to ./Lic_by-nc-nd lang af NoBoilerplate.true .MtnHtnltrue-r-0O9Q9.seg-000O0.warc gz
download: s3://connoncrawl/contrtb/c4corpus/CC-MAIN-2016-07/
L ic_by-nc-nd_Lang_bn_NoBoilerplate_true_Mi nHtnl_true-r-00017.seg-00000. warc.gz \ to ./Lic_by-nc-nd_Lang_bn.Nodotlerplate_trie_Minrtni_true-r-00O17.seo 00000.warc.gz
387 AWS CLI: htrps://aws amazon.com/rT/cli/.
224 | Глава 7, Сетевое взаимодействие
download: s3://comMOncrawl/<:ontrtb/c4corpus/CC-MATN-2016 07/
l ic_by-nc-nd_lang_da_^oBotlerplate_true_MinHtnl_true- г 63004 seg 00000< ware.gz \ to . /Lic_by - nc- nd_La ng_da_NoBollerp late_tr ue_MinHtnlJ| rue - г  00004. $eg 06603. wa rc. gz
О С помощью команды AWS S3 синхронизируем файлы из публичного контейнера.
© Это исходный контейнер s3://comonci awl и точный путь к источнику, который будет синхронизирован. Сразу предупрежу: в этом каталоге больше 8 ГБ данных, пробуйте только если вас не смущает огромный трафик.
© Место назначения — текущий каталог, он обозначен точкой (.).
Q Игнорировать/пропустить аутентификацию: контейнер общедоступный (и данные в нем тоже).
Протокол передачи файлов (FTP), RFC 959388, все еще доступен, но использовать его больше нс рекомендуется: он небезопасен. Несколько отличных альтернатив мы даже обсудили в этом разделе. В FTP больше нет насущной необходимости.
Сетевая файловая система
Сетевая файловая система (NFS) — это активно поддерживаемый и практикуемый способ обмена файлами из центрального хранилища. Изначально разрабо тайная Sun Microsystems в начале 1980-х, она претерпела множество изменений для соответствия RFC 7530”’ и связанным спецификациям IF.TF, и в настоящий момент крайне стабильна.
Пс обычному сценарию есть NFS, поддерживаемый облачным провайдером (или центральным IT-от делом в профессиональной среде). Все, что вам требуется, — установить клиент (обычно через пакет, называемый nfs-сонноп), и вы сможете смонтировать исходный каталог сервера NFS следующей командой:
$ sudo noint nfs.example.con:/source.dir /opt/target_mount. dir
Сегодня многие поставщики облачных услуг, например, AWS или Azure, предлагают NFS как услугу. Отличный способ предоставить вашему приложению, жадному до места в хранилище, большое пространство, которое будет
File Transfer Protocol (FTP): bttps://data:rackcr ietf.org/doc/html/rfc959.
Network File System (NFS) Version 4 Protocol: https://datatracker.ietf.org/doc/htnil/rfc7530.
Сетевое взгимодействие на прикладюм уровне | 225
выглядеть и ощущаться практически как локально подключенное. Но для медиаприложений настройка сетевого хранилища (NAS)'”*’ — все же более предпочтительный выбор.
Совместное использование с Windows
Если у вас представлены компьютеры с ОС Windows, и вы хотите организовать общий доступ к ним, обратите внимание на протокол серверного блока сообщений (SMB)391 * *, разработанный в IBM в 1980-х годах, или на общий протокол доступа к файлам интернета (CIFS)39i — преемника SMB, принадлежащего Microsoft.
Вполне достойный вариант для обмена файлами — Samba593, стандартная коллекция программ Linux для взаимодействия с Windows.
Дополнительная информация о сетевом взаимодействии
В этом разделе мы обсудим несколько серьезных протоколов и инструментов для работы со стеком TCP/IP. Обычным пользователям они, как правило, не нужны. Но разрабогчикам или системным администраторам будет полезно о них знать
whois
whois394 — клиент для службы каталогов с одноименным названием, предназначенной для поиска регистрационной и пользовательской информации. Если бы я захотел узнать, кто стоит за доменом ietf.org (за отдельную плату регистратор домена может скрыть эти данные), я бы сделал следующее:
$ whois ietf.org О
% 1ANA WH01S server
% for йоге information on 1ANA, visit http://www.iana.org
% This query returned 1 object
3,0 «Top 5 open source Linux NAS Servers»; https7/olinux.net/opcn-source-hnux nas-servers/
3” Server Message Block (SMB): https://en.wilcpedia.org/wiKi/Server_ Message_Block.
[MS -Clb'S]: Common Internet File System (CIFS) Protocol: https://learn.microsoft.com/en-us/ openspccs/wmdows_protocols/ms-cits/d416<?7c-c536-406e-a951-4ft)4b2fdld2b.
3,3 Samba: https://www.samba org/
”* whois: https://linux.die.net/mart./l/whois.
226 | Глава 7. Сетевое взаимодействие
refer: whois.pit org domain: GRG organisation: Public Interest Registry (PIR) address: 11911 Freedom Drive 10th Floor, address: Suite 1000 aodress: Reston, VA ?0196 address: United States contact: administrative name: Director of Operations, Compliance and Customer Support organisation: Public Interest Registry (PIR) address: 11911 Freedom Drive 10th Floor, address: Suite 1000 address: Reston, VA 20190 address: United States phone: +1 703 889 5778 fax-no: +1 703 889 S779 e-mail: ops@pir.org
О Используем whois для поиска регистрационной информации о домене.
Протокол динамической настройки узла
Сетевой протокол динамической настройки узла (DHCP)39i с клиент-серверной установкой позволяет автоматически назначать IP-адреса хостам, устраняя необходимость ручной настройки сетевых уст ройств.
Рассмотрение настройки и управления DHCP-сервером выходит за рамки книги, однако вы можете просканировать DHCP-пакеты с помощью dhepdump396. Возможно, придется немного подождать, пока какое-нибудь устройство в вашей локальной сети не попытается получить IP-адрес, чтобы увидеть результат (вывод урезан):
$ sudo dhepdump-i wlplsJi О TIME: 2021-09-19 17:26:24.115
3,5 Dynamic Host Configuration Protocol (DHCP), https://en Wikipedia .org/wiki/Dynamx_Host_ Configuration_Protocol.
3% dhcpdump(l). https://linux.die.net/man/l/dhcpdjmp.
Дополна 1вньная информация о сетевом взаимодействии | 227
IP: 0.0.0.0 (8fi:cb:87:c9:19:92) > 255.255.255.255 (ff:ff:ff:ff:ff:ff)
OP 1 (BOOTPREQUEST)
HTYPE: 1 (Ethernet) HLEN: 6
HOPS: 0 XID: 7533fb/0
OPTION:	57	(2) Maximum DHCP message sizelSOi1
OPTION:	61	(7) Cllent-identifier	01:88 cb:87i c9:19:92
OPTION:	50	(4) Reauest IP address	192.168.178.42
OPTION.'	51	(4) IP address leasetime	7776088(12w6d)
0P1 ION	12	(15) Host name	MichaelmintiPad
О Используя dhcpdvmp, анализируем пакеты DHCP на интерфейсе wlplsO.
Протокол сетевого времени
Протокол сетевого времени (NTP)J97 предназначен для синхронизации часов на компьютерах в сети. Используя команду ntpq298 (стандартную для NTP за просов), вы можете выполнить явный запрос к серверу времени:
$ ntpq -р О remote
refid st t when poll reach delay offset jitter
0.ubuntu pool.n POOL.	16	p	-	64	0	0.Э0О	0.000	0.000
1.ubuntu.pool.n POOL.	16	p	-	64	0	0.000	0.000	j.000
2.ubuntu.pool.n.POOL.	16	p	-	64	6	0.000	0.000	0.000
3.ubuntu.poo I.n.POOL.	15	p	-	64	e	0.000	0.000	0.000
ntp.ubuntu.com.POOL.	16	p	=	64	0	0 .026	0.000	0.000
ntpl7.kashra-se 96.187.148.77	2	и	7	64	1	27.482	-3.451	2.285
golem.canonical 17.253.34.123	2	и	13	54	1	28.338	0.057	0.000
chilipepper.can 17.253.34.123	2	и	12	64	1	19 117	-0.439	0.000
alphyn.canonica 140.203.204.77	2	u	14	64	1	91.462	-0.356	0.000
pugot.canonLeal 145.238.263.14	2	u	13	64	1	20.788	0.226	0.008
Network Time Protocol (NTP): https://www.n1p.org,
ntpq(8): https://linux.die.net'man/8/ntpq.
228 | Глава 7. Сетевое взаимодействие
О Добавив параметр  р, можно увидеть список известных машине источников точного времени и их состояние.
Обычно NTP работает в фоновом режиме под управлением systemd и других демонов, поэтому вам вряд ли придется запрашивать время вручную.
Wireshark и tshark
Если вы задумали низкоуровневый анализ сетевого трафика и хотите изучить именно пакегы ио всему стеку, вам может пригодиться инструмент командной строки tshark399 или его графическая версия — wii eshark400
К примеру, обнаружив через ip link сетевой интерфейс с именем wlpisO, я могу перехватить его график следующим образом (вывод урезан):
$ sudo tshark -i wlpisO tcp О
Running as user "root" and group "root". This could be dangerous.
Capturing or 'wlpisO'
1 0.040000606	192.168.178.40 -a 34.196.251.55 TCP 66 47618 -> 443
[ACK] Seq=l Ack=l Kin=50i Len=0 TSval=3796364053 TSecr=1531224S8
2 0.111215098	34.196.251.55 -=> 192.163.178.40 TCP 66
[TCP ACKed unseen segment] 443 -> 47618 [ACK] Seq=l Ack=2 Win=283
Len=0 TSval=153167579 TSecr=3796227866
8 7.712741925 192.168.178.40 -> 185.199.109.153 HTTP 146 GET / HTTP/1.1 О
9 7.776535946 18o.199.109.153 -> 192.168.178.40 TCP 66 86 -> 42000 [ACK]
Seq=l Ack=81 Win=144896 Len-0 TSval=2759410860 TSecr=4258870662
10 7.878721682	185.199.109.153 -» 192.168.178.40 TCP 29*6 HTTP/1.1 206 OX
[TCP segment of a reassembled PDU]
11 7.878722366	185.199.109.153 > 192.168 178.40 TCP 2946 80 -» 42600
[PSH, ACK] Seq=2881 Ack=81 Win=144896 Len=2880 TSval=2759410966 \
TSecr=4258870662
[TCP segment of a reassembled PDU]
О С помощью tshark захватываем трафик на сетевом интерфейсе wlpisO (просматриваем только TCP).
399 tshark Manual Page: https.//www.wireshark.org/aocs/man-pages/tsnark.htrm.
*” wireshark Manual Page: https://www.wiresharkorg/docs/man-pages/wiresharkhbnl.
Дополи отельная информация о сетевом взаимодействии | 229
® В соседнем сеансе я выполнил curl-запрос, чтобы запустить сеанс взаимодействия HTTP на прикладном уровне. Кстати, для той же задачи можно использовать не такой мощный, но распространенный tcpounp401 402 *.
Другие передовые инструменты
Вы можете счесть полезными современные сетевые инструменты из следующе го списка:
socat™
Устанавливает два двунаправленных потока данных для передачи данных между конечными точками.
деогр lookup
Сопоставляет JP-адрес с географическим регионом.
Туннели
Простая альтернатива для VPN404 и других решений для прямых межсетевых соединений. Обеспечивается такими инструментами, как inlets405.
BitTorrent
Peer- to-peer система, которая группирует файлы в пакет, называемый torrent. Попробуйте несколько клиентов406 и выберите тот, который вам больше подходит.
401 tepdump: https://www.tcpdump.org/.
402 socatf 1): https://linux.die.net/man/! /socat.
433 geoiplockup(l): https://lir.ux.die.net/man/l/geoiplookup.
404 VPN (VPN-сервис) — С ноября 2022 г. на территории Российской Федерации запрещено распространять информацию о VPN-сервисах с целью доступа к запрещенному контенту. Научная, каучно-техничес кая и ста~истическая информаци я о VPN- сервисах для обхода блокировок признана запрещенной в России, исключением является информация о VPN для обеспечения защищенного удаленного доступа. (Прим, ред.)
405 Inlets: https://cocs.inlets.dev/.
4,6 «Best Torrent Clients You Can Use on Linux Desktop» https://linuxiac.com/best-torrent-clients/.
230 | Глава 7. Сетевое взаимодействие
Заключение
В этой главе мы определили базу общих сетевых понятий от уровня оборудования и сетевых карт до стека TCP/IP, прикладного уровня и пользовательских компонентов, подобных HTTP.
В Linux представлена мощная и основанная на стандартах реализация стека TCP/IP, которая используется программно (сокеты), а также при настройке и для опросов (обычно с помощью команды ip).
Далее мы обсудили основные протоколы и интерфейсы прикладного уровня, наиболее часто используемые для решения ежедневных (сетевых) задач. К вашему инструментарию командной строки добавились curi для передачи и dig для DNS-поиска.
Если вы хотите глубже погрузиться в темы сетевых взаимодействий, предлагаю вашему вниманию следующие ресурсы:
Стек TCP/IP
— Understanding Linux Network Internal by Christian Benvenuti (O'Reilly), 200540''.
—	«Протокол пакетной сетевой коммуникации»’08.
—	Веб-страница настройки DHCP-сервера407 * 409,
—	«Привет IPv6: Минимальное руководство для пользователей IPv4»’10.
—	«Понимание IPv6 - серия из 7 частей»411
-	Сборник статей по IPv6 Йоханнеса Вебера412 413.
—	«Веб-сайт эксперта в BGP» Ильича вак Бейкума’13.
—	«Все, что вы хотели знать о сокетах UDP, но боялись спросить»*14.
407 Understanding Linux Network Internals by Christian Benvenuti (O’Reilly) 2005: htfps://www. oreiUy.com/library/view/ur.derstanding linux network/05960025t>6/ («Понимание внутреннего устройства сети в Linux»).
«А Protocol for Packet Network Intercommunication» by Vinton G. Cerf and Robert E. Kahn (Member, IEEE): https://www.cs.princeton.edu/courses/arctiive/fall.06/cosc>61/papers/cerf74. pdf.
m DHCP server setup webpage: https://wiki.debian.org; DHCP..Server.
410 «Hello IPv6: A Minimal Tutorial for IPv4 Users»: https://metebalci.com/blog/heno-ipv6/.
411 «Understanding IPv6-7 Pari Series»: https://www.networkirgwithfish.com/understanding ipv6-7-part series/.
412 Collection of IPv6 articles by Johannes Weber: https://weberblog.net/ipv6/.
413 Ilj.tsch van Bcijnum’s BGP Expert website: https://www.bgpexoert.com/.
4,4 «Everything you ever wanted to know about UDP sockets but were afraid to ask»: https./Zblog. cloudflare.com/everything-you-ever-wanted-to-know-about-udp-sockets-but-were-afraid-to-ask-part-1/.
Заключение | 231
DNS
—	«Введение в терминологию, компоненты и концепции DNS»415.
—	«Как установить и настроить DNS-сервер в Linux»416.
—	«Анатомия DNS-поиска Linux»417.
—	«Забавляемся с TLD: выводим .fun на вершину DNS»418.
Приклаоной уровень и расширенные сетевые возможности
—	«Объяснение туннелирования через SSH»41 *’.
—	Everything curl by Damel Stenberg (open source)™.
—	«Что хакое DHCP и как настроить DHCP-сервер в Linux»421.
—	«Как установить и настроить Linux NTP-сервер и клиент»422.
-	NFS Wiki423.
—	«Использование Wireshark в командной строке Linux с ТShark»424.
—	«Начало работы с socat»425.
—	«Картографирование сетевого трафика»426.
Теперь мы готовы перейти к следующей теме книги и изучить наблюдаемостп, чтобы не тыкаться вслепую.
415 «Ап Introduction to DNS Terminology, Components, and Concepts»: ht1ps/7wwwdigiulccean com/coromunity/tutortals/an-introduction -to dns -terminology-components-and-concepts.
4,6 «How to Install and Configure DNS Server in Linux»: https://www.thegeeks1ulf.com/2014/01/ install-dns-server/.
417 «Anatomy of a Linux DNS Lockup»: https://zwischenzugs.com/20L8/06/08/anatomy-of-a-linux-dns-looku p-part-7.
416 «TLDs — Putting the fun in the Top of the DNS»: https://www.netmeister.org/blog/ tlds.btml.
414 «SSH Tunneling Explained»: https://goieieport.com/bLog/ssh-tunnehng-explamed./.
420 «Everything curl» by Daniel Stenberg (open source): bttps://curl se/bookhtnil («И все завер-
те...»).
421 «Whal Is DHCP and How to Configure DHCP Server in Linux»: https://linuxconflg.org/what -
is-dhep- and-how-tc-configure-dl icp -server- in-linux.
422 «How to Install and Configure Linux NTP Server and Client»; httpsJ/www.thegeekstufl'. com/2014/06/lir.ux ntp server-client/.
423 NFS Wiki: https://linux-nis.org/wiki/index.php/Main_Page.
424 «Use Wireshark at the Linux Command Line with TShark»; https://opensource.com/articie/20/1/ wireshark-linux-tshark.
423 Getting Started with socat: https://www.redhat.com/en/blog/getting-started-socat.
426 Geomapping Network Traffic: https://bla-gg.no/2015/10/geomapping-nerwork-traffic/.
ГЛАВА 8
Наблюдаемость
Общая картина происходящего в стеке — от яцра до пользовательских компонентов — никогда не бывает лишней. Самую полную картину помогают создать правильно подобранные инструменты.
Эта глава посвящена сбору и упорядочиванию порождаемых Linux и приложениями сигналов, которые помогают вам принимать взвешенные решения. Вы научитесь.
—	Выяснять, сколько памяти потребляет процесс.
—	Понимать, как скоро закончится место на диске.
—	В целях безопасности получать оповещения о действиях пользователя.
Установку понятийной базы мы начнем с обзора полезных сигналов различного рода, которые встретятся вам в работе, — логов системы и приложений, метрик и трассировки процессов. Затем вы научитесь отслеживать проблемы производительности и замерять ее. После мы сосредоточимся на конкретных журналах, их параметрах и назначении, а также узнаем, как мониторить ресур сы — циклы ЦП, намять и трафик I/O. Вы также ознакомитесь с набором полезных инструментов и готовыми рецептами, которые, возможно, захотите перенять.
Наблюдаемость бывает реакционной (и довольно часто). Вы закапываетесь в логи и следите за потреблением памяти и ЦП лишь тогда, когда ваши процессы зависают и тормозят. Наблюдаемость может носить исследовательский характер, когда вам хочется выяснить, сколько времени занимает отработка ваших алго ритмов. И, наконец, наблюдаемость может быть предиктивной. На основе теку щсго состояния вы можете предугадывать будущие проблемы, и отличный тому пример — планирование нагрузки на дисковое пространство.
Маэстро производительности Брендан Грегг создал одну из лучших визуализаций наблюдаемости. Рисунок 8-1, взятый с его сайта о производительности Linux42’, дает представление о богатстве инструментария. 427
427 Linux Performance (Brendan Gregg’s site): https.7zwww.breiLdangregg.com/linuxperf.html.
Заключение | 233
Инструменты наблюдаемости и анализа производительности
орапапоор
fat race filelife
pcatat
Str асе	Операционная «пека	Оборудование Прочие:
Ltrace	аз nstat	sat /proc
dawsg decat
gethost1atency
perf Ftiace LTTny BCC bpftrace
IP
axtidlst ' extlsloaer
(&forbtrfs
rrfs.xtszfs)
Менеджер Тимов _________IP
>лочноеу(гройпв6 Се’евоеунрийпар
offcputima
“7 /Планировщик^ aoftirqa
Виртуальная
Драйверы устроив
память
execsnoop mpstat	turboatat
profile	anowboost
runqlan	rdmsr
top atop pa pidstat
\ \ vmstat tcpdump tcplifa \ slabtop tcpretrans free udpconnect
perf tiptop
iostat bioanoop biolatency biotop blktrace
CRAM
numastat
SCSI log
swapon
netstat ip
1	1	-я nЬге. л-si ВИ. t 
GthtOOl ffnmpget 1 laptool	Nnuxperf.htmi. 2021
Рисунок 8-1. Обзор наблюдаемости в Linux (автор Брендан Грегг, опубликовано по лицензии СС BY-SA 4.0)
CPUs
tiptop porf
Наблюдаемость — захватывающая тема с широкой областью применения и большим количеством инструментов (с открытым исходным кодом). Давайте начнем с общепринятой стратегии и терминологии.
Основы
Перед погружением в понятия наблюдаемости отвлечемся и рассмотрим упорядоченный подход к превращению собранной статистики в потенциальное решение проблемы или идею оптимизации приложения.
Стратегия наблюдаемости
Одна из самых популярных стратегий наблюдаемости — цикл OODA (observe, orient, decide, аст)428 (наблюдай, ориентируйся, решай, действуй). Он предлагает последовательность шагов от проверки гипотез, выстроенных па наблюдении,
42! OODA loop (observe, orient, decide, act): https://en. Wikipedia org/wiki/OODA_loop.
234 | Глава 8. Наблюдаемость
к решению на основе результатов. Проще говоря, это путь превращения посту лающих сигналов в руководство к действию.
Представим, что приложение тормозит. Можно предположить несколько узких мест (мало памяти, не хватает тактов процессора, медленная сеть и т. д.). Для начала неплохо измерить потребление Затем можно выделить дополнительные мощности одному ресурсу (оставив другие нетронутыми) и повторить замеры.
Улучшилась производительность, если добавили памяти? Если да, возможно, причина найдена. Если нет, ослабьте отраничения для другого ресурса, замеряя потребление и соотнося изменения с вашими действиями.
Терминология
С наблюдаемостью429 связано множество понятий. Формальные определения не всегда четкие, и могут различаться, если речь идет об одной машине или сетевой (распределенной) конфигурации:
Наблюдаемость
Оценка внутреннего состояния системы (такой как Linux) через изменение внешней информации, обычно ради дальнейшего воздействия. Например, заметив подвисание системы и сделав замеры, вы обнаружили, что одно из приложений заняло всю доступную память. Вы можете завершить приложение, и это исправит ситуацию.
Типы сигналов
Разные способы представить или отчитаться о состоянии системы для дальнейшей обработки и анализа: в текстовом виде (например, читаемая инфор мания из лога), в цифровом (в виде метрик) или в комбинации обоих видов. См. «.Сигналы наблюдаемости».
Источник
Порождает сигналы разного типа. Источниками служат и ОС Linux, и при ложения.
Место назначения
Место, где собираются и хранятся сигналы, ожидая дальнейшей обработки. Место назначения с пользовательским интерфейсом (GUI, TUI или CLI)
42’ Для обозначения наблюдаемости часто используется нумероним ally. Цифра 11 — это количество сокращенных букв между о и у в слове observability («наблюдаемость»), (Прим пер.)
Основа | 235
обычно называют фронтенд. К примеру, программа для отслеживания журналов или панель мониторинга с графиками это фронтенд, а контейнер S3 — нет (хотя вполне может быть местом назначения для выгрузки журналов).
Телеметрия
Процесс сбора сигналов из источника и их отправка (маршрутизация, передача) к месту назначения. Для телеметрии часто используются агенты, которые собирают и/или предварительно обрабатывают сигналы (например, фильтруют или группируют их).
Сигналы наблюдаемости
Сигналы — это сообщения о состоянии системы, которые используют для дальнейшей обработки и анализа. Тестовые больше подходят для поиска и просмотра человеком, числа хороши для машин (но в обработанной форме подходят и людям). Выделяются три типа сигналов, имеющих отношение к теме главы: журналы, метрики и трассировки.
Журналы
Журналы (или логи) — эго основополагающий тип сигналов, который так или иначе присутствует в любой системе. Поступающие события скапливаются в текст овом виде и нредназн ачаю I ся для чтения человеком. Каждая запись обыч -но снабжается временной меткой и в идеальном случае разбивается на формальные столбцы с определенными значениями, чтобы было проще читать или обрабатывать их программными средствами.
Интересный факт: хотя у каждого журнала есть структура (пусть не четкая и сложная для раэбора из-за разделителей или символов перевода строки), вам часто будет встречаться выражение «структурированное журналирование». Знайте, что за этим выражением скрывается лог в формате )SON.
Автоматизированный анализ журналов довольно сложен (учитывая текстовую природу), зато они сносно читаются людьми — и потому, вероятно, останутся главенствующим типом сигналов и дальше436. Их обработку мы рассмотрим в разделе «Журналирование» В рамках темы журналы наиболее важны, поэто му мы отведем под них большую часть главы. 430
430 В ходе проектирования любого программного продукта стоит сформировать некий документ, описывающий основные поля и паттерны для логов. В дальнейшем это позволит автоматизировать обработку журналов. (Прим.ред.)
236 | шаги 8. Наблюдаемость
Метрики
Метрики — это регулярно обновляемый набор числовых значений, распределенных во времени. Отдельные значения могут быть комплексными и содержать дополнительные замеры или метаданные. Необработанные метрики не потребляются напрямую: они используются для агрегации, построения графиков или в виде уведомлений о наступлении условий. Метрики полезны и в обычкой работе, и для поиска неполадок, когда требуется выяснить, сколько транзакций произвело приложение или как долго выполнялись операции (за последние N минут).
Различают метрики следующих типов:
Счетчик
Значение счетчика только увеличивается (кроме случал сброса сю в ноль). Пример — общее количество обработанных службой запросов или сумма байтов, отправленных через интерфейс за определенное время.
Датчики
Значение датчика может увеличиваться и уменьшаться. Пример — объем до ступной оперативной памяти или количество запущенных процессов
1 истограммы
Комплексный способ подсчета сгруппированных значений. По сегментам гистограммы можно оценивать общую структуру данных или делать гибкие утверждения (50% или 90% значений попадают в определенный диапазон).
В разделе «Наблюдаемость» мы рассмотрим простые инструменты, а в «Prometheus и Grafana» я покажу вам комплексный подход к использованию метрик.
Трассировка
Трассировка — это динамически изменяемая коллекция с данными об исполнении (например, информация системных вызовах, которые сделал процесс, или последовательность событий, наступавших в ядре для конкретного случая). Трассировки полезны и для отладки, и для оценки производительности Этой сложной темы мы коснемся в разделе « Арассировка и профилирование».
Основы | 237
Журналирование
Логи — это наборы тестовых сообщений о событиях, оптимизированные для восприятия человеком. Для лучшего понимания выделим части этого утверждения
Отдельные события
Для понимания представьте себе программу, в ходе выполнения которой вы хотите зафиксировать отдельное (атомарное) действие. Например, вы эапи сываеге в лог, чго соединение с базой данных установлено или что отсутствие нужного файла привело к ошибке. Старайтесь составлять сообщения кратко и информативно, чтобы тому, кто прочтет его, было проще найти проблемное место в коде.
Смысловая нагрузка сообщения
Это описательная часть события, текстовая по своей природе и адресуемая прежде всего человеку. Где бы вы ни просматривали журнал (в командной строке или через графический интерфейс), вы будете принимать решение на основе сообщения, понятного для вас.
С точки зрения структуры в журнале выделяют следующие части:
Набор записей, сообщений или строк
Накопленная информация о последовательных событиях.
Метаданные или контекст
Дополнительные данные, локальные (для отдельных записей) или глобальные (для нсего файла журнала).
Индивидуальный формат для анализа отдельной записи
Различаются части лога и поля. Бывают строчно-ориентированные сообщения, разделенные табуляцией или пробелами, или сериализованные в JSON.
В таблице 8-1 приведены общепринятые форматы. Существуют более специфичные и узконаправленные форматы и фреймворки — например, для баз данных или языков программирования.
Старайтесь избегать излишних накладных расходов на журналы (ради уско рения поиска и экономии места на диске). В этой связи интересна ротация жур налов с помощью logrotate431 и концепция с названием «температура данных»
431 jogrotate(8). https://linux.die.net/man/8/logrotate.
238 | Глава 8. Наблюдаетесь
(перемещение старых журналов в медленные и «дешевые» хранилища: подключенный диск, контейнер S3, Glacier).
Таблица 8 1, Общепринятые форматы журналов
Формат	Описание
Общий формат событий (CEF)432	Разработан ArcSight; используется для устройств и для фиксации событий безопасности
Общий формат логов433	Для веб-серверов; см. также расширенный формат журнала
Расширенный формат Graylog (GELF)434 435	Разработан Graylog; улучшает Sysl од
Sysfog	Для операционных систем, приложений и устройств (см. «Sysiog»)
Фермат встроенных метрик433	Разработан Amazon (для журналов и метрик)
S Будьте осторожны с догами, особенно в производственных средах. Прежде чем записать что то в лог, лишний раз спроси тс себя, нс приведет ли это к утечке значимых данных — паролей, ключей API и даже обычной информации, раскрывающей пользователя (адрес электронной почты или идентификатор учетной записи).
Проблема в том, что логи хранятся долго (на локальном диске и даже в контейнерах S3). Злоумышленник, получивший доступ даже к устаревшей конфиденциальной икформа ции, может использовать се для атаки.
Чтобы отметить важность или конкретизировать потенциального потреби теля, записи в журналах часто маркируются уровнями (к примеру, DEBUG для разработки, INFC для нормальных состояний и ERROR для ситуаций, которые требуют вмешательства человека).
Время засучить рукава. Начнем с простого и взглянем на центральный каталог журналов в Linux (вывод урезан для удобства чтения):
432 https://www.microfocus.eom/documentation/arcsighi/arcsight-smartconnectors-8.4/pdfdoc/ cef implementation standard/cef implementation standard.pdf
433 https://httpd.apache.org/docs/trun k/logs.html#common.
434 https://graylog.org/features/gelf/.
435 https:/zdocs.aws.amazon.com/AmazonCloudWatch/latest/moniroiing/ClcudWatch_ F.mbedded_Metric_Forrnat_Specification.html.
Журналирование ] 239
$ Is г! /var/log
drwxrwxr-x	8 root	syslog	4096 Jul 13 06:16
drwxr-xr-x	13 root	root	4096 Jun 3 07:52 ..
drwxr-xr-x	2 root	root	4096 Jul 12 11:38 apt/ О
-FW-Г		1 syslog	aom	7319 Jul 13 07:17 avth.log ©
-rw-rw-		1 root	utnp	1536 Sep 21 14:07 btmp ©
drwxr-xr-x	2 root	root	4096 Sep 26 0835 cups/ Ф
-rw-r--r--	1 root	root	28896 Sep 21 16:59 dpkg.log Ф
-rw-r		1 root	aern	51166 Jul 13 06:16 dmesg Ф
drwxrwxr-x	2 root	rcot	409o Jan 24 2021 installer/ ©
drwxr-sr-x+	3 root	systemd-journal	4096 Jan 24 2021 journal/ ©
-rw-r		1 syslog	adn	4437 Sep 26 13:30 kern.log Ф
-rw-rw-r--	1 root	utmo	292584 Sep 21 15:01 lastlog ©
drwxr-xr-x	2 ntp	ntp	4096 Aug 18 2020 ntpstats/ ©
-rw-r		1 syslog	a<fm	549081 Jul 13 37:57 syslog Ф
О Журнал менеджера пакетов apt
в Журналы попыток входа в систему (успешных и неудачных) и процессов аутентификации.
© Неудачные попытки входа.
© Журналы печати.
© Журналы менеджера пакетов dpkg.
© Журналы драйверов устройств; для исследования используйте dmesg.
® Журналы установки системы (созданные при уст ановке дистрибутива Linux).
© Расположение journalctl; подробности в разделе «journalctl».
Ф Журналы ядра.
О Все последние входы пользователей; для исследования используйте lastlog Ф Журналы, связанные с КТР (см. «Протокол сетевого времени»).
Ф Расположение syslogd; подробности в разделе «Syslog».
Преследование — один из распространенных способов изучать журналы в реальном времени. Вы постоянно видите конец журнала и новые записи по мере их поступления (вывод урезан, чтобы влезал):
$ tail -f /var/log/syslog О
Sep 26 15:96:41 starlite ni4-applet[31555]: ... 'GTK_IS_WIDGET (widget)' failed
Sep 26 15:06:41 starlite nn-cispatcher: ... new request (3 scripts)
Sep 26 15:96:41 starlite systend[l]: Starting PackageKit Daemon...
240 | Глава 8. Наблюдаемость
Sep 26 1506:41 starlite nn dispatcher: ... start running ordered scripts...
Sep 26 15:66:42 starlite PackageKit: daenon start ®
*C
О Запуск слежения за журналом процесса syslogd с помощью параметра -f. в Пример строки журнала; формат см. в разделе «Syslog».
Чтобы наблюдать за логом процесса и одновременно сохранясь его в файл, используйте команду tee:
$ so"ieprocess | tee -а sone.log
Теперь вы уви дите ход выполнения somepr ocess в терминале, ь то же время сохраняя его в seme. log. Обратите внимание на использованный параметр -а для дозаписи в файл журнала без него файл будет урезан.
Теперь рассмотрим две самых распространенных системы ведения журналов в Linux.
Syslog
Syslog (или системный журнал) — это стандартный журнал для целого ряда источников из ядра от демонов из пользовательского пространства. Свое начало он берет в сетевых средах; ныне его текстовый формат, сценарии развертывания и рекомендации ло безопасности описаны в RFC 5424436. На рисунке 8-2 показан общий формат Syslog; помните, что в нем много необязательных и редко используемых полей.
[ PRI ]( VER ][ TS ][ HN )( АРР ][~РЮ~3[~М10
Столбцы
Структурированные данные
Рисунок 8-2. Формат Syslog согласно RFC 5424
416 "The Syslog protocol: https://datatracker.ietf,org/doc/html/rfc5424.
Жуэналирование | 241
RFC 5424 определяет следующие поля для колонок Syslog (чаще всего используются TS и HN):
PRI
Важность/серьезкость сообщения.
VER
Номер протокола Syslog (обычно не указывается, поскольку может быть только 1).
TS
Метка времени создания сообщения в формате ISO 8601.
HN
Идентификатор машины, отправившей сообщение.
АРР
Идентификатор приложения (или устройства), отправившего сообщение.
PID
Идентификатор процесса, отправившего сообщение.
MID
Необязательный идентификатор сообщения.
Также формат предусматривает включение структурированных данных в виде последовательности элементов, каждый из которых оформлен ь вице ключ/значение и обрамлен квадратными скобками [].
Раньше для управления журналом использовался исполняемый файл syslogd437 438, но со временем появились и другие варианты, о которых следует знать:
syslog-ng4 38
Улучшенный демон журнала на замену syslogd с поддержкой TLS, фильтрации по содержимому и хранения в базах данных, таких как PostgreSQL и MongoDB. Доступен с конца 1990 года.
437 syslogd(8); https://linux.die.net/rnan/8Zsys'.ogd.
438 sys)og-ng: https://github.com/syslog-ng/syslog-ng.
242 | Гласа 8. Наблюдаемость
r syslog339
Расширяет протокол Syslog и может использоваться совместно с systend. Существует с 2004 года.
Несмотря на почтенный возраст, семейство протоколов и инструментов Syslog еще существует и используется. Однако с момента превращения systemd в стандарт для систем инициализации в каждом значимом дистрибутиве Linux появился новый способ ведения журналов. Знакомьтесь: журнал systemd.
journalcti
В разделе «systemd» мы уже знакомились с компонентом экосистемы systend. который отвечает за управление журналами: jour па Lett440. В отличие от Syslog и других систем, применявшихся ранее, journaled сохраняет записи в двоичном формате. Это ускоряет доступ и оптимизирует использование дискового пространства.
Двоичный формат хранения (когда его только представили) мало кому понравился: пользователи теряли возможность пользоваться знакомыми tail, cat и grep для изучения записей и поиска в журналах. Но хотя к работе с journalcti придется привыкнуть, особых усилий это не потребует.
Рассмотрим несколько общих задач. Запущенный без параметров journalcti — эго интерактивный навигатор по всем журналам (переключаться можно стрелками или пробелом, выйти по о).
Для ограничения временного диапазона можно использовать следующие параметры:
$ journalcti -since "3 hours ago1 О
$ journalcti -since "2021-69-26 15:30:00" -until "2021-09-26 15:30:00" ©
О Ограничить отображение событий последними тремя часами.
® Другой способ выбора диапазона — указать точное время начала и окончания.
А так выводятся только определенные записи systemd (предполагается, что служба с именем abc.service существует):
$ journalcti -□ гЬс.service * *
rsyslog. https://www.rsyslog.coin/.
journalcll(l): https://www.man7.Org/linux/ir.an-pages/manl/journalctl.l html.
Журиалаоование | 243
В journalctl встроены мошные механизмы форматирования. С параметром —output (или кратко -о) вы можете выбрать определенный способ вывода записей. Самые полезные:
cat
Краткая форма без метки времени и источника.
short
Формат по умолчанию, имитирует вывод Syslog.
json
Выводит каждую запись в формате JSON (для автоматизации).
Вы можете подключить слежение, аналогичное tall -f, используя одной мен яый параметр:
$ journalctl -f
Скомбинируем возможности в конкретном примере. Представим, что вы собрались перезапустить компонент безопасности АррАгтог441 в дистрибутиве Linux под управлением systemd, В одном терминале вы перезапускаете службу systemctlrestartapparnor, а в другом выполняете следующую команду (вывод подправлен, но на самом деле на каждой строке одна запись):
$ journalctl -f -и арраггсог.service О
Logs begin at Sun 2021-01-24 14:36:30 GMT. --
Sep 26 17:10:02 starlite аррзгпог[13883]: All profile caches have been cleared, but no profiles have been unloaded.
Sep 26 17:10:02 starlite apparnor[13883]: Unloading profiles will leave already running processes permanently
Sep 26 17:16 32 starlite systemd[l]: Stopped AppArmor initialization.
Sep 26 17.10:02 starlite systemd[lj: Starting AppArmor initialization... ©
Sep 26 17:10:32 starlite аррагшог[13904]: * Starting AppArmor profiles
Sep 26 17:10:33 starltte apparmor[13904]: Skipping profile in /etc/гррагтог.d/dtsable: usr.sbtn.rsyslogd
Sep 26 17:10:99 starlite appaгчог[13904]: ...done.
Sep 26 17:10:09 starltte systend[l]: Started AppArmor initialization.
441 AppArmor: https://www.appanrtor.net/.
244 | Глава 8. Наблюдаемость
О Слежение за жуиналами службы Арр Armor.
в После того как systerd остановил службу, она запускается снова.
На этом мы завершаем раздел журналирования и переходим к числовым значениям метрик и обширной теме наблюдения.
Наблюдение (мониторинг)
Мониторинг — это сбор и слежспис за показателями с какой -либо целью. К при меру, вы интересуетесь, сколько времени заняла обработка и сколько ресурсов потребляет процесс («мониторите» производительность), или устраняете неполадки в проблемной системе. Два действия вам придется выполнять чаще всего:
—	Отслеживать во времени одну или несколько метрик.
—	Реагировать на оповещения о состоянии.
Сперва мы сосредоточимся на общих понятиях и полезных инструментах, а потом перейдем к более сложным приемам, которые пригодятся только в определенных ситуациях
Взглянем на простой пример отображения ряда показателей (продолжительность работы системы, использования памяти и г. д.) с помощью команды uptime :
$ uptime О
08:48:29 up 21 days, 2059, 1 user, load average: 0.76, 0.20, 0.Э9 ©
О Запуск uptime для отображения основных показателей системы.
© В выводе команды через замят ую перечислены: время непрерывной рабо гы, количество пользователей в системе, а далее (в секции load average) три значения датчиков, которые указывают на загрузку процессора за 1 минуту, 5 минут и 15 минут. Эти усредненные значения выведены из количества заданий в очереди на выполнение и в ожидании дискового I/O. В нашем случае средняя нагрузка за последние 5 минут составляла 0,2. Это мало о чем говорит: значение нужно сравнивать с временной динамикой других пока зателей.
442 uptime(l): littps://www.rnan7.org/linwc/man-pages/n’.anl/uptiine.l.htinl.
Наблюдение (мониторинг; | 245
Дальше с помощью команды free понаблюдаем за использованием намязи (вывод ужат для удобства):
$ free -h О
	total	used	free	shared	buff/cache	available
Mem;	7.6G	1.3G	355M	395n	6.0G	5.6G ®
Swap.	975M	1.2M	9748,	©		
О Отобразить статистику использования памяти в читаемом виде.
® Показатели памяти- всего, используемая, свободная и общая, отведенная под буферы и кэширование (добавьте -w, если вам нужны раздельные значения) и доступная.
® Полный, использованный и свободный объем пространства подкачки — раздел физической памяти, выделенной под подкачку
Более комплексный подход к наблюдению за использованием памяти — команда vmstat443 (показатели виртуальной памяти) В следующем примере vnstat используется в режиме самообновления (вывод урезан, чтобы влезал):
$ vmstat 1 О
procs		memory		Swap	----co---	-system- ---	--epu- -
г b	swpd free buff cache	si so	bi bo	in cs us	sy id wa st ®
4 0	1184 482116 682388 5447048	0 3	12 105	28 191 6	3 91 0 0
0 0	1184 483444 682388 5446600	0	0	0	0	369 522 1	0 99 0 0
0 0	1184 483696 682392 5446600	0	0	0 104	2/8 3 74 1	1 99 0 0
ЛС
О Вывод статистики памяти. Аргумент 1 заставляет программу добавлять новую строку сводки каждую секунду.
® Расшифровка важных столбцов: г — количество про; [ессэв, запущенных или ожидающих ЦП (меньше или равно количеству имеющихся), free — свобод нал основная намять в килобайтах, in — количество прерываний в секунду, cs — количество переключений контекста в секунду, от us до st — проценты от общей загрузки ЦП для пространства пользователя, ядра, ожидания и т. д.
Узнать, сколько времени выполняется операция, можно командой tine:
44’ vmstat(8): https://linux.die.net/mar/8/vmstat.
246 | Глава 8. Наблюдаемость
$ tine (Is -R /etc 2&> /dev/null) О
real	t>0.022s Ф
user	0mO.012s Ф
sys	0140, 007s Ф
О Измерить, сколько времени занял рекурсивный вывоц всех подкаталогов n /etc. Результат и ошибки мы отбрасываем с помощью инструкции 2&> /dev/null.
в Суммарное затраченное время (по таймеру; информативно разве что в контексте производительности).
Ф Сколько времени Is занимала процессор сама (в пользовательском простран стве)
О Сколько времени Is ждала, пока что-то сделает Linux (в пространстве ядра).
Если вам интересно, сколько времени заняла операция из примера, то наиболее близким значением будет сумма user и sys, а их соотношение покажет, на что потрачена большая часть времени выполнения.
Теперь сосредоточимся на более узкой теме: на сетевых интерфейсах и блоч ных устройствах.
Устройства ввода-вывода и сетевые интерфейсы
iostat444 позволит вам понаблюдать за устройствами I/O (вывод отредактиро ван):
$ ioscat -z --human О
Linux 5.4.0-81-generic (starlite) 69/26/21 _x86_64_ (4 CPU)
avg-cpu: %user %nice Xsystem %iowair %steal %idle
	5.3%	6.0%	2.7%	e.i% 0.0%	91.4%	
Device	tps	kB_read/s	kB_wrtn/s	kB_read	kB_wrtn
loop©	0.00	0.0k	®.0k	343.0k	0.0k
loopl	0.60	0.0k	0.0k	2.8M	0.0k
sda	6.38	1.4k	12 4k	2.5C	22.5G '
444 iostat(l): https://linux.<lie.net/nian/l/iostat.
Наблюдение (мониторинг) | 247
dn-0	0.7?	1.3k	12.5k	2.4G	22.7G
1оор12	0.00	0.0k	0.0k	1.5M	0.0k
О Запуск iostat для отображения метрик устройств ввода-вывода. Параметр -z ограничивает список устройствами, где наблюдается активность, а --huian облагораживает результат (единицы в удобной для чтения форме).
® Пример строки для одного устройства: tps — количество передач (запросов I/O) в секунду, read — объем прочитанных, a wrtn — записанных данных.
А вот еще: с помощью ss445 сетевые интерфейсы могут выводить статистику сокетов (см. «Сокеты»). Следующая команда выведет список сокетов TCP и UDP с идентификаторами процессов (вывод урезан, чтобы влезал):
$ ss -atup О Netid State		Recv-Q Send-Q Local Address: Port			Peer Address: Port 0.0.0.0:*
udp	UNCONN	0	0	0.0.0,0:60360	
udp	UNCONN	0	0	0.0.0.6: ipp	0.0.0.0:*
udp	UNCONN	e	0	0.0.0.0:789	0.0.0.0:*
udp	UNCONN	0	0	224.0.0.251: mdns	0.0.0.0:*
udp	UNCONN	e	0	0.0.0.0: ndns	0.0.0.0:*
uop	ESTAB	0	0	192.168.178.46:51008	74.125.193.113:443
tcp	LISTEN	0	128	0.0.0.0: sunrpc	0.0.0.0:*
tcp	LISTEN	0	128	127.6.0.53%lo: domain	0.0.0.0:*
tcp	LISTEN	0	5	127.0.0.1: ipp	0.0.0.0:*
tcp	LISTEN	0	4096	127.0.0.1:45313	9.0.0.0:*
tcp	ESTAB	0	0	192.168.178.40:57628	74.125.193.188:5228 ©
tcp	LISTEN	0	128	[: :]:sunrpc	[::]:*
tcp	ulSTEN	0	5	[::l]:tpp	[::]:*
О Запуск ss с параметрами: -а — для выборки всех сокетов (прослушиваемых и не прослушиваемых); -t и -и — для вывода TCP и UDP соответственно; и -р, чтобы показать использующие сокеты процессы.
445 ss(8): https://www>nan7.org/linux/rnan-pages/man8/ss'.8.html.
248 | Глава 8. Наблюдаемость
® Пример использования сокета. Похоже, ГСР-соединение между локальным 1Р\4-адрссом 192.168.178.46 и удаленным 74.125.193.188 простаивает: данные в очереди на прием (Recv-Q) и передачу (Send-Q) нулевые
Устаревший способ собрать и отобразить статистику интерфейса — команда netstat446 447. Если вам нужен постоянно об ловля ем ый обзор TCP и UDP с идентификаторами процесса и IP-адресами вместо доменных имен, запустите се так: netstat -ctulpn.
Команда Isof*1' (Isof — list open file — список открытых файлов) — это универсальный инструмент со множеством вариантов использования В следующем примере isof используется для отображения сетевых подключений (вывод урезан, чтобы влезал):
$ sudo Isof -г ТСР:1-1024 О
COMMAND PID	USER	FD	TYPE	DEVICE	SIZE/OFF	NODF	NAME
rpebind 26901	root	8u	IPv4	615970	0t0	TCP	*: sunrpe	(LISTEN)
rpebind 26901	root	llu	IPv6	615973	0t0	TCP	*: sunrpe	(LISTEN
О Вывести список привилегированных портов TCP (нужны права root).
Другой вариант использования Isof ориентирован на процесс. Если известен PID процесса (в данном случае Chtome), можно заставить Isof отслеживать дескрипторы файлов, I/O и прочее (вывод урезан, чтобы влезал):
$ Isof -p 5299								
COMMAND	PID	USER	FD	TYPE	DEVICE	SIZE/OFF	NODE	NAME
chi one	5299	mh9	cwd	DIR	253,0	4096	6291458	/none/mh9
chгоне	5299	mh9	rtd	DIR	253,0	4096	2	/
chrome	5299	tnh9	txt	REG	253,6	179093936	3673554	/opt/google/
chrone/chror«e
446 netstat(8): https://vovwnian7.org/lir.ux/inan-pages/-naii8/netstat8.html.
447 lsof( 8j: https://man7.org/llnux/man pages/man8/lso(.8.htr.il.
Наблюдение (мониторинг! | 249
Инструментов для наблюдения (за производительностью) очень много. Сре ди них sar448 (покрывающий целые наборы счетчиков и удобный для скриптов) и perf449. Некоторые инструменты мы рассмотрим в разделе «Расширенная наблюдаемость».
После изучения отдельных одиночных утилит перейдем к комплексным ин струментам, позволяющим осуществлять интерактивное наблюдение в Linux.
Интегрированный мониторинг производительности
Одиночные инструменты вроде Iscf или vmstat хороши для простых случаев и использования в скриптах. Но для удобного наблюдения лучше подходят полноценные интегрированные решения. Обычно они поставляются с текстовым интерфейсом (TUI), иногда цветным, и предлагают следующий функционал:
—	Поддерживают несколько типов ресурсов (ЦП, ОЗУ, ввод-вывод).
—	Допускают интерактивную сортировку и фильтрацию (по процессу, пользователю, ресурсу).
—	Обновляются в реальном времени, отображают детализацию по группам процессов, или даже контрольным группам и пространствам имен.
К примеру, очень известный top450 выводит обзорный заголовок (похожий на тот, что мы видели в результатах uptime), затем табличное отображение дан ных о ЦП и памяти, а следом список процессов, которые можно отслеживать (вывод отредактирован):
top - 12:52:54 up 22 days, 1:04, 1 user, load average: 0.23, 0.26, 3.23 О
Tasks: 263 total,	1 running, 295 sleeping, 0 stopped, 0 zombie ®
%cpu(s): 0.2 us, 0.4 sy, 0.0 ni, 99.3 id, 0.0 wa, 9.0 hi, 0.6 st, \ 0.0 st% •
KiB Mem; 7975928 total, 363608 free, 1360348 used, 6251972 buff/cache
KiB Swap: 999420 total, 998236 free, 1184 used. 5914992 avail Mem
PID USER	PR	NI VIRT RES SHR S	XCPU %MEM	TIME* COMMAND О
1 root	20	9	225776	9580	6712 S	0.0 0.1	0 25.84 systend
*** sar(l) https://)inux.die.net/nian/l/sar.
449 perf: Linux profiling with performance counters: https://perfwiki.github.io/main/.
450 top(l): https://linwcdie net/man/;/tep.
256 | Главе 8 Наблюдаемость
433 root	20	0	1CS968	1928	1700 S	0.0	0.0	0:09.05	'- Ivmetad
775 root	20	Э	36552	4240	3880 5	0.0	J.l	0:60.16	’- bluetcothd
789 syslog	20	Э	2C3040	4384	3616 5	0.0	0.1	0:01.98	rsyslogd
О Сводка по системе (сравните с результатом uptime).
в Статистика задач.
® Статистика использования ЦП (пространства пользователя и ядра, и т. п.; аналогично выводу vmstat).
О Динамический список сведений о каждом процессе; сопоставим с результа -
том выполнения psaux.
Ниже приведены наиболее важные ключи top, которые стоит запомнить: 
Для вывода справки, включая сопоставление клавиш.
V
Для переключения в режим просмотра дерева процессов и обратно.
п
Для сортировки по потреблению памяти.
Р
Для сортировки по потреблению ЦП.
к
Для отправки сигнала (например, kill).
Q
Для выхода.
Хотя top доступен почти в любой среде, для него существуют альтернативы:
htop45* (рисунок 8-3)
Постепенно развивающийся последователь top, более быстрый и с приятным пользовательским интерфейсом.
atop411 (рисунок 8-4)
Мощная альтернатива top. Кроме процессора и памяти этот инструмент охватывает ресурсы — например, I/O и сетевую статистику. 451 452
451 htop — an interactive process viewer: https://htop dev/.
452 Atop — an ASCH full-screen performance monitor: https://atoptool.nl/.
Наблюдение (мониторинг) | 251
be I Oto4 53
Относительно новый инструмент, примечательный тем, что поддерживает cgroups v2 (см. «Контрольные группы Linux»). Другие инструменты, которые не понимают cgroups, предоставляют только глобальный обзор ресурсов.
PIO USER	PRI	NI VIST RES SHR S CWt MEM%	TIME’ Commend
29763 mh9 28	S 59944	4870	3408 R 2.7 01	8:00 77 htap
4470 472	29
5346 mh9	20
5363 mh9	20
5328 mh9	28
r 1643 mh9	20
16944 root	28
81732 root	20
№3317 mh9	20
5299 mW	28
‘1474 tnh9	20
4531 472	28
4535 472	20
4570 472	20
1574 472	20
4530 472	20
4533 472	20
»1729 root	20
№763 root	28
5628 Ph9	28.
6629 wixxiy	20
6678 nobody	28
5617 mh9	29
805 toot	20
32126 mh9	20
793 messageou 29 .4397 root	0-
4592 mh9	20
5593 mh9	20
9 759M 74020 47708 S 0 16.56 119М 86560 S 0 16.58 118M 86560 S 0 16.80 267M 155M S 8 914M 97340 45148 £ 8 88IM 61688 38864 S
0 1247M 55848 29952 S 0 759M 28128 18668 S Q 16.83 267M 155M S 0 1795M 195И 138Я S 0 758M 74020 47708 S 0 759M 74020 47708 S 0 759M 74020 47708 S 0 7S9M 74020 47788 S 0 758M 74820 47708 S 6 759M 74029 47708 S 9 1247H 55040 29952 S 9 1247M 55040 29952 5 0 20.60 33GM 115М S 0 1087M U7M 46356 S S 1087M 117M 46356 S 0 20.66 330M 115И S 0 305M .7020 6000 S 0 63076 0988 3656 S 0 52116 6564 3888 S
?<•' 4524 72 OS 0 70 IM 20948 11704 S 0 701M 20948 11784 S
-	зДТр 'Л-Дг-г; >ЖЖ!'
0.0 0.9 0:54.41 gratana-server --homepath=/usг/snare/grafana --config=/etс/grafana/grafana.ini -packaging=docker cfg:defsuit. ‘
6.0 1.4 7:40.42 /opt/google/chrome/chrome ••type=utility --utility-sub-type«network.(nojom.Networkservice •-field-trial-handles^ 0.6 1,4 7:02.97 /opt/google/chrome?chrome --type=utlUty -•utillty-sub-type=network.mojom,Het,workService -fir.-ld-trial-handi—J 0.0	3.4	5:24.42	/opt/google/chrome/chrbiie -enable-crashpad
1.3	1.2	0:57,12	/snap/alacritty/46/bin/alacritty
8.7 8.1 21:96.52 /usr/lib/xorg/xorg -core :0 -seat seats -auth /var/run/lightd«i/rooi/:0 -nollsten tep vt7 -novtswitch
0.8	0.7	0:45,35	/usr/bin/containerd
9.0	0.4	1:06.67	/usr/lib/gnome-settings-daemon/gsd-color
0.7	3.4	22.-08.21	/opt/google/chrome/chrome —enable-crashpad
0.7	2.5	19:19.81	gala
6.0	0.9	6:66.67	grafana-server --homepath=/usr/share/grafana	--config«/etc/grafana/grafana.ini	-packaging-docker	cfg:defaui I
e.e	a.9	0:96.96	grafana-server --horwpath=/usr/share/grafana	•-cohfig=/etc/grafana/gr»taiia. jni	•	-packaging=docker	cfgidefau I
6.0	0.9	0:07.96	grafana-server -•homepath«=/usr/share/grafana	--conf ig®/etc/grafana/graf8M. ini	-packaging-docker	cfg:defaulT
0.0	0.9	0:06.19	grafana-server -nomepath^/usr/share/grafana	•-configw/ete/grafana/grafano.ini	-packaging-docker	cfg:default.
8.0	8.9	6:18.92	grafana-server - homepatfw/usr/share/grafana	•-config=/etc/gra*>e»/graf»na.Ini		packaging-docker	ctg:default
e.8	0.9	8:06.11	grafana-server --bonepath»/usr/share/grafana	--config^/etc/grafana/grafona.ini	--packaging=docker	cfg:defsult
O.O	9.7	3:35.18	/usr/bin/containerd .
0.6	0.7	0:22.34	/usr/bin/containerd
0.0 4.2 9:09.18 /opt/google/chrome/chrome -type=rcnderer --enable-crashpad -crashpad-handler-pid»5309 --enable-crash-reportS 8.0 1.5 8:53.95 /ban/prometheus - config.ftle=/etc/prometheus/prometheus.ynil --storage.tsdb.path»/prometheus •-web.console. I it 0.8 1.5 6:99.58 /bin/pronetheus --config.file“/etc/prometheus/prometheus.yml storage.tsdb.path»/prometiieus --web.console.lib 0.0 4.2 53:47.65 /opt/google/chrome/chrome --type=renderer --enable-trashpad -•crashped-handler-pid*5309 -enable-crash-report*™ 0.0 0.1 6:08.61 /usr/lib/arcountsserviee/accounts-daemon
0.6 0.1 1:26.97 tmux new-session -A -s zzz
0,6 0.1 1.-44.66 /usr/bin/dbus-daemon --system --addressesystemd: --nofork --nopidflle --systemd-activatlon --syslog-only
0.0 0.0 0:85.85 /usr/sbin/atopacctd
0.0 C.3 3:47.38 node exporter/node exporter
0.0 0.3 0:16.46 node exbort cr/node exporter
Рисунок 8 3. Снимок инструмента htop
аТОР . ctarIH*					2021/16/03 10-48-15											25d22h59m30S elapsed	
	sys 761Г285 |	user	2h44m |		1 Sproc 338	I ftrun	i	dtslpi	773 | *tslpu	0	; «zombie	9					| S-exit	3
.PU i	m |		294 | irq	24»		| idle	35A I	wait	<34 |		i steal		guest		( curf	1.42GHz	| curscal 56"
	22V I	user	| i rg			| idle	3% |	CpuBOZ	w e\ |		j steal	1ft i	guest	(Л	curr	968MHz'	| curscal 38
	1		6:>4 | irq			I idle	3h I	CPU001	w (Л |		I steal	0% 1	guest	0*	| curf	1.49GHZ	| curscal 59"
	svs	26V |		tiT’t» | erg			| idle	3k 1	сривез	w 04 |		s steal	ВЛ !	guest	01k	curt	92OMHZ	| curscal 36..
pu 1	sys	lit ]	user	24 [ irq	0%		| idle	974 |	epuoes	н 0% I		| steal		guest	04	1 curf	2.28GHZ	! curscal 914
PL i	avgl 0.71 J	avg5	0.59 |		| avgl5 0.32			csw 169504e3 )			| intr 12146e4				1		| потери	4
	tot 7.6G 1	tree	318.ем | cache 4.30		| dirty 21.9M	I buff.	775.0M |	slab 1	>61.4M | shmem	456. IM	I shrss	5.8M	vmbal	8.GM	| hptot	S.0M	! hpusa 0.0M
,WP 1	tot 976.CM |	free	974.IM ]												| vmcom	9.3G	| vmlim 4.86
	scan 993145 j	steal	958026 | stal	I	6					i							41	’ SWOUt 431
VM	ary-vg-root j	busy	2fc | read	91472	I write 1557e3	| KiB/r	31 I	K1B/W	17 1		i M8r/s	8.8	MBw/s	9.0	1 ivq	3.57	j avio 8.70
VM 1	y--vg-swap 1 |	busy	O’: | read	232	| write 431	| KiB/r	19 |	KiB/w	4 1		I MBr/s	0.8 .	MBw/s	Э.0	1 avq	2.64	j avio 3.17 ms
"JK ,	sda |	busy	24 j read	78826	| write 814450	| KiB/r-	41 1	KiB/w	33 j		j MBr/s	0.0 :	MBw/s	0.0	1 avq	1.60	I avio 1.32 л--..
I.ET	transport j	tepi	444725 | tepo	359780	I udpi 1586029	I udpo	346839 |	tepao	7072 | teppo	12B	| teprs	819	tepie	IOC	I tepor	5330	j udpie 4979
	network	j	ipi	2168519 j ipo	841993	1 ipfrw 154015	I deliv	2014e3 |		|						I tempi	1616	| tempo 3081
r 1	wlplsa 8% |	peki	3192803 | peko	713901	| sp 72 Mbps	1 si	12 Kbps |	so (	3 Kbps | mlti	0	I erri		erro		1 drpl	13	| drpo	(->
I- ’ !	vethS68 G4 |	pckl	6406 | peko	7274	| sp 18 Gbps	1 si	0 Kbps |	so	1 Kbps | mlti	0	j erri	1	erro		1 drpi	0	| drpo	°
	vethdSe 84 1	peki	8746 | peko	9430	| Sp 10 Gbps	1 si	0 Kbps |	so	3 Kbps | mlti	Э	1 erri		| erro		1 drpi		
	dockerfi ---- j	pckl	68534 | peko	114596	) sp 0 Mbps	I si	в Kbps |	so	L Kbps 1 mlti	0	| erri		| erro	e	1 drpi	0	| drpo
-(L	lo	— - |	peki	37238 | peko	37238	j sp G Mbps	1 5»	0 Kbps |	so	3 Kbps j mlti	0	| erri		| erro	о	1 drpi	6	| drpo
1								cess ac	tcvit.y since boot •’*								
n					МКЁ2&Л1И					IlMi	ЦЗЯН	Ki'.M					
				49«44s			mh9		ii’.hg	N-							chrome
5617	host			10m29s		20.7G	379.6M	»h9		mh9	N-						54	chrome
52s,.	host			7m33s	14®34s	16.8G	269.0M	m)i9		mh9	N-		26					chrome
	host			9fnl7s	llfflSbS	881.4M	61580K	root		root	N-		lu					Xorg
	host			4mS2s	14m32s	1.8G	203.9M	Mh9		mh9	N-							gala
534:	host- —-.-		2ml2s	5Л1315	16.5G	139.9M	mh9		frh9	N-		. 10	5				chrome
45-?.	host			2mGls	lm46s	701.8M	19856K	mh9		mh9	N-		15				04	node export<
516	host			3m37s	G.00S	9K	0K	root		root	N-			5		3	C':	irq/127-iwL-
1729	host			74.295	2 m2 IS	1.2G	5584GK	root		root	N-		16	S			еч	containerd
5G9’	host			16.68s	2ml8s •	20.6G	182.4M	mh9		mh9	N-		11	S			84	chrome
1.1	host			2ffllBs	0.48s	6K	0K	root		root	N-			I		0	04	rcu sched
835	host-----		44.29s	74.49s	'707.2M	18052K	root		root	N-		3	c		3	84	NetworkMar >
	host			I4.74S	lm44s	1.3G	198.ем	root		root	N-		16	S				docksrd
482	host			lmS4s	0.00s	0K	0K	root		root	N-					0		lrq/126 ALF « I
793	host			14.49s	90.23S	52116K	6564K	messageb		messageb	N-			S			0%	dous-daemon
	host			22.G3S	73.21S	1.8G	Ш.4М	mh9		mh9	H-		6	5		8	04	io.elementar.
Рисунок 8-4. Снимок инструмента atop 453
453 below — an interactive tool to view and record historical system data: https-/,'github.com/ facebookincubator/below.
252 | Глава 8. Наблюдаемость
Несколько других интегрированных инструментов монит оринга охватывают источники за пределами базовых или специализируются на специфичных случаях. Например:
glances454
Мощный гибрид, который в дополнение к обычным ресурсам наблюдает за уст ройствами.
guider45?
Встроенный анализатор производительности, способный отображать и строить графики для множества показателей.
neoss455 * 457
Для наблюдения за сетевым трафиком; замена ss с приятным TUI.
mtr45'
Для наблюдения за сетевым трафиком; мощная альтернатива traceroute (подробнее о traceroute в разделе ^Маршрутизация»).
Научившись анализировать системные метрики, научимся порождать собственные из кода.
Мониторинг среды выполнения
До сих пор мы работали с сигналами, поступающими от ядра и известных приложений, то есть из программного кода, которым вы не владеете. Порождать метрики можно и в собственной программе (примерно также, как вы пишете в лог).
Процесс добавления кода для от правки сигналов (а т акже мет рики) актуален для разработчиков ПО. Есть две основные стратегии добавления мониторинга: автоинструментирование (без дополнительных усилий от разработчика) и ручное инструментирование, когда вы сами расставляете фрагменты кода для испускания метрик в определенных точках программы.
434 Glances: https://nicolargo.github.io/glances/
455 Guider: bttps://gi1bub.conViipeace/guider.
434 neoss; bttpsh/github.com/PabloLec/neoss.
457 mtr: https /'wv. w.hitATzard.nl/'mtr/.
Наблюдение (мснигоринг) | 253
Порождать сигналы поможет StatsD458. Fro клиентские библиотеки доступны для самых разных языков программирования, например, Ruby’5 * 461 462’ Node.js463, Python441 и Go442. StalsD удобен во многих случаях, однако в динамических средах вроде Kubernetes или ТоТ у него есть ограничения. В таких средах практикуется подход, называемый pull-based или scraping, при котором приложения предоставляют метрики запросу, обычно через HTTPAPI. Внутри приложений нет кода, в котором указано, куда поставлять метрики, но агенты могут запросить их сами в любой момент. Мы вернемся к этой теме в разделе «Prometheus и Grafana».
Углубимся в наблюдаемость
Теперь, когда вам знакомы основы наблюдаемости в Linux, затронем более сложные вопросы.
Трассировка и профилирование
У понятия «трассировка» несколько разных значений. В рамках отдельной машины с Linux трассировка означает отслеживание того, как выполнялся процесс (какие функции использовал в пользовательском пространстве, какие систем ные вызовы делал и т. д.),
В распределенных средах, вроде контейнерных микросервисов Kubernetes или в хитросплетении лямбда-функций бессер-верных приложений, мы иногда сокращаем выражение «распределенная трассировка»463 (с OpenTelemetry или Jaeger) до обычной «трассировки», но этот тип выходит за рамки книги.
На отдельно взятой машине с Linux можно трассировать следующие источ ники:
458 StatsD: https://gitr.ub.com/statsd/statsd.
45’ StatsD client for Rnby apps: https://gitbub.com/shopify/statsd-instrument.
440 node stated client: https.//gitbub.com/msiebuhr/noce- statsd-client.
461 Python Statsd Client: https.Z/python statsd readthedocs.io/en/latest/.
462 gostatsd: https://github.com/atiassian/gostatsd.
463 Pattern: Distributed tracing: https://microsrrvices.io/patterns/oaservability/disiributed-tracir.g. html.
254 | Глава 8. Наблюдаемость
Ядро Linux
Трассировки исходят от функций ядра или запускаются системными вызовами. В качестве примера можно привести зонды ядра (kprobes’64) или точки трассировки в ядре (kernel tracepoints)465
Пользовательское пространство
Источником трассировок служат вызовы функций в при/южении, например, через датчики пользовательского пространства (uprobes466).
Трассировка полезна при решении следующих задач:
—	Отладка программ, например, с помощью инструмента трассировки strace467.
—	Анализ производительности из пользовательского интерфейса с использованием perf’68.
ШЕсли у вас возникнет соблазн применять strace везде и повсюду, не забудьте о неизбежных накладных расходах (особенно критичных для производственных сред). Узнайте больше в статье Брендана Грегга «strace: Ничего себе системные вызовы»469
На рисунке 8-5 показана сводка по процессам, выведенная с помощью ко манды sudoperftop.
Судя по всему, благодаря развивающейся экосистеме и растущей поддержке поставщиков eBPF (см. «Современный способ расширить ядро: eBPF») скоро станет стандартом для реализации трассировки, особенно в единичных случаях. Если вы ищете метод трассировки, ориентированный на будущее, выбирайте основанный на eBPF.
404 Kernel Probes (Kprobes): https://www.kernel.0rg/d0c/html/la:est/trace/Kpr0bes.html.
*5 www.kernel.org,'doc/hcml/v5.15 rc3/trace/tracepomts.html: https://docs.kernel.org/trace/ tracepoints.html
466 Uprobe-tracer: Uprobe-based Event Tracing: https://v\'ww.kerneJ.org/doc/ntml/lates:/trace/ uprobetracer.html.
44,7 strace; https://strace.io/.
“* * per Examples: https://www.brendar.gregg.com/perf.html.
«strace Wow Much Syscall» by Brendan Gregg: https://www.brendangregg ccm/blog/2014 05 •
11/strace-wow-much -syscall.htm).
Углубимся з наблюдаемость | 255
Isamples 11К of event ‘cycles’, 4600 Hz, Event count (approx.j: 2991897199lost: 6/0 drop: e/i
(Overhead Shared Object	Symbol
	perf	1.)		symbols	insert
	perf	[.]	ro next
4.83%	[kernel ]	[k]	module get kallsym
3.06%	perf	[.]	rb insert color
2.28%	perf	[.]	d oeraangle callback
1.34%	[kernel]	[k]	clear page erms
1.30%	[kernel]	[k]	acpi os read port
1.18%	[kernel]	Ik]	number
1.15%	libc-2.27.so	[.]	libc calloc
1.15%	[kernel]	[k]	acpi idle do entry
1.10%	[kernel]	Ik]	format decode
1.04%	perf	[.]	dso	loao sym
1.00%	libc-2.27 so	[.]	ctree
0.96%	[kernel]	[k]	kallsyms expand symbol.constprop.1
0.88%	[kernel]	[kJ	memepy erms
0.87%	[kernel]	Ik]	vsnprintf
0.71%	[kernel]	[k]	string nocheck
0.61%	[kernel]	[k]	get pagefrom freelist
0.60%	perf	[.]	symbol	new
0.55%	perf	[.]	rb erase
0.49%	perf	[.]	_ dso	load kallsyms
0.41%	libelf 0.170.so	[.]	gelf getsym
0.41%	libc-2.27.so	[.]	getdelim
0.40%	libc-2.27.so	].]	0x0009O00000093d39
0.39%	perf	[•]	demangle java sym
0.37%	libel f-0.170.so	1.)	gelf getsndr
0.35%	[kernel]	[k]	change protection range
0.34%	[kernel]	Ik]	psi task change
0.33%	libc-2.27.so	[.]	malloc
0.33%	1 kernel]	[k]	update iter
0.33%	perf	[.]	java demangle sym
0.31%	perf	[.]	eprintf
0.30%	[kernel]	Ik]	_ handle mm fault
0.30%	[kernel]	Ik]	update blocked averages
0.29%	[kernel]	[kJ	native irq return iret
0.28%	perf	[•]	rust is mangled
ry:			
Рисунок 8-5. Снимок инструмента трассировки perf
Профилирование — это один из подвидов трассировки, который используют для выявления часто вызываемых секций программного кода. Низкоуровневые инструменты для профилирования включают в себя pprof470, Valgrind471 и визу ализации flame graph472.
Интерактивно использовать выходные данные perf и визуализировать трас сировки можно по-разному. К примеру, ознакомьтесь с статьей в «Графические интерфейсы профилировщика pert в Linux»473 в блотс Марка Хансена.
470 pprofU): https://linux.die.r.et/man/l/pprof
471 Valgrind: https ./zvalgrind.org/.
472 Flame Graphs: https://www.brendangregg.com/flamegraphs.html,
473 «Linux perf Profiler UIs» (Mark Hansens blog): https://www.markhansen.co.nz/prcfiler-uis/.
256 |	Глава 8. Ha& подаемся т ь
Непрерывное профилирование — усовершенствованный вариант профилирования, который фиксирует повторяемые трассировки ядра и пользовательского пространства. После сбора всех снимков их можно визуализировать и сравнить, углубляясь в наиболее интересные сегменты. В пример можно привести многообещающий проект рагса474 475 (открытый исходный код; основан на eBPF), приведенный на рисунке 8 6.
Рисунок 8-6. Снимок инструмента непрерывного профилирования рагса
Prometheus и Grafana
Если вам предстоит иметь дело с целым набором метрик, собранных за период (временной ряд), то связка из Prometheus и Grafana может быть привлекательным выбором в рамках углубленной наблюдаемости.
Я дам ьам простой и готовый репепт, который можно использовать для мониторинга и даже для оповещения о событиях, происходящих на одной локальной машине с Linux.
Для получения системных метрик процессора, памяти и сети мы используем экспортер узлов (node_cxporter4/5). Затем, прописав адрес экспортера (HTTPAPIURL/metrics) в настройках Prometheus, заставим последний забирать метрики в формате OpenMetrics476. И, наконец, мы используем Grafana (с Prometheus в качестве источника данных), чтобы графически отобразить метрики на панелях мониторинга и настроить оповещения о наступлении
47,1 рагса: https://www.parca.GCv/.
475 Node exporter- https://github.com/prometheus/noce_exporter.
47“ OpenMetrics: https://oper.merrics.io/.
Углубимся в наблюдаемость | 257
определенных условий — к примеру, о нехватке места на диске или перегрузках ЦП.
Первым делом скачайте и распакуйте архив с экспортером узлов, а потом запустите его исполняемый файл в фоновом режиме. ./node_exporter& Проверьте. правильно ли он работает (вывод урезан):
$ curl lccalhost:9iG0/metrics
# TYPE gogc_duration_seconds sjrnnary
go_gc_du ration._seconds{quantite="0"} 7.2575e-G5 go_gc_duration_seconds{quantile="G.25"} 0.06011246 oo_gc_duration_seconds{quantile="0.5"} 0 060227351 go. gc duretion .serorids{q'jartile="0.75"} 0.600336613 go_gc_duration_seconds{quantile="l"} 0.Э02659194 go_gc_dur atton_seconds_sum 0.126529838 go_gc_dui ation_seronds_co.ini 390
Источник сигналов настроен, и мы запускаем Prometheus и Grafana в отдельных контейнерах. Для этого понадобится установленный и настроенный Docker (см. «Docker»).
Создайте файл конфигурации Prometheus с именем pronetheus.ynl и следующим содержимым:
global:
scrape.interval: 15s
evaluatiorjinterval: 15s
exte rnal„l3aels:
noritor: ' mypiachine'
sc"ape.configs:
-	job_na"ie: 'pronetheus' О static.configs:
-	targets: ['localhost:9090']
* job.nane: 'machine' ®
static.configs:
- targets: ['172.17.0.1:9100']
258 | Глава 8 Наблюдаемое гь
О Prometheus тоже предоставляет метрики, поэтому включаем самонаблюдение.
О Это наш экспортер узлов. Поскольку мы запускаем Prometheus в контейнере, вместо недоступного localhost прописываем IP-адрес, который Docker использует по умолчанию.
Файл с настройками Prometheus мы монтируем в контейнер через volume:
$ cocker run --name premetheus \
--rm -d -p 909S 9690 \ О
-v /home/nhO/lnl/olly/prometheus.yinl^etc/prometheus/propierheus.yinl \ в prom/prometheus main
О Указанные параметры заставляют Docker удалять контейнер при выходе (- - гп), запускаться в виде демона (-d) и открывать порт 9090 (-р), чтобы до него можно было достучаться с нашей машины.
© Подключаем файл конфигурации в контейнер как volume. Обратите внима ние, что /hone/nh9/lnl/olly/ нужно исправить на абсолютный путь к вашему каталогу с файлом. Если хотите сохранить гибкость, вместо абсолютною пути используйте переменную $PWD в bash, или (p*d) в Fish.
После выполнения команды откройте в браузере localhost.9000 и выберите Targets в раскрывающемся меню Status вверху. Если через несколько секунд вы увидите примерно такой же экран, как на рисунке 8-7, значит, Prometheus успешно извлек собственные метрики и метрики экспортера узлов
Рисунок 8 7, Снимок веб-интерфейса с панелями целей Prometheus
Углубило; в наблюдаемость | 259
Теперь запускаем Grafana:
$ docker run --name grafena \
-- rm -d -p 3909:3063 \
grafana/grafana:8.^.3
После выполнения команды откройте в браузере localhost:3000 и войдите с именем пользователя и паролем admin. Осталось выполнить два шага:
1. Добавьте Prometheus в качестве источника данных для Grafana через URL 172.17.0.1:9160.
2, Импортируйте полный набор панелей Node Exporter477.
По завершении вы увидите экран, похожий на рисунок 8-S.
Рисунок 8-8. Снимок интерфейса Grafana с полным набором панелей Node Exporter
Вот и все. Это был увлекательный пример углубленной наблюдаемости Linux с использованием современных инструментов. Учитывая, что настройка связки Prometheus/Grafana довольно сложна и запутана, вряд ли вы захотите поднимать ее по любому поводу. Однако инструментарию, встроенному в Linux, который мы обсуждали в этой главе, еще далеко до совершенства, и в сложных случаях — при домашней автоматизации или настройке медиассрвера — Prometheus и Grafana обязательно вам пригодятся.
477 Node Exporter bulk: https://grafana.com/grafana/6ashboards/J860-node-exporter-fiill/.
260 | Глава 8, Наблюдаемость
Заключение
В этой главе мы научились не тыкаться вслепую, сталкиваясь с проблемами в Linux. Мы рассмотрели основные типы диагностических сигналов — текстовые (журналы) и числовые (метрики). В запутанных случаях вы можете применять техники профилирования, которые графически отобразят статистику использования ресурсов и предоставят дополнительную информацию (имя файла и номер строки в коде).
Если хотите глубже погрузиться в обсужденную тему, обратите внимание на следующие ресурсы:
Основы
— Брендан Грегг, «Производительность систем на примере Linux», второе издание, Питер, 2024т.
— «Анализ производительности Linux за 60 000 миллисекунд»47’.
Журналирование
—	«Полное руководство по ведению журнала в Linux»478 * 480.
—	«Unix/Linux — Системные журналы»481.
—	«syslog-ng» на Arch Wiki482.
—	Веб-сайт fluentd483.
Наблюдение (мониторинг)
—	«80+ инст рументов мониторинга для сисадминов»484.
—	«Мониторинг в StatsD: типы метрик, форматы, примеры кода»485.
478 Брендан Грегг, «Производительность систем на примере Linux», второе издание, Питер, 2024: https.//www.piter com/col!ectior./!inux/producl /proizvoditelnost-sistem
4/4 «Linux Performance Analysis in 60,000 Millisecond»: https://netflixtecbblog.coni/liriux-performance-analysis in-60-0C0-milliseconds-acccl0403c55.
48C «Linux Logging Complete Guide»: htlps://devconnected.com/linux-logging-co.-nplete-guide,'.
481 «Unix/Linux — System Logging»: https://wwivtutoriaispoint.com/unix/unix-system legging, him.
482 «syslog-ng» on ArchWiki: https:// wiki.archlinux.org/title/Syslog-ng.
483 fluentd website: https:/,'www.fluentd.org/
484 «80+ Linux Monitoring Tools for SysAdmins»: https://web.arcliive.org/web/20190825083445/ https://biog.srackpath.com/linux-monitoring-tools/.
485 Monitoring StatsD: metric types, format + code examples: nttps://sysdig.com/blog/monitoring-stated metrics/.
Заключение | 261
Специалистам
—	«Производительность Linux»486.
—	«Системы трассировки Linux и как они сочетаются»487 488 *.
—	«Profilerpedia: Карта экосистемы ПО для профилирования»48".
—	«О состоянии непрерывного профилирования»439.
—	Веб-сайт eBPF490 *.
—	«Мониторинг показателей отдельного хоста Linux с помощью Node Exporter»4”.
Завершив изучение этой главы (и всех предыдущих), вы можете сказать, что знакомы с основами работы в Linux от ядра и оболочек до файловых систем и сетей. В последней главе собраны углубленные темы, не слишком вписавшиеся в остальную книгу. Возможно, они покажутся вам полезными и интересными (в зависимости от ваших целей), но вашего багажа знаний уже достаточно для решения большинства повседневных задач.
486 «Linux Performance»: https://www.brendangregg.com/linuxperfhtml.
4,7 «Linux Tracing Systems Sr How They Fit Together»: https://jvns.ca/blog/2017/07/05/linux-tracing-systems/.
488 «Profilerpedia: A Map of the Software Profiling Ecosystem»: https://www. markhansen co.nz/ profilerpedia/.
485 «On the State of Continuous Profiling»: https://mhausenblas.rnedium.com/the-state-of-continuous-prcfiling b89cdbdd47f6.
eBPF website: https://ebpf.io/.
4,1 «Monitoring Linux Host Metrics with the Node Exporter»: https://prc metheus.io/docs/guides/ node exporter/.
ГЛАВА 9
Углубленные темы
Последняя глава немного путаная. Мы охватим целый ряд тем— виртуальные машины, безопасность, новаторские способы использования Linux, которые сходятся только в одном: большинство приведенных примеров пригодятся в специ фичных случаях или в профессиональной работе.
Мы начнем главу с разбора того, как взаимодействуют и обмениваются данными процессы одной машины. Из изрядного списка механизмов межпроцессного взаимодействия (ТРС) мы выделим хорошо известные и популярные: сигналы, именованные каналы и сокеты домена Unix.
Затем затронем тему виртуальных машин (VM). В отличие от контейнеров (см. «Контейнеры»), которые хороши для управления зависимостями на уровне отдельных приложений, виртуальные машины предоставляют повышенную изоляцию для рабочих нагрузок. С ними вы столкнетесь в публичном облаке и в центрах обработки данных. Но даже локальное использование VM оправдано: они полезны при тестировании или имитации распределенных систем.
После виртуальных машин мы рассмотрим современные дистрибутивы Linux, ориентированные на контейнеры и неизменяемость, их вы повстречаете в распределенных системах, подобных Kubernetes.
Также мы уделим внимание вопросам безопасности, связанным с Kerberos (известный пакет проверки подлинности пользователей), и обсудим подключаемые модули РАМ — расширения Linux для аутентификации.
В конце главы вас ждут техники работы с Linux, которые на момент написания книги еще не стали популярными, но могут заинтересовать вас и достойны внимания.
Межпроцессное взаимодействие
Можно долго перечислять способы межпроцессного взаимодействия (IPC)492 в Linux, вспоминая и каналы, и общий доступ к памяти. IPC позволяет процессам
492 Inter process ccmrrunication (IPC): https;7en.wlkipedia org/wiki.'lnter process communication.
Межпроцессное взаимодействие | 263
взаимодействовать, синхронизировать действия, обмениваться данными. Демон Docker, к примеру, использует настраиваемые сокеты для управления контейнерами. В этом разделе мы рассмотрим популярные возможности IPC с примерами использования.
Сигналы
Сигналы позволяют ядру уведомлять процессы в пользовательском пространстве о наступлении событий. Воспринимайте их хак отправляемые процессом асинхронные сообщения. Большинство сигналов (полный список см. в пап 7 signal) связаны с определенными действиями по умолчанию — например, оста новкой или завершением процесса.
В большинстве случаев вы будете определять собственные обработчики вместо тех, которые Linux выполнит по умолчанию. Это полезно, когда нужно провести дополнительную очистку перед реакцией на сигнал или просто проигнорировать его.
В таблице 9-1 приведены основные сигналы, о которых полезно знать.
Таблица 9-1. Основные сигналы
Сигнал	Тип	Действие по умолчанию	Обработчики	Клавиши
SIGHUP	Заставляет демон-процесс перечитать Файл конфигурации	Завершение процесса	г ohзр или пользовательский обработчик	
S1GINT	Прерывание программы с клавиатуры	Завершение процесса	Пользовательский обра5о1чик	Ctrl 4-С
SIGQUIT	Команда на выход с клавиатуры	Дамп ядра и завершение гроцесса	Пользовательский обработчик	Ctrl + \
SIGKILL	Жесткое прерывание процесса (kill)	Завершение процесса	Не перехва’ывагся	
SIGSТОР	Остановить процесс	Остановка процесса	Не перехватывается	
SIGTSTP	Сигнал остановки с клавиатуры	Остановка процесса	Пользовательский обработчик	Ctrl + Z
SIGTERM	Изящное (gracefull) завершение	Завершение процесса	Пользовательский обработчик	
Некоторые сигналы, не связанные с конкретными действиями (SICUSR1 и SIGUSR2), процессы используют для обмена асинхронными уведомлениями, если обе стороны поддерживают общую семантику сигнала.
264 | Глава 9. Углубленные темы
Типичный пример отправки сигнала процессу — команда kill («убить»). Ее название объясняется ее стандартным действием — немедленно прервать выполнение процесса.
$ while true; do sleep 1; done & О
[1]	17030 ®
$ ps ® PID TTY	TIME	CMD
16939 pts/2	00:00:00	bash
17030 pts/2	09:00:00	bash	®
17041 pts/2	03'.ЭЭ:00	sleep
17045 pts/2	03:00:00	ps
$ kill 17030 ®
[1]+ Terminated	while true; do
sleep 1;
done
® Мы создали элементарную программу, которая простаивает в цикле, и с помощью 8 перевели ее в фоновый режим.
® Оболочка подтверждает, что программа выполняется как задание с ID 1 в фоновом режиме, и сообщает 1D процесса (17030).
© Используя ps, мы можем убедиться, что программа по- прежнему выполняется, о Наша программа (сравните PID).
О По умолчанию kill отправляет процессу SlGlfRM, стандартное назначение которого — завершить процесс корректно. Мы передаем команде PID (17030), и поскольку никакого обработчика для перехвата не задано, процесс завершается.
Теперь посмотрим, как перехватывать сигнал с помощью trap493, который позволяет определить обработчик ь командной строке или скрипте:
$ trap "echo kthxbye" SICINT; while true; do sleep 1; done О
ACkthxbye ®
G Инструкцией trap "echckthxbye" SIGINT мы регистрируем обработчик. Теперь, если пользователь нажмет Ctrl+С (отправляя процессу7 SIGNT), перед стандартным завершением процесса будет выполнен echokthxbye.
4” trap(lp): bttps://wwv'.man7.org/linux/man-pages/manl/trap.Jp.html.
Межпроцессное влаимодейспие | 265
в Мы видим вмешательство (ЛС это и есть Ctrl+C), а затем наш обработчик выводит kthxbye, как и ожидалось.
Сигналы — простой, нс мощный механизм 1РС, и теперь вы умеете отправлять и обрабатывать их в Linux. Далее обсудим две более сложных и мощных механики 1РС: именованные каналы и сокеты домена UNIX.
Именованные каналы
В разделе «Потеки ввода/вывода» мы обсуждали каналы (называя их конвейерами |), которые позволяют передавать данные, соединяя stdout одного процесса со stdin другого. Такие каналы называются безымянными или анонимными. Логично предположить, что именованным каналам454 можно присваивать имена.
Именованные каналы, также как анонимные, работают с обычным файловым I/O (открытие, запись и т. д.), обеспечивая очередность доставки по принципу «первый пришел, первый ушел» (ЯFO) — с той разницей, что срок службы именованного канала не ограничен процессами, которые он обслуживает. Фактически именованные каналы — это обсргки над каналами, использующими псевдо-файловую систему pipefs (см. «Псевдофайловые системы»).
Чтобы лучше понять область применения именованного канала, посмотрим на него в действии. Создадим именованный канал examplepipe и два процесса — для публикации и потребления данных:
$ nkfifo exanplepipe О
$ Is -I exanplepipe
prw rw-r-- 1 nh9 nh9 0 Oct 2 14 04 exanplepipe ®
$ while true; de echo "x" > exanplepipe; sleep 5; done & C [1] 19628
$ while true; do cat < exanplepipe; sleep 5; done t О
[2]	19636
X ©
x
m Named pipe: https://en.wikipedia.org/wiki/Named_pipe.
266 | Глава 9. Углубленные темы
О Создаем именованный канал exanolepipe
® Обследуя его командой Is, можно узнать его тип: начальная буква р говорит о том, что это именованный канал.
® В цикле мы передаем (публикуем) в наш канал символ х. Учтите, если пи один другой процесс не читает (не потребляет) из какала exanplepipe, то он блокируется. Дальнейшая запись в него невозможна,
о Запускаем второй процесс, который, тоже в цикле, считывает данные из канала.
® При запуске нашей сборки мы наб людаем х, возникающий в терминале примерно каждые пять секунд, то есть всякий раз, когда процессу PID 19636 доступно считывание данных из именованного канала командой cat.
Использовать именованные каналы достаточно просто Благодаря их конструкции работа с ними похожа на работу с файлами, но с ограничением, поддерживается только одно направление и один потребитель. Для следующей механики [PC, кот орую мы рассмотрим, таких ограничений нет
Сокеты домена UNIX
Мы обсуждали сокеты в применении к сетям, но существуют сокеты и других типов, предназначенные для работы иг отдельной машине. Среди них выделяются сокеты домена UNIX495 — двунаправленные многоканальные конечные точки, читать из которых может сразу несколько потребителей.
Сокеты домена бывают трех видов’96: ориентированные на потоки (SOCK, STRFAM), на датаграммы (SOCK_DCRAH) и на серии пакетов (SOCK_SEQPACKET) Адресация строится на файловой системе: вместо IP-адреса и порта используется самый обычный путь к файду.
Чаще всего к сокетам домена обращаются из кода программы497, но в некоторых случаях (при отладке системы) можно взаимодействовать с ними вручную через утилиты командной строки — например, через socat’98
495 Unix domain socket- nttps;//en wikipeJia.org/wiki/Unix_domain_socket
496 unix(7): https://www.man7 org/linux/man-pages/man7/unix.7.html.
497 (jetting Started with Unix Domain Sockets: https://medium.com/swlh/ge1ting-started-with-unix-demain sockets-4472c0do4ebl.
494 socat: https://copyconstruct.medium.com/socat-29453e9fc8a6.
Межпроцессное взаимодейа вне | 267
Виртуальные машины
Мы рассмотрим методику, которая позволяет эмулировать несколько виртуаль ных машин на одном физическом компьютере: в вашем ноутбуке или на сервере. Виртуализация предлагает гибкий и мощный способ запускать нагрузки (напри мер, для разных арендаторов) в строгой изоляции друг от дэуга. Нас интересует аппаратная виртуализация для архитектуры х86.
Рисунок 9-1. Архитектура виртуализации
На рисунке 9-1 показана схематика арлитекг уры вир туалиаации (на1 гиная снизу).
Центральный процессор
Должен поддерживать аппаратную виртуализацию
Виртуальная машина на базе ядра
Встроена в ядро Linux; обсуждается в разделе «Виртуальная машина на базе ядра».
Компоненты пользовательского пространства
Среди компонентов в пользовательском пространстве выделяются:
Монитор виртуальной машины (Virtual Machine Monitor, или VMM) Управляет виртуальными машинами и эмулирует виртуальные устрой ства, например, QF,MU4” и Firecracker (см. «Firecracker»). Стандартизует
4п QEMU: https://wwvv.qemu.org/.
268 | Глава 9 Углубленные темы
VMM и библиотека libvirt500, с базовым API которой обычно работают из программною кода (на рисунке не показана, но считайте ее частью VMM-блока).
Гостевое ядро
В большинстве случаев это тоже ядро Linux, но может быть и Windows.
Гостевые процессы
Запускаются на гостевом ядре.
Базовая машина, где развернуты VM, называется хостом. Процессы, запущенные на ядре хоста (процессы 1 и 2 на рисунке 9-1), изолированы от гостевых По задумке, гостевые действия не влияют на работу физического процессора и память базовой машины, а атака на виртуальную машину не затронет базовое ядро и процессы (если виртуальной машине не предоставлен особый доступ к хосту). Однако на практике бывают исключения — например, атаки rowhammer501, или Meltdown и Spectre502.
Виртуальная машина на основе ядра
Виртуальная машина на базе ядра (KVM503) — эго решение для виртуализации оборудования х86. Оно встроено в Linux и поддерживает специфичные расширения — например, AMD-V504 или Intel VT505.
KVM представлен двумя основными модулями ядра: основным (kvm.ko) и модулем, специфичным для архитектуры ЦП (kvrn -intel-ko или kvm.amd.ko). Ядро Linux становится гипервизором и берет на себя большую часть тяжелой работы. Кроме того, дополнительные драйверы (например, интегрированный Virtio) помогают виртуализировать I/O
Обычно современное оборудование поддерживает виртуализацию и KVM доступен сразу Способность вашей системы работать с KVM легко проверяется (вывод урезан):
500 libvirt: https://libvirt.org/
501 Row Hammer exploit: https://en.wikipedia.org/wiki/Row_hammer,
502 Meltdown and Spectre attack. htrps://me)tdownattack.com/.
503 Kernel based Virtual Machine: https://www.linux-kvm.org/page/Main Page.
503 AMD-V: https://www.amd.com/de.html.
505 Intel VT: https://www.intel.com/content/www/us/en/products/details/network io.html.
Виртуальные машны | 269
$ grep ' svn\,vnx' /proc/cpulnfo О
flags: fpu vine de pse tsc nsr pae mce cx8 apic sep tntrr pge nca cmov pat pse36 ciflush dts acpi nnx fxsr sse sse2 ss ht tn pbe syscall nx pdpelgb rdtscp in constant_tsc art arch.perfnon pebs bts rep_gooa nopl xtopclogy tsc_reliabie nonstop_tsc rputc aperfnperf tsc_known_freq pnt pclmjlqdq dtes64 ds_cpl vnx tn2 ssse3 sdbg cxl6 xtpr pdon sse4_l sse4_2 x2apic novbe pcpcnt ® tsc. deadline timer aes xsave rdrand lahf_ln 3dnowprefetch cpuid_fault cat_l2 ibrs ibpb stibp tpr_shadow vnni flexpriority ept vpid ept_ad fsgsbase tsc_adjust snep erms npx rdt_a rdseed snap clflushopt intel.pt sha_ni xsaveopt xsavec xgetbvl xsaves dtherrn ida arat pin pts шб_с1еаг a rch_capabiliti es
$ Ismod I grep kvm ©
kvm_intel 253952 0 О
kvtn 659456 1 kvn_intel
О Ищем упоминания svm или vnx в отчете о центральном процессоре (он формируется для каждого ЦП, поэтому, если у вас восемь ядер, блок flags повторится восемь раз).
® В списке есть vnx, а значит, с аппаратной поддержкой виртуа пизации все в порядке.
Ф Проверяем доступность модулей ядра KVM.
© Видим, что загружен модуль ядра kvm .intel, а значит, для использования KVM все готово.
В современном мире вирт уальными машинами на базе ядра часто управляют с помощью Firecracker.
Firecracker
Firecracker506 — это написанный на языке Rust гипервизор, который использует KVM для управления виртуальными машинами. Ею разработали в Amazon Web Services преимущественно для бессерверных предложений вроде AWS Lambda и AWS Fargate.
506 Firecracker: Lightweight virtualization for serverie»s applications: lrtps://wwwarr.azon.sc:ence/ publications/firecracker lightweight-virtualization fbr-serverless applications
270 | (лава 9. Углубленные темы
VMM Firecracker предназначен для безопасного запуска многопользовательских рабочих нагрузок ла физической машине. Он управляет так называемыми виртуальными микромашингми (microVM), запуск, опрос и остановка которых производится через HTTP API. Firecracker эмулирует сетевые интерфейсы через устройства ТАР/TUN507 на хосте, а работу блочных устройств поддерживает через файлы хоста при поддержке устройств Virtio.
Кроме виртуализации, Firecracker обеспечивает безопасность, по умолчанию ограничивая вызовы к хосту через фильтры seccomp (см. «Профили secccmp»); egroups тоже поддерживаются. Наблюдаемость представлена именованными каналами, через которые производится журналирование и сбор метрик из Firecracker.
Далее рассмотрим современные дистрибутивы Linux, ориентированные на неизменяемость, и использующие контейнеры.
Современные дистрибутивы Linux
Классические дистрибутивы можно разбить на следующие семейства:
—	Семейство Red Hat (RHEL, Fedora и CentOS/Rocky).
—	Семейство Debian (Ubuntu, Mint, Kali, Parrot OS, elementary OS и т. д.).
—	Семейство SUSE (openSUSE и Enterprise).
—	Gentoo,
-	ArchLinux.
Все они прекрасны по-своему, и, в зависимости от ваших предпочтений, предоставляют вам либо контроль над каждым шагом от установки до применения исправлений, либо дистрибутив, который возьмет всю сложную работу на себя.
С развитием контейнеров (см. «Контейнеры») меняется и роль операционной системы хоста, и традиционное назначение менеджера пакетов (см. «Пакеты и менеджеры пакетов»). Большинство базовых образов строится на конкретном дистрибутиве с указанием зависимостей (.deb или .г pm пакетов), а зависимости приложений добавляются уже поверх в образ контейнера.
Вносить единичные изменения в такую конфигурацию тяжело, а с увеличением парка машин актуальность проблемы только нарастает. Поэтому в современных дистрибутивах все большее внимание уделяется неизменяемости.
507 TUN/TAP device driver: https:/7www.kernel.org/doc/Documentation/networking/hmtap.txt.
Современные дистрибутивы Linux | 271
Идея в том, чтобы любые изменения конфигурации или кода (исправления безопасности или внедренный функционал) приводили к созданию и запуску нового артефакта (нового контейнерного образа) вместо правки работающей системы.
К современным я отношу те дистрибутивы Linux, в которых ставка сделана на работу с контейнерами, неизменяемость и автоматическое обновление (пионерами в этой области можно считать Chrome). Вот несколько таких дистрибутивов.
Red Hat Enterprise Linux CoreOS
В 2013 году молодой стартап CoreOS выпустил дистрибутив CoreOS Linux (затем переименованный в Container Linux)508 Он привлекал внимание двухкорневой схемой разделов для системных обновлений и отсутствием менеджера пакетов. Все приложения запускались как контейнеры. Инструментами, разработанными в этой экосистеме, пользуются по сей день (например, eted; представьте распределенную версию каталога /etc для гибкой настройки).
Когда компанию приобрела Red Hat и объединила CoreOS Linux с собственным детищем Red Hat Atomic (похожей направленности), на свет появился проект Red Hat Enterprise Linux CoreOS (RHCOS)509. Он использоьался не само стоятельно, а в рамках дистрибутива Red Hat Kubernetes под названием «Контейнерная платформа Open Shifts.
Flatcar Container Linux
Вскоре после того как Red Hat обнародовал планы на Container Linux, немецкий стартап Kinvolk GmbH (теперь часть Microsoft) заявил, что продолжает разра ботку ответвления Container Linux иод новой маркой Flatcar Container Linux510.
В презентациях Flatcar описывал себя как легковесную контейнерную ОС с поддержкой оркестраторов (вроде Kubernetes) и 1о'17граничных вычислений. Flatcar продолжает традицию CoreOS по автоматизации обновлений (в том числе через необязательный собственный менеджер обновлений Nebraska511), а также
we Container Linux: nttps:,7en.Hikipedia.org/wiki/ContaiiTer_Linux
505 Red Hat Enterprise Linux CoreOS (RHCOS): https://dflcs.redhar.com/en/documentation/ openshift ,container„platform/4.1 /htrol/archftecture/architecture-rhcos.
51c Flatcar Container Linux: https://www.flatcar.org/.
511 Nebraska — an update manager tor Flatcar Container Lirux: https://www.fla1car.org/docs/ latest/nebraska.
272 | Глава 9. Углубяекнье темы
позволяет гибко контролировать загрузочные устройства через комплексную, но удобную утилиту Ignition512 (используется и в RHCOS). Менеджера пакетов по-прежнему нет, все работает в контейнерах.
Жизненный цикл контейнеров-приложений управляется через systenctl на локальной машине или (чаще) из Kubernetes.
Bottle rocket
Bottlerocket513 — это ОС на базе Linux, написанная на Rust и разработанная AWS для контейнерных хостингов514. Используется в таких продуктах, как Amazon EKS и Amazon ECS.
Подобно Flatcar и CoreOS, вместо менеджера пакетов BottLerocket использует модель OCI-совместимых образов для обновления или отката приложений. Файловая система доступна только для чтения; целостность сверяется через dm-verity515. Для доступа (через SSH, хоть это и не рекомендуется) Bonlerockct запускает специальный управляющий контейнер516 в отдельном экземпляре containerd.
RancherOS
Буквально все в RancherOS517 — это Docker-контейнеры. Дистрибутив спонсируется Rancher (ныне SUSE) и оптимизирован для рабочих нагрузок контейнеров, как и их предложение для Kubernetes. RancherOS запускает два экземпляра Docker: системный, который работает как первый процесс, и пользовательский, чтобы создавать контейнеры приложений. Благодаря легковесности он очень перспективен для применения в области 1оТ-систем и в условиях ограниченных вычислительных мощностей.
512 Ignition (provisioning utility): https://www.flatcar.org/docs/latest/provisioiiiiig/ignitioii/.
513 Bcttlerocket OS: https://github.com/bottJerocket-os/bottlerocket.
514 Botdcrocket — Open Source OS tor Container Hosting: https://aws.amazo." .com/ru/blogs/aws/ bottlerocket-open-source-os-for-container-hosting/.
515 DMVerity: https://gitiab.eom/cryptsetup/cryptsetup/-/wikis/DMVerity.
516 Bottlerocket Control Container: https://github com/bottlerockeios/bottlerocket-concrol-ccntainer.
517 RancherOS: https://github.com/rancher/os.
Современные дистрибутивы Linux | 273
Избранное в области безопасности
В главе 4 мы обсуждали механики контроля доступа: аутентификацию (сократим до authn), или сверку личности пользователя, необходимую перед любой авторизацией (сократим до authz). Давайте кратко обсудим два популярных и достойных упоминания инструмента authn.
Kerberos
Ныне описанный в RFC 4120518 519 и связанных документах IFTF, набор средств ау тентификации Kerberos5'9 был разработан Массачусетским технологическим институтом з 1980-х годах в попытке предоставить клиентам и службам безопасный способ сверять идентичность в небезопасных сетях.
Схематика проверки идентичности в Kerberos показана на рисунке 9-2.
Рисунок 9 2. Протокол Kerberos в теории
1.	Клиент (программа на вашем ноутбуке) запрашивает учетные данные для конкретной службы, например службы печати или каталогов, у компонента Kerberos с названием Центр распространения ключей (KDC).
2.	КОС возвращает учетные данные — тикет к службе и временный ключ шифрования (ключ сеанса).
3.	Клиент передает службе тикет (с данными идентификации и копией ключа сеанса).
4,	Одинаковый ключ сеанса у клиента и службы используется для подтверждения подлинности клиента, но может удостоверять и саму службу.
Несмотря на известные недостатки — центральную роль KDC (единая точка отказа), строгие требования к синхронизации часов между клиентом и сервером (через NTP), сложность эксплуатации и администрирования — Kerberos популярен и поддерживается множеством предприятий и облачных провайдеров.
518 The Kerberos Network Authentication Service: https;//data:racker.ietf.org/'doc/htnil/rfc4120.
519 Kerberos: https://kerberos.org/.
274 | Глава 9. Утлубленные темь.
Подключаемые модули аутентификации (РАМ)
Изначально каждая программа реализовывала проверку подлинности самостоятельно. С появлением подключаемых модулей аутентификации (РАМ)320 в Linux появился универсальный способ писать программы, не завязанные на конкретную схему проверки (РАМ существовали в обширной экосистеме UNIX еще в 1990 х). Благодаря модульности РАМ предоставляют разработчикам мощную библиотеку и интерфейсы к кей. Администраторы могут подключить следую щие модули:
рап_ loca laser32'
Пользователь должен быть указан в /etc/passwd.
pan_keyini t522
Для сессионных связок ключей.
pan_krbS^2i
Для проверок на основе пароля Kerberos 5.
Мы завершаем сложную тему безопасности и переходим к более амбициозной.
Другие современные и перспективные возможности
Далее мы рассмотрим интересные возможности и инновационные способы использования Linux, а также работу с ней в необычных средах. Linux — де-факго стандарт для серверов (в локальных дата-центрах и в облаке), она «под капотом» многих мобильных устройств.
Темы этого раздела объединяет, пожалуй, одно: в момент написания книги они еще не вошли в моду. Однако, если вам интересно, как может выглядеть будущее разработки и в какой области потенциал развития Linux остается высоким, читайте дальше. * 521 522 523
ио Linux РАМ. http://linuxpam.org/.
521 pam.locaiuser(8): https://www.man7.Org/linux/man-pages/man8/pam_local4ser.8.html.
522 pam keyinit(8): https;//www.mar.7.org/linux/ntan-pages/man8/pa-n keyinit.8.html.
523 pam_krt>5(8): https://linux.die.net/man/8/pamJat>5.
Другие современные и перспективн ь е возможности | 275
NixOS
NixOS524 — это дистрибутив Linux с открытым исходным кодом, в котором использован функциональный подход к управлению пакетами и конфигурирова нию системы, а также к откатам для обновлений. Я назвал этот подход «функциональным» (ино1да называют «декларативным»), поскольку все артефакты основаны на неизменяемости.
Менеджер пакетов Nix собирает всю систему полностью — от ядра до системных пакетов и приложений. Он предлагает многопользовательское управление пакетами и даже допускает установку и использование разных версий одного пакета.
В отличие от большинства других дистрибутивов, NixOS не следует стандартной файловой структуре Linux, упомянутой в разделе «Основные модели организации файловых систем» (системные программы в /usr/Ып, /usr/lib, конфигурация в /etc и т. д.).
В N ixOS и его экосис геме множес гво интересных идей, особенно актуа льных для О-конвейеров. Но даже если вы не готовы пуститься во все тяжкие, менеджер пакетов Nix можно использовать и автономно (за пределами NixOS).
Linux на настольных компьютерах
Несмотря на постоянные споры о жизнеспособности Linux на настольных компьютерах-25, выбор удобных для домашнего использования дистрибутивов велик, как и выбор оконных менеджеров526.
По доброй традиции UNIX графический интерфейс (GUI) отделен от осталь ной части ОС. Обычно заботу о возможностях GUI (от управления окнами до стилизации и отрисовки) при поддержке экранного менеджера527 берет на себя оконный менеджер X528
Поверх менеджера окон, реализующего базовые возможности (значки, виджеты и панели инструментов), располагаются среды рабочего стола529, напри мер, KDE или МАТЕ.
524 NixOS: https://nixos.org/.
525 Criticism of desktop L.nux: https://en.wikipedia.org/wiki/Criticism_of_ desktop .Linux.
526 Comparison of X window manages; https//en.wikiped;a.crg/wiki/Comparison_ci_X. window_ir.anagers.
527 Display manager: https://wiki.archlinjx.org/title/Display_manager.
528 X window managers: https://cn.wikipcdia.org,'’wiki/Comparison of_X_window_managers.
529 Desktop environment: https://wiki.archliniix.org/tide/Desktop._env-.rojment.
276 | Глава 9. Углублет кые темы
Выбор дистрибутивов Linux, дружественных к новичку, достаточно велик, чтобы без труда перейти па них с Windows или macOS. Доступен целый ряд приложений с открытым исходным кодом, от офисных программ (для написания текстов и работы с таблицами, например, LibreOflice) до графических редакто ров (Gimp), основных браузеров, игр, медиа плееров, утилит и сред разработки.
Популярности настольного Linux могут способствовать неожиданные события — например, то, что Windows 11 из коробки позволяет запускать графические приложения Linux530, может навсегда изменить восприятие и перспективы. Время покажет.
Linux во встраиваемых системах
Linux ьо встраиваемых системах531 — обширное поле применения, которое включает автомобили, сетевое оборудование (к примеру, маршрутизаторы), устройства «умного дома» (холодильники), медиаустройства и умные телевизоры.
Вы можете приобрести (и недорого) одну из самых интересных универсальных платформ — Raspberry Pi (RPI)5’2, которая поставляется с собственным ди стрибутивом Linux под названием RaspberryPi OS (на базе Debian). Этот и другие дистрибутивы Linux можно установить на RP1 с обычной карты microSD, а несколько входов/выходсв общего назначения (GP1O) позволяют легко подключать датчики и схемы на макетной плате. Можно экспериментировать, изучать электронику или программировать оборудоэание, например, на языке Python.
Linux в облачной IDE
В последние годы облачные среды разработки развились до такой степени, что появились (коммерческие) предложения, которые объединяют IDE (обычно это среда разработки Visual Studio Code), Git и целый ряд языков программирования в среде Linux. Как разработчику вам нужен лишь браузер и доступ к сети, и вы сможете писать, тестировать и запускать код прямо «в облаке».
В момент написания книги среди облачных IDE ярче всего выделяются Gitpod533, доступный как готовый продукт и как открытый код, который можно запустить у себя, и Codespaces534, глубоко интегрированный в GitHub.
530 Windows I i runs Graphical Linux Apps out of the box with WSLg: https://www.youtube.com/ watch ? v=b 1 YBx L L8op4.
531 Linux on embedded systems: https://en.v.ikpedia.org,'wiki,'Linuxon embedded systems.
532 Raspberry Pi: https://www.raspberrypi.org/.
533 Gitpod: https://www.gitped.io/.
534 Codespaces: https://gitbub.com/features/codespaces.
Другие стременные и перспективные возмож юстм | 277
Заключение
В этой главе рассматривались углубленные темы, дополняющие знания о базовых техниках и инструментах. Если вам нужно задействовать IPC, к вашим услугам сигналы и именованные каналы Если хотите изолировать рабочие нагрузки, вам помогут виртуальные машины, особенно такие инновационные решения, как Firecracker. Мы рассмотрели современные дистрибутивы: если собираетесь рабо тать с контейнерами (Docker), обратите внимание на упомянутые сборки, ориентированные на контейнеры и неизменяемость. Мы коснулись избранных тем безопасности, включал Kerberos и РАМ для гибкой и/или масштабируемой аутентификации, и, наконец, рассмотрели использование Linux в нишах, пока не получивших широкого распространения, — на настольных компьютерах и во встраиваемых системах (Raspberry Pi), для локальных экспериментов и разработки.
Несколько дополнительных материалов по теме этой главы:
IPC
— «Введение в Linux IPC»535.
— «Межпроцессное взаимодействие в Linux: каналы и очереди сообщений»536.
— «Реализация каналов и FIFO в ядре Linux»537.
— «Шпаргалка по Socat»538.
VM
— «Что такое виртуальная машина?» (VMware)539.
— «Что такое виртуальная машина (VM)?» (RedHat/IBM)540,
— «Как создавать и управлять виртуальными машинами KVM из командной строки»541.
535 «Ап Introduction to Linux IPC»: https://wrww.man7.org/conf/lca2013/IPC_Overview-LCA-2013-printable.pdL
S3e «Inter-process communication in Linux: LTsing pipes and message queues»: https: '/op ensource com/article/19/4/interprocess-communication-linux-channels.
537 «The Linux Kernel Implementation of Pipes and FIFOs»: bttps://www. slideshare net/slideshow/ linux-kernel-impkmentation-of-pipes-and-fifos/8728264.
538 Socat Cheatsheet: https://web.archive.Org/web/2C230309l51224/https://blog.travismdarke. com/post/socat tutorial/.
f” «What is a virtual machine?» (VMware): https://v\ww.vmwarc.com/‘opics/virtual-machine
540 «What Is a Virtual Machine (VM)?» (Red I lat/IBM): https://www.redhat.com/en/tcpics/virtua-lization/what-is-a-virtual-machine.
541 «How to Create and Manage KVM Virtual Machines from CLI»: https://linjxconfig.org/how-to-create-and-manage-kvm-virtual-machines-from-cli.
278 | Глава 9. Углубленные темы
— «KVM» в Debian Wiki542.
— Веб-сайт эмулятора и виртуализатоэа машин QEMU543.
— Веб-сайт Firecracker544.
Современные дистрибутивы
— «Контейнеры и кластеризация»545.
— «Неизменяемость и слабая связанность: сам бог велел»546 *.
— «Учебник. Установка Flatcar Container Linux на удаленные серверы на голом железе»347.
— Дополняемый список дистрибутивов Linux на основе образов и дополнительных инструментов548.
— «Функции безопасности в Bottlerocket, операционной системе с открытым кодом на базе Linux»54’.
— «RancherOS: простейший Linux для любителей Docker»550.
Избранное по безопасности
— «Kerberos; протокол сетевой аутентификации»551.
— «Учебник РАМ»552.
542 «KVM» via Debian Wiki: https://wikidebian.org/KVM.
543 QEMU machine emulator and virtualizer website: https://www.qemu.org/'.
44 Firecracker website; https--'/firecracker microvm.gitbub.io/.
545 «Containers and Clustering»: https://wwwheavybit.com/library/video/ceo-of-coreos-on-containers-and-clustering/.
M « immutability & loose coupling: a match made in heaven»: https://www.camptocamp.com/en/ new s-events/immutability-and-1 oose-coupling-a-matcb- made- in-heaven.
547 «Install Flatcar Container Linux on Remote Baie Metal Servers»: https://thenewsiack.io/ tutoi ial- install-flatcar-container-linux-on-remote-bare- metal -servers/.
544 List of image- based Linux distributions and associated tooling: https://github,ccm/Malix-Labs/
Awesome - Atomic.
549 «Security features of Bottlerocket, ar. open source Linux-based operating system»: https://aws.
amazon.com/ru/blogs/opensource/security -features-cf-botllerocket-an-open- source-llnux •
based operating system/.
550 «RancherOS: A simpler Linux for Docker lovers»: https://www.infoworld com/article/2255121/
rancheros-a-simpler-linux-for-docker-lovers.html.
551 «Kerberos; The Network Authentication Protocol»: hctps;//web.mit.edi?/kerberos/
552 «РАМ Tutorial»: https://wpoEock.com/AUnix2/PAM-Help.litm.
Заключение | 279
Другие предложения — современные и перспективные
— «Как работаю! менеджеры окон X. и как написать свой»553.
— «Чисто функциональный Linux с NixOS»554.
— «NixOS: чисто функциональное управление конфигурацией»555 556.
— «Что такое Raspberry Pi?»554.
— «Kubernetes на Raspberry Pi 4b с 64-биткой ОС с нуля»557.
Вог и закончилась книга. Надеюсь, что дальше начнется ваше собственное путешествие в мир Linux. Спасибо, что оставались со мной. Я всегда открыт для отзывов через Twitter или через старую добрую электронную почту: modern linux@pm.me.
553 «How X Window Managers Work, Anc How To Write Ore»: https://jichu4n.com/posts/how-x-wirdow-managers-work-and-how-to-write-one-part-i/.
554 «Purely Functional Linux with NixOS»: https://begr)ffs.com/posts/2016-08-08-intro-to-nixcs. himl.
555 «NixOS: purely functional system confguratior management»; https://lwn.net/Articles/337677/.
556 «What is a Raspberry Pi?»: https://opensource.com/resources/raspberry pi.
557 «Kubernetes on Raspberry Pi 4b with 64- bit OS from scratch»: https ://mliausen blas.info/kube-rpi/.
ПРИЛОЖЕНИЕ А
Полезные примеры
В этом дополнении я привел список рецептов, скопившихся у меня при решении повседневных задач, и шпаргалку для которых хотелось бы иметь под рукой. Они ни в коем случае не претендуют на полный или даже глубокий обзор возможностей по работе и администрированию Linux. Со всеобъемлющим и подробно прокомментированным набором рецептов вы можете ознакомиться в книге Карлы Шоедер, «Linux. Книга рецептов»556, которую я настоятельно рекомендую.
Сбор системной информации
Для получения версии Linux, ядра и прочей информации о дистрибутиве используйте любую из следующих команд:
cat /etc/‘-release cat /proc/verston
unane a
Разузнать об основном аппаратном обеспечении (процессор, память, диски и т. п.) можно командами:
cat /proc/cpuinfo cat /ргос/meninfo cat /ргос/diskstats
Чтобы выяснить больше об оборудовании в вашей системе, например о BIOS, наберите:
sudo drnidecode -t bios
556 Керла Шредер, «Linux: Книга рецептов. 2е издание». Питер 2023: https://www.piter.com/ collection/linux/product/Enux kniga retsepto-- 2 e-izd.
Сбор системной информации | 281
Примечание к предыдущей команде: другие интересные аргументы для параметра -t: system и memory.
Чтобы узнать общую статистику использования основной памяти и подкачки, выполните команду:
free -ht
Выяснить, столько файловых дескрипторов доступно процессу, можно ко мандой:
ulimtt -п
Работа с пользователями и процессами
Вывести список вошедших в систему пользователей можно командой who или w (более подробный вывод)
Чтобы отобразить системные метрики (процессора, памяти и т. д.) для отдельного процесса и конкретного пользователя (SOMEUSER), используйте команду:
top -U SOMEUSER
Вывести список процессов в виде дерева и с подробностями (для всех пользователей) можно следующим образом:
ps faux
Найти определенный процесс (язык python):
ps -е | grep python
Завершить процесс по его PID, если он вам известен (добавьте -9 в качестве параметра, если процесс игнорирует сигнал):
кШ PID
Процессы можно завершать и по имени с помощью команды kttlall.
282 | Приложение А. Полез! 1ые примеры
Сбор информации о файлах
Так можно запросить данные о файле (включая специфичные для файловой системы, например, иноды):
stat some file
Чтобы разузнать о команде, о том, как ее интерпретирует оболочка и где находится исполняемый файл, наберите:
type somecomand
which somebinary
Работа с файлами и каталогами
Вывести на экран содержимое текстового файла с именем afile:
cat afile
Командой is можно вывести список содержимого в каталоге, а затем использовать полученную информацию в конвейере. К примеру, следующей инструкцией можно подсчитать количество файлов в каталоге:
is -I /etc | wc -I
Найти определенные файлы или их содержимое.
find /etc -папе "*.conf" О
find, -type f -exec grep -H FINOME {} \; ©
О Ищем файлы, имена которых заканчиваются на.сол/в каталоге /etc.
© Ищем ’ F1NDME" в файлах текущего каталога, используя grep.
Чтобы получить сводку различий в двух файлах, наберите:
diff u somefile cnotherfile
Сбор информаци co файлах | 283
Чтобы заменить символы, используйте tr следующим образом:
echo 'Cor_Acme_Library |tr '_A-Z' '.a-z'
Другой способ заменить часть строки — через sed (обратите внимание, можно использовать и разделитель, отличный от /. Это удобно, когда вы заменяете содержимое по файловому пути или по URL):
Cat 'foo bar bez' | sed -e 's/foe/qjux/'
Чтобы создать файл определенного размера (для теста), используйте команду dd следующим образом:
dd if=/dev/zero of-output.dat bs-1024 cojnt-1000 О
О Создает файл с именем output.dot, размером 1Мб (JООО блоков по 1кб), и за полненный нулями.
Работа с перенаправлением и конвейерами
В разделе «Потоки ввода/вывода» мы обсуждали файловые дескрипторы и потоки. Ниже несколько примеров, связанных с темой.
Перенаправление взода/вывода в файлы;
command 1> file О command 2> file ® command &> file ® command >file 2> &1 О commend > /dev/null © commend < file Ф
О Перенаправить stdout команды command в файл fi le.
® Перенаправить stderr команды command в файл fi le.
Ф Перенаправить и stdout, и sterr команды command в файл fi le.
© Другой способ перенаправить stdout и stderr команды commands файл file.
© Заглушить вывод команды command (перенаправив его в /dev/null).
Ф Перенаправить stdin (входные данные из файла fi le в команду command)
284 | Приложение А Полезные примеры
Чтобы связать выход одного процесса (stdout) со входом другого (stdin), используйте конвейер (|).
cndl | cnd2 | cmd3
Чтобы показать код выхода каждой команды в конвейере
echo $[PIPESTATU5[@]}
Работа с датой и временем
Чтобы запросить данные о времени (локальном или (JTC) и узнать статус синхронизации, выполните команду;
tiredatectl status
При работе с датами часто требуется либо получить текущую дату / временную метку, либо преобразовать временную метку из одного формата в другой.
Чтобы получить дату в формате YYYY-MM-DD (для примера: 2021-16 09), выполните команду:
date +‘’%Y-%i-%d"
Чтобы создать временную метку эпохи Unix (для примера: 1633787676):
date +%s
Чтобы создать метку в формате ISO 8601 для времени UTC (для примера: 2021-10-09T13:5®:47Z):
date -и +"%Y-%n-%cT%H:%r1:%SZ"
Все тот же формат ISO 8601, только для локального (ремеяи:
date +*FT%TZ
Работа с датой и временем | 285
Работа c Git
Чтобы клонировать репозиторий Git (скопировать к себе на локальную машину с Linux), используйте команду:
git clone https://github.com/exanpleorg/exanplerepo.git
После того как gitclcne закончит работу, копия Git-репозитория будет поме щена в ката лег ехапр lerepc, и дальнейшие команды следует выполнять уже из него
Чтобы просмотреть локальные изменения (в цвете и с совмещением удаленных или добавленных строк):
git diff -color-moved
Чтобы увидеть, какие файлы изменились локально (были отредактированы, добавлены, удалены):
git status
Ч гобы добавить все локальные изменения и закоммитить их:
git add --all S8 git connit -n "edds a super cool feature"
Чтобы выяснить TD текущего коммига:
git rev-parse HEAD
Чтобы пометить коммит c ID HASH тегом ATAG:
git tag ATAC HASH
Чтобы, отправить локальные изменения в удаленный (вышестоящий (upstream;) репозиторий с тегом ATAG:
git push origin ATAG
Чтобы просмотреть историю коммитов, используйте команду7 gitlog, а чтобы получить сводку, выполните:
git log (git describe --tags --abbrev-S)..HEAD --oneline
286 | fl рилежеиие А. Полезные приме ры
Производительность системы
Иногда нужно замерить скорость работы устройства, или понять, как ваша Linux справляется с нагрузками. Вот несколько способов нагрузить систему.
Имитировать загрузку памяти (а заодно слегка «разогреть» процессор) можно следующей командой;
yes | tr \\п х | head -с 450rr | grep z
В показанном выше конвейере yes генерирует бесконечный набор символов у (каждый на новой строке) Команда tr превращает его в непрерывный поток ух, который команда head обрезает по 450 миллионов байт (примерно 450 Мб). И, наконец, мы используем grep для поиска в нарезанном блоке ух несуществующего там символа (z); хотя никакого результата нет, выполнение создает нагрузку.
Подробная информация о дисковом пространстве, которое занимает каталог:
du -h /hone
Вывод информации о свободном месте на диске (в данном случае, глобально)
df - h
Провести нагрузочный тест диска и замерить пропускную способность I/O можно так:
dd if=/dev/zero of=/hone/some/file ds=1C count=l oflag-dtrect
ПРИЛОЖЕНИЕ Б
Инструментарий современной Linux
В этом приложении представлен список современных инструментов и команд Linux. Одни утилиты заменяют классические, другие новые, но все они повьппа ют удобство работы (UX) за счет простоты использования или цветного оформления результатов, чтобы улучшить восприятие.
В таблице Б-1 я привел соответствия инструментов с объяснением функционала и потенциальных возможностей для замены.
Таблица Б-1. Современные инструменты и команды Linux
Команда	Лицензия	Функционал	Может заменить или дополнить
bat	Лицензии MIT и Apache 2.C	Отображение с поддержкой страниц и подсветкой синтаксиса	cat
envsubst	Лицензия MIT	Шаблоны для переменных окружения	—
еха	Лицензия MIT	Понятный выводе цветной подсветке й, г родуманные настройки по умог -чанию	Is
dog	Открытая лицензия Евросоюза (tUPL 1.2)	Простой поиск DNS	dtg
fx	Лицензия MIT	Инструмент для работы с J5ON	jq
fzf	Лицензия MIT	Инструмент командной строки для нечеткого поиска	Is + find-i-grep
gptng	Лицензия MIT	Многоцелевой, графический	ping
httpte	Лицензия BSD стремя условиями («Новая» или «Пересмоленная»)	Удобный для человека ингерфейс	curl (также обратите внимание на curlie)
jo	GPL	Генерация jSON	—
288 | П риложение Б. Инс г руменгарий современ ной Linux
Лицензия MIT
Независимый обработчик JSON Быстрый, разумные настройки по умолчанию
sed, awk
Лицензия MIT
find, grep
sysz	Unlicerse	Пользовательский интерфейс fzf) для systemctl	systemctl
tldr	Лицензии CC-BY (содержи-	Упрощенный пап, сосредоточенный	пап
	мое) и МП (скрипты)	на при мерах испо; ьзования команд	
zoxide	Лицензия Ml Г	Быстрая смена каталогов	cd
Чтобы больше узнать об истории создания и применении некоторых из пере численных инструментов, воспользуйтесь следующими ссылками:
— Послушайте эпизод о современных инструментах UNIX559 подкаста «The Changelog: Software Development, Open Source».
— Ознакомьтесь c GitHub репозиторием «Современный UNIX»560 и обнов ляемым списком новых инструментов
559 podcast episode «modern UNIX tools» from The Changelog Software Development, Open Source; https://open.spotify.com/episode/6Ba5gsLTfQROyqsuRyorpl?
560 Modern Unix repo: https://github.com/ibraheemdev/modern-unix.
Об авторе
Майкл Хаузенблас — ведущий разработчик программных решений в команде сервисов наблюдаемости Amazon Web Services (AWS), с большим опытом обработки данных и контейнерной оркес грации от Mesos до Kubernetes. Майкл — ярый сторонник и защитник стандартизации W3C и IETF, и сегодня программирует в основном на Go. До .Amazon он работал в Red Hat, Mesosphere (теперь D2iQ) и MapR (ныне входит в НРЕ) и около десяти лет посвятил прикладным исследованиям.
Животное на обложке
Величественное животное на обложке книги «Как освоить современный Linux» — это императорский пингвин (aptenodyiesforsteri), крупнейший и едва ли не самый заметный вид пингвинов Большие нелетающие птицы уникально приспособились к суровой среде Антарктиды. Обтекаемые тела позволяют им прекрасно плавать, а прочные кости — выдерживать давление на глубине пятисот метров, куда они ныряют за рыбой, кальмарами и крилем. Под водой они проводят до двадцати минут, не выныривая подышать.
Императорские пингвины очень компанейские, они гнездятся и добывают пищу сообща. Сбиваясь в колонии, они жму гея друг к другу, согреваясь в морозы до -45 °C. Возвращаясь после длительного пребывания в море, они криком подзывают партнера, отыскивая его среди тысяч сородичей, даже несмотря на го, что не привязаны к постоянному месту гнездовья. Одно яйцо, отложенное самкой в зимний сезон, высиживает и защищает самец, зажав его между ног, и накрыв лоскутом кожи, который называется выводковой сумкой. К концу двух месяцев высиживания бдительный самец, который ничего пе ел все это время, очень сильно худеет.
Сегодня императорские пингвины находятся на грани исчезновения. Научные модели предсказывают резкое сокращение их популяции из-за т аяния морских льдов и климатических изменений. Как и остальные животные, представленные на обложках O’Reilly, независимо от того, грозит им исчезновение или пет, императорские пингвины жизненно важны нашему миру.
Иллюстрация для обложки, выполненная Карен Монтгомери, создавалась по мотивам старинной гравюры из Энциклопедического словаря Мейера.
Алфавитный указатель
3mux, 84
А
ACL (AccessControlLists), 116
Alacritty, 84
Applmage, 180
ARP (Address Resolution Protocol), 134.
190
AUFS, 142
В
bash
описание, 53
переменные, 59
переносимые скрипты, 88
псевдонимы, 65
bat, 62
bats (автоматизированная система тестирования для bash), 91
BGP (протокол граничного шлюза), 199
BIOS (базовая система ввода/вывода), 28
BitTorrent, 230
Bottlerocket, 273
btrfs (файловая система b-tree), 142 buildah, 178
Byobu, 84
С
CoreOS, 272
D
DAC (дискреционное управление доступом), 99 debugfs, 140
devfs (файловая система/dev), 136
DHCP (протокол динамической конфигурации хосга), 227
DNF, 158
DNS (иерархия доменных имен), 207 записи, 209 запросы, 212
Docker
контейнеризация, 165
контейнеризация greeter, 176
основные понятия, 174
Dockcrfilc, 175
dvtni, 84
Е
eBPF, 45
escape-последовательности, 52
еха, 94 ext3, 125 ext 4, 138
F
FAT, 139
FHS (стандарт иерархии файловой системы), 131
Firecracker, 270
292 | Алфавитный указатель
Flatcar Container Linux, 272
Flatpak, 180
FTP (протокол передачи файлов), 225
G
geoiplookup, 230
Git, работа c, 286
Grafana и Prometheus, 257
H
Homebrew, 180
HTML (язык гипертекстовой разметки), 216
HTTP (протокол передачи гипертекс-
та), 216
I
ICMP (Протокол управляющих сообщений), 197
ID процесса (РШ), 21
IPv4, протокол, 192
IPv6, протокол, 196
1Р-адрес, 190
J
journalctl, мониторинг с помощью, 153
jq, 64
JSON, 64
К
Kerberos, 274
L
Linux
архитектура, 25
видимость ресурсов, 19
дистрибутивы, 19,277
история, 16
общий обзор, 14
современные инструменты и команды, 288
ядро, 19
loopfs, 140
М
MTL1 (максимальный размер пакета.), 189 murex, 77
N
NFS (сетевая файловая система), 225 NIC (контроллер сетевого интерфейса), 188
NixOS, 2/6
NTP (протокол сетевого времени), 228
Nushell, 77
О
ОСТ (спецификация Open Container Initiative), 166
Oil shell, 76
OverlayFS, 142
P
РАМ (подключаемые модули аутентификации), 275
PID (идентификатор процесса), 21 pipefs, 140 podman, 178
POSIX (переносимый интерфейс операционных систем), 23
PowerShell, 77 procfs, 125,13.3
R
RancherOS, 273
Raspberry Pi (RPI), 277
Red Hat Enterprise Linux CoreOS (RHCOS), 272
Алфавитный указателе | 293
rg, 62 RHCOS (Red Hat Enterprise Linux CoreOS), 272 root, 101 RP1 (Raspberry Pi), 277 rsync, 223 rsyslog, 243	tshark, 229 U UDP (протокол пользовательских дата-грамм), 203 UEFI (унифицированный расширяемый интерфейс микропрограмм), 28 UID файловой системы, 112
S scp, 223 screen (мультиплексор терминала), 79 scccomp, 115 SELinux, модели управления доступом, 100 setuid, ПО ShellCheck. 91 Snap, 180 socat, 230 sockfs, 140 sudo, 117 swapfs, 140 sysfs, 135 syslog, 241 syslog-ng, 242 systemctl, 152 systemd journalcti, 153 systemctl, 152 модули, 150 планирование запуска greeter, 153	Unionfs, 142 URL (универсальный указатель ресурса), 216 W W3C (консорциум World Wide Web), 216 web, 215 whois, 226 Windows, совместное использова- ние, 226 wireshark, 229 X XFS, 139 Y yum, 158 Z Zellij, 84 ZFS, 139 Z-shell, 75 Zypper, 159
т
TCP (протокол управления передачей), 202 TLB (буфер ассоциативной трансляции, ассоциативный кэш), 35 tmpfs, 125,140 tmuxinator, 83 tmux (мультиплексор терминала), 79	А автономная система, 200 амперсанд (8с), 55 архитектура ЦП ARM, ЗС
294 | Алфавитный указатель
R1SC-V, 30 x86, 29 аудит, 117 аутентификация
Kerberos, 274 РАМ, 275
время эпохи UNIX, 69
встраиваемые системы, Linux во, 277
Г
гистограммы, 237
графические процессоры (GPU), 37
Б
безопасная оболочка Secure Shell
(SSH), 10
безопасная ободочка SSH (Secure
Stell), 10
безопасность
информация в логах, 239
полезные советы, 90
Kerberos, 274
РАМ, 275
SSH, 222
бесклассовая междоменная маршрутиза-
ция (C1DR), 194
буфер ассоциативной трансляции
(TLB), 35
Д
датаграммы, 203
датчики, 237
демон, определение, 147
диск, определение, 120
дискреционное управление доступом
(DAC), 99
диспетчер логических томов (LVM), 127
дистрибутивы
основные, 19
современные, 271
домашний каталог пользователя, 102
домены верхнего уровня (TLD), 209
драйверы устройств, 37
Ж
В
вертикальная черта (|), 56
взаимодействие с сетью
основы, 183
СтекТСР|1Р, 185
DHCP, 227
NTP, 228
whois, 226
wireshark и tshark, 229
видимость ресурсов, 19
виртуальная машина
Firecracker, 270
KVM, 269
виртуальная машина на базе ядра
(KVM), 269
виртуальная файловая система (VFS), 37
жесткие ссылки, 123
журналирование
journalctl, 243
Syslog, 241
3
загрузка, определение, 147
запуск в стиле SystemV, 149
И
идентификатор пользователя (UID), 98
идентификатор процесса (PTD), 21
г ерархия файловой системы, 131 избирательная модель управления доступом, 99
изоляция, 22
Алфавитный указатель | 295
именованные каналы, 266 иноды, определение, 121 интегрированный монитор производи- тельности, 25С интернет вещей (1оТ), 15 информация о системе, сбор, 281 информация о файле, сбор, 283 использование навигации, 65	менеджер пакетов deb, Debian deb, 161 менеджер пакетов RPM, 158 менеджеры пакетов для языков программирования, 164 современные, 180 Debian deb, 161 RPM, 158 метрики, определение, 237 многопоточность, 31
К	мобильные устройства, 15
каналы именованные, 266 философия Unix, 56 каталоги, работа с, 283 команда date, 68 контейнеры альтернативы для Docker, 178 контрольные группы (cgroups), 169 проостранства имен, г 66 файловые системы CoW, 173 Docker, 173 контроллер сетевою интерфейса (NIC), 188 контрольные группы Linux, 169 контроль потока, 87	модель взаимодействия открытых сетей (OS1), 186 модуль, 44 модуль, для systemd, 150 мониторинг инструменты, 253 интегрированный монитор произво- дительности, 250 устройства ввода/вывода и сетевые интерфейсы, 247 мультиплексор терминала выбор, 85 screen, 79 tmux, 79 мультиплексор терминала (tmux), 79
Л логи, определение, 238	Н наблюдаемость журналирование, 238
М максимальный размер пакета (MTU), 189 мандатная модель управления доступом, 99 маршрутизация. 198 межпроцессное взаимодействие именованные каналы, 2б6 сигналы, 264 сокеты домена UNIX, 267	метрики Grafana и Prometheus, 257 мониторинг, 245 определения, 235 основы, 234 профилирование, 254 сеть, 247 сигналы, 236 трассировка, 237 устройства ввода/вывода и сетевые интерфейсы, 247
2% | Алфавитный указатель
цикл OODA, 234
наименьшие привилегии, 89
настольные компьютеры, Linux на, 276
неизменяемость, 166,271
непрерывное профилирование, 257
О
облачные вычисления, 15
облачные IDE, 277
оболочки
встроенные команды, 59
выбор оболочки, 77
навигация, 65
написание скриптов, 85
переменные, 56
потеки ввода/вывэда, 53
просмотр длинных файлов, 67
работа с датой и временем, 58
работа с содержимым файлов, 66
современные команды, 61
сокращение команд, 65
статус выхода, 59
удобные для работы, 69
управление заданиями, 60
Fish Shell, 70
Z-shell, 75
обратный слеш (, 55
объединенное монтирование, 141
операционная система, зачем нужна, 17
П
пакет, определение, 147
пароли, 103
передача файлов, 222
переменные, в ободочке, 56,57
переменные в скриптах, 86
переменные окружения, 57
перенаправление, 54
переносимые baeh-скрипты
запуск, 89
полезные соьеты, 90
универсальный шаблон, 89
песочница, 99
подключаемые модули аутентификации
(РАМ), 275
пользователи
локальное управление, 102
типы учетных записей, 100
централизованное управление, 105
пользовательское пространство, 26
порты, 200
порядок монтирования, 141
потоки ввода/вывода, 53
префикс/тригтер, 80
привилегии, 114
привязки монтирования, 173
приложение, определение, 147
приложения
определение, 145
терминология, 146
управление, 155
цепочки поставок, 155
программа, определение, 146
производительность системы, тестиро вание, 287
пространства имен, 166
протокол граничного шлюза (BGP), 199 протокол динамической конфигурации
хоста (DHCP), 227
протокол облеченного доступа к катало-
гам (LDAP), 105
протокол определения адреса (ARP), 190
протокол передачи гипертекста
(HTTP), 216
протокол передачи файлов (FTP), 225
протокол пользовательских датаграмм
(UDP), 203
протокол сетевого времени (NTP), 228
Алфавитный указатель | 297
протокол управления передачей (TCP), 202 протокол управляющих сообщений (ICMP), 197 профилирование, 256 процесс определение, 147 список, 282 процесс загрузки в Linux, 148 псевдонимы, 65 псевдофайловые системы, 132	NFS, 225 SSH, 221 web, 215 сетевые интерфейсы, 247 сигна/ты определение, 236 основные, 264 перехват, 265 символические ссылки (synilinks), 123 системные вызовы (syscalls), 17 системы инициализации и процесс загрузки, 148
Р работа с датой и временем, 285 работа с содержимым файла, 66 раздел, определение, 121 разрешения привилегии, 114 п рофили seccom р, 115 процессов, 111 расширенное управление разрешени- ями, 113 файлов, 106 ACL, 116 разрешения процессов, 111 разрешения файлов, 106 расширенная многослойная объединен- ная файловая система (AUFS), 142 реальный DID, 111 режим ядра, 27 ресурсы, контроль доступа, 98	systemd, 149 SystemV, 149 современные дистрибутивы Bottlerocket, 273 CoreOS, 272 Flatcar, 272 RancherOS, 273 современные инструменты, 288 современные команды вывод содержимого каталога через еха, 62 обработка JSON через jq, 64 поиск содержимого в файлах через rg, 62 просмотр содержимого файла через bat, 62 современные, определение, 14 современные среды, 14 сокеты домена, 205 сокеты домена UNIX, 267
С сетевая файловая система (NFS), 225 сетевое взаимодействие на прикладном уровне передача файлов, 222 совместное использование Windows, 226	состояния процессов, 33 сохраненный set-user-ID, 112 спецификация Open Container Initiative (OCI), 166 списки управления доступом, 116 списки управления доступом (ACL), 116
298 | Алфавитный указатель
стандарт иерархии файловой системы (FHS), 131
стандарт W3C, 216
статус выхода, 59
стек TCP/IP
канальный уровень, 187
маршрутизация, 198
межсетевой уровень, 191
порты, 200
прикладной уровень, 215
сокеты, 205
транспортный уровень, 200
ARP, 190
BGP, 199
DNS, 207
ICMP, 197
IPv4, 192
IPv6, 196
NIC, 188
TCP, 186
UDP, 186
структура файловой системы, 131 структурированное журналирование, 236
суперблок, определение, 121 сценарии
контроль потека передачи данных, 87
основы, 86
расширенные типы данных, 86
расширенный ввод/вывод, 88 скрипт для вывода информации о пользователе GitHub, 92 функции, 87
счетчик, 237
Т
температура данных, 238
терминал, 52
том, определение, 121
трассировка и профилирование, 254
трассировка, определение, 237
триггер, 80
туннели, 230
У
универсальный указатель ресурса
(URL), 216
унифицированный расширяемый микропрограммный интерфейс (UEF1), 28 управление доступом
локальное управ л ение доступом, 102 локальное управление пользователями, 102
модели, 99
основы, 97
песочница, 99
полезные советы, 116
пользователи, 101
разрешения, 106
ресурсы, 98
централизованное управление пользователями, 105
управление заданиями, 60
управление памятью, 34
управление процессами, 31
устройства ввода/вывода, наблюдение, 247
учетные данные пользователей, 20
Ф
файловая система
в памяти, 139
и ядро, 138
монтирование, 13С
обычные, 138
обычные файлы, 137
операции, 129
Алфавитный указа гель | 299
основные модели, 131 основы, 120 псевдофайловые системы, 132 создание, 129 AUFS, 142 btrfs, 142 CoW, 140 ext3, 125 ext4, 138 FAT, 139 LVM, 127 OvezlayFS, 142 proofs, 133 sysfs, 135 unlonfs, 142 VFS, 124 XFS, 139 ZFS, 139 файловая система с копированием при записи (CoW), 140 файловая система/dev (devfs), 136 файловая система/ргос, 133 файловая система/sys, 135 файловые системы в памяти, 125 файлы, работа с файлами, 283 физический адрес (МАС), 187 форматирование, 129	функции,в сценариях, 87 ц цепочка поставок, 155 цикл OODA (наблюдай, ориентируйся, решай, действуй), 234 Э эффективный UID, 111 Я ядро Linux архитектура Linux, 25 архитектуры процессоров, 27 драйверы устройств, 37 eBPF, 45 компоненты ядра, 31 модули, 43 процесс загрузки, 28 расширения, 43 сетевое взаимодействие, 36 управление памятью, 34 управление процессами, 31 syscalls, 26 язык гипертекстовой разметки (HTML), 216
Для заметок
Для заметок
Для заметок
Лгылш ын т!л1нен аударма / Перевод с ан, лийско: с «Астана иностранная пресса»
O'REILLY. КНИГИ ПО ПРОГРАММИРОВАНИЮ
Майкл Хаузенблас
КАК ОСВОИТЬ СОВРЕМЕННЫЙ LINUX ПОЛНЫЙ СПРАВОЧНИК: ОТ НОВИЧКА ДО ПРОФЕССИОНАЛА
Бас редактор / Главный редактор Ыскакбай Раби-а
Басуга 2С. 11 2025 кил койылды / П0Д1 |Исано в печать 20.11.2025. niuiiHi 70х100 71е- Кагазы офсептк. Офсет т!к басылыс / Форма, 70x100 71в. Бумага офсетаая Печать офсетнал.
Шартты баспа тзбзгы 24.63. I аралымы 1500,1ана. Тапсырыо № 8638 Усл. пен. л. 24,63 Тираж 1500 эка. Заказ № 8638
Тауар белое! / I оварны и знак- «Asta ла International Publishing» Сапасы жеч!нде мына мекэмеге хабарласыцыз /
С претензиями по качеству обращаться «Ас гана иностранная пресса» Ж1_1С КР, Алматы К-, Аль-Фараби дацг. 19/1, «Нурлы-Тау-БО, 3D блогы, 12офис. ’ОО «Астана иност ранная пресса»
РК, г. Алма>ы, пр. Аль-Фараби, 19/1, БЦ, «Нурлы-Тау». блок ЗБ, помещение 12.
Телефон: +7 (771) 276 41 -OS E-mail: into@astanapublishing.kz Кетерме сауда бел!м! / О гдел оптовых продаж
Алматы к-, Аль-Фараби дацг., 19/1, «Нурлы-Тау» БО. ЗБблогы, 12 офис.
г. Алматы, пр. Аль Фараби, 19/1, БЦ «Нурлы-Тау-, блок 36, помещение 12 E-mail: intot&astanapubtisniiig.kz
"avap барлык сапа жене кау1пс1зд>к ста! 1дар11 арына сай / Тонар соответствуем всем стандартам ка1 lecrea и безопас, юсти Сертификация карает ырылмаген / Сорта фикация не предусмотрена Сактау мерз1м! шектелмеген / Срок годности не ограничен Онд!руилел: Казакста t / Страна-изготовитель; Казахе.ан Казахстан “еспубликасындагы диорибьююр. «РДЦ-Алматы-ЖШС / Дисрибьютор в Республике Казахстан: _ОО «РДЦ-Алматы»
Алмаи»к.,Домбровскийкэыес!,3«а» литерБ офис 1.Тел.:8(727)251-59-9С/Э1/92 г. Алматы, ул. Домбрсвско'о 3«а», литер Б, офис 1. Тел ’8(727) 251-59-90/91/S2
Казастан Республикас ындагы Дистрибьютор интернет-дукен! / Интернет-магазин дистрибьютора в РК’ www oook24.kz
Отпеча1 ано с: о’. овых файлов заказчика в АО «Первая Образцовая тапография», филиал «УЛЬЯНОВСКИЙ ДОМ ПЕЧАТИ-432980, Россия, г. Ульяновск, ул. Гончарова, 14
astarfc
international
publishing
O'REILLY’
Как освоить современный Linux
Структурированный подход к использованию Linux в разработке и рабочих процессах.
Книга будет полезна разработчикам, архитекторам прогоаммного обеспечения и SRE-инженерам.
Вы узнаете:
•	Как использовать Linux не только для администрирования, но и как современную рабочую среду
•	О критически важных компонентах Linux, ядре, терминальном мультиплексоре, оболочках и сценариях командной оболочки
•	О принципах контроля доступа и роли файловых систем
•	Об управлении зависимостями поиложений и о контейнерах
•	О работе с сетевым стеком и инструментами Linux, включая DNS
•	О современных средствах мониторинга операционных систем
•	О принципах мехпроцессного взаимодействия и некоторых аспектах безопасности
Это настоящий атлас выживания в джунглях Linux: от ядра до приложений. Лоскутное одеяло из CLI, конфигов и скриптов, прошитое общей идеей «задавайте вопросы и докапывайтесь до сути». Простые примеры приручают сложные задачи, а ссылки зовут копать глубже Рекомендую всем - от бодрого джуна до матерого сеньора.
Антон Захаров, заместитель технического директора ИТ-компании Forward
Майкл ХАУЗЕНБЛАС -специалист по наблюдаемости и облачным технологиям с опытом в сфере разработки данных, представитель Cloud Native в CNCF. Работает в AWS, бывшей Red Hat, занимается стартапами и прикладными исследованиями.
ISBN 978-601-12-4679-8
9 / OOU I I Z4O I уо >
astQib
international
publishing