Créer des clusters d'utilisateur dans une configuration multicluster

Dans Anthos clusters on Bare Metal, les clusters utilisateur exécutent vos charges de travail. Dans une architecture multicluster, les clusters d'utilisateur sont créés et gérés par un cluster d'administrateur.

Une fois que vous avez créé un cluster d'administrateur, l'appel de la commande bmctl create config crée un fichier yaml que vous pouvez modifier pour définir votre cluster d'utilisateur. Vous pouvez ensuite utiliser la commande kubectl pour appliquer cette configuration et créer le cluster d'utilisateur.

Le fait de conserver des charges de travail hors du cluster d'administrateur protège les données d'administration sensibles, telles que les clés SSH stockées dans le cluster d'administrateur, de celles qui ne doivent pas accéder à ces informations. En outre, séparer les clusters d'utilisateur les uns des autres assure une sécurité générale satisfaisante à vos charges de travail.

Prérequis

  • bmctl téléchargé à partir de gs://anthos-baremetal-release/bmctl/1.6.2/linux-amd64/bmctl
  • Cluster d'administrateur opérationnel ayant accès au serveur d'API du cluster (controlPlaneVIP)
  • Les nœuds du cluster d'administrateur doivent disposer d'une connectivité réseau à tous les nœuds du cluster d'utilisateur cible
  • Clé SSH utilisée pour créer un cluster d'utilisateur offrant un accès racine ou SUDO, sur tous les nœuds du cluster d'utilisateur

Créer un fichier de configuration de cluster d'utilisateur

Le fichier de configuration permettant de créer un cluster d'utilisateur est presque identique à celui utilisé pour créer un cluster d'administrateur. La seule différence est que vous supprimez la section de configuration des identifiants locaux pour faire de cette configuration une collection valide de ressources Kubernetes. La section de configuration se trouve en haut du fichier, dans la section bmctl configuration variables.

Par défaut, les clusters d'utilisateur héritent leurs identifiants du cluster d'administrateur qui les gère. Vous pouvez remplacer chacun ou la totalité de ces identifiants. Pour en savoir plus, consultez l'exemple de configuration de cluster d'utilisateur.

Dans les étapes ci-dessous, vérifiez bien les modifications apportées au fichier de configuration. Comme vous créez le cluster d'utilisateur à l'aide de la commande kubectl, la configuration du cluster d'utilisateur comporte des vérifications préliminaires limitées.

  1. Créez un fichier de configuration de cluster d'utilisateur à l'aide de la commande bmctl create config :

    bmctl create config -c USER_CLUSTER_NAME
    

    Par exemple, exécutez la commande suivante pour créer un fichier de configuration pour un cluster d'utilisateur appelé user1 :

    bmctl create config -c user1
    

    Le fichier est écrit dans bmctl-workspace/user1/user1.yaml. Le chemin d'accès générique au fichier est bmctl-workspace/CLUSTER NAME/CLUSTER_NAME.yaml

  2. Modifiez le fichier de configuration en apportant les modifications suivantes :

    • Supprimez de la configuration les chemins d'accès des identifiants locaux. Ils ne sont pas nécessaires pour un cluster d'utilisateur et ne fonctionnent pas avec la commande kubectl. Supprimez les éléments suivants :
      ....
        gcrKeyPath: {path to GCR service account key}
        sshPrivateKeyPath: (path to SSH private key, used for node access)
        gkeConnectAgentServiceAccountKeyPath: (path to Connect agent service account key)
        gkeConnectRegisterServiceAccountKeyPath: (path to Hub registration service account key)
        cloudOperationsServiceAccountKeyPath: (path to Cloud Operations service account key)
      ....
            
    • Modifiez la configuration pour spécifier le type de cluster user au lieu de admin :
      ....
      spec:
        # Cluster type. This can be:
        #   1) admin:  to create an admin cluster. This can later be used to create
        #   user clusters.
        #   2) user:   to create a user cluster. Requires an existing admin cluster.
        #   3) hybrid: to create a hybrid cluster that runs admin cluster
        #   components and user workloads.
        #   4) standalone: to create a cluster that manages itself, runs user
        #   workloads, but does not manage other clusters.
        type: user
      ....
      
    • Assurez-vous que les spécifications des clusters d'administrateur et d'utilisateur concernant les adresses IP virtuelles d'équilibrage de charge et les pools d'adresses sont complémentaires et qu'elles ne recoupent pas celles des clusters existants. Vous trouverez ci-dessous un exemple de configuration de cluster d'administrateur et de cluster d'utilisateur spécifiant l'équilibrage de charge et les pools d'adresses :
    • ....
      # Sample admin cluster config for load balancer and address pools
        loadBalancer:
          vips:
            controlPlaneVIP: 10.200.0.49
            ingressVIP: 10.200.0.50
          addressPools:
          - name: pool1
            addresses:
            - 10.200.0.50-10.200.0.70
      ....
      ....
      # Sample user cluster config for load balancer and address pools
      loadBalancer:
          vips:
            controlPlaneVIP: 10.200.0.71
            ingressVIP: 10.200.0.72
          addressPools:
          - name: pool1
            addresses:
            - 10.200.0.72-10.200.0.90
      ....
      

      Notez que le reste des fichiers de configuration du cluster d'utilisateur est identique à celui du cluster d'administrateur.

  3. Vérifiez bien le fichier de configuration de votre cluster d'utilisateur. Anthos clusters on bare metal n'offre qu'un nombre limité de vérifications préliminaires lorsque vous créez un cluster d'utilisateur. Celles-ci ne couvrent que les vérifications au niveau des machines (telles que la version du système d'exploitation, les conflits entre versions logicielles et les ressources disponibles).

Créer le cluster d'utilisateur

Exécutez la commande kubectl pour appliquer la configuration du cluster d'utilisateur et créer le cluster :

kubectl --kubeconfig ADMIN_KUBECONFIG apply -f USER_CLUSTER_CONFIG

ADMIN_KUBECONFIG spécifie le chemin d'accès au fichier kubeconfig du cluster d'administrateur, et USER_CLUSTER_CONFIG spécifie le chemin d'accès au fichier YAML du cluster d'utilisateur que vous avez modifié dans la section précédente.

Par exemple, pour un cluster d'administrateur nommé admin et une configuration de cluster d'utilisateur nommée user1, la commande serait la suivante:

kubectl --kubeconfig bmctl-workspace/admin/admin-kubeconfig apply /
  -f bmctl-workspace/user1/user1.yaml

Attendre la fin de la préparation du cluster d'utilisateur

Pour vérifier que le cluster d'utilisateur est prêt, utilisez la commande kubectl wait pour tester une condition. La commande suivante attend 30 minutes pour vérifier que le cluster a terminé le rapprochement et récupère le fichier kubeconfig du cluster d'utilisateur créé :

kubectl --kubeconfig ADMIN_KUBECONFIG wait \
  cluster USER_CLUSTER_NAME -n cluster-USER_CLUSTER_NAME \
  --for=condition=Reconciling=False --timeout=30m && \
  kubectl --kubeconfig ADMIN_KUBECONFIG get secret USER_CLUSTER_NAME-kubeconfig \
  -n cluster-USER_CLUSTER_NAME \
  -o 'jsonpath={.data.value}' | base64 -d > USER_KUBECONFIG

Où :

  • ADMIN_KUBECONFIG spécifie le chemin d'accès au fichier kubeconfig du cluster d'administrateur.
  • USER_KUBECONFIG spécifie le chemin d'accès au fichier kubeconfig de l'utilisateur que vous souhaitez créer.
  • USER_CLUSTER_NAME est le nom de votre cluster d'utilisateur.

Par exemple, pour un cluster d'administrateur nommé admin et une configuration de cluster d'utilisateur nommée user1, la commande est la suivante :

kubectl --kubeconfig bmctl-workspace/admin/admin-kubeconfig wait  \
  cluster user1 -n cluster-user1 --for=condition=Reconciling=False --timeout=30m &&  \
  kubectl --kubeconfig bmctl-workspace/admin/admin-kubeconfig get secret  \
  user1-kubeconfig -n cluster-user1 -o 'jsonpath={.data.value}' | base64  \
  -d > bmctl-workspace/user1/user1-kubeconfig

Attendre la fin de la préparation des pools de nœuds de calcul

La plupart du temps, vous devez également attendre que les pools de nœuds de calcul soient prêts. En règle générale, les pools de nœuds de calcul permettent à vos clusters d'utilisateur d'exécuter des charges de travail.

Pour vérifier que les pools de nœuds de calcul sont prêts, utilisez la commande kubectl wait pour tester une condition. Dans ce cas, la commande attend à nouveau pendant 30 minutes que les pools de nœuds soient prêts :

kubectl --kubeconfig ADMIN_KUBECONFIG wait cluster USER_CLUSTER_NAME \
  -n cluster-USER_CLUSTER_NAME --for=condition=Reconciling=False --timeout=30m && \
  kubectl --kubeconfig ADMIN_KUBECONFIG wait nodepool NODE_POOL_NAME \
  -n cluster-USER_CLUSTER_NAME --for=condition=Reconciling=False --timeout=30m && \
  kubectl --kubeconfig ADMIN_KUBECONFIG get secret \
  USER_CLUSTER_NAME-kubeconfig -n cluster-USER_CLUSTER_NAME -o \
  'jsonpath={.data.value}' | base64 -d >  USER_KUBECONFIG
  

NODE_POOL_NAME spécifie un pool de nœuds que vous créez avec le cluster d'utilisateur.

Par exemple, pour un cluster d'administrateur nommé admin, une configuration de cluster d'utilisateur nommée user1 et un pool de nœuds nommé node-pool-1, la commande est la suivante :

kubectl --kubeconfig bmctl-workspace/admin/admin-kubeconfig wait \
  cluster user1 -n cluster-user1 --for=condition=Reconciling=False --timeout=30m && \
  kubectl --kubeconfig bmctl-workspace/admin/admin-kubeconfig wait \
  nodepool node-pool-1 -n cluster-user1 --for=condition=Reconciling=False --timeout=30m && \
  kubectl --kubeconfig bmctl-workspace/admin/admin-kubeconfig get secret \
  user1-kubeconfig -n cluster-user1 -o \
  'jsonpath={.data.value}' | base64 -d > bmctl-workspace/user1/user1-kubeconfig

Exemple de configuration complète d'un cluster d'utilisateur

Voici un exemple de fichier de configuration de cluster d'administrateur créé par la commande bmctl. Notez que dans cet exemple de configuration, des noms de clusters, des adresses et des adresses IP virtuelles intégrant des espaces réservés sont utilisés. Il est possible qu'ils ne fonctionnent pas sur votre réseau.

# Sample user cluster config:

apiVersion: v1
kind: Namespace
metadata:
  name: cluster-user1
---
apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
  name: user1
  namespace: cluster-user1
spec:
  # Cluster type. This can be:
  #   1) admin:  to create an admin cluster. This can later be used to create user clusters.
  #   2) user:   to create a user cluster. Requires an existing admin cluster.
  #   3) hybrid: to create a hybrid cluster that runs admin cluster components and user workloads.
  #   4) standalone: to create a cluster that manages itself, runs user workloads,
  #   but does not manage other clusters.
  type: user
  # Anthos cluster version.
  anthosBareMetalVersion: 1.6.2
  # GKE connect configuration
  gkeConnect:
    projectID: GOOGLE_PROJECT_ID
    # To override default credentials inherited from the admin cluster:
    # 1. Create a new secret in the admin cluster
    # 2. Uncomment the section below and refer to the secret created above
    # # Optionally override default secret inherited from the admin cluster.
    # connectServiceAccountSecret:
    #  name: GKE_CONNECT_AGENT_SA_SECRET
    #  namespace: cluster-user1
    # # Optionally override default secret inherited from the admin cluster.
    # registerServiceAccountSecret:
    #  name: GKE_CONNECT_REGISTER_SA_SECRET
    #  namespace: cluster-user1
  # Control plane configuration
  controlPlane:
    nodePoolSpec:
      nodes:
      # Control plane node pools. Typically, this is either a single machine
      # or 3 machines if using a high availability deployment.
      - address: 10.200.0.4
  # Cluster networking configuration
  clusterNetwork:
    # Pods specify the IP ranges from which Pod networks are allocated.
    pods:
      cidrBlocks:
      - 192.168.0.0/16
    # Services specify the network ranges from which service VIPs are allocated.
    # This can be any RFC 1918 range that does not conflict with any other IP range
    # in the cluster and node pool resources.
    services:
      cidrBlocks:
      - 10.96.0.0/12
  # Credentials specify the secrets that hold SSH key and image pull credential for the new cluster.
  # credentials:
  #  # Optionally override default ssh key secret inherited from the admin cluster.
  #  sshKeySecret:
  #    name: SSH_KEY_SECRET
  #    namespace: cluster-user1
  #  # Optionally override default image pull secret inherited from the admin cluster.
  #  imagePullSecret:
  #    name: IMAGE_PULL_SECRET
  #    namespace: cluster-user1
  # Load balancer configuration
  loadBalancer:
    # Load balancer mode can be either 'bundled' or 'manual'.
    # In 'bundled' mode a load balancer will be installed on load balancer nodes during cluster creation.
    # In 'manual' mode the cluster relies on a manually-configured external load balancer.
    mode: bundled
    # Load balancer port configuration
    ports:
      # Specifies the port the LB serves the kubernetes control plane on.
      # In 'manual' mode the external load balancer must be listening on this port.
      controlPlaneLBPort: 443
    # There are two load balancer VIPs: one for the control plane and one for the L7 Ingress
    # service. The VIPs must be in the same subnet as the load balancer nodes.
    vips:
      # ControlPlaneVIP specifies the VIP to connect to the Kubernetes API server.
      # This address must not be in the address pools below.
      controlPlaneVIP: 10.200.0.71
      # IngressVIP specifies the VIP shared by all services for ingress traffic.
      # Allowed only in non-admin clusters.
      # This address must be in the address pools below.
      ingressVIP: 10.200.0.72
    # AddressPools is a list of non-overlapping IP ranges for the data plane load balancer.
    # All addresses must be in the same subnet as the load balancer nodes.
    # Address pool configuration is only valid for 'bundled' LB mode in non-admin clusters.
    addressPools:
    - name: pool1
      addresses:
      # Each address must be either in the CIDR form (1.2.3.0/24)
      # or range form (1.2.3.1-1.2.3.5).
      - 10.200.0.72-10.200.0.90
    # A load balancer nodepool can be configured to specify nodes used for load balancing.
    # These nodes are part of the kubernetes cluster and run regular workloads as well as load balancers.
    # If the node pool config is absent then the control plane nodes are used.
    # Node pool configuration is only valid for 'bundled' LB mode.
    # nodePoolSpec:
    #  nodes:
    #  - address: 
  # Proxy configuration
  # proxy:
  #   url: http://[username:password@]domain
  #   # A list of IPs, hostnames or domains that should not be proxied.
  #   noProxy:
  #   - 127.0.0.1
  #   - localhost
  # Logging and Monitoring
  clusterOperations:
    # Cloud project for logs and metrics.
    projectID: $GOOGLE_PROJECT_ID
    # Cloud location for logs and metrics.
    location: us-central1
    # Optionally override default secret inherited from the admin cluster.
    # serviceAccountSecret:
    #  name: $CLOUD_OPERATIONS_SA_SECRET
    #  namespace: cluster-user1
    # Whether collection of application logs/metrics should be enabled (in addition to
    # collection of system logs/metrics which correspond to system components such as
    # Kubernetes control plane or cluster management agents).
    # enableApplication: false
  # Storage configuration
  storage:
    # lvpNodeMounts specifies the config for local PersistentVolumes backed by mounted disks.
    # These disks need to be formatted and mounted by the user, which can be done before or after
    # cluster creation.
    lvpNodeMounts:
      # path specifies the host machine path where mounted disks will be discovered and a local PV
      # will be created for each mount.
      path: /mnt/localpv-disk
      # storageClassName specifies the StorageClass that PVs will be created with. The StorageClass
      # is created during cluster creation.
      storageClassName: local-disks
    # lvpShare specifies the config for local PersistentVolumes backed by subdirectories in a shared filesystem.
    # These subdirectories are automatically created during cluster creation.
    lvpShare:
      # path specifies the host machine path where subdirectories will be created on each host. A local PV
      # will be created for each subdirectory.
      path: /mnt/localpv-share
      # storageClassName specifies the StorageClass that PVs will be created with. The StorageClass
      # is created during cluster creation.
      storageClassName: local-shared
      # numPVUnderSharedPath specifies the number of subdirectories to create under path.
      numPVUnderSharedPath: 5
  # Authentication; uncomment this section if you wish to enable authentication to the cluster with OpenID Connect.
  # authentication:
  #   oidc:
  #     # issuerURL specifies the URL of your OpenID provider, such as "https://accounts.google.com". The Kubernetes API
  #     # server uses this URL to discover public keys for verifying tokens. Must use HTTPS.
  #     issuerURL: 
  #     # clientID specifies the ID for the client application that makes authentication requests to the OpenID
  #     # provider.
  #     clientID: 
  #     # clientSecret specifies the secret for the client application.
  #     clientSecret: 
  #     # kubectlRedirectURL specifies the redirect URL (required) for the gcloud CLI, such as
  #     # "http://localhost:[PORT]/callback".
  #     kubectlRedirectURL: <Redirect URL for the gcloud CLI; optional, default is "http://kubectl.redirect.invalid">
  #     # username specifies the JWT claim to use as the username. The default is "sub", which is expected to be a
  #     # unique identifier of the end user.
  #     username: <JWT claim to use as the username; optional, default is "sub">
  #     # usernamePrefix specifies the prefix prepended to username claims to prevent clashes with existing names.
  #     usernamePrefix: 

  #     # group specifies the JWT claim that the provider will use to return your security groups.
  #     group: 
  #     # groupPrefix specifies the prefix prepended to group claims to prevent clashes with existing names.
  #     groupPrefix: 

  #     # scopes specifies additional scopes to send to the OpenID provider as a comma-delimited list.
  #     scopes: 
  #     # extraParams specifies additional key-value parameters to send to the OpenID provider as a comma-delimited
  #     # list.
  #     extraParams: 
  #     # certificateAuthorityData specifies a Base64 PEM-encoded certificate authority certificate of your identity
  #     # provider. It's not needed if your identity provider's certificate was issued by a well-known public CA.
  #     certificateAuthorityData: 
  # Node access configuration; uncomment this section if you wish to use a non-root user
  # with passwordless sudo capability for machine login.
  # nodeAccess:
  #   loginUser: 
---
# Node pools for worker nodes
apiVersion: baremetal.cluster.gke.io/v1
kind: NodePool
metadata:
  name: node-pool-1
  namespace: cluster-user1
spec:
  clusterName: user1
  nodes:
  - address: 10.200.0.5