Gestion des Kubeconfigs
À la livraison de votre cluster Kubernetes, SdV fournit un fichier kubeconfig d'administration. Ce dernier dispose de toutes les permissions sur le cluster (droits cluster-admin) et présente un risque de sécurité majeur s'il est intégré directement dans vos pipelines CI/CD ou utilisé par vos applications.
SdV recommande vivement de générer des fichiers kubeconfig dédiés pour chacun de vos workloads, en appliquant le principe du moindre privilège pour sécuriser vos déploiements.
Validité des credentials
Le kubeconfig d'administration fourni par SdV dispose d'une validité limitée. Selon le type d'authentification configuré :
| Méthode d'authentification | Durée de validité typique | Rotation requise |
|---|---|---|
| Certificat client x509 | 365 jours | Manuelle |
| Token ServiceAccount | Illimitée (legacy) ou 1 an (TokenRequest API) | Automatique avec projected volumes |
| OIDC (Keycloak, etc.) | Selon le provider (ex: 24h) | Automatique |
Pour plus de détails sur la gestion des permissions au sein de votre cluster Kubernetes, référez-vous au guide dédié à la gestion des droits RBAC.
Anatomie d'un fichier kubeconfig
Un fichier kubeconfig est un fichier YAML structuré contenant trois sections principales :
apiVersion: v1
kind: Config
preferences: {}
# 1. Clusters : endpoints API server
clusters:
- name: sdv-cluster-prod
cluster:
server: https://api.k8s.example.com:6443
certificate-authority-data: LS0tLS1CRUdJTi... # CA du cluster
# 2. Users : credentials d'authentification
users:
- name: gitlab-deployer
user:
token: eyJhbGciOiJSUzI1NiIsImtpZCI6... # Token ServiceAccount
# OU
client-certificate-data: LS0tLS1CRUdJTi...
client-key-data: LS0tLS1CRUdJTi...
# 3. Contexts : association cluster + user + namespace
contexts:
- name: sdv-prod-deployer
context:
cluster: sdv-cluster-prod
user: gitlab-deployer
namespace: production # namespace par défaut
# Contexte actif par défaut
current-context: sdv-prod-deployerGénérer un kubeconfig pour un workload
La génération d'un kubeconfig dédié repose sur la création d'un ServiceAccount associé à un Role ou ClusterRole via un RoleBinding ou ClusterRoleBinding.
Créer un Namespace dédié
Isolez vos applications dans des Namespaces dédiés pour faciliter la gestion RBAC et la segmentation des ressources :
kubectl create namespace productionCréer un ServiceAccount
Le ServiceAccount représente l'identité technique de votre workload (pipeline CI/CD, application, opérateur...) :
apiVersion: v1
kind: ServiceAccount
metadata:
name: gitlab-deployer
namespace: production
labels:
app.kubernetes.io/name: gitlab-deployer
app.kubernetes.io/managed-by: kubectlkubectl apply -f serviceaccount.yamlDéfinir les permissions RBAC
Créez un Role (namespacé) ou ClusterRole (cluster-wide) avec uniquement les permissions nécessaires au workload.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: deployer
namespace: production
rules:
# Gestion des Deployments, StatefulSets, DaemonSets
- apiGroups: ["apps"]
resources: ["deployments", "statefulsets", "daemonsets"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
# Gestion des ReplicaSets (créés par les Deployments)
- apiGroups: ["apps"]
resources: ["replicasets"]
verbs: ["get", "list", "watch"]
# Gestion des Pods (lecture seule pour debug)
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list", "watch"]
# Gestion des Services
- apiGroups: [""]
resources: ["services"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
# Gestion des ConfigMaps et Secrets
- apiGroups: [""]
resources: ["configmaps", "secrets"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
# Gestion des Ingress
- apiGroups: ["networking.k8s.io"]
resources: ["ingresses"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: monitoring-reader
rules:
- apiGroups: [""]
resources: ["pods", "services", "endpoints", "nodes"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
resources: ["deployments", "statefulsets", "daemonsets"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["pods/log"]
verbs: ["get", "list"]kubectl apply -f role-deployer.yaml
# ou pour le ClusterRole
kubectl apply -f clusterrole-readonly.yamlLier le ServiceAccount au Role
Utilisez un RoleBinding (pour un Role namespacé) ou ClusterRoleBinding (pour un ClusterRole) :
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: gitlab-deployer-binding
namespace: production
subjects:
- kind: ServiceAccount
name: gitlab-deployer
namespace: production
roleRef:
kind: Role
name: deployer
apiGroup: rbac.authorization.k8s.ioapiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: monitoring-reader-binding
subjects:
- kind: ServiceAccount
name: prometheus
namespace: monitoring
roleRef:
kind: ClusterRole
name: monitoring-reader
apiGroup: rbac.authorization.k8s.iokubectl apply -f rolebinding.yamlRécupérer le token du ServiceAccount
Depuis Kubernetes 1.24, les tokens de ServiceAccount ne sont plus automatiquement créés. Deux méthodes sont disponibles :
Secret manuellement (token longue durée)apiVersion: v1
kind: Secret
metadata:
name: gitlab-deployer-token
namespace: production
annotations:
kubernetes.io/service-account.name: gitlab-deployer
type: kubernetes.io/service-account-tokenkubectl apply -f serviceaccount-token.yaml
# Récupérer le token
TOKEN=$(kubectl get secret gitlab-deployer-token -n production -o jsonpath='{.data.token}' | base64 -d)
echo $TOKEN# Token avec expiration (par défaut 1h, max 24h selon la config du cluster)
TOKEN=$(kubectl create token gitlab-deployer -n production --duration=8760h)
echo $TOKENRécupérer les informations du cluster
# URL de l'API Server
API_SERVER=$(kubectl config view --raw -o jsonpath='{.clusters[0].cluster.server}')
# Certificat de l'autorité de certification du cluster
CA_CERT=$(kubectl config view --raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}')
echo "API Server: $API_SERVER"Générer le fichier kubeconfig
Créez le fichier kubeconfig complet en combinant les informations récupérées :
cat > kubeconfig-gitlab-deployer.yaml <<EOF
apiVersion: v1
kind: Config
preferences: {}
clusters:
- name: sdv-cluster
cluster:
server: ${API_SERVER}
certificate-authority-data: ${CA_CERT}
users:
- name: gitlab-deployer
user:
token: ${TOKEN}
contexts:
- name: gitlab-deployer-context
context:
cluster: sdv-cluster
user: gitlab-deployer
namespace: production
current-context: gitlab-deployer-context
EOFValider le kubeconfig généré
Testez le nouveau kubeconfig pour vérifier qu'il fonctionne correctement :
# Vérifier la connexion au cluster
kubectl --kubeconfig=kubeconfig-gitlab-deployer.yaml cluster-info
# Tester les permissions
kubectl --kubeconfig=kubeconfig-gitlab-deployer.yaml auth can-i get pods -n production
# Expected: yes
kubectl --kubeconfig=kubeconfig-gitlab-deployer.yaml auth can-i delete nodes
# Expected: no
# Lister les ressources autorisées
kubectl --kubeconfig=kubeconfig-gitlab-deployer.yaml get deployments -n productionCommandes kubectl utiles
# Lister les contextes disponibles
kubectl config get-contexts
# Changer de contexte actif
kubectl config use-context sdv-prod-deployer
# Afficher la configuration actuelle
kubectl config view
# Afficher la configuration avec les secrets (ATTENTION : données sensibles)
kubectl config view --raw
# Définir un namespace par défaut pour un contexte
kubectl config set-context --current --namespace=production
# Créer un nouveau contexte
kubectl config set-context dev-context \
--cluster=sdv-cluster \
--user=dev-user \
--namespace=development
# Supprimer un contexte
kubectl config delete-context old-context
# Fusionner plusieurs kubeconfigs
KUBECONFIG=~/.kube/config:~/kubeconfig-prod.yaml kubectl config view --flatten > ~/.kube/config-mergedBonnes pratiques de sécurité
Stockage des kubeconfigs
Permissions minimales
Appliquez le principe du moindre privilège :
| Use Case | Ressources | Verbs recommandés |
|---|---|---|
| Pipeline de déploiement | deployments, services, configmaps, ingresses | get, list, create, update, patch |
| Monitoring (Prometheus) | nodes, pods, services, endpoints | get, list, watch |
| Backup (Velero) | Toutes ressources | get, list, watch, create (pour restore) |
| Debug ponctuel | pods, pods/log | get, list |
Rotation des credentials
Automatisez la rotation des tokens :
generate_token:
stage: setup
script:
# Générer un token avec durée limitée
- TOKEN=$(kubectl create token gitlab-deployer -n production --duration=168h)
- echo "KUBE_TOKEN=$TOKEN" >> deploy.env
artifacts:
reports:
dotenv: deploy.env
deploy:
stage: deploy
script:
# Utiliser le token fraîchement généré
- kubectl --token=$KUBE_TOKEN apply -f manifests/Audit et traçabilité
Activez l'audit des API calls dans le cluster pour tracer les actions effectuées par chaque ServiceAccount :
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
# Log toutes les modifications (create, update, patch, delete)
- level: RequestResponse
verbs: ["create", "update", "patch", "delete"]
# Log les accès en lecture aux secrets
- level: Metadata
resources:
- group: ""
resources: ["secrets"]
verbs: ["get", "list", "watch"]Namespaces dédiés
Isolez les ServiceAccounts par Namespace selon l'environnement ou l'application :
production/
├── gitlab-deployer (droits d'écriture)
└── prometheus (lecture seule)
staging/
├── gitlab-deployer (droits d'écriture)
└── prometheus (lecture seule)
monitoring/
└── prometheus (lecture cluster-wide)Intégration CI/CD
GitLab CI/CD
Stockez le kubeconfig en tant que File Variable :
deploy:
stage: deploy
image: bitnami/kubectl:latest
script:
# La variable KUBECONFIG_FILE est injectée comme fichier
- export KUBECONFIG=$KUBECONFIG_FILE
- kubectl apply -f k8s/
- kubectl rollout status deployment/app -n production
only:
- mainGitHub Actions
name: Deploy to Kubernetes
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup kubectl
uses: azure/setup-kubectl@v3
- name: Deploy
env:
KUBECONFIG_CONTENT: ${{ secrets.KUBECONFIG }}
run: |
echo "$KUBECONFIG_CONTENT" > /tmp/kubeconfig
export KUBECONFIG=/tmp/kubeconfig
kubectl apply -f k8s/
kubectl rollout status deployment/app -n productionJenkins
pipeline {
agent any
environment {
KUBECONFIG = credentials('kubeconfig-prod')
}
stages {
stage('Deploy') {
steps {
sh 'kubectl apply -f k8s/'
sh 'kubectl rollout status deployment/app -n production'
}
}
}
}Dépannage
Erreur "The connection to the server was refused"
Vérifiez l'URL de l'API Server :
kubectl config view -o jsonpath='{.clusters[0].cluster.server}'
# Testez la connectivité
curl -k https://api.k8s.example.com:6443/versionErreur "x509: certificate signed by unknown authority"
Le certificat CA du cluster est manquant ou invalide :
# Vérifier la présence du CA
kubectl config view --raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}' | base64 -d | openssl x509 -noout -text
# Alternative : désactiver la vérification TLS (NON RECOMMANDÉ en production)
kubectl --insecure-skip-tls-verify=true get nodesErreur "User 'system:serviceaccount:...' cannot get resource"
Le ServiceAccount ne dispose pas des permissions RBAC nécessaires :
# Vérifier les permissions actuelles
kubectl auth can-i get pods --as=system:serviceaccount:production:gitlab-deployer -n production
# Lister toutes les permissions
kubectl auth can-i --list --as=system:serviceaccount:production:gitlab-deployer -n production
# Vérifier les RoleBindings
kubectl get rolebinding -n production
kubectl describe rolebinding gitlab-deployer-binding -n productionToken expiré
Si vous utilisez un token temporaire (méthode 2), régénérez-le :
# Vérifier l'expiration du token (décode le JWT)
echo $TOKEN | cut -d'.' -f2 | base64 -d 2>/dev/null | jq .exp
# Régénérer un nouveau token
kubectl create token gitlab-deployer -n production --duration=168hAlternatives et outils complémentaires
kubelogin (OIDC)
Pour les clusters configurés avec un provider OIDC (Keycloak, Azure AD, Okta) :
kubectl oidc-login setup \
--oidc-issuer-url=https://keycloak.example.com/auth/realms/kubernetes \
--oidc-client-id=kubernetes \
--oidc-client-secret=xxxLe kubeconfig utilisera alors l'authentification OIDC avec refresh automatique des tokens.
Référez-vous au guide dédié à l'OIDC dans Kubernetes pour paramétrer votre cluster.
kubie
Outil pour gérer facilement plusieurs contextes kubeconfig :
# Installation
brew install kubie
# Lancer un shell avec un contexte isolé
kubie ctx sdv-prod-deployer
# Dans ce shell, toutes les commandes kubectl utilisent le bon contexte
kubectl get podsk9s
Interface TUI (Text User Interface) pour naviguer dans Kubernetes :
# Installation
brew install k9s
# Lancer avec un kubeconfig spécifique
k9s --kubeconfig=/path/to/kubeconfig.yamlChecklist finale
Avant de déployer un kubeconfig en production :
-
ServiceAccountcréé dans le namespace approprié -
Role/ClusterRoleavec permissions minimales strictes -
RoleBinding/ClusterRoleBindingconfigurés correctement - Token généré avec durée de validité adaptée
- Kubeconfig testé avec
kubectl auth can-i - Kubeconfig stocké de manière sécurisée (secret manager)
- Jamais committé dans Git
- Process de rotation documenté
- Permissions auditées et validées par l'équipe sécurité
-
Namespacepar défaut configuré si nécessaire
Documentation complémentaire
- Guide RBAC : gestion avancée des permissions
- Documentation Kubernetes officielle sur les
ServiceAccounts - Documentation kubectl config