Comment accéder à l’API de votre cluster Kubernetes depuis vos pods
L’API Kubernetes vous permet d’inspecter et de gérer les opérations de votre cluster. Vous pouvez utiliser l’API à l’aide de la CLI Kubectl, des outils tels que curl
ou les bibliothèques d’intégration officielles pour les langages de programmation populaires.
L’API est également disponible pour les applications de votre cluster. Les pods Kubernetes ont automatiquement accès à l’API et peuvent s’authentifier à l’aide d’un compte de service fourni. Vous effectuez des interactions en consommant les variables d’environnement et les fichiers de certificat injectés pour établir des connexions à partir du client de votre choix.
Sommaire
Pourquoi accéder à l’API Kubernetes dans les pods ?
Il existe plusieurs cas d’utilisation pour l’accès à l’API in-Pod. Cette technique permet aux applications d’inspecter dynamiquement leur environnement, d’appliquer les modifications Kubernetes et de collecter des métriques de plan de contrôle qui fournissent des informations sur les performances.
Certaines organisations développent leurs propres outils autour de Kubernetes. Ils peuvent déployer une application spéciale dans le cluster qui utilise l’API pour exposer des fonctionnalités supplémentaires. Opérer à partir du cluster peut être plus sûr que d’effectuer des appels d’API à partir d’un script externe, car vous n’avez pas besoin d’ouvrir votre environnement ou de partager des comptes de service et des jetons d’authentification.
Utilisation des bibliothèques clientes d’API
La méthode la plus simple et recommandée pour accéder à l’API Kubernetes à partir d’un pod consiste à utiliser une bibliothèque cliente. Des options entièrement prises en charge sont disponibles pour C, .NET, Go, Haskell, Java, JavaScript, Perl, Python et Ruby. Il existe des solutions équivalentes gérées par la communauté pour la plupart des autres langages de programmation populaires.
Les bibliothèques clientes ont une prise en charge intégrée pour découvrir l’environnement de cluster dans lequel elles s’exécutent. Chaque implémentation fournit une fonction que vous pouvez appeler et qui configurera la bibliothèque pour se connecter au serveur d’API approprié.
Voici un exemple de liste des pods de votre cluster dans une application Python :
from kubernetes import client, config config.load_incluster_config() api = client.CoreV1Api() # Perform necessary API interactions # pods = api.list_pod_for_all_namespaces()
Cette approche est facile à utiliser et ne nécessite aucune configuration manuelle. Parfois, vous ne pourrez pas utiliser une bibliothèque cliente. Dans ces cas, il est toujours possible d’accéder manuellement à l’API à l’aide du compte de service fourni par Kubernetes.
Exécution d’interactions API manuelles
Pour appeler l’API, vous devez connaître deux choses : le nom d’hôte du cluster sur lequel il est exposé et le jeton de compte de service qui authentifiera votre pod.
Le nom d’hôte de l’API est toujours kubernetes.default.svc
. Le fournisseur DNS Kubernetes résoudra ce nom sur le serveur d’API du plan de contrôle. Alternativement, vous pouvez utiliser le $KUBERNETES_SERVICE_HOST
variable d’environnement pour découvrir l’adresse IP du serveur d’API :
$ echo $KUBERNETES_SERVICE_HOST 10.96.0.1
L’API est uniquement disponible via HTTPS. Vous pouvez trouver le fichier d’autorité de certification pour votre cluster sur /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
dans votre Pod. Kubernetes le dépose dans le système de fichiers chaque fois qu’un nouveau conteneur est créé.
Vous devrez vous authentifier pour obtenir quoi que ce soit d’utile avec l’API. Kubernetes crée un nouveau compte de service pour chaque pod et fournit son jeton à /var/run/secrets/kubernetes.io/serviceaccount/token
. Cela devrait être inclus avec chaque requête HTTP en tant que jeton de support dans le Authorization
entête.
En rassemblant tout, voici un exemple de création d’une requête d’API Kubernetes dans le pod de base à l’aide de curl
:
$ curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://kubernetes.default.svc/api { "kind": "APIVersions", "versions": [ "v1" ], "serverAddressByClientCIDRs": [ { "clientCIDR": "0.0.0.0/0", "serverAddress": "192.168.49.2:8443" } ]
Le serveur Kubernetes a répondu avec les versions d’API disponibles. Cela confirme qu’une connexion réussie a été établie à l’aide du kubernetes.default.svc
nom d’hôte et le compte de service fourni.
Gestion du RBAC
Bien qu’une demande d’API ait été effectuée avec succès, la plupart des autres seront hors limites si RBAC est activé pour votre cluster. Les comptes de service nouvellement créés ne reçoivent pas automatiquement les rôles. Votre pod ne pourra donc pas demander de points de terminaison d’API protégés.
Vous pouvez résoudre ce problème en créant vos propres objets Rôle et en les liant au compte de service fourni à vos pods. Créez d’abord un nouveau rôle :
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: default name: demo-role rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "list"]
Appliquez-le à votre cluster avec Kubectl :
$ kubectl apply -f role.yaml
Associez ensuite le rôle au compte de service :
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: namespace: default name: demo-role-binding subjects: - kind: ServiceAccount name: default apiGroup: "" roleRef: kind: Role name: demo-role apiGroup: ""
La default
le compte de service est sélectionné comme sujet de la liaison de rôle. Les pods sont toujours fournis avec ce compte de service, limité à l’espace de noms dans lequel ils ont été créés. Dans cet exemple, le default
namespace est utilisé, mais cela doit être modifié sur les objets Role et RoleBinding si votre pod existe dans un espace de noms différent.
Ajoutez le RoleBinding à votre cluster :
$ kubectl apply -f role-binding.yaml
Désormais, vos pods seront autorisés à obtenir et à répertorier d’autres objets pod dans le default
espace de noms. Vous pouvez le vérifier en envoyant une requête API au point de terminaison des pods avec espace de noms :
$ curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://kubernetes.default.svc/api/v1/namespaces/default/pods { "kind": "PodList", "apiVersion": "v1" ... }
Les pods peuvent identifier leur propre espace de noms en lisant le /var/run/secrets/kubernetes.io/serviceaccount/namespace
dossier:
$ cat /var/run/secrets/kubernetes.io/serviceaccount/namespace default
Cela fournit une méthode pratique pour interpoler l’espace de noms actif dans les URL de point de terminaison :
$ curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" https://kubernetes.default.svc/api/v1/namespaces/$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)/pods { "kind": "PodList", "apiVersion": "v1" ... }
Choisir un autre compte de service
Kubernetes fournit automatiquement aux pods les default
compte de service dans leur espace de noms. Vous pouvez éventuellement injecter un compte de service différent à la place en définissant le spec.serviceAccountName
sur vos pods :
apiVersion: v1 kind: Pod metadata: name: demo spec: serviceAccountName: demo-sa
Dans cet exemple, le pod s’authentifiera en tant que demo-sa
jeton. Vous pouvez créer ce compte de service manuellement et lui lier les rôles dont vous avez besoin.
$ kubernetes create serviceaccount demo-sa
Le compte de service doit exister dans le même espace de noms que le pod.
Désactiver le montage du compte de service
L’injection automatique de compte de service n’est pas toujours souhaitable. Cela peut constituer un risque pour la sécurité, car une compromission réussie du pod offre un accès immédiat à l’API de votre cluster Kubernetes. Vous pouvez désactiver les montages de jetons de compte de service avec le spec.automountServiceAccountToken
Champ de manifeste du pod :
apiVersion: v1 kind: Pod metadata: name: demo spec: automountServiceAccountToken: false
Kubernetes n’injectera pas le /var/run/secrets/kubernetes.io/serviceaccount/token
dossier. Cela empêchera le pod de s’authentifier auprès de l’API Kubernetes, sauf si vous fournissez manuellement les informations d’identification à l’aide d’une méthode différente. Ce champ est également pris en charge sur les objets de compte de service, ce qui les rend inéligibles pour être montés automatiquement dans n’importe quel pod.
Si vous utilisez le montage de compte de service, définissez les stratégies RBAC appropriées pour restreindre le jeton aux cas d’utilisation prévus. Éviter les accès hautement privilégiés réduira le risque de dommages si un attaquant accède à votre Pod.
Sommaire
L’accès au serveur d’API Kubernetes depuis votre cluster permet aux applications en cours d’exécution d’inspecter et de modifier les charges de travail voisines. Vous pouvez ajouter des fonctionnalités supplémentaires sans ouvrir votre cluster à un accès API externe.
Les bibliothèques clientes officielles facilitent la mise en place et l’exécution, si elles conviennent à votre cas d’utilisation. Dans d’autres situations, vous devrez faire manuellement des demandes à https://kubernetes.default.svc
, fournissant le fichier d’autorité de certification et le jeton de compte de service que Kubernetes injecte dans vos conteneurs Pod. Quelle que soit l’approche que vous utilisez, le compte de service doit être correctement configuré avec les liaisons de rôle RBAC afin que le pod soit autorisé à effectuer les actions prévues.