SlideShare ist ein Scribd-Unternehmen logo
1 von 46
Downloaden Sie, um offline zu lesen
Cloud-native applications with Java
and Kubernetes
Hello, ${username}!
● Senior Java developer @ DataArt
● Working with Java for 5+ years
● Background in networking and game
development, mostly C/C++
● Interested in everything DevOps related
since started working with Java
● https://www.facebook.com/yegor.volkov.x64
Evolution of Environments
Evolution of Environments
Bare metal
Virtualization (HW)
Virtualization (SW)
OS
Container Engine
JVM
Your app
1. Bare metal, VM software-based, VM hardware-based
2. IaaS, PaaS, SaaS
3. Amazon Services, Amazon EC2, Amazon ECS
4. Google Services, Google App Engine, Google
Kubernetes Engine
5. CloudFoundry, Heroku, etc.
Evolution of Environments
my-project-0.0.1-SNAPSHOT.jar app-build-2541.war
./exploded jar/
./exploded war/
Java developers only care about these!
Evolution of Environments
… and sometimes about these ...
java version "10.0.2" 2018-07-17
Java(TM) SE Runtime Environment 18.3 (build 10.0.2+13)
Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10.0.2+13, mixed mode)
openjdk version "9-internal"
OpenJDK Runtime Environment (build 9-internal+0-2016-04-14-195246.buildd.src)
OpenJDK 64-Bit Server VM (build 9-internal+0-2016-04-14-195246.buildd.src, mixed mode)
Evolution of Environments
1. As long as the JRE is the same, that we develop against - everything
should be fine
2. As long as the Servlet container version is the same, that we develop
against - everything should be fine
3. As long as the RDBMS version is the same, that we develop against -
everything should be fine
4. …
Evolution of Environments
● We need to solidify versions of everything (JVM, JDK/JRE, servers,
servlet containers, databases, etc)
● There’s no good way to limit Ops people from screwing everything up
● This should be done by software, not people
● We already have solutions for similar problems in Java world -
dependency managers!
Dockerization: starting small
● Docker to the rescue!
● Make a snapshot of your environment
● Redistribute and run anywhere “©”
● Bake internal custom service versions and builds
Dockerization: starting small
Dockerization: starting small
FROM openjdk:10-jre
VOLUME /tmp
COPY target/project1-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
gradlew clean build && docker build -t starships .
docker run -p 3306:3306 -v C:/dev/docker/mysql-project1:/var/lib/mysql --env
MYSQL_ROOT_PASSWORD=s3cur1ty@maks --env MYSQL_DATABASE=space --name mysql-project1
--network space-net mysql:5.6
docker run -p 8443:8443 --name starships --network space-net starships:latest
Dockerfile:
Run with:
Dockerization: starting small
Dockerization: starting small
Dockerization: starting small
Dockerization: next obvious step
version: "3"
services:
starships:
build:
context: .
dockerfile: Dockerfile
image: "starships:latest"
ports:
- "8443:8443"
networks:
- space-net
depends_on:
- mysql
mysql:
hostname: "mysql"
image: "mysql:5.6"
ports:
- "3306:3306"
volumes:
- mysql_volume:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=s3cur1ty@maks
- MYSQL_DATABASE=space
networks:
space-net:
networks:
space-net:
volumes:
mysql_volume:
Dockerization: next obvious step
gradlew clean build
docker build -t starships .
docker-compose up
Run with:
Dockerization: next obvious step
Dockerization: next obvious step
Diving into Kubernetes
Diving into Kubernetes
Diving into Kubernetes
kompose convert -f docker-compose.yaml
docker-compose.yaml
mysql-deployment.yaml
mysql-service.yaml
mysql-pvc.yaml
starships-deployment.yaml
starships-service.yaml
Diving into Kubernetes
$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/mysql-646fdcd6b9-8x9f7 1/1 Running 0 3h
pod/starships-68585d5f5b-v5qtr 1/1 Running 0 2m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 12d
service/mysql ClusterIP 10.102.90.77 <none> 3306/TCP 3h
service/starships ClusterIP 10.98.205.45 <none> 8443/TCP 2m
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deployment.apps/mysql 1 1 1 1 3h
deployment.apps/starships 1 1 1 1 2m
Diving into Kubernetes
Take advantage of Kubernetes features: secrets and configuration!
kubectl create secret generic spacekey
--from-file=src/main/resources/spacekey.p12
Update app configuration:
server.ssl.key-store=/app/spacekey.p12
server.ssl.key-store-password=spac3ke1
server.ssl.key-alias=spacecert
Diving into Kubernetes
Adjust YAML file to mount the secret:
spec:
containers:
...
volumeMounts:
- mountPath: "/app"
name: spacekey
readOnly: true
...
volumes:
- name: spacekey
secret:
secretName: spacekey
Diving into Kubernetes
So far we have:
● MySQL service
● MySQL persistent volume claim
● MySQL deployment
● Application service
● Application deployment
● SSL certificate secret
Playing with Kubernetes
Expose the application:
kubectl expose deployment starships
--port=8443 --protocol=TCP --target-port=8443
--type=LoadBalancer --name=starships-lb
Examine new service:
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 12d
mysql ClusterIP 10.102.90.77 <none> 3306/TCP 3h
starships-lb LoadBalancer 10.100.175.25 localhost 8443:32699/TCP 3h
Playing with Kubernetes
Access the application:
https://localhost:8443/
Playing with Kubernetes
Inject config from ConfigMap:
kubectl create configmap starship-config
--from-file=src/main/resources/application-k8s-cm.properties
Mount it in the pod:
volumeMounts:
- mountPath: /app/application-k8s.properties
name: app-config
subPath: application-k8s-cm.properties
volumes:
- name: spacekey
secret:
secretName: spacekey
- name: app-config
configMap:
name: starship-config
Playing with Kubernetes
Restart pods:
kubectl scale --replicas=0
deployment.apps/starships
kubectl scale --replicas=1
deployment.apps/starships
Access the application:
https://localhost:8443/
Playing with Kubernetes
Scale it up:
kubectl scale --replicas=2 deployment.apps/starships
Playing with Kubernetes
wollf@WOLLF-TYPHOON MINGW64 ~/IdeaProjects/project1 (master-february-kubernetes)
$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/mysql-646fdcd6b9-8x9f7 1/1 Running 0 2h
pod/starships-68585d5f5b-pcdcg 1/1 Running 0 2m
pod/starships-68585d5f5b-v5qtr 1/1 Running 0 3m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 12d
service/mysql ClusterIP 10.102.90.77 <none> 3306/TCP 2h
service/starships-lb LoadBalancer 10.100.175.25 localhost 8443:32699/TCP 2h
...
Playing with Kubernetes
...
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deployment.apps/mysql 1 1 1 1 2h
deployment.apps/starships 2 2 2 2 2h
NAME DESIRED CURRENT READY AGE
replicaset.apps/mysql-646fdcd6b9 1 1 1 2h
replicaset.apps/starships-68585d5f5b 2 2 2 15m
Back to the surface
Things we added:
● App config via ConfigMap
● Environment variable populated
with current pod name
● Load balanced service
Back to the surface
Stateful services in Kubernetes
Current database configuration:
● Regular ReplicaSet (as for the app)
● Will lose data if re-scheduled
● Credentials are insecure
● Configuration is hard-coded
Stateful services in Kubernetes
Moving MySQL configuration and credentials outside of
deployment YAML:
apiVersion: v1
kind: Secret
metadata:
name: mysql-credentials
data:
username: dW5pdmVyc2U=
password: ZDRrZlg4QndBQ3F4Rkt0Mw==
root-password: YWRtaW4=
Stateful services in Kubernetes
MySQL master and slave config:
apiVersion: v1
kind: ConfigMap
metadata:
name: mysql-config
data:
mysql_database: space
master.cnf: |
# Apply this config only on the master.
[mysqld]
log-bin
slave.cnf: |
# Apply this config only on slaves.
[mysqld]
super-read-only
Stateful services in Kubernetes
Use DB configuration from ConfigMap:
containers:
- name: mysql
env:
- name: MYSQL_DATABASE
valueFrom:
configMapKeyRef:
name: mysql-config
key: mysql_database
- name: MYSQL_ALLOW_EMPTY_PASSWORD
value: "1"
Use credentials configuration from ConfigMap:
containers:
- name: mysql
env:
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-credentials
key: password
- name: MYSQL_USER
valueFrom:
secretKeyRef:
name: mysql-credentials
key: username
Stateful services in Kubernetes
Use DB credentials for the application deployment:
spec:
containers:
- image: starships:latest
name: starships
Env:
...
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-credentials
key: password
- name: MYSQL_USERNAME
valueFrom:
secretKeyRef:
name: mysql-credentials
key: username
Stateful services in Kubernetes
Use DB master/slave endpoint and credentials in the app config:
spring.datasource.url=jdbc:mysql://mysql:3306,mysql-read:3306/space
spring.datasource.username=${MYSQL_USERNAME}
spring.datasource.password=${MYSQL_PASSWORD}
Stateful services in Kubernetes
# Headless service for stable
# DNS entries of StatefulSet members.
apiVersion: v1
kind: Service
metadata:
name: mysql
labels:
app: mysql
spec:
ports:
- name: mysql
port: 3306
clusterIP: None
selector:
app: mysql
# Client service for connecting to any MySQL
# instance for reads. For writes, you must instead
connect to the master: mysql-0.mysql.
apiVersion: v1
kind: Service
metadata:
name: mysql-read
labels:
app: mysql
spec:
ports:
- name: mysql
port: 3306
selector:
app: mysql
Stateful services in Kubernetes
Road ahead
1. Get rid of HTTPS in the application and use a web server for that
2. Configure replica set to support dynamic scaling
3. Deploy multiple types of the same instances (/app,/api,/admin)
4. Utilize namespaces to limit visibility of environments
5. Start using K8S metric API to get more info about your cluster
6. Try deploying somewhere else (AWS, Azure, GCE, OpenStack,
CloudStack)
7. Log aggregation
8. Rolling updates and blue/green deployments
Road ahead
https://github.com/wollfxp/project1/tree/master-february-kubernetes
Questions and Answers
Thank you!
Good luck!
https://github.com/wollfxp/project1/tree/master-february-kubernetes
https://www.facebook.com/yegor.volkov.x64

Weitere ähnliche Inhalte

Was ist angesagt?

Was ist angesagt? (20)

Docker London: Container Security
Docker London: Container SecurityDocker London: Container Security
Docker London: Container Security
 
Building a Secure App with Docker - Ying Li and David Lawrence, Docker
Building a Secure App with Docker - Ying Li and David Lawrence, DockerBuilding a Secure App with Docker - Ying Li and David Lawrence, Docker
Building a Secure App with Docker - Ying Li and David Lawrence, Docker
 
Jacopo Nardiello - Monitoring Cloud-Native applications with Prometheus - Cod...
Jacopo Nardiello - Monitoring Cloud-Native applications with Prometheus - Cod...Jacopo Nardiello - Monitoring Cloud-Native applications with Prometheus - Cod...
Jacopo Nardiello - Monitoring Cloud-Native applications with Prometheus - Cod...
 
Container Security
Container SecurityContainer Security
Container Security
 
Security best practices for kubernetes deployment
Security best practices for kubernetes deploymentSecurity best practices for kubernetes deployment
Security best practices for kubernetes deployment
 
DevOpsDaysRiga 2018: Andrew Martin - Continuous Kubernetes Security
DevOpsDaysRiga 2018: Andrew Martin - Continuous Kubernetes Security DevOpsDaysRiga 2018: Andrew Martin - Continuous Kubernetes Security
DevOpsDaysRiga 2018: Andrew Martin - Continuous Kubernetes Security
 
Docker Security - Continuous Container Security
Docker Security - Continuous Container SecurityDocker Security - Continuous Container Security
Docker Security - Continuous Container Security
 
How abusing the Docker API led to remote code execution same origin bypass an...
How abusing the Docker API led to remote code execution same origin bypass an...How abusing the Docker API led to remote code execution same origin bypass an...
How abusing the Docker API led to remote code execution same origin bypass an...
 
Kubernetes - security you need to know about it
Kubernetes - security you need to know about itKubernetes - security you need to know about it
Kubernetes - security you need to know about it
 
Containers & Security
Containers & SecurityContainers & Security
Containers & Security
 
Automation and Collaboration Across Multiple Swarms Using Docker Cloud - Marc...
Automation and Collaboration Across Multiple Swarms Using Docker Cloud - Marc...Automation and Collaboration Across Multiple Swarms Using Docker Cloud - Marc...
Automation and Collaboration Across Multiple Swarms Using Docker Cloud - Marc...
 
Understanding container security
Understanding container securityUnderstanding container security
Understanding container security
 
Docker Container Security
Docker Container SecurityDocker Container Security
Docker Container Security
 
Csa container-security-in-aws-dw
Csa container-security-in-aws-dwCsa container-security-in-aws-dw
Csa container-security-in-aws-dw
 
Hug #9 who's keeping your secrets
Hug #9 who's keeping your secretsHug #9 who's keeping your secrets
Hug #9 who's keeping your secrets
 
Container Runtime Security with Falco
Container Runtime Security with FalcoContainer Runtime Security with Falco
Container Runtime Security with Falco
 
Kubescape single pane of glass
Kubescape   single pane of glassKubescape   single pane of glass
Kubescape single pane of glass
 
Container Security Essentials
Container Security EssentialsContainer Security Essentials
Container Security Essentials
 
Advanced Container Security
Advanced Container Security Advanced Container Security
Advanced Container Security
 
(SACON) Madhu Akula - Automated Defense Using Cloud Service Aws, Azure, Gcp
(SACON) Madhu Akula  - Automated Defense Using Cloud Service Aws, Azure, Gcp(SACON) Madhu Akula  - Automated Defense Using Cloud Service Aws, Azure, Gcp
(SACON) Madhu Akula - Automated Defense Using Cloud Service Aws, Azure, Gcp
 

Ähnlich wie Cloud-native applications with Java and Kubernetes - Yehor Volkov

Ähnlich wie Cloud-native applications with Java and Kubernetes - Yehor Volkov (20)

Kubernetes - training micro-dragons without getting burnt
Kubernetes -  training micro-dragons without getting burntKubernetes -  training micro-dragons without getting burnt
Kubernetes - training micro-dragons without getting burnt
 
廣宣學堂: 容器進階實務 - Docker進深研究班
廣宣學堂: 容器進階實務 - Docker進深研究班廣宣學堂: 容器進階實務 - Docker進深研究班
廣宣學堂: 容器進階實務 - Docker進深研究班
 
Docker 進階實務班
Docker 進階實務班Docker 進階實務班
Docker 進階實務班
 
Scaling docker with kubernetes
Scaling docker with kubernetesScaling docker with kubernetes
Scaling docker with kubernetes
 
Amazon Web Services and Docker: from developing to production
Amazon Web Services and Docker: from developing to productionAmazon Web Services and Docker: from developing to production
Amazon Web Services and Docker: from developing to production
 
Postgres the hardway
Postgres the hardwayPostgres the hardway
Postgres the hardway
 
Deploying windows containers with kubernetes
Deploying windows containers with kubernetesDeploying windows containers with kubernetes
Deploying windows containers with kubernetes
 
Istio Playground
Istio PlaygroundIstio Playground
Istio Playground
 
Running Docker in Development & Production (DevSum 2015)
Running Docker in Development & Production (DevSum 2015)Running Docker in Development & Production (DevSum 2015)
Running Docker in Development & Production (DevSum 2015)
 
Docker Azure Friday OSS March 2017 - Developing and deploying Java & Linux on...
Docker Azure Friday OSS March 2017 - Developing and deploying Java & Linux on...Docker Azure Friday OSS March 2017 - Developing and deploying Java & Linux on...
Docker Azure Friday OSS March 2017 - Developing and deploying Java & Linux on...
 
Scaling Docker Containers using Kubernetes and Azure Container Service
Scaling Docker Containers using Kubernetes and Azure Container ServiceScaling Docker Containers using Kubernetes and Azure Container Service
Scaling Docker Containers using Kubernetes and Azure Container Service
 
Get you Java application ready for Kubernetes !
Get you Java application ready for Kubernetes !Get you Java application ready for Kubernetes !
Get you Java application ready for Kubernetes !
 
Exploring MySQL Operator for Kubernetes in Python
Exploring MySQL Operator for Kubernetes in PythonExploring MySQL Operator for Kubernetes in Python
Exploring MySQL Operator for Kubernetes in Python
 
Higher order infrastructure: from Docker basics to cluster management - Nicol...
Higher order infrastructure: from Docker basics to cluster management - Nicol...Higher order infrastructure: from Docker basics to cluster management - Nicol...
Higher order infrastructure: from Docker basics to cluster management - Nicol...
 
Orchestrating Docker with OpenStack
Orchestrating Docker with OpenStackOrchestrating Docker with OpenStack
Orchestrating Docker with OpenStack
 
Docker for Web Developers: A Sneak Peek
Docker for Web Developers: A Sneak PeekDocker for Web Developers: A Sneak Peek
Docker for Web Developers: A Sneak Peek
 
Docker 1.11 Presentation
Docker 1.11 PresentationDocker 1.11 Presentation
Docker 1.11 Presentation
 
桃園市教育局Docker技術入門與實作
桃園市教育局Docker技術入門與實作桃園市教育局Docker技術入門與實作
桃園市教育局Docker技術入門與實作
 
Dayta AI Seminar - Kubernetes, Docker and AI on Cloud
Dayta AI Seminar - Kubernetes, Docker and AI on CloudDayta AI Seminar - Kubernetes, Docker and AI on Cloud
Dayta AI Seminar - Kubernetes, Docker and AI on Cloud
 
Nats meetup oct 2016 docker 112
Nats meetup oct 2016 docker 112Nats meetup oct 2016 docker 112
Nats meetup oct 2016 docker 112
 

Kürzlich hochgeladen

Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Kürzlich hochgeladen (20)

Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Vector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptxVector Search -An Introduction in Oracle Database 23ai.pptx
Vector Search -An Introduction in Oracle Database 23ai.pptx
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
Apidays New York 2024 - Passkeys: Developing APIs to enable passwordless auth...
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 

Cloud-native applications with Java and Kubernetes - Yehor Volkov

  • 1. Cloud-native applications with Java and Kubernetes
  • 2. Hello, ${username}! ● Senior Java developer @ DataArt ● Working with Java for 5+ years ● Background in networking and game development, mostly C/C++ ● Interested in everything DevOps related since started working with Java ● https://www.facebook.com/yegor.volkov.x64
  • 4. Evolution of Environments Bare metal Virtualization (HW) Virtualization (SW) OS Container Engine JVM Your app 1. Bare metal, VM software-based, VM hardware-based 2. IaaS, PaaS, SaaS 3. Amazon Services, Amazon EC2, Amazon ECS 4. Google Services, Google App Engine, Google Kubernetes Engine 5. CloudFoundry, Heroku, etc.
  • 5. Evolution of Environments my-project-0.0.1-SNAPSHOT.jar app-build-2541.war ./exploded jar/ ./exploded war/ Java developers only care about these!
  • 6. Evolution of Environments … and sometimes about these ... java version "10.0.2" 2018-07-17 Java(TM) SE Runtime Environment 18.3 (build 10.0.2+13) Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10.0.2+13, mixed mode) openjdk version "9-internal" OpenJDK Runtime Environment (build 9-internal+0-2016-04-14-195246.buildd.src) OpenJDK 64-Bit Server VM (build 9-internal+0-2016-04-14-195246.buildd.src, mixed mode)
  • 7. Evolution of Environments 1. As long as the JRE is the same, that we develop against - everything should be fine 2. As long as the Servlet container version is the same, that we develop against - everything should be fine 3. As long as the RDBMS version is the same, that we develop against - everything should be fine 4. …
  • 8. Evolution of Environments ● We need to solidify versions of everything (JVM, JDK/JRE, servers, servlet containers, databases, etc) ● There’s no good way to limit Ops people from screwing everything up ● This should be done by software, not people ● We already have solutions for similar problems in Java world - dependency managers!
  • 9. Dockerization: starting small ● Docker to the rescue! ● Make a snapshot of your environment ● Redistribute and run anywhere “©” ● Bake internal custom service versions and builds
  • 11. Dockerization: starting small FROM openjdk:10-jre VOLUME /tmp COPY target/project1-0.0.1-SNAPSHOT.jar app.jar ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] gradlew clean build && docker build -t starships . docker run -p 3306:3306 -v C:/dev/docker/mysql-project1:/var/lib/mysql --env MYSQL_ROOT_PASSWORD=s3cur1ty@maks --env MYSQL_DATABASE=space --name mysql-project1 --network space-net mysql:5.6 docker run -p 8443:8443 --name starships --network space-net starships:latest Dockerfile: Run with:
  • 15. Dockerization: next obvious step version: "3" services: starships: build: context: . dockerfile: Dockerfile image: "starships:latest" ports: - "8443:8443" networks: - space-net depends_on: - mysql mysql: hostname: "mysql" image: "mysql:5.6" ports: - "3306:3306" volumes: - mysql_volume:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=s3cur1ty@maks - MYSQL_DATABASE=space networks: space-net: networks: space-net: volumes: mysql_volume:
  • 16. Dockerization: next obvious step gradlew clean build docker build -t starships . docker-compose up Run with:
  • 21. Diving into Kubernetes kompose convert -f docker-compose.yaml docker-compose.yaml mysql-deployment.yaml mysql-service.yaml mysql-pvc.yaml starships-deployment.yaml starships-service.yaml
  • 22. Diving into Kubernetes $ kubectl get all NAME READY STATUS RESTARTS AGE pod/mysql-646fdcd6b9-8x9f7 1/1 Running 0 3h pod/starships-68585d5f5b-v5qtr 1/1 Running 0 2m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 12d service/mysql ClusterIP 10.102.90.77 <none> 3306/TCP 3h service/starships ClusterIP 10.98.205.45 <none> 8443/TCP 2m NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE deployment.apps/mysql 1 1 1 1 3h deployment.apps/starships 1 1 1 1 2m
  • 23. Diving into Kubernetes Take advantage of Kubernetes features: secrets and configuration! kubectl create secret generic spacekey --from-file=src/main/resources/spacekey.p12 Update app configuration: server.ssl.key-store=/app/spacekey.p12 server.ssl.key-store-password=spac3ke1 server.ssl.key-alias=spacecert
  • 24. Diving into Kubernetes Adjust YAML file to mount the secret: spec: containers: ... volumeMounts: - mountPath: "/app" name: spacekey readOnly: true ... volumes: - name: spacekey secret: secretName: spacekey
  • 25. Diving into Kubernetes So far we have: ● MySQL service ● MySQL persistent volume claim ● MySQL deployment ● Application service ● Application deployment ● SSL certificate secret
  • 26. Playing with Kubernetes Expose the application: kubectl expose deployment starships --port=8443 --protocol=TCP --target-port=8443 --type=LoadBalancer --name=starships-lb Examine new service: kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 12d mysql ClusterIP 10.102.90.77 <none> 3306/TCP 3h starships-lb LoadBalancer 10.100.175.25 localhost 8443:32699/TCP 3h
  • 27. Playing with Kubernetes Access the application: https://localhost:8443/
  • 28. Playing with Kubernetes Inject config from ConfigMap: kubectl create configmap starship-config --from-file=src/main/resources/application-k8s-cm.properties Mount it in the pod: volumeMounts: - mountPath: /app/application-k8s.properties name: app-config subPath: application-k8s-cm.properties volumes: - name: spacekey secret: secretName: spacekey - name: app-config configMap: name: starship-config
  • 29. Playing with Kubernetes Restart pods: kubectl scale --replicas=0 deployment.apps/starships kubectl scale --replicas=1 deployment.apps/starships Access the application: https://localhost:8443/
  • 30. Playing with Kubernetes Scale it up: kubectl scale --replicas=2 deployment.apps/starships
  • 31. Playing with Kubernetes wollf@WOLLF-TYPHOON MINGW64 ~/IdeaProjects/project1 (master-february-kubernetes) $ kubectl get all NAME READY STATUS RESTARTS AGE pod/mysql-646fdcd6b9-8x9f7 1/1 Running 0 2h pod/starships-68585d5f5b-pcdcg 1/1 Running 0 2m pod/starships-68585d5f5b-v5qtr 1/1 Running 0 3m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 12d service/mysql ClusterIP 10.102.90.77 <none> 3306/TCP 2h service/starships-lb LoadBalancer 10.100.175.25 localhost 8443:32699/TCP 2h ...
  • 32. Playing with Kubernetes ... NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE deployment.apps/mysql 1 1 1 1 2h deployment.apps/starships 2 2 2 2 2h NAME DESIRED CURRENT READY AGE replicaset.apps/mysql-646fdcd6b9 1 1 1 2h replicaset.apps/starships-68585d5f5b 2 2 2 15m
  • 33. Back to the surface Things we added: ● App config via ConfigMap ● Environment variable populated with current pod name ● Load balanced service
  • 34. Back to the surface
  • 35. Stateful services in Kubernetes Current database configuration: ● Regular ReplicaSet (as for the app) ● Will lose data if re-scheduled ● Credentials are insecure ● Configuration is hard-coded
  • 36. Stateful services in Kubernetes Moving MySQL configuration and credentials outside of deployment YAML: apiVersion: v1 kind: Secret metadata: name: mysql-credentials data: username: dW5pdmVyc2U= password: ZDRrZlg4QndBQ3F4Rkt0Mw== root-password: YWRtaW4=
  • 37. Stateful services in Kubernetes MySQL master and slave config: apiVersion: v1 kind: ConfigMap metadata: name: mysql-config data: mysql_database: space master.cnf: | # Apply this config only on the master. [mysqld] log-bin slave.cnf: | # Apply this config only on slaves. [mysqld] super-read-only
  • 38. Stateful services in Kubernetes Use DB configuration from ConfigMap: containers: - name: mysql env: - name: MYSQL_DATABASE valueFrom: configMapKeyRef: name: mysql-config key: mysql_database - name: MYSQL_ALLOW_EMPTY_PASSWORD value: "1" Use credentials configuration from ConfigMap: containers: - name: mysql env: - name: MYSQL_PASSWORD valueFrom: secretKeyRef: name: mysql-credentials key: password - name: MYSQL_USER valueFrom: secretKeyRef: name: mysql-credentials key: username
  • 39. Stateful services in Kubernetes Use DB credentials for the application deployment: spec: containers: - image: starships:latest name: starships Env: ... - name: MYSQL_PASSWORD valueFrom: secretKeyRef: name: mysql-credentials key: password - name: MYSQL_USERNAME valueFrom: secretKeyRef: name: mysql-credentials key: username
  • 40. Stateful services in Kubernetes Use DB master/slave endpoint and credentials in the app config: spring.datasource.url=jdbc:mysql://mysql:3306,mysql-read:3306/space spring.datasource.username=${MYSQL_USERNAME} spring.datasource.password=${MYSQL_PASSWORD}
  • 41. Stateful services in Kubernetes # Headless service for stable # DNS entries of StatefulSet members. apiVersion: v1 kind: Service metadata: name: mysql labels: app: mysql spec: ports: - name: mysql port: 3306 clusterIP: None selector: app: mysql # Client service for connecting to any MySQL # instance for reads. For writes, you must instead connect to the master: mysql-0.mysql. apiVersion: v1 kind: Service metadata: name: mysql-read labels: app: mysql spec: ports: - name: mysql port: 3306 selector: app: mysql
  • 42. Stateful services in Kubernetes
  • 43. Road ahead 1. Get rid of HTTPS in the application and use a web server for that 2. Configure replica set to support dynamic scaling 3. Deploy multiple types of the same instances (/app,/api,/admin) 4. Utilize namespaces to limit visibility of environments 5. Start using K8S metric API to get more info about your cluster 6. Try deploying somewhere else (AWS, Azure, GCE, OpenStack, CloudStack) 7. Log aggregation 8. Rolling updates and blue/green deployments