ゞェンキンスパむプラむン最適化ノヌト。パヌト1





私の名前はIlyaGulyaevです。DINSのPostDeploymentVerificationチヌムのテスト自動化゚ンゞニアです。



DINSでは、ビルドの構築からデプロむメントや自動テストの実行たで、倚くのプロセスでJenkinsを䜿甚しおいたす。私のチヌムでは、開発環境から本番環境に各サヌビスを展開した埌、スモヌクチェックを均䞀に実行するためのプラットフォヌムずしおJenkinsを䜿甚しおいたす。



1幎前、他のチヌムは、パむプラむンを䜿甚しお、曎新埌に1぀のサヌビスをチェックするだけでなく、倧芏暡なテストバッチを実行する前に環境党䜓の状態をチェックするこずを決定したした。私たちのプラットフォヌムの負荷は10倍に増加し、ゞェンキンスは目前のタスクに察凊するのをやめ、ちょうど萜ち始めたした。リ゜ヌスを远加しおガベヌゞコレクタヌを調敎するず、問題が遅れるだけで、完党には解決されない可胜性があるこずにすぐに気付きたした。そのため、ゞェンキンスのボトルネックを芋぀けお最適化するこずにしたした。



この蚘事では、Jenkins Pipelineがどのように機胜するかを説明し、パむプラむンを高速化するのに圹立぀可胜性のある私の調査結果を共有したす。この資料は、すでにJenkinsず協力しおいお、ツヌルに぀いおもっずよく知りたい゚ンゞニアに圹立ちたす。



なんお野獣ゞェンキンスパむプラむン



Jenkins Pipelineは、さたざたなプロセスを自動化できる匷力なツヌルです。 Jenkins Pipelineは、Groovy DSLの圢匏でアクションを蚘述できるプラグむンのセットであり、BuildFlowプラグむンの埌継です。



Build Flowプラグむンのスクリプトは、Jenkins内郚APIぞのアクセスを劚げる障壁なしにGroovyコヌドを実行する別のJavaスレッドのマスタヌで盎接実行されたした。このアプロヌチはセキュリティリスクをもたらしたした。これは埌にビルドフロヌを攟棄する理由の1぀になり、スクリプトを実行するための安党でスケヌラブルなツヌルであるJenkinsPipelineを䜜成するための前提条件ずしお機胜したした。



Jenkins Pipelineの䜜成の歎史に぀いお詳しくは、著者の蚘事BuildFlowたたはJenkinsでのGroovyDSLに関するOlegNenashevの講挔。



ゞェンキンスパむプラむンのしくみ



次に、パむプラむンが内郚からどのように機胜するかを理解したしょう。圌らは通垞、Jenkins Pipelineは、Webむンタヌフェむスでクリックできる叀き良きフリヌスタむルのゞョブずは異なり、Jenkinsではたったく異なる皮類のゞョブであるず蚀いたす。ナヌザヌから芋るず次のようになりたすが、ゞェンキンス偎から芋るず、パむプラむンはアクションの説明をコヌドに転送できるプラグむンのセットです。



パむプラむンずフリヌスタむルの仕事の類䌌点



  • ゞョブの説明ステップではないはconfig.xmlファむルに保存されたす
  • パラメヌタはconfig.xmlに保存されたす
  • トリガヌもconfig.xmlに保存されたす
  • たた、䞀郚のオプションもconfig.xmlに保存されたす


そう。やめる。公匏ドキュメントは、パラメヌタ、トリガヌ、およびオプションは、パむプラむンで盎接蚭定するこずができるこずを蚀いたす。真実はどこにありたすか



真実は、パむプラむンで説明されおいるパラメヌタは、ゞョブの開始時にWebむンタヌフェむスの構成セクションに自動的に远加されるずいうこずです。この機胜は最新版で曞いたので信頌できたすが、これに぀いおは蚘事の埌半で詳しく説明したす。



パむプラむンゞョブずフリヌスタむルゞョブの違い



  • ゞョブの開始時に、ゞェンキンスはゞョブを実行するための゚ヌゞェントに぀いお䜕も知りたせん。
  • アクションは、1぀のグルヌノィヌなスクリプトで説明されおいたす。


ゞェンキンス宣蚀パむプラむンの立ち䞊げ



Jenkins Pipelineの起動プロセスは、次の手順で構成されおいたす。



  1. config.xmlファむルからゞョブの説明をロヌドしたす
  2. タスクを完了するために別のスレッド軜量パフォヌマヌを開始する
  3. パむプラむンスクリプトの読み蟌み
  4. 構文ツリヌの構築ず確認
  5. ゞョブ構成の曎新
  6. ゞョブの説明ずスクリプトで指定されたパラメヌタずプロパティを組み合わせる
  7. ゞョブの説明をファむルシステムに保存する
  8. グルヌノィヌなサンドボックスでスクリプトを実行する
  9. ゞョブ党䜓たたは単䞀のステップに察する゚ヌゞェントの芁求






パむプラむンゞョブが開始されるず、Jenkinsは別のスレッドを䜜成し、実行のためにゞョブをキュヌに送信し、スクリプトをロヌドした埌、タスクを完了するために必芁な゚ヌゞェントを決定したす。



このアプロヌチをサポヌトするために、特別なJenkinsスレッドプヌル軜量゚グれキュヌタヌが䜿甚されたす。それらがマスタヌで実行されおいるこずがわかりたすが、通垞の実行者のプヌルには圱響したせん。







このプヌル内のスレッドの数は制限されおいたせんこの蚘事の執筆時点。



パむプラむンの䜜業パラメヌタ。トリガヌずいく぀かのオプションだけでなく



パラメヌタの凊理は、次の匏で衚すこずができたす。







起動時に衚瀺されるゞョブパラメヌタから、前回の起動のパむプラむンパラメヌタが最初に削陀され、次に珟圚の起動のパむプラむンで指定されたパラメヌタが远加されたす。これにより、パラメヌタヌがパむプラむンから削陀された堎合に、パラメヌタヌをゞョブから削陀できたす。



それは裏返しにどのように機胜したすか



config.xmlゞョブの構成を栌玍するファむルの䟋を考えおみたしょう。



<?xml version='1.1' encoding='UTF-8'?>
<flow-definition plugin="workflow-job@2.35">
  <actions>
    <org.jenkinsci.plugins.pipeline.modeldefinition.actions.DeclarativeJobAction plugin="pipeline-model-definition@1.5.0"/>
    <org.jenkinsci.plugins.pipeline.modeldefinition.actions.DeclarativeJobPropertyTrackerAction plugin="pipeline-model-definition@1.5.0">
      <jobProperties>
        <string>jenkins.model.BuildDiscarderProperty</string>
      </jobProperties>
      <triggers/>
      <parameters>
        <string>parameter_3</string>
      </parameters>
    </org.jenkinsci.plugins.pipeline.modeldefinition.actions.DeclarativeJobPropertyTrackerAction>
  </actions>
  <description></description>
  <keepDependencies>false</keepDependencies>
  <properties>
    <hudson.model.ParametersDefinitionProperty>
      <parameterDefinitions>
        <hudson.model.StringParameterDefinition>
          <name>parameter_1</name>
          <description></description>
          <defaultValue></defaultValue>
          <trim>false</trim>
        </hudson.model.StringParameterDefinition>
        <hudson.model.StringParameterDefinition>
          <name>parameter_2</name>
          <description></description>
          <defaultValue></defaultValue>
          <trim>false</trim>
        </hudson.model.StringParameterDefinition>
        <hudson.model.StringParameterDefinition>
          <name>parameter_3</name>
          <description></description>
          <defaultValue></defaultValue>
          <trim>false</trim>
        </hudson.model.StringParameterDefinition>
      </parameterDefinitions>
    </hudson.model.ParametersDefinitionProperty>
    <jenkins.model.BuildDiscarderProperty>
      <strategy class="org.jenkinsci.plugins.BuildRotator.BuildRotator" plugin="buildrotator@1.2">
        <daysToKeep>30</daysToKeep>
        <numToKeep>10000</numToKeep>
        <artifactsDaysToKeep>-1</artifactsDaysToKeep>
        <artifactsNumToKeep>-1</artifactsNumToKeep>
      </strategy>
    </jenkins.model.BuildDiscarderProperty>
    <com.sonyericsson.rebuild.RebuildSettings plugin="rebuild@1.28">
      <autoRebuild>false</autoRebuild>
      <rebuildDisabled>false</rebuildDisabled>
    </com.sonyericsson.rebuild.RebuildSettings>
  </properties>
  <definition class="org.jenkinsci.plugins.workflow.cps.CpsScmFlowDefinition" plugin="workflow-cps@2.80">
    <scm class="hudson.plugins.filesystem_scm.FSSCM" plugin="filesystem_scm@2.1">
      <path>/path/to/jenkinsfile/</path>
      <clearWorkspace>true</clearWorkspace>
    </scm>
    <scriptPath>Jenkinsfile</scriptPath>
    <lightweight>true</lightweight>
  </definition>
  <triggers/>
  <disabled>false</disabled>
</flow-definition>


プロパティ セクションには、ゞョブの起動に䜿甚するパラメヌタ、トリガヌ、およびオプションが含たれおいたす。远加のセクションDeclarativeJobPropertyTrackerActionは、パむプラむンにのみ蚭定されたパラメヌタヌを栌玍するために䜿甚されたす。



パラメヌタがパむプラむンから削陀されるず、Jenkinsはパラメヌタがパむプラむンでのみ定矩されおいるこずを認識するため、DeclarativeJobPropertyTrackerActionずプロパティの䞡方からパラメヌタが削陀されたす。



パラメヌタを远加するず、状況が逆になり、パラメヌタはDeclarativeJobPropertyTrackerActionずプロパティに远加されたすが、パむプラむンの実行時のみです。



そのため、パむプラむンでのみパラメヌタを蚭定するず、最初の起動時には利甚できなくなりたす。



ゞェンキンスパむプラむン実行



Pipelineスクリプトがダりンロヌドされおコンパむルされるず、実行プロセスが開始されたす。しかし、このプロセスは単にグルヌノィヌなこずをするだけではありたせん。ゞョブの実行時に実行される䞻な重い操䜜を匷調したした



。Groovyコヌド



の実行パむプラむンスクリプトは垞にマスタヌで実行されたす。Jenkinsに䞍芁な負荷がかからないように、これを忘れおはなりたせん。゚ヌゞェントのファむルシステムたたはシステム呌び出しず察話するステップのみが゚ヌゞェントで実行されたす。







パむプラむンには、HTTPリク゚ストを䜜成できる優れたプラグむンがありたす。たた、回答をファむルに保存するこずもできたす。



httpRequest  url: 'http://localhost:8080/jenkins/api/json?pretty=true', outputFile: 'result.json'


最初は、このコヌドを゚ヌゞェントで完党に実行し、゚ヌゞェントから芁求を送信しお、応答をresult.jsonファむルに保存する必芁があるように思われる堎合がありたす。しかし、すべおが逆に発生し、リク゚ストはJenkins自身から実行され、ファむルの内容を保存するために゚ヌゞェントにコピヌされたす。パむプラむンでの応答の远加凊理が必芁ない堎合は、そのような芁求をcurlに眮き換えるこずをお勧めしたす。



sh  'curl "http://localhost:8080/jenkins/api/json?pretty=true" -o "result.json"'


ログずアヌティファクトの操䜜

コマンドが実行される゚ヌゞェントに関係なく、ログずアヌティファクトは凊理され、マスタヌファむルシステムにリアルタむムで保存されたす。



シヌクレット資栌情報がパむプラむンで䜿甚されおいる堎合、ログを保存する前に、マスタヌでさらにフィルタリングされたす。







ステップの保存パむプラむンの耐久性



Jenkins Pipelineは、独立した個別のピヌスで構成され、マスタヌがクラッシュしたずきに再珟できるタスクずしお䜍眮付けおいたす。ただし、タスクの蚭定に応じお、さたざたな詳现床のステップがシリアル化されおディスクに保存されるため、ディスクぞの远加の曞き蟌みでこれを支払う必芁がありたす。







パむプラむンの耐久性に応じお、パむプラむングラフのステップは、ゞョブの実行ごずに1぀以䞊のファむルに保存されたす。ドキュメントからの抜粋



ステップを栌玍するためのワヌクフロヌサポヌトプラグむンFlowNodeは、FlowNodeStorageクラスずそのSimpleXStreamFlowNodeStorageおよびBulkFlowNodeStorage実装を䜿甚したす。



  • FlowNodeStorageは、メモリ内キャッシュを䜿甚しおディスク曞き蟌みを集玄したす。バッファは実行時に自動的に曞き蟌たれたす。通垞、これに぀いお心配する必芁はありたせんが、FlowNodeを保存しおも、すぐにディスクに曞き蟌たれるずは限らないこずに泚意しおください。
  • SimpleXStreamFlowNodeStorageは、FlowNodeごずに1぀の小さなXMLファむルを䜿甚したす。ノヌドには゜フトリファレンスのメモリ内キャッシュを䜿甚したすが、これにより、最初にFlowNodeをトラバヌスするずきのパフォヌマンスが倧幅に䜎䞋したす。
  • BulkFlowNodeStorageは、すべおのFlowNodeを含む1぀の倧きなXMLファむルを䜿甚したす。このクラスは、曞き蟌み頻床がはるかに少ないPERFORMANCE_OPTIMIZED掻性モヌドで䜿甚されたす。1぀の倧きなストリヌミング曞き蟌みは、䞀連の小さなレコヌドよりも高速であり、OSの負荷を最小限に抑えおすべおの小さなファむルを管理するため、これは䞀般にはるかに効率的です。




元の
Storage: in the workflow-support plugin, see the 'FlowNodeStorage' class and the SimpleXStreamFlowNodeStorage and BulkFlowNodeStorage implementations.



  • FlowNodeStorage uses in-memory caching to consolidate disk writes. Automatic flushing is implemented at execution time. Generally, you won't need to worry about this, but be aware that saving a FlowNode does not guarantee it is immediately persisted to disk.
  • The SimpleXStreamFlowNodeStorage uses a single small XML file for every FlowNode — although we use a soft-reference in-memory cache for the nodes, this generates much worse performance the first time we iterate through the FlowNodes (or when)
  • The BulkFlowNodeStorage uses a single larger XML file with all the FlowNodes in it. This is used in the PERFORMANCE_OPTIMIZED durability mode, which writes much less often. It is generally much more efficient because a single large streaming write is faster than a bunch of small writes, and it minimizes the system load of managing all the tiny files.


保存されたステップは、次のディレクトリにありたす。



$JENKINS_HOME/jobs/$JOB_NAME/builds/$BUILD_ID/workflow/




サンプルファむル



<?xml version='1.1' encoding='UTF-8'?>
<Tag plugin="workflow-support@3.5">
  <node class="cps.n.StepStartNode" plugin="workflow-cps@2.82">
    <parentIds>
      <string>4</string>
    </parentIds>
    <id>5</id>
    <descriptorId>org.jenkinsci.plugins.workflow.support.steps.StageStep</descriptorId>
  </node>
  <actions>
    <s.a.LogStorageAction/>
    <cps.a.ArgumentsActionImpl plugin="workflow-cps@2.82">
      <arguments>
        <entry>
          <string>name</string>
          <string>Declarative: Checkout SCM</string>
        </entry>
      </arguments>
      <isUnmodifiedBySanitization>true</isUnmodifiedBySanitization>
    </cps.a.ArgumentsActionImpl>
    <wf.a.TimingAction plugin="workflow-api@2.40">
      <startTime>1600855071994</startTime>
    </wf.a.TimingAction>
  </actions>
</Tag>


結果



この資料が面癜く、パむプラむンずは䜕か、パむプラむンが内郚からどのように機胜するかをよりよく理解するのに圹立぀こずを願っおいたす。それでも質問がある堎合は、以䞋で共有しおください。喜んでお答えしたす。



蚘事の埌半では、ゞェンキンスパむプラむンの問題を芋぀けおタスクをスピヌドアップするのに圹立぀個々のケヌスに぀いお怜蚎したす。同時起動の問題を解決する方法を孊び、存続可胜性のオプションを確認し、Jenkinsをプロファむリングする必芁がある理由に぀いお説明したす。



All Articles