BeOps
37 subscribers
19 photos
3 videos
54 links
Добро пожаловать на канал BeOps! Здесь я разбираюсь с DevOps, Kubernetes и разными инфраструктурами, делая сложные задачи простыми и доступными. “Ops” в названии — это не только Operations, но и Over Powered, ведь главная цель — стать про в этих областях.
Download Telegram
Собеседование в Yandex Cloud: Консоль и траблшутинг

Хочу поделиться впечатлениями о втором собеседовании в Yandex Cloud, которое я недавно прошел. Эта секция называлась “Консоль и траблшутинг” и была посвящена навыкам работы в командной строке, пониманию операционных систем и способам диагностики различных проблем. Интересный момент — секция была без кодинга, и мне не пришлось сидеть и писать питон.

Интервьюер оказался настоящим ветераном — 12 лет работы в Яндексе, и общение сразу настроилось на легкую волну. Как и на первом этапе, все прошло в приятной атмосфере, говорили на “русско-айтишном”. Начали с привычного SSH-коннекта на яндексовскую машину, после чего я приступил к первому заданию.


Парсинг логов Nginx
Первое задание выглядело знакомо: нужно было распарсить Nginx логи. Довольно стандартная задача: нужно было посчитать все успешные (код ответа 200) и неуспешные ответы. К слову, это была уже третья такая задача за последние полгода.

Я использовал grep (https://man7.org/linux/man-pages/man1/grep.1.html) с регулярными выражениями, чтобы подсчитать успешные ответы:
grep ' HTTP/[0-9.]* 200 ' access.log | wc -l

Для неуспешных запросов я воспользовалася инверсией с grep -v, хотя еще предложил просто отнять успешные запросы от общего числа строк. Улыбнулись и поехали дальше.

Затем нужно было найти самые частые URL в логе. Мой любимый инструмент для таких задач — awk (https://linux.die.net/man/1/awk). В паттернизированном логе легко можно сосчитать когда появляется путь (типа /authenticate или /set/fflzuns), Подсчитать количество повторений каждого уникального URL (uniq -c), отсортировать его и вывести например 3 самых частых пути
awk '{print $6}' access.log | sort | uniq -c | sort -nr | tail -n 3

Определение типа системы
Следующий вопрос был интереснее: мне нужно было определить, виртуальная машина это, физическая или контейнер. Начал я с проверки файла /proc/1/cgroup, который иногда содержит информацию о контейнеризации, но файл оказался пустым. Тогда я использовал hostnamectl (https://man7.org/linux/man-pages/man1/hostnamectl.1.html), и вывод показал, что это виртуалка. Вывод выглядел примерно так:

 Static hostname: ixx
Icon name: computer-vm
Chassis: vm
Virtualization: xen

Мы дальше исследовали какие процессоры стоят на даной машине и я использовал lscpu (https://man7.org/linux/man-pages/man1/lscpu.1.html).

Диагностика производительности
Дальше по накатанной был разговор про производительность системы (top/atop/laod averages/free/vmstat), процессы (ps -ef) и виды процессов. Я не смог развернуто ответить про статус процессов (Zombie, Sleep, Uninterrupted sleep, etc.) но думаю, что однажды я пойму эту концепцию до конца.
Найдя огромные load average values и только лишь один процесс который отжирает половину ядра (потому что top показывает процент на ядро, а не на все ядра) мне пришлось ответить на кажущийся простым вопрос - так что же нагружает систему. Я предположил что это какие то интенсивные IO операции и мы макнулись в прекрасный мир iostat (https://linux.die.net/man/1/iostat). Тула предназначенная для мониторинга статистики ввода-вывода (I/O) и загрузки процессоров (CPU) в Unix-подобных операционных системах. С ее помощью я смог понять что на сервере огромный %iowait, то есть процент времени CPU, когда он ожидал завершения операций ввода-вывода.


Финал: Исследование неизвестного сервиса

Финальная задача была исследовать неизвестный сервис (назовем его mi-service), который занимался операциями записи и чтения на диск. Я использовал systemctl для проверки статуса службы, но это не дало результата, поэтому я переключился на анализ логов в /var/log/mi-service. Именно там я нашел нужную информацию о работе демона (ну вы поняли) и выяснил, какие порты он использует, с помощью netstat -tuln (https://linux.die.net/man/8/netstat).

Были еще какие-то вопросы и обсуждения, но их я уже не вспомню (или не смогу рассказать).
Вообще нравится как проходят интервью в этой компании, и я с удовольствием пойду на следующий уровень (если конечно предложат).
🔥2👍1
Оптимизация использования ConfigMap для NGINX в Kubernetes

Недавно я столкнулся с проблемой в одном из своих Kubernetes проектов, где nginx.conf в подах не обновлялся после сборки и деплоя Docker-образа, несмотря на изменения в конфигурацию. Проблема оказалась в том, что Kubernetes использовал ConfigMap для управления конфигурацией NGINX, а конфигурация в Docker-образе просто игнорировалась.

Решение проблемы и оптимизация процесса навели на размышления о том, как правильно управлять конфигурациями в Kubernetes и Docker. В этом посте я расскажу, как убрать избыточные шаги в Dockerfile и правильно работать с конфигурацией через ConfigMap.

---

Почему ConfigMap важен?


Прежде чем мы углубимся в изменения Dockerfile, давайте разберемся, зачем вообще нужен ConfigMap. Kubernetes использует ConfigMap для хранения и управления конфигурациями контейнеров. Это позволяет обновлять конфигурацию приложений без необходимости пересобирать Docker-образы и перезапускать все приложение целиком. Это особенно удобно в ситуациях, когда конфигурация может меняться в зависимости от среды (например, dev, staging, production), а сам код остается неизменным.

Проблема: Зачем копировать nginx.conf в Docker, если есть ConfigMap?

Изначально мой Dockerfile копировал nginx.conf в образ:

# Копирование конфигурационного файла nginx.conf
COPY nginx/nginx.conf /etc/nginx/nginx.conf


Но эта операция оказалась лишней, так как Kubernetes использует ConfigMap, чтобы монтировать конфигурацию поверх этой. Поэтому, независимо от того, что находилось в образе, на этапе выполнения контейнера Kubernetes заменял nginx.conf на тот, что содержался в ConfigMap.

Решение: Удаление лишнего копирования из Dockerfile

Чтобы избавиться от дублирования и оптимизировать процесс сборки, я обновил Dockerfile, удалив строку, которая копирует nginx.conf. Теперь конфигурация управляется только через Kubernetes.

Вот как выглядит финальный Dockerfile после исправлений:

FROM nginx:1.21.6

# Удаляем ненужные конфигурации, которые могут вызвать конфликты
RUN rm -f /etc/nginx/conf.d/* /etc/nginx/snippets/*

# Обеспечиваем наличие каталога для SSL-сертификатов
RUN mkdir -p /etc/nginx/ssl && chmod -R 755 /etc/nginx

# Копируем только необходимые HTML-файлы для нашего приложения
COPY html/index.html /usr/share/nginx/html/index.html
COPY html/index2.html /usr/share/nginx/html/index2.html

# Устанавливаем права на выполнение для точки входа, если это необходимо
RUN chmod +x /docker-entrypoint.sh


Почему это решение лучше?

1. Избежание дублирования конфига. Теперь конфигурация NGINX управляется исключительно через ConfigMap. Это позволяет обновлять конфигурацию без пересборки Docker-образа.

2. Упрощение CI/CD-процессов. Теперь процесс деплоя становится более гибким, так как для внесения изменений в конфигурацию NGINX не требуется заново собирать образ. Достаточно обновить ConfigMap и перезапустить поды.

3. Поддержка среды без изменения кода. ConfigMap позволяет легко адаптировать конфигурацию под разные среды (например, использовать одну конфигурацию для development и другую для production) без необходимости изменения Docker-образа.

Как обновить ConfigMap и перезапустить поды?

После внесения изменений в конфигурацию NGINX, необходимо обновить ConfigMap:

kubectl delete configmap nginx-config
kubectl create configmap nginx-config --from-file=nginx/nginx.conf


После этого достаточно перезапустить деплоймент:

kubectl rollout restart deployment nginx-deployment


Теперь NGINX будет использовать обновленную конфигурацию из ConfigMap.

---

Личный опыт

Эта ситуация показала мне, как важно избегать дублирования конфигурации между Docker и Kubernetes. Благодаря такому подходу удается упростить процесс обновления конфигурации и сделать деплой более гибким. Если в вашем проекте активно используется Kubernetes, стоит обратить внимание на использование ConfigMap для управления конфигурациями, а не встраивать их в Docker-образы.

Надеюсь, этот пост был полезен для тех, кто работает с Docker и Kubernetes и стремится оптимизировать свои CI/CD процессы.
👍4
Книга Kubernetes in Action (2nd edition by Marko Lukša, Kevin Conner) - продолжаем знакомиться с книгой.

Я продолжаю изучать K8S и углубился в вопрос контейнеров. Дальше обзор второй главы книги которая мне дала понять очень много теории из мира контейнеров.

📦 Что такое контейнеры и зачем они нужны в Kubernetes?

Контейнеры стали основой современных технологий разработки, и Kubernetes — это именно та система, которая максимально эффективно управляет приложениями в контейнерах. Однако прежде чем начать работать с Kubernetes, важно понять, что такое контейнеры и почему они так важны. Автор разбирает основные концепции контейнеров, сравнивает их с виртуальными машинами и объясняет, как Docker стал основным инструментом для их создания и управления.

🤔 Зачем нужны контейнеры?

Когда разработчики начали переходить к архитектуре микросервисов, стало понятно, что виртуальные машины (ВМ-ки) не всегда справляются с задачей. Каждый микросервис мог требовать различных версий библиотек или других зависимостей, что приводило к конфликтам при работе на одном сервере.

Виртуальные машины могли решать эту проблему, но они занимают много ресурсов и требуют индивидуальной настройки для каждой отдельной VM. В этом случае приходят на помощь контейнеры. Они предоставляют возможность запускать несколько микросервисов на одном сервере, изолируя их друг от друга, но при этом не создавая значительную нагрузку на ресурсы.

🔮 Контейнеры vs Виртуалки: в чем разница?

Контейнеры позволяют запускать приложения в изолированных средах, но при этом они работают в одном ядре операционной системы хоста, в отличие от виртуальных машин, которые требуют отдельных операционных систем для каждого экземпляра.

💪 Отмечаем преимущества:

- Контейнеры используют меньше ресурсов, так как не нуждаются в отдельной операционной системе.
- Контейнеры стартуют практически мгновенно, поскольку не требуется запуск всей системы.
- Каждый контейнер работает в изолированной среде, но использует ресурсы существующей операционной системы.

Однако, стоит учитывать, что виртуальные машины обеспечивают лучшую изоляцию, так как каждая из них имеет свое собственное ядро. Контейнеры же могут представлять риск, если уязвимость найдена в ядре ОС хоста.

🐧 Важные технологии Linux, которые делают контейнеры возможными

Это крайне интересная тема, может и по той причине, что я реально провалил интервью пару недель назад которое вел CTO компании продукты которой целиком и полностью базируются на контейнерах. Ну может и к лучшему, ведь этот фейл заставил углубиться в тему контейнеров с головой. 💩💩💩

Контейнеры существуют благодаря функциям ядра Linux. Основные технологии, которые обеспечивают работу контейнеров, включают:
👍1
- Namespaces: Эта функция позволяет каждому процессу видеть только свою собственную версию файлов, процессов и сетевых интерфейсов. Благодаря этому контейнеры изолированы друг от друга. Какие бывают типы namespaces? Вот тут я был сильно удивлен.
- Mount namespace (mnt): Отвечает за изоляцию точек монтирования файловых систем. Процесс, работающий в отдельном mount namespace, видит только те файловые системы, которые смонтированы внутри этого пространства имен. Это означает, что контейнеры могут иметь свои собственные файловые структуры, даже если они используют один и тот же хост.
- Process ID namespace (pid): Изолирует идентификаторы процессов. Каждый контейнер имеет свой собственный набор PID, что позволяет избежать пересечения с процессами других контейнеров или хоста. Процессы внутри контейнера видят только те процессы, которые принадлежат этому контейнеру, что повышает безопасность и управляемость.
- Network namespace (net): Изолирует сетевые интерфейсы, IP-адреса, порты и сетевые стеки. Это позволяет каждому контейнеру иметь свой собственный виртуальный сетевой интерфейс, а также выделенные IP-адреса и маршруты. Благодаря network namespaces контейнеры могут взаимодействовать с сетью так, как будто они работают на разных физических машинах.
- Inter-process Communication namespace (ipc): Изолирует механизмы межпроцессного взаимодействия, такие как очереди сообщений и разделяемая память. Это помогает избежать утечек данных и нежелательного взаимодействия между процессами разных контейнеров.
- User namespace (user): Позволяет контейнерам иметь собственные пользовательские и групповые идентификаторы. Это важно для обеспечения безопасности, так как процессы могут работать от имени root внутри контейнера, но быть обычными пользователями на хосте.
- UTS namespace: Отвечает за изоляцию имени хоста и доменного имени системы. Это дает контейнеру возможность иметь собственное имя хоста, создавая впечатление, что он работает на отдельной машине.
- Time namespace: Позволяет контейнеру иметь собственные настройки системного времени, что может быть полезно для тестирования и других специфических сценариев.
- Cgroups (Control Groups) - это механизм в ядре Linux, который позволяет ограничивать, отслеживать и изолировать использование ресурсов (таких как процессор, память, дисковый ввод-вывод и сеть) для каждого процесса или группы процессов. Cgroups особенно важны для контейнеров, так как они обеспечивают разделение ресурсов и предотвращают ситуации, когда один контейнер потребляет все доступные ресурсы системы. Вот как Cgroups управляют основными ресурсами:
- Ограничение использования процессора: Cgroups позволяют ограничить использование процессорного времени контейнером. Это может быть реализовано двумя способами:
- cpusets: позволяет выделить конкретные ядра процессора для использования контейнером.
- CPU shares: распределение процессорного времени между контейнерами на основе относительных весов. Например, если контейнеру A назначено 1024 «доли» CPU, а контейнеру B — 512, то A получит в два раза больше процессорного времени, чем B.
- Ограничение памяти: Cgroups позволяют задавать жесткие лимиты на использование оперативной памяти контейнером. Если контейнер превысит лимит, то Linux может начать «вытеснять» данные из памяти в swap (если он разрешен) или даже завершить контейнер для освобождения памяти. Например, можно установить ограничение, чтобы контейнер использовал не более 1 ГБ памяти.
- Ограничение сетевых ресурсов: Позволяет ограничивать использование сети контейнером. Это может быть полезно для предотвращения перегрузки сетевого интерфейса одним контейнером, если несколько контейнеров работают на одном сервере.
- Ограничение дискового ввода-вывода: Cgroups могут ограничивать скорость операций чтения и записи на диск для каждого контейнера. Это предотвращает ситуации, когда один контейнер может замедлить систему, выполняя интенсивные операции ввода-вывода.
🐳 Docker: Как он упростил работу с контейнерами

Хотя контейнерные технологии существуют уже давно, популярными они стали благодаря Docker. Docker упростил процесс создания, распространения и запуска контейнеров на разных системах.

- Images - это то, что содержит приложение и все его зависимости. Docker позволяет создавать образы, которые могут запускаться на любой системе с установленным Docker.
- Registries (e.g. Docker Hub) — это публичный репозиторий для хранения и распространения контейнерных образов.

Каждый контейнер создается на основе образа, который можно сравнить с «шаблоном» операционной системы и приложения. Эти образы состоят из нескольких слоев, что позволяет экономить ресурсы и ускорять загрузку, поскольку общие слои могут использоваться несколькими контейнерами одновременно.

Когда вы запускаете контейнер через Docker, это по сути процесс, который изолирован от других процессов на вашей системе. При этом Docker гарантирует, что контейнер видит только те ресурсы, которые ему разрешены.

🔐 Безопасность и изоляция контейнеров (Cgroups и неймспейсы были не всё!)


Несмотря на преимущества контейнеров, они не так изолированы, как виртуальные машины, что может создать проблемы с безопасностью. Однако Docker предоставляет различные механизмы для усиления изоляции:

- Capabilities: С помощью этих настроек можно ограничить привилегии, доступные контейнеру. Например, можно разрешить контейнеру изменять сетевые настройки, но запретить доступ к системному времени.
- AppArmor и SELinux: Эти инструменты обеспечивают дополнительную защиту на уровне файловой системы и процессов внутри контейнеров.

⚓️ Как Kubernetes управляет контейнерами?


Основная цель Kubernetes — автоматизировать управление контейнерами. Kubernetes обеспечивает оркестрацию контейнеров, что означает, что вы можете автоматически развертывать, масштабировать и управлять контейнерами в больших масштабах.

Используя Kubernetes, вы можете запустить сложные приложения, состоящие из множества микросервисов, при этом каждый микросервис будет изолирован в своем контейнере, что делает управление намного проще и эффективнее.

Добавлю FAQ раздел (для TL;DR публики)

1. Чем контейнеры отличаются от виртуальных машин? Контейнеры легче, быстрее запускаются и не требуют отдельных операционных систем для каждого экземпляра, в отличие от виртуальных машин.

2. Почему контейнеры быстрее виртуальных машин? Контейнеры не требуют запуска полноценной операционной системы, поэтому они стартуют практически мгновенно.

3. Как Docker изолирует контейнеры с помощью ядра Linux? Docker использует функции ядра Linux, такие как namespaces и cgroups, чтобы изолировать процессы и ресурсы для каждого контейнера.

4. Какие риски связаны с контейнерами? Главный риск — это общая операционная система для всех контейнеров. Если в ней есть уязвимость, один контейнер может потенциально повлиять на другие.

5. Как Kubernetes управляет контейнерами? Kubernetes автоматизирует развертывание, управление и масштабирование контейнеров, что делает управление большими системами с множеством микросервисов значительно проще.

Плюс, по классике, mind map 1-3 частей этой великолепной книги тут:

- https://www.dropbox.com/scl/fi/afeuq65sb7wxc2mzvpgud/Kubernetes-in-Action-till-3.pdf?rlkey=2f88qx4he5880b8vb594uv4h4&st=ltge2a9u&dl=0
❤‍🔥1
Channel photo updated
Опять этот git…Интересный проект на кистартере: Карточная колода с командами Git

Девченка из Молдовы стартовала интересный проект на Kickstarter — .dot, Dev Cheatsheet: Git. Это карточная колода, созданная для помощи разработчикам (особенно джунам) в изучении команд Git. Основная цель — сделать процесс обучения легким и увлекательным.

Что это за проект?

.dot, Dev Cheatsheet: Git — это набор из 56 карточек, каждая из которых содержит полезные команды Git, советы и минималистичный дизайн, чтобы помочь освоить этот инструмент. Основные функции Git довольно просты, но он так же может быть сложным и громоздким если мы начнем пользоваться всем функционалом. Кароче, с удобными визуальными подсказками обучение будет точно проще.

Что входит в набор?

- 16 карт с командами Git — карты с описаниями основных команд Git и иллюстрациями для быстрой ссылки и легкого запоминания.
- 2 Джокера — включают основные сведения о Git и GitHub.
- 2 дополнительных карты с паттерном — двусторонние карты с дизайном, который соответствует задней стороне колоды.
- 36 стандартных игровых карт — карты с командами Git, их определениями и примерами использования.

Почему стоит поддержать этот проект?

Если вы только начинаете изучать Git или хотите улучшить свои навыки, этот набор карт может вам пригодится, да и на вечеринке лучших друзейпрограммистов самое оно.

Цена и сроки

Начальная цена на Kickstarter составляет 20 евро. Оплата будет списана только в случае успешного завершения кампании, а доставка начнётся в декабре 2024 года.

Перейти на страницу проекта на Kickstarter
2
Неделя выдалась очень загруженной и крайне регрессивной из-за апдейтов macOS. Об этом и будет этот пост боли. 😢

Мой проект использует инфраструктуру, описанную в Terraform , с поддержкой нескольких облачных провайдеров (в данном случае — Azure и GCP). Вся конфигурация логично разделена по типам окружений и элементам инфраструктуры, типа такого:
- общие элементы которые описывают схожие для обоих облаков элементы
- GCP
- dev
- 00-folders
- 01-projects
- 02-iam
- 03-network-firewall
- 04-compute
- 0…storage, logging, gke, dnz zones, secrets, etc.
- prod
- mirror from dev
- etc.
- Azure
- dev
- prod

Особенно удобно использование terraform_remote_state, который позволяет держать снимки инфраструктуры в облачных хранилищах и использовать их для описания дальнейших ресурсов.
- https://developer.hashicorp.com/terraform/language/state/remote-state-data

Я могу описать GCP folders (о них больше инфы можно найти здесь https://cloud.google.com/resource-manager/docs/creating-managing-folders) и потом хранить ”снимок” этой части инфры в GCP bucket. Дальше, когда я буду описывать проекты которые будут находиться в этих папках (https://cloud.google.com/resource-manager/docs/creating-managing-projects), я смогу использовать terraform_remote_state. Например так

resource "google_folder" "development" {
display_name = "development"
parent = var.root_folder_id
}

resource "google_folder" "development_barebone" {
display_name = "development-barebone"
parent = google_folder.development.id
}


При переходе к описанию проектов можно извлечь идентификаторы папок через terraform_remote_state:

module "dev_bb_project" {
source = "terraform-google-modules/project-factory/google"
version = "14.3.0"

folder_id = data.terraform_remote_state.dev_folders_remote_data.outputs.development_barebone_folder_id
}


Однако радость закончилась, когда вышло обновление macOS 15.0 (Sequoia 🌲). С новой функцией управления сетевыми режимами начались серьезные проблемы с подключением к удаленному состоянию в GCP. Вот пример ошибки:

Error: error loading state: Failed to open state file at gs://infrastructure/dev/01-dev-projects/default.tfstate:
Get "<https://storage.googleapis.com/infrastructure/dev/01-dev-projects/default.tfstate>": local error: tls: bad record MAC

или

Error: Error when reading or editing Project "development-71b9":
Get "https://cloudresourcemanager.googleapis.com/v1/projects/development-71b9?alt=json&prettyPrint=false": oauth2: cannot fetch token:
Post "https://oauth2.googleapis.com/token": net/http: TLS handshake timeout

или

error loading the remote state: Failed to open state file at gs://infrastructure/dev/00-dev-folders/default.tfstate: Get "https://storage.googleapis.com/infrastructure/dev/00-dev-folders/default.tfstate":
oauth2: cannot fetch token: Post "https://oauth2.googleapis.com/token":
unexpected EOF


После долгих попыток — смены сетей, регенерации сервисных аккаунтов, повторных настроек — проблема оставалась. Лишь работа на старых машинах с macOS 14 показала, что проблема явно связана с апдейтом операционной системы. Ошибки касались TLS-соединений, OAuth-токенов и таймаутов на уровне сетевого стека. 🛜

Оказалось что Apple добавила новую функцию для управления сетевыми режимами, направленную на “улучшение” конфиденциальности при подключении к Wi-Fi сетям:
🔥2
1. Off (отключено): В этом режиме устройство использует стандартный аппаратный MAC-адрес без изменений. Этот режим обеспечивает максимальную стабильность при работе с сетевыми сервисами, но может использоваться для отслеживания устройства.
2. Fixed (фиксированный: При выборе этого режима ваше устройство использует приватный MAC-адрес, который не меняется при подключении к одной и той же сети. Это компромисс между конфиденциальностью и стабильностью. Этот режим подходит для использования с защищенными сетями (например, WPA2), и он выбран по умолчанию.
3. Rotating (ротация): В этом режиме MAC-адрес устройства изменяется каждые две недели. Это нацеленное на повышение конфиденциальности решение может вызывать проблемы с сервисами, которые требуют стабильности сетевых настроек, как в случае с Terraform. При подключении к сетям с низким уровнем безопасности этот режим выбирается по умолчанию.

Эти новые режимы оказывают влияние на такие системы, как Terraform, поскольку смена MAC-адреса или проблемы с TLS могут нарушать работу инфраструктурных сервисов. В моем случае это привело к тому, что удаленное состояние не загружалось должным образом, а подключение к GCP сервисам периодически прерывалось. Даже переключение между сетевыми режимами не помогло устранить проблему.

Решение 🧩

К счастью, решение оказалось простым: Apple выпустила обновление macOS 15.1, которое устранило проблему. Вся проблема была только в том что я потратил 3 дня на изолирование этой проблемы и документирование ресерча сей.

После обновления всё снова заработало как раньше:

Terraform has compared your real infrastructure against your configuration
and found no differences, so no changes are needed.


Этот опыт — яркий пример того, как системные обновления могут ломать даже базовые вещи. Плюс, пострадали не только Terraform-проекты: разработчики также жалуются на проблемы с SSL, VPN, и RDP. Надеюсь, Apple учтет эти нюансы в дальнейших апдейтах, чтобы избежать таких сюрпризов.

Ссылки на источники о других проблемах которые вызвала сырейший на моей памяти макос апдейт:

- macOS 15.0 SSL проблемы: https://forums.sketchup.com/t/macos-15-0-sequoia-ssl-problems/291274
- VPN и RDP проблемы после обновления: https://www.securityweek.com/cybersecurity-products-conking-out-after-macos-sequoia-update/
💘1
Третье интервью в Yandex Cloud: Python и траблшутинг

После двух успешных раундов интервью в Yandex Cloud, пришло время для третьего, и вот что мне удалось пройти.

Python задача: поиск подотрезков


Интервью началось с классической задачи по Python. Мне дали массив, состоящий из нулей и единиц, и нужно было найти максимальную длину подотрезка, состоящего из единиц, при условии удаления одного элемента. Пример:
assert maxOnes([1, 1, 0, 1]) == 3
assert maxOnes([1, 1, 0, 0, 1]) == 2

Я быстро нашел решение с использованием скользящего окна. Сначала определяем переменные для подсчета нулей и длины подотрезка. Алгоритм проходил по массиву, и если встречался второй ноль, левая граница окна сдвигалась вправо.

def maxOnes(arr):
n = len(arr)
max_len = 0
zero_count = 0
left = 0

for right in range(n):
if arr[right] == 0:
zero_count += 1

while zero_count > 1:
if arr[left] == 0:
zero_count -= 1
left += 1

max_len = max(max_len, right - left)
return max_len


Усложнение: удаление произвольного числа нулей

Далее задача усложнилась: теперь можно было удалить произвольное количество нулей. В это раннее утро, найти решение для этого усложнения было намного сложнее. Я попробовал сделать что-то подобное, но по итогу это оказалось не до конца правильным

def maxOnesWithKDeletions(arr, k):
n = len(arr)
max_len = 0
zero_count = 0
left = 0

for right in range(n):
if arr[right] == 0:
zero_count += 1

while zero_count > k:
if arr[left] == 0:
zero_count -= 1
left += 1

max_len = max(max_len, right - left + 1)
return max_len


Разбор алгоритмов

Мы обсудили временную сложность обоих решений и, что неожиданно для меня, заговорили о Big O для памяти vs процессора. Я предположил, что первое решение использует O(1) памяти, так как мы обрабатываем элементы на месте, а второе — O(n), где n — длина массива. Про сложность по процессору я не помню что ответил, но интервьюер одобрительно покачал головой.

Траблшутинг бинарников


Дальше перешли к траблшутингу, что, честно говоря, было для меня более привычно.

1. Бинарник app1 не запускается
Начал с проверки exit code с помощью echo $? — код возврата был 1, что говорит о какой-то ошибке. Далее применил strace для отслеживания системных вызовов программы. Оказалось, что бинарник пытался записать данные в файл app1.txt, но по ошибке был создан файл app11.txt. После создания правильного файла бинарник запустился.
2. Проблема с app2 (EADDRINUSE)
Программа app2 не запускалась из-за того, что порт 8080 уже был занят. Команда ss -tuln :8080 помогла найти процесс, который занимал этот порт — это оказался Nginx. Я завершил процесс с помощью sudo kill -9.
3. Ошибка “Too many open files” в app3
Лимит на количество открытых файлов в системе оказался 4097, а программа пыталась открыть 4098 файлов. С помощью ulimit -n я увеличил этот лимит до 10000, и программа успешно запустилась.

Финальная задача: очистка файлов

Последняя задача состояла в том что в папке есть почти несчетное кол-во файлов и нужно было удалить только те, что размер имеют от 2 до 4 кб. Загвоздка была в том что размеры эти были включительные, то есть я не мог указать 2K / 4K и дропнуть их. Я воспользовался man find и с подсказкой интервьюера, обнаружил что там есть флаг (который по сути больше как суффикс) с - который используется для более точного контроля над размером файлов. Я перевел 2 и 4 КБ в байты и исполнил такую команду
find /path/to/garbage -type f -size +2047c -size -3073c -delete
Файлы были успешно удалены.

После этого меня попросили удалить оставшиеся файлы в несколько потоков, для чего я использовал xargs:

ls | xargs -0 -P 4 rm -f

Итоги

Это было одно из самых насыщенных интервью по задачам и траблшутингу. Приятно, что интервьюер не просто проверял мои знания, но и подсказывал, как справиться с заданиями, что делает процесс гораздо более обучающим.

Теперь жду приглашения на следующий раунд!
😍2
Для быстрого тестирования подключения приложения в Kubernetes часто бывает полезно запустить отдельный под, созданный исключительно для проверки соединения. Одним из популярных инструментов для этого является curl, который можно использовать в одноразовом поде.

Почему?

Тестирование сетевого подключения с помощью curl в одноразовом поде полезно, когда нужно проверить доступность других подов. Например, если приложение не может достучаться до другого сервиса, или подозреваете проблемы с сетевыми правилами. Даже если сеть работает корректно, всегда стоит проверить доступность напрямую.

Пример команды

Чтобы создать под с curl для одноразовой проверки подключения, используйте следующую команду:

kubectl run --image=curlimages/curl -it --restart=Never --rm client-pod curl 10.244.2.4:8080

Эта команда создаёт под, запускает в нем curl, проверяет соединение с сервисом по IP и порту, а затем удаляет под. Это полезно тем, что под создается только для выполнения теста и сразу удаляется, не занимая ресурсы кластера.

Кейсы использования

1. Тестирование доступа между подами. Когда приложение пытается подключиться к другому сервису, но соединение по какой-то причине не проходит. Например, после настройки NetworkPolicy, нужно убедиться, что поды действительно могут общаться друг с другом. В таких случаях удобно запустить одноразовый под с curl и проверить доступность.
2. Отладка сетевых проблем. В случае, если сервис не доступен, используя одноразовый под, можно быстро проверить, проблема ли в приложении или в сетевой инфраструктуре (например, проблемный ingress, firewall, или ошибки в конфигурации сервисов).

Одноразовые поды — это простой способ проверить сетевые соединения в Kubernetes, curl в таком оказывается очень полезным на практике.
This media is not supported in your browser
VIEW IN TELEGRAM
Product Manager разруливает спринтовые таски
🤣2
Иногда приходится забрать файл из контейнера или закинуть туда что-то свое, и тут на помощь приходит команда kubectl cp. В продакшене, конечно, так особо не поиграешь, но в разработке — вполне себе полезный трюк.

Как это работает

Представьте, вы нашли баг в своем HTML-файле, который под обслуживает. Вроде бы и мелочь, но пересобирать образ лень. Вместо этого вы просто вытаскиваете файл:

kubectl cp service:/html/index.html /tmp/index.html

Правите его локально, возвращаете обратно:

kubectl cp /tmp/index.html service:/html/

И обновляете страницу.

Когда пригодится?

1. Экономия на пересборке образа: Все мы знаем, как это бывает: нашел проблему в конфигурации или статику обновить надо, а Dockerfile уже видит, как его пересобирают в десятый раз за день. Не беда! Просто скопируйте файл, поправьте его, и без лишних танцев с образами верните обратно в контейнер.
2. Лог-файлы — это золото: Логи — это как черный ящик самолета, если что-то пошло не так. Но зачем ломать голову над тем, как их достать, если можно просто взять и скачать их на локальную машину с помощью kubectl cp. Это как будто на минуточку заглянули в контейнер, чтобы забрать нужные документы.

И только один нюанс: контейнер должен дружить с tar. Если вдруг нет — что ж, будет повод его подружить!
Интересный концепт для прокрастинаторов (точно не про меня)

Наткнулся на пару полезных инструментов, которые могут облегчить жизнь тем, кто часто застревает на YouTube, теряя часы в бесполезных видео. В основе обоих решений, кажется, лежит искусственный интеллект, который помогает фильтровать ненужный контент и оставлять только то, что имеет ценность. Делюсь двумя расширениями:

1. YouTube Addiction Rehab

Это расширение для Chrome фильтрует ваши интересы и отсеивает мусорные рекомендации. Цель — оставить в ленте только полезные видео и избавить от «тёмных кроличьих нор», куда YouTube любит затягивать. Отлично подходит для тех, кто хочет осознанно управлять своим временем и не поддаваться на алгоритмические соблазны.

2. BlockTube

Более продвинутое решение для тех, кто хочет вручную настроить свой YouTube. BlockTube даёт возможность:

• Блокировать видео и каналы по названию
• Исключать комментарии на основе ключевых слов или имени автора
• Убирать YouTube Shorts и фильмы
• Прятать просмотренные видео из рекомендаций
• Настраивать фильтры по длительности роликов
• И даже отключать раздражающие всплывающие окна «Видео приостановлено, продолжить просмотр?»

Для правильных пацанов есть поддержка regex📜 и возможность интегрировать JavaScript-функции для кастомной блокировки.

Ссылки на расширения:

YouTube Addiction Rehab
BlockTube

В итоге, если YouTube всё-таки затягивает, эти инструменты могут стать отличным решением.
👀1
Phase vs Status подов в Kubernetes

При работе с Kubernetes важно понимать, как следить за состоянием и фазами подов. Сегодня разберем, как Kubernetes управляет фазами Pod’ов и состояниями контейнеров - эта инфа точно пригодится для менеджмента нод, ну или просто пройти интервью.

Фазы подов - что происходит от создания до завершения

Каждый под на протяжении своего жизненного цикла проходит несколько фаз. Эти фазы помогают быстро понять, что происходит с подом в данный момент.

Pending – под создан, но еще не запущен. Он ожидает, пока его назначат на ноду и загрузят все образы контейнеров.
Running – Хотя бы один из контейнеров пода успешно запущен.
Succeeded – Контейнеры выполнили свои задачи и завершились корректно.
Failed – По крайней мере один контейнер завершился с ошибкой, или под был неправильно сконфигурирован.
Unknown – Состояние неизвестно, так как нода перестала отвечать API-серверу.

Чтобы посмотреть, в какой фазе находится под:

$ kubectl get po pod -o yaml | grep phase

Или старым дескрайбом

$ kubectl describe po pod

Состояния подов - что происходит внутри

Фазы показывают общий статус пода, но более точная информация содержится в состояниях. Подобно состояниям нод (например, MemoryPressure и DiskPressure), поды имеют собственные статусы.

PodScheduled – назначен на ноду.
Initialized – Все init-контейнеры успешно завершили выполнение.
ContainersReady – Все контейнеры внутри пода готовы.
Ready – готов обслуживать запросы клиентов.

Каждое из этих состояний может иметь значение True или False в зависимости от текущего статуса пода. Например, если хотя бы один контейнер не готов, состояние ContainersReady будет False. Это позволяет более точно отслеживать проблемы и устранять их.

Пример

Запустим под с помощью манифеста:

$ kubectl apply -f pod.pod.yaml

После этого проверим его статус:

$ kubectl describe po pod

Если вы видите, что контейнеры не готовы или под не стартует, используйте вывод команды describe для диагностики. Например, состояние Initialized: False может указывать на проблемы с init-контейнером.

Понимание фаз и состояний подов помогает не только отслеживать работу, но и траблшутить проблемы. Используйте команды kubectl describe и kubectl get и помните: диагностика – ключ к стабильной инфраструктуре.
🔧 Траблшутинг Kubernetes: как не потеряться в лабиринте

Решение проблем в Kubernetes для меня всегда напоминает блуждание по лабиринту. С его распределённой архитектурой и множеством компонентов, найти и устранить проблему требует целого набора инструментов и методик. Это не просто — но с опытом приходит понимание, как делать это эффективно.

В этом посте я собрал несколько техник и инструментов для траблшутинга Kubernetes. Неважно, опытный ли вы пользователь Kubernetes или только начинаете — этот гайд подскажет, как сделать процесс отладки эффективным.

Хотя я стараюсь собрать советы из собственного опыта, не забывайте, что официальная документация Kubernetes остаётся основным и самым достоверным источником информации. 📜

🔄 Анализ жизненного цикла подов

Понимание того, как проходит жизненный цикл подов — главный момент в суппорте приложений. Каждый под проходит несколько этапов — от создания до завершения — и анализ этих событий помогает выявлять проблемы.

Этапы жизненного цикла пода
Про фазы пода я писал в предыдущем посте. Напомню просто, чтобы проанализировать состояние подов, используйте команды kubectl get и kubectl describe.

Евенты пода

Секция “Events” в выводе команды kubectl describe предоставляет хронологический журнал всех событий которые случились с подом. Это помогает понять, что привело к проблеме и как её устранить. Вот несколько типичных случаев, с которыми я сталкиваюсь:

- "Неназначение" на ноду:: возможно, нехватка ресурсов на Node или проблемы с планировщиком.
- Ошибки при загрузке образов: чаще всего указывают на сетевые проблемы или недоступность контейнерного реестра.
- Сбои контейнера: повторяющиеся падения контейнера можно диагностировать, изучив события перед сбоем.

📝 События и аудит-логи в Kubernetes

Kubernetes генерирует события на уровне кластера, которые дают краткий обзор происходящего. Аудит-логи, с другой стороны, полезны для обеспечения безопасности и соответствия требованиям. Они фиксируют попытки входа в систему, эскалации привилегий и многое другое.

🔍 Просмотр событий

kubectl get events чтобы просмотреть события в кластере. Вот пример:
LAST SEEN   TYPE      REASON             OBJECT                                   MESSAGE
12s Normal Scheduled pod/web-server-pod Successfully assigned default/web-server-pod to node-1
10s Normal Pulling pod/web-server-pod Pulling image "nginx:latest"
8s Normal Created pod/web-server-pod Created container web-container
7s Normal Started pod/web-server-pod Started container web-container
5s Warning BackOff pod/db-server-pod


Аудит-логи Kubernetes

Аудит-логи записывают все API-запросы, поступающие в Kubernetes API-сервер, включая информацию о пользователе, выполненное действие и его результат. Широко используется в компаниях которым важна безопасность кластера. Пример записи в аудит-логе:
{
"kind": "Event",
"apiVersion": "audit.k8s.io/v1",
"level": "Metadata",
"auditID": "12345",
"stage": "ResponseComplete",
"requestURI": "/api/v1/namespaces/default/pods",
"verb": "create",
"user": {
"username": "admin",
"groups": ["system:masters"]
},
"sourceIPs": ["192.168.1.1"],
"objectRef": {
"resource": "pods",
"namespace": "default",
"name": "web-server-pod"
},
"responseStatus": {
"metadata": {},
"code": 201
},
"requestReceivedTimestamp": "2024-01-01T12:00:00Z",
"stageTimestamp": "2024-01-01T12:00:01Z"
}
📊 Дашборды
Когда работаю с кластером, пользуюсь инструментом для мониторинга - Lens. Это удобный GUI для Kubernetes, который помогает отслеживать состояние кластеров, управлять ресурсами и проводить диагностику.
Lens — это кросс-платформенное приложение с открытым исходным кодом, которое позволяет подключаться к Kubernetes-кластерам и управлять ими через визуальный интерфейс. По сути, Lens — это дашборд, который упрощает взаимодействие с Kubernetes, предлагая все возможности kubectl, но с визуализацией и множеством дополнительных функций для удобства. Загрузить приложение можно с официального сайта.


Траблшутинг Kubernetes требует понимания его компонентов и внимательного анализа событий. Используя инструменты, такие как kubectl get, kubectl describe, события, аудит-логи и дашборды можно эффективно находить и решать проблемы. 😵‍💫
System Design интервью: проектировал Instagram📸

Недавно на system design интервью (https://yandex.ru/jobs/pages/devops_cloud) мне выпало задание спроектировать сервис для обмена фотографиями, чем-то напоминающий Instagram. Конечно, я уже где-то такое видел (но, честно говоря, мало что запомнил), и мне почти профессионально удалось проговорить все ключевые моменты дизайна. Потом я поработал над архитектурой, которую можно увидеть на скриншоте — тут уже не так “профессионально”, но всё равно сносно. Давайте погрузимся в детали проектирования и самого интервью.

Основные функции

Начал я с разбора основных сервисов и их функций. Вот ключевые моменты:

- 📤 Загрузка фотографий.
- 🔔Подписки и фолловеры.
- 📜Построение персонализированных лент новостей.

Также важно было учесть масштаб:

- 500M DAU (ежедневно активных пользователей).
- 1B MAU (ежемесячных активных пользователей).
- 2.5B общих пользователей.
- 50B фотографий в системе.
- 50M фотографий загружается каждый день, каждая размером 100 KB.

1. Как грузить фотки?

Начали с самого главного — как же юзеры будут загружать фотографии? Первый вопрос был: как эффективно хранить и обрабатывать такие объёмы, учитывая их стремительный рост? Мой выбор пал на облачные хранилища типа AWS S3 — оно отлично масштабируется и помогает справляться с такими объёмами данных.

Каждая загруженная фотка попадает в основное хранилище, а для ускорения доступа — кешируется через Redis. Система простая: Redis сидит между базой данных, где хранятся фотографии, и API-шлюзом. Когда пользователь запрашивает фотку, сперва проверяется кеш. Если там её нет — идём в базу данных. Конечно, всё работает на хешах, потому что гонять блобы через сеть в таком объёме — задача почти фантастическая.

Дальше добавил механизмы репликации данных для отказоустойчивости, чтобы, если что-то где-то упало, фотки не исчезли в цифровой бездне.

2. Как организовать шардирование? 🪨

С такими данными игнорировать шардирование просто непрвильно. Поэтому следующий вопрос — как распределить пользователей по шардам? Я использовал хеширование по userId для обычных пользователей, чтобы их данные равномерно распределялись. Это не только облегчает масштабирование, но и позволяет системе дышать спокойно. VIP-пользователи 👑 которые генерируют кучу трафика, были выделены в отдельные шарды. Это не только изолировало их от остальных пользователей, но и снизило нагрузку на общую систему.

3. Лента новостей (Feed)

Теперь самый важный момент — как обеспечить низкую задержку при генерации ленты новостей? Используем асинхронную обработку: при публикации новых фотографий от VIP пользователей фоны ленты не должны тормозить. Для этого была введена система обработки данных с использованием очередей (типа Kafka) которая позволила фоново обновлять ленты пользователей. Кроме того, все непрямые задачи (статистика и маркетинг) тоже вынес в асинхронные процессы, чтобы основной канал оставался чистым, а пользователь всегда получал контент с приоритетом. Аналитические данные мы собираем в фоновом режиме, так что цифры у нас есть, а пользователи счастливы.

4. Fault tolerance и балансировка нагрузки 🤹

Для обеспечения доступности сервиса 24/7 логично было использовать load balancer на входе. Я также предусмотрел развёртывание нескольких дата-центров с асинхронной репликацией данных и добавил CDN. Теперь пользователи из Канады не ждут свои фотки из России как-будто они грузятся по почте.

5. Безопасность и масштабируемость 🔒

Система хранения метаданных (комментарии, лайки, подписки) была спроектирована с использованием PostgreSQL с мастер-слейв репликацией для отказоустойчивости. Кеширование в Redis также ускоряет доступ к часто запрашиваемым данным.

Итоги

Вот ключевые решения, которые я принял:

- Шардирование пользователей с выделением VIP в отдельные шарды.
- Использование CDN для ускорения доставки фотографий.
- Кеширование данных и асинхронная генерация ленты новостей.
- Репликация данных для повышения отказоустойчивости.

Все эти меры помогли создать систему, способную выдерживать огромные нагрузки, масштабироваться и минимизировать задержки.
Как выбирать визы и контракты для работы в США?

Недавно получил письмо от HR, который набирает специалистов из разных областей на контракты в США.
Are you looking for Next opportunity in U.S.A?
Hiring Talent specialized from most of the Technologies like Java,.Net,Devop?s,AWS,Azure,Sharepoint,Mulesoft,Salesforce,Python,BI,MS CRM,RPA,ML etc..
Exclusively working on E3 Visa /TN Visa/E3 Transfer /TN transfer/H1B Transfers/EAD?s/OPT?s/C2C/GC process along with the Project in USA.


Разные визы, условия найма, бесконечные термины и аббревиатуры — кажется, проще стать DevOps, чем разобраться в этих визах. Попробуем прояснить, какие существуют визы и контракты для работы в США, и кому какие могут подойти.

Визы: типы и особенности

1. E-3 Visa 🇦🇺 для граждан Австралии.
Кому подходит: специалистам из Австралии, желающим поработать в США по своей специальности.
Длительность: сначала дается на два года, с возможностью неограниченного продления по два года.
Пример: австралийский инженер или DevOps специалист, работающий в крупной компании, может легко продлевать визу без необходимости возвращения домой.

2. TN Visa 🇲🇽 🇨🇦 для граждан Канады и Мексики.
Кому подходит: подходит для определенных профессий, перечисленных в NAFTA USMCA, и доступна гражданам Канады и Мексики.
Длительность: выдается на три года, с возможностью продления.
Пример: канадский Data Scientist, работающий над крупными аналитическими проектами, может получить TN визу и продлевать ее на протяжении нескольких лет.

3. H-1B Visa 🫅для высококвалифицированных специалистов.
Кому подходит: специалистам в области требующих специальных навыков (смотреть ниже ⬇️︎).
Длительность: обычно действует три года, с возможностью продления до шести лет.
Пример: DevOps инженер из Индии может получить H-1B визу, работая на американскую компанию, с перспективой продления до шести лет.

4. EAD 💼 (Employment Authorization Document) для всех подряд.
Кому подходит: этот документ предоставляет право на работу многим категориям, включая супругов H-1B держателей и участников программы DACA.
Пример: супруг специалиста с H-1B визой может работать в США благодаря EAD, что позволяет семье получать два дохода.

5. OPT 🧑‍🎓 (Optional Practical Training) для студентов.
Кому подходит: выпускникам американских университетов по F-1 визе для получения практического опыта.
Длительность: до 12 месяцев, с возможностью продления на 24 месяца для STEM специальностей.
Пример: выпускник по специальности Data Engineering может работать в США по OPT, а затем попытаться получить H-1B визу.

Типы контрактов: C2C и Green Card Process

1. C2C 🤝 (Corp-to-Corp) контракт между компаниями (смотреть следующий пост об этом виде контракта ⬇️︎).
Кому подходит: подходит для специалистов, работающих на себя и желающих быть гибкими в выборе проектов.
Пример: опытный DevOps специалист (я) с собственным LLC (не я) может заключить контракт C2C с американской компанией, выбирая проекты по своему вкусу.

2. GC Process 🟩 (Green Card Sponsorship) путь к ПМЖ.
Кому подходит: подходит тем, кто планирует оставаться в США на долгий срок.
Пример: специалист, работающий на крупную корпорацию, может пройти процесс получения грин-карты через спонсорство компании и стать постоянным жителем США.



Дальше будет про H-1B.
H-1B Visa: а я обладаю "специальными" навыками
Справедливый вопрос: какие навыки считаются “специальными” для IT?
В контексте H-1B, под специальными навыками понимаются те, которые сложно заменить без специальных знаний и обучения. Далее несколько направлений, которые подходят под H-1B, но "уникальность" таких знаний для меня под вопросом.

1. Программирование и разработка ПО — владение языками программирования, такими как Java, Python, C++, JavaScript, Go и другие, часто требуется для разработчиков ПО, мобильных приложений, веб-разработчиков и архитекторов систем. Ну ок.
2. Работа с облачными технологиями — навыки работы с AWS, Microsoft Azure, Google Cloud и другими облачными платформами востребованы для инженеров DevOps, архитекторов облачных решений, специалистов по виртуализации и автоматизации инфраструктуры. Ну да, каждый день я уникален.
3. Инженерия данных и аналитика — включает умения работать с Big Data платформами (например, Hadoop, Apache Spark), а также знание языков SQL, R и Python. Эти навыки требуются для data engineers, data scientists, аналитиков больших данных и специалистов по BI (бизнес-аналитика). Ну таких тоже пруд-пруди.
4. Кибербезопасность — специалисты по информационной безопасности должны обладать знанием сетевой безопасности, управлением рисками, и часто сертификациями, такими как CISSP или CEH, чтобы защищать корпоративные данные и инфраструктуру. Тут могу согласиться, стек серьезный.
5. Машинное обучение и искусственный интеллект — знание алгоритмов, математических методов и таких технологий, как TensorFlow, PyTorch, применяется в роли ML-инженеров, специалистов по ИИ и data scientists. Навык хороший, довольно уникален.
6. Разработка и администрирование баз данных — опыт работы с реляционными и NoSQL базами данных, такими как Oracle, MySQL, MongoDB, востребован для администраторов баз данных и backend-разработчиков. Это спрашивают на базовых джуниор интервью.

Так, H-1B в IT-сфере - в чем подвох?
Для получения H-1B визы, работодатель должен подтвердить ☑️, что должность требует специфических технических знаний. На практике это означает, что компания должна обосновать, что вакансия предназначена для высококвалифицированного специалиста с конкретными навыками. Например, позиции DevOps, разработчиков на Java или аналитиков данных должны попадать под эту категорию, так как их функции требуют детальных технических знаний, понимания инструментов и платформ, а также опыта работы с конкретными языками программирования или технологиями.

Каждый из этих вариантов найма и виз предлагает свою степень гибкости, сроков и условий. Например, если вы хотите на долгий срок обосноваться в США, стоит задуматься о процессе получения грин-карты. Если же вам важна свобода выбора проектов, то C2C — отличное решение, но требует финансовой самостоятельности (или грамотного бухгалтера).


Дальше будет про C2C.
Работать по Corp-to-Corp (C2C) в США 👔
Интересный вариант, как мне и другим cold-plunger'ам показался. Выглядит как реальный и гибкий вариант для IT-специалистов, особенно если вы планируете работать как независимый консультант или фрилансер на проекты.
C2C контракт заключается между двумя юридическими лицами. Обычно это означает, что у вас есть зарегистрированная компания (например, LLC в Канаде), и вы заключаете договор с американской компанией на выполнение услуг через ваше юридическое лицо, а не как индивидуальный подрядчик.

Основные преимущества C2C
1. Финансовая гибкость 💸: можно получать более высокий доход, так как у вас нет налогов на заработную плату, и вы сами управляете налоговыми обязательствами своей компании.
2. Контроль над проектами и графиком 🛂: C2C контракты предполагают большую независимость в проектной деятельности, и вы можете работать одновременно с несколькими клиентами.
3. Простота доступа к проектам в США 🗽: Поскольку в C2C вы работаете как компания, а не как физическое лицо, американские компании нередко охотнее заключают такие контракты с международными специалистами.

Как подготовиться к работе по C2C

1. Зарегистрировать компанию (LLC) как отдельное юридическое лицо. Это может быть простая корпорация или LLC в Канаде, которая будет выступать стороной договора с клиентом из США. Регистрация корпорации в Канаде достаточно проста и можно ее сделать онлайн.
2. Открыть банковский счет для бизнеса (после регистрации LLC) - это корпоративный счет в банке, чтобы принимать платежи по контракту, избегая смешивания личных и деловых финансов.
3. Оформить договор с американской компанией: После выбора проекта американская компания оформляет контракт с вашей корпорацией. В контракте указываются все условия, включая сроки проекта, оплату и конкретные обязанности вашей компании.
4. Рассмотрите необходимость рабочей визы или поездок в США: Если проект требует регулярных поездок в США, может понадобиться виза TN или B-1 (Business Visitor). Однако, если работа полностью удаленная, виза может не потребоваться, поскольку все операции осуществляются через вашу канадскую компанию.

C2C налоги и финансовые аспекты
- Налоговые обязательства в Канаде 🏦: Вы платите налоги как канадское юридическое лицо и можете вычитать бизнес-расходы (оборудование, программное обеспечение, аренда офиса и т.д.).
- Отчеты для IRS (США) 📝: Так как вы будете eработать с американскими клиентами, возможно, вам потребуется оформить форму W-8BEN-E для подтверждения статуса иностранного юридического лица. Эта форма помогает избежать двойного налогообложения в США, так как Канада и США имеют налоговое соглашение.

Пример
Представим, что вы DevOps инженер в Канаде с собственной компанией. Американская компания предлагает вам контракт на разработку и поддержку CI/CD процессов в своих проектах. Вы заключаете C2C контракт через свою LLC, работаете удаленно, самостоятельно выписываете инвойсы, получаете оплату на корпоративный счет и оплачиваете налоги по канадскому законодательству.
—-

Подытожим
Каждый из этих вариантов найма и виз предлагает свою степень гибкости, сроков и условий. Например, если вы хотите на долгий срок обосноваться в США, стоит задуматься о процессе получения грин-карты. Если же вам важна свобода выбора проектов, то C2C — отличное решение, но требует финансовой самостоятельности.