[ Jenkins](https://jenkins.io/)は、アプリケーションの構築、テスト、および展開のプロセスを自動化するパイプラインを構築できるようにするオープンソースの自動化サーバーです。このガイドでは、継続的な統合と継続的な配信(CI / CD)プロセスを高速化するための基本的なワークフローを実装します。
sudo apt-get update && sudo apt-get upgrade
このチュートリアルは、root以外のユーザーを対象としています。昇格された特権を必要とするコマンドの前には
sudo
が付いています。
このガイドはDevOpsの専門家を対象としているため、次のことを前提としています。
ワークフローを自動化する前に、基本的なCI / CDプロセスを理解する必要があります。次の図はこれを示しています。
最も基本的なプロセスは、ビルド、テスト、およびデプロイの3つの段階で構成されます。分散バージョン制御システムで変更が行われるたびに、Jenkinsサーバーで自動化ループがトリガーされます。プロセス Jenkinsfile
を実行するための完全な手順は、ソースリポジトリのルートディレクトリにあります。この単一のファイルは、サーバーにこれらのタスクを実行するタイミングと方法を指示します。
前のセクションで述べたように、自動化されたプロセスは最初にバージョン制御システムに送信されます。
GitHubに新しいリポジトリを作成します。このガイドでは、単純なNode.jsアプリケーションを使用して、Jenkinsパイプラインがどのように機能するかを示します。対応する .gitignore
を選択し、次のコンテンツ README
で初期化することを忘れないでください。
新しいリポジトリをローカルワークステーションにクローンします。
git clone [email protected]:<GITHUB_USERNAME>/jenkins-guide.git
お気に入りのテキストエディタを開き、リポジトリのルートディレクトリにファイル app.js
を作成します。次のコンテンツを追加します。
~ /jenkins-guide/app.js
1 2 3 4 5 6 7 8 9101112131415161718192021 | ' use strict';const express = require('express');const app = express();// Server connectionconst PORT = 9000;const HOST = '0.0.0.0';// Application contentconst os = ['Windows','macOS','Linux']// Web Serverapp.get('/',function(req,res) { res.json(os);});// Console outputapp.listen(PORT, HOST);console.log(Running on http://${HOST}:${PORT} ); |
---|
このアプリケーションは、[Express](https://expressjs.com/)Webサーバーを使用して、ポート9000でブラウザーに単一のJSON出力を提供します。次に、 test.js
をリポジトリのルートの同じ場所に保存します。
~ /jenkins-guide/ test.js
1 2 3 4 5 6 7 8 91011121314151617181920212223242526272829 | var supertest = require("supertest");var should = require("should");var server = supertest.agent("http://nodeapp-dev:9000");// Unit Testdescribe("Webapp Status",function(){ // Test 1 - HTTP status it("Expect HTTP status 200",function(done){ server .get("/") .expect("Content-type",/text/) .expect(200) .end(function(err,res){ res.status.should.equal(200); done(); }); }); // Test 2 - Control Tests it("Mocha Control Test",function(done){ (1).should.be.exactly(1).and.be.a.Number(); done(); });}); |
---|
これは、 supertest
と should
を使用した簡略化されたテストスイートです。テストは2つだけです。最初のテストはHTTPステータスをチェックします。これは200と予想されます。2番目のテストは実際のテストではなく、常に合格するコントロールです。
この例では、2つのDockerコンテナを使用します。1つはExpressを使用する app.js
用で、もう1つはMochaを使用するテストスイート用です。各画像には、対応する Dockerfile
と package.json
を含む独自のフォルダーがあります。
Dockerfile
と package.json
を express-image
として作成します。 〜/ jenkins-guide / express-image / DockerfileFROM node:6-alpine
# Create a server directory
RUN mkdir -p /home/node/app
WORKDIR /home/node/app
# Install server dependencies
COPY /express-image/package.json /home/node/app
RUN npm install
# Copy node Application
COPY app.js /home/node/app
# Open port
EXPOSE 9000
CMD ["npm","start"]
App.js
は、起動時にデフォルトでこのイメージを実行します。これは、Webアプリケーションの「ドッカー化」バージョンと考えることができます。
package.json
は、プロジェクトディレクトリのルートにあるファイルを新しいイメージにコピーします:〜/ jenkins-guide / express-image / package.json{" name":"express-image","version":"1.0.0","description":"Example Node Application","author":"Your name","repository":{"type":"git","url":"git+https://github.com/<YOUR_USERNAME>/<REPOSITORY_NAME>.git"},"license":"ISC","scripts":{"start":"node app.js"},"dependencies":{"express":"^4.13.3"}}
Dockerfile
を test-image
として作成します:〜/ jenkins-guide / test-image / DockerfileFROM node:6-alpine
# Create feports directory
RUN mkdir -p /JUnit
# Create a server directory
RUN mkdir -p /home/node/tests
WORKDIR /home/node/tests
# Install app dependencies
COPY /test-image/package.json /home/node/tests
RUN npm install
# Copy test source
COPY test.js /home/node/tests
EXPOSE 9000
CMD ["npm","test"]
このイメージは* reports *フォルダーを作成し、そこから依存関係 package.json
をインストールします。最初は、モカテストを実行します。
このJSONファイルには、 mocha-junit-reporter
を含むすべての必要な依存関係が含まれています。Jenkinsは、ストレージに必要な依存関係をテストするために使用されます。テストスクリプトは、 mochaFile
が画像で指定された画像レポートフォルダを使用するオプション Dockerfile
で構成されていることに注意してください。最終的なプロジェクトの配布は次のようになります。
**注:**フォルダー構造の方法と2つのDockerコンテナーの実装は珍しいですが、教育上の理由から、Jenkinsパイプラインの機能を示すために使用されています。
実際の自動化プロセスを開始する前に、まず自動化するコンテンツを理解する必要があります。
nodeapp-dev
コンテナを起動する必要があります。フラグ --network
は、他のコンテナネットワークとの競合を回避するために使用されます。ポート9000が開いており、 -d
フラグを使用してデタッチモードで実行していることに注意してください。起動したら、ブラウザを開いてアドレス http:// localhost:9000
を入力して確認できます。 sudo docker run --name nodeapp-dev --network = "bridge" -d -p 9000:9000 nodeapp-dev:trunktest-image
コンテナを起動します。 --link
通信するには、同じネットワークを使用し、 nodeapp-dev
にフラグを立てることが非常に重要です。コンテナのレポートフォルダ JUnit
が現在のリポジトリルートディレクトリにインストールされていることがわかります。これは、 reports.xml
がホストに書き込まれるために必要な条件です。 -it
フラグを指定してインタラクティブモードで実行し、結果を stdout
に出力します。 sudo docker run --name test-image -v $ PWD:/ JUnit --network = "bridge" --link = nodeapp-dev -it -p 9001:9000 test-image:latest npm run mochasudo -i
が必要な場合があります)、デタッチモードで再度実行して、 JUnit
出力をテストします。このファイルは reports.xml
の後に保存する必要があります。 sudo docker rm -f test-image sudo docker run --name test-image -v $ PWD:/ JUnit --network = "bridge" --link = nodeapp-dev -d -p 9001:9000 test-image:latestsudo -i
必要に応じて、両方のコンテナの使用を停止します。 sudo docker stop test-image nodeapp-devこれで、この架空のWebアプリケーションのビルド、テスト、および展開プロセス全体が完了しました。今度は自動化する時です。
Jenkinsには、多くのインストールオプションがあります。
jenkins.war
でダウンロードできます。これは、Jenkinsで使用できる高速で効果的なソリューションであり、必要な前提条件はほとんどありませんが、保守と更新がより困難です。Jenkinsプロジェクトによって維持されているパッケージを使用すると、配布パッケージマネージャーに含まれているバージョンよりも新しいバージョンを使用できます。
sources.list
に追加します:sudo sh -c'echo deb http://pkg.jenkins.io/debian-stable binary />/etc/apt/sources.list.d/jenkins。リスト'sudoservicejenkins
を選択し、 start
、 stop
、 restart
、または status
を選択します。サービスを開始してインストールを確認します。sudoservicejenkinsstartjenkins
ユーザーをDockerグループに追加するときは、技術的には root
権限を付与します。Jenkinsは、 Jenkinsfile
構文に2つの異なるオプションを提供します。
どちらも継続配信とJenkinsプラグインをサポートしています。スクリプト構文はGroovyプログラミング環境に基づいているため、より完全です。一方、宣言的文法は「ジェンキンスのパイプラインを作成するためのより単純で洞察に満ちた文法を提供するために作成された」ため、日常の自動構築に適しています。構文の比較について詳しくは、[Jenkinsのドキュメント](https://jenkins.io/doc/book/pipeline/syntax/#compare)をご覧ください。
このガイドでは、宣言構文を使用してJenkinsプロセスを説明します。これは、その設計が実装と理解が容易だからです。
宣言的なパイプライン構文は非常に直感的です。最も基本的なレイアウトは、以下に示すレイアウトに似ています。
パイプライン
:すべてのファイルは、このステートメントを先頭にして開始する必要があります。これは、新しいパイプラインの始まりを表しています。 agent
:作業環境、通常はDockerイメージを定義します。 any
ステートメントは、パイプラインが使用可能な任意のプロキシを使用できることを示します。 stages
:このブロックは stage
命令のコレクションです。 stage
:1つ以上の steps
をグループ化します。必要な数のステージを使用できます。これは、「各ステージ」で詳細なデバッグが必要な複雑なモデルで作業している場合に非常に便利です。ステップ
:ここでアクションを定義します。ステージは多くのステップをグループ化でき、各ステップは通常、特定のタスク/コマンドにリンクされています。コードブロックは中括弧( {
および }
)で区切られ、セミコロンを使用しません。各ステートメントは独自の行にある必要があり、 Jenkinsfile
は実行するステップの中核です。一般的な手順は次のとおりです。
これらの操作はすべて、内部で実行できます。エージェント、またはSSHを介してリモートで操作を実行するようにJenkinsに指示できます。ご覧のとおり、自動化には無限の可能性があります。単純なシナリオでは、ステージを順番に実行する1つのパイプラインだけで、目的の最終状態を実現できますが、必要に応じて並列で実行するようにパイプラインを定義できます。 Jenkinsの宣言パイプライン構文の詳細については、[公式ドキュメント](https://jenkins.io/doc/book/pipeline/syntax/)を参照してください。
Jenkinsfile
は、最初に jenkins-guide
ワークステーションのディレクトリに作成されます。これは単なるテンプレートですが、パイプラインを開始するために必要なすべてのコードが含まれています。pipeline{agent any stage {stage( 'Build'){steps {echo'This is the Build Stage '}} stage(' Test '){steps { echo 'これはテストステージです'}} stage( 'Deploy'){ステップ{echo 'これはデプロイステージです'}}}}ここから、次の貴重な情報を取得できます。1)ビルド番号、2)各ステップのコンソール出力、3)さらに分析するステージの選択、4)変更の送信、テストに関する情報を含むタブの参照結果と保存されたアーティファクトに関する情報、5)ビルドの再生、6)パイプラインの視覚的な編集、7)パイプライン設定に移動します。
Jenkinsfile
テンプレートは、3つのステージしかない非常に基本的なパイプライン構造を使用します。必要に応じて、複数のステージに合わせてカスタマイズできます。最終的なパイプライン構造は、プロジェクトの複雑さと従う必要のある開発ガイドラインによって決まります。 Node.jsの例がわかったので、各ステージを自動化するパイプラインを設計する方法を理解しました。このガイドの目的上、最終的なパイプラインは次のようになります。
設立段階
エラーが発生した場合は、2つのイメージを作成し、それ以上のテストまたは展開を中止します。
不具合が発生した場合は、担当部署にご連絡ください。
テストフェーズ
自動化されたMochaテストスイートを実行します。
簡単に配布して手動で品質テストを行うために、 nodeapp-dev
イメージを公開します。
自動テストの結果に応じて、対応する部門に通知されます:成功、不安定(自動テストの失敗)、またはステージの完全な失敗。
展開フェーズ
コミットが master
ブランチで実行され、テストフェーズが正常に完了した場合にのみ実行されます。
公開する前に画像タグを変更してください。
ドッキングされたアプリケーションをDockerHubにデプロイします。
さらに配布するために、圧縮された「ゴールデン」イメージを保存します。
レポートフェーズ
JUnit
ファイルを保存し、 reports.xml
で詳細な分析を実行します。
nodeapp-prod-golden.tar.gz
の圧縮されたイメージを永続的な場所に保存します。
クリーンアップフェーズ
すべてのコンテナを停止します。
剪定システム。
Jenkinsワークスペースをクリーンアップします。
最初にJenkinsfileを編集し、次のパイプラインを貼り付けます。置換 <DockerHub Username>
あなた自身の情報のために。
〜/ Jenkinsガイド/ Jenkinsfile
|1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99100101| pipeline { environment { DOCKER = credentials('docker-hub') } agent any stages {// Building your Test Images stage('BUILD') { parallel { stage('Express Image') { steps { sh 'docker build -f express-image/Dockerfile \ -t nodeapp-dev:trunk .' } } stage('Test-Unit Image') { steps { sh 'docker build -f test-image/Dockerfile \ -t test-image:latest .' } } } post { failure { echo 'This build has failed. See logs for details.' } } }// Performing Software Tests stage('TEST') { parallel { stage('Mocha Tests') { steps { sh 'docker run --name nodeapp-dev --network="bridge" -d \ -p 9000:9000 nodeapp-dev:trunk' sh 'docker run --name test-image -v $PWD:/JUnit --network="bridge" \ --link=nodeapp-dev -d -p 9001:9000 \ test-image:latest' } } stage('Quality Tests') { steps { sh 'docker login --username $DOCKER_USR --password $DOCKER_PSW' sh 'docker tag nodeapp-dev:trunk
|--------|--------|
この完全なJenkinsfileは、宣言構文を使用して記述されています。注意深く読むと、前のセクションでアプリケーションの展開中に使用されたのと同じプロセスが説明されていることがわかります。このセクションでは、Jenkinsファイルをより詳細に分析します。
最初のブロックは、グローバルに利用可能な環境変数 DOCKER
を定義します。パイプラインブロックの内側にあるがステージブロックの外側にあるため、グローバルに適用するように指示できます。次は agent
のステートメントです。これは、Jenkinsが任意の(サーバー)エージェントを使用できることを意味します。
〜/ Jenkinsガイド/ Jenkinsfile
12345 | pipeline { environment { DOCKER = credentials('docker-hub') } agent any |
---|
DOCKER
の定義は、* voucher *関数を介して完了します。これにより、Jenkinsファイルに含めずに機密のログイン情報を使用できます。このキーペアを構成するには:
docker-hub
です。資格情報を保存すると、パイプラインのどこでも使用できます。この例のパイプラインでは、 DOCKER = authentication( 'docker-hub')
は、dockerhubアカウントへのログインに使用できる DOCKER_USER
と DOCKER_PWD
の2つの環境変数を作成します。
parallel
コードブロックについて最初に気付くのは、それが自明であるということです-それはサブフェーズを並列に実行します。これは、以前に使用したのと同じシェルコマンドを使用して2つのDockerイメージを構築する場合に非常に役立ちます。各画像は独自のステップで宣言されますが、これも独立フェーズの一部です。
~ /jenkins-guide/Jenkinsfile
1 2 3 4 5 6 7 8 910111213141516171819202122 | // Building your Test Images stage('BUILD') { parallel { stage('Express Image') { steps { sh 'docker build -f express-image/Dockerfile \ -t nodeapp-dev:trunk .' } } stage('Test-Unit Image') { steps { sh 'docker build -f test-image/Dockerfile \ -t test-image:latest .' } } } post { failure { echo 'This build has failed. See logs for details.' } } } |
---|
並列フェーズを閉じた後、「post」状態が発生します。 Post
は、定義が BUILD
フェーズ全体に適用されることを意味します。この場合、 failure
条件のみが設定されるため、 BUILD
フェーズのいずれかの部分が失敗した場合にのみ実行されます。 Jenkinsが通信用に提供するさまざまなツールの構成は、このガイドの範囲を超えています。
テストフェーズでも並列実行を使用します。
~ /jenkins-guide/Jenkinsfile
1 2 3 4 5 6 7 8 9101112131415161718192021222324252627282930313233 | // Performing Software Tests stage('TEST') { parallel { stage('Mocha Tests') { steps { sh 'docker run --name nodeapp-dev --network="bridge" -d \ -p 9000:9000 nodeapp-dev:trunk' sh 'docker run --name test-image -v $PWD:/JUnit --network="bridge" \ --link=nodeapp-dev -d -p 9001:9000 \ test-image:latest' } } stage('Quality Tests') { steps { sh 'docker login --username $DOCKER_USR --password $DOCKER_PSW' sh 'docker tag nodeapp-dev:trunk |
---|
Mocha Tests
ステージは2つの画像で始まり、自動テストを実行します。結果の reports.xml
はJenkinsワークスペースファイルに保存されます。一方、この「品質テスト」ステージでは、アプリケーションの「トランク」バージョンがDockerHubに公開されます。最初に(事前定義された資格情報を使用して)Dockerログインコマンドを発行し、次にイメージタグを変更してプッシュします。
ここでも、「post」コードブロックがありますが、今回は、正常な完了、不安定性、および失敗の通知があります。ここでは、通知だけでなく、任意のコードを使用できることを忘れないでください。
この段階では、さまざまなタイプのブロックが導入されます: when
。名前が示すように、この句は特定の条件が満たされた場合にのみ実行されます。この例の場合、マスターブランチへの変更が検出された場合にのみコードが実行されます。他のブランチに送信しても、パイプラインのこのステップはトリガーされません。
このステップでは、 retry
および timeout
パラメーターを構成することを選択できます。上記の例は、イメージ構築プロセスのタイムアウトが10分で、タイマーの期限が切れると合計3回の再試行があるネストされた使用法を示しています。
post
ブロックは、障害が発生した場合にクリーンアップするように設計されています。この段階では通知は設定されていません。
パイプラインの最後の2つの段階は比較的単純です。 junit
ステートメントにより、JenkinsはMochaイメージによって生成された reports.xml
ファイルを使用でき、 archiveArtifacts
コマンドはレポートファイルとアプリケーションファイルを永続的な場所に保存します。デフォルトでは、場所は JENKINS_HOME / var / lib / jenkins / jobs /です。<REPOSITORY> / branchs / master / builds / lastStableBuild
。必要に応じて、Jenkinsの一般設定でカスタムの場所を構成できます。
完全なJenkinsファイルをJenkinsサーバーに送信し、新しいパイプラインの実行をトリガーします。 「when」で前述したブロックをテストするために、変更は別のブランチにプッシュされます。
DEPLOY
はステージをスキップしたことに注意してください。リポジトリを定期的にスキャンするようにJenkinsを設定できます。これを行うには、パイプラインビューのギアアイコンをもう一度クリックしてから、構成をクリックします。多くのオプションがあります。 スキャンリポジトリトリガーを探します。実行されていない場合、定期的にこのチェックボックスをオンにしてください。何度でも選択できます。この例では、1分が選択されます。
これまでのところ、すべてがエラーなしで期待どおりに機能するはずです。しかし、エラーが発生するとどうなりますか?
app.js
はローカルワークステーションで編集されます。サーバー上で、ルートアドレス /
を / ERROR
に変更します。これにより、 express
サーバーでエラー404(ページが見つかりません)が発生するため、テストは失敗します。~ /jenkins-guide/app.js
12345 | // Web Serverapp.get('/ERROR',function(req,res) { res.json(os);}); |
---|
app.js
ファイルを修復して保存します。これで、 BUILD
ステージでエラーが発生します。
express-image / package.json
を編集します。 Expressパッケージの名前を express-ERROR
に変更して、エラー入力をシミュレートします。~ /jenkins-guide/express-image/package.json "dependencies": { "express-ERROR": "^4.13.3" }
express-image / package.json
を修正します。trunk
ブランチを master
にマージしました。これにより、展開フェーズを含むパイプライン全体の操作がトリガーされます。
git checkout master
git merge trunk
git push origin master
ブルーオーシャンインターフェースはまだ開発中です。つまり、ジェンキンスの多くの側面が新しいインターフェースによって管理されていません。最も一般的な画面のいくつかを次に示します。
master
ブランチをクリックすると、より詳細なダッシュボードが表示されます。このビューから、ログ、アーティファクト、変更、テスト結果の傾向など、多くの有用な情報を表示できます。
このガイドでは、ジェンキンスとブルーオーシャンの基本的な自動ワークフローを紹介しますが、できることはたくさんあります。いくつかの可能性を挙げれば:
エージェントに特定の
ステージ `を使用することもできます。このトピックの詳細については、次のリソースを参照してください。これらは有用であることを願って提供されていますが、外部でホストされている資料の正確性や適時性を保証することはできませんのでご注意ください。
チュートリアルの詳細については、[Tencent Cloud + Community](https://cloud.tencent.com/developer?from=10680)にアクセスして詳細をご覧ください。
参照:「[https://www.linode.com/docs/development/ci/automate-builds-with-jenkins-on-ubuntu/](https://www.linode.com/docs/development/ci/automate-builds-with-jenkins-on-ubuntu/)」
Recommended Posts