Trucs et astuces Kubernetes: sur le développement local et la téléprésence



On nous interroge de plus en plus sur le développement des microservices à Kubernetes. Les développeurs, en particulier les langages interprétés, veulent corriger rapidement le code dans leur IDE préféré et sans attendre la génération / déploiement pour voir le résultat - en appuyant simplement sur F5. Et en ce qui concerne l'application monolithique, il suffisait d'augmenter localement la base de données et le serveur web (dans Docker, VirtualBox ...), après quoi - profitez immédiatement du développement. Avec le sciage des monolithes en microservices et l'avènement de Kubernetes, avec l'émergence de dépendances les uns des autres, les choses se sont un peu plus compliquées . Plus il y a de microservices, plus il y a de problèmes. Pour profiter à nouveau du développement, vous devez lever plus d'un ou deux conteneurs Docker, et parfois même plus d'une douzaine ... En général, tout cela peut prendre beaucoup de temps, car vous devez également le tenir à jour.

À différents moments, nous avons essayé différentes solutions au problème. Et je vais commencer par les solutions de contournement accumulées ou simplement des «béquilles».

1. Béquilles


La plupart des IDE ont la possibilité de modifier le code directement sur le serveur en utilisant FTP / SFTP. Cette manière est très évidente et nous avons immédiatement décidé de l'utiliser. Son essence est la suivante:

  1. Dans le pod pour les environnements de développement (dev / review), un conteneur supplémentaire est lancé avec accès via SSH et retransmission de la clé publique SSH du développeur qui va valider / déployer l'application.
  2. Au stade init (dans le conteneur prepare-app ) nous transférons le code vers emptyDir afin d'avoir accès au code des conteneurs avec l'application et le serveur SSH.



Pour une meilleure compréhension de l'implémentation technique d'un tel schéma, je donnerai des fragments des configurations YAML impliquées dans Kubernetes.

Configurations


1.1. values.yaml


 ssh_pub_key: vasya.pupkin: <ssh public key in base64> 

Ici vasya.pupkin est la valeur de la variable ${GITLAB_USER_LOGIN} .

1.2. deployment.yaml


 ... {{ if eq .Values.global.debug "yes" }} volumes: - name: ssh-pub-key secret: defaultMode: 0600 secretName: {{ .Chart.Name }}-ssh-pub-key - name: app-data emptyDir: {} initContainers: - name: prepare-app {{ tuple "backend" . | include "werf_container_image" | indent 8 }} volumeMounts: - name: app-data mountPath: /app-data command: ["bash", "-c", "cp -ar /app/* /app-data/" ] {{ end }} containers: {{ if eq .Values.global.debug "yes" }} - name: ssh image: corbinu/ssh-server volumeMounts: - name: ssh-pub-key readOnly: true mountPath: /root/.ssh/authorized_keys subPath: authorized_keys - name: app-data mountPath: /app ports: - name: ssh containerPort: 22 protocol: TCP {{ end }} - name: backend volumeMounts: {{ if eq .Values.global.debug "yes" }} - name: app-data mountPath: /app {{ end }} command: ["/usr/sbin/php-fpm7.2", "--fpm-config", "/etc/php/7.2/php-fpm.conf", "-F"] ... 

1.3. secret.yaml


 {{ if eq .Values.global.debug "yes" }} apiVersion: v1 kind: Secret metadata: name: {{ .Chart.Name }}-ssh-pub-key type: Opaque data: authorized_keys: "{{ first (pluck .Values.global.username .Values.ssh_pub_key) }}" {{ end }} 

Touche finale


Après cela, il ne reste plus qu'à passer les variables nécessaires à gitlab-ci.yml :

 dev: stage: deploy script: - type multiwerf && source <(multiwerf use 1.0 beta) - type werf && source <(werf ci-env gitlab --tagging-strategy tag-or-branch --verbose) - werf deploy --namespace ${CI_PROJECT_NAME}-stage --set "global.env=stage" --set "global.git_rev=${CI_COMMIT_SHA}" --set "global.debug=yes" --set "global.username=${GITLAB_USER_LOGIN}" tags: - build 

Voila: le développeur qui a lancé le déploiement peut se connecter en utilisant le nom du service ( nous vous avons déjà dit comment émettre en toute sécurité l'accès au cluster) depuis votre bureau via SFTP et modifier le code sans attendre qu'il soit livré au cluster.

Il s'agit d'une solution totalement fonctionnelle, mais du point de vue de la mise en œuvre, elle présente des inconvénients évidents:

  • la nécessité d'affiner le graphique Helm, ce qui complique encore sa lecture;
  • Seul celui qui a déployé le service peut l'utiliser;
  • vous devez vous rappeler de le synchroniser avec le répertoire local avec le code et de valider dans Git.

2. Téléprésence


Le projet de téléprésence est connu depuis un certain temps, mais l'essayer sérieusement dans la pratique avec nous, comme on dit, «n'a pas atteint nos mains». Cependant, la demande a fait son travail et nous sommes maintenant heureux de partager une expérience qui pourrait être utile aux lecteurs de notre blog - d'autant plus qu'il n'y avait pas d'autre matériel sur la téléprésence sur le hub.

Bref, ce n'était pas si effrayant. Toutes les actions qui nécessitent une exécution par le développeur, nous les avons placées dans le fichier texte du Helm-chart, appelé NOTES.txt . Ainsi, le développeur après avoir déployé le service dans Kubernetes voit les instructions pour démarrer l'environnement de développement local dans le journal des travaux GitLab:

 !!!   ,   Kubernetes !!! *   * *       VPN * *     kubectl ( https://kubernetes.io/docs/tasks/tools/install-kubectl/ ) * *  config-  kubectl (  ~/.kube/config) * *     telepresence ( https://www.telepresence.io/reference/install ) * *    Docker * *    reporter     https://gitlab.site.com/group/app * *    registry  /  GitLab (  ): ######################################################################### docker login registry.site.com ######################################################################### *   ######################################################################### telepresence --namespace {{ .Values.global.env }} --swap-deployment {{ .Chart.Name }}:backend --mount=/tmp/app --docker-run -v `pwd`:/app -v /tmp/app/var/run/secrets:/var/run/secrets -ti registry.site.com/group/app/backend:v8 ######################################################################### 


Nous ne nous attarderons pas sur les étapes décrites dans ce manuel ... à l'exception de la dernière. Que se passe-t-il lors du lancement de la téléprésence?

Travailler avec la téléprésence


Au démarrage (par la dernière commande spécifiée dans les instructions ci-dessus), nous définissons:

  • espace de noms (espace de noms) dans lequel le microservice est lancé;
  • les noms du déploiement et du conteneur que nous voulons pénétrer.

Les arguments restants sont facultatifs. Si notre service interagit avec l'API Kubernetes et qu'un ServiceAccount est créé pour lui, nous devons monter les certificats / jetons sur notre bureau. Pour ce faire, utilisez l'option --mount=true (ou --mount=/dst_path ), qui montera la racine (/) du conteneur de Kubernetes sur notre bureau. Après cela, nous pouvons (en fonction du système d'exploitation et de la façon dont l'application est lancée) utiliser les «clés» du cluster.

Tout d'abord, considérez l'option de lancement d'application la plus polyvalente - dans le conteneur Docker. Pour ce faire, utilisez le --docker-run et montez le répertoire avec le code dans le conteneur: -v `pwd`:/app

Veuillez noter que cela implique de partir du répertoire avec le projet. Le code d'application sera monté dans le répertoire /app du conteneur.

Suivant: -v /tmp/app/var/run/secrets:/var/run/secrets - pour monter le répertoire avec le certificat / jeton dans le conteneur.

Cette option est enfin suivie de l'image dans laquelle l'application sera lancée. NB : Lors de la construction d'une image, vous devez spécifier CMD ou ENTRYPOINT !

Que se passera-t-il en fait ensuite?

  • Dans Kubernetes, pour le déploiement spécifié, le nombre de réplicas sera changé à 0. Au lieu de cela, un nouveau déploiement sera lancé - avec le conteneur backend remplacé.
  • Sur le bureau, 2 conteneurs vont démarrer: le premier - avec Telepresence (il va proxy les requêtes de / vers Kubernetes), le second - avec l'application en cours de développement.
  • Si exec'nitsya dans le conteneur avec l'application, nous aurons accès à toutes les variables ENV passées par Helm pendant le déploiement, ainsi que tous les services sont disponibles. Il ne reste plus qu'à éditer le code dans votre IDE préféré et profiter du résultat.
  • À la fin du travail, il suffit de fermer simplement le terminal où la téléprésence est exécutée (terminer la session en utilisant Ctrl + C), les conteneurs Docker s'arrêteront sur le bureau et tout reviendra à son état d'origine dans Kubernetes. Il ne reste plus qu'à valider, émettre le MR et le passer à revoir / fusionner / ... (en fonction de vos workflows).

Si nous ne voulons pas exécuter l'application dans un conteneur Docker - par exemple, nous la développons non pas en PHP, mais en Go, et la collectons toujours localement - le lancement de Telepresence sera encore plus facile:

 telepresence --namespace {{ .Values.global.env }} --swap-deployment {{ .Chart.Name }}:backend --mount=true 

Si l'application accède à l'API Kubernetes, vous devrez monter le répertoire avec les clés . Pour Linux, il existe un utilitaire proot :

 proot -b $TELEPRESENCE_ROOT/var/run/secrets/:/var/run/secrets bash 

Après avoir démarré --docker-run sans l'option --docker-run , toutes les variables d'environnement seront disponibles dans le terminal actuel, vous devez donc y démarrer l'application.

NB : Lorsque vous utilisez, par exemple, PHP, vous devez vous rappeler de désactiver divers op_cache, apc et autres accélérateurs pour le développement - sinon l'édition du code ne produira pas le résultat souhaité.

Résumé


Le développement local avec Kubernetes est un problème dont le besoin de solution croît proportionnellement à la diffusion de cette plateforme. Ayant reçu des demandes pertinentes des développeurs (de nos clients), nous avons commencé à les résoudre avec les premiers moyens disponibles, qui n'ont cependant pas fait leurs preuves sur une longue distance. Heureusement, cela est devenu évident non seulement maintenant et pas seulement pour nous, donc des moyens plus appropriés sont déjà apparus dans le monde, et la téléprésence est la plus célèbre d'entre elles (à propos, il y a encore un échafaudage de Google). Notre expérience de son utilisation n'est pas si grande, mais cela donne déjà des raisons de recommander des "collègues" - essayez-le!

PS


Autres du cycle de trucs et astuces de K8:

Source: https://habr.com/ru/post/fr446788/


All Articles