Подготовка инфраструктуры

Требования

  • GitLab;

  • Linux-хост для установки GitLab Runner, имеющий:

    • Bash;

    • Git версии 2.18.0 или выше;

    • GPG;

  • Argo CD.

Установка GitLab Runner

Установите GitLab Runner на выделенный для него хост, следуя официальным инструкциям.

Установка Buildah

Для установки Buildah выполните следующие инструкции на хосте для GitLab Runner:

  • Установите пакет Buildah, следуя официальным инструкциям, но не производите его дальнейшую настройку. Если для вашего дистрибутива нет готовых пакетов Buildah, используйте следующие инструкции:
Ручная установка Buildah
  • Установите пакеты, предоставляющие программы newuidmap и newgidmap.

  • Убедитесь, что программы newuidmap и newgidmap имеют корректные права:

    sudo setcap cap_setuid+ep /usr/bin/newuidmap
    sudo setcap cap_setgid+ep /usr/bin/newgidmap
    sudo chmod u-s,g-s /usr/bin/newuidmap /usr/bin/newgidmap
    
  • Установите пакет, предоставляющий файлы /etc/subuid и /etc/subgid.

  • Убедитесь, что в файлах /etc/subuid и /etc/subgid имеется строка вида gitlab-runner:1000000:65536, где:

    • gitlab-runner — имя пользователя GitLab Runner;

    • 1000000 — первый subUID/subGID в выделяемом диапазоне;

    • 65536 — размер диапазона subUIDs/subGIDs (минимум 65536).

    Избегайте коллизий с другими диапазонами, если они имеются. Изменение файлов может потребовать перезагрузки. Подробнее в man subuid и man subgid.

  • (Для Linux 5.12 и ниже) Установите пакет, предоставляющий программу fuse-overlayfs.

  • Убедитесь, что путь /home/gitlab-runner/.local/share/containers создан, и пользователь gitlab-runner имеет доступ на чтение и запись.

  • Команда sysctl -ne kernel.unprivileged_userns_clone НЕ должна вернуть 0, а иначе выполните echo 'kernel.unprivileged_userns_clone = 1' | sudo tee -a /etc/sysctl.conf && sudo sysctl -p.

  • Команда sysctl -n user.max_user_namespaces должна вернуть 15000 или больше, а иначе выполните echo 'user.max_user_namespaces = 15000' | sudo tee -a /etc/sysctl.conf && sudo sysctl -p.

Установка werf

Для установки werf на хосте для GitLab Runner выполните:

curl -sSL https://werf.io/install.sh | bash -s -- --ci

Регистрация GitLab Runner

Для регистрации GitLab Runner в GitLab следуйте официальным инструкциям, указав Shell в качестве executor’а. При желании после регистрации произведите дополнительную конфигурацию GitLab Runner’а.

Конфигурация container registry

Включите сборщик мусора вашего container registry.

Подготовка системы к кроссплатформенной сборке (опционально)

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

Регистрируем в системе эмуляторы с помощью образа qemu-user-static:

docker run --restart=always --name=qemu-user-static -d --privileged --entrypoint=/bin/sh multiarch/qemu-user-static -c "/register --reset -p yes && tail -f /dev/null"

Установка Argo CD Image Updater

Установите Argo CD Image Updater с патчем “continuous deployment of OCI Helm chart type application”:

kubectl apply -n argocd -f https://raw.githubusercontent.com/werf/3p-argocd-image-updater/master/manifests/install.yaml

Настройка проекта

Настройка приложения Argo CD

  1. В целевом кластере примените следующий Application CRD, чтобы развернуть бандл из container registry:
kubectl create -f - <<EOF
---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  annotations:
    argocd-image-updater.argoproj.io/chart-version: ~ 1.0
    argocd-image-updater.argoproj.io/pull-secret: pullsecret:myproject-production/myproject-regcred
  name: myproject
  namespace: argocd
  finalizers:
  - resources-finalizer.argocd.argoproj.io
spec:
  destination:
    namespace: myproject-production
    server: https://kubernetes.default.svc
  project: default
  source:
    chart: myproject
    repoURL: registry.mycompany.org/myproject
    targetRevision: 1.0.0
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
EOF

Значение argocd-image-updater.argoproj.io/chart-version="~ 1.0" означает, что оператор должен автоматически развернуть чарт с последней версией патча в диапазоне SEMVER 1.0.*.

  1. Создайте Secret для доступа к container registry проекта:
kubectl create -f - <<EOF
---
apiVersion: v1
kind: Secret
metadata:
  name: myproject-regcred
  namespace: myproject-production
type: kubernetes.io/dockerconfigjson
data:
  .dockerconfigjson: BASE64_DOCKER_CONFIG_JSON
EOF

Настройка GitLab-проекта

  • Создайте и сохраните токен доступа для очистки ненужных образов из container registry. Используйте следующие параметры:

    • Token name: werf-images-cleanup;

    • Role: developer;

    • Scopes: api.

  • Добавьте следующие переменные в переменные проекта:

    • Токен доступа для очистки ненужных образов:

      • Key: WERF_IMAGES_CLEANUP_PASSWORD;

      • Value: <"werf-images-cleanup" токен доступа, сохраненный ранее>;

      • Protect variable: yes;

      • Mask variable: yes.

  • Добавьте ночную задачу по расписанию для очистки ненужных образов в container registry, установив ветку main/master в качестве целевой (Target branch).

Настройка CI/CD проекта

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

.helm
app
.gitlab-ci.yml
werf.yaml
stages:
  - release
  - cleanup

variables:
  WERF_BUILDAH_MODE: auto

default:
  before_script:
    - source $(~/bin/trdl use werf 2 stable)
    - source $(werf ci-env gitlab --as-file)
  tags: ["<GitLab Runner tag>"]

Build and publish release:
  stage: release
  script:
    - werf bundle publish --tag "1.0.${CI_PIPELINE_ID}"
  only:
    - main
  except:
    - schedules

Cleanup registry:
  stage: cleanup
  script:
    - werf cr login $WERF_REPO
    - werf cleanup
  only:
    - schedules

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
spec:
  selector:
    matchLabels:
      app: app
  template:
    metadata:
      labels:
        app: app
    spec:
      containers:
      - name: app
        image: {{ .Values.werf.image.app }}

apiVersion: v1
kind: Service
metadata:
  name: app
spec:
  selector:
    app: app
  ports:
  - name: app
    port: 80

FROM node

WORKDIR /app
COPY . .
RUN npm ci

CMD ["node", "server.js"]

{
  "name": "app",
  "version": "1.0.0",
  "lockfileVersion": 2,
  "requires": true,
  "packages": {
    "": {
      "name": "app",
      "version": "1.0.0"
    }
  }
}

{
  "name": "app",
  "version": "1.0.0",
  "main": "server.js",
  "scripts": {
    "start": "node server.js"
  }
}

const http = require('http');

const hostname = '127.0.0.1';
const port = 80;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

configVersion: 1
project: myproject
---
image: app
dockerfile: Dockerfile
context: ./app

Дополнительно:

  • Добавьте параметры авторизации для werf cleanup в container registry, следуя инструкции.