
C'est vrai, après la sortie de Hashicorp Consul 1.5.0 au début de mai 2019 dans Consul, vous pouvez autoriser les applications et les services s'exécutant dans Kubernetes en mode natif.
Dans ce tutoriel, nous allons créer pas à pas un POC (Proof of concept, PoC - proof of concept] - démontrant cette nouvelle fonctionnalité. Une connaissance de base de Kubernetes et du Consul d'Hashicorp est attendue de vous. Et bien que vous vous pouvez utiliser n'importe quelle plateforme cloud ou environnement local, dans ce guide, nous utiliserons la plateforme cloud de Google.
Revue
Si nous nous tournons vers la documentation du Consul sur sa méthode d'autorisation , nous obtiendrons un bref aperçu de son objet et de son cas d'utilisation, ainsi que quelques détails techniques et un aperçu général de la logique. Je recommande fortement de le lire au moins une fois avant de continuer, car je vais l'expliquer et le mâcher maintenant.

Figure 1: Aperçu de la méthode d'autorisation du consul officiel
Jetons un coup d'œil à la documentation de la méthode d'autorisation Kubernetes spécifique .
Bien sûr, il y a des informations utiles, mais il n'y a pas de guide sur la façon d'utiliser réellement tout cela. Par conséquent, comme toute personne sensée, vous parcourez Internet pour vous guider. Et puis ... être vaincu. Ça arrive. Corrigeons-le.
Avant de passer à la création de notre POC, revenons à l'aperçu des méthodes d'autorisation du consul (figure 1) et affinons-le dans le contexte de Kubernetes.
L'architecture
Dans ce guide, nous allons créer un serveur Consul sur une machine distincte qui interagira avec le cluster Kubernetes avec le client Consul installé. Ensuite, nous allons créer notre application factice dans l'âtre et utiliser notre méthode d'autorisation personnalisée pour lire à partir de notre référentiel de clés / valeurs Consul.
Le schéma ci-dessous montre en détail l'architecture que nous créons dans ce guide, ainsi que la logique de la méthode d'autorisation, qui sera expliquée plus loin.

Figure 2: Présentation de la méthode d'autorisation dans Kubernetes
Une note rapide: le serveur consul n'a pas besoin de vivre en dehors du cluster Kubernetes pour que cela fonctionne. Mais oui, il peut faire ceci et cela.
Donc, en prenant le diagramme de vue d'ensemble du consul (schéma 1) et en lui appliquant Kubernetes, nous obtenons le diagramme ci-dessus (schéma 2), et ici la logique sera la suivante:
- Chaque pod aura un compte de service attaché contenant un jeton JWT généré et connu par Kubernetes. Ce jeton est également inséré dans le sous par défaut.
- Notre application ou service à l'intérieur du foyer lance une commande pour entrer dans notre client Consul. La demande de connexion indiquera également notre token et le nom d'une méthode d'autorisation spécialement créée (telle que Kubernetes). Cette étape n ° 2 correspond à l'étape 1 du dispositif Consul (schéma 1).
- Notre client Consul transmettra ensuite cette demande Ă notre serveur Consul.
- MAGIQUE! C'est ici que le serveur Consul vérifie l'authenticité de la demande, recueille des informations sur l'identité de la demande et la compare avec les règles prédéfinies associées. Voici un autre diagramme pour illustrer cela. Cette étape correspond aux étapes 3, 4 et 5 du schéma de synthèse Consul (Schéma 1).
- Notre serveur Consul génère un jeton Consul avec des autorisations conformément aux règles de la méthode d'autorisation que nous avons spécifiée (que nous avons déterminée) concernant l'identité du demandeur. Ensuite, il renverra ce jeton. Cela correspond à l'étape 6 du programme Consul (schéma 1).
- Notre client Consul redirige le jeton vers l'application ou le service demandeur.
Notre application ou service peut désormais utiliser ce jeton Consul pour communiquer avec nos données Consul, comme déterminé par les privilèges du jeton.
La magie est révélée!
Pour ceux d'entre vous qui ne sont pas satisfaits du lapin dans le chapeau et qui veulent savoir comment cela fonctionne ... permettez-moi de "vous montrer la profondeur du trou du lapin ".
Comme mentionné précédemment, notre étape «magique» (Schéma 2: Étape 4) est que le serveur Consul vérifie l'authenticité de la demande, recueille des informations sur la demande et la compare avec toutes les règles prédéfinies associées. Cette étape correspond aux étapes 3, 4 et 5 du schéma de synthèse Consul (Schéma 1). Vous trouverez ci-dessous un diagramme (schéma 3), dont le but est de montrer clairement ce qui se passe réellement sous le capot d'une méthode d'autorisation Kubernetes spécifique.

Schéma 3: La magie est révélée!
- Comme point de départ, notre client Consul redirige la demande de connexion vers notre serveur Consul avec le jeton de compte Kubernetes et le nom spécifique de l'instance de la méthode d'autorisation qui a été créée précédemment. Cette étape correspond à l'étape 3 de l'explication précédente du circuit.
- Le serveur Consul (ou leader) doit maintenant vérifier l'authenticité du jeton reçu. Par conséquent, il consultera le cluster Kubernetes (via le client Consul) et, avec les autorisations appropriées, nous verrons si le jeton est authentique et à qui il appartient.
- Ensuite, la demande vérifiée revient au responsable Consul et le serveur Consul recherche une instance de la méthode d'autorisation avec le nom spécifié dans la demande de connexion (et tapez Kubernetes).
- Le chef de consul détermine l'instance spécifiée de la méthode d'autorisation (s'il en existe une) et lit l'ensemble des règles contraignantes qui lui sont attachées. Il lit ensuite ces règles et les compare avec des attributs d'identité vérifiés.
- Tada! Passez à l'étape 5 de l'explication précédente du circuit.
Exécutez Consul-server sur une machine virtuelle standard
Désormais, je donnerai principalement des instructions pour créer ce POC, souvent en points, sans phrases entières explicatives. En outre, comme indiqué précédemment, j'utiliserai GCP pour créer l'ensemble de l'infrastructure, mais vous pouvez créer la même infrastructure n'importe où ailleurs.
- Démarrez la machine virtuelle (instance / serveur).

- Créez une règle pour le pare-feu (groupe de sécurité dans AWS):
- J'aime attribuer le même nom de machine à la règle et à la balise réseau, dans ce cas, c'est «skywiz-consul-server-poc».
- Trouvez l'adresse IP de votre ordinateur local et ajoutez-la à la liste des adresses IP source afin que nous puissions accéder à l'interface utilisateur (UI).
- Ouvrez le port 8500 pour l'interface utilisateur. Cliquez sur Créer. Nous allons bientôt changer ce pare-feu [ lien ].
- Ajoutez la règle de pare-feu à l'instance. Revenez au tableau de bord de la VM sur le serveur Consul et ajoutez «skywiz-consul-server-poc» au champ de balise réseau. Cliquez sur Enregistrer.

- Installez Consul sur une machine virtuelle, vérifiez ici. N'oubliez pas que vous avez besoin de la version Consul ≥ 1.5 [link]
- Créez un seul nœud Consul - la configuration est la suivante.
groupadd --system consul useradd -s /sbin/nologin --system -g consul consul mkdir -p /var/lib/consul chown -R consul:consul /var/lib/consul chmod -R 775 /var/lib/consul mkdir /etc/consul.d chown -R consul:consul /etc/consul.d
- Pour un guide plus détaillé sur l'installation de Consul et la configuration d'un cluster de 3 nœuds, voir ici .
- Créez le fichier /etc/consul.d/agent.json comme suit [ lien ]:
### /etc/consul.d/agent.json { "acl" : { "enabled": true, "default_policy": "deny", "enable_token_persistence": true } }
- Lancez notre serveur Consul:
consul agent \ -server \ -ui \ -client 0.0.0.0 \ -data-dir=/var/lib/consul \ -bootstrap-expect=1 \ -config-dir=/etc/consul.d
- Vous devriez voir un tas de sortie et vous retrouver avec "... mise à jour bloquée par les ACL".
- Localisez l'adresse IP externe du serveur Consul et ouvrez un navigateur avec cette adresse IP sur le port 8500. Assurez-vous que l'interface utilisateur s'ouvre.
- Essayez d'ajouter une paire clé / valeur. Il doit y avoir une erreur. En effet, nous avons chargé le serveur Consul à l'aide de l'ACL et refusé toutes les règles.
- Revenez à votre shell sur le serveur Consul et démarrez le processus en arrière-plan ou d'une autre manière pour qu'il fonctionne, et entrez ce qui suit:
consul acl bootstrap
- Trouvez la valeur "SecretID" et revenez Ă l'interface utilisateur. Dans l'onglet ACL, entrez l'identifiant secret du jeton que vous venez de copier. Copiez SecretID ailleurs, nous en aurons besoin plus tard.
- Ajoutez maintenant une paire clé / valeur. Pour ce POC, ajoutez ce qui suit: clé: "custom-ns / test_key", valeur: "Je suis dans le dossier custom-ns!"
Lancez Kubernetes Cluster pour notre application avec Consul Client en tant que Daemonset
- Créez un cluster K8s (Kubernetes). Nous allons le créer dans la même zone que le serveur pour un accès plus rapide, et donc nous pouvons utiliser le même sous-réseau pour une connexion facile avec les adresses IP internes. Nous l'appellerons skywiz-app-with-consul-client-poc.

- Comme note, voici un bon guide que j'ai rencontré lors de la configuration d'un cluster POC Consul avec Consul Connect.
- Nous utiliserons également le graphique de barre Hashicorp avec un fichier de valeurs étendu.
- Installez et configurez Helm. Étapes de configuration:
kubectl create serviceaccount tiller --namespace kube-system kubectl create clusterrolebinding tiller-admin-binding \ --clusterrole=cluster-admin --serviceaccount=kube-system:tiller ./helm init --service-account=tiller ./helm update
### poc-helm-consul-values.yaml global: enabled: false image: "consul:latest" # Expose the Consul UI through this LoadBalancer ui: enabled: false # Allow Consul to inject the Connect proxy into Kubernetes containers connectInject: enabled: false # Configure a Consul client on Kubernetes nodes. GRPC listener is required for Connect. client: enabled: true join: ["<PRIVATE_IP_CONSUL_SERVER>"] extraConfig: | { "acl" : { "enabled": true, "default_policy": "deny", "enable_token_persistence": true } } # Minimal Consul configuration. Not suitable for production. server: enabled: false # Sync Kubernetes and Consul services syncCatalog: enabled: false
- Appliquer le tableau de barre:
./helm install -f poc-helm-consul-values.yaml ./consul-helm - name skywiz-app-with-consul-client-poc
- Lorsque vous essayez de démarrer, il aura besoin d'autorisations pour le serveur Consul, alors ajoutons-les.
- Faites attention à la "plage d'adresses Pod" située sur le tableau de bord du cluster et revenez à notre règle pour le pare-feu skywiz-consul-server-poc.
- Ajoutez la plage d'adresses pour l'IPA Ă la liste des adresses IP et ouvrez les ports 8301 et 8300.

- Accédez à l'interface utilisateur du Consul, et dans quelques minutes, vous verrez que notre cluster apparaîtra sur l'onglet du nœud.

Configurer la méthode d'autorisation en intégrant Consul à Kubernetes
- Revenez au shell du serveur Consul et exportez le jeton que vous avez enregistré précédemment:
export CONSUL_HTTP_TOKEN=<SecretID>
- Nous avons besoin des informations de notre cluster Kubernetes pour créer une instance de méthode d'authentification:
- kubernetes-host
kubectl get endpoints | grep kubernetes
- kubernetes-service-account-jwt
kubectl get sa <helm_deployment_name>-consul-client -o yaml | grep "\- name:" kubectl get secret <secret_name_from_prev_command> -o yaml | grep token:
- Le jeton est encodé en base64, alors déchiffrez-le à l'aide de votre outil préféré [ link ]
- kubernetes-ca-cert
kubectl get secret <secret_name_from_prev_command> -o yaml | grep ca.crt:
- Prenez le certificat «ca.crt» (après décodage avec base64) et écrivez-le dans le fichier «ca.crt».
- Créez maintenant une instance de la méthode auth, en remplaçant les espaces réservés par les valeurs que vous venez de recevoir.
consul acl auth-method create \ -type "kubernetes" \ -name "auth-method-skywiz-consul-poc" \ -description "This is an auth method using kubernetes for the cluster skywiz-app-with-consul-client-poc" \ -kubernetes-host "<k8s_endpoint_retrieved earlier>" \ -kubernetes-ca-cert=@ca.crt \ -kubernetes-service-account- jwt="<decoded_token_retrieved_earlier>"
- Ensuite, nous devons créer une règle et l'attacher au nouveau rôle. Vous pouvez utiliser l'interface utilisateur Consul pour cette partie, mais nous utiliserons la ligne de commande.
- Écrivez une règle
### kv-custom-ns-policy.hcl key_prefix "custom-ns/" { policy = "write" }
consul acl policy create \ -name kv-custom-ns-policy \ -description "This is an example policy for kv at custom-ns/" \ -rules @kv-custom-ns-policy.hcl
- Recherchez l'identifiant de la règle que vous venez de créer à partir de la sortie.
- Créez un rôle avec une nouvelle règle.
consul acl role create \ -name "custom-ns-role" \ -description "This is an example role for custom-ns namespace" \ -policy-id <policy_id>
consul acl binding-rule create \ -method=auth-method-skywiz-consul-poc \ -bind-type=role \ -bind-name='custom-ns-role' \ -selector='serviceaccount.namespace=="custom-ns"'
Dernières configurations
Droits d'accès
- Créez des autorisations. Nous devons donner au consul l'autorisation de vérifier et d'identifier l'identité du jeton du compte de service K8s.
- Écrivez le [lien] suivant dans le fichier:
###skywiz-poc-consul-server_rbac.yaml --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: review-tokens namespace: default subjects: - kind: ServiceAccount name: skywiz-app-with-consul-client-poc-consul-client namespace: default roleRef: kind: ClusterRole name: system:auth-delegator apiGroup: rbac.authorization.k8s.io --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: service-account-getter namespace: default rules: - apiGroups: [""] resources: ["serviceaccounts"] verbs: ["get"] --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: get-service-accounts namespace: default subjects: - kind: ServiceAccount name: skywiz-app-with-consul-client-poc-consul-client namespace: default roleRef: kind: ClusterRole name: service-account-getter apiGroup: rbac.authorization.k8s.io
- Créer des droits d'accès
kubectl create -f skywiz-poc-consul-server_rbac.yaml
Connectez-vous au client Consul
- Comme indiqué ici , il existe plusieurs options pour se connecter à daemonset, mais nous allons passer à la solution simple suivante:
- Appliquez le fichier suivant [ lien ].
### poc-consul-client-ds-svc.yaml apiVersion: v1 kind: Service metadata: name: consul-ds-client spec: selector: app: consul chart: consul-helm component: client hasDNS: "true" release: skywiz-app-with-consul-client-poc ports: - protocol: TCP port: 80 targetPort: 8500
- Utilisez ensuite la commande intégrée suivante pour créer le configmap [ lien ]. Veuillez noter que nous nous référons au nom de notre service, remplacez-le si nécessaire.
cat <<EOF | kubectl apply -f - apiVersion: v1 kind: ConfigMap metadata: labels: addonmanager.kubernetes.io/mode: EnsureExists name: kube-dns namespace: kube-system data: stubDomains: | {"consul": ["$(kubectl get svc consul-ds-client -o jsonpath='{.spec.clusterIP}')"]} EOF
Test de la méthode d'authentification
Voyons maintenant la magie en action!
- Créez quelques dossiers de clés supplémentaires avec la même clé de niveau supérieur (c'est-à -dire <nouveau_fichier> / sample_key) et la valeur de votre choix. Créez des stratégies et des rôles appropriés pour de nouveaux chemins d'accès clés. Nous ferons les reliures plus tard.

Test d'espace de noms personnalisé:
- Créez notre propre espace de noms:
kubectl create namespace custom-ns
- Créez sous dans notre nouvel espace de noms. Écrivez la configuration du foyer.
###poc-ubuntu-custom-ns.yaml apiVersion: v1 kind: Pod metadata: name: poc-ubuntu-custom-ns namespace: custom-ns spec: containers: - name: poc-ubuntu-custom-ns image: ubuntu command: ["/bin/bash", "-ec", "sleep infinity"] restartPolicy: Never
kubectl create -f poc-ubuntu-custom-ns.yaml
- Une fois le conteneur démarré, allez-y et installez curl.
kubectl exec poc-ubuntu-custom-ns -n custom-ns -it /bin/bash apt-get update && apt-get install curl -y
- Nous allons maintenant envoyer une demande pour entrer dans Consul en utilisant la méthode d'autorisation que nous avons créée plus tôt [ lien ].
- Pour afficher le jeton entré à partir de votre compte de service:
cat /run/secrets/kubernetes.io/serviceaccount/token
- Écrivez ce qui suit dans un fichier à l'intérieur du conteneur:
### payload.json { "AuthMethod": "auth-method-test", "BearerToken": "<jwt_token>" }
curl \ --request POST \ --data @payload.json \ consul-ds-client.default.svc.cluster.local/v1/acl/login
- Pour effectuer les étapes ci-dessus sur une seule ligne (car nous exécuterons plusieurs tests), vous pouvez effectuer les opérations suivantes:
echo "{ \ \"AuthMethod\": \"auth-method-skywiz-consul-poc\", \ \"BearerToken\": \"$(cat /run/secrets/kubernetes.io/serviceaccount/token)\" \ }" \ | curl \ --request POST \ --data @- \ consul-ds-client.default.svc.cluster.local/v1/acl/login
- Ça marche! Doit au moins. Maintenant, prenez le SecretID et essayez d'accéder à la clé / valeur à laquelle nous devons avoir accès.
curl \ consul-ds-client.default.svc.cluster.local/v1/kv/custom-ns/test_key --header “X-Consul-Token: <SecretID_from_prev_response>”
- Vous pouvez décoder la base «Value» 64 et voir qu'elle correspond à la valeur dans custom-ns / test_key dans l'interface utilisateur. Si vous avez utilisé la même valeur ci-dessus dans ce manuel, votre valeur encodée serait IkknbSBpbiB0aGUgY3VzdG9tLW5zIGZvbGRlciEi.
Test de compte de service utilisateur:
- Créez un ServiceAccount personnalisé avec la commande suivante [ lien ].
kubectl apply -f - <<EOF apiVersion: v1 kind: ServiceAccount metadata: name: custom-sa EOF
- Créez un nouveau fichier de configuration pour l'âtre. Veuillez noter que j'ai activé l'installation de boucle pour économiser du travail :)
###poc-ubuntu-custom-sa.yaml apiVersion: v1 kind: Pod metadata: name: poc-ubuntu-custom-sa namespace: default spec: serviceAccountName: custom-sa containers: - name: poc-ubuntu-custom-sa image: ubuntu command: ["/bin/bash","-ec"] args: ["apt-get update && apt-get install curl -y; sleep infinity"] restartPolicy: Never
- Après cela, exécutez le shell à l'intérieur du conteneur.
kubectl exec -it poc-ubuntu-custom-sa /bin/bash
echo "{ \ \"AuthMethod\": \"auth-method-skywiz-consul-poc\", \ \"BearerToken\": \"$(cat /run/secrets/kubernetes.io/serviceaccount/token)\" \ }" \ | curl \ --request POST \ --data @- \ consul-ds-client.default.svc.cluster.local/v1/acl/login
- Autorisation refusée. Oh, nous avons oublié d'ajouter une nouvelle liaison de règle avec les autorisations appropriées, faisons-le maintenant.
Répétez les étapes précédentes ci-dessus:
a) Créez une politique identique pour le préfixe "custom-sa /".
b) Créez un rôle, nommez-le "custom-sa-role"
c) Attachez la stratégie au rôle.
- Créez une règle de liaison (uniquement possible à partir de cli / api). Notez la valeur différente de l'indicateur de sélection.
consul acl binding-rule create \ -method=auth-method-skywiz-consul-poc \ -bind-type=role \ -bind-name='custom-sa-role' \ -selector='serviceaccount.name=="custom-sa"'
- Connectez-vous à nouveau à partir du conteneur poc-ubuntu-custom-sa. Succès!
- Vérifiez notre accès au chemin custom-sa / key.
curl \ consul-ds-client.default.svc.cluster.local/v1/kv/custom-sa/test_key --header “X-Consul-Token: <SecretID>”
- Vous pouvez également vous assurer que ce jeton ne donne pas accès à kv dans «custom-ns /». Répétez simplement la commande ci-dessus après avoir remplacé «custom-sa» par le préfixe «custom-ns».
Autorisation refusée.
Exemple de superposition:
- Il convient de noter que tous les mappages de liaison de règles seront ajoutés au jeton avec ces droits.
- Notre conteneur poc-ubuntu-custom-sa est dans l'espace de noms par défaut - nous allons donc l'utiliser pour une autre liaison de règles.
- Répétez les étapes précédentes:
a) Créez une politique identique pour le préfixe de clé «par défaut /».
b) Créez un rôle, nommez-le "default-ns-role"
c) Attachez la stratégie au rôle. - Créer une liaison de règles (uniquement possible à partir de cli / api)
consul acl binding-rule create \ -method=auth-method-skywiz-consul-poc \ -bind-type=role \ -bind-name='default-ns-role' \ -selector='serviceaccount.namespace=="default"'
- Revenez à notre conteneur poc-ubuntu-custom-sa et essayez d'accéder au chemin "default /" kv.
- Autorisation refusée.
Vous pouvez afficher les informations d'identification spécifiées pour chaque jeton dans l'interface utilisateur sous ACL> Tokens. Comme vous pouvez le voir, un seul «rôle custom-sa» est attaché à notre jeton actuel. Le jeton que nous utilisons actuellement a été généré lorsque nous nous sommes connectés, puis il n'y a eu qu'une seule liaison de règles, qui correspondait alors. Nous devons nous reconnecter et utiliser le nouveau jeton. - Assurez-vous que vous pouvez lire à la fois les chemins kv «custom-sa /» et «default /».
Succès!
En effet, notre poc-ubuntu-custom-sa correspond aux liaisons des règles custom-sa et default-ns.
Conclusion
Mgmt de jeton TTL?
Au moment d'écrire ces lignes, il n'existe aucun moyen intégré de déterminer le TTL pour les jetons générés par cette méthode d'autorisation. Ce serait une opportunité fantastique de fournir une automatisation sécurisée de l'autorisation du consul.
Il est possible de créer manuellement un token avec TTL:
J'espère que dans un avenir proche, nous serons en mesure de contrôler la façon dont les jetons sont générés (pour chaque règle ou méthode d'autorisation) et d'ajouter TTL.
D'ici là , il est proposé d'utiliser dans votre logique le point final de la sortie du système.
Lisez également d'autres articles sur notre blog: