Przewodnik - 9 min

Archestack na Kubernetesie, najkrótszą drogą

To najkrótsza droga na klaster, który już utrzymujesz, AKS albo dowolny inny: Archestack pod ścieżką nazwy hosta, którą jego ingress już obsługuje, na przykład https://apps.example.com/archestack/. Pięć plików manifestów i jeden pipeline, w Azure DevOps, GitHub Actions albo GitLab CI, bez Helma i bez niczego do tworzenia poza klastrem: PostgreSQL też działa w klastrze. Prawdziwa instalacja na AKS uruchamia dokładnie te manifesty, z pipeline'u Azure DevOps.

Chcesz własnych nazw hostów, zarządzanej bazy danych, kilku replik API i nocnych aktualizacji? Pełną wersją jest Hosting na AKS.

Twój system CI

Co działa

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

Przeglądarka ładuje builder z /archestack/ i wywołuje API pod /archestack/api pod tym samym adresem, więc nie ma drugiej nazwy hosta ani konfiguracji cross-origin. Aktualizacje na żywo korzystają z WebSocketu do /archestack/hubs. Opublikowana aplikacja jest pod /archestack/app/.

Czego potrzebujesz

  • Klastra z ingress-nginx i nazwy hosta, którą już obsługuje przez HTTPS.
  • Namespace archestack i klasy storage, która przydziela dyski, tak jak domyślna klasa w AKS.
  • Azure DevOps, GitHub albo GitLab z repozytorium, z którego działa pipeline. Runnery dostarczane przez GitHub i GitLab łączą się z API klastra przez internet, więc klaster prywatny potrzebuje własnego runnera wewnątrz swojej sieci.

Trzy kroki

  1. Rozpakuj zestaw do swojego repozytorium jako archestack/.
  2. Skonfiguruj pipeline w swoim systemie CI, tak jak opisuje to jego sekcja poniżej: gdzie trafia jego plik i jedno środowisko na każde środowisko Archestack, najpierw archestack-dev, z tymi pięcioma zmiennymi, z których trzy ostatnie są sekretami:
    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. Uruchom pipeline i wybierz środowisko. Pierwsze uruchomienie trwa kilka minut, bo API tworzy i migruje swoje bazy danych, zanim zacznie odpowiadać. Potem zaloguj się pod https://<HOST>/archestack/ e-mailem i hasłem administratora.

Pipeline

Zestaw zawiera go dla trzech systemów CI. Każdy wykonuje te same trzy kroki: uzupełnia manifesty, tworzy Secret, a potem wdraża i czeka, aż każdy pod będzie gotowy.

Twój system CI

Azure DevOps

  1. Dodaj archestack/azure-pipelines.yml jako pipeline.
  2. W Pipelines, Environments utwórz archestack-dev i dodaj do niego namespace archestack klastra jako zasób Kubernetes. Gdy będą potrzebne, utwórz w ten sam sposób archestack-tst, -acc i -prd.
  3. W Pipelines, Library utwórz grupę zmiennych o tej samej nazwie, archestack-dev, z tymi pięcioma zmiennymi, z hasłami jako sekretami.
# 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 podmienia w manifestach sześć nazw i nic więcej, więc hasło do bazy danych, które API odczytuje w trakcie działania, pozostaje odwołaniem do Secretu.
  • Make the secret zamienia trzy hasła w jeden Secret Kubernetes. Gdy któregoś brakuje, zatrzymuje uruchomienie, zamiast wdrażać z pustym hasłem.
  • Deploy Archestack stosuje folder i czeka, aż każdy pod będzie gotowy. Przy wyłączonym monitoring Grafana i jej stos są pomijane.

GitHub Actions

  1. Przenieś archestack/github-actions.yml do .github/workflows/archestack.yml: GitHub uruchamia workflowy tylko z tego folderu.
  2. W Settings, Environments utwórz archestack-dev z HOST i ADMIN_EMAIL jako zmiennymi i trzema hasłami jako sekretami, a do tego z sekretem KUBECONFIG: tym, co wypisuje kubeconfig.sh. W prywatnym repozytorium środowiska wymagają GitHub Pro, Team albo Enterprise.
  3. Uruchom workflow w 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 }}
  • Push do main, który zmienia archestack/, wdraża na środowisko deweloperskie z obrazami latest, tak jak robi to pipeline Azure DevOps.
  • concurrency nie pozwala dwóm uruchomieniom wdrażać na to samo środowisko w tym samym czasie.
  • kubectl ma przypiętą wersję. Niech różni się od wersji Twojego klastra najwyżej o jedną wersję minor.

GitLab CI

  1. Dołącz plik zestawu we własnym .gitlab-ci.yml repozytorium albo utwórz taki, który zawiera tylko to:
    include:
      - local: archestack/gitlab-ci.yml
  2. W Settings, CI/CD, Variables dodaj te pięć zmiennych z zakresem środowiska archestack-dev, z hasłami jako maskowanymi, a do tego KUBECONFIG typu File: to, co wypisuje kubeconfig.sh. Oznacz je wszystkie jako chronione, żeby dostawały je tylko chronione gałęzie.
  3. Uruchom pipeline w Build, Pipelines, New pipeline i tam wybierz środowisko.
# 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
  • Push do gałęzi domyślnej, który zmienia archestack/, wdraża na środowisko deweloperskie z obrazami latest.
  • Job działa w etapie deploy, który GitLab ma, chyba że Twój .gitlab-ci.yml wymienia własne etapy bez niego.
  • Agent GitLab dla Kubernetesa też działa: ustaw KUBE_CONTEXT na kontekst agenta zamiast KUBECONFIG.
  • resource_group nie pozwala dwóm pipeline'om wdrażać na to samo środowisko w tym samym czasie.
  • Obraz i kubectl mają przypięte wersje. Niech kubectl różni się od wersji Twojego klastra najwyżej o jedną wersję minor.

Co uruchamiają GitHub Actions i GitLab CI

Oba uruchamiają deploy.sh, czyli trzy kroki pipeline'u Azure DevOps jako jeden skrypt:

#!/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

Logowanie do klastra

GitHub Actions i GitLab CI logują się kubeconfigiem, który wypisuje kubeconfig.sh: kontem usługi (service account) z dostępem do namespace archestack i do niczego więcej, z tokenem, który nie wygasa. Uruchom skrypt raz na każdy klaster, jako ktoś, kto może tam tworzyć role:

#!/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
  • Nie Twój własny kubeconfig. Niesie Twoje uprawnienia do całego klastra, a na AKS z logowaniem przez Entra ID prosi osobę o zalogowanie się, czego pipeline nie potrafi.
  • Odebranie dostępu to usunięcie Secretu archestack-deploy-token w namespace. Uruchom skrypt ponownie, żeby dostać nowy.

Pliki

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

Ingress to jedyny plik, który musi pasować do Twojego klastra:

# 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
  • Bez przepisywania. API i builder oczekują prefiksu /archestack (Http__PathBase w api.yml, BASE_PATH w web.yml), więc ingress przekazuje ścieżki bez zmian.
  • Duże pliki i długie połączenia. Rozmiar body pozwala na import pakietów i przesyłanie plików, a limity czasu utrzymują otwarty WebSocket aktualizacji na żywo i długie kopie zapasowe.
  • Żadnego proxy logowania przed nim. Adnotacja oauth2 zastąpiłaby token, który wysyła każde wywołanie API. Archestack sam loguje użytkowników. Ingress Grafany może mieć takie proxy.

Aktualizacja

Uruchom pipeline ponownie z innym tagiem obrazu. latest bierze najnowsze wydanie; wersja taka jak 1.0.42 mówi dokładnie, co działa, i pozwala przenieść tę samą wersję z testów na produkcję. Pod API jest zastępowany, a nie uruchamiany obok starego, bo jego dyski można podłączyć tylko do jednego poda naraz, więc API jest niedostępne przez minutę potrzebną na start. Wszystko, co utworzysz, jest na dyskach i zostaje.

Pułapki

  • Hasło do bazy danych ustawia się raz. PostgreSQL przyjmuje je przy pierwszym starcie na pustym dysku. Późniejsza zmiana w systemie CI nie zmienia go w bazie danych, a wtedy API nie może się już połączyć.
  • Hasło administratora jest używane raz, do utworzenia pierwszego administratora. Później zmieniaj je w Archestack, a nie w systemie CI.
  • Kopie zapasowe zostają w klastrze. Są zapisywane na dysku archestack-backups. Kopiuj je też w inne miejsce.
  • Powrót do starszej wersji może się nie udać, gdy nowsza zmigrowała już bazę danych. Najpierw przetestuj aktualizację na archestack-tst.

Co dalej

Wdrażanie z repozytorium przenosi Twoje aplikacje z gita do tych środowisk. Hosting na AKS dodaje własne nazwy hostów, zarządzaną bazę danych, kilka replik API i nocne aktualizacje.