Skip to content

Kubernetes

Vue d'ensemble

Kubernetes (K8s) est une plateforme d'orchestration de conteneurs open-source qui automatise le déploiement, la mise à l'échelle et la gestion des applications conteneurisées. Développé par Google, il est devenu le standard de facto pour l'orchestration de conteneurs.

Philosophie

"Container orchestration at scale - Gérez des applications conteneurisées avec automation, scalabilité et résilience."

Avantages clés

Orchestration avancée

  • Auto-scaling : Horizontal et vertical
  • Rolling updates : Déploiements sans interruption
  • Self-healing : Redémarrage automatique des pods défaillants
  • Load balancing : Distribution automatique du trafic

Écosystème riche

  • Helm : Gestionnaire de packages
  • Operators : Logique métier personnalisée
  • Service mesh : Istio, Linkerd pour communications
  • Monitoring/Logging : Intégrations nombreuses

Multi-cloud et portable

  • Cloud agnostic : AWS EKS, Azure AKS, GCP GKE
  • On-premise : Bare metal, VMware
  • Edge computing : K3s, MicroK8s
  • Hybrid : Multi-cluster management

Architecture

Control Plane

  • API Server : Point d'entrée API REST
  • etcd : Base de données distribuée
  • Scheduler : Placement des pods
  • Controller Manager : Boucles de contrôle

Worker Nodes

  • kubelet : Agent sur chaque noeud
  • kube-proxy : Proxy réseau
  • Container Runtime : Docker, containerd, CRI-O

Resources principales

# Pod - Unité de déploiement de base
apiVersion: v1
kind: Pod
metadata:
  name: webapp
spec:
  containers:
  - name: app
    image: nginx:1.21
    ports:
    - containerPort: 80

# Deployment - Gestion des réplicas
apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapp-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: webapp
  template:
    metadata:
      labels:
        app: webapp
    spec:
      containers:
      - name: webapp
        image: nginx:1.21
        ports:
        - containerPort: 80

# Service - Exposition réseau
apiVersion: v1
kind: Service
metadata:
  name: webapp-service
spec:
  selector:
    app: webapp
  ports:
  - port: 80
    targetPort: 80
  type: LoadBalancer

Patterns de déploiement

Application Laravel

apiVersion: apps/v1
kind: Deployment
metadata:
  name: laravel-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: laravel
  template:
    metadata:
      labels:
        app: laravel
    spec:
      containers:
      - name: laravel
        image: laravel-app:latest
        ports:
        - containerPort: 8000
        env:
        - name: DB_HOST
          value: "mysql-service"
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secret
              key: password
        volumeMounts:
        - name: storage
          mountPath: /app/storage
      volumes:
      - name: storage
        persistentVolumeClaim:
          claimName: laravel-storage
---
apiVersion: v1
kind: Service
metadata:
  name: laravel-service
spec:
  selector:
    app: laravel
  ports:
  - port: 80
    targetPort: 8000
  type: ClusterIP

Application React

apiVersion: apps/v1
kind: Deployment
metadata:
  name: react-frontend
spec:
  replicas: 2
  selector:
    matchLabels:
      app: react-app
  template:
    metadata:
      labels:
        app: react-app
    spec:
      containers:
      - name: react
        image: nginx:alpine
        ports:
        - containerPort: 80
        volumeMounts:
        - name: react-build
          mountPath: /usr/share/nginx/html
        - name: nginx-config
          mountPath: /etc/nginx/conf.d
      volumes:
      - name: react-build
        configMap:
          name: react-build-files
      - name: nginx-config
        configMap:
          name: nginx-config

Intégrations

Avec Terraform

# Cluster EKS sur AWS
resource "aws_eks_cluster" "main" {
  name     = "main-cluster"
  role_arn = aws_iam_role.cluster.arn
  version  = "1.28"

  vpc_config {
    subnet_ids = aws_subnet.private[*].id
  }

  depends_on = [
    aws_iam_role_policy_attachment.cluster-AmazonEKSClusterPolicy,
  ]
}

# Node group
resource "aws_eks_node_group" "main" {
  cluster_name    = aws_eks_cluster.main.name
  node_group_name = "main-nodes"
  node_role_arn   = aws_iam_role.node.arn
  subnet_ids      = aws_subnet.private[*].id

  scaling_config {
    desired_size = 3
    max_size     = 10
    min_size     = 1
  }

  instance_types = ["t3.medium"]
}

Avec Ansible

# Déploiement via Ansible
- name: Deploy application to Kubernetes
  kubernetes.core.k8s:
    name: "{{ app_name }}"
    api_version: apps/v1
    kind: Deployment
    namespace: "{{ namespace }}"
    definition:
      spec:
        replicas: "{{ replicas }}"
        selector:
          matchLabels:
            app: "{{ app_name }}"
        template:
          metadata:
            labels:
              app: "{{ app_name }}"
          spec:
            containers:
            - name: "{{ app_name }}"
              image: "{{ image }}:{{ version }}"
              ports:
              - containerPort: "{{ port }}"

Avec GitLab CI

# .gitlab-ci.yml
deploy:
  stage: deploy
  image: bitnami/kubectl:latest
  script:
    - kubectl config use-context $KUBE_CONTEXT
    - kubectl set image deployment/webapp webapp=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
    - kubectl rollout status deployment/webapp
  only:
    - main

Monitoring avec Prometheus et Grafana

Prometheus configuration

apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-config
data:
  prometheus.yml: |
    global:
      scrape_interval: 15s
    scrape_configs:
    - job_name: 'kubernetes-pods'
      kubernetes_sd_configs:
      - role: pod
      relabel_configs:
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
        action: keep
        regex: true

Grafana dashboard

apiVersion: apps/v1
kind: Deployment
metadata:
  name: grafana
spec:
  replicas: 1
  selector:
    matchLabels:
      app: grafana
  template:
    metadata:
      labels:
        app: grafana
    spec:
      containers:
      - name: grafana
        image: grafana/grafana:latest
        ports:
        - containerPort: 3000
        env:
        - name: GF_SECURITY_ADMIN_PASSWORD
          valueFrom:
            secretKeyRef:
              name: grafana-secret
              key: admin-password

Gestion des secrets avec Vault

External Secrets Operator

apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
  name: vault-backend
spec:
  provider:
    vault:
      server: "https://vault.example.com:8200"
      path: "secret"
      version: "v2"
      auth:
        kubernetes:
          mountPath: "kubernetes"
          role: "external-secrets"

---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: laravel-secrets
spec:
  refreshInterval: 15s
  secretStoreRef:
    name: vault-backend
    kind: SecretStore
  target:
    name: laravel-secret
    creationPolicy: Owner
  data:
  - secretKey: database-password
    remoteRef:
      key: laravel/database
      property: password

Helm Charts

Structure chart Laravel

laravel-chart/
├── Chart.yaml
├── values.yaml
├── templates/
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   └── configmap.yaml
└── charts/

values.yaml

# values.yaml
image:
  repository: laravel-app
  tag: latest
  pullPolicy: IfNotPresent

replicaCount: 3

service:
  type: ClusterIP
  port: 80

ingress:
  enabled: true
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt-prod
  hosts:
    - host: app.example.com
      paths:
        - path: /
          pathType: Prefix

resources:
  limits:
    cpu: 500m
    memory: 512Mi
  requests:
    cpu: 250m
    memory: 256Mi

autoscaling:
  enabled: true
  minReplicas: 2
  maxReplicas: 10
  targetCPUUtilizationPercentage: 70

Comparaison avec Nomad

Aspect Kubernetes Nomad
Complexité ⭐⭐⭐⭐⭐ ⭐⭐
Écosystème ⭐⭐⭐⭐⭐ ⭐⭐⭐
Courbe apprentissage ⭐⭐⭐⭐⭐ ⭐⭐
Multi-workload ⭐⭐ ⭐⭐⭐⭐⭐
Performance ⭐⭐⭐ ⭐⭐⭐⭐⭐
Opérabilité ⭐⭐ ⭐⭐⭐⭐

Cas d'usage typiques

Idéal pour

  • Microservices complexes : Applications cloud-native
  • Grandes équipes : Ecosystème riche
  • Multi-cloud : Abstraction infrastructure
  • Applications stateful : Operators et StatefulSets

Challenges

  • Complexité : Courbe d'apprentissage élevée
  • Overhead : Consommation ressources
  • Sécurité : Configuration complexe
  • Maintenance : Mises à jour fréquentes

Ressources