автордың кітабын онлайн тегін оқу Python для сетевых инженеров. Автоматизация сети, программирование и DevOps
Перевод С. Черников
Эрик Чоу
Python для сетевых инженеров. Автоматизация сети, программирование и DevOps. — СПб.: Питер, 2022.
ISBN 978-5-4461-1769-7
© ООО Издательство "Питер", 2022
Все права защищены. Никакая часть данной книги не может быть воспроизведена в какой бы то ни было форме без письменного разрешения владельцев авторских прав.
Моей жене Джоанне и детям Микаелин и Эсми.
Моим родителям, которые зажгли во мне страсть много лет назад.
Предисловие
Многие думают (или кто-то так им сказал), что изучение программирования и языка Python пойдет им на пользу. «Навыки программирования пользуются спросом, поэтому вы должны стать программистом». Это неплохой совет. Но лучше ответить на вопрос: как, имея определенный опыт в какой-то области, опередить своих коллег за счет автоматизации и расширения своих умений с помощью навыков разработки ПО? Именно эта цель ставится в данной книге. Вы будете знакомиться с Python в контексте настройки, администрирования и мониторинга сети.
Если вам надоело постоянно заходить на свои серверы и вводить кучу команд для настройки сети; если вы хотите быть уверенными в надежности и воспроизводимости настроек своей сети; если хотите в реальном времени следить за всем происходящим в ней, то Python — это то, что вам нужно.
Вы уже, наверное, пришли к тому, что вам необходимо овладеть навыками программирования, которые можно применить для управления сетями. В конце концов, такие термины, как программно-определяемые сети (Software-Defined Networking, SDN), в последние несколько лет у всех на слуху. Но почему Python? Может быть, лучше выучить JavaScript, Go или какой-то другой язык? Возможно, стоит сделать упор на Bash и освоить разработку сценариев на языке командной оболочки?
Есть две причины, по которым Python отлично подходит для сетевых технологий.
Во-первых, на страницах этой книги Эрик покажет, что для Python написано множество библиотек (иногда их называют пакетами), предназначенных специально для работы с сетью. Простой поиск на https://pypi.org по слову network дает более 500 различных библиотек для автоматизации и мониторинга сети. С помощью таких библиотек, как Ansible, вы сможете создавать сложные сетевые и серверные конфигурации декларативным способом, используя простые конфигурационные файлы.
Используя Pexpect или Paramiko, вы сможете управлять устаревшими удаленными системами, как если бы у них был свой API поддержки сценариев. Если у настраиваемого вами устройства есть свой API, то для работы с ним, скорее всего, уже существует специальная библиотека на Python. Поэтому данный язык, несомненно, подходит для таких задач.
Во-вторых, Python занимает особое место среди языков программирования. Я называю его языком полного спектра и определяю этот термин так: очень простой в освоении язык (print("helloworld") — как вам?) и очень мощная технология, лежащая в основе невероятных программных комплексов, таких как youtube.com.
Это редкое явление. Существуют хорошие языки для начинающих, позволяющие быстро начать программировать. Сразу вспоминается Visual Basic, а также MATLAB и другие коммерческие языки. Но у них ограниченные возможности применения. Можете ли вы себе представить Linux, Firefox или видеоигры, написанные на любом из них? Конечно же нет.
На другом конце спектра находятся очень мощные языки, такие как C++, .NET, Java и многие другие. C++ используется для создания некоторых модулей ядра Linux и крупных программных проектов, таких как Firefox. Однако эти языки не для новичков. Чтобы начать писать код, вам придется разобраться в указателях, компиляторах, компоновщиках, заголовочных файлах, классах, модификаторах доступа (public/private) и т.д.
Python совмещает в себе лучшее из этих двух миров. С одной стороны, на нем очень легко написать что-то полезное, уложившись в несколько строчек кода и использовав простые концепции программирования. С другой — его все чаще применяют в весьма значительных проектах: YouTube, Instagram, Reddit и т.д. Компания Microsoft реализовала на Python интерфейс командной строки (Command Line Interface, CLI) для Azure (хотя для работы с ним не нужно знать или использовать Python).
Итак, подытожим. Умение программировать — это суперсила, способная вывести ваши инженерные навыки на новый уровень. Python — один из самых быстроразвивающихся и популярных языков программирования в мире. Кроме того, для Python имеется множество высококачественных сетевых библиотек. Книга «Python для сетевых инженеров» освещает все вышеперечисленное и изменит ваше представление о работе с сетями. В добрый путь!
Майкл Кеннеди, основатель подкаста Talk Python, Портленд, штат Орегон, США
Введение
В 2014 году на конференции Cisco Live я провел первый семинар Coding 101 по Python и REST API для сетевых инженеров в DevNet Zone. В помещении было полно известных сетевых инженеров и архитекторов, многие из которых в этот день сделали свой первый API-вызов. После этого мне посчастливилось работать с сетевыми инженерами со всего мира, которые решили добавить в число своих навыков программирование.
Отделы информационных технологий и администрирования начинают меняться. Я считаю, что в будущем сетевые инженеры и разработчики ПО будут объединяться в единые команды. Для развертывания современных приложений необходимы масштабируемые, сложные и безопасные сети. И чтобы сделать управление этими сетями воспроизводимым, надежным и динамичным, требуется автоматизация.
Сетевые инженеры имеют большой опыт решения всевозможных проблем. Если в их набор инструментов управления сетями добавить Python, автоматизацию и умение работать с API, то получится потрясающая комбинация. С помощью этих дополнительных технологий инженеры смогут по-новому подходить к решению имеющихся проблем и браться за немыслимые ранее задачи. Эта книга — ценный ресурс как для сетевых инженеров, которые хотят освоить программирование, так и для разработчиков ПО, желающих воспользоваться преимуществами новой программируемой инфраструктуры.
Инженеры часто меня спрашивают: «С чего начать?» Мой совет: начинайте с простого. Выберите «извечные» проблемы, с которыми сталкивается ваша команда, и попытайтесь автоматизировать диагностику и сбор информации. Затем попробуйте автоматизировать передачу собранного в систему тикетов или в приложение мониторинга. Вскоре у вас начнет вырисовываться рабочий процесс. Такое постепенное внедрение нововведений поможет укрепить доверие к автоматизации в команде и позволит ее членам освоиться с новыми инструментами.
Сначала сосредоточьтесь на приобретении базовых навыков программирования, которые пригодятся вам в любом проекте, включая программирование на Python и REST API. Также уделите внимание таким инструментам, как Git и GitHub, которые помогут вам управлять своим исходным кодом и организовать совместную работу. Уделите время подготовке среды разработки. Попробуйте разные редакторы для написания кода и инструменты для исследования API, такие как Postman и curl. Изучите приемы обработки JSON и XML. Начните исследовать методологии разработки программного обеспечения, такие как разработки через тестирование (Test-Driven Development, TDD) и основные принципы DevOps1.
Эта книга отлично подойдет для приобретения этих навыков и поможет вам изучить все эти темы в контексте работы с сетью. Она начинается с использования Python для простых взаимодействий с сетевыми устройствами посредством CLI и API, а затем переходит к фреймворку автоматизации общего назначения — и все это с точки зрения сетевых инженеров. Попутно Эрик демонстрирует примеры кода на Python для обеспечения сетевой безопасности, мониторинга и построения своего API с помощью фреймворка Flask. Знакомит с облачными сетевыми технологиями на примере AWS и Azure и общепринятыми инструментами DevOps, такими как Git, Jenkins и TDD. В своих объяснениях Эрик использует прагматичный подход, основанный на практическом опыте. Это поможет вам внедрить изученные концепции в свою работу.
DevOps и облачные технологии трансформируют нашу индустрию. Команды, занимающиеся обслуживанием сетей, разработкой ПО и администрированием, начинают по-новому взаимодействовать, разделяя ответственность за достижение общих бизнес-целей. Сетевые инженеры с навыками программирования помогут определить ход этой трансформации.
Найдите себе какой-нибудь проект и начните оттачивать эти навыки в его контексте. Выберите какое-то простое действие, которое вам бы хотелось надежно воспроизводить, и попытайтесь его автоматизировать. Начните писать код с самого начала — и делайте это почаще. Найдите или организуйте себе рабочее место для экспериментов. Чем больше вы будете экспериментировать, тем быстрее пойдет обучение.
Инновации, которые станут результатом совместной работы сетевых инженеров и разработчиков в ближайшие пять лет, будут революционными.
Сделайте первые шаги навстречу будущему и не забудьте отпраздновать первый успешный ответ 200OK своего API.
Удачного программирования!
Мэнди Уэйли,старший директор по поддержке разработчиков, Cisco DevNet
1 DevOps — интеграция разработки и эксплуатации. Форма организации труда, главной целью которой является налаживание сотрудничества службы эксплуатации (Ops) и команды разработчиков (Dev). — Примеч. ред.
Сначала сосредоточьтесь на приобретении базовых навыков программирования, которые пригодятся вам в любом проекте, включая программирование на Python и REST API. Также уделите внимание таким инструментам, как Git и GitHub, которые помогут вам управлять своим исходным кодом и организовать совместную работу. Уделите время подготовке среды разработки. Попробуйте разные редакторы для написания кода и инструменты для исследования API, такие как Postman и curl. Изучите приемы обработки JSON и XML. Начните исследовать методологии разработки программного обеспечения, такие как разработки через тестирование (Test-Driven Development, TDD) и основные принципы DevOps1.
DevOps — интеграция разработки и эксплуатации. Форма организации труда, главной целью которой является налаживание сотрудничества службы эксплуатации (Ops) и команды разработчиков (Dev). — Примеч. ред.
Об авторе
Эрик Чоу — IT-технолог с более чем двадцатилетним опытом. Имел дело с крупнейшими сетями в индустрии, работая в Amazon, Azure и других компаниях из списка Fortune 500. Эрик страстно увлекается автоматизацией сетей и языком Python и помогает организациям в создании эффективных механизмов безопасности.
Он также соавтор книги Distributed Denial of Service (DDoS): Practical Detection and Defense (O’Reilly Media).
Еще на счету Эрика два американских патента в сфере IP-телефонии. Своим глубоким интересом к технологиям он делится в книгах, лекциях и блоге, а также участвует в некоторых популярных проектах с открытым кодом на языке Python.
Я бы хотел поблагодарить членов сообщества и разработчиков открытого ПО, сетевых архитектур и Python, которые щедро делятся своими знаниями и кодом. Без них многие проекты, упоминаемые в этой книге, никогда бы не увидели свет. Надеюсь, я тоже внес свой скромный вклад.
Благодарю команду издательства Packt: Тушара, Тома, Иэна, Алекса, Джона и многих других за возможность совместной работы над третьим изданием этой книги. Особая благодарность Рикарду Кёрке за согласие вычитать мой текст.
Спасибо вам, Мэнди и Майкл, что написали предисловие к этой книге. Мне сложно выразить словами, насколько я вам признателен. Вы молодцы!
Моим родителям и моей семье: ваши постоянные поддержка и ободрение сделали меня тем, кто я есть. Я вас люблю.
О научном редакторе
Рикард Кёрке работает консультантом по NetDevOps в компании SDNit в группе опытных технических специалистов, проявляющих глубокий интерес и внимание к перспективным сетевым технологиям.
Программист-самоучка, которого в основном интересует Python. В число его ежедневных обязанностей входит управление сетевыми устройствами с помощью таких средств оркестрации, как Ansible.
Он также был научным редактором книги Марка Г. Собеля A Practical Guide to Linux Commands, Editors and Shell Programming. Third Edition.
Вступление
Как написал Чарльз Диккенс в «Повести о двух городах», «это было лучшее изо всех времен, это было худшее изо всех времен; это был век мудрости, это был век глупости». Эти на первый взгляд противоречивые слова идеально описывают хаос и настроения, царящие во времена перемен и преобразований. Мы, несомненно, испытываем нечто подобное в связи со стремительными изменениями, происходящими в области сетевых технологий. По мере того как разработка ПО все глубже проникает во все аспекты сетей, традиционный интерфейс командной строки и вертикально интегрированные сетевые методики перестают быть оптимальными способами управления современными сетями. С точки зрения сетевых инженеров, изменения, которые мы наблюдаем, волнующи: они открывают новые возможности, но в то же время создают трудности, особенно для тех, кому приходится быстро адаптироваться, чтобы поспевать за новшествами. Эта книга написана с целью облегчить переход для сетевых специалистов и содержит практическое руководство, в котором объясняется, как внедрить в традиционную платформу методики из мира разработки ПО.
В качестве языка программирования для решения задач управления сетями мы будем использовать Python. Это легкий в изучении высокоуровневый язык, который помогает сетевым инженерам эффективно реализовывать их творческие способности и применять навыки решения проблем и облегчает их повседневную работу. Python становится неотъемлемой частью многих крупномасштабных сетей, и с помощью этой книги я попытаюсь поделиться с вами усвоенными мною уроками.
С момента выхода первого и второго изданий я провел интересные и содержательные беседы со многими моими читателями. Я был польщен успехом этой книги и серьезно отнесся к полученным отзывам. В третьем издании я попытался охватить много новых библиотек и обновил примеры, использовав самое свежее программное и аппаратное обеспечение. Я также добавил две главы, которые, как мне кажется, будут важны для сетевых инженеров в сегодняшних условиях.
Времена перемен открывают отличные возможности для технического прогресса. Концепции и инструменты, описанные в этой книге, очень помогли моей карьере, и я надеюсь, что ту же роль они сыграют и в вашей жизни.
Кому подойдет эта книга
Эта книга идеально подойдет ИТ-специалистам и инженерам, которые занимаются администрированием сетевых устройств и хотят расширить свои знания о Python и других инструментах для решения сетевых проблем. Желательно иметь хотя бы базовое понимание сетевых технологий и Python.
Какие темы здесь освещаются
Глава 1. Обзор протоколов TCP/IP и Python. Содержит краткий обзор фундаментальных технологий, из которых состоят современные интернет-коммуникации, начиная с OSI и клиент-серверной модели и заканчивая протоколами TCP, UDP и IP. Здесь мы поговорим об основах языка Python: типах данных, операторах, циклах, функциях и пакетах.
Глава 2. Низкоуровневое взаимодействие с сетевыми устройствами. На практических примерах иллюстрирует использование Python для выполнения команд в контексте сетевого устройства. Также обсуждает трудности автоматизации с одним лишь CLI-интерфейсом. В примерах используются библиотеки Pexpect, Paramiko, Netmiko и Nornir.
Глава 3. API и IDN-сети. Обсуждает новейшие сетевые устройства с поддержкой интерфейсов прикладного программирования (Application Programming Interface, API) и других высокоуровневых методов взаимодействий. Здесь также рассматриваются инструменты, позволяющие абстрагировать низкоуровневые задачи и сосредоточиться на общих целях, которые стоят перед сетевыми инженерами. Обсуждение и примеры будут касаться Cisco NX-API, Meraki, Juniper PyEZ, Arista Pyeapi и Vyatta VyOS.
Глава 4. Фреймворк автоматизации на Python: основы Ansible. Обсуждает основы Ansible, открытого фреймворка автоматизации на Python. Ansible — это дальнейшее развитие идеи API с акцентом на декларативное описание задач. В этой главе описываются преимущества системы Ansible и ее высокоуровневой архитектуры, а также демонстрируются примеры использования с устройствами Cisco, Juniper и Arista.
Глава 5. Фреймворк автоматизации на Python: следующий уровень. Продолжает предыдущую главу и охватывает более сложные аспекты Ansible. Здесь мы поговорим об условных выражениях, циклах, шаблонах, переменных, Ansible Vault и ролях, а также затронем основы создания собственных модулей.
Глава 6. Сетевая безопасность с использованием Python. Представляет несколько инструментов, написанных на Python, которые помогут вам защитить вашу сеть. Обсуждает использование Scapy для тестирования безопасности, Ansible для быстрой реализации списков доступа и Python для ретроспективного анализа инцидентов в сети.
Глава 7. Сетевой мониторинг с использованием Python: часть 1. Охватывает мониторинг сетей с помощью различных инструментов. Содержит примеры использования SNMP и PySNMP для получения информации из устройств. Демонстрирует примеры использования Matplotlib и Pygal для представления результатов в графическом виде. В конце показан пример использования сценария на Python в роли источника данных для Cacti.
Глава 8. Сетевой мониторинг с использованием Python: часть 2. Охватывает дополнительные инструменты мониторинга. Вначале мы создадим графическую диаграмму сети из LLDP-данных с использованием Graphviz. Затем перейдем к пассивному сетевому мониторингу на основе Netflow и других технологий. Мы декодируем поток пакетов с помощью Python и применим ntop для визуализации результатов. Здесь вы также найдете краткий обзор системы Elasticsearch и применения для мониторинга сети.
Глава 9. Создание сетевых веб-сервисов с помощью Python. Здесь мы покажем, как создать собственный API для автоматизации управления сетью с помощью веб-фреймворка Python Flask. Преимущества таких API: сокрытие деталей организации сети от запрашивающей стороны, объединение и настройка операций, а также обеспечение повышенной безопасности за счет ограничения доступа к поддерживаемым операциям.
Глава 10. Облачные сетевые технологии AWS. Показывает, как с помощью AWS можно создать функциональную и устойчивую виртуальную сеть. Охватывает технологии виртуальных приватных облаков, такие как CloudFormation, таблицы маршрутизации VPC, списки доступа, Elastic IP, шлюзы NAT, Direct Connect и другие связанные с этим темы.
Глава 11. Облачные сетевые технологии Azur. Рассказывает о сетевых сервисах от Azur и о том, как в этом облаке можно создавать собственные сервисы. Здесь мы обсудим Azure VNet, Express Route and VPN, сетевые балансировщики нагрузки Azure и другие связанные с этим технологии.
Глава 12. Анализ сетевых данных с помощью Elastic Stack. Показывает, как использовать Elastic Stack в роли набора тесно интегрированных инструментов для анализа и мониторинга сети. Здесь обсуждается множество тем, от установки, настройки, импортирования данных с помощью Logstash и Beats и поиска данных с применением Elasticsearch до визуализации с использованием Kibana.
Глава 13. Работа с Git. Иллюстрирует роль Git для организации совместной работы и управления версиями кода. Демонстрирует примеры использования Git в повседневной практике администрирования сетей.
Глава 14. Непрерывная интеграция с помощью Jenkins. Рассказывает о применении Jenkins для автоматического создания конвейеров операций, которые могут сэкономить наше время и повысить надежность.
Глава 15. TDD для сетей. Объясняет, как с помощью Python-пакетов unittest и pytest создавать простые тесты для проверки нашего кода. Демонстрирует примеры написания тестов, проверяющих достижимость, сетевые задержки, безопасность и сетевые транзакции. Здесь вы также увидите, как внедрить тесты в инструменты непрерывной интеграции, такие как Jenkins.
Как извлечь максимум из этой книги
Чтобы получить максимальную пользу, читателю желательно иметь базовый опыт сетевого администрирования и знать Python. Главы можно читать в произвольном порядке, за исключением 4-й и 5-й. Помимо основных программных и аппаратных средств, представленных в начале книги, в каждой главе будут описываться дополнительные новые инструменты.
Настоятельно рекомендуем выполнять показанные здесь примеры в своей экспериментальной сетевой среде.
Загрузка файлов с примерами кода
Архив с примерами кода из этой книги также доступен на GitHub по адресу https://github.com/PacktPublishing/Mastering-Python-Networking-Third-Edition. Любые обновления будут вноситься в этот репозиторий.
У нас есть и другие архивы с кодом для нашей богатой коллекции книг и видеороликов, доступные по адресу https://github.com/PacktPublishing/. Загляните туда!
Загрузка полноцветных иллюстраций
Мы также предоставляем PDF-файл с цветными изображениями оригинальных снимков экранов и диаграмм, использованных в этой книге. Он доступен по адресу https://static.packt-cdn.com/downloads/9781839214677_ColorImages.pdf.
Условные обозначения
В этой книге используется ряд соглашений по оформлению текста.
Моноширинным шрифтом выделены код в тексте, имена таблиц баз данных, папок, файлов, расширений файлов, фиктивные URL, ввод пользователя и теги Twitter. Например, «В автоматически сгенерированной конфигурации также открыт доступ к vty по протоколам telnet и SSH».
Блоки кода оформляются так:
# Это комментарий
print("hello world")
Курсивом выделяются новые термины и важные слова. Например: «В следующем разделе мы продолжим обсуждать SNMP, но уже в контексте полнофункциональной системы мониторинга сети под названием Cacti».
От издательства
Обратите внимание: виртуальная лаборатория VIRL от Cisco, подробно описанная в главе 2 и используемая в примерах книги, на момент выхода данного издания уже не существует в представленном автором виде. Начиная с релиза 2.0, этот инструмент носит название Cisco Modeling Labs. Тем не менее книга, которую вы держите в руках, не теряет от этого свою ценность, а проекты на github и другие продукты Cisco, упоминаемые автором в контексте VIRL, актуальны и для новой версии лаборатории.
Ваши замечания, предложения, вопросы отправляйте по адресу comp@piter.com (издательство «Питер», компьютерная редакция).
Мы будем рады узнать ваше мнение!
На веб-сайте издательства www.piter.com вы найдете подробную информацию о наших книгах.
1. Обзор TCP/IP и Python
Добро пожаловать в век новых и удивительных сетевых технологий! Когда на рубеже тысячелетий я начинал работать сетевым инженером, моя роль тогда определенно отличалась от роли сетевого инженера сегодня. В то время сетевые инженеры управляли и обслуживали локальные и глобальные сети с помощью интерфейса командной строки. Иногда нам приходилось пересекать границу, разделяющую профессии сетевого инженера и разработчика, чтобы решать свои задачи, но вообще от нас не требовалось писать код или понимать концепции программирования. Сегодня все иначе.
С годами DevOps, программно-определяемые сети (Software-Defined Networking, SDN) и прочие технологии существенно размыли границы между ролями сетевого, системного инженера и разработчика.
Раз вас заинтересовала эта книга — значит, вы либо уже внедрили у себя DevOps для управления сетями, либо рассматриваете возможность перехода на программируемые сети. Возможно, вы, как и я, много лет работали сетевым инженером и захотели разобраться в языке программирования Python, о котором столько разговоров. А может быть, вы уже свободно владеете этим языком, но хотите узнать, как его применять в сетевых технологиях.
Если вы принадлежите к любой из этих категорий или просто интересуетесь языком Python в контексте сетевых технологий, я убежден, что эта книга — для вас (рис. 1.1).
Рис. 1.1. Как пересекаются Python и сетевые технологии
Во многих учебниках сетевые технологии и язык Python рассматриваются как отдельные темы. Я выбрал другой подход. Предполагается, что у читателей этой книги есть некоторый практический опыт управления сетями и общее представление о сетевых протоколах. Знакомство с Python как языком тоже не помешает, но его основы будут рассмотрены далее в этой главе. Чтобы извлечь максимум из этой книги, вовсе не нужно быть специалистом по Python или в сетевых технологиях. Мы будем отталкиваться от базовых понятий, чтобы читатель мог изучить и опробовать различные приемы, которые могут упростить его жизнь.
В этой главе мы рассмотрим некоторые базовые понятия сетевых технологий и Python, а затем определим, какими знаниями нужно обладать, чтобы получить максимальную выгоду от этой книги. Если вам потребуется освежить свои знания, то в интернете есть множество бесплатных и недорогих ресурсов, которые помогут вам в этом. Могу посоветовать бесплатные лекции на Khan Academy (https://www.khanacademy.org/) и руководства по Python (https://www.python.org).
Мы кратко пробежимся по темам, касающимся сетевых технологий. Как показывает мой опыт работы в этой области, типичный сетевой инженер или разработчик может не помнить наизусть все состояния протокола передачи данных (Transmission Control Protocol, TCP) — я так точно не помню — и это не мешает ему решать повседневные задачи. Однако такой инженер обычно знаком с основами модели взаимодействий открытых систем (Open Systems Interconnection, OSI), принципами работы протоколов TCP и передачи пользовательских датаграмм (User Datagram Protocol, UDP), различными полями в IP-заголовках и другими базовыми понятиями.
Кроме того, бегло рассмотрим Python, чтобы читатели, которые не пишут на этом языке регулярно, могли себя уверенно чувствовать при чтении следующих глав.
В частности, в этой главе вас ждет краткий обзор:
• устройства интернета;
• модели OSI и архитектуры «клиент — сервер»;
• набора протоколов TCP, UDP и IP;
• синтаксиса, типов данных, операторов и циклов в языке Python;
• приемов расширения Python с помощью функций, классов и пакетов.
Конечно, представленная здесь информация не является исчерпывающей, поэтому при необходимости обращайтесь к дополнительным материалам по приводимым ссылкам.
Работу сетевых инженеров затрудняют масштаб и сложность сетей. Мы имеем дело и с небольшими домашними сетями, и со средними сетями в малом бизнесе, и с крупными сетями корпораций международного масштаба. Самая большая из всех сетей, конечно, интернет. Без него у нас не было бы электронной почты, веб-сайтов, служб, потокового мультимедиа или облачной обработки данных. Поэтому, прежде чем погружаться в подробности протоколов и Python, поговорим об интернете.
Краткий обзор интернета
Что такое интернет? Ответ на этот, казалось бы, простой вопрос зависит от того, в какой области вы работаете. Люди вкладывают в это слово разный смысл; молодежь, старики, студенты, учителя, предприниматели, поэты имеют собственное мнение на этот счет.
С точки зрения сетевого инженера, интернет — это глобальная вычислительная сеть, объединяющая мелкие и крупные сети. Иными словами, это сеть сетей без центрального управления. Возьмите, к примеру, свою домашнюю сеть. Она состоит из устройства, выполняющего функции маршрутизатора, коммутатора и беспроводной точки доступа, и позволяет взаимодействовать вашим смартфонам, планшетам, компьютерам и смарт-телевизорам. Это ваша локальная вычислительная сеть (Local Area Network, LAN).
Когда вашей домашней сети нужно обратиться к внешнему миру, она передает информацию из LAN в более крупную сеть, принадлежащую вашему поставщику услуг интернета, или интернет-провайдеру (Internet Service Provider, ISP). Обычно это компания, которой вы платите за доступ к интернету. Провайдер подключает мелкие сети к сетям большего масштаба, которые он обслуживает. Сеть провайдера часто содержит граничные узлы, которые направляют трафик в магистральную сеть. Задача магистральной сети — связать эти граничные узлы с помощью высокоскоростных соединений.
Специальные граничные узлы соединяют сети разных провайдеров, чтобы ваш трафик мог попасть к адресату. Ответ, отправленный вашему домашнему компьютеру, планшету или смартфону, может идти по другому маршруту, однако отправитель и получатель остаются неизменными.
Рассмотрим компоненты, из которых состоят сети.
Серверы, хосты и сетевые компоненты
Хост — это конечный узел сети, который взаимодействует с другими узлами. В современных реалиях хостом может быть обычный компьютер, смартфон, планшет или телевизор. С появлением интернета вещей (Internet of Things, IoT) определение хоста расширилось и теперь охватывает IP-камеры, ресиверы цифрового телевидения и всевозможные датчики, которые применяются в сельском хозяйстве, автомобилях и т.д. Учитывая взрывной рост количества хостов, подключенных к интернету, все эти устройства нужно как-то адресовать, маршрутизировать и администрировать. Мы наблюдаем беспрецедентный спрос на зрелые сетевые технологии.
Большую часть времени, которое мы проводим в интернете, занимает выполнение запросов к сервисам. Это может быть просмотр веб-страницы, отправка или получение электронной почты, передача файлов и т.д. За работу этих сервисов отвечают серверы. Сервер предоставляет услуги множеству узлов и обычно обладает мощной аппаратной конфигурацией. В каком-то смысле серверы — это суперузлы сети, расширяющие возможности остальных узлов. Мы еще вернемся к ним, когда будем обсуждать клиент-серверную модель.
Если представить серверы и хосты в виде мегаполисов и небольших городов, сетевые компоненты будут играть роль дорог и автострад, соединяющих их. При описании сетевых компонентов, которые передают по всему миру постоянно растущие потоки битов и байтов, вспоминается термин «информационная магистраль». В модели OSI, которую мы рассмотрим далее, этими компонентами являются устройства с первых трех уровней, иногда и с четвертого. Это, к примеру, маршрутизаторы и коммутаторы канального и сетевого уровней, которые направляют трафик, а также транспортная инфраструктура вроде оптоволоконных и коаксиальных кабелей, витой пары, а иногда и оборудования для спектрального уплотнения каналов (Dense Wavelength Division Multiplexing, DWDM).
В совокупности хосты, серверы, хранилища данных и сетевые компоненты составляют то, что принято считать современным интернетом.
Появление дата-центров
В предыдущем разделе мы обсудили разные роли, которые играют серверы, хосты и сетевые компоненты в межсетевых взаимодействиях. Ввиду повышенных требований к аппаратным ресурсам серверы зачастую размещаются в каком-то одном месте, чтобы ими можно было эффективно управлять. Такое место называется центром обработки данных (ЦОД), или просто дата-центром.
Корпоративные дата-центры
Бизнес-нужды типичной компании — это электронная почта, хранилище документов, система отслеживания продаж, система управления заказами, инструменты для отдела кадров и внутренняя сеть для обмена знаниями. Для поддержки этих сервисов нужны файловый и почтовый серверы, серверы баз данных и веб-серверы. В отличие от рабочих станций это, как правило, высокопроизводительные компьютеры, потребляющие много электроэнергии и требующие хорошей системы охлаждения и быстрых сетевых соединений. К тому же такое оборудование зачастую создает много шума, что недопустимо для обычных условий труда. Серверы, как правило, размещаются в каком-то одном помещении в здании компании, которое называется главным распределительным пунктом (Main Distribution Frame, MDF); это позволяет подвести к нему необходимое электропитание, установить резервный генератор, предусмотреть охлаждение и соединить все это в сеть.
Прежде чем попасть в MDF, пользовательский трафик обычно агрегируется недалеко от самого пользователя, в месте, которое иногда называют промежуточным распределительным пунктом (Intermediate Distribution Frame, IDF). Нередко структура IDF-MDF повторяет план помещений в здании компании или на территории учебного заведения. Например, на каждом этаже может находиться свой пункт IDF, который собирает трафик и направляет его в MDF, размещенный в другой части здания. Если предприятие размещено в нескольких зданиях, может потребоваться дополнительная агрегация трафика с последующей передачей его в корпоративный дата-центр.
Корпоративные дата-центры обычно имеют трехуровневую сетевую архитектуру, включающую уровень доступа, уровень распределения и системный уровень. Конечно, как в любой архитектуре, здесь нет жестких правил и универсальных решений; это всего лишь общий подход. Например, если наложить эту трехуровневую архитектуру на модель «пользователь — IDF — MDF», то получится, что уровень доступа — это порты, к которым подключается каждый пользователь, IDF можно считать уровнем распределения, а системный уровень состоит из соединений, ведущих к MDF и корпоративным дата-центрам. Это, конечно же, обобщенный взгляд на корпоративные сети; некоторые компании используют другие модели.
Облачные дата-центры
С появлением облачных вычислений и программного обеспечения, объединяемых термином «инфраструктура как услуга» (Infrastructure as a Service, IaaS), облачные провайдеры стали строить по-настоящему огромные дата-центры, которые иногда называют гипермасштабными. Под облачными вычислениями имеются в виду вычислительные ресурсы, доступ к которым осуществляется по мере необходимости и которые не требуют ручного управления со стороны пользователя. Такие услуги, к примеру, предоставляются компаниями Amazon, Microsoft и Google.
Учитывая количество серверов, которое необходимо вместить, облачные дата-центры обычно имеют куда более высокие требования к электропитанию, охлаждению и пропускной способности сети по сравнению с корпоративными ЦОД. Даже после многих лет использования облачных сервисов я не перестаю удивляться масштабу этих дата-центров, когда мне приходится посещать их лично. Они настолько большие и потребляют столько электроэнергии, что их обычно строят рядом с электростанциями, чтобы получить самый низкий тариф и минимизировать потери в электросети. При выборе места строительства также учитываются высочайшие требования к охлаждению. Например, компания Facebook выбрала для своего дата-центра город Лулео на севере Швеции (113 километров южнее полярного круга) отчасти из-за низкой температуры воздуха. В любой поисковой системе можно найти поразительные цифры, связанные с наукой проектирования и обслуживания облачных дата-центров для таких компаний, как Amazon, Microsoft, Google и Facebook. Например, ЦОД компании Microsoft в Вест-Де-Мойне, штат Айова, занимает 110 000 квадратных метров плюс еще 80 гектаров окружающей территории; чтобы обеспечить его строительство, городу пришлось вложить в общественную инфраструктуру 65 миллионов долларов (рис. 1.2).
Рис. 1.2. Дата-центр в штате Юта (источник: https://en.wikipedia.org/wiki/Utah_Data_Center)
В масштабах облачных провайдеров размещение сервисов на одном сервере экономически невыгодно или просто невозможно. Сервисы распределяют между множеством серверов, иногда размещенных в разных зданиях, чтобы обеспечить избыточность и гибкость для владельцев сервисов.
Требования ко времени отклика и избыточности, а также физический разброс серверов создают огромную нагрузку на сеть. Для соединения множества серверов между собой требуется огромное количество сетевого оборудования, такого как кабели, коммутаторы и маршрутизаторы. И каждый из этих компонентов нужно поместить в стойку, подключить и затем обслуживать. Архитектура типичного дата-центра имеет вид многокаскадной сети Клоза (рис. 1.3).
Рис. 1.3. Сеть Клоза
Для обеспечения производительности, гибкости и надежности облачных дата-центров часто требуется автоматизация сети. Традиционные способы управления сетевыми устройствами с помощью терминала и интерфейса командной строки не позволяют вводить сервисы в работу в разумные сроки. Не говоря уже о том, что выполнение рутинных задач вручную чревато ошибками, неэффективно и по сути является пустой тратой инженерных талантов. Ситуация усложняется еще и тем, что быстро меняющиеся потребности бизнеса часто требуют оперативного изменения конфигурации сети.
Мой собственный путь к автоматизации сетей с помощью Python начался несколько лет назад именно в облачных дата-центрах, и я еще ни разу об этом не пожалел.
Граничные дата-центры
Если у нас достаточно вычислительных мощностей на уровне дата-центра, зачем размещать наше оборудование где-то еще? Клиентские соединения со всего мира можно направить к серверам в этом дата-центре, и этого будет достаточно? Ответ, конечно, зависит от ситуации. Самое серьезное ограничение заключается в задержках при маршрутизации запросов и сеансов между клиентом и крупным дата-центром: большие задержки превращают сеть в узкое место.
Конечно, любой, кто знаком с элементарной физикой, понимает, что задержка сети не может быть нулевой: даже свету в вакууме нужно какое-то время на преодоление расстояния. А в реальных условиях задержка будет куда выше. Почему? Потому что сетевой пакет должен пройти через множество сетей, а иногда и по подводному кабелю, через далекий спутник связи, сотовые сети 3G или 4G, Wi-Fi-соединения и т.д.
Как уменьшить задержку сети? Одно из решений: сократить количество сетей, через которые проходят клиентские запросы. Граница вашей сети должна находиться как можно ближе к конечному пользователю и обладать достаточными для обслуживания запросов ресурсами. Такой подход часто применяется для раздачи медиаконтента — музыки и видео.
Представьте, что вы занимаетесь созданием сервиса видеовещания следующего поколения. Чтобы порадовать своих клиентов идеальным видеопотоком, вам следует разместить свой сервер раздачи потокового видео как можно ближе к ним — либо внутри сети провайдера, либо рядом с ней. Также, чтобы зарезервировать ресурсы и повысить скорость соединения, исходящий сетевой канал серверной фермы должен быть подключен к как можно большему числу интернет-провайдеров, чтобы уменьшить количество транзитных участков. Все соединения должны иметь достаточную пропускную способность, чтобы не увеличивать задержки в периоды пиковых нагрузок. Эти требования привели к появлению граничных дата-центров для пирингового обмена данными между крупными интернет- и контент-провайдерами. Сетевых устройств в них не так много, как в облачных ЦОД, но они тоже могут извлечь пользу из автоматизации сетей в плане надежности, гибкости, безопасности и наблюдаемости.
Далее в книге мы еще вернемся к вопросам безопасности (см. главу 6) и наблюдаемости (см. главы 7 и 8).
Многие сложные системы делят на меньшие части для уменьшения сложности, аналогично в основу сетевых взаимодействий была положена концепция уровней. С годами было разработано несколько сетевых моделей. В этой книге мы поговорим о двух самых важных и начнем с модели OSI.
Модель OSI
Никакую книгу по сетям нельзя считать полной без обзора модели OSI. В этой основополагающей модели телекоммуникационные функции делятся на уровни. Всего имеется семь независимых уровней, располагающихся один поверх другого и обладающих четкой структурой и характеристиками.
Например, поверх различных протоколов канального уровня, таких как Ethernet и Frame Relay, располагается протокол IP сетевого уровня. Эталонная модель OSI — отличное средство разделения разнообразных технологий по понятным группам, ни у кого не вызывающим возражений. Благодаря этому люди могут сосредоточиться на своих задачах в рамках одного уровня, не слишком заботясь о совместимости (рис. 1.4).
Изначально модель OSI разрабатывалась в конце 1970-х и позже была опубликована Международной организацией по стандартизации (International Organization for Standardization, ISO), известной ныне под названием Международного консультационного комитета по телефонии и телеграфии (Telecommunication Standardization Sector of the International Telecommunication Union, ITU-T). Это общепринятый стандарт, на основе которого обычно создаются новые телекоммуникационные технологии.
Примерно в то же время происходило становление интернета. Эталонную модель, которую использовал его создатель, часто называют TCP/IP. TCP и IP — это протоколы, составлявшие оригинальную архитектуру интернета. Они перекликаются с моделью OSI в том смысле, что передача данных между узлами в них разделена на абстрактные уровни.
| Модель OSI |
|||
| Уровень |
Тип данных протокола (PDU) |
Функции |
|
| Уровни хоста |
7. Прикладной |
Данные |
Высокоуровневые API, включая совместное использование ресурсов, доступ к удаленным файлам |
| 6. Представления |
Передача данных между сетевыми сервисами и приложениями, включая преобразование кодировок символов, сжатие данных и шифрование/расшифровывание |
||
| 5. Сеансовый |
Управление сеансами связи, например организация непрерывного обмена информацией в форме многократной передачи туда-обратно между двумя узлами |
||
| 4. Транспортный |
Сегменты (TCP)/ датаграммы (UDP) |
Надежная передача сегментов данных между узлами в сети, включая сегментирование, подтверждение получения и мультиплексирование |
|
| Уровни среды передачи данных |
3. Сетевой |
Пакеты |
Структурирование и управление сетями с несколькими узлами, включая адресацию, маршрутизацию и управление трафиком |
| 2. Канальный |
Биты/ кадры |
Надежная передача кадров данных между двумя узлами, связанными на физическом уровне |
|
| 1. Физический |
Биты |
Передача и прием двоичных данных через физическую среду |
|
Рис. 1.4. Модель OSI
Разница в том, что TCP/IP объединяет уровни 5–7 модели OSI в прикладной уровень, а физический и канальный — в уровень сетевого доступа (канальный) (рис. 1.5).
И OSI, и TCP/IP можно использовать в качестве стандартов для сквозной передачи данных. В этой книге основное внимание уделяется модели TCP/IP, так как именно на ней основан интернет. Но мы будем иногда вспоминать модель OSI — например, в ходе обсуждения веб-фреймворка в следующих главах. Помимо моделей транспортного уровня, существуют также модели управления сетевыми взаимодействиями на прикладном уровне. В современных сетях большинство приложений основано на клиент-серверной архитектуре. О ней и пойдет речь в следующем разделе.
Рис. 1.5. Набор интернет-протоколов
Клиент-серверная модель
Эталонная клиент-серверная модель определяет стандартный способ обмена данными между двумя узлами. Конечно, сегодня ни для кого не секрет, что не все узлы равнозначны. Даже во времена ARPANET (Advanced Research Projects Agency Network) одни узлы играли роль рабочих станций, а другие — серверов, снабжающих рабочие станции данными. Серверные узлы обычно обладают более мощной аппаратной конфигурацией и находятся под более пристальным вниманием инженеров. Они предоставляют ресурсы и услуги другим узлам сети, поэтому их вполне обоснованно называют серверами (от англ. server — «обслуживающее устройство»). Серверы, как правило, пассивно ждут, когда к ним обратятся за ресурсами. Эту модель распределенных ресурсов, которые запрашиваются клиентами, называют клиент-серверной архитектурой.
Почему это важно? Если задуматься, отношения между клиентами и серверами являются ярким свидетельством значимости сетевых технологий. Если бы клиенту и серверу не нужно было обмениваться услугами (сервисами), у нас не было бы необходимости во взаимных сетевых соединениях. Именно тот факт, что клиент и сервер посылают друг другу биты и байты, иллюстрирует важность сетевых технологий. Всем известно, как самая крупная из сетей, интернет, изменила мир и теперь играет важную роль в нашей жизни.
Вы можете спросить, как узлы определяют время, скорость, адрес отправителя и получателя каждый раз, когда им нужно обменяться данными? Это подводит нас к вопросу о сетевых протоколах.
Наборы сетевых протоколов
На ранних этапах развития компьютерных сетей протоколы были закрытыми и тесно контролировались компаниями, которые разрабатывали методы передачи данных. Хосты, использующие протокол IPX/SPX от Novell, не могли общаться с хостами, использующими AppleTalk от Apple, и наоборот. Закрытые наборы протоколов обычно делились на уровни по аналогии с эталонной моделью OSI и следовали архитектуре «клиент — сервер», но не были совместимы между собой. Они в основном работали в изолированных локальных сетях, не связанных с внешним миром. Когда трафик нужно было передать за пределы локальной сети, обычно использовали устройство вроде маршрутизатора, которое транслировало данные из одного протокола в другой. Например, чтобы подключить к интернету сеть на основе AppleTalk, маршрутизатор преобразовывал этот протокол в IP. Это промежуточное преобразование, как правило, было неидеальным, но, поскольку большая часть взаимодействий в те дни происходила внутри локальной сети, сетевые администраторы считали такой способ приемлемым.
Появление необходимости в межсетевых взаимодействиях вызвало острую потребность в стандартизации наборов сетевых протоколов. В конечном итоге закрытые протоколы уступили стандартизированным, таким как TCP, UDP и IP, что существенно улучшило способность сетей сообщаться между собой. Корректная работа интернета, самой большой и важной сети, зависит от этих протоколов. Далее мы рассмотрим каждый из них.
Протокол управления передачей (TCP)
TCP (Transmission Control Protocol) — один из основных протоколов современного интернета. Открывая веб-страницу или отправляя электронное письмо, вы так или иначе используете его. Он находится на 4-м, транспортном уровне модели OSI и отвечает за надежную передачу сегментов данных между двумя узлами с проверкой ошибок. Пакет TCP состоит из 160-битного заголовка, который, помимо прочего, содержит номера портов отправителя и получателя, порядковый номер, номер подтверждения, управляющие флаги и контрольную сумму (рис. 1.6).
Рис. 1.6. TCP-заголовок
Функции и характеристики TCP
Для установления соединения между хостами протокол TCP использует сокеты или порты датаграмм. Администрация адресного пространства интернета (Internet Assigned Numbers Authority, IANA) закрепляет хорошо известные порты за определенными сервисами — например, порт 80 для HTTP (веб), а порт 25 — для SMTP (почта). Сервер в клиент-серверной модели обычно прослушивает один из этих стандартных портов в ожидании клиентских запросов. Операционная система управляет TCP-соединением с помощью сокета — локального представления конечной точки соединения.
Протокол действует подобно конечному автомату, определяя, когда принимать новые запросы на соединение, когда обслуживать действующий сеанс и когда освобождать ресурсы после закрытия соединения. Каждое TCP-соединение проходит через цепочку состояний, таких как Listen, SYN-SENT, SYN-RECEIVED, ESTABLISHED, FIN-WAIT, CLOSE-WAIT, CLOSING, LAST-ACK, TIME-WAIT и CLOSED.
TCP-сообщения и передача данных
Важнейшее отличие протокола TCP от его близкого «родственника» UDP: TCP передает данные упорядоченным и надежным образом. Благодаря гарантиям доставки TCP часто называют протоколом, ориентированным на соединения. Чтобы установить соединение, TCP сначала выполняет трехэтапную процедуру «рукопожатия», SYN, SYN-ACK и ACK, синхронизируя порядковый номер между отправителем и получателем.
Для наблюдения за передачей сегментов данных используются подтверждения. В конце одна из сторон посылает сообщение FIN, а другая подтверждает прием сообщением ACK и дополнительно посылает свое сообщение FIN. После чего инициатор завершения соединения посылает сообщения ACK, подтверждая получение сообщения FIN.
Те, кто занимался диагностикой TCP-соединений, знают, что это взаимодействие может оказаться довольно сложным. Но, к счастью, в большинстве случаев оно происходит незаметно, в фоновом режиме.
О протоколе TCP можно написать целый том; и на самом деле существует множество замечательных книг на эту тему.
Протокол пользовательских датаграмм (UDP)
UDP (User Datagram Protocol) — еще один из основных протоколов интернета. Как и TCP, он работает на 4-м, транспортном уровне модели OSI и отвечает за обмен сегментами данных между прикладным и сетевым уровнями. В отличие от TCP, его заголовок занимает всего 64 бита, включая номера портов отправителя и получателя, длину и контрольную сумму. Легковесные заголовки делают этот протокол идеальным для ситуаций, когда требуется быстрая передача данных без организации сеанса связи между двумя хостами и без гарантий доставки. В эпоху быстрых интернет-соединений сложно представить, что во времена X.21 и Frame Relay размер заголовков существенно влиял на скорость передачи данных.
Помимо скорости, UDP отличается от TCP отсутствием поддержки различных состояний, что тоже экономит вычислительные ресурсы на обеих сторонах соединения (рис. 1.7).
Рис. 1.7. UDP-заголовок
Вам, наверное, интересно, зачем UDP вообще используется в современных условиях. Учитывая отсутствие гарантий доставки данных, не лучше ли использовать во всех соединениях надежный протокол TCP с его проверкой ошибок? Но, например, при передаче потокового видео или звонках по Skype легковесные заголовки позволяют передавать датаграммы максимально быстро, что и требуется в подобных приложениях. Можно также вспомнить DNS-запросы, основанные на UDP: низкая задержка перевешивает потребность в точности.
Преобразование адреса, вводимого в браузере, в идентификатор, понятный компьютеру, желательно выполнять максимально быстро, потому что оно выполняется еще до того, как до вас дойдет первый бит вашего любимого веб-сайта.
И снова в одном разделе книги нельзя охватить все нюансы UDP, поэтому, если вас заинтересовала тема, исследуйте ее с помощью различных ресурсов.
Межсетевой протокол (IP)
Сетевые инженеры, по их собственному признанию, работают на 3-м, сетевом уровне модели OSI. Протокол IP (Internet Protocol), помимо прочего, устанавливает правила адресации и маршрутизации трафика между конечными узлами. Адресное пространство разделено на две части: сеть и хост. Какая часть сетевого адреса относится к сети, а какая к хосту, определяется маской подсети: часть, относящаяся к сети, обозначается единицами, а часть, относящаяся к хосту, — нулями. В IPv4 принята форма записи адресов через точки — например, 192.168.0.1.
Маску подсети можно записать либо в формате с точками (255.255.255.0), либо с косой чертой, которая указывает, сколько битов отводится сетевой части (/24) (рис. 1.8).
Рис. 1.8. Заголовок IPv4
Заголовок IPv6, следующего поколения протокола IP, имеет фиксированную часть и различные расширения (рис. 1.9).
Рис. 1.9. Заголовок IPv6
Поле Следующий заголовок в фиксированной части может указывать на расширенный заголовок с дополнительной информацией. Он также может определять протокол более высокого уровня, такой как TCP или UDP. Дополнительные заголовки могут содержать сведения о маршрутизации и фрагменте. Несмотря на огромное желание разработчиков протоколов перейти на IPv6, адресация в современном интернете в основном происходит с помощью IPv4, а IPv6 чаще используется для внутренней адресации в сетях поставщиков услуг.
Преобразование сетевых адресов (NAT) и сетевая безопасность
NAT (Network Address Translation) обычно используется для преобразования диапазона приватных IPv4-адресов в публично доступные. Но этот термин может также означать трансляцию IPv4 в IPv6; например, провайдер может использовать IPv6 во внутренней сети, но, когда пакеты покидают сеть, они должны преобразовываться в IPv4. Иногда по соображениям безопасности также применяется NAT6:6.
Обеспечение безопасности — это непрерывный процесс, охватывающий все аспекты сетевых технологий, включая автоматизацию и Python. В книге я хочу показать, как Python может помочь в управлении сетью; о безопасности речь пойдет в следующих главах, где мы обсудим использование Python для реализации списков доступа, поиска в журналах признаков несанкционированного вторжения и т.п. Мы также рассмотрим, как с помощью Python и других инструментов можно реализовать наблюдаемость сети — например, динамически создать графическое представление ее топологии на основе информации о сетевых устройствах.
Концепции IP-маршрутизации
IP-маршрутизация заключается в передаче пакетов между двумя конечными точками через промежуточные устройства в зависимости от IP-заголовков. Промежуточные устройства участвуют в передаче пакетов при любом взаимодействии в интернете. Как уже упоминалось, к ним относятся маршрутизаторы, коммутаторы, оптические устройства и другие компоненты, которые не выходят за пределы сетевого и транспортного уровней. Представьте, что вы направляетесь из Сан-Диего, штат Калифорния, в Сиэтл, штат Вашингтон. В этой аналогии Сан-Диего выступает в роли исходного IP-адреса, а Сиэтл — конечного. В своем путешествии вы будете проезжать через другие города: Лос-Анджелес, Сан-Франциско, Портленд; их можно считать промежуточными маршрутизаторами и коммутаторами между начальной и конечной точками.
Почему это важно? Данная книга в каком-то смысле посвящена администрированию и настройке этих промежуточных устройств. В век огромных дата-центров, занимающих несколько футбольных полей, эффективные, динамичные и экономные методы управления сетями становятся важным конкурентным преимуществом для многих компаний. В следующих главах мы подробно поговорим о том, какую роль в этом играет программирование на Python.
Итак, мы рассмотрели эталонные сетевые модели и наборы сетевых протоколов. Теперь можно переходить непосредственно к Python. Начнем с обзора этого языка.
Обзор языка Python
Эта книга писалась для того, чтобы упростить жизнь нам, сетевым инженерам. Но что такое Python и почему этот язык предпочитают многие инженеры DevOps? Приведу цитату из краткого описания этого языка от Python Foundation (https://www.python.org/doc/essays/blurb/):
«Python — это интерпретируемый, объектно-ориентированный язык программирования высокого уровня с динамической семантикой. Высокоуровневая организация встроенных типов данных в сочетании с динамической типизацией и динамической привязкой делает этот язык очень привлекательным для быстрой разработки приложений, а также для использования в качестве языка сценариев или языка для связывания воедино существующих компонентов. Простой и легкий в освоении синтаксис Python делает упор на удобочитаемость и тем самым снижает затраты на обслуживание программ».
Если вы новичок в программировании, то такие понятия, как «объектно-ориентированный» или «динамическая семантика», наверное, мало о чем вам говорят. Но такие характеристики, как «быстрая разработка приложений» и «простой, легкий в освоении синтаксис», как мне кажется, выглядят заманчиво. Python — интерпретируемый язык; это означает, что перед выполнением код почти (или вообще) не компилируется, благодаря чему время на написание, тестирование и редактирование программ на этом языке существенно сокращается. Если ваш сценарий завершается с ошибками, то для его отладки зачастую достаточно оператора print.
Использование интерпретатора также позволяет легко переносить программы на разные операционные системы, включая Windows и Linux. Программа, написанная для одной ОС, может использоваться в другой с минимальными изменениями кода (или вовсе без таковых).
Функции, модули и пакеты поощряют повторное использование кода за счет разбиения больших программ на простые фрагменты, пригодные для многократного использования. Объектно-ориентированная природа Python позволяет пойти дальше и группировать компоненты в объекты. На самом деле все файлы в Python являются модулями, которые можно повторно использовать или импортировать в других программах на том же языке. Это облегчает обмен кодом между инженерами и поощряет его повторное использование. Один из девизов Python: батарейки — в комплекте; это означает, что для выполнения распространенных задач достаточно самого языка и вам не нужно загружать никаких дополнительных пакетов. Чтобы код при этом не был слишком раздутым, вместе с интерпретатором Python устанавливается набор модулей, известных как стандартная библиотека. Для выполнения таких рутинных действий, как обработка регулярных выражений, вычисление математических функций и декодирование JSON, достаточно добавить инструкцию import, и интерпретатор подключит необходимый код к вашей программе. Я бы назвал эту особенность Python одной из ключевых.
Наконец, для сетевых инженеров очень удобно, что разработка на Python может начаться с относительно небольшого сценария с несколькими строчками кода и вырасти в полноценную промышленную систему. Как многим из нас известно, сети часто развиваются естественным путем, без какого-то генерального плана. Язык, способный расти вместе с вашей сетью, бесценен. Вас может удивить, что язык, который нарекли языком сценариев, применяется многими передовыми компаниями в настоящих промышленных системах (список организаций, использующих Python: https://wiki.python.org/moin/OrganizationsUsingPython).
Если вам приходилось работать в условиях, когда требовалось часто переключаться между разными коммерческими платформами, такими как Cisco IOS и Juniper Junos, то вы знаете, насколько болезненным может быть переход с одного синтаксиса на другой в рамках одного проекта. Язык Python легко приспособить как для мелких, так и для крупных программ, поэтому переключение контекста некритично. В разных задачах, больших и маленьких, используется тот же код на Python!
В оставшейся части этой главы мы пройдемся по основам языка Python на случай, если вам нужно освежить свои знания. Если вы уже знакомы с ним, можете просто быстро просмотреть этот материал или сразу перейти к следующей главе.
Версии Python
Как, наверное, известно многим читателям, в последние несколько лет язык Python переходит от второй к третьей версии. Python 3 был выпущен в 2008 году, более десяти лет назад, и последняя версия имеет номер 3.10. К сожалению, Python 3 не имеет обратной совместимости с Python 2.
На момент подготовки третьего издания этой книги большая часть сообщества Python уже перешла на версию 3. На самом деле жизненный цикл Python 2 официально завершился 1 января 2020 года (https://pythonclock.org/). Последняя версия Python 2.x, 2.7, вышла больше восьми лет назад, в середине прошлого десятилетия. К счастью, обе эти версии могут сосуществовать на одном компьютере. Учитывая завершение жизненного цикла и уже состоявшееся прекращение поддержки, мы все должны перейти на Python 3. Вот пример вызова Python 2 и Python 3 на компьютере под управлением Ubuntu Linux (подробнее об использовании интерпретатора Python — в следующем разделе):
$ python2
Python 2.7.15+ (default, Jul 9 2019, 16:51:35)
[GCC 7.4.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> exit()
$ python3.7
Python 3.7.4 (default, Sep 2 2019, 20:47:34)
[GCC 7.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> exit()
С завершением жизненного цикла версии 2.7 большинство фреймворков теперь поддерживают Python 3. У Python 3 также есть множество прекрасных возможностей, таких как асинхронный ввод/вывод, который можно использовать для оптимизации кода. В примерах этой книги по умолчанию используется Python 3. Мы также стараемся указывать на различия между версиями 2 и 3, если таковые имеются.
Если какие-то конкретные библиотеки или фреймворки лучше подходят для Python 2 (например, Ansible; см. примечание ниже), это будет оговорено отдельно и в таких случаях будет использоваться Python 2. Но вообще Python 2 следует применять только там, где нет иного выхода, а в остальных случаях отдавать предпочтение Python 3.
Операционные системы
Как уже упоминалось, Python — это кросс-платформенный язык. Написанные на нем программы могут работать в Windows, Mac и Linux. На самом деле для обеспечения совместимости со всеми платформами нужно принимать определенные меры — например, следует учитывать, что Windows в путях к файлам использует обратную косую черту, — и активировать виртуальную среду в разных системах. Эта книга предназначена для DevOps, системных и сетевых инженеров, поэтому предпочтительной платформой является Linux (особенно в промышленных условиях). Код, который здесь приводится, проверен в Linux Ubuntu 18.04 LTS. Я также позабочусь о том, чтобы все примеры работали одинаково в Windows и macOS.
Подробнее о моей системе, если это вас интересует:
$ uname -a
Linux network-dev-2 4.18.0-25-generic #26~18.04.1-Ubuntu SMP Thu Jun 27
07:28:31 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
Выполнение программы на Python
Программы, написанные на Python, выполняются интерпретатором. Это означает, что интерпретатор получает ваш код, выполняет его и выводит результат. Существует несколько реализаций интерпретатора, созданных сообществом разработчиков Python, таких как IronPython и Jython. В этой книге мы используем самую популярную из них на сегодняшний день, CPython. Упоминая в этой книге Python, я имею в виду CPython (если не указано иное).
Для экспериментов с Python можно использовать интерактивную оболочку. Это особенно удобно, когда нужно быстро проверить какой-то фрагмент кода или концепцию без написания целой программы.
Обычно для этого достаточно ввести в терминале команду python:
$ python3.7
Python 3.7.4 (default, Sep 2 2019, 20:47:34)
[GCC 7.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> print("hello world")
hello world
Интерактивный режим — одна из самых полезных возможностей Python. В интерактивной оболочке можно ввести любую корректную инструкцию или последовательность инструкций и сразу же получить результат. Я обычно поступаю так при исследовании какой-то незнакомой мне возможности или библиотеки. Интерактивный режим можно также применять для более сложных задач, для выяснения особенностей поведения структур данных, например разницы между изменяемым и неизменяемым типами. И правда, зачем откладывать такое удовольствие?
Однако более традиционный способ выполнения программы на Python: сохранение ее в файл и последующий запуск с помощью интерпретатора. Так можно избежать многократного ввода одних и тех же выражений, как в случае с интерактивной оболочкой. Код на языке Python хранится в обычных текстовых файлах, как правило, с расширением .py.
В мире Unix в начало файла можно добавить так называемую строку шебанг (shebang; начинающуюся с пары символов #!), чтобы указать интерпретатор, который должен использоваться для выполнения файла. Символ # можно использовать для добавления комментариев, которые игнорируются интерпретатором. Например, файл helloworld.py содержит следующие инструкции:
# Это комментарий
print("hello world")
Его можно выполнить следующим образом:
$ python helloworld.py
hello world
$
Встроенные в Python типы данных
В Python реализована динамическая (утиная) типизация. Это означает, что язык пытается автоматически определить тип объекта при его объявлении. В интерпретатор Python встроено несколько стандартных типов:
• числа:int, float, complex и bool (подвид int с двумя возможными значениями: True и False);
• последовательности:str, list, tuple и range;
• отображения:dict;
• множества:set и frozenset;
• None: объект null.
Тип None
Тип None — это объект без значения. Он возвращается функциями, которые ничего явно не возвращают. Этот тип также используется в аргументах функций, для которых вызывающая сторона не предоставила никаких значений.
Числа
Числа в Python — это самые обычные числа. Если не считать булевы значения, все числовые типы (int, long, float и complex) имеют знак, то есть могут быть положительными и отрицательными. Тип bool является подтипом int и имеет только два возможных значения: 1 (True) и 0 (False). На практике для проверки булевых значений вместо 1 и 0 почти всегда используются True и False. Остальные числовые типы различаются по точности представления чисел; тип int в Python 3 не имеет максимального значения, а в Python 2 числа этого типа ограничены определенным диапазоном. Для чисел типа float используется представление двойной точности (64-разрядное).
Последовательности
Последовательности — это упорядоченные множества объектов с целочисленными неотрицательными индексами. В этом и следующих нескольких разделах для иллюстрации различных типов используется интерактивный интерпретатор.
Вы можете повторять те же примеры на своем компьютере.
Иногда люди удивляются тому, что тип string на самом деле является последовательностью. Но если задуматься, то строки — это и есть последовательность символов. Строки заключаются в одинарные, двойные или тройные кавычки.
Обратите внимание, что в следующих примерах виды открывающих и закрывающих кавычек должны совпадать и что тройные кавычки позволяют вводить многострочный текст:
>>> a = "networking is fun"
>>> b = 'DevOps is fun too'
>>> c = """what about coding?
... super fun!"""
>>>
Два других распространенных типа последовательностей: списки и кортежи. Список — это последовательность произвольных объектов. Их можно создавать, заключая объекты в квадратные скобки. Как и строки, списки индексируются неотрицательными целыми числами, начиная с нуля. Значения элементов списка извлекаются по индексу:
>>> vendors = ["Cisco", "Arista", "Juniper"]
>>> vendors[0]
'Cisco'
>>> vendors[1]
'Arista'
>>> vendors[2]
'Juniper'
Кортежи похожи на списки, но для их создания используются круглые скобки. Значения их элементов тоже извлекаются по индексу, но, в отличие от списков, кортежи нельзя изменять после создания:
>>> datacenters = ("SJC1", "LAX1", "SFO1")
>>> datacenters[0]
'SJC1'
>>> datacenters[1]
'LAX1'
>>> datacenters[2]
'SFO1'
Некоторые операции являются общими для всех типов последовательностей. Например, извлечение элемента по индексу или создание среза:
>>> a
'networking is fun'
>>> a[1]
'e'
>>> vendors
['Cisco', 'Arista', 'Juniper']
>>> vendors[1]
'Arista'
>>> datacenters
('SJC1', 'LAX1', 'SFO1')
>>> datacenters[1]
'LAX1'
>>>
>>> a[0:2]
'ne'
>>> vendors[0:2]
['Cisco', 'Arista']
>>> datacenters[0:2]
('SJC1', 'LAX1')
>>>
Существуют также стандартные функции, которые можно применять к последовательностям. Например, вот как можно узнать количество элементов, а также минимальное и максимальное значения:
>>> len(a)
17
>>> len(vendors)
3
>>> len(datacenters)
3
>>>
>>> b = [1, 2, 3, 4, 5]
>>> min(b)
1
>>> max(b)
5
Некоторые методы применимы только к строкам, что неудивительно. Стоит отметить, что эти методы не изменяют данные, с которыми они работают, и всегда возвращают новую строку. Если коротко, то изменяемые объекты, такие как списки и словари, можно модифицировать после их создания, а неизменяемые объекты, такие как строки, нельзя. Если вы хотите использовать результат изменения, вам необходимо принять возвращаемое значение и присвоить его другой переменной:
>>> a
'networking is fun'
>>> a.capitalize()
'Networking is fun'
>>> a.upper()
'NETWORKING IS FUN'
>>> a
'networking is fun'
>>> b = a.upper()
>>> b
'NETWORKING IS FUN'
>>> a.split()
['networking', 'is', 'fun']
>>> a
'networking is fun'
>>> b = a.split()
>>> b
['networking', 'is', 'fun']
>>>
Вот некоторые часто используемые методы для списков. Тип данных list — очень полезная структура, позволяющая объединять и последовательно перебирать несколько элементов. Например, можно составить список коммутаторов в дата-центре и применить к ним единый список доступа, перебирая их один за другим. Поскольку значение списка можно изменять после создания (в отличие от кортежей), то мы можем расширять и сокращать списки по мере выполнения программы:
>>> routers = ['r1', 'r2', 'r3', 'r4', 'r5']
>>> routers.append('r6')
>>> routers
['r1', 'r2', 'r3', 'r4', 'r5', 'r6']
>>> routers.insert(2, 'r100')
>>> routers
['r1', 'r2', 'r100', 'r3', 'r4', 'r5', 'r6']
>>> routers.pop(1)
'r2'
>>> routers
['r1', 'r100', 'r3', 'r4', 'r5', 'r6']
Списки отлично подходят для хранения данных, однако следить за местоположением конкретных элементов в них может быть немного проблематично. В таких случаях удобнее использовать отображения.
Отображения
Отображения в Python реализованы в виде словаря. Словарь напоминает мне упрощенную базу данных, так как он содержит объекты, на которые можно ссылаться по ключу. В других языках программирования эти структуры часто называют ассоциативными массивами или хеш-таблицами. Если вы уже имели дело с чем-то подобным в других языках, то уже знаете, что это довольно мощный тип, позволяющий обращаться к объектам с помощью удобочитаемых ключей. Использование ключей вместо числовых индексов поможет бедолаге, которому приходится обслуживать или отлаживать чей-то код.
Таким бедолагой можете оказаться и вы, когда вам придется в два часа ночи искать проблему в собственном коде, написанном несколько месяцев назад. Элемент словаря может быть другим сложным объектом, таким как список. Вы уже знаете, что списки создаются с помощью квадратных скобок, а кортежи — круглых, поэтому на долю словарей остаются фигурные скобки:
>>> datacenter1 = {'spines': ['r1', 'r2', 'r3', 'r4']}
>>> datacenter1['leafs'] = ['l1', 'l2', 'l3', 'l4']
>>> datacenter1
{'leafs': ['l1', 'l2', 'l3', 'l4'], 'spines': ['r1',
'r2', 'r3', 'r4']}
>>> datacenter1['spines']
['r1', 'r2', 'r3', 'r4']
>>> datacenter1['leafs']
['l1', 'l2', 'l3', 'l4']
Словари в Python — одни из моих любимых контейнеров данных, которые я использую в своих сетевых сценариях. Существуют и другие контейнеры, которые могут вам пригодиться. Множества — один из них.
Множества
Множества используются для хранения неупорядоченных коллекций объектов. В отличие от списков и кортежей множества не поддерживают порядок следования элементов и числовую индексацию. Но одна особенность делает их полезными: элементы множества никогда не повторяются. Представьте, что у вас есть набор IP-адресов, которые нужно добавить в список доступа, но проблема в том, что многие элементы в этом наборе повторяются.
Теперь подумайте, сколько строк кода потребуется написать, чтобы путем последовательного циклического перебора этих IP-адресов удалить повторяющиеся значения. Встроенный тип set позволяет сделать то же самое одной строкой. Если честно, я не так часто применяю этот тип, но в ситуациях, когда он действительно необходим, я очень рад, что он существует. Множества можно сравнивать между собой с помощью методов union, intersection и difference:
>>> a = "hello"
# Используем встроенную функцию set() для преобразования строки в множество
>>> set(a)
{'h', 'l', 'o', 'e'}
>>> b = set([1, 1, 2, 2, 3, 3, 4, 4])
>>> b
{1, 2, 3, 4}
>>> b.add(5)
>>> b
{1, 2, 3, 4, 5}
>>> b.update(['a', 'a', 'b', 'b'])
>>> b
{1, 2, 3, 4, 5, 'b', 'a'}
>>> a = set([1, 2, 3, 4, 5])
>>> b = set([4, 5, 6, 7, 8])
>>> a.intersection(b)
{4, 5}
>>> a.union(b)
{1, 2, 3, 4, 5, 6, 7, 8}
>>> a.difference(b)
{1, 2, 3}
>>>
Итак, мы рассмотрели разные типы данных. Теперь сделаем обзор операторов языка Python.
Операторы в Python
В Python есть привычные числовые операторы, такие как +, – и т.д.; обратите внимание, что деление с усечением (//, известное также как деление нацело) усекает результат по десятичной запятой и возвращает целую его часть. Оператор деления с остатком (%) возвращает величину остатка от деления нацело:
>>> 1 + 2
3
>>> 2 - 1
1
>>> 1 * 5
5
>>> 5 / 1 # возвращает float
5.0
>>> 5 // 2 # // деление нацело
2
>>> 5 % 2 # деление с остатком
1
Есть также операторы сравнения. Обратите внимание, что для сравнения предназначен двойной знак равенства, а одинарный служит для присваивания значений:
>>> a = 1
>>> b = 2
>>> a == b
False
>>> a > b
False
>>> a < b
True
>>> a <= b
True
С помощью двух популярных операторов членства можно проверить присутствие объекта в последовательности:
>>> a = 'hello world'
>>> 'h' in a
True
>>> 'z' in a
False
>>> 'h' not in a
False
>>> 'z' not in a
True
Операторы в языке Python помогают эффективно выполнять простые операции. В следующем подразделе мы посмотрим, как эти операции можно повторять с помощью средств управления потоком выполнения.
Средства управления потоком выполнения в Python
Инструкции if, else и elif делают возможным условное выполнение кода. В отличие от некоторых других языков программирования в Python для структурирования блоков используются отступы. Условные инструкции имеют следующий формат:
if условие:
делаем что-то
elif условие:
делаем что-то, если условие выполняется
elif условие:
делаем что-то, если условие выполняется
...
else:
инструкция
Вот простой пример:
>>> a = 10
>>> if a > 1:
... print("a is larger than 1")
... elif a < 1:
... print("a is smaller than 1")
... else:
... print("a is equal to 1")
...
a is larger than 1
>>>
Цикл while выполняется, пока условное выражение не вернет False, поэтому следите за этим выражением, чтобы цикл не стал бесконечным:
while условие:
делаем что-то
>>> a = 10
>>> b = 1
>>> while b < a:
... print(b)
... b += 1
...
1
2
3
4
5
6
7
8
9
>>>
Цикл for работает с любыми объектами, которые поддерживают итерации; это означает, что он совместим со всеми встроенными типами последовательностей, такими как list, tuple и string. Буква i в следующем цикле обозначает переменную цикла — вы можете выбрать любое другое имя, имеющее смысл в контексте вашего кода:
for i in последовательность:
делаем что-то
>>> a = [100, 200, 300, 400]
>>> for number in a:
... print(number)
...
100
200
300
400
Мы рассмотрели типы данных, операторы и средства управления потоком выполнения в Python. Теперь все это можно объединить в многоразовые фрагменты кода, которые называют функциями.
Функции в Python
В большинстве случаев, когда приходится копировать и вставлять какие-то фрагменты кода, их лучше разбить на автономные блоки — функции. Это делает код модульным и более простым в облуживании, облегчая его повторное использование. Для определения функций в Python используется ключевое слово def, за которым следуют имя функции и ее параметры. Тело функции состоит из инструкций, которые следует выполнить. В конце можно вернуть значение вызывающей стороне; если этого не сделать, то по умолчанию функция вернет объект None:
def имя(параметр1, параметр2):
инструкции
return значение
В следующих главах вы увидите множество разных функций, поэтому здесь мы ограничимся простым примером. В листинге ниже используются позиционные параметры, то есть первый аргумент всегда передается функции в первом параметре. На параметры можно также ссылаться по именам и определять значения по умолчанию: defsubtract(a=10,b=5).
>>> def subtract(a, b):
... c = a - b
... return c
...
>>> result = subtract(10, 5)
>>> result
5
>>>
Функции отлично подходят для объединения задач. А можно ли объединить функции в еще более крупный блок многоразового кода? Конечно. Для этого в Python есть классы.
Классы в Python
Python — язык объектно-ориентированного программирования (ООП). Объекты создаются с помощью ключевого слова class, и обычно их представляют как коллекции функций (методов), переменных и атрибутов (свойств). После определения класса можно создавать его экземпляры. Класс служит чертежом, или прообразом, последующих экземпляров.
Тема ООП выходит за рамки этой главы, поэтому приведу простой пример с определением объекта router:
>>> class router(object):
... def __init__(self, name, interface_number, vendor):
... self.name = name
... self.interface_number = interface_number
... self.vendor = vendor
...
>>>
Определив этот класс, вы сможете создать любое число его экземпляров:
>>> r1 = router("SFO1-R1", 64, "Cisco")
>>> r1.name
'SFO1-R1'
>>> r1.interface_number
64
>>> r1.vendor
'Cisco'
>>>
>>> r2 = router("LAX-R2", 32, "Juniper")
>>> r2.name
'LAX-R2'
>>> r2.interface_number
32
>>> r2.vendor
'Juniper'
>>>
Конечно, это только первое знакомство с ООП и объектами в Python. В следующих главах вы увидите еще множество примеров.
Модули и пакеты в Python
Исходный файл на языке Python можно использовать в качестве модуля. Это изначально и есть модуль, и любые функции/классы, которые в нем определены, доступны для повторного использования. Чтобы подключить модуль, используйте ключевое слово import. При импортировании файла происходит следующее.
1. Для объектов, определенных в импортируемом файле, создается новое пространство имен.
2. Импортируемый модуль выполняется.
3. В пространстве имен вызывающей стороны создается имя, ссылающееся на импортированный модуль. Это имя совпадает с именем модуля.
Помните функцию subtract(), которую вы определили в интерактивной оболочке? Чтобы сделать ее доступной для повторного использования, ее можно поместить в файл subtract.py:
def subtract(a, b):
c = a - b
return c
В каталоге, где находится файл subtract.py, можно запустить интерпретатор Python и импортировать эту функцию:
Python 2.7.12 (default, Nov 19 2016, 06:48:10)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import subtract
>>> result = subtract.subtract(10, 5)
>>> result
5
Этот прием сработал, потому что по умолчанию Python ищет модули сначала в текущем каталоге. Помните стандартную библиотеку, упоминавшуюся выше? Как вы могли догадаться, это обычные файлы на языке Python, которые используются в качестве модулей.
Пакеты позволяют объединять модули в коллекции. Это еще один уровень организации, обеспечивающий дополнительную защиту пространств имен и возможность повторного использования кода. Чтобы определить пакет, нужно создать каталог с именем, совпадающим с именем пакета, и поместить в него исходные файлы модулей.
Чтобы интерпретатор Python распознавал этот каталог как пакет, добавьте в него файл __init__.py. Его можно оставить пустым. Создадим каталог math_stuff и поместим в него файл __init__.py и модуль subtract.py из предыдущего примера:
echou@pythonicNeteng:~/Master_Python_Networking/Chapter1$ mkdir math_stuff
echou@pythonicNeteng:~/Master_Python_Networking/Chapter1$ touch math_stuff/
__init__.py
echou@pythonicNeteng:~/Master_Python_Networking/Chapter1$ tree
.
├── helloworld.py
└── math_stuff
├── __init__.py
└── subtract.py
1 directory, 3 files
echou@pythonicNeteng:~/Master_Python_Networking/Chapter1$
Теперь, чтобы обратиться к модулю, нужно указать имя пакета, а за ним через точку имя модуля. Например, math_stuff.subtract:
>>> from math_stuff.subtract import subtract
>>> result = subtract(10, 5)
>>> result
5
>>>
Как видите, модули и пакеты отлично подходят для организации больших коллекций исходных файлов и существенно упрощают повторное использование кода в Python.
Резюме
В этой главе мы рассмотрели модель OSI и наборы сетевых протоколов, такие как TCP, UDP и IP. Они действуют как уровни, определяющие порядок адресации и согласования соединения между двумя хостами. Эти протоколы разрабатывались с учетом возможности расширения, благодаря чему они почти не изменились с момента их создания. Это неординарное достижение, учитывая взрывообразное развитие интернета.
Мы также вкратце рассмотрели язык Python, в том числе встроенные типы данных, операторы, средства управления потоком выполнения, функции, классы, модули и пакеты. Python — мощный язык, готовый к использованию в промышленном окружении, который легко читается. Благодаря этому Python идеально подходит для автоматизации сетей. Сетевые инженеры могут начать с простых сценариев и постепенно переходить к использованию более продвинутых особенностей этого языка.
В главе 2 мы начнем обсуждать приемы использования Python для взаимодействия с сетевым оборудованием.
