Documentation for a newer release is available.
View Latest
Esta página no está disponible actualmente en Español. Si lo necesita, póngase en contacto con el servicio de asistencia de Icon (correo electrónico)
Kubernetes Deployment Guidelines
The following guide will provision both Ingestion and Inquiry service components, each with 3 nodes.
Create Service Account
Create a serviceAccount.yaml file and copy the following admin service account manifest. This allows for underlying IPF Pods to use the Kubernetes API to bootstrap the underlying Akka cluster.
Service Account
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: ipf
namespace: ipf
Role
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: ipf
namespace: ipf
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
Role Binding
---
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
The serviceAccount.yaml creates a Kubernetes role, ServiceAccount and binds this role to the serviceAccount.
Create the service account using kubectl
kubectl apply -f serviceAccount.yaml
Create ODS-Ingestion Manifests
Create ods-ingestion.yaml manifests using the following contents:
Ingestion Deployment
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
Ingestion Configmap
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}
}
}
}
}
Ingestion Service
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
Ingestion Ingress
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
Create ODS-Inquiry Manifests
Create ods-inquiry.yaml manifests using the following contents:
Inquiry Deployment
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
Inquiry 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
}
Inquiry Service
apiVersion: v1
kind: Service
metadata:
name: ods-inquiry
spec:
selector:
app: ods-inquiry
ports:
- protocol: TCP
port: 8080
targetPort: 8080
name: server-port
Inquiry Ingress
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