
Bonjour ! Branche de fonctionnalitĂ© (Ă©galement appelĂ©e dĂ©ploiement de prĂ©visualisation, application de rĂ©vision) â c'est lorsque non seulement la branche master est dĂ©ployĂ©e, mais aussi chaque pull request sur une URL unique. Vous pouvez vĂ©rifier si le code fonctionne dans un environnement de production, et la fonctionnalitĂ© peut ĂȘtre montrĂ©e Ă d'autres dĂ©veloppeurs ou chefs de produit. Tant que vous travaillez dans un pull request, chaque nouveau commit remplace le dĂ©ploiement actuel du vieux code, et un nouveau dĂ©ploiement pour le nouveau code est mis en place. Des questions peuvent se poser lorsque vous avez fusionnĂ© le pull request dans la branche master. La branche de fonctionnalitĂ© n'est plus nĂ©cessaire, mais les ressources Kubernetes sont toujours prĂ©sentes dans le cluster.
Encore au sujet des branches de fonctionnalités
Une des approches pour créer des branches de fonctionnalités dans Kubernetes consiste à utiliser des namespaces. En résumant, la configuration de production ressemble à ceci :
kind: Namespace
apiVersion: v1
metadata:
name: habr-back-end
...
kind: Deployment
apiVersion: apps/v1
metadata:
namespace: habr-back-end
spec:
replicas: 3
...Pour la branche de fonctionnalité, un namespace est créé avec son identifiant (par exemple, le numéro de la pull request) et un préfixe/suffixe (par exemple, -pr-):
kind: Namespace
apiVersion: v1
metadata:
name: habr-back-end-pr-17
...
kind: Deployment
apiVersion: apps/v1
metadata:
namespace: habr-back-end-pr-17
spec:
replicas: 1
...En général, j'ai écrit Kubernetes Operator (une application qui a accÚs aux ressources du cluster), . Il supprime les namespaces associés aux anciennes branches de fonctionnalités. Dans Kubernetes, si vous supprimez un namespace, d'autres ressources dans ce namespace sont également supprimées automatiquement.
$ kubectl get pods --all-namespaces | grep -e "-pr-"
NAMESPACE ... ĂGE
habr-back-end-pr-264 ... 4d8h
habr-back-end-pr-265 ... 5d7hPour savoir comment intégrer les branches de fonctionnalités dans le cluster, vous pouvez lire et .
Motivation
Jetons un Ćil Ă un cycle de vie typique d'une pull request avec intĂ©gration continue (intĂ©gration continue):
- Nous poussons un nouveau commit dans la branche.
- Lors de la construction, des linters et/ou des tests sont lancés.
- Les configurations Kubernetes de la pull request sont gĂ©nĂ©rĂ©es Ă la volĂ©e (par exemple, le numĂ©ro est insĂ©rĂ© dans un modĂšle prĂȘt).
- Les configurations sont appliquées au cluster à l'aide de kubectl (déploiement).
- La pull request est fusionnée dans la branche master.
Tant que vous travaillez dans la pull request, chaque nouveau commit remplace le déploiement actuel du vieux code, et un nouveau déploiement pour le nouveau code est mis en place. Mais lorsque la pull request est fusionnée dans la branche master, seul le master sera construit. Au final, nous oublions la pull request, mais ses ressources Kubernetes sont toujours présentes dans le cluster.
Comment utiliser
Installez le projet avec la commande ci-dessous :
$ kubectl apply -f https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/configs/production.ymlCréez un fichier avec le contenu suivant et installez-le via kubectl apply -f:
apiVersion: feature-branch.dmytrostriletskyi.com/v1
kind: StaleFeatureBranch
metadata:
name: stale-feature-branch
spec:
namespaceSubstring: -pr-
afterDaysWithoutDeploy: 3ParamÚtre namespaceSubstring nécessaire pour filtrer les namespaces des pull requests d'autres namespaces. Par exemple, si le cluster contient les namespaces suivants : habr-back-end, habr-front-end, habr-back-end-pr-17, habr-back-end-pr-33, alors les candidats à la suppression seront habr-back-end-pr-17, habr-back-end-pr-33.
ParamÚtre afterDaysWithoutDeploy nécessaire pour supprimer les vieux namespaces. Par exemple, si un namespace a été créé il y a 3 jours et 1 heure , et que le paramÚtre spécifie 3 jours, ce namespace sera supprimé. Cela fonctionne aussi dans l'autre sens, si le namespace a été créé il y a 2 jours et 23 heures , et que le paramÚtre spécifie 3 jours, ce namespace ne sera pas supprimé.
Il y a un autre paramĂštre, il dĂ©termine Ă quelle frĂ©quence scanner tous les namespaces et vĂ©rifier les jours sans dĂ©ploiement â checkEveryMinutes. Par dĂ©faut, il est Ă©gal Ă 30 minutes.
Comment cela fonctionne
En pratique, il faut :
- pour fonctionner dans un environnement isolé.
- va lancer un cluster Kubernetes localement.
- â interface en ligne de commande pour gĂ©rer le cluster.
Lançons le cluster Kubernetes localement :
$ minikube start --vm-driver=docker
minikube v1.11.0 sur Darwin 10.15.5
Utilisation du pilote docker basé sur le profil existant.
DĂ©marrage du nĆud du plan de contrĂŽle minikube dans le cluster minikube.Indiquons kubectl d'utiliser le cluster local par dĂ©faut :
$ kubectl config use-context minikube
Contexte changé pour "minikube".Téléchargeons les configurations pour l'environnement de production :
$ curl https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/configs/production.yml > stale-feature-branch-production-configs.ymlĂtant donnĂ© que les configurations de production sont rĂ©glĂ©es pour vĂ©rifier les vieux namespaces, et qu'il n'y en a pas dans notre nouveau cluster, remplaçons la variable d'environnement IS_DEBUG sur true. Avec cette valeur, le paramĂštre afterDaysWithoutDeploy n'est pas pris en compte et les namespaces ne sont pas vĂ©rifiĂ©s pour les jours sans dĂ©ploiement, seulement pour la prĂ©sence de la sous-chaĂźne (-pr-).
Si vous ĂȘtes sur Linux:
$ sed -i 's|false|true|g' stale-feature-branch-production-configs.ymlSi vous ĂȘtes sur macOS:
$ sed -i "" 's|false|true|g' stale-feature-branch-production-configs.ymlInstallons le projet :
$ kubectl apply -f stale-feature-branch-production-configs.ymlVérifions que la ressource est apparue dans le cluster StaleFeatureBranch:
$ kubectl api-resources | grep stalefeaturebranches
NOM ... APIGROUP ... TYPE
stalefeaturebranches ... feature-branch.dmytrostriletskyi.com ... StaleFeatureBranchVérifions que l'opérateur est apparu dans le cluster :
$ kubectl get pods --namespace stale-feature-branch-operator
NOM ... ĂTAT ... ĂGE
stale-feature-branch-operator-6bfbfd4df8-m7sch ... En cours d'exĂ©cution ... 38sSi nous regardons ses logs, il est prĂȘt Ă traiter les ressources StaleFeatureBranch:
$ kubectl logs stale-feature-branch-operator-6bfbfd4df8-m7sch -n stale-feature-branch-operator
... "msg":"Version de l'opérateur : 0.0.1"}
...
... "msg":"Démarrage de EventSource", ... , "source":"type source : /, Type="}
... "msg":"Démarrage du contrÎleur", ...}
... "msg":"DĂ©marrage des travailleurs", ..., "nombre de travailleurs":1}Installons les fixtures (configurations prĂȘtes pour la modĂ©lisation des ressources de cluster) pour la ressource StaleFeatureBranch:
$ kubectl apply -f https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/fixtures/stale-feature-branch.ymlLes configurations spécifient de rechercher des namespaces contenant la sous-chaßne -pr- toutes les 1 minute.:
apiVersion: feature-branch.dmytrostriletskyi.com/v1
kind: StaleFeatureBranch
metadata:
name: stale-feature-branch
spec:
namespaceSubstring: -pr-
afterDaysWithoutDeploy: 1
checkEveryMinutes: 1L'opĂ©rateur a rĂ©agi et est prĂȘt Ă vĂ©rifier les namespaces :
$ kubectl logs stale-feature-branch-operator-6bfbfd4df8-m7sch -n stale-feature-branch-operator
... "msg":"La branche de fonctionnalité obsolÚte est en cours de traitement.","namespaceSubstring":"-pr-","afterDaysWithoutDeploy":1,"checkEveryMinutes":1,"isDebug":"true"}Nous installons fixtures, contenant deux namespaces (project-pr-1, project-pr-2) et leurs déploiements, services, ingress, et ainsi de suite :
$ kubectl apply -f https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/fixtures/first-feature-branch.yml -f https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/fixtures/second-feature-branch.yml
...
namespace/project-pr-1 créé
déploiement.apps/project-pr-1 créé
service/project-pr-1 créé
horizontalpodautoscaler.autoscaling/project-pr-1 créé
secret/project-pr-1 créé
configmap/project-pr-1 créé
ingress.extensions/project-pr-1 créé
namespace/project-pr-2 créé
déploiement.apps/project-pr-2 créé
service/project-pr-2 créé
horizontalpodautoscaler.autoscaling/project-pr-2 créé
secret/project-pr-2 créé
configmap/project-pr-2 créé
ingress.extensions/project-pr-2 crééVérifions que toutes les ressources ci-dessus ont été créées avec succÚs :
$ kubectl get namespace,pods,déploiement,service,horizontalpodautoscaler,configmap,ingress -n project-pr-1 && kubectl get namespace,pods,déploiement,service,horizontalpodautoscaler,configmap,ingress -n project-pr-2
...
NOM ... PRĂT ... STATUT ... ĂGE
pod/project-pr-1-848d5fdff6-rpmzw ... 1/1 ... En cours d'exécution ... 67s
NOM ... PRĂT ... DISPONIBLE ... ĂGE
déploiement.apps/project-pr-1 ... 1/1 ... 1 ... 67s
...Puisque nous avons activĂ© debug, les namespaces project-pr-1 et project-pr-2, tous les autres ressources devraient Ă©galement ĂȘtre supprimĂ©es immĂ©diatement, sans tenir compte du paramĂštre afterDaysWithoutDeploy. Dans les logs de l'opĂ©rateur, cela est visible :
$ kubectl logs stale-feature-branch-operator-6bfbfd4df8-m7sch -n stale-feature-branch-operator
... "msg":"Le namespace doit ĂȘtre supprimĂ© car le mode dĂ©bogage est activĂ©.","namespaceName":"project-pr-1"}
... "msg":"Le namespace est en cours de traitement.","namespaceName":"project-pr-1","namespaceCreationTimestamp":"2020-06-16 18:43:58 +0300 EEST"}
... "msg":"Le namespace a été supprimé.","namespaceName":"project-pr-1"}
... "msg":"Le namespace doit ĂȘtre supprimĂ© car le mode dĂ©bogage est activĂ©.","namespaceName":"project-pr-2"}
... "msg":"Le namespace est en cours de traitement.","namespaceName":"project-pr-2","namespaceCreationTimestamp":"2020-06-16 18:43:58 +0300 EEST"}
... "msg":"Le namespace a été supprimé.","namespaceName":"project-pr-2"}Si nous vérifions la présence des ressources, elles seront dans l'état Terminating (processus de suppression) ou déjà supprimées (le résultat de la commande est vide).
$ kubectl get namespace,pods,déploiement,service,horizontalpodautoscaler,configmap,ingress -n project-pr-1 && kubectl get namespace,pods,déploiement,service,horizontalpodautoscaler,configmap,ingress -n project-pr-2
...Vous pouvez répéter le processus de création fixtures assurez-vous plusieurs fois qu'ils seront supprimés dans la minute.
Alternatives
Que peut-on faire à la place d'un opérateur fonctionnant dans un cluster ? Plusieurs approches sont possibles, toutes ne sont pas idéales (et leurs inconvénients sont subjectifs), et chacun décide ce qui convient le mieux à son projet spécifique :
Supprimer la branche feature pendant le build de la branche master d'intégration continue.
- Pour cela, il faut savoir quel pull request se rapporte au commit qui est en cours de build. Ătant donnĂ© que le namespace de la branche feature contient l'identifiant du pull request â son numĂ©ro ou le nom de la branche, il faudra toujours le spĂ©cifier dans le commit.
- Les builds des branches master échouent. Par exemple, vous avez les étapes suivantes : télécharger le projet, exécuter des tests, compiler le projet, faire une release, envoyer des notifications, nettoyer la branche feature du dernier pull request. Si le build échoue lors de l'envoi de la notification, vous devrez supprimer toutes les ressources du cluster manuellement.
- Sans le contexte approprié, la suppression de la branche feature dans le build master n'est pas évidente.
L'utilisation des webhooks ().
- Peut-ĂȘtre que ce n'est pas votre approche. Par exemple, dans , seul un type de pipeline prend en charge la possibilitĂ© de conserver ses configurations dans le code source. Lors de l'utilisation des webhooks, il faut Ă©crire son propre script pour les traiter. Ce script devra ĂȘtre placĂ© dans l'interface de Jenkins, ce qui est difficile Ă maintenir.
Ăcrire et ajouter un cluster Kubernetes.
- Une perte de temps pour écrire et maintenir.
- L'opérateur fonctionne déjà dans un style similaire, est documenté et supporté.
Merci pour votre attention Ă l'article. .
Source : habr.com
