HTM Configuración de Despliegue del Servidor

1. Nombre de la imagen y versión

Para implementar el Human Task Manager(HTM) servidor, usted necesita extraer el Docker imagen del registro de contenedores de ICON Solutions.

Nombre de la imagen:

registry.ipf.iconsolutions.com/human-task-manager-app

Versioning:

Seguimos semántica versioning usando el MAJOR. MINOR. PATCH formato (por ejemplo,1. 3. 9). Siempre debe hacer referencia a una etiqueta de versión específica para garantizar la consistencia en el despliegue y evitar actualizaciones no intencionadas.

Ejemplo de configuración
image:name: registry.ipf.iconsolutions.com/human-task-manager-app
  tag: 1. 3. 9
Evite usar el `latest` etiqueta en entornos de producción.

2. Ejemplo Kubernetes Manifiestos

El siguiente ejemplo demuestra un despliegue básico de la Human Task Manager(HTM) servidor utilizando Kubernetes manifiestos. Estos pueden ser utilizados como punto de partida para escribir gráficos de Helm o directos K8s despliegues.

Este ejemplo incluye:

  • ConfigMap para la configuración de la aplicación

  • Deployment para el HTM aplicación

  • Service para exponer el HTM aplicación internamente

  • Ingress configuración

ConfigMap:`htm-cm`
apiVersion: v1
kind: ConfigMap
metadata:
  name: htm-cm
data:
  application.conf: |-
    ipf.mongodb.url = "${ipf.mongodb.url}"
    ipf.htm {
      event-processor.delegating.enabled = ${ipf.htm.event-processor.delegating.enabled}
      mongodb.purging.time-to-live = 15minutes
    }

    management.health.mongo.enabled = false

    event-processor {
      restart-settings {
        min-backoff = 500 millis
        max-backoff = 1 seconds
      }
    }

    akka {
      actor.provider = cluster

      remote.artery.canonical.hostname = ${POD_IP}
      # Use Kubernetes API to discover the cluster
      discovery {
        kubernetes-api {
          pod-label-selector = "app=%s"
        }
      }

      management {
        # use the Kubernetes API to create the cluster
        cluster.bootstrap {
          contact-point-discovery {
            discovery-method          = kubernetes-api
            service-name              = ${AKKA_CLUSTER_BOOTSTRAP_SERVICE_NAME}
            required-contact-point-nr = 1
            required-contact-point-nr = ${?REQUIRED_CONTACT_POINT_NR}
          }
        }
        # available from Akka management >= 1.0.0
        health-checks {
          readiness-path  = "health/ready"
          liveness-path   = "health/alive"
        }
      }

      cluster {
        seed-nodes = []
        downing-provider-class = "akka.cluster.sbr.SplitBrainResolverProvider"
        split-brain-resolver {
          active-strategy = keep-majority
          stable-after = 20s
        }
        sharding {
          remember-entities = off
          handoff-timeout = 8s
          least-shard-allocation-strategy.rebalance-absolute-limit = 20
          rebalance-interval = 2s
          number-of-shards = 100,
          distributed-data.majority-min-cap = ${akka.management.cluster.bootstrap.contact-point-discovery.required-contact-point-nr}
          snapshot-after = 50
        }
      }
    }

  logback.xml: |-
    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
        <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
            <target>System.out</target>
            <encoder>
                <pattern>[%date{ISO8601}] [%level] [%logger] [%marker] [%thread] - %msg%n</pattern>
            </encoder>
        </appender>

        <logger name="akka.stream.scaladsl.RestartWithBackoffSource" level="warn"/>
        <logger name="com.iconsolutions.ipf.core.connector" level="INFO"/>
        <logger name="com.iconsolutions.ipf.core.platform.read.processor" level="INFO"/>
        <logger name="com.iconsolutions.akka.persistence.mongodb" level="INFO"/>
        <logger name="com.iconsolutions.ipf.htm.notification.autoconfig.TaskNotificationAutoConfiguration" level="WARN"/>
        <logger name="com.iconsolutions.ipf.htm.task.task_manager.handlers.commands.processors.builtin.TaskManagerActionRevivalProcessor" level="DEBUG"/>

        <appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
            <queueSize>8192</queueSize>
            <neverBlock>true</neverBlock>
            <appender-ref ref="CONSOLE" />
        </appender>

        <root level="info">
            <appender-ref ref="ASYNC"/>
        </root>
    </configuration>
Servicio y Despliegue
apiVersion: v1
kind: Service
metadata:
  labels:
    app: human-task-manager
    product: ipfv2
  name: human-task-manager
spec:
  ports:
    - name: server-port
      port: 8080
      protocol: TCP
      targetPort: 8080
  selector:
    app: human-task-manager
    product: ipfv2
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: human-task-manager
  annotations:
    prometheus.io/scrape: "true"
    prometheus.io/path: "/"
    prometheus.io/port: "9001"
  labels:
    app: human-task-manager
    product: ipfv2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: human-task-manager
      product: ipfv2
  template:
    metadata:
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/path: "/"
        prometheus.io/port: "9001"
      labels:
        app: human-task-manager
        product: ipfv2
      name: human-task-manager
    spec:
      containers:
        - name: htm
          image: registry.ipf.iconsolutions.com/human-task-manager-app
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 8080
            - name: debug-port
              containerPort: 5005
          livenessProbe:
            failureThreshold: 5
            httpGet:
              path: /actuator/health/liveness
              port: http
              scheme: HTTP
            initialDelaySeconds: 30
            periodSeconds: 2
            successThreshold: 1
            timeoutSeconds: 1
          readinessProbe:
            failureThreshold: 5
            httpGet:
              path: /actuator/health/readiness
              port: http
              scheme: HTTP
            initialDelaySeconds: 30
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 2
          env:
            - name: "POD_NAME"
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: "IPF_JAVA_ARGS"
              value: " -XX:+UseContainerSupport -XX:MaxRAMPercentage=60 -XX:InitialRAMPercentage=60
            -XX:-PreferContainerQuotaForCPUCount -Dma.glasnost.orika.writeClassFiles=false
            -Dma.glasnost.orika.writeSourceFiles=false"
            - name: "POD_IP"
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
            - name: "KUBERNETES_NAMESPACE"
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            - name: "AKKA_CLUSTER_BOOTSTRAP_SERVICE_NAME"
              valueFrom:
                fieldRef:
                  fieldPath: metadata.labels['app']
          resources:
            requests:
              memory: 4Gi
              cpu: "4"
            limits:
              memory: 4Gi
          volumeMounts:
            - mountPath: /human-task-manager-app/conf/logback.xml
              name: config-volume
              subPath: logback.xml
            - mountPath: /human-task-manager-app/conf/application.conf
              name: config-volume
              subPath: application.conf
      volumes:
        - name: config-volume
          configMap:
            name: htm-cm
        - name: keystore
          secret:
            secretName: keystore
Ejemplo de Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: human-task-manager
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt
    kubernetes.io/ingress.class: nginx
spec:
  rules:
    - host: htm.${ipf.ingress-domain}
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: human-task-manager
                port:
                  number: 8080
Marcadores de posición como `${ipf.mongodb.url}` y `${ipf.ingress-domain}` debe ser reemplazado con valores reales específicos de su entorno antes de la implementación.
Estos son manifiestos mínimos para demostración. Puede que necesite ampliarlos según su infraestructura (por ejemplo, secretos, TLS, almacenamiento persistente).

3. Requisitos de Infraestructura

El HTM El servidor depende de componentes de infraestructura externa que deben estar disponibles y configurados correctamente antes de la implementación.

MongoDB

HTM usos MongoDB como su almacén de datos principal.
  • Debe aprovisionar un MongoDB instancia accesible desde el clúster.

  • El MongoDB la cadena de conexión debe ser proporcionada a través del archivo de configuración utilizando el siguiente marcador de posición ipf.mongodb.url

Kafka

HTM puede enviar notifications cuando las tareas están cerradas, utilizando Apache Kafka.
  • Debe tener un Kafka clúster accesible desde su entorno.

  • Crear Kafka temas para tarea cerrada notifications y registros de tareas.

  • Configure los nombres de los temas en el archivo de configuración a través de la variable htm.kafka.producer.topic y ipf.htm.async.register-task.kafka.producer.topic

4. Requisitos de Recursos Básicos

Para garantizar un rendimiento estable, el HTM el servidor requiere los siguientes recursos básicos:

  • CPU: Mínimo de 4 núcleos

  • Memoria: Se recomienda 4 GB

Estos valores deben considerarse como el límite inferior para los entornos de producción; los valores reales deben determinarse siempre mediante la realización de pruebas de carga adecuadas en días de juego.