Cette rubrique explique comment utiliser Jenkins pour mettre en place un pipeline automatisé de bout en bout qui construit des images à partir du code source, les pousse vers un dépôt et déploie les applications. Lorsque vous validez du code source dans GitLab, Container Registry construit automatiquement une image, Container Service for Kubernetes (ACK) récupère l'image pour déployer l'application, et une notification d'événement est envoyée à un groupe DingTalk.
Prérequis
-
Git, GitLab et Jenkins sont installés.
RemarqueGitLab nécessite JDK 8. Certains plugins ne peuvent pas s'exécuter sur JDK 11.
Une instance Enterprise Edition d'Alibaba Cloud Container Registry (ACR) a été créée et l'accès public est activé. Pour plus d'informations, consultez les rubriques Créer une instance Enterprise Edition et Configurer l'accès via Internet.
Un cluster Container Service for Kubernetes (ACK) a été créé dans la même région que l'instance ACR. Pour plus d'informations, consultez la rubrique Créer un cluster Kubernetes managé.
Vous avez créé un robot DingTalk et enregistré son URL de webhook ainsi que son jeton secret. Pour plus d'informations, consultez la rubrique Étape 1 : Créer un robot DingTalk.
Pour utiliser la fonctionnalité de chaîne de livraison d'ACR, vous devez mettre à niveau votre instance vers ACR Advanced Edition. Pour plus d'informations, consultez la rubrique Facturation.
Mettre en œuvre le CI des images avec Jenkins
Lorsque vous validez du code source dans GitLab, Container Registry construit automatiquement une image à partir de ce code. Vous pouvez ensuite analyser la sécurité de l'image. Une fois l'analyse terminée, vous recevez automatiquement une notification d'événement dans votre groupe DingTalk.
-
Créez un projet dans GitLab.
Connectez-vous à GitLab.
Dans la barre de navigation supérieure, sélectionnez Projects > Your projects.
Sur la page Projects, cliquez sur New Project dans le coin supérieur droit, puis cliquez sur Create blank project.
-
Sur la page Create blank project, définissez les champs Project name, Project URL et Project slug. Définissez le champ Visibility Level sur Private, puis cliquez sur Create project.
Dans cet exemple, définissez les champs Project name et Project slug sur
java-web. Pour le champ Project URL, sélectionnez shoppingmall comme namespace. -
Sur votre machine locale, créez un fichier Dockerfile, un fichier pom.xml, un fichier DemoApplication.java et un fichier HelloController.java avec le contenu suivant.
-
Dockerfile
FROM registry.cn-hangzhou.aliyuncs.com/public-toolbox/maven:3.8.3-openjdk-8-aliyun AS build COPY src /home/app/src COPY pom.xml /home/app RUN ["/usr/local/bin/mvn-entrypoint.sh","mvn","-f","/home/app/pom.xml","clean","package","-Dmaven.test.skip=true"] FROM registry.cn-hangzhou.aliyuncs.com/public-toolbox/openjdk:8-jdk-alpine COPY --from=build /home/app/target/demo-0.0.1-SNAPSHOT.jar /usr/local/lib/demo-0.0.1-SNAPSHOT.jar EXPOSE 8080 ENTRYPOINT ["java","-jar","/usr/local/lib/demo-0.0.1-SNAPSHOT.jar"] -
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.6.1</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>demo</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.13.2</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build> </project> -
DemoApplication.java
package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import java.util.TimeZone; @SpringBootApplication public class DemoApplication { public static void main(String[] args) { TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai")); SpringApplication.run(DemoApplication.class, args); } } -
HelloController.java
package com.example.demo; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; import java.text.SimpleDateFormat; import java.util.Date; @RestController @Slf4j public class HelloController { @RequestMapping({"/hello", "/"}) public String hello(HttpServletRequest request) { return "Hello World at " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); } }
-
-
Exécutez les commandes suivantes pour envoyer les fichiers de build vers GitLab.
cd java-web # Enter the directory where the build files are located. git remote set-url origin http://8.218.20*.***/shoppingmall/java-web.git git push origin master * [new branch] master -> master
-
Configurez un pipeline dans Jenkins pour construire les images.
-
Configurez la clé SSH GitLab dans Jenkins.
Connectez-vous à Jenkins.
Dans le volet de navigation de gauche, cliquez sur Manage Jenkins.
Dans la section Security, cliquez sur Manage Credentials.
Dans la section Stores scoped to Jenkins, cliquez sur Jenkins dans la colonne Store, puis cliquez sur Global credentials.
Dans le volet de navigation de gauche, cliquez sur Add Credentials.
-
Définissez le champ Kind sur SSH Username with private key, saisissez une Description et un Username, sélectionnez Enter directly, puis cliquez sur OK.
Sur la page Global credentials, Jenkins génère automatiquement un ID d'identifiant. Enregistrez cet ID.
-
Créez un pipeline.
Dans le volet de navigation de gauche, cliquez sur New Item.
Saisissez un nom d'élément, sélectionnez Pipeline, puis cliquez sur OK.
-
Cliquez sur l'onglet Build Triggers, sélectionnez Build when a change is pushed to GitLab, puis sélectionnez Push Events.
Enregistrez l'URL de webhook affichée à droite de Build when a change is pushed to GitLab.
-
Cliquez sur Advanced, puis cliquez sur Generate dans le coin inférieur droit du champ Secret token.
Jenkins génère un jeton secret. Enregistrez ce jeton.
-
Cliquez sur l'onglet Pipeline, modifiez le modèle suivant en fonction de vos informations réelles, collez le contenu dans la zone de texte, puis cliquez sur Save.
def git_auth_id = "6d5a2c06-f0a7-43c8-9b79-37b8c266****" # The credential ID. def git_branch_name = "master" # The branch name. def git_url = "git@172.16.1*.***:shoppingmall/java-web.git" # The GitLab repository URL. def acr_url = "s*****-devsecops-registry.cn-hongkong.cr.aliyuncs.com" # The image repository URL. def acr_username = "acr_test_*****@test.aliyunid.com" # The Container Registry username. def acr_password = "HelloWorld2021" # The Container Registry password. def acr_namespace = "ns" # The namespace. def acr_repo_name = "test" # The repository name. def tag_version = "0.0.1" # The image tag. node { stage('checkout git repo') { checkout([$class: 'GitSCM', branches: [[name: "*/${git_branch_name}"]], extensions: [], userRemoteConfigs: [[credentialsId: "${git_auth_id}", url: "${git_url}"]]]) } stage('build image') { sh "sudo docker build -t java-web:${tag_version} ." sh "sudo docker tag java-web:${tag_version} ${acr_url}/${acr_namespace}/${acr_repo_name}:${tag_version}" } stage('push image') { sh "sudo docker login --username=${acr_username} --password=${acr_password} ${acr_url}" sh "sudo docker push ${acr_url}/${acr_namespace}/${acr_repo_name}:${tag_version}" } }
-
-
Ajoutez l'URL de webhook à GitLab.
Connectez-vous à GitLab.
Sur la page Projects, cliquez sur le projet que vous avez créé.
Dans le volet de navigation de gauche, sélectionnez Settings > Webhooks. Saisissez l'URL de webhook et le jeton secret, désélectionnez Enable SSL verification, puis cliquez sur Add webhooks.
-
Créez une notification d'événement.
Connectez-vous à la console Container Registry.
Dans la barre de navigation supérieure, sélectionnez une région.
Dans le volet de navigation de gauche, cliquez sur Instances.
Sur la page Instances, cliquez sur l'instance Enterprise Edition que vous souhaitez gérer.
Dans le volet de navigation de gauche de la page des détails de l'instance, sélectionnez .
Sur l'onglet Event Rules, cliquez sur Create Rule.
À l'étape Event Scope, définissez le champ Rule Name. Définissez le champ Event Type sur The image is scanned., sélectionnez Scanned., définissez le champ Effective Scope sur Namespaces, sélectionnez ns comme namespace, puis cliquez sur Next.
À l'étape Event Notification, définissez le champ Notification Method sur DingTalk, saisissez l'URL de webhook et le jeton secret pour DingTalk, puis cliquez sur Save.
-
Déclenchez la construction d'une image.
Exécutez les commandes suivantes pour modifier le fichier HelloController.java et le valider dans GitLab. Cela déclenche la construction d'une image.
vim java/com/example/demo/HelloController.java # Modify the HelloController.java file on your local machine based on your needs. git add . && git commit -m 'commit' && git push origin # Commit the file to GitLab.Après quelques instants, sur la page des détails de l'instance Enterprise Edition, sélectionnez dans le volet de navigation de gauche. Sur la page qui s'affiche, cliquez sur le dépôt cible
test. Dans le volet de navigation de gauche de la page Repository, cliquez sur Tags. Vous constatez qu'une image a été générée sur la page Tags. -
Configurez une analyse de sécurité.
Sur la page Tags, recherchez le tag d'image cible et cliquez sur Security Scan dans la colonne Actions.
-
Sur la page Security Scan, cliquez sur Scan.
Une fois l'analyse de sécurité terminée, vous recevrez une notification dans votre groupe DingTalk.
Mettre en œuvre le CD des images avec Jenkins
La construction automatique de l'image déclenche une chaîne de livraison. Une fois terminée, la chaîne de livraison envoie une requête HTTP à Jenkins. Cette requête déclenche le Deployment dans ACK pour récupérer la dernière image et redéployer l'application.
-
Créez une application.
Connectez-vous à la console de gestion Container Service.
Dans le volet de navigation de gauche, cliquez sur Cluster.
Sur la page Cluster List, cliquez sur le nom du cluster de destination ou cliquez sur Details dans la colonne Actions.
Dans le volet de navigation de gauche de la page de gestion du cluster, sélectionnez .
Sur la page Deployments, sélectionnez un Namespace, puis cliquez sur Create from YAML.
-
Dans le panneau Create from YAML, définissez le champ Sample Template sur Custom, collez le contenu suivant dans l'éditeur de modèle, puis cliquez sur Create.
RemarqueSi vous ne configurez pas la récupération d'images sans mot de passe, vous devez activer l'accès public dans Container Registry et définir le dépôt comme public. Pour plus d'informations, consultez la rubrique Configurer l'accès via Internet.
apiVersion: apps/v1 kind: Deployment metadata: creationTimestamp: null labels: app: demo name: demo spec: replicas: 3 minReadySeconds: 5 progressDeadlineSeconds: 60 revisionHistoryLimit: 5 selector: matchLabels: app: demo strategy: rollingUpdate: maxUnavailable: 1 type: RollingUpdate template: metadata: annotations: prometheus.io/port: "9797" prometheus.io/scrape: "true" creationTimestamp: null labels: app: demo spec: containers: - image: s*****-devsecops-registry.cn-hongkong.cr.aliyuncs.com/ns/test:0.0.1 imagePullPolicy: Always name: demo ports: - containerPort: 8080 name: http protocol: TCP readinessProbe: initialDelaySeconds: 5 tcpSocket: port: 8080 timeoutSeconds: 5 resources: limits: cpu: "2" memory: 512Mi requests: cpu: 100m memory: 64Mi status: {} --- apiVersion: v1 kind: Service metadata: name: demo-svc spec: selector: app: demo ports: - protocol: TCP port: 80 targetPort: 8080 --- apiVersion: extensions/v1beta1 kind: Ingress metadata: name: demo labels: app: demo spec: rules: - host: app.demo.example.com http: paths: - backend: serviceName: demo-svc servicePort: 80 --- -
Sur la page Deployments, cliquez sur l'application cible, demo, puis cliquez sur l'onglet Access Method.
Sur l'onglet Access Method, obtenez l'endpoint externe.
-
Ajoutez l'entrée suivante à votre fichier
hostslocal.<External endpoint address> app.demo.example.com -
Dans un navigateur, saisissez app.demo.example.com dans la barre d'adresse.
Hello World 2021 xxx at 2021-12-06 20:51:36La page s'affiche, indiquant que l'application a été déployée avec succès.
-
Créez un déclencheur.
Sur la page Deployments, cliquez sur le nom de l'application cible, demo.
Sur la page des détails de l'application, cliquez sur l'onglet Triggers, puis cliquez sur Create Trigger.
-
Dans la boîte de dialogue Create Trigger, définissez le champ Action sur Redeploy et cliquez sur OK.
Sur l'onglet Triggers, obtenez l'URL du déclencheur.
-
Créez un pipeline.
Connectez-vous à Jenkins.
Dans le volet de navigation de gauche, cliquez sur New Item.
Saisissez un nom d'élément, sélectionnez Pipeline, puis cliquez sur OK.
-
Cliquez sur l'onglet Build Triggers et sélectionnez Generic Webhook Trigger.
Sous Generic Webhook Trigger, l'URL du déclencheur de requête HTTP est au format
JENKINS_URL/generic-webhook-trigger/invoke. Dans cette rubrique, le paramètreGeneric Webhook tokenest défini surhelloworld2021. Par conséquent, l'URL de webhook estJENKINS_URL/generic-webhook-trigger/invoke?token=helloworld2021. -
Cliquez sur l'onglet Pipeline, modifiez le jeton Generic Webhook et l'URL du déclencheur dans le modèle suivant en fonction de vos informations réelles, collez le contenu dans la zone de texte, puis cliquez sur Save.
pipeline { agent any triggers { GenericTrigger( genericVariables: [ [key: 'InstanceId', value: '$.data.InstanceId'], [key: 'RepoNamespaceName', value: '$.data.RepoNamespaceName'], [key: 'RepoName', value: '$.data.RepoName'], [key: 'Tag', value: '$.data.Tag'] ], causeString: 'Triggered on $ref', token: 'helloworld2021', # The Generic Webhook token. Replace it with your actual token. tokenCredentialId: '', printContributedVariables: true, printPostContent: true, silentResponse: false, regexpFilterText: '$ref' ) } stages { stage('Some step') { steps { sh "echo 'will print post content'" sh "echo $InstanceId" sh "echo $RepoNamespaceName" sh "echo $RepoName" sh "echo $Tag" sh "echo 'redeploy to ACK or you can deoloy to other platforms use before message'" sh "curl 'https://cs.console.alibabacloud.com/hook/trigger?token=g****' # The trigger URL. Replace it with your actual URL. sh "echo 'done'" } } } }
Créez une chaîne de livraison. Pour plus d'informations, consultez la rubrique Créer une chaîne de livraison.
-
Créez une règle d'événement.
Dans le volet de navigation de gauche de la page de gestion de l'instance Enterprise Edition, sélectionnez .
Sur l'onglet Event Rules, cliquez sur Create Rule.
À l'étape Event Scope, définissez le champ Rule Name. Définissez le champ Event Type sur The delivery chain is processed., sélectionnez Success, définissez le champ Effective Scope sur Namespaces, sélectionnez ns comme namespace, puis cliquez sur Next.
À l'étape Event Notification, définissez le champ Notification Method sur HTTP, saisissez l'URL de webhook obtenue à l'étape 3, puis cliquez sur Save.
-
Exécutez les commandes suivantes pour modifier le fichier HelloController.java et valider le code dans GitLab. Cela déclenche la construction d'une image.
vim java/com/example/demo/HelloController.java # Modify the HelloController.java file on your local machine based on your needs. git add . && git commit -m 'add update' && git push origin # Commit the file to GitLab.La construction de l'image déclenche la chaîne de livraison. Une fois la chaîne de livraison terminée, elle déclenche le Deployment dans ACK pour récupérer la nouvelle image et redéployer l'application.
-
Exécutez la commande suivante pour vérifier que l'application a été redéployée.
curl app.demo.example.comLa sortie modifiée indique que l'application a été redéployée avec succès.