EJECUTAR 1 - Ejecutándose en Kubernetes
Requisitos previos
Para ejecutar este tutorial, usted necesitará ejecutar un kubernetes agrupar localmente: A continuación se presentan algunas opciones posibles que puede utilizar:
Instale y inicie su solución deseada para ejecutar un Kubernetes agrupación local.
Kubernetes(K8s) es un sistema de código abierto para automatizar el despliegue, la escalabilidad y la gestión de aplicaciones en contenedores.
Despliegue del Tutorial de IPF en Kubernetes
Para ejecutar el tutorial de IPF como una aplicación en clúster en Kubernetes, haremos lo siguiente:
Paso 2 - Crear Cuenta de Servicio
Cree un 'serviceAccount.yaml' archivo y copie el siguiente manifiesto de cuenta de servicio administrativo.
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: ipf-tutorial
namespace: ipf-tutorial
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: ipf-tutorial
namespace: ipf-tutorial
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: ipf-tutorial
namespace: ipf-tutorial
subjects:
- kind: ServiceAccount
name: ipf-tutorial
namespace: ipf-tutorial
roleRef:
kind: Role
name: ipf-tutorial
apiGroup: rbac.authorization.k8s.io
La 'serviceAccount.yaml' crea un rol de ipf-tutorial, una cuenta de servicio 'ipf-tutorial' y vincula el 'Rol' a la cuenta de servicio.
El rol 'ipf-tutorial' tiene todos los permisos para consultar la API para los pods de IPF que se ejecutan dentro del espacio de nombres.
Ahora cree la cuenta de servicio utilizando kubectl.
kubectl apply -f serviceAccount.yaml
Paso 3 - Crear Configmap
Cree un archivo Configmap llamado 'configmap.yaml y copie el siguiente manifiesto de configuración.
apiVersion: v1
kind: ConfigMap
metadata:
name: ipf-tutorial-service-cm
namespace: ipf-tutorial
data:
application.conf: |
akka {
loglevel = "INFO"
cluster {
# undefine seed nodes to allow for Kubernetes to describe cluster topography
seed-nodes = []
sharding {
distributed-data.majority-min-cap = 2
}
}
# Use Kubernetes API to discover the cluster
discovery {
kubernetes-api {
pod-label-selector = "app=%s"
}
}
actor.provider = cluster
}
akka.remote.artery.canonical.hostname = ${POD_IP}
akka.management {
# available from Akka management >= 1. 0. 0
health-checks {
readiness-path = "health/ready"
liveness-path = "health/alive"
}
# use the Kubernetes API to create the cluster
cluster.bootstrap {
contact-point-discovery {
service-name = "ipf-tutorial-service"
discovery-method = kubernetes-api
required-contact-point-nr = 2
}
}
}
management.endpoints.web.exposure.include = "*"
flow-restart-settings {
min-backoff = 1s
max-backoff = 5s
random-factor = 0. 25
max-restarts = 5000
max-restarts-within = 3h
}
ipf.behaviour.retries.initial-timeout = 3s
ipf.behaviour.config.action-recovery-delay = 3s
#Change the Mongo URL for your specific setup
ipf {
mongodb.url = "mongodb://ipf-mongo:27017/ipf"
processing-data.egress {
enabled = true
transport = http
http {
client {
host = "ipf-developer-service"
port = 8081
endpoint-url = "/ipf-processing-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" level="WARN" />
<root level="INFO">
<appender-ref ref="ASYNC"/>
</root>
</configuration>
Ahora cree el mapa de configuración utilizando kubectl.
kubectl apply -f configmap.yaml
Paso 4 - Crear imagePullSecret
| Sustituir docker-servidor,docker-nombre de usuario y docker-contraseña para valores apropiados |
kubectl create secret docker-registry registrysecret --docker-server=**** --docker-username=********* --docker-password=******* --namespace ipf-tutorial
Paso 5 - Crear MongoDB
Cree un archivo de statefulset llamado 'infrastructure'.yaml y copie el siguiente manifiesto. Esto crea MongoDB que es requerido por la aplicación del tutorial
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongo
namespace: ipf-tutorial
spec:
selector:
matchLabels:
role: mongo
serviceName: "ipf-mongo"
replicas: 1
template:
metadata:
labels:
role: mongo
spec:
imagePullSecrets:
- name: "registrysecret"
terminationGracePeriodSeconds: 10
containers:
- name: mongo
image:mongo:latest
imagePullPolicy: Always
ports:
- containerPort: 27017
- name: mongo-exporter
image:bitnami/mongodb-exporter:0. 11. 2
imagePullPolicy: IfNotPresent
ports:
- name: mongo-exporter
containerPort: 9216
protocol: TCP
env:
- name: MONGODB_URI
value: "mongodb://localhost:27017"
---
apiVersion: v1
kind: Service
metadata:
name: ipf-mongo
namespace: ipf-tutorial
labels:
name: ipf-mongo
type: mongo
spec:
ports:
- port: 27017
name: mongo
protocol: TCP
targetPort: 27017
selector:
role: mongo
kubectl apply -f infrastructure.yaml
Paso 6 - Crear Aplicación para Desarrolladores
Cree un archivo de implementación llamado developerApp.yaml y copie el siguiente manifiesto. Esto crea la aplicación de desarrollador que es requerida por la aplicación tutorial para ver el flujo.events
${registry_service} - sustituto para la ubicación de la docker registro
apiVersion: apps/v1
kind: Deployment
metadata:
name: ipf-developer-service
namespace: ipf-tutorial
annotations:
prometheus.io/scrape: "true"
prometheus.io/path: "/"
prometheus.io/port: "9001"
spec:
replicas: 1
selector:
matchLabels:
app: ipf-developer-service
product: ipfv2
template:
metadata:
annotations:
prometheus.io/scrape: "true"
prometheus.io/path: "/"
prometheus.io/port: "9001"
labels:
app: ipf-developer-service
product: ipfv2
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- ipf-developer-service
topologyKey: kubernetes.io/hostname
securityContext:
fsGroup: 1000
runAsUser: 1000
serviceAccountName: ipf-tutorial
imagePullSecrets:
- name: "registrysecret"
containers:
- name: ipf-developer-service
image: $\{registry_service}/ipf-developer-app:latest
imagePullPolicy: Always
ports:
- name: actuator
containerPort: 8081
env:
- name: "POD_NAME"
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: "POD_IP"
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: "KUBERNETES_NAMESPACE"
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: "IPF_JAVA_ARGS"
value: "-Dma.glasnost.orika.writeClassFiles=false -Dma.glasnost.orika.writeSourceFiles=false"
resources:
limits:
memory: "2Gi"
requests:
memory: "2Gi"
cpu: "1000m"
volumeMounts:
- mountPath: /ipf-developer-app/conf/logback.xml
name: config-volume
subPath: logback.xml
- mountPath: /ipf-developer-app/conf/application.conf
name: config-volume
subPath: application.conf
volumes:
- name: config-volume
configMap:
name: ipf-developer-service-cm
---
apiVersion: v1
kind: ConfigMap
metadata:
name: ipf-developer-service-cm
namespace: ipf-tutorial
data:
application.conf: |
flow-restart-settings {
min-backoff = 1s
max-backoff = 5s
random-factor = 0.25
max-restarts = 5
max-restarts-within = 10m
}
spring.data.mongodb.uri = ${?ipf.mongodb.url}
actor-system-name = ipf-developer
ipf.mongodb.url = "mongodb://ipf-mongo:27017/ipf"
ods.security.oauth.enabled = false
application.write.url="http://localhost:8080"
ipf.processing-data.ingress.transport=http
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" level="WARN" />
<root level="INFO">
<appender-ref ref="ASYNC"/>
</root>
</configuration>
---
apiVersion: v1
kind: Service
metadata:
name: ipf-developer-service
namespace: ipf-tutorial
labels:
name: ipf-developer-service
spec:
type: NodePort
ports:
- protocol: TCP
port: 8081
targetPort: 8081
nodePort: 30200
name: ipf-developer-service
selector:
app: ipf-developer-service
Paso 7 - Crear un Despliegue
Cree un archivo de implementación llamado 'deployment.yaml y copie el siguiente manifiesto de implementación.
${registry_service} - sustituto para la ubicación de la docker registro ${tutorial-service-version} - versión de la aplicación tutorial
apiVersion: apps/v1
kind: Deployment
metadata:
name: ipf-tutorial-service
namespace: ipf-tutorial
annotations:
prometheus.io/scrape: "true"
prometheus.io/path: "/"
prometheus.io/port: "9001"
spec:
replicas: 3
selector:
matchLabels:
app: ipf-tutorial-service
product: ipfv2
template:
metadata:
annotations:
prometheus.io/scrape: "true"
prometheus.io/path: "/"
prometheus.io/port: "9001"
labels:
app: ipf-tutorial-service
product: ipfv2
spec:
# affinity:
# podAntiAffinity:
# requiredDuringSchedulingIgnoredDuringExecution:
# - labelSelector:
# matchExpressions:
# - key: app
# operator: In
# values:
# - ipf-tutorial-service
# topologyKey: kubernetes.io/hostname
securityContext:
fsGroup: 1000
runAsUser: 1000
serviceAccountName: ipf-tutorial
imagePullSecrets:
- name: "registrysecret"
containers:
- name: ipf-tutorial-service
image: ${registry_service}/ipf-tutorial-app:${tutorial-service-version}
imagePullPolicy: Always
ports:
- name: actuator
containerPort: 8080
- name: akka-artery
containerPort: 55001
- name: akka-management
containerPort: 8558
- name: akka-metrics
containerPort: 9001
livenessProbe:
failureThreshold: 5
httpGet:
path: /health/alive
port: akka-management
scheme: HTTP
initialDelaySeconds: 30
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
readinessProbe:
failureThreshold: 3
httpGet:
path: /health/ready
port: akka-management
scheme: HTTP
initialDelaySeconds: 30
periodSeconds: 10
successThreshold: 10
timeoutSeconds: 1
env:
- name: "POD_NAME"
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: "POD_IP"
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: "KUBERNETES_NAMESPACE"
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: "IPF_JAVA_ARGS"
value: "-Dma.glasnost.orika.writeClassFiles=false -Dma.glasnost.orika.writeSourceFiles=false"
resources:
limits:
memory: "2Gi"
requests:
memory: "2Gi"
cpu: "1000m"
volumeMounts:
- mountPath: /ipf-tutorial-app/conf/logback.xml
name: config-volume
subPath: logback.xml
- mountPath: /ipf-tutorial-app/conf/application.conf
name: config-volume
subPath: application.conf
volumes:
- name: config-volume
configMap:
name: ipf-tutorial-service-cm
---
apiVersion: v1
kind: Service
metadata:
name: ipf-tutorial-service
namespace: ipf-tutorial
labels:
name: ipf-tutorial-service
spec:
type: NodePort
ports:
- protocol: TCP
port: 8080
targetPort: 8080
nodePort: 30100
name: ipf-tutorial-service
selector:
app: ipf-tutorial-service
| las reglas de afinidad (comentadas), si se utilizan, son una forma de especificar dónde/en qué nodos deben estar los pods scheduled. Esto puede ser útil para asegurar que los pods sean scheduled en diferentes nodos, por ejemplo. |
En este IPF Kubernetes en la implementación hemos utilizado lo siguiente:
-
securityContextpara el pod de IPF -
Sonda de vivacidad y preparación para monitorear la salud del pod IPF.
-
Archivos de configuración de aplicación y registro almacenados como Kubernetes Elementos de ConfigMap.
Cree la implementación utilizando kubectl.
kubectl apply -f deployment.yaml
Verifique el estado de la implementación.
kubectl get deployments -n ipf-tutorial
Ahora, puede obtener los detalles de implementación utilizando el siguiente comando.
kubectl describe deployments --namespace=ipf-tutorial
Envíe un pago utilizando el siguiente comando.
curl -X POST http://<cluster-node-ip-address>:30100/submit | jq
Verifique el pago en la aplicación para desarrolladores en la siguiente URL.
http://<cluster-node-ip-address>:30200/explorer.html[NOTA]
Consulte la documentación de la opción de clúster elegida sobre cómo obtener la dirección IP del nodo. Algunas opciones posibles son:
'kubectl get nodes -o wide', 'minikube ip'.