编程知识 cdmana.com

Docker + Jenkins pour une intégration continue déploiement continu

L'auteur est en route,Si le texte est incorrect、Si ce n'est pas le cas, Veuillez commenter et me dire,Merci beaucoup!!  

Maintenant, nous avons un projet frontal de centre de documentation,Nous allons le déployer sur le serveur pour la publication,Mais chaque fois que vous mettez à jour un document ou un code dans un projet,Tout doit être reconditionné pour le déploiement,C'est trop gênant..Comment faire chaque soumission de code、Emballez、Le déploiement est plus automatisé?Cet article décrit l'utilisation deJenkinsAvecDockerRéaliser une intégration continue déploiement continu.Les principaux éléments sont les suivants::

Jenkins:jenkinsIntroduction、Installation、Créer une tâche、pipelineDéployer des pipelines、pipelineDeux grammaires、L'automatisation déclenche l'exécution. Docker:dockerIntroduction、Installation、dockerCommandes de base、UtiliserdockerfileConstruire un miroir personnalisé、docker-composeConstruire plusieurs conteneurs miroirs.

Jenkins

- Oui.Jenkins

JenkinsEst une source ouverte、Intégration continue avec une interface conviviale(CI)Outils,Il est principalement utilisé pour、Construction automatique/Projet de logiciel de test.

CIIntégration continue:Intégration automatique fréquente du Code dans l'épine dorsale et l'environnement de production,Découvrez les erreurs d'intégration dès que possible.Processus:Code de soumission->Tirez le Code->Compiler->Emballez->Tests->Questions de rétroaction->Traitement du développement->Code de soumission.

CDExécution continue:Basé sur une intégration continue,Mettre fréquemment de nouvelles versions du logiciel,Livré à l'équipe de qualité ou à l'utilisateur,Pour examen.Quoi qu'il en soit, les mises à jour,Le logiciel peut être livré n'importe quand, n'importe où.

Déploiement continu: Prochaines étapes de la prestation continue , Code passé l'examen , Déploiement automatisé dans un environnement de production .

Pour que nous puissionsJenkinsCréer une tâche,JeanJenkins Pour nous aider à faire des choses qui se répètent constamment .

Installation

Installer la configuration sur le serveur jenkins,RÉFÉRENCESjenkins Installation et configuration de base (LinuxPlate - forme.

Peut également être utilisédockerInstallationjenkins, Cette section ne couvre pas .

Après le démarrage de l'installation , L'interface principale est la suivante: :

Créer une tâche

Cliquez sur“Nouvelle tâche”, Nous pouvons créer une tâche normale , Ou une tâche de Pipeline .

Style libre

Combiner tout SCM Et tout système de construction pour construire un projet , Faire des tâches simples en général .

Nous pouvons définir la configuration du code source , Décrire la tâche dans la construction ,UtiliserNodePlug - in,Mise en œuvrenpm run build Le script emballe le projet et le déploie sur le serveur . Chaque fois que vous cliquez sur une tâche de construction ,jenkinsVa tirergitlabCode, Placé sur le serveur jenkinsDeworkspaceSous le dossier, Ce dossier de code sera utilisé comme répertoire de travail lors de la construction du script .

pipeline

Si la tâche de construction est compliquée ,Peut être créépipleline Tâches de Pipeline .

Déployer des pipelinesPipeline- Oui.Jenkins 2.xL'essence de,Connectez des tâches qui fonctionnent autrement indépendamment d'un ou de plusieurs noeuds, Mettre en œuvre des processus complexes qui sont difficiles à accomplir pour une seule tâche , Formation d'une libération en continu , Visualisation des étapes de construction .Pipeline Scénario plus large applicable , Capable de gérer des processus de publication plus complexes .( Vous pouvez même travailler sur plusieurs projets )

1、pipelineDeux grammaires
  • Syntaxe scriptée ( Utilisation GroovyLangues)

Flexible、Extensible,Plus compliqué, Coûts d'apprentissage .

node {
  stage('build') {
    try{ 
       def dockerName='documentcontainer'  //def Variables de définition des mots clés 
       def imageUrl = "${dockerName}:${dockerTag}"
       def customImage = docker.build(imageUrl)
       sh "docker rm -f ${dockerName} | true"
       customImage.run("-it -p 8900:80 --name ${dockerName}")
        ...
       currentBuild.result="SUCCESS"
    }catch(e){
       currentBuild.result="FAILURE"         
       throw e
    }
  }
}
Copier le Code
  • Syntaxe déclarative
    Plus simple.、 Plus structuré
pipeline {  // Représente toute la ligne de montage 
    agent any  // Spécifier l'emplacement d'exécution du pipeline 
    stages { //Contient un ou plusieursstageConteneur pour
        stage('Docker build') { //Phase,UnstageIl n'y en a qu'unsteps, Ces étapes peuvent être réutilisées 
            steps {  // Conteneur contenant une ou plusieurs étapes spécifiques 
              echo 'hello world' //echo C'est une étape. 
              
            }
        }
        stage(‘test') { //Phase,UnstageIl n'y en a qu'unsteps, Ces étapes peuvent être réutilisées 
            steps {  // Conteneur contenant une ou plusieurs étapes spécifiques 
              echo 'hello world' //echo C'est une étape. 
              
            }
        }
    }
}
Copier le Code

C'est une déclaration. piplelineStructure de base, Chaque partie est nécessaire .

More:

1、post En partie dans l'ensemble pipeline Ou quelques étapes supplémentaires après la fin de la phase

post{
  success{
     echo "========pipeline executed successfully ========"
  }
  failure{
     echo "========pipeline execution failed========"
  }
  always/changed/aborted...
}
Copier le Code

2、Dans la DéclarationpipelineImpossible d'utiliserif-elseAttendez.,Et donc,jenkinsOffrescriptÉtapes,Pour que vous puissiezstepsC'est écrit ici.groovyCode.

 stage('Docker build') { 
     steps {  
          script{
             def browsers=['chrome','firefox']
             for(int i=0;i<browsers.size();++i){
               echo "${browsers[i]}"
             }          
           } 
      }
 }
Copier le Code

3、 Prise en charge de certaines directives , Complément à l'infrastructure , La directive a sa propre portée

Par exemple:environment:Définir les variables d'environnement, Peut être défini dans stageOupipelineSection

2、jenkinsfile :

Vous pouvez écrire la logique du pipeline de déploiement dans jenkinsfileDans le document, Dans le projet .

ParamètresPipeline Script from SCM Extrait de la Bibliothèque de contrôle de version pipeline

Déclenchement de l'exécution des tâches

Maintenant, chaque fois que nous soumettons le Code , Et coupez jenkins Cliquez pour construire l'interface , Ce n'est pas assez automatique. .

Il y a plusieurs conditions pour déclencher une tâche , Déclencheur de construction configurable .

  • Déclenchement temporel Déclencheur chronométré、 Entrepôt de code de vote

  • Déclenchement de l'événement Par exemple:GitLab Déclenchement de la notification :QuandGitLab Lorsqu'un changement de code source est constaté ,DéclencheurjenkinsExécuter la construction.(Pas mal.,Ça marche!)
    UtilisationGitLabFourniwebhookCrochet

Maintenant, nous utilisons jenkins Peut être déployé de façon continue et intégrée , Mais nous devons le déployer sur le serveur nginx,Encore.jenkins Création node L'installation de l'environnement dépend de l'emballage et du déploiement vers nginx, Il y a deux questions. : Le premier est qu'il doit être déployé à l'avance. nginx, Ou s'il s'agit d'un projet d'arrière - plan nécessitant le déploiement d'une base de données, etc. , Environnement de déploiement complexe , Si nous voulons migrer le serveur et le redéployer ; Deuxièmement, le temps d'installation est trop long pour être réinstallé à chaque fois .

Donc maintenant, nous utilisons Docker, Mettre l'application et l'environnement d'exécution en un seul dockerDans le récipient, Déploiement facile et rapide sur n'importe quel serveur , Réduire le temps d'installation dépendant en utilisant le cache miroir .

Docker

- Oui.Docker

1、Qu'est - ce quedocker

Docker Est un moteur de conteneur d'application Open Source,Permettre aux développeurs d'emballer leurs applications et leurs dépendances dans un conteneur portable, Le conteneur contient le Code de l'application 、Environnement opérationnel、Bibliothèques dépendantes、 Ressources nécessaires telles que les profils , Les conteneurs permettent un déploiement automatisé facile, rapide et découplé de la plateforme , Quel que soit votre environnement de déploiement , Les applications du conteneur fonctionnent toutes dans le même environnement .

(Résumé:Utilisationdocker Peut emballer nos applications et dépendances dans un conteneur , Facile et rapide à déployer sur n'importe quelle machine via un conteneur , Et les applications dans le conteneur fonctionnent dans le même environnement .)

2、dockerQuels problèmes ont été résolus

  • Environnement de construction fréquent

    L'ingénieur o & m construit plusieurs machines 、 Migration du serveur

  • Environnement incohérent

    windowAveclinux Système d'exploitation différent 、 Différentes versions dépendantes

  • Virtualisation secondaire

      Pas vraiment.. Une plateforme comme Cloud Computing est une sorte de virtualisation , Résumé des ressources informatiques .docker Est la virtualisation au niveau du système d'exploitation , Chaque conteneur a son propre système de fichiers 、Gestion des processus(maybe), Isolé de l'extérieur .

Miroir、Conteneur、 La différence entre les entrepôts

Miroir(Image): C'est l'équivalent d'un root Système de fichiers,En plus de fournir les programmes nécessaires à l'exécution du conteneur、Bibliothèque、Ressources、En dehors des fichiers de configuration, etc.,Contient également quelques paramètres de configuration pour l'exécution(Comme un volume anonyme、Variables d'environnement、Utilisateurs, etc.). Le miroir lui - même est en lecture seule ,Son contenu ne sera pas modifié après la construction.

Conteneur(Container):Instance d'exécution du miroir. Lorsque le conteneur est démarré sur une image miroir ,docker Crée une couche writable au niveau supérieur du miroir , L'opération dans le conteneur ne modifie pas le miroir lui - même .

Entrepôt(Repository): Où les miroirs sont stockés centralement , Divisé en entrepôt public (DockerHub、dockerpool)Et des entrepôts privés.DockerHub:docker Un entrepôt public officiellement entretenu hub.docker.com,Y compris15000 Miroirs multiples , La plupart peuvent passer dockerhub Télécharger l'image directement .Également disponible viadocker searchEtdocker pull Commandes à télécharger .

Installation

1、WindowsInstallation   Installer temporairement sur l'ordinateur local ,ApprendredockerLes ordres.

Problèmes rencontrés I :

net localgroup docker-users username /add
OuAdd-LocalGroupMember -Group "docker-users" -Member "username "`
Copier le Code

Puis redémarrez

Problèmes rencontrés II :

docker pull failed

Définir le miroir source

{
  "experimental": false,
  "features": {
  "buildkit": true
  },
  "registry-mirrors": [
  "https://h3j9xv2v.mirror.aliyuncs.com"
  ]
}
Copier le Code

2、linuxInstallation du serveur

RÉFÉRENCES:linux Installationdocker

Utiliserdocker

dockerCommande de base pour, Commandes principalement divisées en miroirs et conteneurs

Obtenir un miroir docker pull  node [Adresse de l'entrepôt miroir]

Voir tous les miroirs  docker image ls -a   (-a Inclure un miroir de niveau intermédiaire , Sans étiquette , Est un miroir dont dépendent d'autres miroirs )

Supprimer le miroir docker image rm <container_id Par exemple:08ec>

Construire un miroir docker build -t documentcontainer .  (-t Nommez le miroir )Basé surdockerfile .ReprésentantdockerfileDans le répertoire actuel

Créer un conteneur en utilisant un miroir docker run -p 3000:80 -d --name documentApp documentcontainer

  • -p 3000:80 Cartographie des ports, Sera hébergé 3000Port mapped to Container80Port

  • -d Fonctionnement en arrière - plan

  • --name Nom du conteneur

  • -v Cartographie des fichiers /root/code:/data/code

Voir tous les conteneurs docker ps

Ouvert/Arrêtez!/Redémarrer le conteneur docker start/stop/restart <Nom du conteneur>

Dans le récipient docker attach <container_id> Sortie dans le récipient de la buse

docker exec -ti [container_id] /bin/bash

Supprimer le conteneur docker rm  -f <container...>

Basé surDockerfile Pour construire un miroir personnalisé

RÉFÉRENCES:Docker——Du début à la pratique

Docker Déploiement vue Projets

  • dockerfileDirectives

FROM :Miroir de base, Indique sur quel miroir le nouveau miroir actuel est modifié

RUN :Mise en œuvreshellLes ordres,Indocker buildExécution à l'heure

CMD :Indocker run Exécution à l'heure,Spécifiez le programme par défaut à exécuter pour le conteneur démarré,Peut être docker run Le programme spécifié dans les paramètres de la ligne de commande à exécuter est écrasé.

COPY 、ADD: Copier le fichier dans le conteneur

EXPOSE: Port du conteneur exposé

WORKDIR: Basculer le Répertoire Similaire àcd

ParUCF3.0 Exemple de projet de centre de documents , Processus de déploiement de cette application frontale :

  1. npm install, Dépendances d'installation

  2. npm run build,Compiler,Emballez, Générer des ressources statiques

  3. Ressources statiques desservies

FROM node:alpine as builder 

ENV NODE_ENV production   
WORKDIR /code
ADD . /code
RUN npm install --registry=https://registry.npm.taobao.org  --production && npm run build

// Pour les domaines croisés , Le dossier emballé doit être déployé dans nginxEn bas.
//AccèsnginxMiroir
FROM nginx
COPY --from=builder /code/nginx/default.conf /etc/nginx/conf.d/default.conf
COPY --from=builder /code/build/ /usr/share/nginx/html/

EXPOSE 82
CMD ["nginx", "-g", "daemon off;"]
Copier le Code

Cela donne un nginx Miroir basé sur et un miroir intermédiaire non étiqueté (Doit être supprimé).

UtilisationjenkinsInjenkinsfileUtilisé dansdockerConstruction de commandesdocker Conteneur miroir .

def dateFormat = new SimpleDateFormat("yyyyMMddHHmm")
def dockerTag = dateFormat.format(new Date())
pipeline {
    agent any
    environment {
        dockerName='documentcontainer'
    }
    stages { 
        stage('Docker build') {
            steps {
                sh 'pwd'
                sh 'ls'
                sh "docker stop ${dockerName} || true"
                sh "docker rm -f ${dockerName} || true"
                sh "docker build -t  ${dockerName}:${dockerTag} ."
                sh "docker rmi $(docker images -f dangling=true -q | sed -n  '3,$p' | awk '{print $0}') --force || true"
                sh "docker run -it -p 82:82 -d --name ${dockerName} ${dockerName}:${dockerTag}"
                //only retain last 3 images
                sh "docker rmi $(docker images | grep ${dockerName} | sed -n  '4,$p' | awk '{print $3}') --force || true"
            }
        }
    }
    post{
        success{
            echo "========pipeline executed successfully ========"
        }
        failure{
            echo "========pipeline execution failed========"
        }
    }
}
Copier le Code

De cette façon, nous avons réalisé l'intégration continue et le déploiement continu , Mais il a fallu trop de temps pour construire le miroir , Pensez à l'optimisation .

Comment optimiser, Rendre la construction du miroir plus efficace

Lors de la construction du miroir, Souvent, les miroirs sont trop volumineux 、 Problème de construction d'images trop longues , Comment optimiser? ?

RÉFÉRENCES:Comment utiliser docker Déploiement des applications frontales

  • dependencies Et devDependencies

Utilisation dans un environnement de production npm install --production Emballage

  • Utiliser le cache miroir
...
WORKDIR /code
ADD package.json /code //package.json  Miroir d'écriture séparé du fichier source 
RUN npm install --registry=https://registry.npm.taobao.org  --production 
ADD . /code
RUN npm run build
...
Copier le Code
  • Construction en plusieurs étapes

À propos de la taille excessive du miroir , En grande partie parce que node_modules Volume notoire .

Peut être utilisé Docker Construction en plusieurs étapes de , Pour extraire uniquement les fichiers post - compilés .

Docker Compose

Si notre projet a besoin d'un service d'arrière - plan 、mongoBase de données, Nous devons écrire beaucoup docker Commande pour construire des conteneurs miroirs individuels ,Nous pouvons utiliserDocker Compose Aidez - nous à gérer plusieurs DockerConteneur, Il suffit d'une simple commande pour construire et démarrer des conteneurs miroirs individuels .

Docker Compose Via un profil docker-compose.yml Pour gérer plusieurs DockerConteneur,docker-compose.yml Décrit les propriétés de plusieurs conteneurs .

version: '3.2'
services:
  mongodb:
    image: mongo
    build:
      context: ./
      dockerfile: mongo-Dockerfile
    restart: always
    ports:
      - '27017:27017'
    volumes:
      - /usr/local/egg-app/mongo/backup/o45:/mongo/backup/o45
      - /usr/local/egg-app/mongo/data/db:/data/db
  server:
    image: egg-server
    volumes:
      - /usr/local/egg-app/run:/egg-app/run
      - /usr/local/egg-app/logs/server:/root/logs/server
    build: ./
    restart: always
    depends_on:
      - mongodb
    links:
      - mongodb
    ports:
      - '7001:7001'
Copier le Code
  • docker-compose Commandes de base

Fermer le contenant docker-compose stop || true;

Supprimer le conteneur docker-compose down || true;

Construire un miroir docker-compose build;

Démarrer et exécuter en arrière - plan docker-compose up -d;

Problèmes rencontrés

1、 Le Service d'arrière - plan n'a pas pu se connecter à la base de données

① Mettre l'arrière dockerfileÀ l'intérieur.RUN npm run start Lire comme suit:CMD  npm run start

  • RUN Oui. docker buildExécution à l'heure

  • CMD Indocker run Exécution à l'heure. Par conséquent, le Service d'arrière - plan devrait être dans le conteneur de base de données build Démarrer après la construction

②mongooseConnexionurl

 mongoose: {
      client: {
        url: 'mongodb://root:123456@172.27.24.217:27017/o45?authSource=admin&readPreference=primary&appname=MongoDB%20Compass&directConnection=true&ssl=false',// Lorsqu'il y a un mot de passe de compte 
        options: {
          useNewUrlParser: true,
          useUnifiedTopology: true,//warning
        },
      },
    },
Copier le Code

2、 Le conteneur de service d'arrière - plan n'a pas démarré depuis le début

Raisons:egg-scripts start Passer à la réception

Commande de démarrage

$ egg-scripts start --port=7001 --daemon --title=egg-server-showcase
Copier le Code

Exemple ci - dessus , Les paramètres suivants sont pris en charge :

  • --port=7001 Numéro de port, Les variables d'environnement sont lues par défaut process.env.PORT, Si elle n'est pas transmise, le port intégré du cadre sera utilisé. 7001.
  • --daemon Autoriser en mode arrière - plan ,Pas besoin. nohup.Si utilisé Docker Fonctionnement direct de la réception recommandé .

版权声明
本文为[Poisson cuit à la vapeur avec sauce soja]所创,转载请带上原文链接,感谢
https://cdmana.com/2021/09/20210915195323549H.html

Scroll to Top