Configurer des objets Kubernetes

Cet article explique comment créer des configurations, les fichiers qu'Anthos Config Management lit à partir de Git et applique automatiquement à vos clusters.

Avant de commencer

  • Veillez à bien comprendre la structure du dépôt. L'emplacement d'une configuration dans le dépôt a un impact sur les clusters et les objets Namespace auxquels elles est appliquée. Ceci est particulièrement important pour le répertoire namespaces/, car les sous-répertoires du répertoire namespaces/ peuvent hériter des configurations de leurs répertoires d'espace de noms abstraits.

  • Vous devez connaître les principes de base de la syntaxe YAML ou JSON, car les configurations doivent être écrites dans l'un de ces deux formats. Tous les exemples de cette documentation utilisent YAML, car ce langage est plus facile à lire pour les utilisateurs.

  • Chaque type d'objet Kubernetes est associé à des options configurables spécifiques. Il est utile de comprendre comment obtenir manuellement la configuration souhaitée avant d'écrire une configuration pour ce type d'objet.

  • Nous avons créé un exemple de dépôt canonique pour illustrer le fonctionnement d'Anthos Config Management. Les exemples de cet article proviennent de ce dépôt. Il peut donc être utile d'ouvrir ce dernier dans un navigateur ou de le cloner sur votre système local.

Créer une ressource Configuration

Lorsque vous créez une configuration, vous devez déterminer le meilleur emplacement dans le dépôt et les champs à inclure.

Emplacement dans le dépôt

L'emplacement d'une configuration dans le dépôt est un facteur qui détermine les clusters auxquels elle s'applique.

  • Les configurations pour les objets à l'échelle d'un cluster à l'exception des objets Namespace sont stockées dans le répertoire cluster/ du dépôt.
  • Les configurations pour les objets Namespace et à l'échelle de ces objets sont stockées dans le répertoire namespaces/ du dépôt.
  • Les configurations pour les composants d'Anthos Config Management sont stockées dans le répertoire system/ du dépôt.
  • La configuration de Config Management Operator n'est pas stockée directement dans le dépôt et n'est pas synchronisée.

Contenu de la configuration

Les configurations utilisent une approche additive, semblable à kubectl. Lors de la création d'objets, vous devez inclure tous les champs obligatoires. Toutefois, lors de la mise à jour d'objets existants, il vous suffit de fournir les champs que vous souhaitez mettre à jour.

Lors de son application, la configuration doit générer un objet Kubernetes valide.

Configurer les objets Kubernetes existants

Vous pouvez créer une configuration pour un objet Kubernetes existant, tel qu'un objet Namespace déjà présent dans votre cluster, avant d'installer Anthos Config Management. Cependant, cette configuration est ignorée, sauf si l'objet possède l'annotation configmanagement.gke.io/managed: enabled. Pour un objet existant, vous devez appliquer l'annotation manuellement.

Pour les objets Namespace, Anthos Config Management applique les configurations qui créent des objets dans un objet Namespace non annoté et applique l'annotation configmanagement.gke.io/managed: enabled à ces objets. Toutefois, Anthos Config Management refuse de modifier ou de supprimer tout objet à l'échelle d'un cluster non annoté. Ceci est illustré dans le schéma de la section Utiliser des configurations au fil du temps.

Configurer des objets CustomResourceDefinitions

Anthos Config Management vous permet de synchroniser des objets CustomResourceDefinitions (CRD) de la même manière que n'importe quelle autre ressource. Quelques points sont à garder à l'esprit lors de la synchronisation des objets CRD.

  • Les objets CRD, même lors de la déclaration d'une ressource personnalisée associée à un espace de noms, doivent être placés dans le répertoire cluster/.

  • Les mises à jour des objets CRD et de leurs ressources personnalisées correspondantes ne s'effectuent pas dans un ordre prévisible. Si vous modifiez des objets CRD et leurs ressources personnalisées correspondantes dans le même commit, les objets CRD ne seront pas nécessairement mis à jour avant les ressources personnalisées. Les journaux syncer peuvent alors signaler une erreur temporaire pendant une courte période, jusqu'à ce que les ressources personnalisées et les objets CRD soient présents dans le cluster.

  • Anthos Config Management n'autorise pas la suppression d'un objet CRD si une ressource personnalisée du dépôt en dépend. Pour supprimer un objet CRD, vous devez également supprimer sa ressource personnalisée. Il est recommandé de les supprimer dans le même commit pour le dépôt.

  • Vous pouvez synchroniser une ressource personnalisée sans synchroniser son objet CRD, à condition de garantir que ce dernier existe déjà dans le cluster.

Exemples de configurations

Les exemples de configurations ci-dessous proviennent tous de l'exemple de dépôt et doivent vous aider à écrire vos propres configurations. Cette liste n'est pas exhaustive. Vous pouvez configurer n'importe quel type d'objet Kubernetes avec Anthos Config Management.

Configuration de l'objet Namespace

La configuration ci-dessous crée un objet Namespace appelé audit.

apiVersion: v1
kind: Namespace
metadata:
  name: audit

Lorsque vous créez une configuration d'objet Namespace, vous pouvez également y ajouter des libellés ou des annotations. Les libellés sont obligatoires lorsque vous utilisez un objet NamespaceSelector.

L'exemple de configuration suivant crée un objet Namespace nommé shipping-prod s'il n'existe pas déjà ou s'il n'est pas géré. L'objet Namespace comporte le libellé env: prod et l'annotation audit: true. Si quelqu'un modifie manuellement les métadonnées de l'objet, Anthos Config Management le réinitialise rapidement sur la valeur de la configuration.

apiVersion: v1
kind: Namespace
metadata:
  name: shipping-prod
  labels:
    env: prod
  annotations:
    audit: "true"

Pour en savoir plus sur l'utilisation des espaces de noms, consultez la page Configurer des espaces de noms et des objets à l'échelle des espaces de noms.

Configuration de l'objet ClusterRole

Cette configuration crée un objet ClusterRole nommé namespace-reader, qui permet de lire (obtenir, surveiller et répertorier) tous les objets namespace du cluster. Une configuration d'objet ClusterRole est souvent utilisée avec une configuration d'objet ClusterRoleBinding.

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: namespace-reader
rules:
- apiGroups: [""]
  resources: ["namespaces"]
  verbs: ["get", "watch", "list"]

Configuration de l'objet ClusterRoleBinding

Cette configuration crée un objet ClusterRoleBinding nommé namespace-readers, qui accorde à l'utilisateur cheryl@foo-corp.com l'objet ClusterRole namespace-reader.

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: namespace-readers
subjects:
- kind: User
  name: cheryl@foo-corp.com
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: namespace-reader
  apiGroup: rbac.authorization.k8s.io

Les objets ClusterRoleBinding sont définis à l'échelle d'un cluster et ne peuvent pas être placés dans des répertoires d'espaces de noms ou des espaces de noms abstraits.

Configuration de l'objet PodSecurityPolicy

L'exemple ci-dessous crée un objet PodSecurityPolicy nommé psp, qui interdit l'exécution des conteneurs privilégiés, mais permet aux conteneurs de s'exécuter comme n'importe quel utilisateur valide du nœud.

apiVersion: extensions/v1beta1
kind: PodSecurityPolicy
metadata:
  name: psp
spec:
  privileged: false
  seLinux:
    rule: RunAsAny
  supplementalGroups:
    rule: RunAsAny
  runAsUser:
    rule: RunAsAny
  fsGroup:
    rule: RunAsAny
  volumes:
  - '*'

Les objets PodSecurityPolicy sont définis à l'échelle d'un cluster et ne peuvent pas être placés dans des répertoires d'espaces de noms ou des espaces de noms abstraits.

Configuration de l'objet NetworkPolicy

L'exemple ci-dessous crée un objet NetworkPolicy nommé default-deny-all-traffic.

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: default-deny-all-traffic
spec:
  podSelector: {}

Les objets NetworkPolicy sont définis à l'échelle d'un espace de noms et ne peuvent être placés que dans des répertoires d'espaces de noms ou des espaces de noms abstraits.

Lorsque vous appliquez l'objet NetworkPolicy ci-dessus à un seul espace de noms, il isole les pods de cet espace de noms du trafic entrant et sortant.

Lorsque vous appliquez le même objet NetworkPolicy à plusieurs espaces de noms en le plaçant dans un espace de noms abstrait avec des espaces de noms descendants, chacun de ces espaces de noms hérite de cet objet. Dans l'exemple de dépôt, shipping-app-backend est un espace de noms abstrait contenant les configurations associées à shipping-dev, shipping-prod et shipping-stage. Si vous ajoutez à ces dernières l'exemple d'objet NetworkPolicy ci-dessus, elles héritent toutes de cet objet de sorte que chacun de leurs pods soit protégé contre le trafic entrant et sortant.

Vous pouvez utiliser le processus d'héritage des espaces de noms pour appliquer une approche de la sécurité basée sur le principe du moindre privilège. Par exemple, si l'exemple NetworkPolicy précédent est appliqué à shipping-app-backend et si l'objet NetworkPolicy suivant est ajouté à l'objet Namespace shipping-dev, le trafic entrant n'est autorisé que vers les pods de cet espace de noms portant le libellé app:nginx. Les objets Namespace shipping-prod et shipping-staging ne sont pas concernés par cet objet NetworkPolicy.

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: allow-nginx-ingress
spec:
  podSelector:
    matchLabels:
      app: nginx
  ingress:
  - {}

Configuration de l'objet ResourceQuota

L'exemple ci-dessous crée un objet ResourceQuota nommé quota, qui définit une limite stricte de 1 pod, 100 millièmes de temps CPU et 100 mébioctets (Mio) de mémoire.

kind: ResourceQuota
apiVersion: v1
metadata:
  name: quota
spec:
  hard:
    pods: "1"
    cpu: "100m"
    memory: 100Mi

Si la création d'un objet d'un type donné a pour effet d'enfreindre la condition définie par un objet ResourceQuota existant, Kubernetes ne peut pas créer l'objet tant que la limite fixée par ResourceQuota n'est pas respectée.

Et ensuite ?