Slide 1

Slide 1 text

for Java Developers Docker & Kubernetes Practices

Slide 2

Slide 2 text

2 @saturnism @googlecloud @kubernetesio Ray Tsang Developer Advocate Google Cloud Platform Spring Cloud GCP cloud.spring.io/spring-cloud-gcp/ @saturnism | +RayTsang

Slide 3

Slide 3 text

3 @saturnism @googlecloud @kubernetesio Ray Tsang Developer Architect Traveler Photographer flickr.com/saturnism

Slide 4

Slide 4 text

4 @saturnism @googlecloud @kubernetesio 4 A Short Recap

Slide 5

Slide 5 text

5 @saturnism @googlecloud @kubernetesio apiVersion: extensions/v1beta1 kind: Deployment metadata: name: work-server-v1 ... spec: replicas: 2 template: ... spec: containers: - name: work-server image: saturnism/work-server-istio:v1

Slide 6

Slide 6 text

6 @saturnism @googlecloud @istiomesh @kubernetesio web browsers Scheduler kubectl web browsers scheduler Kubelet Kubelet Kubelet Kubelet Config file Kubernetes Master Container Image

Slide 7

Slide 7 text

7 @saturnism @googlecloud @istiomesh @kubernetesio Let's see it...

Slide 8

Slide 8 text

8 @saturnism @googlecloud @istiomesh @kubernetesio Let's see some practices... Based on materials from: ● Docker Tips and Tricks for Java Developers (Ray Tsang) ● Kubernetes Best Practices (Sandeep Dinesh) ● Kubernetes Security Best Practices (Ian Lewis)

Slide 9

Slide 9 text

9 @saturnism @googlecloud @kubernetesio 9 Building Containers

Slide 10

Slide 10 text

10 @saturnism @googlecloud @kubernetesio Tag your containers! What do these containers have in common? helloworld-service:latest debian:9 openjdk:8

Slide 11

Slide 11 text

11 @saturnism @googlecloud @kubernetesio Pin Your Versions! RUN apt-get update RUN apt-get install curl ← which version??

Slide 12

Slide 12 text

12 @saturnism @googlecloud @kubernetesio Combine Run Commands RUN apt-get update RUN apt-get install -y --no-install-recommends ... RUN rm -rf /var/lib/apt/lists/* vs. RUN apt-get update && \ apt-get install -y --no-install-recommends ... && \ rm -rf /var/lib/apt/lists/*

Slide 13

Slide 13 text

13 @saturnism @googlecloud @kubernetesio Avoid Saving Files RUN curl http://.../apache-tomcat-8.5.20.tar.gz | tar xz -C /opt/

Slide 14

Slide 14 text

14 @saturnism @googlecloud @kubernetesio Don’t Log to Container Filesystem! Log to a volume… docker -v /tmp/log:/log Or, better yet, Send it elsewhere! I prefer STDOUT

Slide 15

Slide 15 text

15 @saturnism @googlecloud @kubernetesio One Container, One Process Don't start multiple processes in daemon

Slide 16

Slide 16 text

16 @saturnism @googlecloud @kubernetesio Don't run as root! It's default… :( Specify via USER directive and switch users

Slide 17

Slide 17 text

17 @saturnism @googlecloud @kubernetesio What's in that public container? Vulnerabilities

Slide 18

Slide 18 text

18 @saturnism @googlecloud @kubernetesio Don't Run as root But I think we all do...

Slide 19

Slide 19 text

19 @saturnism @googlecloud @kubernetesio 19 Specifically, Java Applications

Slide 20

Slide 20 text

20 @saturnism @googlecloud @kubernetesio Use JDK 8u131 or Newer -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap

Slide 21

Slide 21 text

21 @saturnism @googlecloud @kubernetesio Heap vs Native Memory Set -Xmx to percentage of memory limit Use a Startup Script

Slide 22

Slide 22 text

22 @saturnism @googlecloud @kubernetesio Build Thin Layers Use Multi-Stage Build Extract Dependencies to a Layer

Slide 23

Slide 23 text

23 @saturnism @googlecloud @kubernetesio Avoid Multi-Module Project When you have independent services, Don't put in the same multi-module project...

Slide 24

Slide 24 text

24 @saturnism @googlecloud @kubernetesio 24 Running in Kubernetes

Slide 25

Slide 25 text

25 @saturnism @googlecloud @kubernetesio Label, label, label! app=helloworld-service version=2.0 serving=true

Slide 26

Slide 26 text

26 @saturnism @googlecloud @kubernetesio Let it crash Let Kubernetes restart for you

Slide 27

Slide 27 text

27 @saturnism @googlecloud @kubernetesio Assume Unreliable Services Don't sequence/orchestrate startups Handle failures, or let it crash

Slide 28

Slide 28 text

28 @saturnism @googlecloud @kubernetesio L4 vs L7 Know the differences, especially for gRPC

Slide 29

Slide 29 text

29 @saturnism @googlecloud @kubernetesio kubectl apply --record Record the command line, shows in history: kubectl rollout history deployments ...

Slide 30

Slide 30 text

30 @saturnism @googlecloud @kubernetesio Readiness Probe, Liveness Probe If feeling lazy, always have Readiness Probe!

Slide 31

Slide 31 text

31 @saturnism @googlecloud @kubernetesio External Service kind: Service apiVersion: v1 metadata: name: mydatabase namespace: prod spec: type: ExternalName externalName: my.db.example.com kind: Service apiVersion: v1 metadata: name: mydatabase spec: ports: - protocol: TCP port: 80 targetPort: 12345 Then add your own endpoints!

Slide 32

Slide 32 text

32 @saturnism @googlecloud @kubernetesio Graceful Shutdown Lifecycle Hooks Shutdown hooks, or listen to SIGTERM

Slide 33

Slide 33 text

33 @saturnism @googlecloud @kubernetesio 33 More on Security...

Slide 34

Slide 34 text

34 @saturnism @googlecloud @kubernetesio Don't Run as root! apiVersion: v1 kind: Pod metadata: name: hello-world spec: securityContext: runAsNonRoot: true allowPrivilegeEscalation: false runAsUser: 1000 fsGroup: 2000 containers: # specification of the pod’s containers # ...

Slide 35

Slide 35 text

35 @saturnism @googlecloud @kubernetesio Read Only Filesystem apiVersion: v1 kind: Pod metadata: name: hello-world spec: securityContext: readOnlyRootFilesystem: true ... containers: ...

Slide 36

Slide 36 text

36 @saturnism @googlecloud @kubernetesio Containing Breakouts Containers are are not security boundaries! We can try seccomp, apparmor, selinux, but still! annotations: seccomp.security.alpha.kubernetes.io/pod: ... container.apparmor.security.beta.kubernetes.io/hello: ...

Slide 37

Slide 37 text

37 @saturnism @googlecloud @kubernetesio PodSecurityPolicy Enforce Security Policy cluster-wide apiVersion: extensions/v1beta1 kind: PodSecurityPolicy metadata: name: example spec: privileged: false # Don't allow privileged pods! # The rest fills in some required fields. seLinux: rule: RunAsAny supplementalGroups: rule: RunAsAny runAsUser: rule: 1000 fsGroup: rule: RunAsAny

Slide 38

Slide 38 text

38 @saturnism @googlecloud @kubernetesio Service Accounts & RBAC Who can access which Kubernetes API to do what?

Slide 39

Slide 39 text

39 @saturnism @googlecloud @kubernetesio Use use transient credentials Google Kubernetes Engine uses OAuth token

Slide 40

Slide 40 text

40 @saturnism @googlecloud @kubernetesio Better yet, tied to user directory Google Kubernetes Engine ties to Identity Access Manager

Slide 41

Slide 41 text

41 @saturnism @googlecloud @kubernetesio And, don't expose API Server If it's on public internet, make sure it's firewalled gcloud container clusters create --enable-master-authorized-networks --master-authorized-networks=...

Slide 42

Slide 42 text

42 @saturnism @googlecloud @kubernetesio Network Policy Which pod can establish connections to which pod? gcloud container clusters create ... --enable-network-policy

Slide 43

Slide 43 text

43 @saturnism @googlecloud @kubernetesio Mutual TLS Stronger than Network Policy Use a Service Mesh, like Istio Automatic certificate generation and rotation

Slide 44

Slide 44 text

44 @saturnism @googlecloud @kubernetesio 44 CI/CD

Slide 45

Slide 45 text

45 @saturnism @googlecloud @kubernetesio Pull Base Layer Because you are probably using :latest tag

Slide 46

Slide 46 text

46 @saturnism @googlecloud @kubernetesio Build without Cache Because you probably install w/o pinning RUN apt-get update && apt-get install ...

Slide 47

Slide 47 text

47 @saturnism @googlecloud @kubernetesio Check-in YAMLs! If you didn't remember anything else, do this!! If you use a template and don't check-in YAMLs, Must have template + variables values, so you can regenerate it.

Slide 48

Slide 48 text

48 @saturnism @googlecloud @kubernetesio 48 Microservices

Slide 49

Slide 49 text

49 @saturnism @googlecloud @kubernetesio Observability is not a hindsight! Don't wait until something went wrong...

Slide 50

Slide 50 text

50 @saturnism @googlecloud @kubernetesio Trace Log Debug

Slide 51

Slide 51 text

51 @saturnism @googlecloud @kubernetesio 51 Finally...

Slide 52

Slide 52 text

52 @saturnism @googlecloud @kubernetesio Don't manage your own cluster... Use a managed service, like Google Kubernetes Engine!

Slide 53

Slide 53 text

53 @saturnism @googlecloud @kubernetesio 53 Thanks! http://saturnism.me @saturnism