OVHcloud Kubernetes Initiation Tech Lab Horacio Gonzalez 2023-06-05 - Madrid
Slide 2
Who are we? Introducing myself and introducing OVHcloud
Slide 3
Horacio Gonzalez @LostInBrittany Spaniard Lost in Brittany
Flutter
Slide 4
OVHcloud Web Cloud & Telcom
30 Data Centers in 12 locations
1 Million+ Servers produced since 1999
Private Cloud
34 Points of Presence on a 20 TBPS Bandwidth Network
1.5 Million Customers across 132 countries
Public Cloud
2200 Employees worldwide
3.8 Million Websites hosting
Storage
115K Private Cloud VMS running
1.5 Billion Euros Invested since 2016
300K Public Cloud instances running
P.U.E. 1.09 Energy efficiency indicator
380K Physical Servers running in our data centers
20+ Years in Business Disrupting since 1999
Network & Security
Slide 5
Why do we need Kubernetes? Taming the complexity of operating containers
Slide 6
From bare metal to containers
Slide 7
From bare metal to containers
Slide 8
From bare metal to containers
Slide 9
Dockerfiles, images and containers
Slide 10
Containers are easy…
For developers
Slide 11
Less simple if you must operate them
Like in a production context
Slide 12
And what about microservices?
Are you sure you want to operate them by hand?
Slide 13
And what about microservices?
Are you sure you want to operate them by hand?
Slide 14
Kubernetes: a full orchestrator
Slide 15
Not the only orchestrator
But the most popular one…
Slide 16
Kubernetes cluster: masters and nodes
Slide 17
Kubernetes cluster: more details
Slide 18
Desired State Management
Declarative infrastructure
Slide 19
Desired State Management
Slide 20
Let’s deploy an application
Slide 21
Demo: Hello Kubernetes World
https://docs.ovh.com/gb/en/kubernetes/deploying-hello-world/
Putting Kubernetes in production A journey not for the faint of heart
Slide 24
Kubernetes can be wonderful
For both developers and devops
Slide 25
The journey from dev to production
Slide 26
It’s a complex technology
Lots of abstraction layers
Slide 27
Kubernetes networking is complex…
Slide 28
The storage dilemma
Slide 29
The ETCD vulnerability
Slide 30
Kubernetes is insecure by design*
It’s a feature, not a bug. Up to K8s admin to secure it according to needs
Slide 31
Not everybody has the same security needs
Slide 32
Kubernetes allows to enforce security practices as needed
Slide 33
Always keep up to date
Both Kubernetes and plugins
Slide 34
And remember, even the best can get hacked
Remain attentive, don’t get too confident
Slide 35
A managed Kubernetes Because your company job is to use Kubernetes, not to operate it!
Slide 36
Kubernetes is powerful
It can make Developers’ and DevOps’ lives easier
Slide 37
But there is a price: operating it
Lot of things to think about
Slide 38
We have seen some of them
Slide 39
Different roles
Each role asks for very different knowledge and skill sets
Slide 40
Operating a Kubernetes cluster is hard
But we have a good news…
Slide 41
Most companies don’t need to do it!
As they don’t build and rack their own servers!
Slide 42
If you don’t need to build it, choose a certified managed solution
You get the cluster, the operator get the problems
Slide 43
Demo: A complete app - Wordpress
https://docs.ovh.com/gb/en/kubernetes/installing-wordpress/
Slide 44
Needed tools: helm
https://helm.sh/
Slide 45
Helm: a package manager for K8s
Slide 46
Wordpress is easy…
Two pods and a persistent volume
Slide 47
Yet is a complete app
Specially when deployed in production context
Slide 48
Namespaces Logical isolation
Slide 49
Namespaces
Slide 50
Initial namespaces
Slide 51
Working with namespaces $ kubectl create namespace my-namespace namespace/my-namespace created $ kubectl get namespaces NAME STATUS default Active kube-node-lease Active kube-public Active kube-system Active my-namespace Active $ kubectl get NAMESPACE kube-system kube-system kube-system kube-system kube-system kube-system […]
AGE 45d 45d 45d 45d 7s
pods —all-namespaces NAME calico-kube-controllers-6b5885747b-m79ng canal-22dj9 canal-4l4mv canal-6rdxv coredns-9f744c589-64spf coredns-9f744c589-tl26z
READY 1/1 2/2 2/2 2/2 1/1 1/1
STATUS Running Running Running Running Running Running
RESTARTS 0 0 0 0 0 0
AGE 6m58s 7m 6m39s 7m19s 42s 6m25s
Interactively execute commands $ kubectl exec hello-world-deployment-bc4fd6b9-5sgls -c hello-world -it — sh / # ls bin dev etc home lib mnt proc root run sbin srv sys / #
tmp
usr
Execute commands in a container inside a pod
var
Slide 56
Persistent Volumes How to store persistent data in K8s
What if a pod uses too many resources?
CPU is compressible, memory is incompressible
Slide 63
Resource quota kind: ResourceQuota metadata: name: compute-resources spec: hard: requests.cpu: “1” requests.memory: 1Gi limits.cpu: “2” limits.memory: 2Gi requests.nvidia.com/gpu: 4
Limit the total sum of compute resources that can be requested in a given namespace
Slide 64
Limit range apiVersion: v1 kind: LimitRange metadata: name: cpu-resource-constraint spec: limits: - default: # this section defines default limits cpu: 500m defaultRequest: # this section defines default requests cpu: 500m max: # max and min define the limit range cpu: “1” min: cpu: 100m type: Container
Default, minimum and maximum resources usage per pod in a namespace
Config maps
Storing configuration for other objects to use
Slide 73
Creating a Config Map # Create a new configmap named my-config with keys for each file in folder bar $ kubectl create configmap my-config-1 —from-file=./config/bar configmap/my-config created # Create a new configmap named my-config with specified keys instead of names on disk $ kubectl create configmap my-config-2 —from-file=ssh-privatekey=~/.ssh/id_rsa —from-file=ssh-publickey=~/.ssh/id_rsa.pub configmap/my-config created # Create a new configMap named my-config with key1=config1 and key2=config2 $ kubectl create configmap my-config-3 —from-literal=key1=config1 —from-literal=key2=config2 configmap/my-config created
Slide 74
Describing a Config Map apiVersion: v1 kind: ConfigMap metadata: name: game-demo data: # property-like keys; each key maps to a simple value player_initial_lives: “3” ui_properties_file_name: “user-interface.properties” # file-like keys game.properties: | enemy.types=aliens,monsters player.maximum-lives=5 user-interface.properties: | color.good=purple color.bad=yellow allow.textmode=true
Slide 75
Using a Config Map in a Pod
Slide 76
Using a Config Map in a Pod apiVersion: v1 kind: Pod metadata: name: configmap-demo-pod spec: containers: - name: demo image: alpine command: [“sleep”, “3600”] env: # Define the environment variable - name: PLAYER_INITIAL_LIVES # Notice that the case is different here # from the key name in the ConfigMap. valueFrom: configMapKeyRef: name: game-demo # The ConfigMap this value comes from. key: player_initial_lives # The key to fetch. - name: UI_PROPERTIES_FILE_NAME valueFrom: configMapKeyRef: name: game-demo key: ui_properties_file_name
Slide 77
Using a Config Map in a Pod apiVersion: v1 kind: Pod metadata: name: configmap-demo-pod spec: containers: - name: demo image: alpine command: [“sleep”, “3600”] volumeMounts: - name: config mountPath: “/config” readOnly: true volumes: # You set volumes at the Pod level, then mount them into containers inside that Pod - name: config configMap: # Provide the name of the ConfigMap you want to mount. name: game-demo # An array of keys from the ConfigMap to create as files items: - key: “game.properties” path: “game.properties” - key: “user-interface.properties” path: “user-interface.properties”
Slide 78
Kubernetes secrets
Storing sensitive information inside the cluster Encoded in Base64, decoded when attached to a pod
Slide 79
A warning on Kubernetes Secrets
No full encryption All YAMLs and base64
Slide 80
Creating a Secret # Create a new Secret named db-user-pass with username=admin and password=’S!B*d$zDsb=’ $ kubectl create secret generic db-user-pass \ —from-literal=username=admin \ —from-literal=password=’S!B*d$zDsb=’ # Or store the credentials in files: $ echo -n ‘admin’ > ./username.txt $ echo -n ‘S!B*d$zDsb=’ > ./password.txt # And pass the file paths in the kubectl command: $ kubectl create secret generic db-user-pass \ —from-file=username=./username.txt \ —from-file=password=./password.txt
Slide 81
Verifying a Secret # Verify the Secret $ kubectl get secrets NAME TYPE db-user-pass Opaque
DATA 2
AGE 3m34s
$ kubectl describe secret db-user-pass Name: db-user-pass Namespace: default Labels: <none> Annotations: <none> Type:
Opaque
Data ==== password: username:
12 bytes 5 bytes
Slide 82
Decoding a Secret # View the contents of the Secret you created: $ kubectl get secret db-user-pass -o jsonpath=’{.data}’ {“password”:”UyFCXCpkJHpEc2I9”,”username”:”YWRtaW4=”} # Decode the password data: $ echo ‘UyFCXCpkJHpEc2I9’ | base64 —decode S!B*d$zDsb= # In one step: $ kubectl get secret db-user-pass -o jsonpath=’{.data.password}’ | base64 —decode S!B*d$zDsb=
Slide 83
Using a Secret in a Pod
Slide 84
Using a Secret in a Pod apiVersion: v1 kind: Pod metadata: name: mypod spec: containers: - name: mypod image: redis volumeMounts: - name: foo mountPath: “/etc/foo” readOnly: true volumes: - name: foo secret: secretName: mysecret optional: true
Slide 85
Using a Secret in a Pod apiVersion: v1 kind: Pod metadata: name: secret-demo-pod spec: containers: - name: demo image: alpine command: [“sleep”, “3600”] env: # Define the environment variable - name: PASSWORD valueFrom: SecretKeyRef: name: game-secret # The Secret this value comes from. key: game-password # The key to fetch.
Slide 86
Taints & Tolerations And Affinity & Anti-affinity
Slide 87
Taints & Tolerations Taint applied to a Kubernetes Node that signals the scheduler to avoid or not schedule certain Pods
Toleration applied to a Pod definition and provides an exception to the taint
Slide 88
Using Taints & Tolerations # No pod will be able to schedule onto node-5c283f unless it has a matching toleration. $ kubectl taint nodes node-5c283f type=high-cpu:NoSchedule node/node-5c283f tainted apiVersion: v1 kind: Pod metadata: name: nginx labels: env: test spec: containers: - name: nginx image: nginx imagePullPolicy: IfNotPresent tolerations: - key: “high-cpu” operator: “Exists” effect: “NoSchedule”
Slide 89
Example use cases for Taints
Dedicated nodes
Slide 90
Example use cases for Taints
Nodes with Special Hardware
Slide 91
Affinity & Anti-affinity Node Affinity rules that force the pod to be deployed, either exclusively or in priority, in certains nodes
Pod Affinity indicate that a group of pods should always be deployed together on the same node (because of network communication, shared storage, etc.)
Slide 92
Deploy applications to specific Nodes
https://help.ovhcloud.com/csm/fr-public-cloud-kubernetes-label-nodeaffinity-node-pools
Slide 93
OVHcloud Managed Kubernetes Why would you choose ours?
Slide 94
Certified Kubernetes platform
Slide 95
OVHcloud Managed Private Registry
Slide 96
Node Pools
Users can define node pools controlled from inside Kubernetes
Slide 97
Autoscaling
Based on node pools New instances are spawned or released based on load
Slide 98
Kubernetes in a private network
Slide 99
Other features ● ● ● ● ● ●
Healthcare HDS 1 conformity ISO 27001/27701/27017/27018 conformity Terraform provider Control plane audit logs API server IP restrictions …
https://github.com/ovh/public-cloud-roadmap/projects/1 https://discord.com/invite/ovhcloud
Slide 100
Demo: Working with OVHcloud API
https://docs.ovh.com/gb/en/kubernetes/deploying-hello-world-ovh-api/
Slide 101
Infrastructure as Code The perfect companion to a cloud