In this demos loaded talk we’ll explore the best practices to create a Docker image for a Java app (it’s 2019 and new comers such as Jib, CNCF buildpacks are interesting alternatives to Docker builds !) - and how to integrate best with the Kubernetes ecosystem : after explaining main Kubernetes objects and notions, we’ll discuss Helm charts and productivity tools such as Skaffold, Draft and Telepresence.
2. LET ME INTRODUCE MYSELF
„Anthony Dahanne
„Software Engineer @Software AG
„Working on Terracotta cloud deployments
(Docker, Kubernetes, AWS, etc.)
„Also working on Management and Monitoring for
Terracotta products
„Montréal JUG leader
3. AGENDA
• Containers & the JVM
• Kubernetes 101
• Tools to become a 100x developer with Kubernetes
• Integrating with Kubernetes
4. CONTAINERS IN ONE SLIDE
• Containers all use host OS kernel
• Host OS can be running in a VM or barebone
• Host OS Linux distribution does not matter
• only the kernel does !
• Isolation performed with chroot, namespaces, cgroups
• namespaces : limit what you can see
• pid, net, mnt, uts, ipc, user
• cgroups : limit what you can use
• memory, CPU, block IO, network (with iptables)
THAT’S JUST AN ISOLATED PROCESS !
https://www.slideshare.net/jpetazzo/anatomy-of-a-container-namespaces-cgroups-some-filesystem-magic-linuxcon
https://www.enterprisetech.com/2014/08/18/ibm-techies-pit-docker-kvm-bare-metal/
5. JAVA AND LINUX CONTAINERS
• The JVM “guesses” available CPU and Memory resources available on the host
• By default, uses 1/4 of the available memory
• Although it can be set manually
• -XX:ParallelGCThreads,-XX:CICompilerCount,-Xmx
• Since Java SE 8u131, the JVM
• is “Docker aware with respect to Docker CPU limits transparently”
• has new options for detecting memory limits (not transparent, yet)
• -XX:+UnlockExperimentalVMOptions
• -XX:+UseCGroupMemoryLimitForHeap
BEWARE WHAT THE JVM CAN SEE ! (AND USE !)
Since Java 10
(backported to Java 8u191 !)
the JVM properly (without -XX)
detects CPU and Memory limits
https://blog.docker.com/2018/04/improved-docker-container-integration-with-java-10/
6. WE ALL KNOW DOCKER, BUT…
IS IT THE ONLY OPTION TO BUILD IMAGES AND RUN CONTAINERS ?
FROM openjdk
EXPOSE 8080
ADD app.jar /app.jar
CMD java - jar /app.jar
Linux Container
Docker / OCI Image
Data & Metadata
runbuild
7. WE ALL KNOW DOCKER, BUT…
WHAT ARE THE CONTENDERS ?
“regular” container runtimes
• cri-o
• rkt
Virtualized container runtimes
• katacontainers (uses QEMU,OCI-comp)
• AWS Firecracker (micro VM)
BUILD RUN
Supports Dockerfile ?
Buildah Yes (daemonless)
Bazel No (daemonless)
Makisu Yes (daemonless)
Buildpack No (uses the Docker
daemon for now…)
Jib No (java native builder)
And others local (IMG), and cloud builders : Knative build, DockerHub, Google Cloud Builder, etc.
8. JAVA IMAGE BUILDERS DEMO
• You need a Java project ready (war or executable jar)
• Use buildpack to create and push the image :
• $ pack build anthonydahanne/demo:buildpack --publish
• Use Jib to create and push the image :
• $ mvn package com.google.cloud.tools:jib-maven-plugin:
1.0.1:build -Dimage=anthonydahanne/demo:jib
• we can edit the pom.xml file to configure the plugin too !
CNCF BUILDPACK VS JIB
10. KUBERNETES INTRODUCTION
• Initial release June 7th 2014
• Apache 2 License, written in Go
• heavily inspired by Borg, internal system from Google
• Currently 1.13 (a new release every 3 months on average)
• Under the umbrella of the Cloud Native Computing Foundation
• that includes Oracle, Intel, IBM, Pivotal, Redhat, etc.
• along with Prometheus, Helm, OpenTracing, containerd, CNI, Buildpacks, etc.
FROM BORG TO CNCF
https://l.cncf.io
11. KUBERNETES ARCHITECTURE
By Khtan66 - CC BY-SA 4.0, https://commons.wikimedia.org/w/index.php?curid=53571935
MASTER NODES, WORKER NODES, SOME NETWORKING…
12. Deployment (Declarative Updates)
> kubectl set image deployment/tmc-deployment tmc=tmc:10.3
> kubectl rollout status deployment/tmc-deployment
Replica Set (Match and Scale definitions)
spec:
replicas: 3
selector:
matchLabels:
tier: tmc
KUBERNETES WORKLOADS (PODS AND CONTROLLERS)
DEPLOYMENT > REPLICA SET > POD > CONTAINER
Pod
spec:
containers:
- name: tmc
image: store/softwareag/tmc:10.2
command: [‘start.sh’]
- name: helper-container
image: busybox
command: ['sh', '-c', 'ping tmc’]
volumes: (secrets, configmaps, etc.)
hostname: terracotta
+ Jobs, StatefulSets, Daemon sets, etc.
metadata:
labels:
tier: tmc
13. KUBERNETES SERVICES (L4)
• ClusterIP (default)
• Exposes the service on a cluster-internal IP
• NodePort
• Exposes the service on a port on each node’s IP
• LoadBalancer
• Exposes the service externally,
• using the cluster provided load balancer
HOW DO YOU EXPOSE YOUR WORKLOADS
“A Kubernetes Service is an abstraction which defines a logical set of Pods and a policy by which to access them”
https://kubernetes.io/docs/concepts/services-networking/service/
Node A
Pod-1
labels
tier:frontend
Service
spec:
type: LoadBalancer
ports:
-port:80
selector:
tier:frontend
in | outside
NodeB
Pod-2
labels
tier:frontend
14. KUBERNETES VOLUMES, CONFIG MAPS AND SECRETS
• Many types of volumes are available : hostPath, nfs, cloud specific, etc.
• ConfigMaps and Secrets are stored on the Kubernetes key/value store
YOU CAN MOUNT THEM ALL !
Pod
apiVersion: v1
kind: Pod
spec:
containers:
- name: terracotta-server
image: store/softwareag/terracotta-server:10.2
volumeMounts:
- name: config-volume
mountPath: /config
- name: data
mountPath: /data
volumes:
- name: config-volume
configMap:
name: tc-config
- name: data
hostPath:
path: /usr
ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: tc-config
data:
tc-config.xml: |
<xml></xml>
15. KUBERNETES DEPLOYMENTS
• Cloud providers
• Google Cloud with GKE
• Microsoft Azure with AKS
• Amazon with Kops or EKS
• Oracle Cloud with OKE
• Exoscale, Digital Ocean, OVH, etc.
• Playgrounds
• Katacoda
• Play with Kubernetes
CLOUD, ON-PREMISE, LOCAL
• On-premise
• Hard way
• Kubeadm
• Rancher, OpenShift, Pivotal PKS, etc.
• Local
• Minikube
• Minishift
• Docker for Mac
17. KUBERNETES PACKAGING : HELM
• Helm is installed on the client, Tiller is the server side
• With Helm you deploy / create Charts that are run as Releases
• In a Chart, you package your Kubernetes manifests, and your dependencies
• A very notable feature is the “templatization“ of your Kubernetes manifests
APT / YUM FOR KUBERNETES
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: {{ template "terracotta.fullname" . }}
labels:
app: {{ template "terracotta.name" . }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ template "terracotta.name" . }}
serviceName: {{ template "terracotta.fullname" . }}
spec:
{{- if .Values.nodeSelector }}
nodeSelector:
{{ toYaml .Values.nodeSelector | indent 8 }}
{{- end }}
containers:
- name: {{ template "terracotta.fullname" . }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}”
19. CLASSIC DOCKER AND KUBERNETES TOOLING
• IDE plugins
• auto completion for Dockerfile, Kubernetes and Helm! (IntelliJ, VS Code, etc.)
• To build and deploy images from the IDE
• Build tools (Maven / Gradle) Docker integration
• Maven Docker plugin, Jib
• Docker for Mac / Win 10
•latest stable comes with K8s support
• Minikube, Microk8s, Minishift, Kind
20. KUBERNETES TOOLING : DRAFT
• Draft goal is to streamline Kubernetes development
• Draft will detect your project (JS, Java, etc.) and generate Docker / k8s artifacts
• Typing a simple draft up will :
• build and publish a Docker image
• create and deploy a helm chart to Kubernetes
MAGICALLY AUTO REDEPLOYS ON CHANGE
21. KUBERNETES TOOLING : SKAFFOLD
• Skaffold goal is to auto re-deploy on change
• Can build images using Jib, Bazel or a Dockerfile - locally or “in the cloud”
• A Kubernetes manifest, a skaffold config file and typing skaffold dev :
• watches your source files
• rebuilds them (output is a Docker/OCI image) on change
• (re) deploys your app to Kubernetes
MAGICALLY AUTO REDEPLOYS ON CHANGE
apiVersion: skaffold/v1
kind: Config
build:
artifacts:
- image: anthonydahanne/fullstack
context: .
jibMaven:
profile: "dev,skipTestsAndYarn"
22. KUBERNETES TOOLING : TELEPRESENCE
• Telepresence goal is to allow local processes to be available in a remote
Kubernetes cluster
• A process running on your laptop can access (remote) Kubernetes resources
• It can also be seen by them
• Most common use case is to replace an existing pod with the telepresence pod
that proxies both ways to your local process
MAGICALLY DEPLOY LOCAL PROCESSES INTO THE K8S CLUSTER
> telepresence
--swap-deployment fullstack
--expose 8080:80
--run java -jar target/demo-1.0.0-SNAPSHOT.war
24. MONITORING WITH PROMETHEUS
• CNCF graduated / is the basis for an open monitoring format
• By default pull metrics from apps; but a Node exporter supports push
• Extremely simple to configure for Kubernetes workloads :
• Dropwizard metrics, micrometer, etc. provide Prometheus integration for Java
MONITORING SYSTEM AND TIME SERIES DATABASE
kind: Service
metadata:
annotations:
prometheus.io/scrape: 'true'
prometheus.io/path: '/prometheusMetrics'
25. KUBERNETES OPERATOR IN JAVA
• Operators (or controllers) provide better user experience for deploying and
managing complex applications like databases (PostgreSQL, Terracotta server, etc.)
• They can create and manage their own Custom Resource Definitions (CRDs)
- or provide a CLI or UI via their own REST endpoints
USING FABRIC8 OR KUBERNETES JAVA SDK
<dependency>
<groupId>io.fabric8</groupId>
<artifactId>kubernetes-client</artifactId>
<version>4.1.1</version>
</dependency>
<dependency>
<groupId>io.kubernetes</groupId>
<artifactId>client-java</artifactId>
<version>4.0.0</version>
</dependency>
Service tmcService = new ServiceBuilder()
.withNewMetadata()
.withName("tmc")
.endMetadata()
.withNewSpec()
.addNewPort()
.withName("tmc-port")
.withPort(9480)
.endPort()
.withType("LoadBalancer")
.addToSelector("app", "tmc")
.endSpec()
.build();
26. THE END ! OR JUST THE BEGINNING ?
RBAC
Service Mesh
Ingress controller
…
27. LINKS AND OTHER REFERENCES
• Containers from scratch, talk by Liz Rice
• Analyzing images with Dive, project on Github
• Jib presentation, talk by Qingyang Chen and Appu Goundan
• Deep Dive: Cloud Native Buildpacks - Terence Lee & Joe Kutner
• The fullstack demo app (and its jib, kubernetes, helm, skaffold files) is on Github