JUnit ao amin'ny GitLab CI miaraka amin'i Kubernetes

Na dia eo aza ny zava-misy fa fantatry ny rehetra tsara fa zava-dehibe sy ilaina ny fitiliana ny rindrambaiko, ary maro no nanao izany ho azy nandritra ny fotoana ela, tao amin'ny midadasika ny Habr dia tsy nisy na dia iray aza fomba fanamboarana ny fametrahana fitambarana vokatra malaza toy izany ao ity niche ity ho (tianay) GitLab sy JUnit . Andao hameno ity banga ity!

JUnit ao amin'ny GitLab CI miaraka amin'i Kubernetes

enti-mampiditra ny

Voalohany, avelao aho hanome contexte vitsivitsy:

  • Koa satria mandeha amin'ny Kubernetes ny fampiharanay rehetra, dia handinika ny fanaovana fitiliana amin'ny fotodrafitrasa mety izahay.
  • Ho an'ny fanangonana sy ny fametrahana dia ampiasainay werf (amin'ny lafiny fotodrafitrasa dia midika ho azy koa izany fa tafiditra ao anatin'izany ny Helm).
  • Tsy hiditra amin'ny antsipirian'ny tena famoronana fitsapana aho: amin'ny tranga misy antsika, ny mpanjifa dia manoratra ny fitsapana ny tenany, ary miantoka fotsiny ny fandefasana azy ireo izahay (sy ny fisian'ny tatitra mifandraika amin'ny fangatahana fampiraisana).


Hanao ahoana ny filaharan'ny hetsika ankapobeny?

  1. Manangana ny fampiharana - hofoanana ny famaritana ity dingana ity.
  2. Alefaso any amin'ny toerana misy anarana misaraka amin'ny cluster Kubernetes ny fampiharana ary atombohy ny fitiliana.
  3. Mitadiava artifacts sy manara-maso ny tatitra JUnit miaraka amin'ny GitLab.
  4. Famafana ny espace anarana efa noforonina teo aloha.

Ankehitriny - ho fampiharana!

fanitsiana

GitLab CI

Andeha isika hanomboka amin'ny sombiny .gitlab-ci.yaml, izay mamaritra ny fametrahana ny fampiharana sy ny fanaovana fitiliana. Ny lisitra dia hita fa be dia be, noho izany dia nohamafisina tanteraka tamin'ny fanehoan-kevitra:

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

Ao amin'ny lahatahiry izao .helm/templates andao hamorona YAML miaraka amin'i Job - tests-job.yaml — hanaovana andrana sy ny loharanon-karena Kubernetes ilainy. Jereo ny fanazavana aorian'ny lisitra:

{{- 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 }}

Karazana loharano inona voalaza ato amin'ity configuration ity? Rehefa manaparitaka dia mamorona sehatra anarana tokana ho an'ny tetikasa izahay (izany dia aseho amin'ny .gitlab-ci.yaml - tests-${CI_COMMIT_REF_SLUG}) ary amboary izany:

  1. ConfigMap miaraka amin'ny script test;
  2. Job miaraka amin'ny famaritana ny pod sy ny torolàlana voafaritra command, izay manao fitiliana fotsiny;
  3. PV sy PVC, izay ahafahanao mitahiry angona fitsapana.

Tandremo ny fepetra fampidirana miaraka amin'ny if eo am-piandohan'ny fanehoana - araka izany, ny rakitra YAML hafa amin'ny tabilao Helm miaraka amin'ny fampiharana dia tsy maintsy fonosina hanova drafitra mba tsy ho voapetraka mandritra ny fitsapana. Izany hoe:

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

Na izany aza, raha ny fitsapana mila fotodrafitrasa sasany (ohatra, Redis, RabbitMQ, Mongo, PostgreSQL...) - ny YAML-ny dia mety ho tsy vonoy. Ampidiro ao anatin'ny tontolo fitsapana koa izy ireo... amboary araka izay hitanao fa mety, mazava ho azy.

Final touch

SATRIA famoriana sy fametrahana mampiasa asa werf amin'izao fotoana izao ihany Ao amin'ny server build (miaraka amin'ny gitlab-runner), ary ny pod misy fitsapana dia atomboka amin'ny tompony, mila mamorona lahatahiry ianao /mnt/tests amin'ny tompony ka omeo ny mpihazakazaka, ohatra, amin'ny alàlan'ny NFS. Ohatra amin'ny antsipiriany misy fanazavana azo jerena ao Takelaka data K8S.

Ny vokatra dia ho:

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

Tsy misy mandrara ny fizarana NFS mivantana amin'ny gitlab-runner, ary avy eo mametraka izany ao anaty pods.

fanamarihana

Mety hanontany ianao hoe maninona no manasarotra ny zava-drehetra amin'ny famoronana Joba raha toa ka afaka manao script fotsiny ianao miaraka amin'ny fitsapana mivantana amin'ny mpihazakazaka shell? Tena tsinontsinona ny valiny...

Ny fitsapana sasany dia mitaky fidirana amin'ny fotodrafitrasa (MongoDB, RabbitMQ, PostgreSQL, sns.) mba hanamarinana fa miasa tsara izy ireo. Mampiray ny fitsapana izahay - miaraka amin'ity fomba ity, dia lasa mora ny mampiditra ireo singa fanampiny ireo. Ankoatra izany, mahazo Malagasy fomba fametrahana (na dia mampiasa NFS aza, fametrahana ny lahatahiry fanampiny).

vokatra

Inona no ho hitantsika rehefa mampihatra ny fandrindrana voaomana isika?

Ny fangatahana fanakambanana dia hampiseho antontan'isa famintinana ho an'ny andrana atao amin'ny fantsona farany azy:

JUnit ao amin'ny GitLab CI miaraka amin'i Kubernetes

Ny lesoka tsirairay dia azo kitihina eto raha mila antsipiriany:

JUnit ao amin'ny GitLab CI miaraka amin'i Kubernetes

NB: Ho hitan'ny mpamaky tsara fa manao fitiliana fampiharana NodeJS izahay, ary ao amin'ny pikantsary - .NET... Aza gaga: fa teo am-panomanana ny lahatsoratra dia tsy nisy fahadisoana hita tamin'ny fitsapana ny fampiharana voalohany, fa izy ireo hita tany amin'ny hafa.

famaranana

Araka ny hitanao, tsy misy sarotra!

Raha ny fitsipika, raha efa manana mpanangona akorandriaka ianao ary miasa izany, saingy tsy mila Kubernetes ianao, ny fametahana fitsapana amin'izany dia ho asa tsotra kokoa noho ny voalaza eto. Ary in Documentation GitLab CI Hahita ohatra ho an'i Ruby, Go, Gradle, Maven sy ny hafa ianao.

Sal

Vakio ihany koa ao amin'ny bilaoginay:

Source: www.habr.com

Add a comment