Упаковываем php приложение в helm chart и деплоим в k8s. Часть 1
Мы базово подготовили кластер к работе и теперь нам не терпится задеплоить туда наш код.
Для этого мы сделаем helm chart в репозитории приложения, настроим там деплой во внутреннее хранилище пакетов gitlab и внесем изменения в инфраструктурный репозиторий кластера, чтобы наш чарт устанавливался и обновлялся в кластере при пуше в гитлаб.
Начнем:
1. Заходим в гитлаб, в репозиторий приложения. Там открываем раздел Settings -> Repository -> Deploy tokens. Создаем три токена:
2. В репозитории приложения создаем папку .helm. Тут будет лежать наш helm chart. Он состоит из следующих файлов:
2.1. Chart.yaml - здесь лежит описание чарта, его тип, версия чарта и версия приложения. Мы будем в дальнейшем использовать только версию чарта
2.2. values.yaml - здесь хранятся дефолтные настройки чарта. Мы будем переопределять при деплое image, из которого будет деплоится приложение и image tag. Также обратите внимание на параметр
2.3. .helmignore - думаю понятно для чего этот файл. Взят дефолтный из конструктора чарта (Команда
2.4. templates/deployment.yaml - здесь описана базовая сущность куба - deployment. В этом файле описывается в скольких репликах запускать приложение, из какого образа, на каком порту контейнер принимает подключения, healthchecks и ограничения по ресурсам, на основе которых куб решает на какую ноду деплоить приложение. Все значения тут - плэйсхолдеры, которые подставляются при установке чарта из
2.5. templates/service.yaml - создается также базовая сущность k8s - service. Тут мы говорим кластеру, что данный сервис принимает подключения на
2.6. Ну и наконец templates/ingress.yaml - настраиваем
3. Возвращаемся в gitlab и в разделе Settings -> CI/CD -> Variables создаем две переменные
4. Правим .gitlab-ci.yml. Тут у нас будет три шага:
4.1. Собираем production образ приложения (На самом деле не совсем production, пока мы не переопределям
4.2. Пушим в gitlab registry. Тэг ставим по тэгу текущего коммита в сокращенной форме
4.3. Подменяем адрес image и image tag в
5. Закидываем изменения в гитлаб, ждем выполнения pipeline. В секции Deploy -> Package registry проверяем наличие helm chart, в секции Deploy -> Container registry должен лежать образ приложения с нужным тэгом.
Мы базово подготовили кластер к работе и теперь нам не терпится задеплоить туда наш код.
Для этого мы сделаем helm chart в репозитории приложения, настроим там деплой во внутреннее хранилище пакетов gitlab и внесем изменения в инфраструктурный репозиторий кластера, чтобы наш чарт устанавливался и обновлялся в кластере при пуше в гитлаб.
Начнем:
1. Заходим в гитлаб, в репозиторий приложения. Там открываем раздел Settings -> Repository -> Deploy tokens. Создаем три токена:
app-example-pull с правом read_registry, helm с правом read_package_registry и helm-push с правом write-package-registry. При создании токенов будут сгенерированы пароли для каждого. Запишите их в надежное хранилище паролей. Далее они нам понадобятся.2. В репозитории приложения создаем папку .helm. Тут будет лежать наш helm chart. Он состоит из следующих файлов:
2.1. Chart.yaml - здесь лежит описание чарта, его тип, версия чарта и версия приложения. Мы будем в дальнейшем использовать только версию чарта
2.2. values.yaml - здесь хранятся дефолтные настройки чарта. Мы будем переопределять при деплое image, из которого будет деплоится приложение и image tag. Также обратите внимание на параметр
ingress.host. По этому адресу будет доступно приложение из браузера. 2.3. .helmignore - думаю понятно для чего этот файл. Взят дефолтный из конструктора чарта (Команда
helm create)2.4. templates/deployment.yaml - здесь описана базовая сущность куба - deployment. В этом файле описывается в скольких репликах запускать приложение, из какого образа, на каком порту контейнер принимает подключения, healthchecks и ограничения по ресурсам, на основе которых куб решает на какую ноду деплоить приложение. Все значения тут - плэйсхолдеры, которые подставляются при установке чарта из
values.yaml и переопределенных значений. 2.5. templates/service.yaml - создается также базовая сущность k8s - service. Тут мы говорим кластеру, что данный сервис принимает подключения на
80 порту и перенаправляет трафик на поды (Еще одна базовая сущность куба, по сути стручок с контейнерами; пока у нас в стручке будет один контейнер) приложения на порт 8080. На какие именно поды отправлять трафик задается в секции selector. Тут указываются labels, которые заданы в deployment, чтобы сервис и поды могли друг-друга найти.2.6. Ну и наконец templates/ingress.yaml - настраиваем
ingress так, чтобы трафик приходящий на домен app-example.local перенаправлялся на наш сервис, который в свою очередь зарулит все в нужные контейнеры.3. Возвращаемся в gitlab и в разделе Settings -> CI/CD -> Variables создаем две переменные
HELM_USER со значением helm-push и HELM_PASS с паролем этого Deploy token, его мы создавали на первом шаге. Переменную с паролем помечаем как masked, чтобы в логах pipeline не светилось ее значение.4. Правим .gitlab-ci.yml. Тут у нас будет три шага:
4.1. Собираем production образ приложения (На самом деле не совсем production, пока мы не переопределям
APP_ENV, будем делать это позже, когда подключим БД)4.2. Пушим в gitlab registry. Тэг ставим по тэгу текущего коммита в сокращенной форме
4.3. Подменяем адрес image и image tag в
values.yaml чарта. К сожалению, сам helm при запаковке в архив подменять значения не умеет. Это возможно только при установке, но мы будем ставить чарт автоматом через flux. Далее добавляем helm repo, запаковываем чарт, при этом подменяя последнюю цифру версии на ID текущей Job`ы гитлаба (Это нужно для того, чтобы flux автоматически обновлял приложение в кластере). Ну и пушим архив в гитлаб. На машине с gitlab-runner должен быть установлен helm и плагин cm-push. Плагин устанавливается след. командой helm plugin install https://github.com/chartmuseum/helm-push под юзером gitlab-runner5. Закидываем изменения в гитлаб, ждем выполнения pipeline. В секции Deploy -> Package registry проверяем наличие helm chart, в секции Deploy -> Container registry должен лежать образ приложения с нужным тэгом.
Упаковываем php приложение в helm chart и деплоим в k8s. Часть 2
6. Осталось настроить только выкатку этого добра через flux.
Тут все практически аналогично установке
Из отличий:
6.1. Файл image-pull-secret.yaml - тут мы создаем secret (сущность куба для хранения чувствительных данных) для скачивания образов приложения из gitlab container registry. Тут необходимо в секцию
6.1.1. Логинимся в registry с помощью команды
6.1.2. Делаем
6.1.3. Удаляем папку
6.2. В файле hr-app.yaml тоже есть создание секрета. Но тут мы уже напрямую указываем логин
Все эти секреты нужны, чтобы скачивать образы приложения и helm chart из приватных хранилищ гитлаба. Так как это у нас инфраструктурный репозиторий - я считаю допустимым тут указывать секреты прямо в репо. Возможно есть более правильные способы создать секреты и не пушить их в репозиторий, но я пока о таких не знаю.
7. Пушим в инфраструктурный репозиторий наши изменения, смотрим статус
8. С помощью команды
Если все окей добавляем в локальный DNS или
Открываем браузер и проверяем, что приложуха отвечает по нужному домену. Должна быть надпись
Фуф, мы молодцы. В след. посте прикрутим к этому всему добру SSL сертификат, получаемый через
6. Осталось настроить только выкатку этого добра через flux.
Тут все практически аналогично установке
metallb и ingress-nginx. Смотрим этот коммит.Из отличий:
6.1. Файл image-pull-secret.yaml - тут мы создаем secret (сущность куба для хранения чувствительных данных) для скачивания образов приложения из gitlab container registry. Тут необходимо в секцию
.dockerconfigjson вставить строку, подготовленную след. образом:6.1.1. Логинимся в registry с помощью команды
docker --config deploy login registry.example.com. Используем токен app-example-pull, созданный на первом шаге6.1.2. Делаем
base64 deploy/config.json, получаем искомую строку6.1.3. Удаляем папку
deploy6.2. В файле hr-app.yaml тоже есть создание секрета. Но тут мы уже напрямую указываем логин
helm и пароль для этого токена. Все эти секреты нужны, чтобы скачивать образы приложения и helm chart из приватных хранилищ гитлаба. Так как это у нас инфраструктурный репозиторий - я считаю допустимым тут указывать секреты прямо в репо. Возможно есть более правильные способы создать секреты и не пушить их в репозиторий, но я пока о таких не знаю.
7. Пушим в инфраструктурный репозиторий наши изменения, смотрим статус
flux get all -A. Как только везде будет Ready = True - переходим к след. шагу.8. С помощью команды
kubectl get ing -n app-example проверяем настроен ли наш ingress для работы с доменом app-example.local. Видим что-то подобное:NAME CLASS HOSTS ADDRESS PORTS AGE
app-example-ingress nginx app-example.local 192.168.0.200 80 47h
Если все окей добавляем в локальный DNS или
/etc/hosts своей машины соответствующую запись. У меня это 192.168.0.200 app-example.localОткрываем браузер и проверяем, что приложуха отвечает по нужному домену. Должна быть надпись
Welcome to example application. Фуф, мы молодцы. В след. посте прикрутим к этому всему добру SSL сертификат, получаемый через
letsencrypt. Домен тоже придется сделать настоящий)👍4
Опрос в догонку. Сложность постов возрастает, объяснить все в маленьком количестве текста становится сложно. Нужны ли видео на ютубе, где все вышеизложенное будет наглядно показано?
Anonymous Poll
52%
Нужны
35%
И текстом норм
13%
Мне все равно
В декабре буду выступать с докладом на PHP Russia 2024!
Расскажу как подготовить своё PHP приложение к работе в облаке.
Если кто-то планирует быть оффлайн - с радостью пообщаюсь.
Расскажу как подготовить своё PHP приложение к работе в облаке.
Если кто-то планирует быть оффлайн - с радостью пообщаюсь.
🎉7👍5🔥5
Шифрованные секреты в инфраструктурном репозитории
Мне не давала покоя мысль о том, что в нашем инфраструктурном git репозитории не должно быть секретов в открытом виде. Все best practice твердят нам это. Я почитал доку и сейчас мы будем делать шифрованные секреты в репозитории, чтобы затем они расшифровывались в кластере и попадали в нужное место. Я выбрал вариант с использованием gpg и утилиты sops.
Приступим:
1. Заходим на мастер машину нашего кластера и создаем там gpg ключ
2. Получаем отпечаток нашего ключа
Видим следующее:
3. Сохраняем его в env переменную
4. Экспортируем ключ в кластер
5. Экспортируем публичную часть ключа и сохраняем его в репозитории в файл cluster/flux-system/.sops.pub.asc
6. Удаляем ключи с мастер машины кластера. Они тут нам больше не нужны
7. Теперь пришло время зашифровать наши секреты и настроить flux так, чтобы он их расшифровывал и в расшифрованном виде сохранял в кластер. Первым делом добавляем в 03-app.yaml следующие строчки:
Здесь мы указываем кластеру имя секрета, где хранится секретный ключ gpg, который будет использоваться для расшифровки файлов из репозитория
8. Из файла hr-app.yaml убираем секрет и кладем его в
9. Импортируем публичную часть ключа уже на нашей рабочей машине
10. Ставим утилиту sops. И шифруем наши секреты
Получаем зашифрованные версии наших конфигов секретов. helm-pull-secret.yaml и image-pull-secret.yaml
11. Вот и все. Пушим в репо и проверяем статус командой
Для того, чтобы проверить все ли работает - можно запустить деплой приложения в гитлабе и убедиться, что все по прежнему деплоится и функционирует. Конечно это нужно было сделать с самого начала и у нас в истории коммитов остались открытые секреты, но больше мы так делать не будем.
Stay tuned ;)
Мне не давала покоя мысль о том, что в нашем инфраструктурном git репозитории не должно быть секретов в открытом виде. Все best practice твердят нам это. Я почитал доку и сейчас мы будем делать шифрованные секреты в репозитории, чтобы затем они расшифровывались в кластере и попадали в нужное место. Я выбрал вариант с использованием gpg и утилиты sops.
Приступим:
1. Заходим на мастер машину нашего кластера и создаем там gpg ключ
export KEY_NAME="cluster.yourdomain.com"
export KEY_COMMENT="flux secrets"
gpg --batch --full-generate-key <<EOF
%no-protection
Key-Type: 1
Key-Length: 4096
Subkey-Type: 1
Subkey-Length: 4096
Expire-Date: 0
Name-Comment: ${KEY_COMMENT}
Name-Real: ${KEY_NAME}
EOF
2. Получаем отпечаток нашего ключа
gpg --list-secret-keys "${KEY_NAME}"Видим следующее:
pub rsa4096 2024-09-23 [SCEA]
AD02237C200DCF7465E0FA88AF8CB328D6E19757
uid [ultimate] dev flux (flux secrets)
sub rsa4096 2024-09-23 [SEA]
3. Сохраняем его в env переменную
export KEY_FP=AD02237C200DCF7465E0FA88AF8CB328D6E197574. Экспортируем ключ в кластер
gpg --export-secret-keys --armor "${KEY_FP}" |
sudo kubectl create secret generic sops-gpg \
--namespace=flux-system \
--from-file=sops.asc=/dev/stdin5. Экспортируем публичную часть ключа и сохраняем его в репозитории в файл cluster/flux-system/.sops.pub.asc
gpg --export --armor "${KEY_FP}" > /home/user/.sops.pub.asc6. Удаляем ключи с мастер машины кластера. Они тут нам больше не нужны
gpg --delete-secret-and-public-keys "${KEY_FP}"rm /home/user/.sops.pub.asc7. Теперь пришло время зашифровать наши секреты и настроить flux так, чтобы он их расшифровывал и в расшифрованном виде сохранял в кластер. Первым делом добавляем в 03-app.yaml следующие строчки:
decryption:
provider: sops
secretRef:
name: sops-gpg
Здесь мы указываем кластеру имя секрета, где хранится секретный ключ gpg, который будет использоваться для расшифровки файлов из репозитория
8. Из файла hr-app.yaml убираем секрет и кладем его в
helm-pull-secret.yaml9. Импортируем публичную часть ключа уже на нашей рабочей машине
gpg --import cluster/flux-system/.sops.pub.asc10. Ставим утилиту sops. И шифруем наши секреты
cd components/app-example
sops --encrypt --encrypted-regex '^(data|stringData)$' --pgp 'AD02237C200DCF7465E0FA88AF8CB328D6E19757' --in-place helm-pull-secret.yaml
sops --encrypt --encrypted-regex '^(data|stringData)$' --pgp 'AD02237C200DCF7465E0FA88AF8CB328D6E19757' --in-place image-pull-secret.yaml
Получаем зашифрованные версии наших конфигов секретов. helm-pull-secret.yaml и image-pull-secret.yaml
11. Вот и все. Пушим в репо и проверяем статус командой
flux get all -AДля того, чтобы проверить все ли работает - можно запустить деплой приложения в гитлабе и убедиться, что все по прежнему деплоится и функционирует. Конечно это нужно было сделать с самого начала и у нас в истории коммитов остались открытые секреты, но больше мы так делать не будем.
Stay tuned ;)
🔥6
Видео с конференции по безопасности контейнеров и контейнерных сред (БЕКОН)
Пока что адски перегружен и никак не могу продолжить писать следующий пост. Но без контента вас не оставлю :)
Держите офигенные доклады по безопасности с конференции БЕКОН 2024
https://www.youtube.com/watch?v=V7wOfQeghpQ&list=PL80eyh4Ug9W-bg3wco8e9UNpawrQlnkAk
Пока что адски перегружен и никак не могу продолжить писать следующий пост. Но без контента вас не оставлю :)
Держите офигенные доклады по безопасности с конференции БЕКОН 2024
https://www.youtube.com/watch?v=V7wOfQeghpQ&list=PL80eyh4Ug9W-bg3wco8e9UNpawrQlnkAk
YouTube
Латаем огрехи в образах приложений с помощью Kubernetes - Анатолий Карпенко | БеКон 2024
"Латаем огрехи в образах приложений с помощью Kubernetes", Анатолий Карпенко, Luntry
Обычная ситуация — вам достался образ, который вот совсем не по best practice по безопасности. И вы отказаться от него не можете и поправить в нем ничего не можете. Или…
Обычная ситуация — вам достался образ, который вот совсем не по best practice по безопасности. И вы отказаться от него не можете и поправить в нем ничего не можете. Или…
👍4
Идеальный Dockerfile
В очередной раз переосмыслил для себя каким должен быть Dockerfile.
Вовсе не обязательно делать отдельно под локальную разработку и под prod.
Достаточно использовать мультистадийную сборку и локально собирать с одним
По сути мы наследуем все что собираем для локалки и добавляем слои, которые нужны для прода.
А
В очередной раз переосмыслил для себя каким должен быть Dockerfile.
Вовсе не обязательно делать отдельно под локальную разработку и под prod.
Достаточно использовать мультистадийную сборку и локально собирать с одним
target, а для прода с другим.По сути мы наследуем все что собираем для локалки и добавляем слои, которые нужны для прода.
А
CMD можно вынести за скобки в docker-compose.yaml, .gitlab-ci.yml и т.д.Gist
Dockerfile
Dockerfile. GitHub Gist: instantly share code, notes, and snippets.
👍12
Healthcheck для php-fpm
Я уже несколько лет везде использую roadrunner. Но не так давно пришлось поработать с php-fpm в докере.
Думал как же проверять его здоровье, но оказалось, что уже все придумано. Есть такой вот скрипт - php-fpm-healthcheck.
Использование предельно просто:
Чтобы это работало - в php-fpm должен быть включен
Я уже несколько лет везде использую roadrunner. Но не так давно пришлось поработать с php-fpm в докере.
Думал как же проверять его здоровье, но оказалось, что уже все придумано. Есть такой вот скрипт - php-fpm-healthcheck.
Использование предельно просто:
healthcheck:
test: [ "CMD", "php-fpm-healthcheck" ]
interval: 5s
timeout: 5s
retries: 5
Чтобы это работало - в php-fpm должен быть включен
status и в докер образе должна стоять библиотечка для работы с fcgi. Для Debian ставим libfcgi-bin👍5🔥3
Symfony + docker. Когда компилировать DI контейнер?
Недавно созванивались с Валентином Удальцовым и обсуждали этот вопрос.
Сначала я компилировал DI контейнер сразу в
Потом вынес этот момент из
Когда же лучше это делать?
Если у вас нет специфичных настроек DI, зависящих от переменной APP_ENV или еще каких-то переменных окружения, которые влияют на сборку DI контейнера - можно и нужно компилировать DI контейнер в
Если такие настройки есть - то компиляцию DI контейнера лучше вынести вне сборки образа и сделать при запуске приложения.
P.S. Когда я это все тестировал - обнаружил любопытный момент. Linux кэширует ENV переменные для запущенного процесса и если мы поменяем переменную в уже запущенном docker контейнере, то в приложении ничего не изменится, так как значение переменной уже закэшировано для процесса, который запускает php скрипты, будь то
Недавно созванивались с Валентином Удальцовым и обсуждали этот вопрос.
Сначала я компилировал DI контейнер сразу в
Dockerfile, что обеспечивало быстрый запуск docker контейнера с приложением из уже подготовленного образа.Потом вынес этот момент из
Dockerfile в запуск приложения, т.е. сначала делаем cache:clear, а потом запускаем roadrunner. Но это замедляет старт docker контейнера.Когда же лучше это делать?
Если у вас нет специфичных настроек DI, зависящих от переменной APP_ENV или еще каких-то переменных окружения, которые влияют на сборку DI контейнера - можно и нужно компилировать DI контейнер в
Dockerfile.Если такие настройки есть - то компиляцию DI контейнера лучше вынести вне сборки образа и сделать при запуске приложения.
P.S. Когда я это все тестировал - обнаружил любопытный момент. Linux кэширует ENV переменные для запущенного процесса и если мы поменяем переменную в уже запущенном docker контейнере, то в приложении ничего не изменится, так как значение переменной уже закэшировано для процесса, который запускает php скрипты, будь то
roadrunner или php-fpm👍8🔥2
На канале FartTime сегодня стрим по нашей излюбленной тематике!
Forwarded from PHP Fart Time (Pavel Buchnev)
Давненько у нас не было стримов. Сегодня появилось время и я первым делом запланировал стрим, чтобы увидеть своих маленьких друзей! Почти месяц погружался в devops, поднял несколько кластеров k8s и т.д. Короче пока помню все и есть желание вам показать очередной крутой инструмент - terraform. Те кто незнаком, советую приходить.
Ваша жизнь изменится на до и после! :)
🕘 В 20:00 по МСК
https://youtube.com/live/NVHV-Mp-B5k?feature=share
В этом стриме мы шаг за шагом покажем, как описывать инфраструктуру с помощью кода на Terraform и будем в реалтайме запускать сервера. (Потратим немного деньжат)
Разберем создание инфраструктуры, настройку домена, подключение сервера и автоматизацию всех этих процессов. А также узнаем чем еще можно управлять с помощью terraform.
Подходит для тех, кто хочет не только расширить свой кругозор, но и упростить жизнь, осваивая Infrastructure as Code (IaC) и делая управление инфраструктурой более удобным.
Готовьте вопросы!
Ваша жизнь изменится на до и после! :)
🕘 В 20:00 по МСК
https://youtube.com/live/NVHV-Mp-B5k?feature=share
В этом стриме мы шаг за шагом покажем, как описывать инфраструктуру с помощью кода на Terraform и будем в реалтайме запускать сервера. (Потратим немного деньжат)
Разберем создание инфраструктуры, настройку домена, подключение сервера и автоматизацию всех этих процессов. А также узнаем чем еще можно управлять с помощью terraform.
Подходит для тех, кто хочет не только расширить свой кругозор, но и упростить жизнь, осваивая Infrastructure as Code (IaC) и делая управление инфраструктурой более удобным.
Готовьте вопросы!
YouTube
Автоматизируем разворачивание инфры для Web приложения с terraform
В этом стриме мы шаг за шагом покажем, как описывать инфраструктуру с помощью кода на Terraform и будем в реалтайме запускать сервера. (Потратим немного деньжат)
Разберем создание инфраструктуры, настройку домена, подключение сервера и автоматизацию всех…
Разберем создание инфраструктуры, настройку домена, подключение сервера и автоматизацию всех…
👍2❤1🔥1
PHP Russia 2024
Добиваю оставшиеся моменты по подготовке к конференции. До встречи на PHP Russia 2024, кто будет присутствовать оффлайн!
Ну и маленькое объявление:
Чтобы наверстать упущенное - ориентировочно в середине декабря планирую провести стрим. Закрепим уже вышедшие посты про кубер и посмотрим как это все делается вживую. Думаю так материал будет усвоен лучше. Ну и пообщаемся в чате трансляции.
Stay tuned!
Добиваю оставшиеся моменты по подготовке к конференции. До встречи на PHP Russia 2024, кто будет присутствовать оффлайн!
Ну и маленькое объявление:
Чтобы наверстать упущенное - ориентировочно в середине декабря планирую провести стрим. Закрепим уже вышедшие посты про кубер и посмотрим как это все делается вживую. Думаю так материал будет усвоен лучше. Ну и пообщаемся в чате трансляции.
Stay tuned!
👍14🔥7❤4
Production конфигурация php в докере
Доделываю сегодня последний шаблон приложения как дополнение для моего выступления на конференции. Стал проверять один момент и с удивлением обнаружил, что php работает в конфигурации по умолчанию и никакой базовый
Чтобы переключить php в prod режим нужно сделать следующее:
И об этом написано в документации к официальному php образу на docker hub.
Будьте внимательны, всегда читайте доку!
Доделываю сегодня последний шаблон приложения как дополнение для моего выступления на конференции. Стал проверять один момент и с удивлением обнаружил, что php работает в конфигурации по умолчанию и никакой базовый
php.ini для него не загружен. Я думал, что умолчание - production ready конфигурация. Но нет :)Чтобы переключить php в prod режим нужно сделать следующее:
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
И об этом написано в документации к официальному php образу на docker hub.
Будьте внимательны, всегда читайте доку!
👍6🔥3
Forwarded from linkmeup
Небольшое напоминание, что в этом мире есть команда timeout, чтобы ограничивать выполнение команд по времени. Типа, пишешь timeout 30s ping pelmeni и пинговалка будет убита через 30 секунд, а не будет долбиться в хост до скончания времён.
https://www.cyberciti.biz/faq/linux-run-a-command-with-a-time-limit/
https://www.cyberciti.biz/faq/linux-run-a-command-with-a-time-limit/
nixCraft
Linux run a command with a time limit (timeout)
Run a Linux/Unix command with a time limit: Learn how to run a command, and have it abort or timeout after N seconds using timeout, bash & Perl one-liner
❤4👍3
Выбираю платформу(мы) для стрима. Вы можете повлиять на выбор :)
Anonymous Poll
28%
ВК
33%
Telegram
22%
Twitch
44%
Youtube (Скорее всего только для записи)
Завтра стрим!
Как и договаривались - завтра будем проводить стрим. В 18 Мск.
Покажу на практике развертывание dev кластера k8s, покажу все то, что было уже описано в постах здесь, на канале.
В опросе победили две площадки - youtube и telegram. Поэтому будем стримить на них.
Сегодня будет несколько тестовых трансляций, заходить на них не нужно, это просто мои тесты.
Держите ссылочку на ютуб:
https://www.youtube.com/watch?v=dDfWQp3JRqg
Как и договаривались - завтра будем проводить стрим. В 18 Мск.
Покажу на практике развертывание dev кластера k8s, покажу все то, что было уже описано в постах здесь, на канале.
В опросе победили две площадки - youtube и telegram. Поэтому будем стримить на них.
Сегодня будет несколько тестовых трансляций, заходить на них не нужно, это просто мои тесты.
Держите ссылочку на ютуб:
https://www.youtube.com/watch?v=dDfWQp3JRqg
YouTube
Bootstrap dev k8s cluster
Покажу на практике все то, что уже было описано в постах в telegram канале
🔥9👍4🎉2
