Откуда есть пошла iptables заморская https://iximiuz.com/en/posts/laymans-iptables-101/?utm_medium=social&utm_source=tchannel #netfilter #linux #iptables #ip
Iximiuz
Illustrated introduction to Linux iptables
What are iptables chains, rules, policies, and tables? Describe iptables in layman's terms.
Что такое "операционная система Linux"? Это ядро (Linux kernel, бинарник в несколько мегабайт, хитрая прослойка между железом и софтом) и пользовательское пространство (user space, десяки или сотни мегабайт разных бинарников утилит, помогающих работать с ядром). Ядро всегда одно, отличается лишь версиями, а пользовательских пространств много (Debian, Ubuntu, CentOS, Alpine, busybox, кастомные сборки и т.п.).
Что такое "контейнеризация"? Это способ виртуализации на уровне операционной системы. В частности, это когда на запущенной Linux ОС можно положить разные пользовательские пространства в разные папки и потом запустить их выполняться. В качестве ядра будет использовано ядро родительской ОС, но программы, выполняющиеся в разных контейнерах, будут думать, что каждая из них имеет свою собственную ОСь вокруг. Изменения, сделанные в рамках одного контейнера, могут быть скрыты от остальных контейнеров и родительской ОС. Как это работает? Ядро Linux поддерживает т.н. namespaces, то есть способ изоляции ресурсов. Например, Process ID namespace позволяет иметь несколько деревьев процессов, начинающихся каждое со своего PID 1 и все это в рамках одного и того же экземпляра выполняющегося ядра. Также существуют network, mount, user ID и прочите изолированные пространства. Системный вызов clone(), являющийся основой канонического fork() принимает флаги, позволяющие изолировать новый запускаемый процесс в различных пространствах. Зачем это нужно? Здорово уметь запускать на одной железке как можно больше изолированных окружений, это круто повышает утилизацию ресурсов (альтернативный подход - запускать полностью излоированные ОСи на одной и той же железке - обычно менее эффективен [см. kata containers], правда и более безопасен).
Что такое Docker? Когда-то давно Docker был большим демоном-монолитом (и клиентом, со всеми знакомым нам CLI API), решающим комплексную задачу запуска и обслуживания контейнеров. Что же именно это значит? Когда на диске уже есть папка с набором файлов какого-либо user space, остается лишь создать нужные namespace и запустить бинарник, указанный как entry point в качестве процесса с PID 1. Но после запуска необходимо мониторить состояние контейнера, возможно перезапускать его при падении, очищать ресусры при остановке и т.п. Папку с user space на диске тоже нужно создать умело. Многие контейнеры используют на 100% схожий user space, отличаясь лишь полезной нагрузкой (кто-то хочет запускать nginx в debian:latest, кто-то свой node.js app но тоже в debian:latest и т.п.). Так как речь идет о десятках и сотнях мегабайт, неплохо бы уметь реиспользовать повторяющиеся части. Я могу выделить следующие основные куски Docker-а: 1) обслуживание жизненного цикла контейнеров (запуск, мониторинг состояния, очистка ресурсов после остановки) 2) работа с образами (images), т.е. жонглирование всеми этими большими папками, в частности загрузка их из реестров по сети 3) мощный API для запуска и запроса состояния контейнеров и образов. Так как каждый из этапов вполне себе самодостаточный, а релизить все синхронно - сложно, в какой-то момент Docker решили распилить на runc (запускатор контейнеров, консольная утилита, один запус == один контейнер), containerd (демон, делает все, чтобы runc мог запускать новые контейнеры, в частности работу с образами) и dockerd ("лицевой" демон, общающийся с containerd, чтобы мы могли исползьовать вот эти все удобные плюшки Docker-а в командной строке, через docker client). С момента распила каждый из проектов живет своей отдельной жизнью. Например, runc используется и другими менеджерами контейнеров (см. cri-o), а его интерфейс стандартизирован и он является канонической реалзиацией Container Runtime Specification.
Что такое "контейнеризация"? Это способ виртуализации на уровне операционной системы. В частности, это когда на запущенной Linux ОС можно положить разные пользовательские пространства в разные папки и потом запустить их выполняться. В качестве ядра будет использовано ядро родительской ОС, но программы, выполняющиеся в разных контейнерах, будут думать, что каждая из них имеет свою собственную ОСь вокруг. Изменения, сделанные в рамках одного контейнера, могут быть скрыты от остальных контейнеров и родительской ОС. Как это работает? Ядро Linux поддерживает т.н. namespaces, то есть способ изоляции ресурсов. Например, Process ID namespace позволяет иметь несколько деревьев процессов, начинающихся каждое со своего PID 1 и все это в рамках одного и того же экземпляра выполняющегося ядра. Также существуют network, mount, user ID и прочите изолированные пространства. Системный вызов clone(), являющийся основой канонического fork() принимает флаги, позволяющие изолировать новый запускаемый процесс в различных пространствах. Зачем это нужно? Здорово уметь запускать на одной железке как можно больше изолированных окружений, это круто повышает утилизацию ресурсов (альтернативный подход - запускать полностью излоированные ОСи на одной и той же железке - обычно менее эффективен [см. kata containers], правда и более безопасен).
Что такое Docker? Когда-то давно Docker был большим демоном-монолитом (и клиентом, со всеми знакомым нам CLI API), решающим комплексную задачу запуска и обслуживания контейнеров. Что же именно это значит? Когда на диске уже есть папка с набором файлов какого-либо user space, остается лишь создать нужные namespace и запустить бинарник, указанный как entry point в качестве процесса с PID 1. Но после запуска необходимо мониторить состояние контейнера, возможно перезапускать его при падении, очищать ресусры при остановке и т.п. Папку с user space на диске тоже нужно создать умело. Многие контейнеры используют на 100% схожий user space, отличаясь лишь полезной нагрузкой (кто-то хочет запускать nginx в debian:latest, кто-то свой node.js app но тоже в debian:latest и т.п.). Так как речь идет о десятках и сотнях мегабайт, неплохо бы уметь реиспользовать повторяющиеся части. Я могу выделить следующие основные куски Docker-а: 1) обслуживание жизненного цикла контейнеров (запуск, мониторинг состояния, очистка ресурсов после остановки) 2) работа с образами (images), т.е. жонглирование всеми этими большими папками, в частности загрузка их из реестров по сети 3) мощный API для запуска и запроса состояния контейнеров и образов. Так как каждый из этапов вполне себе самодостаточный, а релизить все синхронно - сложно, в какой-то момент Docker решили распилить на runc (запускатор контейнеров, консольная утилита, один запус == один контейнер), containerd (демон, делает все, чтобы runc мог запускать новые контейнеры, в частности работу с образами) и dockerd ("лицевой" демон, общающийся с containerd, чтобы мы могли исползьовать вот эти все удобные плюшки Docker-а в командной строке, через docker client). С момента распила каждый из проектов живет своей отдельной жизнью. Например, runc используется и другими менеджерами контейнеров (см. cri-o), а его интерфейс стандартизирован и он является канонической реалзиацией Container Runtime Specification.
Почему даже после распила на части Docker - все еще монолит? Одна из причин в том, что containerd - это демон, да еще и требующий root (ибо он запускает runc, которому нужен root для создания namespaces). Но работа с образами не требует ни демона ни тем более root. Однако, в случае Docker альтернативы (пока?) нет. Если хочется скачать какой-либо image из сети или собрать свой - придется запускать containerd. К счастью, ребятам из Red Hat это не понравилось и они решили запилить свой тулсет контейнеризации с блекджеком и барышнями. Так, запустить контейнер, используя докеро-подобный CLI можно утилитой podman (https://github.com/containers/libpod), которая под капотом использует опять же runc. Собрать свой образ или модифицировать существующий можно утилитой buildah (https://github.com/containers/buildah), которая под капотом испоьзует крутую либу https://github.com/containers/storage, которую также, например, использует демон cri-o, реализующий Kubernetes Container Runtime Interface (CRI). На мой взгляд, альтернативная (от Docker-вселенной) реализация Red Hat-ом всех этих контейнерных дел получилась куда более гибкой и структурированной. Но Docker все еще очень сильный игрок, благодаря исторически сформировавшемуся полчищу конечных пользователей.
GitHub
GitHub - containers/podman: Podman: A tool for managing OCI containers and pods.
Podman: A tool for managing OCI containers and pods. - containers/podman
Подводя итог нескольких месяцев, проведенных за изучением мира контейнеров и их оркестрирования, написал обзорную статью про экосистему контейнеризации, попробовав структурировать и описать взаимосвязи наиболее заметных проектов в области (OCI specs, runc, containerd, moby, cri-o, podman, etc) https://iximiuz.com/en/posts/journey-from-containerization-to-orchestration-and-beyond/?utm_medium=social&utm_source=tchannel
Iximiuz
Journey From Containerization To Orchestration And Beyond
What's the difference between dockerd and containerd? Why Kubernetes CRI was introduced? What is a container runtime?
Кратенько о том, как Perl и PHP не успевают за реалиями серверной разработки.
Оба языка используют схожий подход к обработке HTTP запросов. Являясь по своей натуре однопоточными (как с точки зрения реализации интерпретатора, так и из-за отсутствия примитивов синхронизации вроде mutex-ов в спецификации языков), они вынуждены назначать выделенный процесс на каждый входящий HTTP-запрос. Таким образом, для обработки 100 одновременных HTTP-запросов на одной машине необходимо иметь 100 процессов-воркеров с запущенным интерпретатором PHP или Perl. 101й запрос будет вынужден находиться в очереди на обработку, пока один из 100 активных запросов не будет завершен. Каждый процесс-воркер может занимать от сотни мегабайт до нескольких гигабайт RAM в resident set size (!), и это без учета объема обрабатываемых в запросе данных. Таким образом, если на гипотетическом сервере у нас 8 ядер и 16 GB RAM, получится запустить в среднем 16-32 воркеров (при memory utilization стремящейся к 100%, что в реальном мире недопустимо), т.е. иметь 16-32 одновременных запроса.
Оба языка используют схожий подход к обработке HTTP запросов. Являясь по своей натуре однопоточными (как с точки зрения реализации интерпретатора, так и из-за отсутствия примитивов синхронизации вроде mutex-ов в спецификации языков), они вынуждены назначать выделенный процесс на каждый входящий HTTP-запрос. Таким образом, для обработки 100 одновременных HTTP-запросов на одной машине необходимо иметь 100 процессов-воркеров с запущенным интерпретатором PHP или Perl. 101й запрос будет вынужден находиться в очереди на обработку, пока один из 100 активных запросов не будет завершен. Каждый процесс-воркер может занимать от сотни мегабайт до нескольких гигабайт RAM в resident set size (!), и это без учета объема обрабатываемых в запросе данных. Таким образом, если на гипотетическом сервере у нас 8 ядер и 16 GB RAM, получится запустить в среднем 16-32 воркеров (при memory utilization стремящейся к 100%, что в реальном мире недопустимо), т.е. иметь 16-32 одновременных запроса.
В мире микросервисов и сторонних API редкий обработчик HTTP запроса обходится без десятка [под-]запросов к соседним сервисам. Это, очевидно, заставляет воркеры ожидать I/O, вместо того, чтобы заниматься непосредственно обработкой (т.е. считать что-то на CPU). Да, сетевое взаимодействие в PHP и Perl можно сделать асинхронным (в Perl даже есть промисы), но, в общем случае, эти [под-]запросы могут иметь зависимость по данным, делающую невозможным их конкурентную отправку. Таким образом, процессы-воркеры будут значительную часть времени находиться в ожидании ответов от сторонних сервисов. Что приводит, к неприятной ситуации - overutilization of RAM and underutilization of CPU.
Для сравнения, языки с нативной поддержкой асинхронной обработки запросов (JS/NodeJS асинхронный до мозга костей, Go обычно выделяет по горутине на процесс, в Python есть asynio или gevent-подобные штуки) не требуют оверхеда в виде выделенного процесса на каждый HTTP-запрос, делая возможным иметь тысячи одновременных HTTP-запросов на одной машине. И в конечном итоге позволяют иметь более сбалансированную утилизацию ресурсов сервера.
Про аккуратность и запуск новых процессов в Linux
Когда запускается новый процесс, его потоки ввода/вывода STD(IN|OUT|ERR) определяются родительским процессом. Например, делая
Когда мы запускаем новый процесс программно (fork + exec), мы можем указать его STD(IN|OUT|ERR) файловые дескрипторы (`man dup`). Но по умолчанию форкнутый процесс просто наследует потоки родителя.
Когда мы запускаем новый процесс программно (fork + exec) и хотим дождаться его завершения, нам всего лишь нужно вызвать
Когда мы хотим прочитать то, что запущенный нами процесс печатает в свой STDOUT, можно создать pipe (`man pipe`) и указать его в качестве соответствующего файлового дескриптора для нового процесса, а затем начать читать из этого pipe в родительском процессе.
Когда процесс форкает другой процесс, а затем сам завершается, потоки, унаследованне форком не будут закрыты.
А теперь представьте ситуацию - мы запускаем (fork + exec) процесс (назовем его стартер), который в свою очередь запускает новый процесс (назовем его демон), а сам завершается печатая статус на экран. И в нашем коде мы хотим а) дождаться завершения стартера б) прочитать статус из его STDOUT.
Оказывается, если стартер-процесс не переназначил STD(IN|OUT|ERR) демона,
Вывод - стартеры должны быть умными =) А самое смешное, что вездесущий runc (https://github.com/opencontainers/runc) - пример неумного стартера. Пруф https://github.com/cri-o/cri-o/blob/8a43af20119ad8fe1ffebb4128d8938134eaaeb1/conmon/conmon.c#L1336-L1342. Это умный стартер неумного стартера.
Когда запускается новый процесс, его потоки ввода/вывода STD(IN|OUT|ERR) определяются родительским процессом. Например, делая
cat - в консоли, родительским процессом будет командный интерпретатор (`bash`, zsh, etc), а его (интерпретатора) STD(IN|OUT|ERR) уже связаны с терминалом. cat же просто унаследует тот же набор.Когда мы запускаем новый процесс программно (fork + exec), мы можем указать его STD(IN|OUT|ERR) файловые дескрипторы (`man dup`). Но по умолчанию форкнутый процесс просто наследует потоки родителя.
Когда мы запускаем новый процесс программно (fork + exec) и хотим дождаться его завершения, нам всего лишь нужно вызвать
waitid() (`man waitpid`) в родительском процессе.Когда мы хотим прочитать то, что запущенный нами процесс печатает в свой STDOUT, можно создать pipe (`man pipe`) и указать его в качестве соответствующего файлового дескриптора для нового процесса, а затем начать читать из этого pipe в родительском процессе.
Когда процесс форкает другой процесс, а затем сам завершается, потоки, унаследованне форком не будут закрыты.
А теперь представьте ситуацию - мы запускаем (fork + exec) процесс (назовем его стартер), который в свою очередь запускает новый процесс (назовем его демон), а сам завершается печатая статус на экран. И в нашем коде мы хотим а) дождаться завершения стартера б) прочитать статус из его STDOUT.
Оказывается, если стартер-процесс не переназначил STD(IN|OUT|ERR) демона,
waitpid() нам благополучно сообщит, что стартер завершился, но вот блокирующая операция чтение из pipe на нашей стороне приведет к зависанию нашего процесса до окончания выполнения (в общем случае долгоживущего) демона. И это вряд ли то, что нам нужно. Фактически, демон наследует STDOUT стартера и, несмотря на то, что стартер уже давно завершился, файловый дескриптор останется открытым в течение всей жизни демона.Вывод - стартеры должны быть умными =) А самое смешное, что вездесущий runc (https://github.com/opencontainers/runc) - пример неумного стартера. Пруф https://github.com/cri-o/cri-o/blob/8a43af20119ad8fe1ffebb4128d8938134eaaeb1/conmon/conmon.c#L1336-L1342. Это умный стартер неумного стартера.
DevOps можно сравнивать с Agile. DevOps определяет не конкретные техники, а скорее общую философию, что разработка (Dev) и эксплуатация (Ops) должны быть тесно связаны. Но не говорит, как. SRE же уместно сравнивать с конкретной Agile методологией, такой как scrum или kanban. SRE отвечает на вопрос как именно практиковать DevOps культуру в отдельно взятой компании. Вспоминается каламбур
Более того, раз уж мы упомянули Agile, то на мой взгляд, DevOps зачастую конфликтует с конкретными реализациями последнего. Если у вас в спринте (или на kanban доске) нет задач по Ops, но при этом кандидатам на собеседовании вы заявляете, что практикуете DevOps - где-то что-то не сходится. Ops должен быть представлен как равноправный аспект ежедневной работы.
https://twitter.com/iximiuz/status/1181177923610513409?s=09
class SRE implements DevOps от Google.Более того, раз уж мы упомянули Agile, то на мой взгляд, DevOps зачастую конфликтует с конкретными реализациями последнего. Если у вас в спринте (или на kanban доске) нет задач по Ops, но при этом кандидатам на собеседовании вы заявляете, что практикуете DevOps - где-то что-то не сходится. Ops должен быть представлен как равноправный аспект ежедневной работы.
https://twitter.com/iximiuz/status/1181177923610513409?s=09
Twitter
Ivan Velichko
Taxonomically, DevOps is like Agile, and SRE is like scrum (or kanban). By the way, if your Agile implementation focuses solely on development and you claim to have a DevOps culture as well, you are doing something wrong. #DevOps #SRE #agile
В рамках погружения в увлекательный мир оркестрации решил посмотреть, зачем же Kubernetes-у зависимость от Docker-а как прослойки для работы с контейнеризацией, когда Docker сам по себе вполне себе оркестратор со своим мертворожденным swarm. И оказывается она вовсе и не нужна, просто так сложилось исторически. Containerd, который отвечает именно за контейнеризацию в докере сгодится в качестве такой прослойки и для Kubernetes. И оказывается там уже несколько лет как существует формальная спецификация на API такой прослойки - Kubernetes CRI. И есть реализация прослойки даже лайтовее, чем containerd, и имя ей cri-o. В общем, решил я самообразования ради сам написать что-то подобное, так что встречайте - conman - the container manager!
https://iximiuz.com/en/posts/conman-the-container-manager-inception/
https://iximiuz.com/en/posts/conman-the-container-manager-inception/
Iximiuz
conman - [the] Container Manager: Inception
dockerd vs. containerd. What is a container manager and what is a container runtime? Learn the difference with a deep dive into a container manager implementation.
О моем восприятии Docker-а
Для тех, кто мог подумать, что я, по каким-то причинам, пытаюсь своими постами выставить Docker в негативном свете. Это далеко не так. Docker - это именно тот проект, с которого началась массовая популярность контейнеров. Docker - это исторически первая удачная упаковка разрозненных фич контейнирзации (Linux namespaces, cgroups, etc) в законченный продукт. Вклад Docker в эту область индустрии просто неоценим. Но у этой медали есть и обратная сторона... Я вижу как минимум 2 проблемы и постоянно пытаюсь обратить на них внимание коллег по цеху.
Во-первых, благодаря своей первоначальной популярности, слово _docker_ для среднестатистического программиста в какой-то момент стало синонимом слова _container_. В то время, как с технической точки зрения было бы корректно говорить "мое приложение выполняется в контейнере", люди традиционно говорят "мое приложение работает в докере". И в этом нет ничего страшного, ровно до тех пор, пока на основе этого искаженного понимания предметной области начинают приниматься технические (в частности архитектурные) решения.
Во-вторых, everything out of the box подход к проблеме контейнеризации, принесший докеру такой стремительный первоначальный успех (что может быть проще, чем yum install docker; docker build .; docker run), оказался и его слабой стороной. Docker старается решить проблемы запуска контейнеров (docker run/exec), управления образами (docker build/push/pull), оркестрирования (docker compose/swarm) и пр. Но далеко не все клиенты Docker заинтересованы сразу во всех его возможностях, в то время, как реализация всех этих фич в одном куске софта налагает как архитектурные (большой демон, управляющий другим демоном), так и операционные (демон еще и запущен под root) издержки. К счастью, кроме Docker существуют и друге проекты, решающие как целиком задачу контейнеризации, так и ее отдельные изолированные подзадачи (podman для управления контейнерами; runc для создания и запуска контейнеров; buildah и skopeo для работы с образами; containerd и cri-o как реализации container runtime для Kubernetes; Kubernetes - как оркестратор; в конце концов kata containers как альтернативный подход к изоляции). И, возвращаясь к первому пункту, для того, чтобы осмысленно начать пользоваться всеми преимуществами этих проектов, необходимо четко представлять зоны отвественности каждого из них.
На мой взгляд, самая сильная сторона Docker сейчас в его применимости в процессе разработки. Установить и начать использовать Docker на локальной машине - проще простого (для контраста попробуйте развернуть локальный Kubernetes cluster). Но если создание образов и выполнение контейнеров в Docker не будет совместимо с конечным окружением, где эти контейнеры выполняются в бою, Docker потеряет и свое последнее преимущество. Благо сейчас каждый из аспектов в этой области стараются завернуть в формальную спецификацию (OCI runtime spec, OCI image spec, Kubenetes CRI spec, etc), и Docker принимает активное участие в этих начинаниях.
Для тех, кто мог подумать, что я, по каким-то причинам, пытаюсь своими постами выставить Docker в негативном свете. Это далеко не так. Docker - это именно тот проект, с которого началась массовая популярность контейнеров. Docker - это исторически первая удачная упаковка разрозненных фич контейнирзации (Linux namespaces, cgroups, etc) в законченный продукт. Вклад Docker в эту область индустрии просто неоценим. Но у этой медали есть и обратная сторона... Я вижу как минимум 2 проблемы и постоянно пытаюсь обратить на них внимание коллег по цеху.
Во-первых, благодаря своей первоначальной популярности, слово _docker_ для среднестатистического программиста в какой-то момент стало синонимом слова _container_. В то время, как с технической точки зрения было бы корректно говорить "мое приложение выполняется в контейнере", люди традиционно говорят "мое приложение работает в докере". И в этом нет ничего страшного, ровно до тех пор, пока на основе этого искаженного понимания предметной области начинают приниматься технические (в частности архитектурные) решения.
Во-вторых, everything out of the box подход к проблеме контейнеризации, принесший докеру такой стремительный первоначальный успех (что может быть проще, чем yum install docker; docker build .; docker run), оказался и его слабой стороной. Docker старается решить проблемы запуска контейнеров (docker run/exec), управления образами (docker build/push/pull), оркестрирования (docker compose/swarm) и пр. Но далеко не все клиенты Docker заинтересованы сразу во всех его возможностях, в то время, как реализация всех этих фич в одном куске софта налагает как архитектурные (большой демон, управляющий другим демоном), так и операционные (демон еще и запущен под root) издержки. К счастью, кроме Docker существуют и друге проекты, решающие как целиком задачу контейнеризации, так и ее отдельные изолированные подзадачи (podman для управления контейнерами; runc для создания и запуска контейнеров; buildah и skopeo для работы с образами; containerd и cri-o как реализации container runtime для Kubernetes; Kubernetes - как оркестратор; в конце концов kata containers как альтернативный подход к изоляции). И, возвращаясь к первому пункту, для того, чтобы осмысленно начать пользоваться всеми преимуществами этих проектов, необходимо четко представлять зоны отвественности каждого из них.
На мой взгляд, самая сильная сторона Docker сейчас в его применимости в процессе разработки. Установить и начать использовать Docker на локальной машине - проще простого (для контраста попробуйте развернуть локальный Kubernetes cluster). Но если создание образов и выполнение контейнеров в Docker не будет совместимо с конечным окружением, где эти контейнеры выполняются в бою, Docker потеряет и свое последнее преимущество. Благо сейчас каждый из аспектов в этой области стараются завернуть в формальную спецификацию (OCI runtime spec, OCI image spec, Kubenetes CRI spec, etc), и Docker принимает активное участие в этих начинаниях.
Практикующий software engineer может эволюционировать в двух направлениях - generalist и specialist.
Specialist подразумевает постоянное углубление знаний в какой-либо одной предметной области, технологии или языке. Если вам нужно знать, как выжать максимальную производительность из Кассандры, вы идете именно к специалисту.
Generalist же скорее должен постоянно повышать свой технический кругозор и делать упор на обобщении и применении общих инженерных практик в различных областях, задачах и технологиях. Применимость тут разная, например, в стартапах, где нужно уметь все и сразу.
Мне по душе именно обобщение, так как я всегда склонен подмечать одинаковые паттерны, какую бы задачу и на каком стеке я ни решал, и переносить известные решения на новые предметные области.
Как известно, каждой задаче - свой инструмент. Всегда можно забивать гвозди микроскопом, но редко это будет эффективно. То же справедливо и для программистских задач. А у generalist-а их тьма и все они разные. Поэтому я долго думал над минимальным набором языков, эффективным как с точки зрения затрат на его изучение, так и количества областей, которые он будет покрывать. И, после почти 10 лет в индустрии, мой список выглядит так: Python, Go, C/Rust, JavaScript/TypeScript.
https://twitter.com/iximiuz/status/1191622134646411267?s=09
Specialist подразумевает постоянное углубление знаний в какой-либо одной предметной области, технологии или языке. Если вам нужно знать, как выжать максимальную производительность из Кассандры, вы идете именно к специалисту.
Generalist же скорее должен постоянно повышать свой технический кругозор и делать упор на обобщении и применении общих инженерных практик в различных областях, задачах и технологиях. Применимость тут разная, например, в стартапах, где нужно уметь все и сразу.
Мне по душе именно обобщение, так как я всегда склонен подмечать одинаковые паттерны, какую бы задачу и на каком стеке я ни решал, и переносить известные решения на новые предметные области.
Как известно, каждой задаче - свой инструмент. Всегда можно забивать гвозди микроскопом, но редко это будет эффективно. То же справедливо и для программистских задач. А у generalist-а их тьма и все они разные. Поэтому я долго думал над минимальным набором языков, эффективным как с точки зрения затрат на его изучение, так и количества областей, которые он будет покрывать. И, после почти 10 лет в индустрии, мой список выглядит так: Python, Go, C/Rust, JavaScript/TypeScript.
https://twitter.com/iximiuz/status/1191622134646411267?s=09
Twitter
Ivan Velichko
My choice of programming languages: - Python: noscripting, prototyping, data analysis - Go: server side, tools, containerization and alike - C: reading systems stuff, playing with OS capabilities - Rust: systems programming, performance-critical tools - Ja…
Mirantis купили Docker Enterprise и теперь Swarm официально мертв. Хотя пару лет поддержки для существующих клиентов, пока все не переедут на Kubernetes, все ещё обещают.
https://thenewstack.io/mirantis-acquires-docker-enterprise/
https://thenewstack.io/mirantis-acquires-docker-enterprise/
The New Stack
Mirantis Acquires Docker Enterprise
Mirantis, the cloud consulting company with OpenStack roots and a more recent focus on Kubernetes, has acquired Docker’s enterprise business,
Что можно узнать, построив flamegraph на основе вывода cloc для кодовой базы Kubernetes https://iximiuz.com/en/posts/kubernetes-repository-on-flame/. Всего за 5 минут, без регистрации и смс.
Iximiuz
Kubernetes Repository On Flame
Analyze Kubernetes codebase using cloc and FlameGraph
Бинарный мир, бинарный подход к карьере, бинарный подход к учению!
https://twitter.com/iximiuz/status/1206828106004271104
https://twitter.com/iximiuz/status/1206828106004271104
Twitter
Ivan Velichko
Two ways to learn systems / tools/ programming languages: - Shallow: read mans & try out what it can; memorize; repeat. - ✅Deep: look under the hood, understand how it’s done; gain an ability to use it for free. Pick your favorite one! #morningmadness
Подвел итоги нет, не года, но десятилетия бытия программистом на полный рабочий день (а иногда и ночь, и почти всегда - выходные и праздники). Статья получилась техническая, с фокусом на мои личные best practices, выработанные за эти годы.
https://iximiuz.com/en/posts/my-10-years-of-programming-experience/?utm_medium=social&utm_source=tchannel
https://iximiuz.com/en/posts/my-10-years-of-programming-experience/?utm_medium=social&utm_source=tchannel
Iximiuz
My 10 Years of Programming Experience
Summarizing a decade of being a full-time software developer.
Об отказоустойчиости и cloud-native
Что делать, если что-то перестало работать? Первое правило инженера - выключить и снова включить (aka перезагрузить). А теперь посмотрите, во что превращается серверная разработка. Сплошные микросервисы, состоящие из большого числа эфемерных контейнеров. Если раньше мы мерились, у кого uptime сервера больше (потому что ребут очень часто был болью), то сейчас мы соревнуемся, кому проще прибить и перезапустить контейнер. Да еще и chaos monkey выпускаем, которые только тем и занимаются, что киляют процессы, ожидая, что сервис сам себя восстановит. Получается, что индустрия начала перманентно применять правило "выключи/включи" и это должно привести к качественному увеличению отказоустойчивости наших систем. Причинно-следственная связь правда не ясна. То ли Docker с Kubernetes-ом и AWS ECS нам позволили осуществить этот переход, то ли их для того и сделали, чтобы этот переход свершился...
Что делать, если что-то перестало работать? Первое правило инженера - выключить и снова включить (aka перезагрузить). А теперь посмотрите, во что превращается серверная разработка. Сплошные микросервисы, состоящие из большого числа эфемерных контейнеров. Если раньше мы мерились, у кого uptime сервера больше (потому что ребут очень часто был болью), то сейчас мы соревнуемся, кому проще прибить и перезапустить контейнер. Да еще и chaos monkey выпускаем, которые только тем и занимаются, что киляют процессы, ожидая, что сервис сам себя восстановит. Получается, что индустрия начала перманентно применять правило "выключи/включи" и это должно привести к качественному увеличению отказоустойчивости наших систем. Причинно-следственная связь правда не ясна. То ли Docker с Kubernetes-ом и AWS ECS нам позволили осуществить этот переход, то ли их для того и сделали, чтобы этот переход свершился...
conman - [the] container manager
В рамках моего pet project по созданию Kubernetes CRI-совместимого менеджера контейнеров (читай, клона containerd или cri-o) я наконец-то добрался до первых интерактивных результатов. Использовали
https://twitter.com/iximiuz/status/1219011765943533570?s=20
О предыдущих этапах можно прочитать тут:
- conman - [the] container manager: inception https://iximiuz.com/en/posts/conman-the-container-manager-inception/
- Implementing Container Runtime Shim: runc https://iximiuz.com/en/posts/implementing-container-runtime-shim/
- Implementing Container Runtime Shim: First Code https://iximiuz.com/en/posts/implementing-container-runtime-shim-2/
В рамках моего pet project по созданию Kubernetes CRI-совместимого менеджера контейнеров (читай, клона containerd или cri-o) я наконец-то добрался до первых интерактивных результатов. Использовали
docker run -i? Это примерно о том, как реализовать такую же фичу самостоятельно. На подходе docker run -i -t 🤓https://twitter.com/iximiuz/status/1219011765943533570?s=20
О предыдущих этапах можно прочитать тут:
- conman - [the] container manager: inception https://iximiuz.com/en/posts/conman-the-container-manager-inception/
- Implementing Container Runtime Shim: runc https://iximiuz.com/en/posts/implementing-container-runtime-shim/
- Implementing Container Runtime Shim: First Code https://iximiuz.com/en/posts/implementing-container-runtime-shim-2/
Twitter
Ivan Velichko
I replicated interactive #containers 🔥 in my toy container manager! Now it's possible to attach to a running container, send in some data and stream back its stdout and stderr. One step closer to #Kubernetes CRI compatibility! PR on GitHub https://t.co/HExL5h7tj4…
В продолжение темы интерактивных контейнеров, описал свои приключения с реализацией этой функции в conman:
https://iximiuz.com/en/posts/implementing-container-runtime-shim-3/
#Go #Rust #Containers
https://iximiuz.com/en/posts/implementing-container-runtime-shim-3/
#Go #Rust #Containers
Iximiuz
Implementing Container Runtime Shim: Interactive Containers
How kubectl exec, docker exec, and docker attach commands are implemented under the hood.
И действительно, полностью согласен с результатами этого исследования. Книг про разработку или около-разработку вокруг очень много, но лишь малая часть из них по-настоящему стоящая и неустаревающая классика. Приятно осознавать, что в Top-5 выборки из исследования попали 4 книги из моего личного Top-5. А вот Clean Code by Robert Martin я, к своему стыду, все еще не прочитал.
https://threadreaderapp.com/thread/1229731043332231169.html
https://threadreaderapp.com/thread/1229731043332231169.html
Threadreaderapp
Thread by @PierreDeWulf: Back at it again. This time I wanted to know what were the most recommended programming books ever So…
Thread by @PierreDeWulf: Back at it again. This time I wanted to know what were the most recommended programming books ever So I've compiled 200 recommendations from 68 lists and came up with this top 25 most recommended programming books of all-time THR…
С этим вашим карантином работы почему-то стало больше, а свободного времени - заметно меньше. Так что создание собственного контента пришлось пока поставить на паузу. К счастью, кому-то все еще удается писать статьи. И вот одна новая и действительно классная:
"Surprising Things About Working at Well-Known Tech Unicorns"
https://blog.pragmaticengineer.com/surprising-things-about-working-at-tech-unicorns/
"Surprising Things About Working at Well-Known Tech Unicorns"
https://blog.pragmaticengineer.com/surprising-things-about-working-at-tech-unicorns/
The Pragmatic Engineer
Surprising Things About Working at Well-Known Tech Unicorns
My past few companies - Skype, Skyscanner, Uber - have been well-known companies
that I've joined in their "unicorn" phase. Unicorns are private companies that
have reached the $1B valuation - and they usually do this in less than ten
years.
All of these…
that I've joined in their "unicorn" phase. Unicorns are private companies that
have reached the $1B valuation - and they usually do this in less than ten
years.
All of these…