Kubernetes Directrices de Despliegue

La siguiente guía aprovisionará tanto los componentes del servicio de Ingesta como los de Consulta, cada uno con 3 nodos.

Diagram

Crear Espacio de Nombres

kubectl create namespace ipf

Crear Cuenta de Servicio

Crear un serviceAccount.yaml archivo y copie el siguiente manifiesto de cuenta de servicio de administración. Esto permite que los Pods de IPF subyacentes utilicen el Kubernetes API para iniciar la base subyacente Akka cluster.

Cuenta de Servicio
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: ipf
  namespace: ipf
Rol
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: ipf
  namespace: ipf
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "watch", "list"]
Vinculación de Roles
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: ipf
  namespace: ipf
subjects:
  - kind: ServiceAccount
    name: ipf-ods
    namespace: ipf
roleRef:
  kind: Role
  name: ipf
  apiGroup: rbac.authorization.k8s.io

El serviceAccount.yaml crea un Kubernetes rol, ServiceAccount y vincula este rol al serviceAccount.

Cree la cuenta de servicio utilizando kubectl

kubectl apply -f serviceAccount.yaml

Crear ODS-Manifiestos de Ingesta

Crear ods-ingestion.yaml manifiesta utilizando los siguientes contenidos:

Despliegue de Ingesta
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ods-ingestion
spec:
  serviceName: ods-ingestion
  replicas: 3
  selector:
    matchLabels:
      app: ods-ingestion
  template:
    metadata:
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/path: "/"
        prometheus.io/port: "9001"
      labels:
        app: ods-ingestion
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            - labelSelector:
                matchExpressions:
                  - key: app
                    operator: In
                    values:
                      - ods-ingestion
              topologyKey: kubernetes.io/hostname
      securityContext:
        fsGroup: 1000
        runAsUser: 1000
      serviceAccountName: ipf
      containers:
        - name: ods-ingestion
          image: registry.ipf.iconsolutions.com/ods-ingestion-app:latest
          imagePullPolicy: IfNotPresent
          ports:
            - name: akka-management
              containerPort: 8558
            - name: akka-artery
              containerPort: 55001
            - name: actuator
              containerPort: 8080
          env:
            - name: IPF_JAVA_ARGS
              value: "-XX:+UseContainerSupport -XX:-PreferContainerQuotaForCPUCount"
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: POD_IP
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
            - name: AKKA_CLUSTER_BOOTSTRAP_SERVICE_NAME
              valueFrom:
                fieldRef:
                  apiVersion: v1
                  fieldPath: metadata.labels['app']
          resources:
            limits:
              memory: 2Gi
            requests:
              memory: 2Gi
              cpu: 500m
          livenessProbe:
            failureThreshold: 5
            httpGet:
              path: /health/alive
              port: akka-management
              scheme: HTTP
            initialDelaySeconds: 30
            periodSeconds: 2
            successThreshold: 1
            timeoutSeconds: 1
          readinessProbe:
            failureThreshold: 3
            httpGet:
              path: /actuator/health
              port: actuator
              scheme: HTTP
            initialDelaySeconds: 30
            periodSeconds: 2
            successThreshold: 1
            timeoutSeconds: 1
          volumeMounts:
            - name: config-volume
              mountPath: /ods-ingestion-app/conf
            - name: keystore
              mountPath: /keystore
      volumes:
        - name: config-volume
          configMap:
            name: ods-ingestion-cm
        - name: keystore
          secret:
            secretName: keystore
Configmap de Ingesta
apiVersion: v1
kind: ConfigMap
metadata:
  name: ods-ingestion-cm
data:
  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 MDC: {%mdc}%n</pattern>
        </encoder>
      </appender>

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

      <logger name="akka.cluster" level="INFO" />

      <root level="INFO">
        <appender-ref ref="ASYNC"/>
      </root>

    </configuration>

  application.conf: |
    kafka_bootstrap_servers = "<< KAFKA_BOOTSTRAP_SERVERS >>"
    ipf {
      mongodb.url = "<< DATABASE_URL >>"
      processing-data.ingress {
        kafka {
          consumer {
            topic = "<< IPF_DATA_EGRESS_TOPIC_NAME >>"
            kafka-clients = ${common-kafka-client-settings} {
              group.id = "ods-group-id"
            }
          }
        }
      }
    }
    ods {
      persistence {
        indexing.enabled = false
        summary {
          retry {
            initial-timeout = 5s
            backoff-factor = 1
            max-attempts = 10
          }
          writer.buffering {
            enabled = true
            buffering-interval = 10ms
            buffer-size = 500
          }
        }
      }
    }
    common-kafka-client-settings {
      bootstrap.servers = ${kafka_bootstrap_servers}
      security.protocol = SSL
      ssl {
        protocol = SSL
        keystore {
          location = /keystore/kafka-client-keystore.p12
          password = password
        }
        truststore {
          location = /keystore/kafka-client-truststore.p12
          password = password
        }
      }
    }

    akka {
      kafka {
        consumer {
          kafka-clients = ${common-kafka-client-settings}
          kafka-clients {
            auto.offset.reset = earliest
          }
        }
      }
      cluster {
        seed-nodes             = []
        downing-provider-class = "akka.cluster.sbr.SplitBrainResolverProvider"
      }

      remote.artery {
        enabled            = on
        transport          = tcp
        canonical.hostname = ${POD_IP}
      }

      discovery {
        kubernetes-api {
          pod-label-selector = "app=%s"
        }
      }

      management {
        # available from Akka management >= 1.0.0
        health-checks {
          readiness-path  = "health/ready"
          liveness-path   = "health/alive"
        }
        http.hostname                 = ${POD_IP}
        cluster.bootstrap {
          contact-point-discovery {
            discovery-method          = kubernetes-api
            service-name              = ${AKKA_CLUSTER_BOOTSTRAP_SERVICE_NAME}
            required-contact-point-nr = ${ipf.service.required-contact-point-nr}
            required-contact-point-nr = ${?REQUIRED_CONTACT_POINT_NR}
          }
        }
      }
    }
Servicio de Ingesta
apiVersion: v1
kind: Service
metadata:
  name: ods-ingestion
spec:
  selector:
    app: ods-ingestion
  ports:
    - protocol: TCP
      port: 9001
      targetPort: 9001
      name: akka-metrics
    - protocol: TCP
      port: 8558
      targetPort: 8558
      name: akka-management
    - protocol: TCP
      port: 8080
      targetPort: 8080
      name: actuator
Ingesta Ingreso
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
  name: ods-ingestion-ingress
spec:
  rules:
    - host: ods-ingestion.<< DOMAIN_NAME >>
      http:
        paths:
          - pathType: Prefix
            path: /
            backend:
              service:
                name: ods-ingestion
                port:
                  number: 8080
  tls:
    - hosts:
        - ods-ingestion.<< DOMAIN_NAME >>
      secretName: ods-ingestion-cert

Crear ODS-Manifiestos de Consulta

Crear ods-inquiry.yaml manifiesta utilizando los siguientes contenidos:

Despliegue de Consulta
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ods-inquiry
spec:
  replicas: 1
  selector:
    matchLabels:
      app: ods-inquiry
  template:
    metadata:
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "8080"
        prometheus.io/path: "/actuator/prometheus"
      labels:
        app: ods-inquiry
    spec:
      securityContext:
        fsGroup: 1000
        runAsUser: 1000
      serviceAccountName: ipf
      containers:
        - name: ods-inquiry
          image: registry.ipf.iconsolutions.com/ods-inquiry-app:latest
          imagePullPolicy: IfNotPresent
          ports:
            - name: server-port
              containerPort: 8080
          env:
            - name: IPF_JAVA_ARGS
              value: "-XX:+UseContainerSupport -XX:-PreferContainerQuotaForCPUCount"
          resources:
            limits:
              memory: 2Gi
            requests:
              memory: 2Gi
              cpu: 500m
          livenessProbe:
            failureThreshold: 5
            httpGet:
              path: /actuator/health
              port: server-port
              scheme: HTTP
            initialDelaySeconds: 30
            periodSeconds: 2
            successThreshold: 1
            timeoutSeconds: 1
          readinessProbe:
            failureThreshold: 3
            httpGet:
              path: /actuator/health
              port: server-port
              scheme: HTTP
            initialDelaySeconds: 30
            periodSeconds: 2
            successThreshold: 1
            timeoutSeconds: 1
          volumeMounts:
            - name: config-volume
              mountPath: /ods-inquiry-app/conf
      volumes:
        - name: config-volume
          configMap:
            name: ods-inquiry-cm
Consulta Configmap
apiVersion: v1
kind: ConfigMap
metadata:
  name: ods-ingestion-cm
data:
  application.conf: |
    ipf.mongodb.url = "<< DATABASE_URL >>"
    ods {
      persistence.indexing.enabled = false
      security.oauth.enabled = false
    }  
Servicio de Consultas
apiVersion: v1
kind: Service
metadata:
  name: ods-inquiry
spec:
  selector:
    app: ods-inquiry
  ports:
    - protocol: TCP
      port: 8080
      targetPort: 8080
      name: server-port
Consulta de Ingreso
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
  name: ods-inquiry-ingress
spec:
  rules:
    - host: ods-inquiry.<< DOMAIN_NAME >>
      http:
        paths:
          - pathType: Prefix
            path: /
            backend:
              service:
                name: ods-inquiry
                port:
                  number: 8080
  tls:
    - hosts:
        - ods-inquiry.<< DOMAIN_NAME >>
      secretName: ods-inquiry-cert