Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

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'authentificationDurée de validité typiqueRotation requise
Certificat client x509365 joursManuelle
Token ServiceAccountIllimité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 :

kubeconfig-example.yaml
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-deployer

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

Terminal
kubectl create namespace production

Créer un ServiceAccount

Le ServiceAccount représente l'identité technique de votre workload (pipeline CI/CD, application, opérateur...) :

serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: gitlab-deployer
  namespace: production
  labels:
    app.kubernetes.io/name: gitlab-deployer
    app.kubernetes.io/managed-by: kubectl
Terminal
kubectl apply -f serviceaccount.yaml

Définir les permissions RBAC

Créez un Role (namespacé) ou ClusterRole (cluster-wide) avec uniquement les permissions nécessaires au workload.

Exemple 1 : Permissions de déploiement dans un namespace
role-deployer.yaml
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"]
Exemple 2 : Permissions lecture seule sur plusieurs namespaces
clusterrole-readonly.yaml
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"]
Terminal
kubectl apply -f role-deployer.yaml
# ou pour le ClusterRole
kubectl apply -f clusterrole-readonly.yaml

Lier le ServiceAccount au Role

Utilisez un RoleBinding (pour un Role namespacé) ou ClusterRoleBinding (pour un ClusterRole) :

Binding namespacé :
rolebinding.yaml
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.io
Binding cluster-wide :
clusterrolebinding.yaml
apiVersion: 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.io
Terminal
kubectl apply -f rolebinding.yaml

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

Méthode 1 : Créer un Secret manuellement (token longue durée)
serviceaccount-token.yaml
apiVersion: v1
kind: Secret
metadata:
  name: gitlab-deployer-token
  namespace: production
  annotations:
    kubernetes.io/service-account.name: gitlab-deployer
type: kubernetes.io/service-account-token
Terminal
kubectl 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
Méthode 2 : Générer un token temporaire (recommandé)
Terminal
# 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 $TOKEN

Récupérer les informations du cluster

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

Terminal
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
EOF

Valider le kubeconfig généré

Testez le nouveau kubeconfig pour vérifier qu'il fonctionne correctement :

Terminal
# 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 production

Commandes kubectl utiles

Terminal
# 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-merged

Bonnes pratiques de sécurité

Stockage des kubeconfigs

Permissions minimales

Appliquez le principe du moindre privilège :

Use CaseRessourcesVerbs recommandés
Pipeline de déploiementdeployments, services, configmaps, ingressesget, list, create, update, patch
Monitoring (Prometheus)nodes, pods, services, endpointsget, list, watch
Backup (Velero)Toutes ressourcesget, list, watch, create (pour restore)
Debug ponctuelpods, pods/logget, list

Rotation des credentials

Automatisez la rotation des tokens :

gitlab-ci.yml
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 :

audit-policy.yaml
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 :

.gitlab-ci.yml
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:
    - main

GitHub Actions

deploy.yml
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 production

Jenkins

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

Terminal
kubectl config view -o jsonpath='{.clusters[0].cluster.server}'
# Testez la connectivité
curl -k https://api.k8s.example.com:6443/version

Erreur "x509: certificate signed by unknown authority"

Le certificat CA du cluster est manquant ou invalide :

Terminal
# 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 nodes

Erreur "User 'system:serviceaccount:...' cannot get resource"

Le ServiceAccount ne dispose pas des permissions RBAC nécessaires :

Terminal
# 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 production

Token expiré

Si vous utilisez un token temporaire (méthode 2), régénérez-le :

Terminal
# 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=168h

Alternatives et outils complémentaires

kubelogin (OIDC)

Pour les clusters configurés avec un provider OIDC (Keycloak, Azure AD, Okta) :

Terminal
kubectl oidc-login setup \
  --oidc-issuer-url=https://keycloak.example.com/auth/realms/kubernetes \
  --oidc-client-id=kubernetes \
  --oidc-client-secret=xxx

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

Terminal
# 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 pods

k9s

Interface TUI (Text User Interface) pour naviguer dans Kubernetes :

Terminal
# Installation
brew install k9s
 
# Lancer avec un kubeconfig spécifique
k9s --kubeconfig=/path/to/kubeconfig.yaml

Checklist finale

Avant de déployer un kubeconfig en production :

  • ServiceAccount créé dans le namespace approprié
  • Role/ClusterRole avec permissions minimales strictes
  • RoleBinding/ClusterRoleBinding configuré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é
  • Namespace par défaut configuré si nécessaire

Documentation complémentaire