Azure Container Instance (ACI) — Instalación de Standalone

Support DQE
Support DQE
  • Actualización

Despliegue DQE One Standalone como un grupo autónomo de Azure Container Instance (ACI) con NGINX, Redis y PostgreSQL, expuesto a través de un Application Gateway.

Nota: todos los elementos descritos a continuación son recomendaciones de DQE, basadas en la experiencia de despliegue con distintos clientes. El cliente es responsable de integrar la solución en su propia arquitectura. Un arquitecto familiarizado con el contexto del cliente y la infraestructura interna debe alinear las recomendaciones de DQE con la infraestructura del cliente.

1. Arquitectura

Este documento describe cómo desplegar el backend de DQE One Standalone como un grupo de contenedores de Azure Container Instance (ACI). Todos los contenedores del grupo comparten el mismo espacio de nombres de red y se comunican a través de localhost. Un Application Gateway expone la aplicación mediante HTTPS y enruta el tráfico hacia el ACI a través de una VNET privada.

Arquitectura recomendada

Internet (HTTPS port 443)
         |
Application Gateway (public IP + WAF)
         |
    Private VNET subnet
         |
ACI Container Group (private IP)
         |
    NGINX sidecar (port 443)
         |
  DQE One Standalone (port 8000, internal)
         |
  Redis - PostgreSQL (internal)

Medidas de seguridad

  • Application Gateway: termina el tráfico HTTPS y lo enruta hacia el ACI a través de la VNET privada. Utilice el WAF para restringir los rangos de IP entrantes.
  • VNET: aísla el ACI del acceso directo a internet público. Todo el tráfico proveniente del Application Gateway pasa a través de una subred privada.
  • Certificado SSL: gestionado a nivel del Application Gateway o a nivel de NGINX dentro del ACI.
  • Secretos: utilice secureValue en el YAML del grupo de contenedores para todos los valores sensibles (contraseñas, claves de licencia, claves de cifrado).

Dimensionamiento recomendado

Contenedor CPU Memoria
nginx 0.25 vCPU 0.5 GB
redis 0.5 vCPU 1.0 GB
postgres 0.5 vCPU 1.0 GB
dqeone 1.0 vCPU 2.0 GB
Total 2.25 vCPU 4.5 GB

Los grupos de contenedores ACI están limitados a 4 vCPU y 16 GB de memoria por grupo.

2. Instalación

2.1. Azure CLI

Azure CLI debe estar instalado en su máquina local.

Linux / macOS

curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash

Windows

Consulte la documentación de Microsoft.

2.2. Crear un Application Gateway

El Application Gateway expone el ACI con una dirección IP pública y un nombre DNS. También gestiona la terminación HTTPS y el filtrado de IP mediante el WAF.

Para obtener información completa sobre la configuración, consulte la documentación de Microsoft Application Gateway.

Pestaña Basic

Seleccione su suscripción, grupo de recursos y región. Elija el nivel WAF V2 para habilitar el Web Application Firewall.

Política WAF

Cree una nueva política WAF desde el campo WAF policy. Utilice el WAF para definir los rangos de IP entrantes autorizados a llamar al Application Gateway (por ejemplo, su red corporativa o rangos de IP específicos de socios).

VNET

Cree una nueva red virtual (VNET) desde el campo Virtual network. Esta VNET conecta el Application Gateway con el ACI. Todo el tráfico entre ambos pasa a través de esta red privada.

Frontends

Cree una nueva dirección IP pública. Esta es la dirección IP expuesta externamente y utilizada para enrutar el tráfico hacia el ACI.

Backends

Cree un nuevo grupo de backend. Déjelo vacío por ahora — la dirección IP privada del ACI se añade después de que este haya sido desplegado (sección 3.3).

Configuración — Reglas de enrutamiento

Cree una regla de enrutamiento con:

  • Listener: HTTPS en el puerto 443, con su certificado SSL.
  • Backend target: el grupo de backend creado anteriormente.
  • Backend setting: HTTP en el puerto 80 (el tráfico entre el Application Gateway y el ACI viaja a través de la VNET privada y no requiere HTTPS internamente).

Haga clic en Review + create para desplegar el Application Gateway.

2.3. Añadir una subred VNET para el ACI

En la VNET creada en la sección 2.2, cree una nueva subred dedicada al ACI. Delegue esta subred a Microsoft.ContainerInstance/containerGroups.

Anote el ID de recurso completo de la subred — es necesario en el YAML del grupo de contenedores:

/subscriptions/SUBSCRIPTION_ID/resourceGroups/RESOURCE_GROUP/providers/Microsoft.Network/virtualNetworks/VNET_NAME/subnets/SUBNET_NAME

2.4. Configurar Azure Storage

Los contenedores ACI utilizan Azure File Shares para el almacenamiento persistente. Cree una cuenta de almacenamiento y, a continuación, cree los siguientes recursos compartidos de archivos:

Recurso compartido de archivos Propósito
nginxconf Archivos de configuración de NGINX y certificado SSL
redisdata Datos persistentes de Redis
postgresdata Directorio de datos de PostgreSQL

Paso 1 — Crear la cuenta de almacenamiento:

az storage account create \
  --name MY_STORAGE_ACCOUNT \
  --resource-group MY_RESOURCE_GROUP \
  --location MY_LOCATION \
  --sku Standard_LRS

Paso 2 — Recuperar la clave de la cuenta de almacenamiento:

az storage account keys list \
  --account-name MY_STORAGE_ACCOUNT \
  --resource-group MY_RESOURCE_GROUP \
  --query "[0].value" -o tsv

Paso 3 — Crear los recursos compartidos de archivos:

az storage share create --name nginxconf --account-name MY_STORAGE_ACCOUNT
az storage share create --name redisdata --account-name MY_STORAGE_ACCOUNT
az storage share create --name postgresdata --account-name MY_STORAGE_ACCOUNT

Nota sobre el almacenamiento de PostgreSQL: Azure File Shares utiliza el protocolo SMB, que puede no admitir todas las operaciones del sistema de archivos POSIX requeridas por PostgreSQL. Si el contenedor postgres no logra iniciarse, consulte la sección 5 para conocer la alternativa recomendada utilizando Azure Database for PostgreSQL.

2.5. Crear un Log Analytics Workspace

Un Log Analytics workspace centraliza los registros de los contenedores y permite la supervisión mediante Azure Monitor. Los registros se almacenan durante 30 días de forma predeterminada.

Paso 1 — Crear el workspace:

az monitor log-analytics workspace create \
  --resource-group MY_RESOURCE_GROUP \
  --workspace-name dqe-standalone-logs \
  --location MY_LOCATION

Paso 2 — Recuperar el Workspace ID:

az monitor log-analytics workspace show \
  --resource-group MY_RESOURCE_GROUP \
  --workspace-name dqe-standalone-logs \
  --query customerId -o tsv

Paso 3 — Recuperar la Workspace Primary Key:

az monitor log-analytics workspace get-shared-keys \
  --resource-group MY_RESOURCE_GROUP \
  --workspace-name dqe-standalone-logs \
  --query primarySharedKey -o tsv

Conserve el Workspace ID y la Primary Key — se necesitan en el YAML del grupo de contenedores (sección 2.7).

2.6. Configurar NGINX

NGINX actúa como proxy inverso dentro del grupo de contenedores ACI, reenviando las solicitudes entrantes al contenedor dqeone en el puerto 8000. Dado que todos los contenedores de un grupo ACI comparten el mismo espacio de nombres de red, el destino del proxy utiliza localhost.

Cree un archivo llamado default.conf con el siguiente contenido:

server {
    listen 80;

    location / {
        proxy_pass         http://localhost:8000;
        proxy_read_timeout 300s;
    }
}

Si el HTTPS se gestiona directamente a nivel del ACI (sin la descarga SSL del Application Gateway), añada un segundo bloque server para el puerto 443 y cargue los archivos de certificado SSL y clave en el recurso compartido de archivos nginxconf, bajo un subdirectorio ssl/.

Cargue default.conf en el recurso compartido de archivos nginxconf:

az storage file upload \
  --account-name MY_STORAGE_ACCOUNT \
  --share-name nginxconf \
  --source ./default.conf \
  --path default.conf

2.7. YAML del grupo de contenedores

Cree un archivo llamado container-group.yaml. Reemplace todos los marcadores de posición antes de desplegar. La siguiente tabla enumera todos los valores necesarios.

Marcador de posición Descripción
MY_LOCATION Región de Azure, por ejemplo westeurope
DQE_REGISTRY_LOGIN Nombre de usuario del registro proporcionado por DQE
DQE_REGISTRY_PASSWORD Contraseña del registro proporcionada por DQE
MY_STORAGE_ACCOUNT Nombre de la cuenta de almacenamiento creada en la sección 2.4
MY_STORAGE_ACCOUNT_KEY Clave de la cuenta de almacenamiento recuperada en el Paso 2 de la sección 2.4
LOG_ANALYTICS_WORKSPACE_ID Workspace ID recuperado en el Paso 2 de la sección 2.5
LOG_ANALYTICS_WORKSPACE_KEY Primary Key recuperada en el Paso 3 de la sección 2.5
SUBNET_RESOURCE_ID ID de recurso completo de la subred anotado en la sección 2.3
name: dqe-standalone
apiVersion: '2021-10-01'
location: MY_LOCATION
tags: {"docker-compose-application": "docker-compose-application"}

properties:
  containers:

    - name: nginx
      properties:
        image: nginx:latest
        ports:
          - protocol: TCP
            port: 80
        resources:
          requests:
            memoryInGB: 0.5
            cpu: 0.25
        volumeMounts:
          - name: nginxconf
            mountPath: /etc/nginx/conf.d

    - name: redis
      properties:
        image: dqeone.azurecr.io/dqe-one-redis:v1.0
        resources:
          requests:
            memoryInGB: 1.0
            cpu: 0.5
        volumeMounts:
          - name: redisdata
            mountPath: /data

    - name: postgres
      properties:
        image: dqeone.azurecr.io/dqe-one-postgres:v1.0
        resources:
          requests:
            memoryInGB: 1.0
            cpu: 0.5
        environmentVariables:
          - name: POSTGRES_USER
            value: dqeone
          - name: POSTGRES_PASSWORD
            secureValue: DATABASE_PASSWORD
          - name: POSTGRES_DB
            value: dqeone
        volumeMounts:
          - name: postgresdata
            mountPath: /var/lib/postgresql/data

    - name: dqeone
      properties:
        image: dqeone.azurecr.io/standalone:v1.4.0
        command:
          - "bash"
          - "./entrypoint.sh"
        ports:
          - protocol: TCP
            port: 8000
        resources:
          requests:
            memoryInGB: 2.0
            cpu: 1.0
        environmentVariables:
          - name: SFAPIVERSION
            value: v65.0
          - name: CREATE_SUPERUSER
            value: "true"
          - name: RUN_COLLECTSTATIC
            value: "false"
          - name: DQE_ONE_SERVER_ADMIN_USER
            value: ADMIN_USER
          - name: DQE_ONE_SERVER_ADMIN_PASSWORD
            secureValue: ADMIN_PASSWORD
          - name: DQE_CLIENT_LICENCE
            value: CLIENT_LICENCE
          - name: WEBSITE_HOSTNAME
            value: https://YOUR_DNS_NAME
          - name: SECRET_ENCRYPTION_KEY
            secureValue: SECRET_ENCRYPTION_KEY_VALUE
          - name: WAIT_HOSTS
            value: "localhost:6379"
          - name: WAIT_HOSTS_TIMEOUT
            value: "300"
          - name: WAIT_SLEEP_INTERVAL
            value: "5"
          - name: WAIT_HOST_CONNECT_TIMEOUT
            value: "30"
          - name: REDIS_URL
            value: redis://localhost:6379
          - name: PORT
            value: "8000"
          - name: DEBUG
            value: "false"
          - name: DB_USER
            value: dqeone
          - name: DB_PASSWORD
            secureValue: DATABASE_PASSWORD
          - name: DB_NAME
            value: dqeone
          - name: DB_HOST
            value: localhost
          - name: DB_VOLUME_PATH
            value: ./db/
          - name: DB_MAX_CAPACITY
            value: "8000000000"
          - name: AUTHORIZED_SFTP_HOSTS
            value: AUTHORIZED_SFTP_HOSTS

  imageRegistryCredentials:
    - server: dqeone.azurecr.io
      username: DQE_REGISTRY_LOGIN
      password: DQE_REGISTRY_PASSWORD

  diagnostics:
    logAnalytics:
      workspaceId: LOG_ANALYTICS_WORKSPACE_ID
      workspaceKey: LOG_ANALYTICS_WORKSPACE_KEY

  restartPolicy: Always

  ipAddress:
    ports:
      - protocol: TCP
        port: 80
    type: Private

  osType: Linux

  volumes:
    - name: nginxconf
      azureFile:
        shareName: nginxconf
        readOnly: false
        storageAccountName: MY_STORAGE_ACCOUNT
        storageAccountKey: MY_STORAGE_ACCOUNT_KEY
    - name: redisdata
      azureFile:
        shareName: redisdata
        readOnly: false
        storageAccountName: MY_STORAGE_ACCOUNT
        storageAccountKey: MY_STORAGE_ACCOUNT_KEY
    - name: postgresdata
      azureFile:
        shareName: postgresdata
        readOnly: false
        storageAccountName: MY_STORAGE_ACCOUNT
        storageAccountKey: MY_STORAGE_ACCOUNT_KEY

  subnetIds:
    - id: SUBNET_RESOURCE_ID

Importante: utilice las versiones de imagen proporcionadas por DQE. No las reemplace con la etiqueta latest.

Nota clave sobre redes en ACI: todos los contenedores comparten el mismo espacio de nombres de red. La comunicación entre contenedores utiliza localhost — por eso REDIS_URL es redis://localhost:6379 y DB_HOST es localhost, a diferencia de una configuración de Docker Compose donde se utilizan los nombres de servicio.

2.8. Variables de entorno

Variable Valor de ejemplo Descripción
SFAPIVERSION v65.0 Versión de la API de Salesforce utilizada por la aplicación.
CREATE_SUPERUSER true Crea la cuenta de administrador inicial durante el primer inicio.
RUN_COLLECTSTATIC false Ejecuta el comando collectstatic de Django durante el inicio. Configúrelo en false a menos que sea explícitamente necesario.
DQE_ONE_SERVER_ADMIN_USER Nombre de usuario de la cuenta de administrador inicial.
DQE_ONE_SERVER_ADMIN_PASSWORD Contraseña de la cuenta de administrador inicial. Utilice secureValue.
DQE_CLIENT_LICENCE Clave de licencia del cliente proporcionada por DQE.
WEBSITE_HOSTNAME https://myapp.example.com URL HTTPS pública. Debe coincidir con el nombre DNS que apunta al Application Gateway.
SECRET_ENCRYPTION_KEY Clave de cifrado para datos sensibles. Genérela una vez, nunca la cambie después del despliegue. Utilice secureValue.
WAIT_HOSTS localhost:6379 Servicio que se debe esperar antes de iniciar. Utiliza localhost en ACI.
WAIT_HOSTS_TIMEOUT 300 Tiempo máximo de espera, en segundos, para los servicios dependientes.
WAIT_SLEEP_INTERVAL 5 Retraso, en segundos, entre comprobaciones de disponibilidad.
WAIT_HOST_CONNECT_TIMEOUT 30 Tiempo de espera, en segundos, para cada intento de conexión.
REDIS_URL redis://localhost:6379 URL de conexión de Redis. Utiliza localhost en ACI.
PORT 8000 Puerto de escucha interno de la aplicación.
DEBUG false Modo de depuración. Debe ser false en producción.
DB_USER dqeone Nombre de usuario de PostgreSQL.
DB_PASSWORD Contraseña de PostgreSQL. Debe coincidir con POSTGRES_PASSWORD en el contenedor postgres. Utilice secureValue.
DB_NAME dqeone Nombre de la base de datos PostgreSQL.
DB_HOST localhost Nombre de host de PostgreSQL. Utiliza localhost en ACI. Configúrelo con el nombre de host del servidor gestionado si utiliza Azure Database for PostgreSQL.
DB_VOLUME_PATH ./db/ Ruta para el almacenamiento relacionado con la base de datos.
DB_MAX_CAPACITY 8000000000 Capacidad máxima de la base de datos, en bytes.
AUTHORIZED_SFTP_HOSTS depot-1.dqe-software.net Lista separada por comas de hosts SFTP autorizados.

Importante: la SECRET_ENCRYPTION_KEY debe generarse una vez y conservarse durante toda la vida del despliegue. Para generar una clave compatible:

python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"

3. Lanzador

3.1. Iniciar sesión en Azure

az login

3.2. Desplegar el grupo de contenedores

az container create -g MY_RESOURCE_GROUP -f container-group.yaml

Una vez finalizada la operación, recupere la dirección IP privada asignada al grupo de contenedores:

az container show \
  --resource-group MY_RESOURCE_GROUP \
  --name dqe-standalone \
  --query "ipAddress.ip" -o tsv

Esta dirección IP privada solo es accesible desde dentro de la VNET de Azure.

3.3. Configurar el grupo de backend del Application Gateway

Una vez desplegado el ACI, vaya a Azure Portal > Application Gateway > Backend pools > su grupo de backend > Edit.

Añada la dirección IP privada del ACI recuperada en el paso 3.2. Haga clic en Save.

3.4. Configurar la sonda de estado (health probe) del Application Gateway

La sonda de estado permite al Application Gateway verificar que la aplicación esté en ejecución. Vaya a Azure Portal > Application Gateway > Health probes > Add.

Configure la sonda para llamar a la ruta raíz de la aplicación mediante HTTP. Haga clic en Test. Si el estado muestra Healthy, el ACI está correctamente configurado y el Application Gateway puede enrutar el tráfico hacia él.

Haga clic en Add para guardar la sonda de estado.

3.5. Configurar el DNS

Contacte con sus administradores DNS para crear un registro DNS que apunte a la dirección IP pública del Application Gateway:

Tipo de registro Nombre Valor
A standalone.yourdomain.com IP pública del Application Gateway

3.6. Verificar la instalación

Compruebe que todos los contenedores estén en ejecución:

az container show \
  --resource-group MY_RESOURCE_GROUP \
  --name dqe-standalone \
  --query "containers[].{Name:name, State:instanceView.currentState.state}" \
  -o table

Salida esperada:

Name        State
--------    -------
nginx       Running
redis       Running
postgres    Running
dqeone      Running

Nota: ACI inicia todos los contenedores simultáneamente. El mecanismo WAIT_HOSTS gestiona el orden de arranque reintentando la conexión. Se espera un retraso de 1 a 2 minutos antes de que la aplicación esté completamente operativa en el primer inicio.

Una vez que todos los contenedores estén en ejecución y el DNS se haya propagado, navegue a https://standalone.yourdomain.com.

4. Direcciones IP a autorizar

Una vez que la aplicación esté en ejecución, configure el WAF o el firewall superior para autorizar los siguientes rangos de IP entrantes:

  • DQE Software Office Server: póngase en contacto con el soporte de DQE Software para obtener la dirección IP a autorizar.
  • DQE Deduplication Service: póngase en contacto con el soporte de DQE Software para obtener la dirección IP a autorizar.
  • DQE Quality Service: póngase en contacto con el soporte de DQE Software para obtener la dirección IP a autorizar.

Acción requerida: proporcione a DQE Software la dirección IP pública saliente utilizada por su infraestructura de Azure (NAT Gateway, Azure Firewall o equivalente) para que pueda ser autorizada en los servicios de DQE.

5. Solución de problemas

Ver los registros de los contenedores

Los registros de los contenedores están disponibles en Azure Monitor bajo la tabla ContainerInstanceLog_CL. También puede recuperarlos directamente mediante la CLI:

az container logs \
  --resource-group MY_RESOURCE_GROUP \
  --name dqe-standalone \
  --container-name CONTAINER_NAME

No autorizado al descargar imágenes

Verifique que:

  • la sección imageRegistryCredentials contenga el usuario y la contraseña correctos proporcionados por DQE;
  • todas las imágenes hagan referencia al registro de producción de DQE dqeone.azurecr.io;
  • las versiones de imagen coincidan con las proporcionadas por DQE.

El contenedor de PostgreSQL no logra iniciarse

Azure File Shares utiliza el protocolo SMB, que puede no admitir las operaciones del sistema de archivos POSIX requeridas por PostgreSQL. Si el contenedor postgres se reinicia repetidamente con errores de permisos, utilice en su lugar Azure Database for PostgreSQL — Flexible Server:

  • Elimine el contenedor postgres y el volumen postgresdata del YAML.
  • Configure DB_HOST con el nombre de host del servidor gestionado (por ejemplo: myserver.postgres.database.azure.com).
  • Actualice DB_USER, DB_PASSWORD y DB_NAME para que coincidan con las credenciales del servidor gestionado.

La sonda de estado del Application Gateway falla

Verifique que:

  • todos los contenedores del ACI muestren el estado Running;
  • el grupo de backend contenga la dirección IP privada correcta del ACI;
  • la subred esté correctamente delegada a Microsoft.ContainerInstance/containerGroups;
  • el NSG asociado a la subred permita el tráfico entrante en el puerto 80 desde la subred del Application Gateway.

¿Fue útil este artículo?

Usuarios a los que les pareció útil: 0 de 0