Formation Kubernetes

Concernant ces supports de cours

Supports de cours réalisés par Particule

Kubernetes : Projet, gouvernance et communauté

Kubernetes

  • COE développé par Google, devenu open source en 2014
  • Adapté à tout type d'environnement
  • Devenu populaire en très peu de temps
  • Premier projet de la CNCF

CNCF

The Foundation’s mission is to create and drive the adoption of a new computing paradigm that is optimized for modern distributed systems environments capable of scaling to tens of thousands of self healing multi-tenant nodes.

CNCF : Prérequis

  • Distribuer sous forme de conteneurs
  • Gestion dynamique de la configuration
  • Orienté micro services

CNCF : Les rôles

  • Intendance des projets
  • Faire grossir et évoluer l'écosystème
  • Rendre la technologie accessible
  • Promouvoir la technologie

OCI

  • Créé sous la Linux Fondation
  • But : Créer un standard Open Source concernant la manière de "runner" et le format des conteneurs et images
  • Non lié à des produits
  • Non lié à des COE
  • runC a été donné par Docker à l'OCI comme implémentions de base

Kubernetes : Projet

Kubernetes : Projet

Kubernetes : Cycle de développement

Kubernetes : Communauté

Kubernetes : KubeCon

La CNCF organise trois KubeCon par an :

  • Amérique du Nord (San Diego, Seattle, etc)
  • Europe (Berlin, Barcelone, Amsterdam etc)
  • Chine

Kubernetes : Architecture

Kubernetes : Composants

  • Kubernetes est écrit en Go, compilé statiquement.
  • Un ensemble de binaires sans dépendance
  • Faciles à conteneuriser et à packager
  • Peut se déployer uniquement avec des conteneurs sans dépendance d'OS

Kubernetes : Composants du Control Plane

  • etcd: Base de données
  • kube-apiserver : API server qui permet la configuration d'objets Kubernetes (Pod, Service, Deployment, etc.)
  • kube-proxy : Permet le forwarding TCP/UDP et le load balancing entre les services et les backends (Pods)
  • kube-scheduler : Implémente les fonctionnalités de scheduling
  • kube-controller-manager : Responsable de l'état du cluster, boucle infinie qui régule l'état du cluster afin d'atteindre un état désiré

Kubernetes : Composants du Control Plane

Kubernetes : Composants du Control Plane

Kubernetes : etcd

  • Base de données de type Clé/Valeur (Key Value Store)
  • Stocke l'état d'un cluster Kubernetes
  • Point sensible (stateful) d'un cluster Kubernetes
  • Projet intégré à la CNCF

Kubernetes : kube-apiserver

  • Les configurations d'objets (Pods, Service, RC, etc.) se font via l'API server
  • Un point d'accès à l'état du cluster aux autres composants via une API REST
  • Tous les composants sont reliés à l'API server

Kubernetes : kube-scheduler

  • Planifie les ressources sur le cluster
  • En fonction de règles implicites (CPU, RAM, stockage disponible, etc.)
  • En fonction de règles explicites (règles d'affinité et anti-affinité, labels, etc.)

Kubernetes : kube-proxy

  • Responsable de la publication de services
  • Utilise iptables
  • Route les paquets à destination des pods et réalise le load balancing TCP/UDP

Kubernetes : kube-proxy

Kubernetes : kube-controller-manager

  • Boucle infinie qui contrôle l'état d'un cluster
  • Effectue des opérations pour atteindre un état donné
  • De base dans Kubernetes : replication controller, endpoints controller, namespace controller et serviceaccounts controller

Kubernetes : Autres composants

  • kubelet : Service "agent" fonctionnant sur tous les nœuds et assure le fonctionnement des autres services
  • kubectl : Ligne de commande permettant de piloter un cluster Kubernetes

Kubernetes : Kubelet

  • Service principal de Kubernetes
  • Permet à Kubernetes de s'auto configurer :
    • Surveille un dossier contenant les manifests (fichiers YAML des différents composant de Kubernetes).
    • Applique les modifications si besoin (upgrade, rollback).
  • Surveille l'état des services du cluster via l'API server (kube-apiserver).

Kubernetes: Network

Kubernetes n'implémente pas de solution réseau par défaut, mais s'appuie sur des solutions tierces qui implémentent les fonctionnalités suivantes:

  • Chaque pods reçoit sa propre adresse IP
  • Les pods peuvent communiquer directement sans NAT

Kubernetes : Aujourd'hui

  • Version 1.18.x : stable en production
  • Solution complète et une des plus utilisées
  • Éprouvée par Google

Kubernetes : Concepts et Objets

Kubernetes : API Resources

  • Namespaces
  • Pods
  • Deployments
  • DaemonSets
  • StatefulSets
  • Jobs
  • Cronjobs

Kubernetes : Namespaces

  • Fournissent une séparation logique des ressources :
    • Par utilisateurs
    • Par projet / applications
    • Autres...
  • Les objets existent uniquement au sein d'un namespace donné
  • Évitent la collision de nom d'objets

Kubernetes : Labels

  • Système de clé/valeur
  • Organisent les différents objets de Kubernetes (Pods, RC, Services, etc.) d'une manière cohérente qui reflète la structure de l'application
  • Corrèlent des éléments de Kubernetes : par exemple un service vers des Pods

Kubernetes : Labels

  • Exemple de label :
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80

Kubernetes : Labels

  • La commande kubectl get pods, par défaut, ne liste pas les labels. Il est possible de les voir en utilisant --show-labels:
$ kubectl get pods --show-labels
NAME      READY     STATUS    RESTARTS   AGE       LABELS
nginx     1/1       Running   0          31s       app=nginx,env=prod

Kubernetes : Pod

  • Ensemble logique composé de un ou plusieurs conteneurs
  • Les conteneurs d'un pod fonctionnent ensemble (instanciation et destruction) et sont orchestrés sur un même hôte
  • Les conteneurs partagent certaines spécifications du Pod :
    • La stack IP (network namespace)
    • Inter-process communication (PID namespace)
    • Volumes
  • C'est la plus petite et la plus simple unité dans Kubernetes

Kubernetes : Pod

  • Les Pods sont définis en YAML comme les fichiers docker-compose :
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80

Kubernetes : Deployment

  • Permet d'assurer le fonctionnement d'un ensemble de Pods
  • Version, Update et Rollback
  • Souvent combiné avec un objet de type service

Kubernetes : Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

Kubernetes : DaemonSet

  • Assure que tous les noeuds exécutent une copie du pod sur tous les noeuds du cluster
  • Ne connaît pas la notion de replicas.
  • Utilisé pour des besoins particuliers comme :
    • l'exécution d'agents de collection de logs comme fluentd ou logstash
    • l'exécution de pilotes pour du matériel comme nvidia-plugin
    • l'exécution d'agents de supervision comme NewRelic agent ou Prometheus node exporter

Kubernetes : DaemonSet

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd-elasticsearch
  namespace: kube-system
  labels:
    k8s-app: fluentd-logging
spec:
  selector:
    matchLabels:
      name: fluentd-elasticsearch
  template:
    metadata:
      labels:
        name: fluentd-elasticsearch
    spec:
      containers:
      - name: fluentd-elasticsearch
        image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2

Kubernetes : StatefulSet

  • Similaire au Deployment
  • Les pods possèdent des identifiants uniques.
  • Chaque replica de pod est créé par ordre d'index
  • Nécessite un Persistent Volume et un Storage Class.
  • Supprimer un StatefulSet ne supprime pas le PV associé

Kubernetes : StatefulSet

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx # has to match .spec.template.metadata.labels
  serviceName: "nginx"
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx # has to match .spec.selector.matchLabels
    spec:
      containers:
      - name: nginx
        image: k8s.gcr.io/nginx-slim:0.8
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "my-storage-class"
      resources:
        requests:
          storage: 1Gi

Kubernetes : Job

  • Crée des pods et s'assurent qu'un certain nombre d'entre eux se terminent avec succès.
  • Peut exécuter plusieurs pods en parallèle
  • Si un noeud du cluster est en panne, les pods sont reschedulés vers un autre noeud.

Kubernetes : Job

apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  parallelism: 1
  completions: 1
  template:
    metadata:
      name: pi
    spec:
      containers:
      - name: pi
        image: perl
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: OnFailure

Kubernetes: Cron Job

  • Un CronJob permet de lancer des Jobs de manière planifiée.
  • la programmation des Jobs se définit au format Cron
  • le champ jobTemplate contient la définition de l'application à lancer comme Job.

Kubernetes : CronJob

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: batch-job-every-fifteen-minutes
spec:
  schedule: "0,15,30,45 * * * *"
  jobTemplate:
    spec:
      template:
        metadata:
          labels:
            app: periodic-batch-job
        spec:
          restartPolicy: OnFailure
          containers:
          -  name: pi
             image: perl
             command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]

Kubernetes : Networking

Kubernetes : Network plugins

  • Kubernetes n'implémente pas de solution de gestion de réseau par défaut
  • Le réseau est implémenté par des solutions tierces :
  • Calico: IPinIP + BGP
  • Cilium: eBPF
  • Weave
  • Bien d'autres

Kubernetes : CNI

  • Container Network Interface
  • Projet dans la CNCF
  • Standard pour la gestion du réseau en environnement conteneurisé
  • Les solutions précédentes s'appuient sur CNI

Kubernetes : Services

  • Abstraction des pods sous forme d'une IP virtuelle de service
  • Rendre un ensemble de pods accessibles depuis l'extérieur
  • Load Balancing entre les pods d'un même service

Kubernetes : Services

  • Load Balancing : intégration avec des cloud provider :
    • AWS ELB
    • GCP
    • Azure Kubernetes Service
    • OpenStack
  • NodePort : chaque noeud du cluster ouvre un port statique et redirige le trafic vers le port indiqué
  • ClusterIP : IP dans le réseau privé Kubernetes (VIP)
  • LoadBalancer : expose le service à l'externe en utilisant le loadbalancer d'un cloud provider (AWS, Google, Azure)

Kubernetes : Services

Kubernetes : Services

  • Exemple de service (on remarque la sélection sur le label et le mode d'exposition):
apiVersion: v1
kind: Service
metadata:
  name: frontend
  labels:
    app: guestbook
    tier: frontend
spec:
  type: NodePort
  ports:
  - port: 80
  selector:
    app: guestbook
    tier: frontend

Kubernetes : Services

Il est aussi possible de mapper un service avec un nom de domaine en spécifiant le paramètre spec.externalName.

kind: Service
apiVersion: v1
metadata:
  name: my-service
  namespace: prod
spec:
  type: ExternalName
  externalName: my.database.example.com

Kubernetes: Ingress

  • L'objet Ingress permet d'exposer un service à l'extérieur d'un cluster Kubernetes
  • Il permet de fournir une URL visible permettant d'accéder un Service Kubernetes
  • Il permet d'avoir des terminations TLS, de faire du Load Balancing, etc...

Kubernetes: Ingress

Kubernetes : Ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: particule
spec:
  rules:
  - host: blog.particule.io
    http:
      paths:
      - path: /
        backend:
          serviceName: particule-nodeport
          servicePort: 80

Kubernetes : Ingress Controller

Pour utiliser un Ingress, il faut un Ingress Controller. Il existe plusieurs offres sur le marché :

Kubernetes : Stockage

Kubernetes : Volumes

  • Fournir du stockage persistent aux pods
  • Fonctionnent de la même façon que les volumes Docker pour les volumes hôte :
    • EmptyDir ~= volumes docker
    • HostPath ~= volumes hôte
  • Support de multiples backend de stockage :
    • GCE : PD
    • AWS : EBS
    • GlusterFS / NFS
    • Ceph
    • iSCSI

Kubernetes : Volumes

  • On déclare d'abord le volume et on l'affecte à un pod :
apiVersion: v1
kind: Pod
metadata:
  name: redis
spec:
  containers:
  - name: redis
    image: redis
    volumeMounts:
    - name: redis-persistent-storage
      mountPath: /data/redis
  volumes:
  - name: redis-persistent-storage
    emptyDir: {}

Kubernetes : Storage Class

  • Permet de définir les différents types de stockage disponibles
  • Utilisé par les Persistent Volumes pour solliciter un espace de stockage au travers des Persistent Volume Claims

Kubernetes : Storage Class

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: slow
provisioner: kubernetes.io/aws-ebs
parameters:
  type: io1
  zones: us-east-1d, us-east-1c
  iopsPerGB: "10"

Kubernetes : PersistentVolumeClaims

  • Ressource utilisée et vue comme une requête pour solliciter du stockage persistant
  • Offre aux PV une variété d'options en fonction du cas d'utilisation
  • Utilisé par les StatefulSets pour solliciter du stockage (Utilisaltion du champ volumeClaimTemplates)

Kubernetes : PersistentVolumeClaims

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
    name: storage-claim
spec:
    accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  storageClassName: "slow"

Kubernetes : PersistentVolume

  • Composant de stockage dans le cluster kubernetes
  • Stockage externe aux noeuds du cluster
  • Cycle de vie d'indépendant du pod qui le consomme
  • Peut être provisionné manuellement par un administrateur ou dynamiquement grâce un StorageClass

Kubernetes : PersistentVolume

apiVersion: v1
kind: PersistentVolume
metadata:
  name: persistent-volume-1
spec:
  storageClassName: slow
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/tmp/data"

Kubernetes : CSI

  • Container Storage Interface
  • Équivalent de CNI mais pour les volumes
  • Avant Kubernetes 1.13, tous les drivers de volumes étaient in tree
  • Le but de la séparation est de sortir du code du core de Kubernetes
  • GA depuis Kubernetes 1.13

Kubernetes : CSI

Kubernetes : Gestion de la configuration des applications

Kubernetes : ConfigMaps

  • Objet Kubernetes permettant stocker séparer les fichiers de configuration
  • Il peut être créé d'un ensemble de valeurs ou d'un fichier resource Kubernetes (YAML ou JSON)
  • Un ConfigMap peut sollicité par plusieurs pods

Kubernetes : ConfigMaps

apiVersion: v1
data:
    redis-config: |
      maxmemory 2mb
      maxmemory-policy allkeys-lru
kind: ConfigMap
metadata:
  name: redis-config
  namespace: default

Kubernetes : ConfigMap environnement

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      command: [ "/bin/sh", "-c", "env" ]
      env:
        - name: SPECIAL_LEVEL_KEY
          valueFrom:
            configMapKeyRef:
              name: special-config
              key: special.how
        - name: LOG_LEVEL
          valueFrom:
            configMapKeyRef:
              name: env-config
              key: log_level
  restartPolicy: Never

Kubernetes: ConfigMap volume

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      command: [ "/bin/sh", "-c", "ls /etc/config/" ]
      volumeMounts:
      - name: config-volume
        mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        # Provide the name of the ConfigMap containing the files you want
        # to add to the container
        name: special-config
  restartPolicy: Never

Kubernetes : Secrets

  • Objet Kubernetes de type secret utilisé pour stocker des informations sensibles comme les mots de passe, les tokens, les clés SSH...
  • Similaire à un ConfigMap, à la seule différence que le contenu des entrées présentes dans le champ data sont encodés en base64.
  • Il est possible de directement créer un Secret spécifique à l'authentification sur un registre Docker privé.
  • Il est possible de directement créer un Secret à partir d'un compte utilisateur et d'un mot de passe.

Kubernets : Secrets

  • S'utilisent de la même façon que les ConfigMap
  • La seule différence est le stockage en base64
  • 3 types de secrets:
  • Generic: valeurs arbitraire comme dans une ConfigMap
  • tls: certificat et clé pour utilisation avec un serveur web
  • docker-registry: utilisé en tant que imagePullSecret par un pod pour pouvoir pull les images d'une registry privée

Kubernetes : Secrets

$ kubectl create secret docker-registry mydockerhubsecret \
--docker-username="employeeusername" --docker-password="employeepassword" \
--docker-email="employee.email@organization.com"
kubectl create secret generic dev-db-secret --from-literal=username=devuser --from-literal=password='S!B\*d$zDsb'

Kubernetes : Secrets

apiVersion: v1
kind: Secret
metadata:
  creationTimestamp: 2016-01-22T18:41:56Z
  name: mysecret
  namespace: default
  resourceVersion: "164619"
  uid: cfee02d6-c137-11e5-8d73-42010af00002
type: Opaque
data:
  username: YWRtaW4=
  password: MWYyZDFlMmU2N2Rm

Kubernetes : Gestion des ressources

Pods resources : request et limits

  • Permettent de gérer l'allocation de ressources au sein d'un cluster
  • Par défaut, un pod/container sans request/limits est en best effort
  • Request: allocation minimum garantie (réservation)
  • Limit: allocation maximum (limite)
  • Se base sur le CPU et la RAM

Pods resources : CPU

  • 1 CPU est globalement équivalent à un cœur
  • L'allocation se fait par fraction de CPU:
  • 1 : 1 vCPU entier
  • 100m : 0.1 vCPU
  • 0.5 : 1/2 vCPU
  • Lorsqu'un conteneur atteint la limite CPU, celui ci est throttled

Pods resources : RAM

  • L'allocation se fait en unité de RAM:
  • M : en base 10
  • Mi : en base 2
  • Lorsqu'un conteneur atteint la limite RAM, celui ci est OOMKilled

Pods resources : request et limits

apiVersion: v1
kind: Pod
metadata:
  name: frontend
spec:
  containers:
  - name: db
    image: mysql
    env:
    - name: MYSQL_ROOT_PASSWORD
      value: "password"
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"
  - name: wp
    image: wordpress
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"

Horizontal Autoscaling

  • Permet de scaler automatiquement le nombre de pods d'un deployment
  • Métriques classiques (CPU/RAM): En fonction d'un % de la request CPU/RAM
  • Métriques custom (Applicative)

Horizontal Autoscaling

apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: php-apache
  namespace: default
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: php-apache
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50

LimitRanges

  • l'objet LimitRange permet de définir les valeurs minimales et maximales des ressources utilisées par les containers et les pods
  • l'objet LimitRange s'applique au niveau du namespace
  • les limites spécifiées s'appliquent à chaque pod/container créé dans le namespace
  • le LimitRange ne limite pas le nombre total de ressources disponibles dans le namespace

LimitRanges

apiVersion: v1
kind: LimitRange
metadata:
  name: limit-example
spec:
  limits:
  - default:
      memory: 512Mi
    defaultRequest:
      memory: 256 Mi
    type: Container

ResourceQuotas

  • un objet ResourceQuota limite le total des ressources de calcul consommées par les pods ainsi que le total de l'espace de stockage consommé par les PersistentVolumeClaims dans un namespace
  • il permet aussi de limiter le nombre de pods, PVC et autres objets qui peuvent être créés dans un namespace

ResourceQuotas

apiVersion: v1
kind: ResourceQuota
metadata:
  name: cpu-and-ram
spec:
  hard:
    requests.cpu: 400m
    requests.memory: 200Mi
    limits.cpu: 600m
    limits.memory: 500Mi

Kubernetes : Observabilité et monitoring

Sondes : Readiness and Liveness

  • Permettent à Kubernetes de sonder l'état d'un pod et d'agir en conséquence
  • 2 types de sonde : Readiness et Liveness
  • 3 manières de sonder :
  • TCP : ping TCP sur un port donné
  • HTTP: http GET sur une url donnée
  • Command: Exécute une commande dans le conteneur

Sondes : Readiness

  • Gère le trafic à destination du pod
  • Un pod avec une sonde readiness NotReady ne reçoit aucun trafic
  • Permet d'attendre que le service dans le conteneur soit prêt avant de router du trafic
  • Un pod Ready est ensuite enregistrer dans les endpoints du service associé

Sondes : Liveness

  • Gère le redémarrage du conteneur en cas d'incident
  • Un pod avec une sonde liveness sans succès est redémarré au bout d'un intervalle défini
  • Permet de redémarrer automatiquement les pods "tombés" en erreur

Sondes : Exemple

apiVersion: v1
kind: Pod
metadata:
  name: goproxy
  labels:
    app: goproxy
spec:
  containers:
  - name: goproxy
    image: k8s.gcr.io/goproxy:0.1
    ports:
    - containerPort: 8080
    readinessProbe:
      tcpSocket:
        port: 8080
      initialDelaySeconds: 5
      periodSeconds: 10
    livenessProbe:
      tcpSocket:
        port: 8080
      initialDelaySeconds: 15
      periodSeconds: 20

Kubernetes : Utilisation et déploiement des ressources

Kubernetes : Kubectl

  • Le seul (ou presque) outil pour interagir avec des clusters Kubernetes
  • Utilise un fichier de configuration (kubeconfig) pour communiquer avec l'API de Kubernetes
  • Le(s) fichier(s) se trouve(nt) par défaut dans ~/.kube/config
  • Le fichier de config. contient :
    • L'adresse(URI) de l'APIServer
    • Les chemins des certificats TLS utilisés pour l'authentification
  • Fichier kubeconfig peut être passé en paramètre de kubectl avec le flag --kubeconfig

Kubeconfig

Un seul fichier pour gérer tous ses clusters avec trois informations :

  • Serveurs (IP, CA Cert, Nom)
  • Users (Nom, Certificat, Clé)
  • Context, association d'un user et d'un serveur

Stocké par défaut dans ~/.kube/config

Kubernetes : Kubectl

  • Afficher la liste des ressources API supportées par le serveur:
$ kubectl api-resources
NAME                              SHORTNAMES   APIGROUP                             NAMESPACED   KIND
configmaps                        cm                                                true         ConfigMap
limitranges                       limits                                            true         LimitRange
namespaces                        ns                                                false        Namespace
nodes                             no                                                false        Node
persistentvolumeclaims            pvc                                               true         PersistentVolumeClaim
persistentvolumes                 pv                                                false        PersistentVolume
pods                              po                                                true         Pod
secrets                                                                             true         Secret
services                          svc                                               true         Service
daemonsets                        ds           apps                                 true         DaemonSet
deployments                       deploy       apps                                 true         Deployment
replicasets                       rs           apps                                 true         ReplicaSet
statefulsets                      sts          apps                                 true         StatefulSet
horizontalpodautoscalers          hpa          autoscaling                          true         HorizontalPodAutoscaler
cronjobs                          cj           batch                                true         CronJob
jobs                                           batch                                true         Job
ingresses                         ing          extensions                           true         Ingress

Kubernetes : Kubectl

  • Afficher les noeuds du cluster :
kubectl get nodes
  • Ces commandes sont équivalentes:
kubectl get no
kubectl get nodes

Kubernetes : Kubectl

  • Afficher les namespaces
kubectl get ns
kubectl get namespaces
  • Par défaut, kubectl utilise le namespace default
  • Il est possible de sélectionner un namespace avec l'option -n ou --namespace
kubectl -n kube-system get pods

Kubernetes : Kubectl

  • Afficher les pods (pour le namespace default)
kubectl get pods
kubectl get pod

Kubernetes : Kubectl

  • Afficher les services (pour le namespace default):
kubectl get services
kubectl get svc

Kubernetes : Création d'objets Kubernetes

  • Les objets Kubernetes sont créés sous la forme de fichiers JSON ou YAML et envoyés à l'APIServer
  • Possible d'utiliser la commande kubectl run, mais limitée aux Deployments et aux Jobs
  • L'utilisation de fichiers YAML permet de les stocker dans un système de contrôle de version comme git, mercurial, etc...
  • La documentation de référence pour l'API Kubernetes https://kubernetes.io/docs/reference/#api-reference

Kubernetes : Création d'objets Kubernetes

  • Pour créer un object Kubernetes depuis votre fichier YAML, utilisez la commande kubectl create :
kubectl create -f object.yaml
  • Il est possible de créer des objets Kubernetes à partir d'une URL :
kubectl create -f https://raw.githubusercontent.com/kubernetes/examples/master/guestbook/frontend-deployment.yaml

Kubernetes : Création d'objets Kubernetes

  • Pour les supprimer exécuter simplement :
kubectl delete -f object.yaml
  • Mettre à jour un objet Kubernetes en écrasant la configuration existante:
kubectl replace -f object.yaml

Kubernetes : Kubernetes Dashboard

  • Interface graphique web pour les clusters Kubernetes
  • Permet de gérer les différents objets Kubernetes créés dans le(s) cluster(s).
  • Installé par défaut dans minikube

Kubernetes : Kubernetes Dashboard

Kubernetes : Kubernetes Dashboard

  • Pour déployer le Dashboard, exécuter la commande suivante:
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml
  • Pour accéder au Dashboard, il faut établir une communication entre votre poste et le cluster Kubernetes :
$ kubectl proxy
  • L'accès se fait désormais sur :

http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/

Kubernetes : Introduction to Helm

  • Une application conçue pour faciliter l'installation et la gestion des applications sur Kubernetes.
  • Il utilise un format de paquetage appelé Charts.
  • Il est comparable à apt/yum/homebrew.
  • Plusieurs charts existent déjà sur le répertoire officiel : https://github.com/kubernetes/charts.

Kubernetes : Introduction to Helm

  • Tiller : Serveur Helm. Il interagit avec l'APIServer de Kubernetes pour installer, mettre à jour et supprimer les ressources Kubernetes.
  • Chart : Contient toutes les ressources définies et nécessaires pour éxecuter une application ou un service à l'intérieur de cluster Kubernetes. Un chart est pratiquement un regroupement de ressources Kubernetes pré-configurées.
  • Release : Une instance d'un chart helm s'éxécutant dans un cluster Kubernetes.
  • Repository : répertoire ou espace (public ou privé) où sont regroupés les charts.

Kubernetes : Introduction to Helm

  • Installer Helm (sur une distribution Linux):
  • Deployer tiller : helm init
  • Voir la liste des charts disponibles sur les répertoire officiel : helm search
  • Afficher la liste des charts disponibles pour prometheus : helm search prometheus
  • Afficher les options disponibles dans un chart Helm: helm inspect stable/prometheus

Kubectl : Advanced Usage

  • Il est possible de mettre à jour un service sans incident grâce ce qui est appelé le rolling-update.
  • Avec les rolling updates, les ressources qu'expose un objet Service se mettent à jour progressivement.
  • Seuls les objets Deployment, DaemonSet et StatefulSet support les rolling updates.
  • Les arguments maxSurge et maxUnavailabe définissent le rythme du rolling update.
  • La commande kubectl rollout permet de suivre les rolling updates effectués.

Kubectl : Advanced Usage

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  selector:
    matchLabels:
      app: frontend
  replicas: 2
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
    type: RollingUpdate
  template:
    metadata:
      name: nginx
      labels:
        app: frontend
    spec:
      containers:
        - image: nginx:1.9.1
          name: nginx

Kubectl : Advanced Usage

$ kubectl create -f nginx.yaml --record
deployment.apps/nginx created

Kubectl : Advanced Usage

  • Il est possible d'augmenter le nombre de pods avec la commande kubectl scale :
kubectl scale --replicas=5 deployment nginx
  • Il est possible de changer l'image d'un container utilisée par un Deployment :
kubectl set image deployment nginx nginx=nginx:1.15

Kubectl : Advanced Usage

  • Dry run. Afficher les objets de l'API correspondant sans les créer :

kubectl run nginx --image=nginx --dry-run

  • Démarrer un container en utiliser une commande différente et des arguments différents :
kubectl run nginx --image=nginx \
--command -- <cmd> <arg1> ... <argN>
  • Démarrer un Cron Job qui calcule π et l'affiche toutes les 5 minutes :
kubectl run pi --schedule="0/5 * * * ?" --image=perl --restart=OnFailure \
-- perl -Mbignum=bpi -wle 'print bpi(2000)'

Kubectl : Advanced Usage

  • Se connecter à un container:
kubectl run -it busybox --image=busybox -- sh
  • S'attacher à un container existant :
kubectl attach my-pod -i
  • Accéder à un service via un port :
kubectl port-forward my-svc 6000

Kubectl : Logging

  • Utiliser kubectl pour diagnostiquer les applications et le cluster kubernetes :
kubectl cluster-info
kubectl get events
kubectl describe node <NODE_NAME>
kubectl  logs (-f) <POD_NAME>

Kubectl : Maintenance

  • Obtenir la liste des noeuds ainsi que les informations détaillées :
kubectl get nodes
kubectl describe nodes

Kubectl : Maintenance

  • Marquer le noeud comme unschedulable (+ drainer les pods) et schedulable :
kubectl cordon <NODE_NAME>
kubectl drain <NDOE_NAME>
kubectl uncordon <NODE_NAME>

Kubernetes : Installation

Kubernetes : Minikube

  • Outil permettant de démarrer rapidement un cluster mono-node Kubernetes localement
  • Execute Kubernetes dans une machine virtuelle
  • Nécessite des outils de virtualisation (VirtualBox, VMware Fusion, KVM, etc...)
  • Supporte plusieurs systèmes d'exploitation : Linux, Mac OS, Windows
  • Installation : https://github.com/kubernetes/minikube#Installation

Kubernetes : Minikube

  • Création d'un cluster Kubernetes
$ minikube get-k8s-versions
The following Kubernetes versions are available when using the localkube bootstrapper:
  - v1.16.1
  - v1.15.5
  - v1.14.3
  - v1.9.4
  - v1.9.0

Kubernetes : Minikube

$minikube start --kubernetes-version="v1.16.1"
Starting local Kubernetes v1.16.1 cluster...
Starting VM...
Getting VM IP address...
[...]
Connecting to cluster...
Setting up kubeconfig...
Starting cluster components...
Kubectl is now configured to use the cluster.
Loading cached images from config file.

Kubernetes : Minikube

  • Effectuer un diagnostic basique du cluster
$ kubectl version
Client Version: v1.16.1
Server Version: v1.16.1

Kubernetes : Minikube

$ kubectl get componentstatuses
NAME                      STATUS    MESSAGE              ERROR
controller-manager   Healthy      ok
scheduler                  Healthy      ok
etcd-0                       Healthy      {"health": "true"}

Installation de Kubernetes

  • De nombreuses ressources présentes pour le déploiement de Kubernetes dans un environnement de production

  • Un des outils est kubeadm utilisé pour rapidement démarrer un cluster Kubernetes

Installation de Kubernetes avec Kubeadm

Kubeadm

  • Installer les composants Kubernetes (kubeadm, kubectl, kubelet) : https://kubernetes.io/docs/setup/independent/install-kubeadm/
  • Exécuter kubeadm init sur le noeud master
  • Exécuter kubeadm join sur les autres noeuds (avec le token fournir par la commande kubeadm init)
  • Copier le fichier de configuration généré par kubeadm init
  • Installer le plugin Réseau

Kubeadm

En plus de l'installation de Kubernetes, Kubeadm peut :

  • Renouveler les certificats du Control Plane
  • Générer des certificats utilisateurs signés par Kubernetes
  • Effectuer des upgrades de Kubernetes (kubeadm upgrade)

Kubernetes managés "as a Service"

Installation de Kubernetes

Introduction à Sonobuoy

Kubernetes : Securité et Controle d'accès

Authentication & Autorisation

  • RBAC (Role Based Access Control)
  • ABAC (Attribute-based access control)
  • WebHook
  • Certificates
  • Token

RBAC

3 entités sont utilisées :

  • Utilisateurs représentés par les Users ou les ServiceAccounts
  • Resources représentées par les Deployments, Pods, Services, etc...
  • les différentes opérations possibles : create, list, get, delete, watch, patch

RBAC

Service Accounts

  • Objet Kubernetes permettant d'identifier une application s'éxecutant dans un pod
  • Par défaut, un ServiceAccount par namespace
  • Le ServiceAccount est formatté ainsi :
system:serviceaccount:<namespace>:<service_account_name>

Service Accounts

apiVersion: v1
kind: ServiceAccount
metadata:
    name: default
    namespace: default

Role

  • L'objet Role est un ensemble de règles permettant de définir quelle opération (ou verbe) peut être effectuée et sur quelle ressource
  • Le Role ne s'applique qu'à un seul namespace et les ressources liées à ce namespace

Role

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

RoleBinding

  • L'objet RoleBinding va allouer à un User, ServiceAccount ou un groupe les permissions dans l'objet Role associé
  • Un objet RoleBinding doit référencer un Role dans le même namespace.
  • L'objet roleRef spécifié dans le RoleBinding est celui qui crée le liaison

RoleBinding

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: read-pods
  namespace: default
subjects:
- kind: User
  name: jane
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

ClusterRole

  • L'objet ClusterRole est similaire au Role à la différence qu'il n'est pas limité à un seul namespace
  • Il permet d'accéder à des ressources non limitées à un namespace comme les nodes

ClusterRole

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: secret-reader
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "watch", "list"]

ClusterRoleBinding

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: salme-reads-all-pods
subjects:
- kind: User
  name: jsalmeron
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

RBAC

kubectl auth can-i get pods /
--namespace=default /
--as=spesnova@example.com

NetworkPolicies

  • La ressource NetworkPolicy est une spécification permettant de définir comment un ensemble de pods communiquent entre eux ou avec d'autres endpoints
  • Le NetworkPolicy utilisent les labels pour sélectionner les pods sur lesquels s'appliquent les règles qui définissent le trafic alloué sur les pods sélectionnés
  • Le NetworkPolicy est générique et fait partie de l'API Kubernetes. Il est nécessaire que le plugin réseau déployé supporte cette spécification

NetworkPolicies

NetworkPolicies

  • Exemple de NetworkPolicy permettant de blocker le trafic entrant :
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: web-deny-all
spec:
  podSelector:
    matchLabels:
      app: web
  ingress: []

PodSecurityPolicies

  • Permet de contrôler les privilèges d'un pod
  • Permet de définir ce qui est autorisé pendant l'exécution du pod
  • A utiliser dans un contexte multi-tenant et quand les pods ne viennent pas d'un tiers de confiance
  • Peut-être combiné avec le RBAC
  • Attention: Activer cette fonctionnalité peut endommager votre environnement
  • Il faut une PSP par défaut

PodSecurityPolicies

apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: restricted
spec:
  privileged: false
  allowPrivilegeEscalation: false
  requiredDropCapabilities:
    - ALL
  hostNetwork: false
  hostIPC: false
  hostPID: false
  runAsUser:
    rule: 'MustRunAsNonRoot'
  readOnlyRootFilesystem: false

Admission Controllers

  • Interceptes les requêtes sur l'API Kubernetes
  • Peut effectuer des modifications si nécessaires
  • Conception personnalisée possible

Admission Controllers

  • DenyEscalatingExec
  • ImagePolicyWebhook
  • NodeRestriction
  • PodSecurityPolicy
  • SecurityContextDeny
  • ServiceAccount

Conclusion