Jenkinsを学ぶ(継続的インテグレーションと自動デプロイ)

一:継続的インテグレーションの概念:

全体の概要

継続的インテグレーション(Continuous Integration)
継続的デリバリー(Continuous Delivery)
継続的デプロイメント(Continuous Deployment)

二:継続的インテグレーションツールのインストールとデプロイ

1、JDKのインストール

# rpm -ivh jdk-8u111-linux-x64.rpm
# vim /etc/profile
export JAVA_HOME=/usr/java/jdk1.8.0_111 
export PATH=$JAVA_HOME/bin:$PATH

2、Jenkinsのインストール
方法①:yum方式でのインストール

# cd /etc/yum.repos.d/
# wget http://pkg.jenkins.io/redhat/jenkins.repo
# rpm --import http://pkg.jenkins.io/redhat/jenkins.io.key
# yum install -y jenkins
# systemctl start jenkins

方法②:warパッケージ方式でのインストール

# wget http://updates.jenkins-ci.org/download/war/2.60.1/jenkins.war
# unzip apache-tomcat-8.0.37.zip
# mv apache-tomcat-8.0.37 /usr/local/
# cd /usr/local
# ln -s /usr/local/apache-tomcat-8.0.37 /usr/local/tomcat
# useradd jenkins
# chown -R jenkins.jenkins /usr/local/apache-tomcat-8.0.37
# /usr/local/tomcat/bin/startup.sh

3、Webインターフェースを開く:http://192.168.3.199:8080/jenkins

初期パスワードの確認

$ cat /home/jenkins/.jenkins/secrets/initialAdminPassword
8743f91ff1474a85a0abcd841fc74eb6

プラグインを選択し、自動ダウンロードとインストールを実行

ユーザー名とパスワードを設定

メール通知を設定(システム管理→システム設定、管理者メールアドレスを追加、メールを追加)

保存またはメールテストをクリックすると、システムがターゲットメールにテストメールを送信します:

JenkinsのプラグインマネージャーでGitLabプラグインをインストール(システム管理→プラグイン管理→オプションプラグイン)

三:Jenkinsの使用:

3.1:認証ユーザーを追加し、Gitコードをプルするために使用します:

ジョブの作成→フリースタイルソフトウェアプロジェクトを構築

プロジェクトの説明情報:

Gitプロジェクトアドレスを構成し、まず他の構成を行い、後でGit関連のオプションを構成します

システム管理→グローバルツール構成

デプロイキーを構成し、Jenkinsサーバーのrootユーザーでキーペアを生成

# ssh-keygen -t rsa
# cat .ssh/id_rsa.pub 

GitLab上でweb-demoプロジェクトのprivate deploy keyを設定

キーをコピーして、タイトルに分かりやすい名前を付けます

Jenkinsサーバー192.168.3.199で正常にコードを取得できるかテスト

# git clone git@192.168.3.198:web/web-demo.git

Jenkinsがコードをプルできるので、Jenkinsの認証を構成し続けます。ここではプライベートキーを入力する必要があります

JenkinsがGitコードをプルするサーバーのrootのプライベートキーをコピー

# cat .ssh/id_rsa

説明を追加し、OKをクリックして編集を続けます

これでエラーは発生しません。さらに、どのブランチからプルするかを指定できます。デフォルトはmasterブランチからプルしますが、一部の会社ではreleaseブランチを使用しています

ソースコードブラウザで、GitLabでhttpのURLを見つけます:http://192.168.3.198/web/web-demo.git

GitLabのバージョンを見つけ、URLとバージョンを入力します。バージョンは2桁のみサポートされ、最後に保存します

[root@web01 ~]# rpm -qa|grep gitlab
gitlab-ce-8.10.5-ce.0.el7.x86_64

今すぐビルドをクリックし、コンソールを表示すると、ビルドの詳細出力が見られます

一:Sonarとは?

Sonarはコード品質管理のためのオープンプラットフォームであり、プラグインメカニズムを通じて、Sonarは異なるテストツール、コード分析ツール、および継続的インテグレーションツールを統合できます。Hudson/Jenkinsなどの継続的インテグレーションツールとは異なり、Sonarは単に異なるコードチェックツールの結果(たとえばFindBugs、PMDなど)をWebページに直接表示するのではなく、これらの結果をさらに処理し、定量的な方法でコード品質の変化を測定することで、異なる規模や種類のプロジェクトのコード品質管理を簡単に行うことができます。他のツールのサポートに関しては、SonarはIDEのサポートを提供しており、EclipseやIntelliJ IDEAなどのツールでオンラインで結果を表示できます。同時に、Sonarは多くの継続的インテグレーションツールのインターフェースサポートも提供しており、継続的インテグレーションでSonarを簡単に使用できます。さらに、SonarのプラグインはJava以外のプログラミング言語にもサポートを提供し、国際化やレポートのドキュメント化にも良好なサポートがあります。

#公式サイト:http://www.sonarqube.org/

Sonarのデプロイ

Sonarの関連ダウンロードとドキュメントは、以下のリンクで見つけることができます:http://www.sonarqube.org/downloads/。最新バージョンのSonarは少なくともJDK 1.8以上が必要であることに注意してください

# cd /usr/local/src/
# wget https://sonarsource.bintray.com/Distribution/sonarqube/sonarqube-5.6.6.zip
# unzip sonarqube-5.6.6.zip 
# mv sonarqube-5.6.6 /usr/local/
# ln -s /usr/local/sonarqube-5.6.6/ /usr/local/sonarqube

Sonarデータベースの準備(mysqlバージョンは5.6以上である必要があります。そうでないとsonarは起動しません)

mysql> CREATE DATABASE sonar CHARACTER SET utf8 COLLATE utf8_general_ci;
mysql> GRANT ALL ON sonar.* TO 'sonar'@'%' IDENTIFIED BY 'sonar@341Jpw';
mysql> FLUSH PRIVILEGES;

Sonarの構成

# cd /usr/local/sonarqube/conf/

構成ファイルのデータベース構成を変更

# egrep '^[a-Z]' sonar.properties 
sonar.jdbc.username=sonar
sonar.jdbc.password=sonar@pw
sonar.jdbc.url=jdbc:mysql://localhost:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance

Sonarを起動します。デフォルトは9000ポートです。

# vim sonar.properties
sonar.web.host=0.0.0.0
sonar.web.port=9000

#起動にはテーブルの作成やその他の操作が必要で、少し時間がかかります

# /usr/local/sonarqube/bin/linux-x86-64/sonar.sh start

ログイン:http://192.168.3.199:9000/、アカウントとパスワードはデフォルトでadminです

次に、構成と使用の段階に入ります。

二:Sonarの構成と使用

2.1:プラグインのインストール:

2.1.1:デフォルトのプラグインディレクトリ:

# ll /usr/local/sonarqube-5.6.6/extensions/plugins/

#オンラインでプラグインのインストールが失敗した場合は、プラグインをダウンロードしてこのディレクトリに配置し、Sonarサービスを再起動してプラグインを有効にすることができます。Jenkinsもこの方法でインストールできます。

2.1.2:プラグインのインストール:
administration-system-update center-availableで、検索ボックスにプラグイン名を検索し、installをクリックしてインストール:

または、プラグインディレクトリ/usr/local/sonarqube/extensions/pluginsで
wget https://github.com/SonarQubeCommunity/sonar-l10n-zh/releases/download/sonar-l10n-zh-plugin-1.11/sonar-l10n-zh-plugin-1.11.jar(中国語プラグイン:)を実行し、サービスを再起動:

# /usr/local/sonarqube/bin/linux-x86-64/sonar.sh restart

Sonarプラグインのダウンロードアドレス:
https://sonarsource.bintray.com/Distribution/

主なのは、Sonarによるコード分析はプラグインを通じて行われることです。つまり、Javaコードを分析するにはJavaプラグインをインストールし、PHPコードを分析するにはPHPプラグインをインストールし、分析する言語に応じて対応する言語のプラグインをインストールします
今回はPHP、Python、Java構文チェックプラグインをインストールしました

# ll /usr/local/sonarqube/extensions/plugins
-rw-r--r-- 1 root root 128 Feb 16 18:19 README.txt
-rw-r--r-- 1 root root 4840602 Jul 4 17:05 sonar-java-plugin-4.11.0.10660.jar
-rw-r--r-- 1 root root 3733262 Jul 4 17:05 sonar-php-plugin-2.10.0.2087.jar
-rw-r--r-- 1 root root 4024311 Jul 4 17:05 sonar-python-plugin-1.8.0.1496.jar

2.1.3:コードチェックテスト、sonar-scannerとsonarqubeを関連付けます

sonar-scannerのダウンロードアドレス:https://sonarsource.bintray.com/Distribution/sonar-scanner-cli/

# cd /usr/local/src
# wget https://sonarsource.bintray.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-3.0.3.778-linux.zip
# unzip sonar-scanner-2.6.1.zip 
# mv sonar-scanner-2.6.1 /usr/local/
# cd /usr/local/
# ln -s sonar-scanner-2.6.1 sonar-scanner

sonar-scannerの構成:

# vim /usr/local/sonar-scanner/conf/sonar-scanner.properties
sonar.host.url=http://localhost:9000
sonar.sourceEncoding=UTF-8
sonar.jdbc.username=sonar
sonar.jdbc.password=sonar@341Jpw
sonar.jdbc.url=jdbc:mysql://192.168.3.12:3306/sonar?useUnicode=true&characterEncoding=utf8

PHPプロジェクトをチェックするには、SonarでまずSonarPHPプラグインをインストールする必要があります。githubでphp-sonar-runnerプロジェクトを検索し、このプロジェクトをチェックします
https://github.com/hasanyousuf/php-sonar-runner-unit-tests

# unzip php-sonar-runner-unit-tests-master.zip
# cd php-sonar-runner-unit-tests-master
# ls /root/php-sonar-runner-unit-tests-master

#phpディレクトリで直接sonar-scannerを実行して、コード品質分析を実現します

# cd root/php-sonar-runner-unit-tests-master
# /usr/local/sonar-scanner/bin/sonar-scanner

Sonar管理インターフェースでスキャン結果を表示:
dashboard→homeでプロジェクト名をクリックすると、より詳細な情報を表示できます

2.1.4:コードルール:

2.4:Jenkinsをsonar scannerに関連付ける方法は?
構成ファイルを2つの方法で保存できます。1つはプロジェクト内に保存し、もう1つはJenkins管理インターフェースで構成します:
2.4.1:JenkinsプラグインインストールインターフェースでSonarQuebe Scanner for Jenkinsプラグインをインストール:

2.4.2 JenkinsをSonarに関連付けます:
Jenkinsで操作:システム管理→システム設定、SonarQube serversセクションを見つけます

Sonarアクセスアドレスを追加して保存をクリック

2.4.3スキャナーを追加:
2.4.3.1:#システム管理→global-tool-ocnfigration→ローカルsonar scannerを追加して保存をクリック

2.5:Jenkinsプロジェクトのビルド操作を構成:

2.5.1:以前のsonar scannerのコードチェック構成ファイルの内容をコピーします。例:

# cat /root/php-sonar-runner-unit-tests-master/sonar-project.properties

sonar.projectKey=org.sonarqube:php-ut-sq-scanner
sonar.projectName=PHP :: PHPUnit :: SonarQube Scanner
sonar.projectVersion=1.0
sonar.sources=src
sonar.tests=tests
sonar.language=php
sonar.sourceEncoding=UTF-8

2.5.1:独自のプロジェクト(web-demo)を選択→ビルドトリガー→ビルド→execute sonarqube scanner、構成ファイルの内容を以下の形式に変更して保存をクリック:

sonar.projectKey=web-demo
sonar.projectName=web-demo
sonar.projectVersion=1.0
sonar.sources=./
sonar.language=php
sonar.sourceEncoding=UTF-8

右側にショートカットが表示されます

2.6:Jenkinsプロジェクトのビルドをテスト:
2.6.1:Jenkinsで独自のプロジェクトを選択し、今すぐビルドをクリックします。以下はビルド成功のインターフェースです:

2.6.2:Sonarでコードスキャン品質分析結果があるかどうかを確認:

2.7:ビルド後の操作を追加
2.7.1:メール通知を追加し、ビルドが失敗した場合に指定されたメールに失敗情報を通知します:
#送信者ボックスの設定:

2.7.2:githubサービスを閉じてからプロジェクトをビルドし、gitサービスにアクセスできないため、プロジェクトのビルドが失敗し、メール通知がトリガーされます:
2.7.2.1:gitサービスを停止:

# gitlab-ctl stop

2.7.2.2:プロジェクトをビルドし、以下はビルド失敗のコンソール出力情報です:

2.7.2.3:以下は失敗したメール通知です:

コードをテスト環境に自動デプロイ

1.1:コードリリース用の新しいプロジェクトweb-demo-deployを作成します。前のプロジェクトweb-demoはコードテストに使用でき、テスト段階で問題が発生した場合、すぐにリリースは行われず、テストが通過した後にのみリリースプロジェクトが実行されます:

1.2:コードをwebサーバーにデプロイする方法:
1.2.1:コマンドまたはスクリプトの実行によってコードをデプロイできます。各webサーバーにwwwユーザーを作成し、webサービスを起動し、コードをデプロイします:

# useradd www
# echo "123456" | passwd --stdin www
# su - www
$ ssh-keygen -t rsa
$ cat .ssh/id_rsa.pub 

1.2.2:gitサーバーでwwwユーザーの公開鍵をデプロイキーに追加し、rootの公開鍵をsshキーに追加し、wwwユーザーがコードを取得する権限を持ち、rootユーザーがコードをコミットする権限を持つようにします:

ssh keysとdeploy keysの違い:

githubアカウントのSSH keysは、このアカウントの最高レベルのキーであり、このアカウントが持つ権限(どのプロジェクトでも)で操作できます。
リポジトリのDeploy keysは、そのリポジトリ専用のキーであり、このキーを使用して、このプロジェクトのみを操作でき、他のプロジェクトには権限がありません。
簡単に言えば、大きな別荘を持っている場合、SSH keyは別荘のどの部屋でも開けます。Deploy keyは別荘の1つの部屋だけを開けることができます。

1.2.4:wwwユーザーがコードをプルする権限があることを確認:

1.3:シェルスクリプトの実行権限について:

後でJenkinsがスクリプトを実行してコードのデプロイを完了しますが、デフォルトの実行ユーザーはjenkinsです。jenkinsに一定の権限を付与する必要があります。また、デプロイスクリプトは本サーバーに保存されている場合とそうでない場合があります。今回は本サーバーに保存されていないものと想定し、以下のように設定します:

1.3.1:スクリプトの実行問題を解決:

スクリプトをwwwユーザーのホームディレクトリ/home/wwwに配置し、gitコードもホームディレクトリに配置するため、jenkinsサーバーがデプロイサーバーにリモートで接続してリモートコマンドを実行する必要があります。jenkinsサーバーのrootとwwwユーザーの公開鍵をデプロイサーバーのwwwユーザーのホームディレクトリ.ssh/authorized_keysファイルに配置し、jenkinsサーバーがパスワードを入力せずにデプロイサーバーのスクリプトを呼び出せるようにします

Jenkinsサーバー:192.168.3.199
デプロイサーバー:192.168.3.12

$ chmod 600 authorized_keys
$ cat authorized_keys
$ cat .ssh/authorized_keys

1.3.2:パスワードなしリモートログインが可能か確認:
rootとwwwユーザーを使用してテストし、デプロイサーバーがユーザーのキーをknow_keysに追加できるようにします。そうでないとHost key verification failedエラーが発生します

# ssh www@192.168.3.12
# ssh www@192.168.3.13

1.3.3:jenkinsの権限問題を解決し、Jenkinsサーバー192.168.3.199で操作:

# vim /etc/sudoers
#Defaults requiretty #コメントアウト、ttyは不要
jenkins ALL=(ALL) NOPASSWD: /usr/bin/ssh

1.3.3:Jenkinsプロジェクトでシェルスクリプトを実行するように構成:
1.3.3.1:スクリプトの内容(デプロイサーバー192.168.3.12の/home/wwwディレクトリに保存する必要があります):

$ vim dep.sh

#!/bin/bash
cd /home/www/web-demo_deploy/ #ローカルコードディレクトリに移動
git pull #gitサーバーからコードを更新
scp -r ./* www@192.168.3.12:/webroot/web_www #コードをwebサーバーにデプロイ
scp -r ./* www@192.168.3.13:/webroot/web_www

1.3.3.2:Jenkinsでスクリプトを呼び出す:
#プロジェクトのビルドステップで呼び出し、プロジェクト→構成→ビルド→ビルドステップを追加→Execute shell

webページにアクセスしてテスト:

gitリポジトリでコードを作成し、gitサーバーに更新:

$ vim index.html # www.chinasoft.comを追加
$ git add index.html 
$ git commit -m 'edit index.html add www.chinasoft.com'

再度Jenkinsでプロジェクトをビルドすると、最新のコードが正常に取得されていることがわかります

1.4:コードテストプロジェクトがコードリリースプロジェクトを管理し、コードテストプロジェクトが正常に実行された後、自動的にコードリリースプロジェクトを呼び出してコードデプロイを完了します:
1.4.1:プラグインをインストールし、Jenkinsのプラグインのデフォルトインストールパス

# ll /var/lib/jenkins/plugins/

tomcatバージョンのインストールパス:

# ll /usr/local/tomcat/webapps/jenkins/WEB-INF/detached-plugins/

プラグインのオンラインインストールが失敗した場合は、プラグインをこのディレクトリにダウンロードして、所有者とグループをjenkinsに変更し、Jenkinsサービスを再起動してインストールを完了できます:
#システム管理-プラグイン管理-オプションプラグイン、Parameterizedを検索:

1.4.2:demoプロジェクトのビルド後の操作を構成し、demoのビルド完了後にdemo-deployプロジェクトを自動的にビルドします:
#jenkins→web-demo→構成→ビルド後の操作:

1.4.3:以下のように構成:

1.5:テスト、コードテストプロジェクトが正常に実行された後、コードデプロイプロジェクトが自動的に実行されるかどうかをテスト:

1.6:pipelineプラグイン:

1.6.1:#プラグインをインストール、システム管理-プラグイン管理-インストール可能なプラグイン:

1.6.2:ビューを作成:

1.6.3:カスタム名:

1.6.4:Pipeline情報を構成し、OKをクリックすると、以下のビューがポップアップします

保存後の最終インターフェース:

GitLabがJenkinsプロジェクトのビルドをトリガー

目的は、会社のテスト環境で開発者がgitlabリポジトリにコードを正常にコミットした場合、gitlabがJenkinsに通知してプロジェクトをビルドし、コード品質テストを実行してテスト環境にデプロイすることですが、これはテスト環境であり、本番環境ではまだ手動でコードをデプロイする必要があります:

1.1:Jenkinsの構成:
1.1.1:Gitlab Hook Pluginプラグインをインストール:
#システム管理-プラグイン管理-オプションプラグイン-Gitlab Hook PluginとBuild Authorization Token Root Plugin

1.1.2:ランダムなtokenを生成:

# openssl rand -hex 12
0f2a47c861133916d2e299e3

1.1.3:プロジェクトトリガーを作成:
#プロジェクト→構成→ビルドトリガー:
http://192.168.3.199:8080/jenkins/project/web-demo

1.2:githubを構成:
1.2.1:gitプロジェクトの構成インターフェースでリンクとtokenを設定:

gitlabにログインし、このプロジェクトでフック構成の場所を見つけます

#プロジェクト→設定→webhooksを選択:
#プラグインの使用説明、https://wiki.jenkins-ci.org/display/JENKINS/Build+Token+Root+Plugin

http://192.168.3.199:8080/jenkins/buildByToken/build?job=web-demo&token=0f2a47c861133916d2e299e3
http://jenkinsサーバーアドレス:8080/buildByToken/build?job=プロジェクト名&token=token値

1.2.2:テスト:

1.2.2:テスト、201が表示されれば成功です

1.3:gitサーバーにコードをコミットし、自動デプロイが可能かどうかを検証:
1.3.1:コードをコミット:

$ git clone git@192.168.3.198:web/web-demo.git
$ echo "Build token root plugin" > index.html 
$ git add 'index.html'
$ git commit -m 'build token root plugin test'

1.3.2:Jenkinsサーバーのログ記録:

# tail -f /usr/local/tomcat/logs/catalina.out

1.3.3:Jenkinsプロジェクトのビルド:

1.3.4:webインターフェースにアクセスして、コードが最新かどうかを検証:

1.3.5:Jenkinsコンソールの出力情報:

Jenkinsとスクリプトを組み合わせてコードの自動デプロイとワンクリックロールバックを実現

この記事では、Jenkinsがシェルスクリプトを呼び出す方法を通じて、Gitサーバーからコードを取得し、パッケージ化し、webサーバーにデプロイし、webサーバーをロードバランサーから削除し、解凍し、構成ファイルをコピーし、シンボリックリンクを作成し、各webサーバーをテストし、webサーバーをロードバランサーに追加し、任意のバージョンにロールバックし、前のバージョンにワンクリックでロールバックするなどの機能を実現します。スクリプトはwwwユーザーのホームディレクトリに配置され、wwwユーザーとして実行され、各webサーバーもwwwユーザーでwebサービスを実行し、UIDが同じでwebディレクトリと権限が一貫しているため、より厳格な標準化により、より安全な本番環境と高い効率がもたらされます

1.1:Jenkinsプロジェクト構成でシェルスクリプトを呼び出し、環境の準備:

1.1.1:#jenkins-プロジェクト-構成:

1.1.2:wwwユーザーのホームディレクトリにあるスクリプトの内容:

$ cat code_deploy.sh

#!/bin/bash

#Dir List デプロイノード(デプロイノードで実行する操作)
# mkdir -p /deploy/code/web-demo
# mkdir -p /deploy/config/web-demo/base
# mkdir -p /deploy/config/web-demo/other
# mkdir /deploy/tmp
# mkdir /deploy/tar

# chown -R www.www /deploy
# chown -R www.www /webroot
# chown -R www.www /opt/webroot/
# chown -R www.www /webroot

# クライアントノードで実行する必要がある操作
# mkdir /opt/webroot
# mkdir /webroot
# chown -R www.www /webroot
# chown -R www.www /opt/webroot/
# chown -R www.www /webroot
# [www@ ~]$ touch /webroot/web-dem

# Node List サーバーノード
PRE_LIST="192.168.3.12"        # プレプロダクションノード
GROUP1_LIST="192.168.3.12 192.168.3.13"
GROUP2_LIST="192.168.3.13"
ROLLBACK_LIST="192.168.3.12 192.168.3.13"

# ログの日付と時間変数
LOG_DATE='date "+%Y-%m-%d"' # 実行すると後で実行される時間、この時間は固定されていません。これはログ記録に使用される時間です
LOG_TIME='date "+%H-%M-%S"'

# コードパッケージング時間変数
CDATE=$(date "+%Y-%m-%d") # スクリプトが一度実行されると、固定された時間が変数に割り当てられます。この時間は固定されています
CTIME=$(date +"%H-%M-%S")

# shell env スクリプトの位置などの変数
SHELL_NAME="deploy.sh"    # スクリプト名
SHELL_DIR="/home/www/"  # スクリプトパス
SHELL_LOG="${SHELL_DIR}/${SHELL_NAME}.log" # スクリプト実行ログファイルのパス

# code env コード変数
PRO_NAME="web-demo"    # プロジェクト名の関数
CODE_DIR="/deploy/code/web-demo"    # バージョン管理システムから更新されたコードディレクトリ
CONFIG_DIR="/deploy/config/web-demo"    # 異なるプロジェクトの構成ファイルを保存し、1つのディレクトリに1つのプロジェクトの1つまたは複数の構成ファイルが含まれます
TMP_DIR="/deploy/tmp"            # 一時ディレクトリ
TAR_DIR="/deploy/tar"            # パッケージングディレクトリ
LOCK_FILE="/tmp/deploy.lock" # ロックファイルのパス

usage(){ # 使用ヘルプ関数
    echo $"Usage: $0 [ deploy | rollback [ list | emergency | version ]"
}

writelog(){ # ログに書き込む関数
    LOGINFO=$1 # パラメータをログ入力として使用
    echo "${CDATE} ${CTIME} : ${SEHLL_NAME} : ${LOGINFO}" >> ${SHELL_LOG}
}

# ロック関数
shell_lock(){
    touch ${LOCK_FILE}
}

# ロック解除関数
shell_unlock(){
    rm -f ${LOCK_FILE}
}

# コードを取得する関数
code_get(){
    echo "code_get"
    writelog code_get
    cd $CODE_DIR && git pull # コードディレクトリに入りコードを更新、ここではパスワードなしで更新する必要があります。このディレクトリはコード更新専用で、他のファイルを置いてはいけません
    cp -rf ${CODE_DIR} ${TMP_DIR}/ # 一時的にコードを保存し、名前を変更し、webサーバーにコピーする準備
    API_VERL=$(git show | grep commit | cut -d ' ' -f2)  
    API_VER=$(echo ${API_VERL:0:8})        # バージョン番号
}

code_build(){ # コードコンパイル関数
    echo code_build
}

code_config(){ # 構成ファイル関数
    writelog "code_config"
    /bin/cp -rf ${CONFIG_DIR}/base/* ${TMP_DIR}/"${PRO_NAME}" # 構成ファイルをローカルの構成ファイルの一時ディレクトリに配置し、コードプロジェクトの一時的な保存に使用します
    PKG_NAME="${PRO_NAME}"_"$API_VER"_"${CDATE}-${CTIME}"    # コードディレクトリ名を定義
    cd ${TMP_DIR} && mv ${PRO_NAME} ${PKG_NAME}    # コードファイルをweb-demo_123-20170629-11-19-10形式に名前変更
    
}

code_tar(){    # コードパッケージング関数
    writelog code_tar
    cd ${TMP_DIR} && tar czf ${PKG_NAME}.tar.gz ${PKG_NAME} --exclude=".git" # ディレクトリを圧縮ファイルにパッケージ化し、ネットワーク転送を容易にします
    writelog "${PKG_NAME}.tar.gz packaged success"    # パッケージング成功のログを記録
}

code_scp(){ # コード圧縮パッケージをクライアントにscpする関数
    writelog  "code_scp"
    for node in $PRE_LIST;do # サーバーノードリストをループ
        scp ${TMP_DIR}/${PKG_NAME}.tar.gz $node:/opt/webroot/ # 圧縮されたコードパッケージをwebサーバーの/opt/webrootにコピー
    done

    for node in $GROUP1_LIST;do # サーバーノードリストをループ
        scp ${TMP_DIR}/${PKG_NAME}.tar.gz $node:/opt/webroot/ # 圧縮されたコードパッケージをwebサーバーの/opt/webrootにコピー
    done
}

cluster_node_add(){ #webサーバーをフロントエンドロードバランサーに追加
    echo cluster_node_add
}

cluster_node_remove(){ # クラスタからwebサーバーを削除する関数(デプロイ中はビジネスを処理しない)
    writelog "cluster_node_remove"
}

url_test(){
    URL=$1
    curl -s --head $URL |grep '200 OK'
    if [ $? -ne 0 ];then
        shell_unlock;
        writelog "test error" && exit;
    fi
}

pre_deploy(){ # コード解凍デプロイ関数、プレプロダクションノード
    writelog "pre_deploy"
    for node in ${PRE_LIST};do # プレプロダクションサーバーノードリストをループ
        cluster_node_remove  ${node} # デプロイ前にノードをフロントエンドロードバランサーから削除
        echo  "pre_deploy, cluster_node_remove ${node}"
        ssh ${node} "cd /opt/webroot && tar zxf ${PKG_NAME}.tar.gz" # 各webサーバーで圧縮パッケージの解凍コマンドを実行
        ssh ${node} "rm -f /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo" # 自動化の核心、シンボリックリンクを作成
        done
}

pre_test(){ # プレプロダクションホストテスト関数
    for node in ${PRE_LIST};do # プレプロダクションホストリストをループ
        curl -s --head http://${node}:9999/index.html | grep "200 OK" # webインターフェースへのアクセスをテスト
            if [ $? -eq 0 ];then  # アクセスが成功した場合
                writelog " ${node} Web Test OK!" # ログを記録
                echo " ${node} Web Test OK!"
                cluster_node_add ${node} # テスト成功後に追加関数を呼び出してサーバーをクラスタに追加
                writelog "pre,${node} add to cluster OK!" # サーバーをクラスタに追加したログを記録
            else # アクセスが失敗した場合
                writelog "${node} test no OK" # ログを記録
                echo "${node} test not OK"
                shell_unlock # ロックファイル削除関数を呼び出す
            break # デプロイを終了
        fi
    done

}

group1_deploy(){ # コード解凍デプロイ関数
    writelog "group1_code_deploy"
    for node in ${GROUP1_LIST};do # プロダクションサーバーノードリストをループ
        cluster_node_remove $node  
        echo "group1, cluster_node_remove $node"
        ssh ${node} "cd /opt/webroot && tar zxf ${PKG_NAME}.tar.gz" # 各webサーバーノードで圧縮パッケージの解凍コマンドを実行
        ssh ${node} "rm -f /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo" # 自動化の核心、シンボリックリンクを作成
    done
    scp ${CONFIG_DIR}/other/192.168.3.13.server.xml 192.168.3.13:/webroot/web-demo/server.xml  # 差分プロジェクトの構成ファイルをこのwebサーバーにscpし、プロジェクト名で終わる
}    

group1_test(){ # プロダクションホストテスト関数
    for node in ${PRE_LIST};do # プロダクションホストリストをループ
        curl -s --head http://${node}:9999/index.html | grep "200 OK" # webインターフェースへのアクセスをテスト
        if [ $? -eq 0 ];then  # アクセスが成功した場合
            writelog " ${node} Web Test OK!" # ログを記録
            echo "group1_test,${node} Web Test OK!"
            cluster_node_add
            writelog " ${node} add to cluster OK!" # サーバーをクラスタに追加したログを記録
        else # アクセスが失敗した場合
            writelog "${node} test no OK" # ログを記録
            echo "${node} test not OK"
            shell_unlock # ロックファイル削除関数を呼び出す
            break # デプロイを終了
        fi
    done
}

emergency_code_get(){ # コードを取得する関数
    writelog "code_get"
    cd ${CODE_DIR} && git reset --hard HEAD^   # コードディレクトリに入りコードを更新、ここではパスワードなしで更新する必要があります。このディレクトリはコード更新専用で、他のファイルを置いてはいけません
    /bin/cp -rf ${CODE_DIR} ${TMP_DIR}/ # 一時的にコードを保存し、名前を変更し、webサーバーにコピーする準備
    API_VERL=$(git show | grep commit | cut -d ' ' -f2)
    API_VER=$(echo ${API_VERL:0:8}) # 8桁を取得
}

emergency(){  # 前のバージョンに緊急ロールバックする関数
    emergency_code_get # コードを前のバージョンにロールバックする関数を実行
    code_build; # コンパイルが必要な場合はコンパイル関数を実行
        code_config; # 構成ファイルをコピー
        code_tar; # パッケージング
        code_scp; # サーバーにscp
        cluster_node_remove;
        pre_deploy; # プレプロダクション環境のデプロイ
        pre_test; # プレプロダクション環境のテスト
        group1_deploy; # プロダクション環境のデプロイ
        group1_test; # プロダクション環境のテスト
        code_config; # 差分ファイルをコピー
        #code_test; # コードテスト
        shell_unlock # 実行完了後にロックファイルを削除
}

rollback_fun(){ 
    for node in $ROLLBACK_LIST;do # サーバーノードリストをループ
        # 必ず"を追加する必要があります。そうでないとリモートでコマンドを実行できません
        ssh $node "rm -f /webroot/web-demo && ln -s /opt/webroot/$1 /webroot/web-demo" # 指定されたバージョンに即時ロールバック、$1は指定されたバージョンパラメータ
        echo "${node} rollback success!"
        done
}

rollback(){ # コードロールバックメイン関数
    if [ -z $1 ];then
        shell_unlock # ロックファイルを削除
        echo "Please input rollback version" && exit 3;
    fi
    case $1 in # 2番目のパラメータを自分の1番目のパラメータとして扱う
        list)
            ls -l /opt/webroot/*.tar.gz
            ;;
        *)
            rollback_fun $1
    esac
            
}

main(){
    if [ -f $LOCK_FILE ] ;then # まずロックファイルがあるかどうかを確認し、ある場合は直接終了
        echo "Deploy is running" && exit 10
    fi
    DEPLOY_METHOD=$1 # エラーを避けるためにスクリプトの1番目のパラメータを変数として使用
    ROLLBACK_VER=$2
    case $DEPLOY_METHOD in
        deploy) # 1番目のパラメータがdeployの場合、以下の操作を実行
            shell_lock; # デプロイ前にロックを作成。同時に他の人が実行すると、ロックファイルが存在すると表示されます
            code_get; # コードを取得
            code_build; # コンパイルが必要な場合はコンパイル関数を実行
            code_config; # 構成ファイルをコピー
            code_tar;    # パッケージング
            code_scp;    # サーバーにscp
            pre_deploy;  # プレプロダクション環境のデプロイ
            pre_test;    # プレプロダクション環境のテスト
            group1_deploy; # プロダクション環境のデプロイ
            group1_test;   # プロダクション環境のテスト
            shell_unlock; # 実行完了後にロックファイルを削除
            ;;
        rollback) # 1番目のパラメータがrollbackの場合、以下の操作を実行
            shell_lock; # ロールバック前にロックファイルを作成
            rollback $ROLLBACK_VER;
            shell_unlock; # 実行完了後にロックファイルを削除
            ;;
        emergency)
        emergency; # 緊急ロールバックはパラメータが不要ですが、実行時に緊急ロールバックかどうかを確認する必要があります。誤入力を避けるため
        ;;
        *)
            usage;
    esac
}
main $1 $2

1.1.4:現在のwebページを変更:

$ cd web-demo
$ echo "<h1>jenkins deploy test" > index.html 
$ git add index.html 
$ git commit -m "jenkins deploy test"

1.4:任意のバージョンにロールバック:
1.4.1:ロールバックするバージョンはどこで見つけますか?:
$ ll /deploy/tmp/ # デプロイサーバー、webサーバーはnginxで定義されたディレクトリでバージョンを確認

1.4.3:Jenkinsでロールバックを実行:

# ll /opt/webroot/
drwxr-xr-x 5 www www 4096 Jun 26 12:18 web-demo_123_2017-06-26-12-18-09
-rw-rw-r-- 1 www www 1243347 Jun 28 22:45 web-demo_123_2017-06-26-12-18-09.tar.gz
drwxr-xr-x 5 www www 4096 Jun 26 12:18 web-demo_123_2017-06-26-12-18-57
-rw-rw-r-- 1 www www 1243369 Jun 28 22:46 web-demo_123_2017-06-26-12-18-57.tar.gz
drwxrwxr-x 4 www www 4096 Jun 30 14:59 web-demo_75463f1b_2017-06-30-14-59-58

1.4.2:任意のバージョンにロールバックする場合は、バージョンパラメータをスクリプトに渡し、スクリプトはweb-demoのリンクを渡されたバージョン(パラメータ)を指すように再設定します。たとえば、web-demo_78869143_2017-06-30-15-18-29バージョンにロールバックする場合は、Jenkinsの構成は次のようになります:

1.4.3:Jenkinsでロールバックを実行:
1.4.4:ロールバックの実行情報:

1.4.5:webインターフェースにアクセスして、任意のバージョンのロールバックが成功したかどうかをテスト:

タグ: Jenkins 継続的インテグレーション SonarQube 自動デプロイ GitLab

5月16日 04:14 投稿