Архив автора: admin

Обзор k9s — продвинутого терминального интерфейса для Kubernetes

K9s предоставляет пользовательский интерфейс терминала для взаимодействия с кластерами Kubernetes. Цель этого Open Source-проекта — облегчить удобную навигацию по приложениям в K8s, наблюдение за ними и управление ими. K9s постоянно следит за изменениями в Kubernetes и предлагает быстрые команды для работы с наблюдаемыми ресурсами.




Проект написан на Go, существует уже более полутора лет: первый коммит был сделан 1 февраля 2019 года. На момент написания статьи насчитывается 9000+ звезд на GitHub и около 80 контрибьюторов. Посмотрим, что умеет k9s?




Установка и запуск




Это клиентское (по отношению к кластеру Kubernetes) приложение, которое проще всего запустить как Docker-образ:




docker run --rm -it -v $KUBECONFIG:/root/.kube/config quay.io/derailed/k9s




Для некоторых Linux-дистрибутивов и других ОС также есть готовые для установки пакеты. В общем случае для Linux-систем можно установить бинарный файл:




sudo wget -qO- https://github.com/derailed/k9s/releases/download/v0.22.0/k9s_Linux_x86_64.tar.gz | tar zxvf -  -C /tmp/
sudo mv /tmp/k9s /usr/local/bin




Каких-то специфических требований к самому кластеру K8s нет. Судя по отзывам, приложение работает и с такими старыми версиями Kubernetes, как 1.12.




Приложение запускается, используя стандартный конфиг .kube/config — аналогичному тому, как это делает kubectl.




Навигация




По умолчанию открывается окно со стандартным namespace, который указан для контекста. То есть, если вы прописали kubectl config set-context --current --namespace=test, то и откроется namespace test(О смене контекстов/пространств имён см. ниже.)







Переход в режим команд осуществляется нажатием на «:». После этого можно управлять работой k9s с помощью команд — например, для просмотра списка StatefulSets (в текущем пространстве имен) можно ввести :sts.







Для некоторых других ресурсов Kubernetes:




  • :ns — Namespaces;
  • :deploy — Deployments;
  • :ing — Ingresses;
  • :svc — Services.




Чтобы вывести полный список типов ресурсов, доступных для просмотра, есть команда :aliases.




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







Также в k9s есть режим поиска, для перехода в который достаточно ввести «/». С ним осуществляется поиск по содержимому текущего «окна». Допустим, если вы до этого ввели :ns, у вас открыт список пространств имён. Если их слишком много, то, чтобы не скроллить долго вниз, достаточно в окне с namespaces ввести /mynamespace.




Для поиска по лейблам можно выбрать все pod’ы в нужном пространстве имён, после чего ввести, например, / -l app=whoami. Мы получим список pod’ов с этим лейблом:







Поиск работает во всех видах окон, включая логи, просмотр YAML-манифестов и describe для ресурсов — подробнее об этих возможностях см. ниже.




Как в целом выглядит последовательность действий для навигации?




С помощью команды :ctx можно выбрать контекст:







Для выбора namespace’а есть уже упоминавшаяся команда :ns, а далее можно воспользоваться поиском для нужного пространства: /test.




Если теперь выбрать интересующий нас ресурс (например, всё тот же StatefulSet), для него покажется соответствующая информация: сколько запущено pod’ов с краткими сведениями о них.







Могут быть интересны только pod’ы — тогда достаточно ввести :pod. В случае с ConfigMap’ами (:cm — для списка этих ресурсов) можно выбрать интересующий объект и нажать на «u», после чего K9s подскажет, кто конкретно его (этот CM) использует.




Ещё одна удобная фича для просмотра ресурсов — их «рентген» (XRay view). Такой режим вызывается командой :xray RESOURCE и… проще показать, как он работает, чем объяснять. Вот иллюстрация для StatefulSets:







(Каждый из этих ресурсов можно редактировать, изменять, делать describe.)




А вот Deployment с Ingress:







Работа с ресурсами




О каждом ресурсе можно получить информацию в YAML или его describe нажатием на соответствующие клавиатурные сочетания («y» и «d» соответственно). Базовых операций, конечно, ещё больше: их список и клавиатурные сочетания всегда на виду благодаря удобной «шапке» в интерфейсе (скрывается нажатием на Ctrl + e).







При редактировании любого ресурса («e» после его выбора) открывается текстовый редактор, определённый в переменных окружения (export EDITOR=vim).




А вот как выглядит подробное описание ресурса (describe):







Такой вывод (или вывод просмотр YAML-манифеста ресурса) можно сохранить с помощью привычного сочетания клавиш Ctrl + s. Куда он сохранится, будет известно из сообщения K9s:




Log /tmp/k9s-screens-root/kubernetes/Describe-1601244920104133900.yml saved successfully!




Из созданных файлов-бэкапов можно и восстанавливать ресурсы, предварительно убрав системные лейблы и аннотации. Для этого потребуется перейти в директорию с ними (:dir /tmp), после чего выбрать нужный файл и применить apply.




К слову, в любой момент можно откатиться и на прошлый ReplicaSet, если с текущим есть проблемы. Для этого надо выбрать нужный RS (:rs для их списка):







… и выполнить rollback с помощью Ctrl + l. Мы должны получить уведомление, что все прошло успешно:




k9s/whoami-5cfbdbb469 successfully rolled back




А чтобы масштабировать реплики, достаточно нажать на «s» (scale) и выбрать нужное количество экземпляров:







В любой из контейнеров можно зайти с помощью shell: для этого перейдите к нужному pod’у, нажмите на «s» (shell) и выберите контейнер.




Другие возможности




Конечно, поддерживается и просмотр логов («l» для выбранного ресурса). А чтобы смотреть новые логи, нет необходимости постоянно нажимать Enter: достаточно сделать маркировку («m»), после чего отслеживать только новые сообщения.







Также в этом же окне можно выбрать временной диапазон для вывода логов:




  • клавиша «1» — за 1 минуту;
  • «2» — 5 минут;
  • «3» — 15 минут;
  • «4» — 30 минут;
  • «5» — 1 час;
  • «0» — за все время жизни pod’а.




Специальный режим работы Pulse (команда :pulse) показывает общие сведения о Kubernetes-кластере:







В нем можно увидеть количество ресурсов и их состояние (зеленым показываются те, что имеют статус Running).




Еще одна интересная функция K9s называется Popeye. Она проверяет все ресурсы на определённые критерии корректности и выводит получившийся «рейтинг» с пояснениями. Например, можно увидеть, что не хватает проб или лимитов, а какой-то контейнер может запускаться под root…







Имеется базовая поддержка Helm. Например, так можно посмотреть релизы, задеплоенные в кластер:




:helm all # все
:helm $namespace # в конкретном пространстве имен




Benchmark




В K9s встроили даже hey — это простой генератор нагрузки на HTTP-сервер, альтернатива более известному ab (ApacheBench).




Чтобы включить его, потребуется активация port-forward в pod’е. Для этого выбираем pod и нажимаем на Shift + f, переходим в подменю port-forward с помощью алиаса «pf».







После выбора порта и нажатия на Ctrl + b запустится сам benchmark. Результаты его работы сохраняются в /tmp и доступны для последующего просмотра в K9s.










Для изменения конфигурации benchmark’а нужно создать файл $HOME/.k9s/bench-<my_context>.yml (определяется для каждого кластера).




NB: Важно, чтобы расширение всех YAML-файлов в директории .k9s было именно .yml (.yaml не работает корректно).




Пример конфигурации:




benchmarks:
  defaults:
    # Количество потоков
    concurrency: 2
    # Количество запросов
    requests: 1000
  containers:
    # Настройки для контейнера с бенчмарком
    # Контейнер определяется как namespace/pod-name:container-name
    default/nginx:nginx:
      concurrency: 2
      requests: 10000
      http:
        path: /
        method: POST
        body:
          {"foo":"bar"}
        header:
          Accept:
            - text/html
          Content-Type:
            - application/json
 services:
    # Можно проводить бенчмарк на сервисах типа NodePort и LoadBalancer
    # Синтаксис: namespace/service-name
    default/nginx:
      concurrency: 5
      requests: 500
      http:
        method: GET
        path: /auth
      auth:
        user: flant
        password: s3cr3tp455w0rd




Интерфейс




Вид столбцов для списков ресурсов модифицируется созданием файла $HOME/.k9s/views.yml. Пример его содержимого:




k9s:
 views:
   v1/pods:
     columns:
       - AGE
       - NAMESPACE
       - NAME
       - IP
       - NODE
       - STATUS
       - READY
   v1/services:
     columns:
       - AGE
       - NAMESPACE
       - NAME
       - TYPE
       - CLUSTER-IP




Правда, не хватает колонки по лейблам, на что есть issue в проекте.




Сортировка по столбцам осуществляется клавиатурными сочетаниями:




  • Shift + n — по имени;
  • Shift + o — по узлам;
  • Shift + i — по IP;
  • Shift + a — по времени жизни контейнера;
  • Shift + t — по количеству рестартов;
  • Shift + r — по статусу готовности;
  • Shift + c — по потреблению CPU;
  • Shift + m — по потреблению памяти.




Если же кому-то не нравится цветовое оформление по умолчанию, в K9s даже поддерживаются скины. Готовые примеры (7 штук) доступны здесь. Вот пример одного из таких скинов (in the navy):







Плагины




Наконец, плагины позволяют расширять возможности K9s. Сам я в работе использовал только один из них — kubectl get all -n $namespace.




Выглядит это следующим образом. Создаем файл $HOME/.k9s/plugin.yml с таким содержимым:




plugin:
 get-all:
   shortCut: g    
   confirm: false    
   description: get all
   scopes:
   - all
   command: sh
   background: false
   args:
   - -c
   - "kubectl -n $NAMESPACE get all -o wide | less"




Теперь можно перейти в пространство имён и нажать на «g» для выполнения с соответствующей команды:







Среди плагинов есть, например, интеграции с kubectl-jq и утилитой для просмотра логов stern.




Заключение




На мой вкус, K9s оказалась очень удобна в работе: с ней довольно быстро привыкнуть искать всё нужное без использования kubectl. Порадовал просмотр логов и их сохранение, быстрое редактирование ресурсов, скорость работы в целом*, оказался полезным режим Popeye. Отдельного упоминания стоят возможности создавать плагины и дорабатывать приложение под свои нужды.




* Хотя при большом объеме логов замечал также медленную работу K9s. В такие моменты утилита «съедала» 2 ядра у Intel Xeon E312xx и могла даже зависать.




Чего не хватает в настоящий момент? Быстрого отката на предыдущую версию (речь не про RS) без перехода в директорию. К тому же, восстановление происходит только для всего ресурса: если вы удалили аннотацию или лейбл, придется удалить и восстановить весь ресурс (здесь и понадобится переходить в директорию). Другая мелочь — не хватает даты таких сохраненных «бэкапов».




Источник: https://habr.com/ru/company/flant/blog/524196/



2022-07-28T23:48:08
DevOps

Создание переиспользуемых пайплайнов для GitLab CI на bash

За последние несколько лет я очень полюбил GitLab CI. В основном за его простоту и функциональность. Достаточно просто создать в корне репозитория файл .gitlab-ci.yml , добавить туда несколько строчек кода и при следующем коммите запустится пайплайн с набором джобов, которые будут выполнять указанные команды.




А если добавить к этому возможности include и extends, можно делать достаточно интересные вещи: создавать шаблонные джобы и пайплайны, выносить их в отдельные репозитории и повторно использовать в разных проектах без копирования кода.




Но к сожалению, не всё так радужно, как хотелось бы. Инструкция script в GitLab CI очень низкоуровневая. Она просто выполняет те команды, которые ей переданы в виде строк. Писать большие скрипты внутри YAML не очень удобно. По мере усложнения логики количество скриптов увеличивается, они перемешиваются с YAML делая конфиги нечитаемыми и усложняя их поддержку.




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




Пример: Сборка docker-образов в GitLab




Я хочу рассмотреть процесс создания пайплайна на примере простой задачи, которую часто встречал у разных команд: создание базовых docker-образов в GitLab для их повторного использования.




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




Или другой пример, команда пишет тесты и хочет используя services прямо в GitLab создавать для них временную базу данных (или очередь, или что-то ещё) используя свой собственный образ.




В целом, создать docker-образ из отдельного докерфайла в GitLab достаточно просто. Например можно сделать это с помощью такого .gitlab-ci.yml:




services:
  - docker:dind

Build:
  image: docker
  script:
    - |
      docker login "$CI_REGISTRY" 
        --username "$CI_REGISTRY_USER" 
        --password "$CI_REGISTRY_PASSWORD"

      docker build 
        --file "Dockerfile" 
        --tag "$CI_REGISTRY/$CI_PROJECT_PATH:$CI_COMMIT_REF_SLUG" .

      docker push "$CI_REGISTRY/$CI_PROJECT_PATH:$CI_COMMIT_REF_SLUG"




Здесь мы создаём пайплайн с одним джобом Build, который на каждый коммит логинится в GitLab Container Registry, собирает образ из файла докерфайла в корне репозитория и пушит полученный образ. В качестве тега образа используется название ветки или тега, где происходит сборка (возможно не самая лучшая схема, но это сделано для примера).




Но предположим, что нам необходимо создать чуть более сложный пайплайн, который будет работать следующим образом:




  • В репозитории может находиться несколько докерфайлов, которые будут располагаться в подпапке dockerfiles.
  • На каждый коммит должен запускаться пайплайн с двумя джобами:
    • Build All — будет находить и пересобирать все докерфайлы в подпапке dockerfiles. Этот джоб будет ручным (запускается по кнопке из интерфейса).
    • Build Changed— будет находить и пересобирать все докерфайлы в подпапке dockerfiles, которые были изменены в последнем коммите. Этот джоб будет автоматическим (запускается сразу при коммите) и будет появляться только при изменении файлов.




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




Структура репозитория для такого пайплайна может выглядеть следующим образом:







Содержимое и название докерфайлов особой роли не играет, но в данном случае это докерфайлы для разных версий .NET.




В интерфейсе гитлаба подобный пайплайн может выглядеть следующим образом:







Результатом работы такого пайплайна станет набор docker-образов, которые можно будет найти в Container Registry проекта:







А теперь попробуем создать пайплайн, который бы решал нашу задачу.




Шаг 1: Решение «в лоб»




Начнём самого простого и очевидного решения. Мы можем поместить весь код в файл .gitlab-ci.yml. В таком случае он будет выглядеть следующим образом:




services:
  - docker:dind

stages:
  - Build

Build All:
  stage: Build
  image: docker
  when: manual
  script:
    - |
      dockerfiles=$(find "dockerfiles" -name "*.Dockerfile" -type f)

      docker login "$CI_REGISTRY" 
        --username "$CI_REGISTRY_USER" 
        --password "$CI_REGISTRY_PASSWORD"

      for dockerfile in $dockerfiles; do
        path=$(echo "$dockerfile" | sed 's/^dockerfiles///' | sed 's/.Dockerfile$//')
        tag="$CI_REGISTRY/$CI_PROJECT_PATH/$path:$CI_COMMIT_REF_SLUG"

        echo "Building $dockerfile..."
        docker build --file "$dockerfile" --tag "$tag" .

        echo "Pushing $tag..."
        docker push "$tag"
      done

Build Changed:
  stage: Build
  image: docker
  only:
    changes:
      - 'dockerfiles/*.Dockerfile'
      - 'dockerfiles/**/*.Dockerfile'
  script:
    - |
      apk update
      apk add git # Вообще говоря, так не очень хорошо делать, но для примера можно...

      dockerfiles=$(git diff --name-only HEAD HEAD~1 -- 'dockerfiles/***.Dockerfile')

      docker login "$CI_REGISTRY" 
        --username "$CI_REGISTRY_USER" 
        --password "$CI_REGISTRY_PASSWORD"

      for dockerfile in $dockerfiles; do
        path=$(echo "$dockerfile" | sed 's/^dockerfiles///' | sed 's/.Dockerfile$//')
        tag="$CI_REGISTRY/$CI_PROJECT_PATH/$path:$CI_COMMIT_REF_SLUG"

        echo "Building $dockerfile..."
        docker build --file "$dockerfile" --tag "$tag" .

        echo "Pushing $tag..."
        docker push "$tag"
      done




Ссылки на проект:







Здесь мы делаем следующее:




  • Создаём джоб Build All, который:
    • Запускается вручную, т.к. содержит настройку when: manual.
    • Выполняет поиск всех докерфайлов при помощи команды:
      • find "dockerfiles" -name "*.Dockerfile" -type f
  • Создаём джоб Build Changed, который:
    • Создаётся только при изменении докерфайлов, т.к. содержит настройку only:changes.
    • Выполняет поиск всех докерфайлов, изменённых в последнем коммите при помощи команды:
      • git diff --name-only HEAD HEAD~1 -- 'dockerfiles/***.Dockerfile'
  • В остальном оба джоба работают одинаково, после поиска докерфайлов, они проходят по ним циклом, вырезают из названия каждого докерфайла префикс dockerfiles/ и суффикс .Dockerfile, после чего собирают его и пушат в GitLab Container Registry.




Данный пайплайн работает но есть очевидные проблемы:




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




В этом месте появляется тот микрофреймворк для разработки GitLab CI про который я упоминал в самом начале.




GitLab CI Bootstrap




GitLab CI Bootstrap — это микрофреймворк для разработки GitLab CI. Его основные цели:




  • Разделить описание пайплайна (файл .gitlab-ci.yml) и его скрипты (bash или shell), чтобы оставить YAML более декларативным.
  • Дать возможность разбивать большие скрипты на более мелкие и подключать одни скрипты к другим, чтобы улучшить структурирование кода и упростить его поддержку.
  • Дать возможность выносить скрипты и джобы (со скриптами) в отдельные репозитории, чтобы повторно использовать их в разных проектах.




GitLab CI Bootstrap состоит из одного единственного файла bootstrap.gitlab-ci.yml, который необходимо подключить в файле .gitlab-ci.yml при помощи include. Сделать это можно несколькими способами. Проще всего скопировать файл в свой проект и подключить его через include:local:




include:
  - local: 'bootstrap.gitlab-ci.yml'




В этом файле находится один единственный скрытый джоб .bootstrap, который имеет следующий вид:




.bootstrap:
  before_script:
    - |
     	...




Другие джобы могут расширять джоб .bootstrap, используя extends:




example:
  extends: '.bootstrap'
  script:
    - '...'




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




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




Единственным требованием для загрузчика является наличие bash или shell. Также желательно наличие git, однако при его отсутствии он будет установлен автоматически. Благодаря этому джоб .bootstrap можно использовать практически с любыми официальными docker-образами и он будет там корректно работать.




Итак, давайте посмотрим, как это поможет нам упростить наш пайплайн для сборки docker-образов.




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




Все джобы, использующие джоб .bootstrap автоматически проверяют наличие в репозитории специального файла .gitlab-ci.sh. При его наличии этот файл автоматически загружается и все переменные и функции, которые в нём определены становятся доступными на этапе выполнения скриптов джоба.




Поэтому мы можем вынести все скрипты в этот файл и разбить их на функции, чтобы избежать дублирования, а затем вызвать эти функции из файла .gitlab-ci.yml:




Файл .gitlab-ci.yml:




include:
  - project: '$CI_PROJECT_NAMESPACE/bootstrap'
    ref: 'master'
    file: 'bootstrap.gitlab-ci.yml'

services:
  - docker:dind

stages:
  - Build

Build All:
  stage: Build
  image: docker
  extends: .bootstrap
  when: manual
  script:
    - search_all_dockerfiles_task
    - build_and_push_dockerfiles_task

Build Changed:
  stage: Build
  image: docker
  extends: .bootstrap
  only:
    changes:
      - 'dockerfiles/*.Dockerfile'
      - 'dockerfiles/**/*.Dockerfile'
  script:
    - install_git_task
    - search_changed_dockerfiles_task
    - build_and_push_dockerfiles_task




Файл .gitlab-ci.sh:




DOCKERFILES=""

function search_all_dockerfiles_task() {
    DOCKERFILES=$(find "dockerfiles" -name "*.Dockerfile" -type f)
}

function search_changed_dockerfiles_task() {
    DOCKERFILES=$(git diff --name-only HEAD HEAD~1 -- 'dockerfiles/***.Dockerfile')
}

function install_git_task() {
    # Вообще говоря, так не очень хорошо делать, но для примера можно...
    apk update
    apk add git
}

function build_and_push_dockerfiles_task() {
    docker login "$CI_REGISTRY" 
        --username "$CI_REGISTRY_USER" 
        --password "$CI_REGISTRY_PASSWORD"

    for dockerfile in $DOCKERFILES; do
        path=$(echo "$dockerfile" | sed 's/^dockerfiles///' | sed 's/.Dockerfile$//')
        tag="$CI_REGISTRY/$CI_PROJECT_PATH/$path:$CI_COMMIT_REF_SLUG"

        echo "Building $dockerfile..."
        docker build --file "$dockerfile" --tag "$tag" .

        echo "Pushing $tag..."
        docker push "$tag"
    done
}




Ссылки на проект:







Теперь все скрипты у нас вынесены в отдельный файл gitlab-ci.sh и разбиты на функции, которые вызываются из файла .gitlab-ci.yml. Функции search_all_dockerfiles_task и search_changed_dockerfiles_task заполняют переменную DOCKERFILES, которая позже используется функцией build_and_push_dockerfiles_task для сборки докерфайлов.




Шаг 3: Переносим пайплайн в отдельный репозиторий




Мы сделали работающий пайплайн и вынесли его скрипты в отдельный файл, но пока этот пайплайн находится в том же репозитории, что и докерфайлы. Это означает, что если другая команда захочет использовать его для сборки своих докерфайлов, им придётся скопировать все скрипты. А это в свою очередь означает, что если нам необходимо будет внести в пайплайн какие-нибудь изменения, то потом их нужно будет внести и всем командам, которые скопировали себе пайплайн.




Вместо этого мы можем вынести пайплайн в отельный репозиторий и предложить нескольким командам подключить его через include.




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




Если в джобе, использующей джоб .bootstrap определена переменная CI_IMPORT, то этот джоб проверит наличие трёх переменных: CI_{module}_PROJECTCI_{module}_REF и CI_{module}_FILE, где {module} — это нормализованное значение переменной CI_IMPORT (приведённое в верхнему регистру с заменой дефисов на подчёркивания).




Если все три переменные существуют, джоб перед загрузкой скриптов из файла .gitlab-ci.sh сначала загрузит файл, указанный в этих переменных.




Наш репозиторий с докерфайлами теперь будет выглядеть так:




Файл .gitlab-ci.yml:




include:
  - project: '$CI_PROJECT_NAMESPACE/dockerfiles-example-ci'
    ref: 'step3'
    file: 'dockerfiles.gitlab-ci.yml'




Сам пайплайн в отдельном репозитории будет выглядеть следующим образом:




Файл dockerfiles.gitlab-ci.yml (сюда перенесён код из .gitlab-ci.yml):




include:
  - project: '$CI_PROJECT_NAMESPACE/bootstrap'
    ref: 'master'
    file: 'bootstrap.gitlab-ci.yml'

services:
  - docker:dind

stages:
  - Build

variables:
  CI_DOCKERFILES_PROJECT: '$CI_PROJECT_NAMESPACE/dockerfiles-example-ci'
  CI_DOCKERFILES_REF: 'step3'
  CI_DOCKERFILES_FILE: 'dockerfiles.gitlab-ci.sh'

Build All:
  stage: Build
  image: docker
  extends: .bootstrap
  variables:
    CI_IMPORT: dockerfiles
  when: manual
  script:
    - search_all_dockerfiles_task
    - build_and_push_dockerfiles_task

Build Changed:
  stage: Build
  image: docker
  extends: .bootstrap
  variables:
    CI_IMPORT: dockerfiles
  only:
    changes:
      - 'dockerfiles/*.Dockerfile'
      - 'dockerfiles/**/*.Dockerfile'
  script:
    - search_changed_dockerfiles_task
    - build_and_push_dockerfiles_task




Файл dockerfiles.gitlab-ci.sh (сюда перенесён код из .gitlab-ci.sh):




DOCKERFILES=""

function search_all_dockerfiles_task() {
    DOCKERFILES=$(find "dockerfiles" -name "*.Dockerfile" -type f)
}

function search_changed_dockerfiles_task() {
    DOCKERFILES=$(git diff --name-only HEAD HEAD~1 -- 'dockerfiles/***.Dockerfile')
}

function build_and_push_dockerfiles_task() {
    docker login "$CI_REGISTRY" 
        --username "$CI_REGISTRY_USER" 
        --password "$CI_REGISTRY_PASSWORD"

    for dockerfile in $DOCKERFILES; do
        path=$(echo "$dockerfile" | sed 's/^dockerfiles///' | sed 's/.Dockerfile$//')
        tag="$CI_REGISTRY/$CI_PROJECT_PATH/$path:$CI_COMMIT_REF_SLUG"

        echo "Building $dockerfile..."
        docker build --file "$dockerfile" --tag "$tag" .

        echo "Pushing $tag..."
        docker push "$tag"
    done
}




Ссылки на проект:







Оба наших джоба Build All и Build Changed содержат переменную CI_IMPORT со значением dockerfiles. Поэтому загрузчик при старте джоба также проверит наличие трёх переменых: CI_DOCKERFILES_PROJECTCI_DOCKERFILES_REF и CI_DOCKERFILES_FILE, которые также определены в пайплайне.




Благодаря этим переменным загрузчик понимает, что должен загрузить скрипты из файла dockerfiles.gitlab-ci.sh, который находится в репозитории $CI_PROJECT_NAMESPACE/dockerfiles-example-ci, в ветке step3.




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




Шаг 4: Разбиваем большие скрипты на отдельные файлы




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




Однако сейчас все скрипты у нас находятся в одном файле dockerfiles.gitlab-ci.sh. По мере добавления функциональности, количество кода в нём будет расти и ориентироваться в нём будет всё сложнее и сложнее.




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




Также хочу отметить, что эта функция всегда загружает каждый файл только один раз, даже если вызов функции include с этим файлом встретится несколько раз.




Поэтому мы можем разбить наш файл dockerfiles.gitlab-ci.sh на несколько более мелких:




Файл dockerfiles.gitlab-ci.sh:




include "tasks/search.sh"
include "tasks/docker.sh"




Файл tasks/search.sh:




DOCKERFILES=""

function search_all_dockerfiles_task() {
    DOCKERFILES=$(find "dockerfiles" -name "*.Dockerfile" -type f)
}

function search_changed_dockerfiles_task() {
    DOCKERFILES=$(git diff --name-only HEAD HEAD~1 -- 'dockerfiles/***.Dockerfile')
}




Файл tasks/docker.sh:




function build_and_push_dockerfiles_task() {
    docker login "$CI_REGISTRY" 
        --username "$CI_REGISTRY_USER" 
        --password "$CI_REGISTRY_PASSWORD"

    for dockerfile in $DOCKERFILES; do
        path=$(echo "$dockerfile" | sed 's/^dockerfiles///' | sed 's/.Dockerfile$//')
        tag="$CI_REGISTRY/$CI_PROJECT_PATH/$path:$CI_COMMIT_REF_SLUG"

        echo "Building $dockerfile..."
        docker build --file "$dockerfile" --tag "$tag" .

        echo "Pushing $tag..."
        docker push "$tag"
    done
}




Ссылки на проект:







Заключение




В данной статье мы прошли по шагам создания переиспользуемого пайплайна для GitLab CI с использованием bash и GitLab CI Bootstrap.




Чтобы не увеличивать статью я описал только самые основные возможности своего микрофреймворка. Кроме этого он также позволяет:




  • Подключать скрипты из нескольких репозиториев по цепочке. Т.е. общий пайплайн, вынесенный в отдельный репозиторий сам по себе может также подключать скрипты из ещё нескольких репозиториев. Это создаёт большой простор для создания целых библиотек для GitLab CI.
  • Получать доступ к произвольным файлам в подключаемом репозитории. Это можно использовать для написания скриптов на других языках, таких как Python или C#.
  • Делать хуки на определённые функции. Это позволяет разработчикам, использующим общий пайплайн расширять его логику при необходимости.




Если нужно, я могу рассказать про эти возможности в комментариях.




Я пока не могу сказать, что мой микрофреймворк близок к версии 1.0. Ещё есть вещи, над которыми стоит поработать. Тем не менее, ранние его версии я успешно использовал в нескольких проектах и это действительно сильно упростило мне разработку.




Исходники: можно найти тут: https://gitlab.com/chakrygin/bootstrap




Репозитории с примерами тут:







Источник: https://habr.com/ru/post/557682/



2022-07-28T23:36:15
DevOps

Ventoy 1.0.79 уже вышла и это ее изменения

Ventoy: приложение с открытым исходным кодом для создания загрузочных USB-накопителей.

В выпуск новой версии Ventoy 1.0.79, который является отличным инструментом, предназначенным для создания загрузочных USB-накопителей с различными операционными системами.

Программа примечательна тем, что предоставляет возможность загрузки операционной системы из образов ISO, WIM, IMG, VHD и EFI. без изменений без необходимости распаковывать образ или переформатировать носитель. Например, просто скопируйте интересующий набор iso-образов на флешку с загрузчиком Ventoy, и Ventoy предоставит возможность загрузки внутренних операционных систем.





Читать

Carbon — язык программирования, призванный заменить C++.

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

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



Читать

Система инициализации systemd

Из этой статьи вы узнаете что такое система инициализации SystemD, её основную цель, а также познакомимся с юнитами SystemD.





Читать

7 лучших способов заработать на криптовалюте в 2022 году

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

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

 

Понимание рынка криптовалют

Что такое криптовалюта?

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

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

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

Какие преимущества имеет криптовалюта?

По сравнению с банковской системой криптовалюты имеют ряд преимуществ.

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

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

Во-вторых, биткоин не подвержен инфляции. Ее количество ограничено (21 миллион монет), а спрос постоянно растет с каждым годом. С 1971 года все “бумажные деньги” были отвязаны от золота. С тех пор ее можно печатать в неограниченных количествах, что вызвало бешеную инфляцию. Криптовалюте не грозит инфляция.

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

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

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

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

Как только новая транзакция поступает в сеть, она проверяется другими участниками (узлами). Если все правильно, транзакция признается действительной и записывается в новый блок.

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

За создание нового блока создатель получает фиксированное вознаграждение. Именно так осуществляется выпуск новых монет. Эмиссия большинства криптовалют ограничена: например, конечное количество биткоинов составит 21 миллион BTC, достигнутое примерно в 2040 году.

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

 

Рекомендации экспертов: Как инвестировать в биткойны и зарабатывать деньги?

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

Исследовательские биржи

Прежде чем инвестировать доллар, прочитайте обзоры, руководства в сообществах telegram, проконсультируйтесь с опытными инвесторами. Существует множество источников, которые введут вас в курс дела и укажут на подводные камни. В большинстве случаев платформы предоставляют средство для покупки и продажи криптовалют. На выбор доступно более 500 бирж.

Как вы храните свою цифровую валюту

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

Типы инвестиций

Инвестиционных стратегий столько, сколько инвесторов, поэтому тщательно выбирайте стратегию, которой вы будете придерживаться. Один из главных советов, который поможет инвесторам впервые заработать на криптовалюте, — это диверсификация. Не вкладывайте все свои средства только в одну криптовалюту. Попробуйте разделить свои инвестиции на несколько цифровых активов.

Помните о волатильности

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

 

Продолжение:



2022-07-27T11:34:03
Криптовалюта