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
- Documentation : kubernetes.io
- Helm Hub : artifacthub.io
- CNCF : cncf.io