Docker značkování strategie v CI systémy (GitLab)

0

Otázka

Jsme pomocí GitLab, a tak tam mohl být nějaký konkrétní odpověď na tuto platformu, ale myslím, že otázka je rovněž relevantní v jiných CI systém, stejně.

V našem CI systém máme krok k vybudování Docker image. Ve skutečnosti máme 2 samostatné úlohy:

Prvním úkolem bude vytvořit základní obraz, který zahrnuje všechny vnější závislosti. Tato práce se bude spouštět pouze pokud Dockerfile změnila. Což je vzácné.

Pak máme nějaké zkušební úlohy, které používají nejnovější verze základního obrazu.

Pokud to také projde, budeme mít druhé zaměstnání, které je pomocí nejnovější základní obraz vytvořit obraz, který již obsahuje náš zdrojový kód a zkompilovaný verze kódu, které je potřeba kompilace. Až nyní jsme taged vše, co s "nejnovější", ale to není dobré řešení. Zajímalo by mě, jestli jsou doporučené způsoby, jak označit obrázky. Zejména vzhledem k tomu, že jsme také začít používat větve a Korespondence-Žádosti (Pull Požadavek na GitHub mluvit), takže se musíme rozhodnout, jak označit obrázky, které by byly vytvořeny v pobočce a co použít při sloučení žádost?

Existuje "nejlepší praxe" pro to, nebo jsou tam několik "best practices"?

1

Nejlepší odpověď

1

Na základě vaší otázku, snažím se stručně vysvětlit, jak jsme se používá docker značkování, ale také odkazování správný obraz zevnitř potrubí. Měli jsme docela problémy s tím, jak jsme použili více registrů (včetně GitLab je vlastní). A každé prostředí musel vytvořit vlastní kategorie a tlačit obrázky do různých registrů. Vyřešit všechny problémy, dělali jsme následující (doufám, že tato informace vám pomůže!):

  • Používají GitLab proměnné souboru rozlišovat mezi proměnnými pro různá prostředí a registrů
  • Používat Git commit SHA značky Docker images
  • Použití proměnné řetězce v nasazení souborů
  • interpolaci proměnných pomocí bash nebo uzlu script

Pomocí GitLab proměnné soubory

Jsme vždy používat 3 soubory pro potrubí:

  • .gitlab-ci-vars.yml
  • .gitlab-ci-pracovních míst.yml
  • .gitlab-ci.yml

Používáme to, protože můžeme mít různé docker registry na životní prostředí. Takže teď můžeme snadno zaměřit naše dev acc a prod registru, pokud máme rádi. To dělá pěkný separace mezi dev acc a prod obrázky.

Příklady .gitlab-ci-vars.yml:

# .gitlab-ci-vars.yml

variables:
  FORCE_COLOR: 1
  NODE_ENV: dev
  CI_DOCKER_NAME: ${CI_REGISTRY_IMAGE}

.vars-dev:
  variables:
    NODE_ENV: dev
    REGISTRY: my.dev.registry
    IMAGE_NAME: ${NODE_ENV}-api:${CI_COMMIT_SHA}

.vars-acc:
  variables:
    NODE_ENV: acc
    REGISTRY: my.acc.registry
    IMAGE_NAME: ${NODE_ENV}-api:${CI_COMMIT_SHA}

.vars-prod:
  variables:
    NODE_ENV: prod
    REGISTRY: my.prod.registry
    IMAGE_NAME: ${NODE_ENV}-api:${CI_COMMIT_SHA}

Příklad opakovaně práce v .gitlab-jobs.yml:

# .gitlab-jobs.yml

.publish_gitlab:
  stage: publish
    image: docker
    services:
      - name: docker:dind
        alias: docker
    before_script:
      - echo -n $CI_JOB_TOKEN | docker login -u gitlab-ci-token --password-stdin $CI_REGISTRY
    script:
      - docker build -t ${REGISTRY}/${IMAGE_NAME} .
      - docker push ${REGISTRY}/${IMAGE_NAME}

Nyní můžeme vyvolat z .gitlab-ci.yml jak postupovat:

include:
  - ".gitlab-ci-vars.yml"
  - ".gitlab-ci-jobs.yml"

publish:image:dev:
  extends: .publish_gitlab
  # target dev env vars
  variables: !reference [.vars-dev, variables]
  resource_group: dev
  environment:
    name: dev
  only:
    - develop

publish:image:acc:
  extends: .publish_gitlab
  variables: !reference [.vars-acc, variables]
  resource_group: acc
  environment:
    name: acc
  only:
    - /^release.*$/

publish:image:prod:
  extends: .publish_gitlab
  variables: !reference [.vars-prod, variables]
  resource_group: prod
  environment:
    name: prod
  only:
    - master

Použití proměnné řetězce v nasazení souborů

Jako značka je náhodné (Git SHA), nemusíte znát přesný název. A tak jsme se použít v K8s nebo nějaké jiné formáty souborů byly musíme se zaměřit na náš nový docker image značky, řetězce, které jsme interpolovat pomocí nodejs skript. V tomto případě jsme se vždy zaměřit na správný obrázek, a nikdy nebude mít konflikty s jinými tagy.

Příklad k8s souboru:

apiVersion: apps/v1
...
    spec:
      containers:
        - name: my-image-name
          # target the name we defined in .gitlab-ci-vars.yml
          image: __REPO__/__IMAGE_NAME__
          ports:
            - containerPort: __CONTAINER_PORT__
          env:
            - name: NODE_ENV
              value: __NODE_ENV__

Jsme teď poskytování al těch proměnných naléhavými je těsně před použitím, nasazení (nebo spustit test, nebo co vůbec).

const fs = require('fs');
const path = require('path');

const {
  NODE_ENV,
  REGISTRY,
  IMAGE_NAME,
} = process.env

const DEFAULT_PROVISION_MAP = {
  __REPO__: REGISTRY,
  __IMAGE_NAME__: IMAGE_NAME,
  __CONTAINER_PORT__: 3000,
  __NODE_ENV__: NODE_ENV,
}

async function provisionK8sFiles() {
  const K8S_TEMPLATE_DIR = 'k8s';
  const DIR = path.join('gitlab', K8S_TEMPLATE_DIR);
  const K8S_FILES = await fs.promises.readdir(DIR);

  const MAPPING = {
    ...DEFAULT_PROVISION_MAP,
  }

  for (const file of K8S_FILES) {
    const filePath = path.join(DIR, file);

    let content = await fs.promises.readFile(filePath, {
      encoding: 'utf-8'
    });

    content = Object.keys(MAPPING).reduce((acc, curr) => {
      return acc.replace(new RegExp(curr, 'g'), MAPPING[curr])
    }, content)

    fs.writeFileSync(filePath, content, 'utf8')
  }
}

provisionK8sFiles()

A aktualizovat všechny proměnné z v potrubí používáme before_script zaměřit se na správný obrázek.

  before_script:
    - node ./bin/provision-k8s.js

Conslusion

Snažte se, aby všechno dynamické a interpolovat správný obraz a sha přes bash nebo uzlu script.

2021-11-23 13:43:51

V jiných jazycích

Tato stránka je v jiných jazycích

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................