Formation Kubernetes

Concernant ces supports de cours

Supports de cours réalisés par Particule

Le Cloud : vue d’ensemble

Le cloud, c’est large !

  • Stockage/calcul distant (on oublie, cf. externalisation)

  • Virtualisation++

  • Abstraction du matériel (voire plus)

  • Accès normalisé par des APIs

  • Service et facturation à la demande

  • Flexibilité, élasticité

WaaS : Whatever as a Service

  • IaaS : Infrastructure as a Service

  • PaaS : Platform as a Service

  • SaaS : Software as a Service

Le cloud en un schéma

Pourquoi du cloud ? Côté technique

  • Abstraction des couches basses

  • On peut tout programmer à son gré (API)

  • Permet la mise en place d’architectures scalables

Virtualisation dans le cloud

  • Le cloud IaaS repose souvent sur la virtualisation

  • Ressources compute : virtualisation

  • Virtualisation complète : KVM, Xen

  • Virtualisation conteneurs : OpenVZ, LXC, Docker, RKT

Notions et vocabulaire IaaS

  • L’instance est par définition éphémère

  • Elle doit être utilisée comme ressource de calcul

  • Séparer les données des instances

Orchestration des ressources ?

  • Groupement fonctionnel de ressources : micro services

  • Infrastructure as Code : Définir toute une infrastructure dans un seul fichier texte de manière déclarative

  • Scalabilité : passer à l'échelle son infrastructure en fonction de différentes métriques.

Positionnement des conteneurs dans l'écosystème Cloud ?

  • Facilitent la mise en place de PaaS

  • Fonctionnent sur du IaaS ou sur du bare-metal

  • Simplifient la décomposition d'applications en micro services

Les conteneurs

Définition

  • Les conteneurs fournissent un environnement isolé sur un système hôte, semblable à un chroot sous Linux ou une jail sous BSD, mais en proposant plus de fonctionnalités en matière d'isolation et de configuration. Ces fonctionnalités sont dépendantes du système hôte et notamment du kernel.

Le Kernel Linux

  • Namespaces

  • Cgroups (control groups)

Les namespaces

Mount namespaces ( Linux 2.4.19)

  • Permet de créer un arbre des points de montage indépendants de celui du système hôte.

UTS namespaces (Linux 2.6.19)

  • Unix Time Sharing : Permet à un conteneur de disposer de son propre nom de domaine et d’identité NIS sur laquelle certains protocoles tel que LDAP peuvent se baser.

IPC namespaces (Linux 2.6.19)

  • Inter Process Communication : Permet d’isoler les bus de communication entre les processus d’un conteneur.

PID namespaces (Linux 2.6.24)

  • Isole l’arbre d’exécution des processus et permet donc à chaque conteneur de disposer de son propre processus maître (PID 0) qui pourra ensuite exécuter et manager d'autres processus avec des droits illimités tout en étant un processus restreint au sein du système hôte.

User namespaces (Linux 2.6.23-3.8)

  • Permet l’isolation des utilisateurs et des groupes au sein d’un conteneur. Cela permet notamment de gérer des utilisateurs tels que l’UID 0 et GID 0, le root qui aurait des permissions absolues au sein d’un namespace mais pas au sein du système hôte.

Network namespaces (Linux 2.6.29)

  • Permet l’isolation des ressources associées au réseau, chaque namespace dispose de ses propres cartes réseaux, plan IP, table de routage, etc.

Cgroups : Control Croups

CGroup: /
           |--docker
           |  |--7a977a50f48f2970b6ede780d687e72c0416d9ab6e0b02030698c1633fdde956
           |  |--6807 nginx: master process ngin
           |  |  |--6847 nginx: worker proces

Cgroups : Limitation de ressources

  • Limitation des ressources : des groupes peuvent être mis en place afin de ne pas dépasser une limite de mémoire.

Cgroups : Priorisation

  • Priorisation : certains groupes peuvent obtenir une plus grande part de ressources processeur ou de bande passante d'entrée-sortie.

Cgroups : Comptabilité

  • Comptabilité : permet de mesurer la quantité de ressources consommées par certains systèmes, en vue de leur facturation par exemple.

Cgroups : Isolation

  • Isolation : séparation par espace de nommage pour les groupes, afin qu'ils ne puissent pas voir les processus des autres, leurs connexions réseaux ou leurs fichiers.

Cgroups : Contrôle

  • Contrôle : figer les groupes ou créer un point de sauvegarde et redémarrer.

Deux philosophies de conteneurs

  • Systeme : simule une séquence de boot complète avec un init process ainsi que plusieurs processus (LXC, OpenVZ).
  • Process : un conteneur exécute un ou plusieurs processus directement, en fonction de l'application conteneurisée (Docker, Rkt).

Encore plus “cloud” qu’une instance

  • Partage du kernel

  • Un seul processus par conteneur

  • Le conteneur est encore plus éphémère que l’instance

  • Le turnover des conteneurs est élevé : orchestration

Container runtime

Permettent d'exécuter des conteneurs sur un système

  • docker: historique

  • containerd: implémentation de référence

  • cri-o: implémentation Open Source développée par RedHat

  • kata containers: Conteneurs dans des VMs

Les conteneurs: conclusion

  • Fonctionnalités offertes par le Kernel

  • Les conteneurs engine fournissent des interfaces d'abstraction

  • Plusieurs types de conteneurs pour différents besoins

Build, Ship and Run !

Build

Le conteneur et son image

  • Flexibilité et élasticité

  • Format standard de facto

  • Instanciation illimitée

Construction d'une image

  • Possibilité de construire son image à la main (long et source d'erreurs)

  • Suivi de version et construction d'images de manière automatisée

  • Utilisation de Dockerfile afin de garantir l'idempotence des images

Dockerfile

  • Suite d'instruction qui définit une image

  • Permet de vérifier le contenu d'une image

FROM alpine:3.4
MAINTAINER Particule <admin@particule.io>
RUN apk -U add nginx
EXPOSE 80 443
CMD ["nginx"]

Dockerfile : principales instructions

  • FROM : baseimage utilisée

  • RUN : Commandes effectuées lors du build de l'image

  • EXPOSE : Ports exposées lors du run (si -P est précisé)

  • ENV : Variables d'environnement du conteneur à l'instanciation

  • CMD : Commande unique lancée par le conteneur

  • ENTRYPOINT : "Préfixe" de la commande unique lancée par le conteneur

Dockerfile : best practices

  • Bien choisir sa baseimage

  • Chaque commande Dockerfile génère un nouveau layer

  • Comptez vos layers !

Dockerfile : Bad Layering

RUN apk --update add \
    git \
    tzdata \
    python \
    unrar \
    zip \
    libxslt \
    py-pip \

RUN rm -rf /var/cache/apk/*

VOLUME /config /downloads

EXPOSE 8081

CMD ["--datadir=/config", "--nolaunch"]

ENTRYPOINT ["/usr/bin/env","python2","/sickrage/SickBeard.py"]

Dockerfile : Good Layering

RUN apk --update add \
    git \
    tzdata \
    python \
    unrar \
    zip \
    libxslt \
    py-pip \
    && rm -rf /var/cache/apk/*

VOLUME /config /downloads

EXPOSE 8081

CMD ["--datadir=/config", "--nolaunch"]

ENTRYPOINT ["/usr/bin/env","python2","/sickrage/SickBeard.py"]

Dockerfile : DockerHub

  • Build automatisée d'images Docker

  • Intégration GitHub / DockerHub

  • Plateforme de stockage et de distribution d'images Docker

Ship

Ship : Les conteneurs sont manipulables

  • Sauvegarder un conteneur :
docker commit mon-conteneur backup/mon-conteneur
docker run -it backup/mon-conteneur
  • Exporter une image :
docker save -o mon-image.tar backup/mon-conteneur
  • Importer un conteneur :
docker import mon-image.tar backup/mon-conteneur

Ship : Docker Registry

  • DockerHub n’est qu’au Docker registry ce que GitHub est à git

  • Pull and Push

  • Image officielle : registry

Run

Run : lancer un conteneur

  • docker run

  • -d (detach)

  • -i (interactive)

  • -t (pseudo tty)

Run : beaucoup d’options...

  • -v /directory/host:/directory/container

  • -p portHost:portContainer

  • -P

  • -e “VARIABLE=valeur”

  • --restart=always

  • --name=mon-conteneur

Run : ...dont certaines un peu dangereuses

  • --privileged (Accès à tous les devices)

  • --pid=host (Accès aux PID de l’host)

  • --net=host (Accès à la stack IP de l’host)

Run : se “connecter” à un conteneur

  • docker exec

  • docker attach

Run : Détruire un conteneur

  • docker kill (SIGKILL)

  • docker stop (SIGTERM puis SIGKILL)

  • docker rm (détruit complètement)

Build, Ship and Run : Conclusions

  • Écosystème de gestion d'images

  • Construction automatisée d'images

  • Contrôle au niveau conteneurs

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émention 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, Boston, 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 des Services
  • Utilise iptables
  • Route les paquets à destination des conteneurs et réalise le load balancing TCP/UDP

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 : Kubelet

  • Assure la communication entre les nodes et l'apiserver
  • En charge de créer les conteneurs au travers de l'interface Container Runtime Interface (CRI)
  • Peut fonctionner avec différentes container runtimes

Kubernetes : Kubelet

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 : 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 : 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 :

Kubernetes : Deployment

  • Permet d'assurer le fonctionnement d'un ensemble de Pods
  • Version, Update et Rollback
  • Anciennement appelés Replication Controllers

Kubernetes : Deployment

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
  • 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
spec:
  selector:
    matchLabels:
      name: fluentd
  template:
    metadata:
      labels:
        name: fluentd
    spec:
      containers:
      - name: fluentd
        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
  serviceName: "nginx"
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    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 : VXLAN
  • 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 ou l'intérieur du cluster
  • Load Balancing entre les Pods d'un même Service
  • Sélection des Pods faisant parti d'un Service grâce aux labels

Kubernetes : Services

Kubernetes : Services ClusterIP

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

Kubernetes : Service NodePort

NodePort : chaque noeud du cluster ouvre un port statique et redirige le trafic vers le port indiqué

Kubernetes : Service LoadBalancer

  • LoadBalancer : expose le Service en externe en utilisant le loadbalancer d'un cloud provider
    • AWS ELB/ALB/NLB
    • GCP LoadBalancer
    • Azure Balancer
    • OpenStack Octavia

Kubernetes : Service LoadBalancer

Kubernetes : Services

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

apiVersion: v1
kind: Service
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: /
        pathType: Prefix
        backend:
          service:
            name: frontend
            port:
              number: 80

Kubernetes : Ingress Controller

Pour utiliser un Ingress, il faut un Ingress Controller. Un Ingress permet de configurer une règle de reverse proxy sur l'Ingress Controller.

Kubernetes : Service Mesh

Problématique

  • Découpage des applications en micro services
  • Communication inter service (est-west) accrue

Problématique

  • Sans service mesh la logique de communication est codée dans chaque service
  • Problématiques de sécurité ? Comment implémenter TLS entre les micro services ?
  • Chaque micro service doit implémenter la logique métier ainsi les fonctions réseau, sécurité et fiabilité
  • Augmente la charge sur les équipes de développement
  • Disparité des langages de programmation : implémentation de la même logique N fois

Problématique

L'augmentation du nombre du nombre de micro services peut provoquer :

  • Une latence entre les services
  • Peu de visibilité sur la santé des services individuels
  • Peu de visibilité sur l'inter dépendance des services

Kubernetes : service minimum

  • L'objet Service supporte uniquement TCP/UDP ainsi que de la répartition de charge basique
  • L'objet Ingress utilise un point central de communication : l'ingress contrôleur
  • Pas d'objets natifs pour faire du routage applicatif poussé
  • Nécessité d'augmenter les fonctionnalités par un service tiers

Service Mesh

Les service mesh déportent la logique de communication au niveau de l'infrastructure et non plus au niveau de l'application. Les service mesh sont en général composés de deux plans:

  • Un plan de données : effectue la communication entre les micro services.
  • Un plan de contrôle : Programme le data plane et fourni des outils de configuration et de visualisation (CLI/Dashboard)

Service Mesh : Plan de données

  • Se basent sur un réseau de proxy
  • Ne modifient pas l'application
  • S'exécutent "à coté" : concept de sidecars
  • Ces sidecars s'exécutent dans les même pods que l'application mais dans un conteneur différent

Service Mesh : Plan de données

Service Mesh : Plan de contrôle

  • Pilote le plan de donnée
  • Permet la configuration de règles de routage applicatives
  • Cartographie la communication entre les micro services
  • Fourni des métriques applicatives :
    • Latences
    • Défaillances
    • Logique de retry (désengorgement du réseau)

Service Mesh : Avantages

  • Permettent aux développeurs de se focaliser sur l'application et non pas sur la communication des services
  • Couche commune de communication qui facilite le débogage et l'identification des problèmes
  • Évite automatiquement certaines défaillances grace à du routage intelligent

Service Mesh : Inconvénients

  • Ajoute une surcouche à Kubernetes qui est déjà complexe
  • Difficulté de migrer d'un service mesh à un autre
  • Augmentent la nombre de conteneurs et de ressources consommées sur un cluster
  • Paradoxalement les proxy rajoutent de la latence

Service Mesh : Les solutions

Aujourd'hui les solutions sont multiples et offrent toutes plus ou moins les même fonctionnalités :

  • Gestion du TLS mutuel et des certificats
  • Authentification et autorisation
  • Monitoring et traçage applicatif
  • Routage du trafic via des règles applicatives

Service Mesh : Les solutions

  • Istio : Plus connu et le plus complexe, open sourcé par Google
  • Linkerd : Hébergé dans la CNCF en incubation, open sourcé par Twitter
  • Consul : Développé par Hashicorp
  • Traefik Maesh : Développé par Traefik Lab

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 (Utilisation 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 indépendant du pod qui le consomme
  • Peut être provisionné manuellement par un administrateur ou dynamiquement grâce à une 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 de stocker séparément 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 : ConfigMap environnement (1/2)

apiVersion: v1
data:
  username: admin
  url: https://api.particule.io
kind: ConfigMap
metadata:
  name: web-config

Kubernetes : ConfigMap environnement (2/2)

apiVersion: v1
kind: Pod
metadata:
  name: configmap-env
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      command: [ "/bin/sh", "-c", "env" ]
      env:
        - name: USERNAME
          valueFrom:
            configMapKeyRef:
              name: web-config
              key: username
        - name: URL
          valueFrom:
            configMapKeyRef:
              name: web-config
              key: url
  restartPolicy: Never

Kubernetes : ConfigMap volume (1/2)

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

Kubernetes : ConfigMap volume (2/2)

apiVersion: v1
kind: Pod
metadata:
  name: configmap-volume
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      command: [ "/bin/sh", "-c", "head -v /etc/config/*" ]
      volumeMounts:
      - name: config-volume
        mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        name: redis-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 une registry Docker privée.
  • 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 generic monSuperSecret --from-literal=username='monUser' --from-literal=password='monSuperPassword"

Kubernetes : Secrets

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW4=
  password: MWYyZDFlMmU2N2Rm

Les valeurs doivent être encodées en base64.

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: scheduling

Affinité / Anti-affinité

2 types de règles :

  • Affinité de nodes
  • Affinité / Anti-affinité de pod

Affinité de nodes

  • Permets de scheduler des workloads sur un nœud en particulier
  • Paramétrable en fonction de labels

Affinité de nodes

pods/pod-with-node-affinity.yaml

apiVersion: v1
kind: Pod
metadata:
  name: with-node-affinity
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/e2e-az-name
            operator: In
            values:
            - e2e-az1
            - e2e-az2
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: another-node-label-key
            operator: In
            values:
            - another-node-label-value
  containers:
  - name: with-node-affinity
    image: k8s.gcr.io/pause:2.0

Affinité / Anti-affinité

  • Permet de scheduler des pods en fonction des labels
  • Sur un même nœud (collocation)
  • Sur des nœuds différents

Affinité / Anti-affinité

apiVersion: v1
kind: Pod
metadata:
  name: with-pod-affinity
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: security
            operator: In
            values:
            - S1
        topologyKey: failure-domain.beta.kubernetes.io/zone
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: security
              operator: In
              values:
              - S2
          topologyKey: failure-domain.beta.kubernetes.io/zone
  containers:
  - name: with-pod-affinity
    image: k8s.gcr.io/pause:2.0

Taints et Tolerations

  • Une taint permet l'inverse d'une affinité
  • Permet à un nœud de refuser des pods
  • Utilisé pour dédier des nœuds à un certain usage
kubectl taint nodes node1 key=value:NoSchedule

Taints and Tolerations

Aucun pod ne pourra être schedulé sur ce nœud à moins de tolérer la taint:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  tolerations:
  - key: "key"
    operator: "Exists"
    effect: "NoSchedule"

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 enregistré 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 : Helm

Qu'est-ce que Helm ?

  • Outil de packaging d'application Kubernetes
  • Developpé en Go
  • Actuellement en v3
  • Projet graduated de la CNCF

https://github.com/helm/helm

Pourquoi Helm ?

  • Applique le principe DRY (Don't Repeat Yourself)
    • Mécanisme de templating (Go templating)
    • Variabilisation des ressources générées
  • Facilité de versionnement et de partage (repository Helm)
  • Helm permet d'administrer les Releases
    • Rollbacks / upgrades d'applications

Concepts

Concept Description
Chart Ensemble de ressources permettant de definir une application Kubernetes
Config Valeurs permettant de configurer un Chart (values.yaml)
Release Chart deployé avec une Config

Comparaison avec des manifests YAML

  • Permet de mettre en place le DRY (Don't Repeat Yourself)
    • customisation via fichier de configuration YAML
  • Définition d'une seule source de vérité
    • Les ressources sont packagées
  • Packages déployés via des Releases

Structure d'un Chart

  • Chart.yaml pour définir le chart ainsi que ses metadatas
  • values.yaml sert à definir les valeurs de configuration du Chart par défaut
  • crds/: Dossier qui recense les CRDs
  • templates/: les templates de manifeste Kubernetes en YAML

Chart.yaml

Le fichier de configuration du Chart dans lequel sont définies ses metadatas.

---
apiVersion: v2
description: Hello World Chart.
name: hello-world-example
sources:
  - https://github.com/prometheus-community/helm-charts
version: 1.3.2
appVersion: 0.50.3
dependencies: []

Structure du values.yaml

  • Chaque attribut est ensuite disponible au niveau des templates
---
### Provide a name in place of kube-prometheus-stack for `app:` labels
##
applicationName: ""

### Override the deployment namespace
##
namespaceOverride: ""


### Apply labels to the resources
##
commonLabels: {}

Surcharge du values.yaml

---
# values-production.yaml
commonLabels:
  env: prod
tree
.
├── Chart.yaml
├── templates
│   ├── application.yaml
│   ├── configuration.yaml
│   └── secrets.yaml
├── values-production.yaml
├── values-staging.yaml
└── values.yaml

Templates

Helm permet de variabiliser les manifestes Kubernetes, permettant de créer et configurer des ressources dynamiquement. Le langage Go Template est utilisé.

apiVersion: apps/v1
kind: Pod
metadata:
  name: {{ .Chart.Name }}
  labels:
    app.kubernetes.io/managed-by: "Helm"
    chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
    release: {{ .Release.Name | quote }}
    version: 1.0.0
spec:
  containers:
  - image: "{{ .Values.helloworld.image.name }}:{{ .Values.helloworld.image.tag }}"
    name: helloworld

Gestion des repositories

  • Un Repository Helm permet de distribuer et versionner des Charts
  • Contient un index.yaml listant les Charts packagés disponibles par version
  • Deux méthodes de déploiement possibles
    • Via HTTP en tant que fichiers statiques
    • Via OCI en utilisant une Registry (depuis Helm v3)

Commandes communes

$ helm repo add stable https://charts.helm.sh/stable
"stable" has been added to your repositories
$ helm repo update
$ helm install stable/airflow --generate-name
helm install stable/airflow --generate-name
NAME: airflow-1616524477
NAMESPACE: defaul
...
$ helm upgrade airflow-1616524477 stable/airflow
helm upgrade airflow-1616524477 stable/airflow
Release "airflow-1616524477" has been upgraded. Happy Helming!
$ helm rollback airflow-1616524477
Rollback was a success! Happy Helming!
$ helm uninstall airflow-1616524477
release "airflow-1616524477" uninstalled

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 <NODE_NAME>
kubectl uncordon <NODE_NAME>

Kubernetes: où deployer et comment ?

Bare metal, private et public Clouds

azure aws gcp magnum

Managed - Kops - Kubespray - Kubeadm - Kube-aws - Symplegma

Cluster Deployment

Cluster Lifecycle

Infrastucture as code

IaC : Infrastructure as Code

Terraform - CloudFormation - Cloud Deployment Manager - OpenStack Heat - Azure Resource Manager

Infrastructure déclarée

Infrastructure immuable

Implémentation de référence

Que choisir ?

Je veux utiliser Kubernetes

Cloud ?

Cloud public ou privé ?

Configuration particulière ?

Multiple cloud providers ?

Homogénéité des outils ?

Local Kubernetes

Kubernetes managé

AWS EKS

  • Control plane managé par AWS
  • Amazon Linux / Ubuntu
  • CloudFormation / Terraform / eksctl

GKE

  • Control plane managé par GCP
  • Premier sur le marché
  • COS / Ubuntu
  • Terraform / Google Cloud SDK

AZURE AKS

  • Control plane managé par Azure

OPENSTACK MAGNUM

  • Control plane managé par OpenStack
  • Basé sur OpenStack Heat
  • Proposé sur certains public cloud basés sur OpenStack

Outils de déploiements agnostiques

kubeadm

  • Outil officiel de la communauté
  • Stable depuis v1.13.0
  • Ne provisionne pas de machine
  • Facilement personnalisabe
  • Respect des best practices
  • Peut être utilisé par d'autres outils

kubespray

  • Basé sur Ansible
  • Dense, permet d'installer un nombre important de plugins
  • Multiples OS
  • Support Kubeadm

symplegma

  • Basé sur Ansible
  • Inspiré de Kubespray en plus léger
  • CoreOS/Ubuntu
  • Full Kubeadm

Outils de déploiements spécifiques

kube-aws

  • Pure AWS CloudFormation Stack
  • Cycle de release lent
  • Facilement personnalisable
  • CoreOS ❤

kops

  • Déploie sur AWS/GCP/OpenStack et Digital Ocean
  • Cycle de release lent
  • Facilement personnalisable
  • Multiples OS
  • Supporte Cloudformation and Terraform

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
  • Ressources 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

  • Interceptent 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