Blu/verde distribuzione di portainer utilizzo di gitlab CI/CD

0

Domanda

Ho webservice utilizzando websockets, e la necessità di implementare tempi di inattività di distribuzione. Perché non voglio cadere le connessioni esistenti sul distribuire, ho deciso di implementare blu/verde distribuire. La mia soluzione attuale si presenta come:

  1. Ho creato due identici servizi in portainer, in ascolto su porte diverse. Ogni servizio ha messo in nodo ambienti di un identificatore, ad esempio alfa e beta
  2. Entrambi i servizi sono nascosti dietro di bilanciamento del carico e bilanciamento del controllo periodico dello stato di ogni servizio. Se il servizio risponde su percorso specifico (/balancer-keepalive-check) con la stringa "OK", questo servizio è attivo e bilanciamento del grado di routing per questo servizio. Se il servizio risponde con la stringa "STOP", sistema di bilanciamento del marchio di questo servizio come inaccessibile, ma le connessioni attive saranno conservati
  3. che è attivo il servizio e che è stato arrestato è sincronizzato su redis. In redis ci sono i tasti lb.service.alfa e lb.service.beta che contiene i valori 1 e 0 sono inattivi. Esempio di implementazione /balancer-keepalive-check percorso in nestjs:
    import {Controller, Get} from '@nestjs/common';
    import {RedisClient} from "redis";
    const { promisify } = require("util");
    
    
    @Controller()
    export class AppController {
    
        private redisClient = new RedisClient({host: process.env.REDIS_HOST});
        private serviceId:string = process.env.ID;  //alfa, beta
    
        @Get('balancer-keepalive-check')
        async balancerCheckAlive(): Promise<string> {
            const getAsync = promisify(this.redisClient.get).bind(this.redisClient);
            return getAsync(`lb-status-${this.serviceId}`).then(status => {
                const reply: string = status == 1 ? 'OK' : 'STOP';
                return `<response>${reply}</response>`;
            })
        }
    }
  1. in gitlab CI crea mobile immagine contrassegnati da tag di commit, e riavviare il servizio di chiamata portainer webhook per il servizio specifico. Questo funziona bene per 1 servizio, ma non so come utilizzare 2 diversi DEPLOY_WEBHOOK CI variabili e passare tra di loro.
image: registry.rassk.work/pokec/pokec-nodejs-build-image:p1.0.1
services:
  - name: docker:dind

variables:
  DOCKER_TAG: platform-websocket:$CI_COMMIT_TAG

deploy:
  tags:
    - dtm-builder
  environment:
    name: $CI_COMMIT_TAG
  script:
    - npm set registry http://some-private-npm-registry-url.sk
    - if [ "$ENV_CONFIG" ]; then cp $ENV_CONFIG $PWD/.env; fi
    - if [ "$PRIVATE_KEY" ]; then cp $PRIVATE_KEY $PWD/privateKey.pem; fi
    - if [ "$PUBLIC_KEY" ]; then cp $PUBLIC_KEY $PWD/publicKey.pem; fi
    - docker build -t $DOCKER_TAG .
    - docker tag $DOCKER_TAG registry.rassk.work/community/$DOCKER_TAG
    - docker push registry.rassk.work/community/$DOCKER_TAG
    - curl --request POST $DEPLOY_WEBHOOK
  only:
    - tags

Le mie domande, che non so come risolvere sono:

  • Quando ho 2 servizi, ho 2 diversi distribuire webhooks da cui ho bisogno di chiamare uno dopo la distribuzione, perché non ho voglia di riavviare entrambi i servizi. Come determinare quale? Come implementare un qualche tipo di contatore, se questa distribuzione è a "alfa", "beta" del servizio? Devo usare gitlab api e aggiornamento DEPLOY_WEBHOOK dopo ogni distribuire? O shoud I sbarazzarsi di questo gitlab CI/CD variabile e l'utilizzo di alcune API servizi che mi dirà webhook url?
  • Come aggiornare i valori in redis? Dovrei implementare le API personalizzate per questo?
  • Esiste un modo migliore per realizzare questo?

aggiunta info: non è Possibile utilizzare gitlab api da serviceses, perché il nostro gitlab è self-hosted di dominio accessibile solo dalla nostra rete privata.

1

Migliore risposta

0

Ho modificato il mio AppController. Ci sono 2 nuovi endpoint ora, uno per identificare il servizio è in esecuzione, il secondo il valore di switch in redis:

private serviceId:string = process.env.ID || 'alfa';

    @Get('running-service-id')
    info(){
        return this.serviceId
    }

    @Get('switch')
    switch(){
        const play = this.serviceId == 'alfa' ? `lb-status-beta` : `lb-status-alfa`;
        const stop = `lb-status-${this.serviceId}`;
        this.redisClient.set(play, '1', (err) => {
            if(!err){
                this.redisClient.set(stop, '0');
            }
        })
    }

dopo di che, ho modificato il mio gitlab-ci.yml come segue:

image: registry.rassk.work/pokec/pokec-nodejs-build-image:p1.0.1
services:
  - name: docker:dind

stages:
  - build
  - deploy
  - switch

variables:
  DOCKER_TAG: platform-websocket:$CI_COMMIT_TAG

test:
  stage: build
  allow_failure: true
  tags:
    - dtm-builder
  script:
    - npm set registry http://some-private-npm-registry-url.sk
    - npm install
    - npm run test

build:
  stage: build
  tags:
    - dtm-builder
  environment:
    name: $CI_COMMIT_TAG
  script:
    - if [ "$ENV_CONFIG" ]; then cp $ENV_CONFIG $PWD/.env; fi
    - if [ "$PRIVATE_KEY" ]; then cp $PRIVATE_KEY $PWD/privateKey.pem; fi
    - if [ "$PUBLIC_KEY" ]; then cp $PUBLIC_KEY $PWD/publicKey.pem; fi
    - docker build -t $DOCKER_TAG .
    - docker tag $DOCKER_TAG registry.rassk.work/community/$DOCKER_TAG
    - docker push registry.rassk.work/community/$DOCKER_TAG
  only:
    - tags

deploy:
  stage: deploy
  needs: [build, test]
  environment:
    name: $CI_COMMIT_TAG
  script:
    - 'SERVICE_RUNNING=$(curl --request GET http://172.17.101.125/running-service-id)'
    - echo $SERVICE_RUNNING
    - if [ "$SERVICE_RUNNING" == "1" ]; then curl --request POST $DEPLOY_WEBHOOK_2; fi
    - if [ "$SERVICE_RUNNING" == "2" ]; then curl --request POST $DEPLOY_WEBHOOK_1; fi
  only:
    - tags

switch:
  stage: switch
  needs: [deploy]
  environment:
    name: $CI_COMMIT_TAG
  script:
    - sleep 10
    - curl --request GET http://172.17.101.125/switch
  only:
    - tags

Nel processo di costruire il mobile immagine è costruire. Dopo di che esegue lavoro di distribuzione, che fanno richiesta per /running-servizio-id che identifica, che il servizio è in esecuzione. Quindi distribuire l'immagine ha smesso di servizio. Ultimo lavoro di interruttore, che ne faranno richiesta per /switch percorso, che passa i valori in redis.

Questo funziona bene. L'ultima cosa che ho bisogno di implementare un qualche tipo di segreto per questo due percorsi (jwt per esempio)

2021-12-02 07:39:41

In altre lingue

Questa pagina è in altre lingue

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