Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to implement CICD with jenkins and gitlab

2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)06/03 Report--

Core concepts of CICD

CICD is the abbreviation of continuous integration (continuous integration,CI), continuous delivery (continuous delivery,CD), continuous deployment (continuous Deployment,CD).

Refers to the automatic execution of a series of scripts in the development process to reduce the probability of development introducing bug, and minimize human intervention in the process of new code from development to deployment.

1. Continuous integration

Continuous integration refers to the frequent (multiple times a day) integration of code into the trunk.

It has two benefits:

1) quickly find errors: every time a little update is completed, it is integrated into the backbone, which can quickly find errors, and it is easier to locate errors.

2) prevent branches from deviating significantly from the trunk: if it is not often integrated and the backbone is constantly updated, it will become more difficult or even difficult to integrate in the future.

The purpose of continuous integration:

To enable the product to iterate quickly while maintaining high quality, its core measure is that before the code is integrated into the backbone, it must pass automated testing, and as long as one test case fails, it cannot be integrated.

Martin Fowler said, "continuous integration does not eliminate Bug, but makes them very easy to find and correct."

2, continuous delivery

Continuous delivery refers to the frequent delivery of new versions of software to quality teams or users for review, and if the review passes, the code enters the production phase.

Continuous delivery can be seen as the next step in continuous integration, emphasizing that software can be delivered anytime, anywhere, no matter how it is updated.

3. Continuous deployment

Continuous deployment is the next step in continuous delivery, which means that the code is automatically deployed to the production environment after it has been reviewed.

The goal of continuous deployment is that the code can be deployed at any time and can go into production.

The premise of continuous deployment is to automate the testing, build, deployment and other steps.

For the difference between continuous deployment and continuous delivery, please refer to the following figure:

The idea of CICD implementation of Docker,kubernetes

Jenkins is a popular continuous integration tool.

GitLab is the image repository where images are stored.

Details of the process:

The client pushes the code push to the git repository, and something configured with a webHook on the gitlab can trigger the build of the Jenkins. Within the scope of the Jenkins dotted line, it does a lot of things. Build the code from mvn, conduct static analysis of the code, and do unit tests. After passing the test, you can build the image. After the image is successfully built, the image push is pushed to the Harbor image warehouse. After the image push is pushed to the image warehouse, we can call the restAPI update service of the kubernetes cluster, and then the kubernetes receives the update instruction to pull the image from the Harbor image repository pull. In order to complete the update and restart of the service, finally we access the service of the kubernetes cluster from the client.

Project practice

Project environment:

Host operating system ip address k8s01 (master) Centos 7.3172.16.1.30k8s02 (node01) Centos 7.3172.16.1.31k8s03 (node02) Centos 7.3172.16.1.32jenkins+gitlab+dockerCentos 7.3172.16.1.33 project implementation:

The installation packages and plug-ins used in this article have been uploaded to Baidu online disk: link: https://pan.baidu.com/s/17mDLgSZ218a-zYhjYddhiA

Extraction code: nyxh

1. Deploy the kubernetes cluster (the first three hosts):

To deploy a kubernetes cluster, please refer to the blog kubeadm to deploy a kubernetes cluster.

# ensure the normal operation of the k8s cluster: [root@master ~] # kubectl get nodes NAME STATUS ROLES AGE VERSIONmaster Ready master 112d v1.15.0node01 Ready 112d v1.15.0node02 Ready 112d v1.15.02, deploy harbor private warehouse in the cluster * *

You can choose any server, and here you choose master as the harboar private repository. For more information on configuration, please see blog kubernetes to deploy Harbor private repository.

[root@master ~] # yum- y install yum-utils device-mapper-persistent-data lvm2 [root@master ~] # curl-L https://github.com/docker/compose/releases/download/1.25.0-rc4/docker-compose-`uname-s`-`uname-m`-o / usr/local/bin/docker-compose [root@master ~] # chmod + x / usr/local/bin/docker-compose [root@master harbor] # wget https://storage.googleapis.com/harbor-releases/ Release-1.7.0/harbor-offline-installer-v1.7.4.tgz [root@master harbor] # tar xf harbor-offline-installer-v1.7.4.tgz [root@master harbor] # cd harbor/ [root@master harbor] # vim harbor.cfg

[root@master harbor] #. / install.sh # execute the installation script [Step 4]: starting Harbor... Creating network "harbor_harbor" with the default driverCreating harbor-log. DoneCreating redis... DoneCreating registryctl... DoneCreating harbor-adminserver... DoneCreating harbor-db... DoneCreating registry... DoneCreating harbor-core... DoneCreating harbor-portal... DoneCreating harbor-jobservice... DoneCreating nginx... Done ✔-Harbor has been installed and started successfully.----Now you should be able to visit the admin portal at http://172.16.1.30. For more details, please visit https://github.com/goharbor/harbor.

# Log in to the web interface to create a new warehouse and URL: http://172.16.1.30

Default user name: admin password: Harbor12345

# modify the docker configuration file (and restart docker) and log in to harbor: (three nodes in the cluster do the same)

[root@master harbor] # vim / usr/lib/systemd/system/docker.service

[root@master harbor] # systemctl daemon-reload [root@master harbor] # systemctl restart docker [root@master harbor] # docker login-uadmin-pHarbor12345 172.16.1.30:80WARNING! Using-- password via the CLI is insecure. Use-password-stdin.WARNING! Your password will be stored unencrypted in / root/.docker/config.json.Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-storeLogin Succeeded#node01 and node02 operations are the same as above (both need to log in to harbor)

# upload the image to the private repository on the harbor server (master):

[root@master harbor] # docker pull nginx:latest [root@master harbor] # docker tag nginx:latest 172.16.1.30:80/cicd/nginx:v1.0 [root@master harbor] # docker push 172.16.1.30:80/cicd/nginx:v1.0 The push refers to repository [172.16.1.30:80/cicd/nginx] 12fdf55172df: Pushed 002a63507c1c: Pushed 1c95c77433e8: Pushed v1.0: digest: sha256:099019968725f0fc12c4b69b289a347ae74cc56da0f0ef56e8eb8e0134fc7911 size: 948

# create an authentication login key to ensure that kubernetes can pull private images in the harbor repository:

[root@master harbor] # kubectl create secret docker-registry login-- docker-server=172.16.1.30:80-- docker-username=admin-- docker-password=Harbor12345secret/login created [root@master harbor] # kubectl get secrets NAME TYPE DATA AGEdefault-token-wswg2 kubernetes.io/service-account-token 3 113dlogin kubernetes.io/dockerconfigjson 1 33s

# Select a node in the cluster to test whether the image can be pulled from the Harbor private repository:

[root@node01 ~] # docker pull 172.16.1.30:80/cicd/nginx:v1.0v1.0: Pulling from cicd/nginx1ab2bdfe9778: Pull complete a17e64cfe253: Pull complete e1288088c7a8: Pull complete 7ee7d3fe92e1: Pull complete Digest: sha256:763562fbc544806c1305304da23d36d0532f082325a1c427996474e304313801Status: Downloaded newer image for 172.16.1.30:80/cicd/nginx:v1.0 [root@node01 ~] # docker images | grep "172.16.1.30" 172.16.1.30:80/cicd/nginx v1.0 c6ad7233ab97 10 minutes ago 126MB

Ok, certifying that kubernetes and Harbor private repositories have been deployed. Next, deploy jenkins+gitlab and configure the linkage.

3. Deploy jenkins+gitlab

# operate on the last host 172.16.1.33.

1), basic environmental preparation

# disable the firewall:

[root@docker-cicd ~] # systemctl stop firewalld [root@docker-cicd ~] # systemctl status firewalld ● firewalld.service-firewalld-dynamic firewall daemon Loaded: loaded (/ usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled) Active: inactive (dead) Docs: man:firewalld (1)

# disable selinux:

[root@docker-cicd ~] # vim / etc/sysconfig/selinux

2) deploy jenkins service

[root@docker-cicd ~] # mkdir CICD [root@docker-cicd ~] # cd CICD/ [root@docker-cicd CICD] # tar zxf jdk-8u131-linux-x64.tar.gz [root@docker-cicd CICD] # mv jdk1.8.0_131/ / usr/java# set global variable: [root@docker-cicd CICD] # vim / etc/profile add the following configuration item at the end: export JAVA_HOME=/usr/javaexport JRE_HOME=/usr/java/jreexport PATH=$JAVA_ HOME/bin:$JRE_HOME/bin:$PATHexport CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/ dt.jar [root @ docker-cicd CICD] # source / etc/profile # make its environment variable effective [root@docker-cicd CICD] # java-version # verify the java environment java version "1.8.0mm 131" Java (TM) SE Runtime Environment (build 1.8.0_131-b11) Java HotSpot (TM) 64-Bit Server VM (build 25.131-b11) Mixed mode) # install tomcat [root @ docker-cicd CICD] # tar zxf apache-tomcat-7.0.54.ta [root@docker-cicd CICD] # mv apache-tomcat-7.0.54 / usr/tomcat7 [root@docker-cicd CICD] # cd / usr/tomcat7/webapps/ [root@docker-cicd webapps] # lsdocs examples host-manager manager ROOT [root@docker-cicd webapps] # rm-rf * # Delete the original files of the tomcat web page directory # upload the jenkins war package to [root@docker-cicd webapps] # ls jenkins.war# modifies the tomcat character set under tomcat's web page root directory: [root@docker-cicd webapps] # vim / usr/tomcat7/conf/server.xml

# define the home directory of jenkins in tomcat (/ data/jenkins) [root@docker-cicd webapps] # vim / usr/tomcat7/bin/catalina.sh export CATALINA_OPTS= "- DJENKINS_HOME=/data/jenkins" export JENKINS_JAVA_OPTIONS= "- Djava.awt.headless=true-Dhudson.ClassicPluginStrategy.noBytecodeTransformer=true"

# start tomcat (that is, start jenkins)

[root@docker-cicd webapps] # / usr/tomcat7/bin/catalina.sh startUsing CATALINA_BASE: / usr/tomcat7Using CATALINA_HOME: / usr/tomcat7Using CATALINA_TMPDIR: / usr/tomcat7/tempUsing JRE_HOME: / usr/java/jreUsing CLASSPATH: / usr/tomcat7/bin/bootstrap.jar:/usr/tomcat7/bin/tomcat-juli.jarTomcat started. [root@docker-cicd webapps] # ss-anput | grep 8080tcp LISTEN 0 100 : 8080:: * users: ("java" Pid=41682,fd=46))

# Log in to the jenkins web interface by browser, and configure and install jenkins in the web interface

URL: http://172.16.1.33:8080/jenkins

[root@docker-cicd webapps] # cat / data/jenkins/secrets/initialAdminPassword36ceb6eeb1bc46af8ce20935b81d8fe8

After pasting the administrator password, click continue.

# automatic installation on the left and custom installation on the right. We choose to install the recommended plug-ins.

Select offline installation. If you fail to disconnect the network, click continue.

The login interface is as follows:

# install the necessary plug-ins

1) first install Chinese plug-ins: system Administration-> plug-in Management-> avalilable (optional), and then search for localization-zh-cn

After the installation is successful, restart jenkins and you can find that the interface already supports Chinese:

# need to install 3 more plug-ins, search for gitlab installation: Gitlab Authentication, GitLab, Gitlab Hook

The installation process may be slow. Wait patiently.

After the plug-in is downloaded successfully, check the option to restart jenkins:

If the download is not successful due to network problems, you can also upload the plug-in in the server directory: / var/lib/jenkins/plugins this directory is where all installed plug-ins are stored. (the plug-in has been uploaded to the network disk)

3) deploy gitlab service

[root@docker-cicd CICD] # rpm-ivh gitlab-ce-11.9.8-ce.0.el6.x86_64.rpm warning: gitlab-ce-11.9.8-ce.0.el6.x86_64.rpm: Header V4 RSA/SHA1 Signature, key ID f27eab47: NOKEYPreparing... # # [100%] Updating / installing... 1:gitlab-ce-11.9.8-ce.0.el6 # # [100%]

# to resolve port conflicts, modify the gitlab configuration file:

[root@docker-cicd CICD] # vim / etc/gitlab/gitlab.rb

Since dns is not deployed, url is changed to native ip,80, which defaults to the port of http service, and unicorn ['port'] defaults to 8080, which also conflicts with the above jenkins8080 port, so it is modified to 81 and 8081 respectively.

# initialize and launch gitlab: [root @ docker-cicd CICD] # gitlab-ctl reconfigure# confirm that port 81 listens normally: [root@docker-cicd CICD] # netstat-anput | grep-w 81 tcp 0 0 0.0 0 gitlab-ctl reconfigure# 81 0 0 0. 0. 0. 0.

# the browser logs in to gitlab and configures it in the web interface

URL: http://172.16.1.33:81/

After logging in to gitlab, you need to set a password before logging in. Here, set 1234.com (at least 8 digits to meet the password complexity requirement). The user defaults to root.

# configure ssh key authentication:

The linkage of deploying jenkins and gitlab services needs to be verified by ssh.

First bind the ssh public key of the jenkins server on gitlab (bind your own public key because it is deployed on the same server)

[root@docker-cicd ~] # ssh-keygen-t rsa [root@docker-cicd ~] # cat / root/.ssh/id_rsa.pub ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDW7s9qm08DaiShtnjBbUUwOpFYmvYaqUuqrIrXHrvcGGQDlte6Ug0R7/K5Igz4HKsjZIFCCblzgH2VLIk6FM0L+eccKnW8/uSywQcKclgK3gqiTRBDiqSt4NqYQz1R8hEW3KbXkXXUIU8kJ3svehxzG0Y8lUrMy7zEhkJ6vod7z5wcJeayzVfkro6Xd4TMiRrasXilApRiIr1Sr9Z9dWgWQkCCM85pQeZZirsZ/w4fT6gwRpP1kTtRBggDnXGi7lfWkMbKYljKMuG4jp92K8mRBLyjsg6Lkq0hkKAOToftwmpCx8CA/05LhMexvDnJXyFg/o+8yG+o0qmrlSvojl+N root@docker-cicd

Copy the public key, then log in to gitlab, and click the settings in the upper right corner:

# create a code repository on gitlab:

Enter the name of a warehouse and select the public (public), and then click create:

Click create a new.file:

After the creation is complete, test locally whether you can pull the files in the warehouse:

[root@docker-cicd ~] # git clone git@172.16.1.33:root/my-test-project.git

[root@docker-cicd ~] # cd my-test-project/ [root@docker-cicd my-test-project] # lsindex.html [root@docker-cicd my-test-project] # cat index.html print: "hello worldview!"

4) configure jenkins and gitlab linkage

The URL link:

# perform the build operation:

#! / bin/bash # define variables (directory where data is stored) backupcode= "/ data/backcode/$JOB_NAME/$BUILD_NUMBER" # create this directory mkdir-p $backupcode # permissions required to set workspace/ under jenkins home directory (/ data/jenkins) chmod 644 "$JENKINS_HOME" / workspace/ "$JOB_NAME" / * # use the rsync tool to copy and synchronize data rsync-acP "$JENKINS_HOME "/ workspace/" $JOB_NAME "/ * $backupcode# the following operation is to write a Dockerfile file (copy the modified content to the new image) echo FROM 172.16.1.30:80/cicd/nginx:v1.0 >" $JENKINS_HOME "/ workspace/Dockerfile# source image uses the private repository image echo COPY. /" $JOB_NAME "/ * / usr/share/nginx/html/ > >" $JENKINS_HOME "/ workspace/Dockerfile# to delete the old image. Version of the image (because of the existence will continue to build) docker rmi 172.16.1.30:80/cicd/nginx:v2.0# uses docker build to build a new version of the image through the dockerfile docker build-t 172.16.1.30:80/cicd/nginx:v2.0 / "$JENKINS_HOME" / workspace/.# to docker push 172.16.1.30:80/cicd/nginx:v2 the newly generated new image to the private repository Delete the previous version of deployment resource (nginx application) ssh root@172.16.1.30 kubectl delete deployment nginx# to recreate the nginx application (the image pulled from the repository this time is a newly generated image) ssh root@172.16.1.30 kubectl apply-f / root/yaml/nginx.yaml Note: / root/yaml/nginx.yaml this path is custom Later, you need to create a YAML file for nginx in this directory (the path remains the same, otherwise it will cause the build to fail)

What is written in this is the shell script that will be executed when jenkins is built. This script is the core of continuous integration, which implements the operation of the lower end kubernetes to update the container automatically.

Note: the content defined in the script has to be defined according to your current environment (such as host address, private warehouse image and file storage path are all different). It is easy to script and can be modified according to your own needs.

# Don't save it after writing the script. The following plug-in is very important, that is, it automatically updates the webhook plug-in. First, copy the jenkins URL address of the following figure, and then bind the webhook to the gitlab:

Click Save after copying url:

# # Log in to github to operate

After clicking add, you can see an error message: by default, gitlab does not allow webhook to be sent to itself (because we are deployed on a server), as shown in the following figure:

# # modify the global configuration and check allow local requests to be sent:

# after the modification is successful, add web hook again:

# after the addition is completed, a section will appear to test the connection:

It is proved that the linkage between jenkins and gitlab is successful.

# if the following error message appears when adding webhook, you need to enable anonymous access in "Global Security configuration" on jenkins, and then add it again. The error message is shown below:

5) configure jenkins secret-free login to kubernetes cluster

The purpose of configuring secret-free login is to be able to execute the YAML file in master at build time.

# copy the key pair on the jenkins host to the master node to enable secret-free login to the master in the cluster: [root@docker-cicd ~] # ssh-copy-id root@172.16.1.30

At this point, the integration environment is deployed, and then the test is carried out.

5. Test the deployment environment

Creating new code, deleting code, and modifying code on gitlab will trigger webhook to deploy automatically. It will eventually work in all nginx containers, that is, our web server.

# first log in the jenkins and gitlab hosts to the harbor private warehouse:

1) install docker:

[root@docker-cicd ~] # cd / etc/yum.repos.d/ [root@docker-cicd yum.repos.d] # wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo[root@docker-cicd yum.repos.d] # yum repolist # View available repo sources [root@docker-cicd yum.repos.d] # yum-y install docker-ce [root@docker-cicd yum.repos.d] # systemctl start docker [root@docker- Cicd yum.repos.d] # systemctl enable docker [root@docker-cicd yum.repos.d] # docker- vDocker version 19.03.6 Build 369ce74a3c

2) modify the docker configuration file:

[root@docker-cicd yum.repos.d] # vim / usr/lib/systemd/system/docker.service

# reload docker service: [root@docker-cicd yum.repos.d] # systemctl daemon-reload [root@docker-cicd yum.repos.d] # systemctl restart docker

3) Log in to the harbor repository:

[root@docker-cicd ~] # docker login-uadmin-pHarbor12345 172.16.1.30:80WARNING! Using-- password via the CLI is insecure. Use-password-stdin.WARNING! Your password will be stored unencrypted in / root/.docker/config.json.Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-storeLogin Succeeded

4) create the YAML file of the nginx application defined in the shell script on master (deploy the web service):

[root@master ~] # mkdir yaml [root@master ~] # cd yaml/ [root@master yaml] # vim nginx.yaml apiVersion: extensions/v1beta1kind: Deploymentmetadata: name: nginxspec: replicas: 2 # define two copies template: metadata: labels: web: nginxspec: containers:-name: nginx image: 172.16.1.30:80/cicd/nginx:v2.0 # Image specified private Images in the repository (Note: the version is a newly built version on jenkins) imagePullPolicy: Always # defines the mirror policy (each time a pod is created Always re-pull the image from the repository) ports:-containerPort: 80 imagePullSecrets: # add the imagePullSecrets field, specify the login key you just created (login)-name: login---apiVersion: v1 # create the service resource (map web port is 31234) kind: Servicemetadata: name: nginx-svcspec: type: NodePort ports:-port: 80 targetPort: 80 nodePort: 31234 selector: web: nginx

# modify or create new code on gitlab (for example, modify the previously created index.html file)

# after clicking submit, webhook will be triggered to build:

The details of the construction process are displayed in the console output. If there is a problem during the construction process, you can also accurately view it in the information, as shown in the following figure:

# browsers access web service (nginx) and URL: http://172.16.1.30:31234

# modify the code on gitlab:

/ / modify content: hello world, This is two build

Trigger webhook again and rebuild:

# access the nginx service again through the browser:

# modify the code on gitlab for the third time:

/ / modify the code as: hello world, This is three build

# access nginx again through the browser:

# View the projects and files built above locally on the server:

[root@docker-cicd ~] # cd / data/ [root@docker-cicd data] # ls backcode jenkins # backcode created for us the directory where the build project is stored A home directory for jenkins [root@docker-cicd data] # cd backcode/test/ [root@docker-cicd test] # ls # stores the built project 1011 12 3 4 5 6 7 8 9 [root@docker-cicd test] # cat 12/index.html # in the current directory, and the content in the directory is the code hello world that we built. This is three build [root@docker-cicd test] # cd.. / jenkins/workspace/ [root@docker-cicd workspace] # ls Dockerfile test [root@docker-cicd workspace] # cat test/index.html hello world, This is three build# stores the Dcokerfile file and the newly built code in the jenkins home directory

At this point, after the deployment of the CICD project, the web application in Kubernetes will automatically deploy and update the web interface through the automatic construction of jenkins+gitlab without human intervention, reducing the probability of bug in production, waiting time and higher product quality.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Servers

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report