Upgrade to Pro — share decks privately, control downloads, hide ads and more …

[JNATION 2021] Kubernetes & Co, beyond the hype: 10 tips for designers who want to create cloud native apps

[JNATION 2021] Kubernetes & Co, beyond the hype: 10 tips for designers who want to create cloud native apps

Kubernetes and cloud technologies are nowadays the new standard to deploy different cloud native applications: api, batchs, microservices and ... monoliths!
These technologies help to solve many issues but with some complexity.
It could be difficult for developers and designers to identify the constraints of such architectures.

In this presentation, you will (re)discover ten tips and pieces of advice I applied and found useful in my last JAVA projects (Spring, JEE).

I will talk about:

Application ecosystem
Choice of technical solutions
K8S design constraints
And more!


Alexandre Touret

October 28, 2021

More Decks by Alexandre Touret

Other Decks in Programming


  1. Kubernetes & Co, beyond the hype 10 tips for designers

    who want to create cloud native apps
  2. Alexandre Touret Architect / Developer #Java #API #CI #Cloud #Software_Craftsmanship

    2 @touret_alex https://blog.touret.info
  3. Some context... 1.

  4. 4

  5. Used technologies 5

  6. Do you REALLY need it?

  7. Small business application Controlled scope Automatized deployments already implemented 7

  8. What are the NFRs? Do you have constraining SLOs? (eg.

    >99% SLA availability) Does your system need to be dynamically scaled? 8
  9. Providing « on demand » environments 9 Do you need

    to deliver environments on demand (and really fast)?
  10. Docker & Cie basics

  11. 11

  12. You will have to know… 12

  13. 13

  14. Organization

  15. «Any organization that designs a system (defined broadly) will produce

    a design whose structure is a copy of the organization's communication structure.» — M. Conway 15
  16. What’s the associated RACI ? Is your organisation compatible? 16

    RACI & Responsabilies
  17. The stateless apps and the others…

  18. 18 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
  19. 19 For an API

  20. (Fast) application startup

  21. 21

  22. Choose wisely your frameworks and target runtime platforms

  23. 23

  24. 24 Items to check ✓ Fast startup ✓ Shutdown handling

    ✓ Ability to be integrated into Docker and K8S ✓ Observability ✓ Memory and CPU consumption ✓ Dependency and patch management
  25. TOMCAT vs FAT JARS → Production – Development teams trade-off

  26. Observability

  27. Address this point from design phase Don’t wait for the

    production deployment Expose your system status through endpoints Be careful to the used FRAMEWORKS 27
  28. liveness & readiness probes livenessProbe: failureThreshold: 3 httpGet: path: /actuator/health/liveness

    port: http scheme: HTTP initialDelaySeconds: 30 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 28 readinessProbe: failureThreshold: 3 httpGet: path: /actuator/health/readiness port: http scheme: HTTP initialDelaySeconds: 30 periodSeconds: 30 successThreshold: 1 timeoutSeconds: 1
  29. 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 29
  30. 30 @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(); } } [...] }
  31. Monitoring ▪ Micrometer ▪ Prometheus ▪ Grafana 31

  32. 32 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
  33. None
  34. Steps to integrate in your CI/CD pipeline ✓ Unit and

    integration tests ✓ Docker image creation ✓ Created docker image “Smoke tests” ✓ Continuous deployment of your develop branch ✓ HELM charts deployment ✓ Release deployment ✓ ... 34
  35. Example Spring Boot, Tomcat, JDK Migration Tested locally → Dev

    → Staging ⇒ In one day 35
  36. Configuration

  37. 37 ▪ Environment variables ▪ Config Maps ▪ Secrets

  38. Environment variables spec: containers: - env: - name: JAVA_OPTS value:

    >- -XX:+UseContainerSupport -XX:MaxRAMPercentage=70.0 -Dfile.encoding=UTF-8 - Djava.security.egd=file:/dev/./urandom 38
  39. 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 39
  40. What about configuration files? We can specify them as variables

    in config maps We can also externalize them 40
  41. Files in config maps volumeMounts: - mountPath: /config name: configuration-volume

    readOnly: true [...] volumes: - configMap: defaultMode: 420 name: configuration name: configuration-volume 41 apiVersion: v1 kind: ConfigMap [...] data: my.conf: {{- (.Files.Glob "conf/*").AsConfig | nindent 2 }}
  42. Externalize values apiVersion: autoscaling/v1 kind: HorizontalPodAutoscaler metadata: labels: [...] spec:

    maxReplicas: {{ .Values.myapp.maxReplicaCount }} minReplicas: {{ .Values.myapp.minReplicaCount }} [...] targetCPUUtilizationPercentage: {{ .Values.myapp.replicationThreesold }} 42
  43. Values.yml myapp: minReplicaCount: "2" maxReplicaCount: "6" replicationThreesold: 80 43

  44. File templates apiVersion: v1 kind: ConfigMap metadata: name: configuration labels:

    [...] data: application.properties: |- {{ tpl (.Files.Get "conf/application.properties") . | nindent 4}} 44
  45. Templates application.properties file 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 }} 45 values.yml file configmap: application: org_hibernate_stat: ERROR org_springframework_security: ERROR
  46. Binary files 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 }} 46
  47. Efficiently logging

  48. Log management In the console: kubectl logs --tail Logs aggregator

    (ex. ELK) 48
  49. Docker containers output stream stdout & stderr It’s useless to

    setup a file output stream 49
  50. Best practices Indicate in your LOGS: Container informations (image name,

    container ID,…) Kubernetes related informations (POD @IP, POD ID, namespace,...) Log4j Docker Support – Log4j Kubernetes Support 50
  51. To go further You can identify the related informations of

    the APIs calls: Caller ID, Correlation ID, request data,… zalando/logbook: An extensible Java library for HTTP request and response logging 51
  52. Distributed tracing You can identify and correlate your API calls

    on your microservices based architecture by implement Opentracing 52
  53. 53

  54. Thanks! Any question? 54