Aller au contenu principal

ConfigMaps et Secrets


1 - Introduction

La gestion de la configuration est essentielle pour déployer des applications de manière flexible. Kubernetes propose deux ressources principales :

RessourceUsageEncodage
ConfigMapConfiguration généralePlain text
SecretDonnées sensiblesBase64

2 - ConfigMaps

2.1 Créer un ConfigMap

Méthode impérative :

# Depuis des valeurs littérales
kubectl create configmap app-config \
--from-literal=DATABASE_HOST=mysql \
--from-literal=DATABASE_PORT=3306

# Depuis un fichier
kubectl create configmap nginx-config --from-file=nginx.conf

# Depuis un répertoire
kubectl create configmap app-configs --from-file=config/

Méthode déclarative :

# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
# Valeurs simples
DATABASE_HOST: mysql
DATABASE_PORT: "3306"
LOG_LEVEL: info

# Fichier de configuration complet
app.properties: |
server.port=8080
server.context-path=/api
logging.level.root=INFO

# Fichier JSON
config.json: |
{
"features": {
"darkMode": true,
"beta": false
}
}
kubectl apply -f configmap.yaml
kubectl get configmap app-config -o yaml

2.2 Utiliser un ConfigMap comme variables d'environnement

apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: mon-app:v1

# Toutes les clés comme variables
envFrom:
- configMapRef:
name: app-config

# Clés spécifiques
env:
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: app-config
key: DATABASE_HOST

2.3 Utiliser un ConfigMap comme volume

apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: nginx
volumeMounts:
- name: config-volume
mountPath: /etc/nginx/conf.d
readOnly: true

volumes:
- name: config-volume
configMap:
name: nginx-config
# Optionnel: sélectionner des clés spécifiques
items:
- key: nginx.conf
path: default.conf

2.4 ConfigMap avec fichiers multiples

apiVersion: v1
kind: ConfigMap
metadata:
name: multi-config
data:
database.properties: |
host=mysql
port=3306
cache.properties: |
host=redis
port=6379
---
apiVersion: v1
kind: Pod
metadata:
name: app
spec:
containers:
- name: app
image: mon-app
volumeMounts:
- name: config
mountPath: /etc/app/config
volumes:
- name: config
configMap:
name: multi-config
# Résultat:
# /etc/app/config/database.properties
# /etc/app/config/cache.properties

3 - Secrets

3.1 Types de Secrets

TypeUsage
OpaqueDonnées arbitraires (par défaut)
kubernetes.io/tlsCertificats TLS
kubernetes.io/dockerconfigjsonCredentials registry
kubernetes.io/basic-authUsername/password
kubernetes.io/ssh-authClés SSH

3.2 Créer un Secret

Méthode impérative :

# Depuis des valeurs littérales
kubectl create secret generic db-secret \
--from-literal=username=admin \
--from-literal=password=supersecret123

# Depuis des fichiers
kubectl create secret generic tls-secret \
--from-file=tls.crt=./cert.crt \
--from-file=tls.key=./cert.key

# Secret TLS
kubectl create secret tls app-tls \
--cert=./tls.crt \
--key=./tls.key

# Secret Docker registry
kubectl create secret docker-registry regcred \
--docker-server=registry.example.com \
--docker-username=user \
--docker-password=password \
[email protected]

Méthode déclarative :

# secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
# Les données doivent être encodées en base64
data:
username: YWRtaW4= # echo -n "admin" | base64
password: c3VwZXJzZWNyZXQ= # echo -n "supersecret" | base64

---
# Alternative avec stringData (auto-encodé)
apiVersion: v1
kind: Secret
metadata:
name: db-secret-v2
type: Opaque
stringData:
username: admin
password: supersecret
# Encoder en base64
echo -n "monsecret" | base64
# bW9uc2VjcmV0

# Décoder
echo "bW9uc2VjcmV0" | base64 -d
# monsecret

3.3 Utiliser un Secret comme variables d'environnement

apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: mon-app

# Toutes les clés
envFrom:
- secretRef:
name: db-secret

# Clés spécifiques
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: password

3.4 Utiliser un Secret comme volume

apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: mon-app
volumeMounts:
- name: secret-volume
mountPath: /etc/secrets
readOnly: true

volumes:
- name: secret-volume
secret:
secretName: db-secret
# Permissions des fichiers (optionnel)
defaultMode: 0400

3.5 Secret pour Pull d'images privées

apiVersion: v1
kind: Pod
metadata:
name: private-app
spec:
containers:
- name: app
image: registry.example.com/mon-app:v1
imagePullSecrets:
- name: regcred

4 - Bonnes pratiques de sécurité

4.1 Limiter l'accès aux Secrets

# RBAC pour limiter l'accès
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: secret-reader
namespace: production
rules:
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["db-secret"] # Secrets spécifiques uniquement
verbs: ["get"]

4.2 Chiffrement au repos (Encryption at Rest)

# Configurer le chiffrement etcd
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- aescbc:
keys:
- name: key1
secret: <base64-encoded-key>
- identity: {}

4.3 Solutions externes recommandées


5 - External Secrets Operator

5.1 Installation

helm repo add external-secrets https://charts.external-secrets.io
helm install external-secrets external-secrets/external-secrets \
-n external-secrets --create-namespace

5.2 Configuration avec AWS Secrets Manager

# SecretStore
apiVersion: external-secrets.io/v1beta1
kind: SecretStore
metadata:
name: aws-secrets
spec:
provider:
aws:
service: SecretsManager
region: eu-west-1
auth:
secretRef:
accessKeyIDSecretRef:
name: aws-credentials
key: access-key
secretAccessKeySecretRef:
name: aws-credentials
key: secret-key
---
# ExternalSecret
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: db-credentials
spec:
refreshInterval: 1h
secretStoreRef:
name: aws-secrets
kind: SecretStore
target:
name: db-secret
creationPolicy: Owner
data:
- secretKey: username
remoteRef:
key: prod/database
property: username
- secretKey: password
remoteRef:
key: prod/database
property: password

6 - Mise à jour dynamique

6.1 ConfigMap et redémarrage automatique

Les Pods ne redémarrent pas automatiquement quand un ConfigMap change. Solutions :

# Utiliser une annotation avec le hash du ConfigMap
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
template:
metadata:
annotations:
# Mettre à jour cette annotation force un redéploiement
configmap-hash: "abc123"
spec:
containers:
- name: app
image: mon-app
envFrom:
- configMapRef:
name: app-config

6.2 Reloader (outil tiers)

# Installer Reloader
kubectl apply -f https://raw.githubusercontent.com/stakater/Reloader/master/deployments/kubernetes/reloader.yaml
# Annoter le Deployment pour auto-reload
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
annotations:
reloader.stakater.com/auto: "true"
spec:
# ...

6.3 Volumes ConfigMap (mise à jour automatique)

Les fichiers montés depuis un ConfigMap sont mis à jour automatiquement (délai ~1 minute).

apiVersion: v1
kind: Pod
spec:
containers:
- name: app
volumeMounts:
- name: config
mountPath: /etc/config
volumes:
- name: config
configMap:
name: app-config
# Les fichiers sont mis à jour automatiquement

7 - Immutable ConfigMaps et Secrets

apiVersion: v1
kind: ConfigMap
metadata:
name: immutable-config
data:
key: value
immutable: true # Ne peut plus être modifié

---
apiVersion: v1
kind: Secret
metadata:
name: immutable-secret
data:
password: c2VjcmV0
immutable: true

Avantages :

  • Protection contre les modifications accidentelles
  • Performance améliorée (pas de watch)

8 - Exemple complet

# Application complète avec ConfigMap et Secret
---
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_ENV: production
LOG_LEVEL: info
config.yaml: |
server:
port: 8080
timeout: 30s
features:
cache: enabled

---
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
type: Opaque
stringData:
DATABASE_URL: "postgres://user:pass@db:5432/app"
API_KEY: "sk-1234567890abcdef"

---
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
replicas: 3
selector:
matchLabels:
app: mon-app
template:
metadata:
labels:
app: mon-app
spec:
containers:
- name: app
image: mon-app:v1
ports:
- containerPort: 8080

# Variables d'environnement depuis ConfigMap
envFrom:
- configMapRef:
name: app-config

# Variables depuis Secret
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: app-secrets
key: DATABASE_URL
- name: API_KEY
valueFrom:
secretKeyRef:
name: app-secrets
key: API_KEY

# Fichier de config monté
volumeMounts:
- name: config-file
mountPath: /etc/app/config.yaml
subPath: config.yaml
readOnly: true

volumes:
- name: config-file
configMap:
name: app-config

Résumé

Dans ce chapitre, nous avons appris :

  • Créer et utiliser des ConfigMaps pour la configuration
  • Gérer les données sensibles avec des Secrets
  • Les différentes façons d'injecter la configuration (env, volumes)
  • Les bonnes pratiques de sécurité
  • L'utilisation d'External Secrets Operator
  • La mise à jour dynamique de la configuration

Prochaine étape

Dans le prochain chapitre, nous explorerons les Volumes et le Stockage persistant.

→ Chapitre suivant : Volumes et Stockage


← Retour à la table des matières