Mám webservice pomocí websockets, a je třeba realizovat nulové prostoje nasazení. Protože nechci drop existující připojení na nasazení, jsem se rozhodl realizovat modrá/zelená nasazení. Mé skutečné řešení vypadá:
- Vytvořil jsem dvě identické služby v portainer, poslech na různých portech. Každá služba má nastavit v uzlu prostředí nějaký identifikátor, například
alfa
abeta
- Obě služby jsou skryté za load balancer, vyvažovací zařízení je pravidelně kontrolovat stav jednotlivých služeb. Pokud služba reaguje na konkrétní trase (/vyvažovací zařízení-keepalive-check) s string "OK", tato služba je aktivní a balancer může směrování k této službě. Pokud služba odpovídá řetězec "STOP", vyvažovací označit tuto službu jako nepřístupné, ale aktivní spojení bude zachována
- která služba je aktivní a který je zastaven, je synchronizovat přes redis. V redis existuje klíče
lb.service.alfa
alb.service.beta
které mohou obsahuje hodnoty 1 pro aktivní a 0 pro neaktivní. Příklad realizace /vyvažovací zařízení-keepalive-podívejte se na trasy v 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>`;
})
}
}
- v gitlab CI vytvořit docker image tagged podle značek na potvrdit a restartovat službu volání portainer webhook pro konkrétní služby. To funguje dobře pro 1 službu, ale nevím, jak používat 2 různé DEPLOY_WEBHOOK CI proměnných a přepínat mezi nimi.
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
Na mé otázky, které nevím, jak řešit, jsou:
- Když jsem si 2 služby, mám 2 různé nasadit webhooks, z nichž musím zavolat jeden po nasazení, protože nechci, aby restart obou služeb. Jak určit, který z nich? Jak implementovat nějaký čítač, pokud to nasazení je "alfa" nebo "beta" provozu? Mám použít gitlab api a aktualizace DEPLOY_WEBHOOK po každém nasazení? Nebo se mám zbavit tohoto gitlab CI/CD proměnné a použít nějaké API pro služby, které mi řekne, webhook url?
- Jak aktualizovat hodnoty v redis? Měl jsem implementovat vlastní rozhraní API pro?
- Existuje lepší způsob, jak toho dosáhnout?
kromě info: nelze použít gitlab api od serviceses, protože naše gitlab je self-hostované na doméně přístupný pouze z naší privátní sítě.