一:継続的インテグレーションの概念:
全体の概要
継続的インテグレーション(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インターフェースにアクセスして、任意のバージョンのロールバックが成功したかどうかをテスト: