Archestack su Kubernetes, la via breve
Questa è la via più breve per arrivare su un cluster che gestisci già, AKS o qualsiasi altro:
Archestack sotto un percorso di un hostname che il suo ingress serve già, per esempio
https://apps.example.com/archestack/. Cinque file manifest e una pipeline, su Azure
DevOps, GitHub Actions o GitLab CI, niente Helm, e niente da creare fuori dal cluster: anche
PostgreSQL gira al suo interno. Una vera installazione AKS esegue esattamente questi manifest,
dalla pipeline Azure DevOps.
Vuoi hostname tutti suoi, un database gestito, più repliche dell'API e aggiornamenti notturni? Hosting su AKS è la versione completa.
Cosa gira
https://apps.example.com
/archestack/api, /archestack/hubs -> archestack-api 1 pod, with disks for files and backups
/archestack/... -> archestack-web 2 pods: the builder and the published app
/archestack-grafana/ -> archestack-grafana optional, with Prometheus, Tempo and Loki
archestack-api -> archestack-postgres PostgreSQL 16 on a disk of its own
Il browser carica il builder da /archestack/ e chiama l'API su
/archestack/api allo stesso indirizzo, quindi non c'è un secondo hostname né una
configurazione cross-origin. Gli aggiornamenti in tempo reale usano un WebSocket verso
/archestack/hubs. L'app pubblicata è su /archestack/app/.
Cosa ti serve
- Un cluster con ingress-nginx e un hostname che serve già in HTTPS.
-
Un namespace
archestack, e una storage class che fornisce dischi, come fa quella predefinita di AKS. - Azure DevOps, GitHub o GitLab, con il repository da cui gira la pipeline. I runner di GitHub e di GitLab raggiungono l'API del cluster da internet, quindi un cluster privato ha bisogno di un runner tuo all'interno della sua rete.
Tre passi
- Estrai il kit nel tuo repository come
archestack/. -
Configura la pipeline nel tuo sistema CI, come dice la sua sezione qui
sotto: dove va il suo file, e un ambiente per ogni ambiente di Archestack, a cominciare da
archestack-dev, che contenga queste cinque, le ultime tre come segreti:HOST apps.example.com ADMIN_EMAIL you@example.com POSTGRES_PASSWORD secret, set once and never changed ADMIN_PASSWORD secret, the first admin's password GRAFANA_PASSWORD secret, Grafana's user admin -
Esegui la pipeline e scegli l'ambiente. Il primo avvio richiede qualche minuto, perché l'API crea
e migra i suoi database prima di rispondere. Poi accedi su
https://<HOST>/archestack/con l'email e la password dell'admin.
La pipeline
Il kit la contiene per tre sistemi CI. Ognuna fa gli stessi tre passi: compila i manifest, crea il Secret, poi fa il deploy e aspetta che ogni pod sia pronto.
Azure DevOps
- Aggiungi
archestack/azure-pipelines.ymlcome pipeline. -
In Pipelines, Environments, crea
archestack-deve aggiungi il namespacearchestackdel cluster come risorsa Kubernetes. Crea allo stesso modoarchestack-tst,-acce-prdquando ti servono. -
In Pipelines, Library, crea un gruppo di variabili con lo stesso nome,
archestack-dev, che contenga le cinque, le password come segreti.
# archestack/azure-pipelines.yml: Archestack on a Kubernetes cluster, under /archestack of a hostname the cluster's
# ingress already serves. Run it by hand, pick the environment and the Archestack version.
trigger:
branches:
include: [main]
paths:
include:
- archestack/**
parameters:
- name: environment
displayName: Environment
type: string
default: dev
values: [dev, tst, acc, prd]
- name: imageTag
displayName: Archestack version (image tag)
type: string
default: latest
- name: monitoring
displayName: Deploy Grafana with Prometheus, Tempo and Loki
type: boolean
default: true
variables:
# One variable group per environment, named archestack-<environment>, holding:
# HOST the hostname the cluster's ingress serves, such as apps.example.com
# ADMIN_EMAIL the first Archestack admin, created on the first start
# POSTGRES_PASSWORD secret; set once, see the note at "Secrets" below
# ADMIN_PASSWORD secret; the first admin's password
# GRAFANA_PASSWORD secret; Grafana's user admin
- group: archestack-${{ parameters.environment }}
- name: namespace
value: archestack
# The public Docker Hub images of Archestack.
- name: registry
value: docker.io/nickpeelman
stages:
- stage: deploy
displayName: Deploy ${{ parameters.environment }}
jobs:
- deployment: deploy
displayName: Deploy Archestack
pool:
vmImage: ubuntu-latest
# An Azure DevOps environment with the cluster's namespace added as a Kubernetes resource.
environment:
name: archestack-${{ parameters.environment }}
resourceName: archestack
resourceType: Kubernetes
strategy:
runOnce:
deploy:
steps:
- checkout: self
# Only these six names are replaced, so the $(POSTGRES_PASSWORD) the API reads and
# Grafana's $${...} stay as they are.
- bash: |
set -e
if [ -z "$HOST" ] || [ -z "$ADMIN_EMAIL" ]; then
echo "##vso[task.logissue type=error]Set HOST and ADMIN_EMAIL in the variable group archestack-${{ parameters.environment }}."
exit 1
fi
mkdir -p "$(Agent.TempDirectory)/manifests"
for f in archestack/manifests/*.yml; do
envsubst '${NAMESPACE} ${REGISTRY} ${IMAGE_TAG} ${ADMIN_EMAIL} ${HOST} ${MONITORING}' < "$f" > "$(Agent.TempDirectory)/manifests/$(basename "$f")"
done
if [ "$MONITORING" != "true" ]; then rm "$(Agent.TempDirectory)/manifests/observability.yml"; fi
displayName: Fill in the manifests
env:
NAMESPACE: $(namespace)
REGISTRY: $(registry)
IMAGE_TAG: ${{ parameters.imageTag }}
ADMIN_EMAIL: $(ADMIN_EMAIL)
HOST: $(HOST)
MONITORING: ${{ lower(parameters.monitoring) }}
# Secrets. The database password is fixed when PostgreSQL first starts on an empty disk:
# changing it afterwards does not change it in the database, and the API can no longer
# connect. The admin password is used only to create the first admin.
- bash: |
set -e
for value in "$PG_PASSWORD" "$ADMIN_PASSWORD_VALUE" "$GRAFANA_PASSWORD_VALUE"; do
case "$value" in
"" | '$('*)
echo "##vso[task.logissue type=error]Set the secrets POSTGRES_PASSWORD, ADMIN_PASSWORD and GRAFANA_PASSWORD in the variable group archestack-${{ parameters.environment }}."
exit 1
;;
esac
done
kubectl create secret generic archestack-secrets \
--from-literal=postgres-password="$PG_PASSWORD" \
--from-literal=admin-password="$ADMIN_PASSWORD_VALUE" \
--from-literal=grafana-admin-password="$GRAFANA_PASSWORD_VALUE" \
-n $(namespace) --dry-run=client -o yaml > "$(Agent.TempDirectory)/manifests/secrets.yml"
displayName: Make the secret
env:
PG_PASSWORD: $(POSTGRES_PASSWORD)
ADMIN_PASSWORD_VALUE: $(ADMIN_PASSWORD)
GRAFANA_PASSWORD_VALUE: $(GRAFANA_PASSWORD)
# Waits for every rollout. The API's first start creates and migrates its databases.
- task: KubernetesManifest@1
displayName: Deploy Archestack
inputs:
action: deploy
namespace: $(namespace)
rolloutStatusTimeout: 1800
manifests: $(Agent.TempDirectory)/manifests/*.yml
- bash: |
echo "Builder: https://$(HOST)/archestack/"
echo "Published app: https://$(HOST)/archestack/app/"
echo "Grafana: https://$(HOST)/archestack-grafana/"
displayName: Archestack addresses - Fill in the manifests sostituisce sei nomi nei manifest e nient'altro, così la password del database che l'API legge in esecuzione resta un riferimento al Secret.
- Make the secret trasforma le tre password in un unico Secret Kubernetes. Ferma l'esecuzione quando ne manca una, invece di fare il deploy con una password vuota.
- Deploy Archestack applica la cartella e aspetta che ogni pod sia pronto. Con monitoring disattivato, Grafana e il suo stack restano fuori.
GitHub Actions
-
Sposta
archestack/github-actions.ymlin.github/workflows/archestack.yml: GitHub esegue i workflow solo da quella cartella. -
In Settings, Environments, crea
archestack-dev, conHOSTeADMIN_EMAILcome variabili e le tre password come segreti, più il segretoKUBECONFIG: ciò che stampakubeconfig.sh. Su un repository privato, gli ambienti richiedono GitHub Pro, Team o Enterprise. - Eseguilo in Actions, Archestack, Run workflow.
# archestack/github-actions.yml: Archestack on a Kubernetes cluster, from GitHub Actions. GitHub runs
# workflows from one folder only: move this file to .github/workflows/archestack.yml. A push to main
# that changes archestack/ deploys to dev; under Actions, Archestack, Run workflow, you pick the
# environment and the Archestack version.
name: Archestack
on:
push:
branches: [main]
paths: ["archestack/**"]
workflow_dispatch:
inputs:
environment:
description: Environment
type: choice
options: [dev, tst, acc, prd]
default: dev
imageTag:
description: Archestack version (image tag)
default: latest
monitoring:
description: Deploy Grafana with Prometheus, Tempo and Loki
type: boolean
default: true
permissions:
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
# One GitHub environment per environment, named archestack-<environment>, holding the variables
# HOST the hostname the cluster's ingress serves, such as apps.example.com
# ADMIN_EMAIL the first Archestack admin, created on the first start
# and the secrets
# POSTGRES_PASSWORD set once: PostgreSQL keeps the password it first started with
# ADMIN_PASSWORD the first admin's password
# GRAFANA_PASSWORD Grafana's user admin
# KUBECONFIG the cluster sign-in archestack/kubeconfig.sh prints
environment: archestack-${{ inputs.environment || 'dev' }}
concurrency: archestack-${{ inputs.environment || 'dev' }} # one rollout per environment at a time
steps:
- uses: actions/checkout@v4
- uses: azure/setup-kubectl@v4
with:
version: v1.35.9 # within one minor version of the cluster's
- name: Sign in to the cluster
run: |
if [ -z "$KUBECONFIG_FILE" ]; then
echo "::error::Set the secret KUBECONFIG in the environment archestack-${{ inputs.environment || 'dev' }}."
exit 1
fi
install -m 600 /dev/null "$RUNNER_TEMP/kubeconfig"
printf '%s\n' "$KUBECONFIG_FILE" > "$RUNNER_TEMP/kubeconfig"
echo "KUBECONFIG=$RUNNER_TEMP/kubeconfig" >> "$GITHUB_ENV"
env:
KUBECONFIG_FILE: ${{ secrets.KUBECONFIG }}
- name: Deploy Archestack
run: bash archestack/deploy.sh
env:
IMAGE_TAG: ${{ inputs.imageTag || 'latest' }}
# A push has no inputs, so it deploys with monitoring on.
MONITORING: ${{ (github.event_name == 'workflow_dispatch' && !inputs.monitoring) && 'false' || 'true' }}
HOST: ${{ vars.HOST }}
ADMIN_EMAIL: ${{ vars.ADMIN_EMAIL }}
POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }}
ADMIN_PASSWORD: ${{ secrets.ADMIN_PASSWORD }}
GRAFANA_PASSWORD: ${{ secrets.GRAFANA_PASSWORD }} - Un push su
mainche modificaarchestack/fa il deploy in sviluppo con le immaginilatest, come fa la pipeline Azure DevOps. -
concurrencyimpedisce che due esecuzioni facciano il rollout sullo stesso ambiente nello stesso momento. - kubectl è fissato. Tienilo a non più di una versione minor di distanza da quella del tuo cluster.
GitLab CI
-
Includi il file del kit dal
.gitlab-ci.ymldel repository stesso, oppure creane uno che contenga solo questo:include: - local: archestack/gitlab-ci.yml -
In Settings, CI/CD, Variables, aggiungi le cinque limitate all'ambiente
archestack-dev, con le password mascherate, piùKUBECONFIGdi tipo File: ciò che stampakubeconfig.sh. Proteggile tutte, così solo i branch protetti le ricevono. - Eseguila in Build, Pipelines, New pipeline, e scegli lì l'ambiente.
# archestack/gitlab-ci.yml: Archestack on a Kubernetes cluster, from GitLab CI. Include it from the
# repository's own .gitlab-ci.yml (a file holding just these two lines when there is none):
# include:
# - local: archestack/gitlab-ci.yml
# A push to the default branch that changes archestack/ deploys to dev; under Build, Pipelines,
# New pipeline, you pick the environment and the Archestack version.
variables:
ARCHESTACK_ENVIRONMENT:
value: dev
options: [dev, tst, acc, prd]
description: Environment
ARCHESTACK_IMAGE_TAG:
value: latest
description: Archestack version (image tag)
ARCHESTACK_MONITORING:
value: "true"
options: ["true", "false"]
description: Deploy Grafana with Prometheus, Tempo and Loki
archestack:
stage: deploy
image: alpine:3.22
rules:
- if: $CI_PIPELINE_SOURCE == "web"
- if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
changes: [archestack/**/*]
# Variables scoped to this environment (Settings, CI/CD, Variables), all protected:
# HOST the hostname the cluster's ingress serves, such as apps.example.com
# ADMIN_EMAIL the first Archestack admin, created on the first start
# POSTGRES_PASSWORD masked; set once: PostgreSQL keeps the password it first started with
# ADMIN_PASSWORD masked; the first admin's password
# GRAFANA_PASSWORD masked; Grafana's user admin
# KUBECONFIG type File: the cluster sign-in archestack/kubeconfig.sh prints. With the
# GitLab agent for Kubernetes, set KUBE_CONTEXT to the agent's context instead.
environment:
name: archestack-$ARCHESTACK_ENVIRONMENT
resource_group: archestack-$ARCHESTACK_ENVIRONMENT # one rollout per environment at a time
variables:
KUBECTL_VERSION: v1.35.9 # within one minor version of the cluster's
before_script:
- apk add --no-cache bash curl gettext-envsubst
- curl -fsSLo /usr/local/bin/kubectl "https://dl.k8s.io/release/$KUBECTL_VERSION/bin/linux/amd64/kubectl"
- chmod +x /usr/local/bin/kubectl
- 'if [ -n "${KUBE_CONTEXT:-}" ]; then kubectl config use-context "$KUBE_CONTEXT"; fi'
script:
- IMAGE_TAG=$ARCHESTACK_IMAGE_TAG MONITORING=$ARCHESTACK_MONITORING bash archestack/deploy.sh - Un push sul branch predefinito che modifica
archestack/fa il deploy in sviluppo con le immaginilatest. - Il job gira nello stage
deploy, che GitLab ha a meno che il tuo.gitlab-ci.ymlnon elenchi stage propri senza di esso. - Anche l'agente GitLab per Kubernetes funziona: imposta
KUBE_CONTEXTsul contesto dell'agente invece diKUBECONFIG. -
resource_groupimpedisce che due pipeline facciano il rollout sullo stesso ambiente nello stesso momento. - L'immagine e kubectl sono fissati. Tieni kubectl a non più di una versione minor di distanza da quella del tuo cluster.
Cosa eseguono GitHub Actions e GitLab CI
Entrambi eseguono deploy.sh, i tre passi della pipeline Azure DevOps in un unico
script:
#!/usr/bin/env bash
# archestack/deploy.sh: what github-actions.yml and gitlab-ci.yml run, the same three steps
# azure-pipelines.yml takes with Azure DevOps' own tasks. kubectl has to reach the cluster already.
# Reads HOST, ADMIN_EMAIL, POSTGRES_PASSWORD, ADMIN_PASSWORD and GRAFANA_PASSWORD, and optionally
# IMAGE_TAG (latest) and MONITORING (true):
# IMAGE_TAG=1.4.23 bash archestack/deploy.sh
set -euo pipefail
cd "$(dirname "$0")"
for name in HOST ADMIN_EMAIL POSTGRES_PASSWORD ADMIN_PASSWORD GRAFANA_PASSWORD; do
if [ -z "${!name:-}" ]; then echo "Set $name for this environment" >&2; exit 1; fi
done
export NAMESPACE=${NAMESPACE:-archestack}
export REGISTRY=${REGISTRY:-docker.io/nickpeelman} # the public Docker Hub images of Archestack
export IMAGE_TAG=${IMAGE_TAG:-latest}
export MONITORING=${MONITORING:-true}
export HOST ADMIN_EMAIL
# 1. Fill in the manifests. Only these six names are replaced, so the $(POSTGRES_PASSWORD) the API
# reads and Grafana's $${...} stay as they are.
out=$(mktemp -d)
trap 'rm -rf "$out"' EXIT
for f in manifests/*.yml; do
envsubst '${NAMESPACE} ${REGISTRY} ${IMAGE_TAG} ${ADMIN_EMAIL} ${HOST} ${MONITORING}' < "$f" > "$out/$(basename "$f")"
done
if [ "$MONITORING" != true ]; then rm "$out/observability.yml"; fi
# 2. The secret, handed from one kubectl to the next and never written to a file. The database
# password is fixed when PostgreSQL first starts on an empty disk; the admin password only makes
# the first admin.
kubectl create secret generic archestack-secrets -n "$NAMESPACE" \
--from-literal=postgres-password="$POSTGRES_PASSWORD" \
--from-literal=admin-password="$ADMIN_PASSWORD" \
--from-literal=grafana-admin-password="$GRAFANA_PASSWORD" \
--dry-run=client -o yaml | kubectl apply -f -
# 3. Deploy, then wait for every rollout. The API's first start creates and migrates its databases.
applied=$(kubectl apply -n "$NAMESPACE" -f "$out" -o name)
for workload in $(grep -E '^(deployment|statefulset)\.apps/' <<< "$applied"); do
kubectl rollout status -n "$NAMESPACE" "$workload" --timeout=30m
done
echo "Builder: https://$HOST/archestack/"
echo "Published app: https://$HOST/archestack/app/"
if [ "$MONITORING" = true ]; then echo "Grafana: https://$HOST/archestack-grafana/"; fi Accedere al cluster
GitHub Actions e GitLab CI accedono con il kubeconfig che stampa kubeconfig.sh: un
service account che può entrare nel namespace archestack e in nient'altro, con un token
che non scade. Eseguilo una volta per cluster, come qualcuno che lì può creare ruoli:
#!/usr/bin/env bash
# archestack/kubeconfig.sh: the cluster sign-in for the GitHub Actions or GitLab CI pipeline, allowed
# into the archestack namespace and nothing else. Run it once per cluster, as someone who may create
# roles there, with kubectl pointing at that cluster:
# bash archestack/kubeconfig.sh > kubeconfig-dev
# Paste the file into the environment's KUBECONFIG, then delete it. To take the access away:
# kubectl -n archestack delete secret archestack-deploy-token
set -euo pipefail
NAMESPACE=${NAMESPACE:-archestack}
kubectl create namespace "$NAMESPACE" --dry-run=client -o yaml | kubectl apply -f - >&2
kubectl apply -n "$NAMESPACE" -f - >&2 <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: archestack-deploy
---
# Everything inside the namespace (the built-in admin role), nothing outside it.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: archestack-deploy
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: admin
subjects:
- kind: ServiceAccount
name: archestack-deploy
namespace: $NAMESPACE
---
# A token that does not expire. Deleting this secret revokes it.
apiVersion: v1
kind: Secret
metadata:
name: archestack-deploy-token
annotations:
kubernetes.io/service-account.name: archestack-deploy
type: kubernetes.io/service-account-token
EOF
# Kubernetes fills the token in a moment later.
token=""
for _ in $(seq 30); do
token=$(kubectl get secret archestack-deploy-token -n "$NAMESPACE" -o jsonpath='{.data.token}' | base64 --decode)
if [ -n "$token" ]; then break; fi
sleep 1
done
if [ -z "$token" ]; then echo "The token did not appear in archestack-deploy-token" >&2; exit 1; fi
ca=$(kubectl get secret archestack-deploy-token -n "$NAMESPACE" -o jsonpath='{.data.ca\.crt}')
server=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
cat <<EOF
apiVersion: v1
kind: Config
clusters:
- name: cluster
cluster:
server: $server
certificate-authority-data: $ca
users:
- name: archestack-deploy
user:
token: $token
contexts:
- name: archestack
context:
cluster: cluster
user: archestack-deploy
namespace: $NAMESPACE
current-context: archestack
EOF - Non il tuo kubeconfig. Porta con sé i tuoi diritti sull'intero cluster, e su AKS con l'accesso tramite Entra ID chiede a una persona di accedere, cosa che una pipeline non può fare.
- Togliere l'accesso significa eliminare il Secret
archestack-deploy-tokennel namespace. Esegui di nuovo lo script per averne uno nuovo.
I file
archestack/
azure-pipelines.yml Azure DevOps: fills in the manifests, makes the secret, deploys
github-actions.yml GitHub Actions: move it to .github/workflows/archestack.yml
gitlab-ci.yml GitLab CI: include it from the repository's .gitlab-ci.yml
deploy.sh what GitHub Actions and GitLab CI run: the same three steps
kubeconfig.sh their sign-in, allowed into the archestack namespace only
manifests/
postgres.yml PostgreSQL 16 with a 32 GB disk
api.yml the API, with disks for files (20 GB) and backups (50 GB)
web.yml the builder and the published app
ingress.yml /archestack on the hostname the cluster already serves
observability.yml optional: Grafana with Prometheus, Tempo and Loki L'ingress è l'unico file che deve adattarsi al tuo cluster:
# Archestack on the cluster's ingress-nginx, under a path of the shared host:
# https://${HOST}/archestack/ the builder
# https://${HOST}/archestack/app/<page> the published app
# https://${HOST}/archestack/api, /hubs the API and live updates
# No rewrite-target: the API (Http__PathBase) and the frontend (BASE_PATH) both expect the prefix.
# No oauth2 annotations on this one: they would replace the bearer token every API call carries.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: archestack
annotations:
# The default 1m refuses package imports and file uploads.
nginx.ingress.kubernetes.io/proxy-body-size: "1024m"
# /hubs keeps a WebSocket open; backups and imports read for a long time.
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
spec:
ingressClassName: nginx
rules:
- host: ${HOST}
http:
paths:
- path: /archestack/api
pathType: Prefix
backend:
service:
name: archestack-api
port:
number: 8080
- path: /archestack/hubs
pathType: Prefix
backend:
service:
name: archestack-api
port:
number: 8080
- path: /archestack
pathType: Prefix
backend:
service:
name: archestack-web
port:
number: 80 - Nessuna riscrittura. L'API e il builder si aspettano entrambi il prefisso
/archestack(Http__PathBaseinapi.yml,BASE_PATHinweb.yml), quindi l'ingress passa i percorsi invariati. - Upload grandi e connessioni lunghe. La dimensione del body permette import di pacchetti e upload di file, e i timeout tengono aperti il WebSocket degli aggiornamenti in tempo reale e i backup lunghi.
- Nessun proxy di accesso davanti. Un'annotazione oauth2 sostituirebbe il token che ogni chiamata all'API porta con sé. Archestack fa accedere le persone da solo. L'ingress di Grafana può averne uno.
Aggiornare
Esegui di nuovo la pipeline con un altro tag dell'immagine. latest prende la release
più recente; una versione come 1.0.42 dice esattamente cosa gira, ed è il modo per
portare la stessa versione dal test alla produzione. Il pod dell'API viene sostituito invece di
girare accanto al vecchio, perché i suoi dischi si collegano a un pod alla volta, quindi l'API non è
disponibile per il minuto che impiega ad avviarsi. Tutto ciò che hai creato sta sui dischi e resta.
Trappole
- La password del database si imposta una volta sola. PostgreSQL la prende quando si avvia per la prima volta su un disco vuoto. Cambiarla dopo nel sistema CI non la cambia nel database, e a quel punto l'API non riesce più a connettersi.
- La password dell'admin si usa una volta sola, per creare il primo admin. Dopo cambiala in Archestack, non nel sistema CI.
- I backup restano nel cluster. Vengono scritti sul disco
archestack-backups. Copiali anche da un'altra parte. - Tornare indietro a una versione più vecchia può fallire una volta che una più
nuova ha migrato il database. Prova prima un aggiornamento su
archestack-tst.
Dove andare dopo
Il deploy dal repository porta le tue applicazioni da git a questi ambienti. Hosting su AKS aggiunge hostname tutti suoi, un database gestito, più repliche dell'API e aggiornamenti notturni.