Slide 1

Slide 1 text

Checklist pour concevoir une application dans le cloud: 10 conseils à l’attention des concepteurs et architectes 1

Slide 2

Slide 2 text

2022 Merci à nos sponsors

Slide 3

Slide 3 text

Alexandre Touret Architecte / Développeur #Java #API #CI #Cloud #Software_Craftsmanship 3 @touret_alex https://blog.touret.info

Slide 4

Slide 4 text

Un peu de contexte ... 1.

Slide 5

Slide 5 text

5

Slide 6

Slide 6 text

Technologies utilisées 6

Slide 7

Slide 7 text

En avez vous VRAIMENT besoin ?

Slide 8

Slide 8 text

Application gestion Périmètre maîtrisé Déploiement déjà automatisé 8

Slide 9

Slide 9 text

Quelles sont les contraintes techniques? Avez-vous des SLOs contraignantes? (ex. disponibilité supérieure à 99%) Avez vous vraiment besoin de scaler dynamiquement votre application ? 9

Slide 10

Slide 10 text

Mise à disposition d’environnements 10 Avez vous besoin de délivrer des environnements à la demande (et très rapidement)?

Slide 11

Slide 11 text

Les bases de Docker & Cie

Slide 12

Slide 12 text

12

Slide 13

Slide 13 text

Il vous faudra connaître 13

Slide 14

Slide 14 text

14

Slide 15

Slide 15 text

De mon côté…

Slide 16

Slide 16 text

Le contexte

Slide 17

Slide 17 text

« les organisations qui conçoivent des systèmes [...] tendent inévitablement à produire des designs qui sont des copies de la structure de communication de leur organisation. » — M. Conway 17

Slide 18

Slide 18 text

Quel est le RACI ? Est-ce que votre organisation est compatible ? 18 RACI & Responsabilités

Slide 19

Slide 19 text

Les applications stateless et les autres ...

Slide 20

Slide 20 text

20 Codebase One codebase tracked in revision control, many deploys Dependencies Explicitly declare and isolate dependencies Config Store config in the environment Backing Services Treat backing services as attached resources Build, release, run Strictly separate build and run stages Backing Services Treat backing services as attached resources Processes Execute the app as one or more stateless processes Port Binding Export services via port binding Disposability Maximize robustness with fast startup and graceful shutdown Dev/prod parity Keep development, staging, and production as similar as possible Logs Treat logs as event streams Admin processes Run admin/management tasks as one-off processes Source: https://12factors.net

Slide 21

Slide 21 text

21 Pour une API Port Binding Disposability Dev Prod Parity Processes Config Concurrency

Slide 22

Slide 22 text

Démarrage (rapide) de l’application

Slide 23

Slide 23 text

23

Slide 24

Slide 24 text

Comment faire avec Spring Boot? • Vérifiez d’abord vos NFRs • Activez le lazy loading spring.main.lazy-initialization=true • Désactivez l’autoconfiguration et utilisez l’annotation @Import • Activez le graceful shutdown server.shutdown=graceful

Slide 25

Slide 25 text

Bien choisir ses frameworks et environnements d’exécution

Slide 26

Slide 26 text

26

Slide 27

Slide 27 text

27 Items à identifier ✓ Rapidité du démarrage ✓ Gestion des arrêts ✓ Capacité à s’intégrer dans Docker et K8S ✓ Observabilité ✓ Mémoire et CPU utilisées ✓ Gestion des dépendances et du patch management

Slide 28

Slide 28 text

L’ observabilité

Slide 29

Slide 29 text

Adresser sur ce sujet dès la conception ! Ne pas attendre la mise en production :) Exposer via des endpoints REST l’état de votre système Faire attention aux FRAMEWORKS utilisés 29

Slide 30

Slide 30 text

liveness & readiness probes livenessProbe: failureThreshold: 3 httpGet: path: /actuator/health/liveness port: http scheme: HTTP initialDelaySeconds: 30 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 30 readinessProbe: failureThreshold: 3 httpGet: path: /actuator/health/readiness port: http scheme: HTTP initialDelaySeconds: 30 periodSeconds: 30 successThreshold: 1 timeoutSeconds: 1

Slide 31

Slide 31 text

Spring Actuator dependencies { implementation 'org.springframework.boot:spring-boot- starter-actuator' } https://docs.spring.io/spring-boot/docs/current/reference/html/actuator.html

Slide 32

Slide 32 text

Spring Actuator management.health.probes.enabled=true management.endpoints.enabled-by-default=true management.health.livenessstate.enabled=true management.health.readinessstate.enabled=true management.endpoint.health.show-details=always management.endpoint.health.probes.enabled=true management.endpoint.health.enabled=true LivenessStateHealthIndicator & ReadinessStateHealthIndicator 32

Slide 33

Slide 33 text

33 @Component public class MongoDBActuatorHealthIndicator implements HealthIndicator { [...] @Override public Health health() { // ping database } @Override public Health getHealth(boolean includeDetails) { if (!includeDetails) { return health(); } else { var statuses = mongoDBHealthService.findStatusForAllConfigurations(); return Health.status(checkStatus(statuses)).withDetails(statuses).build(); } } [...] }

Slide 34

Slide 34 text

Monitoring ▪ Micrometer ▪ Prometheus ▪ Grafana 34

Slide 35

Slide 35 text

Micrometer • Permet d’exporter des métriques (par ex. Le TTR d’une API en utilisant l’annotation @Timed) • Ces métriques peuvent être agrégées dans Prometheus dependencies { implementation 'io.micrometer:micrometer-registry-prometheus’ }

Slide 36

Slide 36 text

36 management: endpoints: enabled-by-default: true web: exposure: include: '*' jmx: exposure: include: '*' endpoint: health: show-details: always enabled: true probes: enabled: true shutdown: enabled: true prometheus: enabled: true metrics: enabled: true health: livenessstate: enabled: true readinessstate: enabled: true datasource: enabled: true metrics: web: client: request: autotime: enabled: true Actuator configuration Metrics configuration

Slide 37

Slide 37 text

La CI/CD

Slide 38

Slide 38 text

Deux sortes de pipelines • Création plateforme • Build & Deploy

Slide 39

Slide 39 text

Platform provisionning terraform apply

Slide 40

Slide 40 text

Application build & deploy Build •Application Java •Image Docker •Chart Helm Tests •Tests unitaires et d’integration •Smoke tests de la nouvelle image Docker Deployment •Déploiement continu de la branche develop •Déploiement de la release

Slide 41

Slide 41 text

Exemple Migration Spring Boot, Image Docker, JDK Testé en local → Dev → Recette ⇒ En 1 jour 41

Slide 42

Slide 42 text

La configuration

Slide 43

Slide 43 text

Comment configurer votre application cloud native? 43 ▪ Variables d’environnement ▪ Config Maps ▪ Secrets

Slide 44

Slide 44 text

Les variables d’environnement spec: containers: - env: - name: JAVA_OPTS value: >- -XX:+UseContainerSupport -XX:MaxRAMPercentage=70.0 -Dfile.encoding=UTF-8 - Djava.security.egd=file:/dev/./urandom 44

Slide 45

Slide 45 text

Les config maps apiVersion: v1 kind: ConfigMap metadata: creationTimestamp: 2021-03-11T18:38:34Z name: my-config-map [...] data: JAVA_OPTS: >- -XX:+UseContainerSupport -XX:MaxRAMPercentage=70.0 -Dfile.encoding=UTF-8 -Djava.security.egd=file:/dev/./urandom 45

Slide 46

Slide 46 text

Quid des fichiers de configuration ? On peut les spécifier “comme des variables” directement dans les config maps On peut les externaliser 46

Slide 47

Slide 47 text

Les fichiers dans les config maps volumeMounts: - mountPath: /config name: configuration-volume readOnly: true [...] volumes: - configMap: defaultMode: 420 name: configuration name: configuration-volume 47 apiVersion: v1 kind: ConfigMap [...] data: my.conf: {{- (.Files.Glob "conf/*").AsConfig | nindent 2 }}

Slide 48

Slide 48 text

Limitations ▪ Error: UPGRADE FAILED: ConfigMap "my- service" is invalid: data: Too long: must have at most 1048576 characters

Slide 49

Slide 49 text

Externaliser les valeurs apiVersion: autoscaling/v1 kind: HorizontalPodAutoscaler metadata: labels: [...] spec: maxReplicas: {{ .Values.myapp.maxReplicaCount }} minReplicas: {{ .Values.myapp.minReplicaCount }} [...] targetCPUUtilizationPercentage: {{ .Values.myapp.replicationThreesold }} 49

Slide 50

Slide 50 text

Le fichier values.yml myapp: minReplicaCount: "2" maxReplicaCount: "6" replicationThreesold: 80 50

Slide 51

Slide 51 text

Les templates de fichier apiVersion: v1 kind: ConfigMap metadata: name: configuration labels: [...] data: application.properties: |- {{ tpl (.Files.Get "conf/application.properties") . | nindent 4}} 51

Slide 52

Slide 52 text

Les templates Le fichier application.properties logging.level.org.hibernate.stat={{ .Values.configmap.application.org_hib ernate_stat }} logging.level.org.springframework.sec urity={{ .Values.configmap.application.org_spr ingframework_security }} 52 Le fichier values.yml configmap: application: org_hibernate_stat: ERROR org_springframework_security: ERROR

Slide 53

Slide 53 text

Les fichiers binaires apiVersion: v1 # Definition of secrets kind: Secret [...] type: Opaque # Inclusion of binary configuration files data: my_keystore.jks: {{ .Files.Get "secrets/my_keystore.jks" | b64enc }} 53

Slide 54

Slide 54 text

Logger efficacement

Slide 55

Slide 55 text

L’utilisation des logs Dans la console: kubectl logs --tail Agrégateur de logs (ex. ELK) 55

Slide 56

Slide 56 text

Flux de sortie des containers Docker stdout & stderr Inutile de configurer la sortie vers des fichiers 56

Slide 57

Slide 57 text

Bonnes pratiques Indiquer dans vos LOGS: Les éléments de votre conteneur (Image, containerID,...) Les éléments de contexte K8S (IP POD, ID POD, namespace,...) Log4j Docker Support – Log4j Kubernetes Support 57

Slide 58

Slide 58 text

Pour aller plus loin Vous pouvez logger et tracer les appels à vos APIS: Requête, ID de l’appelant, ID de corrélation,... zalando/logbook: An extensible Java library for HTTP request and response logging 58

Slide 59

Slide 59 text

Distributed tracing Vous pouvez identifier et corréler vos différents appels dans votre plateforme microservices en implémentant OpenTracing. 59

Slide 60

Slide 60 text

60

Slide 61

Slide 61 text

Sur GCP ▪ Vous avez par défaut: □ Un explorateur de logs (Google Logs Explorer ~ELK) □ Un rapport d’ erreurs (~ dashboard ELK) □ Un analyseur de traces distribuées 61

Slide 62

Slide 62 text

Logging ▪ Utilisez Spring Cloud GCP Starter dependencies { implementation("com.google.cloud:spring-cloud-gcp-starter-logging") } ▪ Utilisez Logback comme framework de Logging ▪ Initialisez les variables GOOGLE_CLOUD_PROJECT & GOOGLE_APPLICATION_CREDENTIALS dans vos charts HELM 62

Slide 63

Slide 63 text

63

Slide 64

Slide 64 text

Error Reporter ▪ Par défaut, il agrège toutes les erreurs de votre plateforme ▪ Vous pouvez également ajouter vos erreurs business (ex. HTTP 500) ▪ Vous pouvez intégrer votre application grâce à des appenders Logback 64

Slide 65

Slide 65 text

65

Slide 66

Slide 66 text

Distributed tracing ▪ By using Spring Cloud GCP starter trace dependencies { compile group: 'org.springframework.cloud', name: 'spring-cloud-gcp-starter-trace’ } 66

Slide 67

Slide 67 text

En résumé 67

Slide 68

Slide 68 text

Evitez le hype driven development Pensez à votre organisation Travaillez sur l’observabilité dès les premières étapes Automatisez tout (ou presque)

Slide 69

Slide 69 text

Merci! Des questions? 69

Slide 70

Slide 70 text

https://roti.express/r/sc22-046