Guía · 9 min

Archestack en Kubernetes, la vía corta

Esta es la vía más corta para llegar a un clúster que ya tienes en marcha, AKS o cualquier otro: Archestack bajo una ruta de un nombre de host que su ingress ya sirve, como https://apps.example.com/archestack/. Cinco archivos de manifiesto y un pipeline, en Azure DevOps, GitHub Actions o GitLab CI, sin Helm, y nada que crear fuera del clúster: PostgreSQL también se ejecuta en él. Una instalación real en AKS ejecuta exactamente estos manifiestos, desde el pipeline de Azure DevOps.

¿Quieres nombres de host propios, una base de datos gestionada, varias réplicas de la API y actualizaciones cada noche? Alojamiento en AKS es la versión completa.

Tu sistema de CI

Qué se ejecuta

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

El navegador carga el builder desde /archestack/ y llama a la API en /archestack/api en la misma dirección, así que no hay un segundo nombre de host ni ninguna configuración entre orígenes. Las actualizaciones en vivo usan un WebSocket a /archestack/hubs. La aplicación publicada está en /archestack/app/.

Qué necesitas

  • Un clúster con ingress-nginx y un nombre de host que ya sirve por HTTPS.
  • Un namespace archestack y una storage class que proporcione discos, como hace la predeterminada de AKS.
  • Azure DevOps, GitHub o GitLab, con el repositorio desde el que se ejecuta el pipeline. Los runners propios de GitHub y de GitLab llegan a la API del clúster desde internet, así que un clúster privado necesita un runner tuyo dentro de su red.

Tres pasos

  1. Descomprime el kit en tu repositorio como archestack/.
  2. Configura el pipeline en tu sistema de CI, como indica su sección más abajo: dónde va su archivo, y un entorno por cada entorno de Archestack, primero archestack-dev, con estas cinco variables, las tres últimas como secretos:
    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
  3. Ejecuta el pipeline y elige el entorno. El primer arranque tarda unos minutos, porque la API crea y migra sus bases de datos antes de responder. Después, inicia sesión en https://<HOST>/archestack/ con el correo y la contraseña del administrador.

El pipeline

El kit lo trae para tres sistemas de CI. Cada uno da los mismos tres pasos: rellena los manifiestos, crea el secreto y después despliega y espera hasta que todos los pods estén listos.

Tu sistema de CI

Azure DevOps

  1. Añade archestack/azure-pipelines.yml como pipeline.
  2. En Pipelines, Environments, crea archestack-dev y añádele el namespace archestack del clúster como recurso de Kubernetes. Crea archestack-tst, -acc y -prd del mismo modo cuando los necesites.
  3. En Pipelines, Library, crea un grupo de variables con el mismo nombre, archestack-dev, con las cinco variables, las contraseñas como secretos.
# 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 sustituye seis nombres en ellos y nada más, así que la contraseña de la base de datos que la API lee en tiempo de ejecución sigue siendo una referencia al secreto.
  • Make the secret convierte las tres contraseñas en un único secreto de Kubernetes. Detiene la ejecución cuando falta alguna, en lugar de desplegar con una contraseña vacía.
  • Deploy Archestack aplica la carpeta y espera hasta que todos los pods estén listos. Con monitoring desactivado, Grafana y su stack quedan fuera.

GitHub Actions

  1. Mueve archestack/github-actions.yml a .github/workflows/archestack.yml: GitHub solo ejecuta flujos de trabajo desde esa carpeta.
  2. En Settings, Environments, crea archestack-dev, con HOST y ADMIN_EMAIL como variables y las tres contraseñas como secretos, más el secreto KUBECONFIG: lo que imprime kubeconfig.sh. En un repositorio privado, los entornos requieren GitHub Pro, Team o Enterprise.
  3. Ejecútalo en 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 a main que cambia archestack/ despliega en desarrollo con las imágenes latest, como hace el pipeline de Azure DevOps.
  • concurrency impide que dos ejecuciones desplieguen en un mismo entorno a la vez.
  • kubectl está fijado. Mantenlo a no más de una versión menor de la de tu clúster.

GitLab CI

  1. Incluye el archivo del kit desde el .gitlab-ci.yml propio del repositorio, o crea uno que contenga solo esto:
    include:
      - local: archestack/gitlab-ci.yml
  2. En Settings, CI/CD, Variables, añade las cinco con el ámbito de entorno archestack-dev, las contraseñas enmascaradas, más KUBECONFIG de tipo File: lo que imprime kubeconfig.sh. Protégelas todas, para que solo las ramas protegidas las reciban.
  3. Ejecútalo en Build, Pipelines, New pipeline, y elige allí el entorno.
# 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 a la rama predeterminada que cambia archestack/ despliega en desarrollo con las imágenes latest.
  • El job se ejecuta en la etapa deploy, que GitLab tiene salvo que tu .gitlab-ci.yml enumere etapas propias sin ella.
  • El agente de GitLab para Kubernetes también sirve: pon en KUBE_CONTEXT el contexto del agente en lugar de KUBECONFIG.
  • resource_group impide que dos pipelines desplieguen en un mismo entorno a la vez.
  • La imagen y kubectl están fijados. Mantén kubectl a no más de una versión menor de la de tu clúster.

Lo que ejecutan GitHub Actions y GitLab CI

Ambos ejecutan deploy.sh, los tres pasos del pipeline de Azure DevOps como un único 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

Iniciar sesión en el clúster

GitHub Actions y GitLab CI inician sesión con el kubeconfig que imprime kubeconfig.sh: una cuenta de servicio con acceso al namespace archestack y a nada más, con un token que no caduca. Ejecútalo una vez por clúster, como alguien que pueda crear roles en él:

#!/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
  • No tu propio kubeconfig. Lleva tus permisos sobre todo el clúster, y en AKS con inicio de sesión de Entra ID pide a una persona que inicie sesión, cosa que un pipeline no puede hacer.
  • Retirar el acceso es borrar el secreto archestack-deploy-token del namespace. Vuelve a ejecutar el script para obtener uno nuevo.

Los archivos

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

El ingress es el único archivo que tiene que ajustarse a tu clúster:

# 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
  • Sin reescritura. La API y el builder esperan ambos el prefijo /archestack (Http__PathBase en api.yml, BASE_PATH en web.yml), así que el ingress pasa las rutas sin cambios.
  • Subidas grandes y conexiones largas. El tamaño máximo de las peticiones permite importar paquetes y subir archivos, y los tiempos de espera mantienen abiertos el WebSocket de las actualizaciones en vivo y las copias de seguridad largas.
  • Ningún proxy de inicio de sesión delante. Una anotación de oauth2 sustituiría el token que lleva cada llamada a la API. Archestack inicia la sesión de las personas por sí mismo. El ingress de Grafana sí puede llevar una.

Actualizar

Vuelve a ejecutar el pipeline con otra etiqueta de imagen. latest toma la release más reciente; una versión como 1.0.42 indica exactamente qué se ejecuta, y es la forma de llevar la misma versión de pruebas a producción. El pod de la API se sustituye en lugar de ejecutarse junto al antiguo, porque sus discos se conectan a un solo pod a la vez, así que la API no está disponible durante el minuto que tarda en arrancar. Todo lo que hayas creado está en los discos y se conserva.

A tener en cuenta

  • La contraseña de la base de datos se fija una sola vez. PostgreSQL la toma cuando arranca por primera vez sobre un disco vacío. Cambiarla después en el sistema de CI no la cambia en la base de datos, y entonces la API ya no puede conectarse.
  • La contraseña del administrador se usa una sola vez, para crear el primer administrador. Cámbiala después en Archestack, no en el sistema de CI.
  • Las copias de seguridad se quedan en el clúster. Se escriben en el disco archestack-backups. Cópialas también a otro sitio.
  • Volver a una versión anterior puede fallar una vez que una más nueva ha migrado la base de datos. Prueba primero una actualización en archestack-tst.

Hacia dónde va esto a continuación

Desplegar desde el repositorio lleva tus aplicaciones de git a estos entornos. Alojamiento en AKS añade nombres de host propios, una base de datos gestionada, varias réplicas de la API y actualizaciones cada noche.