JUnit sa GitLab CI kauban ang Kubernetes

Bisan pa sa kamatuoran nga ang tanan hingpit nga nahibal-an nga ang pagsulay sa imong software hinungdanon ug gikinahanglan, ug daghan ang nagbuhat niini nga awtomatiko sa dugay nga panahon, sa kadaghanon sa Habr wala’y usa ka resipe alang sa pag-set up sa usa ka kombinasyon sa ingon nga mga sikat nga produkto sa kini nga niche isip (among paborito) GitLab ug JUnit . Atong pun-on kini nga kal-ang!

JUnit sa GitLab CI kauban ang Kubernetes

Pasiuna

Una, tugoti ako sa paghatag og pipila ka konteksto:

  • Tungod kay ang tanan namong mga aplikasyon nagdagan sa Kubernetes, among ikonsiderar ang pagpadagan sa mga pagsulay sa angay nga imprastraktura.
  • Para sa asembliya ug deployment among gigamit werf (sa termino sa mga sangkap sa imprastraktura, kini usab awtomatikong nagpasabut nga ang Helm naapil).
  • Dili ako moadto sa mga detalye sa aktuwal nga paghimo sa mga pagsulay: sa among kaso, ang kliyente nagsulat sa mga pagsulay sa iyang kaugalingon, ug among gisiguro lamang ang ilang paglansad (ug ang presensya sa usa ka katugbang nga taho sa hangyo sa paghiusa).


Unsa ang hitsura sa kinatibuk-ang han-ay sa mga aksyon?

  1. Pagtukod sa aplikasyon - atong laktawan ang paghulagway niini nga yugto.
  2. I-deploy ang aplikasyon sa lahi nga namespace sa Kubernetes cluster ug sugdi ang pagsulay.
  3. Pagpangita alang sa mga artifact ug pag-parse sa mga taho sa JUnit sa GitLab.
  4. Pagtangtang sa nabuhat na nga namespace.

Karon - sa pagpatuman!

kausaban

GitLab CI

Magsugod ta sa usa ka tipik .gitlab-ci.yaml, nga naghulagway sa pagdeploy sa aplikasyon ug pagpadagan sa mga pagsulay. Ang listahan nahimo nga daghan kaayo, mao nga kini hingpit nga gidugangan sa mga komentaryo:

variables:
# объявляем версию werf, которую собираемся использовать
  WERF_VERSION: "1.0 beta"

.base_deploy: &base_deploy
  script:
# создаем namespace в K8s, если его нет
    - kubectl --context="${WERF_KUBE_CONTEXT}" get ns ${CI_ENVIRONMENT_SLUG} || kubectl create ns ${CI_ENVIRONMENT_SLUG}
# загружаем werf и деплоим — подробнее об этом см. в документации
# (https://werf.io/how_to/gitlab_ci_cd_integration.html#deploy-stage)
    - type multiwerf && source <(multiwerf use ${WERF_VERSION})
    - werf version
    - type werf && source <(werf ci-env gitlab --tagging-strategy tag-or-branch --verbose)
    - werf deploy --stages-storage :local
      --namespace ${CI_ENVIRONMENT_SLUG}
      --set "global.commit_ref_slug=${CI_COMMIT_REF_SLUG:-''}"
# передаем переменную `run_tests`
# она будет использоваться в рендере Helm-релиза
      --set "global.run_tests=${RUN_TESTS:-no}"
      --set "global.env=${CI_ENVIRONMENT_SLUG}"
# изменяем timeout (бывают долгие тесты) и передаем его в релиз
      --set "global.ci_timeout=${CI_TIMEOUT:-900}"
     --timeout ${CI_TIMEOUT:-900}
  dependencies:
    - Build

.test-base: &test-base
  extends: .base_deploy
  before_script:
# создаем директорию для будущего отчета, исходя из $CI_COMMIT_REF_SLUG
    - mkdir /mnt/tests/${CI_COMMIT_REF_SLUG} || true
# вынужденный костыль, т.к. GitLab хочет получить артефакты в своем build-dir’е
    - mkdir ./tests || true
    - ln -s /mnt/tests/${CI_COMMIT_REF_SLUG} ./tests/${CI_COMMIT_REF_SLUG}
  after_script:
# после окончания тестов удаляем релиз вместе с Job’ом
# (и, возможно, его инфраструктурой)
    - type multiwerf && source <(multiwerf use ${WERF_VERSION})
    - werf version
    - type werf && source <(werf ci-env gitlab --tagging-strategy tag-or-branch --verbose)
    - werf dismiss --namespace ${CI_ENVIRONMENT_SLUG} --with-namespace
# мы разрешаем падения, но вы можете сделать иначе
  allow_failure: true
  variables:
    RUN_TESTS: 'yes'
# задаем контекст в werf
# (https://werf.io/how_to/gitlab_ci_cd_integration.html#infrastructure)
    WERF_KUBE_CONTEXT: 'admin@stage-cluster'
  tags:
# используем раннер с тегом `werf-runner`
    - werf-runner
  artifacts:
# требуется собрать артефакт для того, чтобы его можно было увидеть
# в пайплайне и скачать — например, для более вдумчивого изучения
    paths:
      - ./tests/${CI_COMMIT_REF_SLUG}/*
# артефакты старше недели будут удалены
    expire_in: 7 day
# важно: эти строки отвечают за парсинг отчета GitLab’ом
    reports:
      junit: ./tests/${CI_COMMIT_REF_SLUG}/report.xml

# для упрощения здесь показаны всего две стадии
# в реальности же у вас их будет больше — как минимум из-за деплоя
stages:
  - build
  - tests

build:
  stage: build
  script:
# сборка — снова по документации по werf
# (https://werf.io/how_to/gitlab_ci_cd_integration.html#build-stage)
    - type multiwerf && source <(multiwerf use ${WERF_VERSION})
    - werf version
    - type werf && source <(werf ci-env gitlab --tagging-strategy tag-or-branch --verbose)
    - werf build-and-publish --stages-storage :local
  tags:
    - werf-runner
  except:
    - schedules

run tests:
  <<: *test-base
  environment:
# "сама соль" именования namespace’а
# (https://docs.gitlab.com/ce/ci/variables/predefined_variables.html)
    name: tests-${CI_COMMIT_REF_SLUG}
  stage: tests
  except:
    - schedules

Kubernetes

Karon sa direktoryo .helm/templates maghimo kita og YAML uban ni Job - tests-job.yaml — sa pagpadagan sa mga pagsulay ug sa mga kapanguhaan sa Kubernetes nga gikinahanglan niini. Tan-awa ang mga katin-awan pagkahuman sa paglista:

{{- if eq .Values.global.run_tests "yes" }}
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: tests-script
data:
  tests.sh: |
    echo "======================"
    echo "${APP_NAME} TESTS"
    echo "======================"

    cd /app
    npm run test:ci
    cp report.xml /app/test_results/${CI_COMMIT_REF_SLUG}/

    echo ""
    echo ""
    echo ""

    chown -R 999:999 /app/test_results/${CI_COMMIT_REF_SLUG}
---
apiVersion: batch/v1
kind: Job
metadata:
  name: {{ .Chart.Name }}-test
  annotations:
    "helm.sh/hook": post-install,post-upgrade
    "helm.sh/hook-weight": "2"
    "werf/watch-logs": "true"
spec:
  activeDeadlineSeconds: {{ .Values.global.ci_timeout }}
  backoffLimit: 1
  template:
    metadata:
      name: {{ .Chart.Name }}-test
    spec:
      containers:
      - name: test
        command: ['bash', '-c', '/app/tests.sh']
{{ tuple "application" . | include "werf_container_image" | indent 8 }}
        env:
        - name: env
          value: {{ .Values.global.env }}
        - name: CI_COMMIT_REF_SLUG
          value: {{ .Values.global.commit_ref_slug }}
       - name: APP_NAME
          value: {{ .Chart.Name }}
{{ tuple "application" . | include "werf_container_env" | indent 8 }}
        volumeMounts:
        - mountPath: /app/test_results/
          name: data
        - mountPath: /app/tests.sh
          name: tests-script
          subPath: tests.sh
      tolerations:
      - key: dedicated
        operator: Exists
      - key: node-role.kubernetes.io/master
        operator: Exists
      restartPolicy: OnFailure
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: {{ .Chart.Name }}-pvc
      - name: tests-script
        configMap:
          name: tests-script
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: {{ .Chart.Name }}-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 10Mi
  storageClassName: {{ .Chart.Name }}-{{ .Values.global.commit_ref_slug }}
  volumeName: {{ .Values.global.commit_ref_slug }}

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: {{ .Values.global.commit_ref_slug }}
spec:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 10Mi
  local:
    path: /mnt/tests/
  nodeAffinity:
   required:
     nodeSelectorTerms:
     - matchExpressions:
       - key: kubernetes.io/hostname
         operator: In
         values:
         - kube-master
  persistentVolumeReclaimPolicy: Delete
  storageClassName: {{ .Chart.Name }}-{{ .Values.global.commit_ref_slug }}
{{- end }}

Unsa nga matang sa mga kapanguhaan gihulagway niini nga configuration? Kung nag-deploy, naghimo kami usa ka talagsaon nga namespace alang sa proyekto (gipakita kini sa .gitlab-ci.yaml - tests-${CI_COMMIT_REF_SLUG}) ug paligdi kini:

  1. ConfigMap uban ang test script;
  2. Job nga adunay usa ka paghulagway sa pod ug sa piho nga direktiba command, nga nagpadagan lang sa mga pagsulay;
  3. PV ug PVC, nga nagtugot kanimo sa pagtipig sa datos sa pagsulay.

Hatagi'g pagtagad ang pasiuna nga kondisyon nga adunay if sa sinugdanan sa manifest - sumala niana, ang ubang mga YAML nga mga file sa Helm chart uban sa aplikasyon kinahanglan nga giputos sa balihon disenyo aron dili sila ma-deploy sa panahon sa pagsulay. Mao ni:

{{- if ne .Values.global.run_tests "yes" }}
---
я другой ямлик
{{- end }}

Apan, kon ang mga pagsulay nanginahanglan pipila ka imprastraktura (pananglitan, Redis, RabbitMQ, Mongo, PostgreSQL...) - ang ilang mga YAML mahimong dili pagpalong. I-deploy usab sila sa usa ka palibot sa pagsulay ... pag-adjust kanila kung gusto nimo, siyempre.

katapusan nga paghikap

Kay asembliya ug pag-deploy gamit ang mga buhat sa werf sa pagkakaron lamang sa build server (uban ang gitlab-runner), ug ang pod nga adunay mga pagsulay gilunsad sa master, kinahanglan nimo nga maghimo usa ka direktoryo /mnt/tests sa agalon ug ihatag kini sa magdadalagan, pananglitan, pinaagi sa NFS. Ang usa ka detalyado nga pananglitan nga adunay mga pagpasabut makita sa K8s nga dokumentasyon.

Ang resulta mao ang:

user@kube-master:~$ cat /etc/exports | grep tests
/mnt/tests    IP_gitlab-builder/32(rw,nohide,insecure,no_subtree_check,sync,all_squash,anonuid=999,anongid=998)

user@gitlab-runner:~$ cat /etc/fstab | grep tests
IP_kube-master:/mnt/tests    /mnt/tests   nfs4    _netdev,auto  0       0

Wala’y nagdili sa paghimo sa usa ka bahin sa NFS nga direkta sa gitlab-runner, ug dayon i-mount kini sa mga pod.

Примечание

Mahimong mangutana ka ngano nga komplikado ang tanan pinaagi sa paghimo og Trabaho kung mahimo nimo nga ipadagan ang usa ka script nga adunay mga pagsulay nga direkta sa shell runner? Ang tubag gamay ra...

Ang ubang mga pagsulay nanginahanglan og access sa imprastraktura (MongoDB, RabbitMQ, PostgreSQL, ug uban pa) aron mapamatud-an nga kini nagtrabaho sa husto. Gihimo namon nga nahiusa ang pagsulay - sa kini nga pamaagi, mahimong dali nga ilakip ang ingon nga mga dugang nga entidad. Dugang pa niini, atong makuha sumbanan pamaagi sa pag-deploy (bisan kung gigamit ang NFS, dugang nga pag-mount sa mga direktoryo).

resulta

Unsa ang atong makita kung atong gamiton ang giandam nga configuration?

Ang hangyo sa paghiusa magpakita sa summary statistics alang sa mga pagsulay nga gipadagan sa pinakabag-o nga pipeline niini:

JUnit sa GitLab CI kauban ang Kubernetes

Ang matag sayup mahimong i-klik dinhi alang sa mga detalye:

JUnit sa GitLab CI kauban ang Kubernetes

NB: Ang matinagdanon nga magbabasa makamatikod nga kami nagsulay sa usa ka aplikasyon sa NodeJS, ug sa mga screenshot - .NET... Ayaw kahibulong: kini lang nga samtang nag-andam sa artikulo, walay mga sayup nga nakit-an sa pagsulay sa unang aplikasyon, apan sila nakit-an sa lain.

konklusyon

Sama sa imong nakita, wala’y komplikado!

Sa prinsipyo, kung aduna ka'y ​​usa ka kolektor sa kabhang ug kini nagtrabaho, apan dili nimo kinahanglan ang mga Kubernetes, ang paglakip sa pagsulay niini mahimong mas sayon ​​​​nga buluhaton kaysa gihulagway dinhi. Ug sa GitLab CI nga dokumentasyon makit-an nimo ang mga pananglitan alang sa Ruby, Go, Gradle, Maven ug uban pa.

PS

Basaha usab sa among blog:

Source: www.habr.com

Idugang sa usa ka comment