Sparrow多目的スクリプトシステムを使用したDockerコンテナの開発

この記事では、 Sparrow *多目的スクリプティングシステムを使用して、 Dockerコンテナー用のイメージアセンブリスクリプトを作成する方法について説明します。









(*)注-この記事の技術的なニュアンスの一部を理解するには、Sparrow多目的スクリプトシステムに少なくとも表面的に精通していることが望ましいです。







Dockerコンテナー開発



最初は少し問題があります。 Dockerfileを使用してDockerイメージのアセンブリを記述するタスクがあります。 ビルドスクリプトが重要で、多くの指示が含まれている場合は、どうにかして抜け出す必要があります。 Dockerfileに120を超えるレイヤーを含めることはできないという事実(私がDockerのドキュメントから正しく理解している限り)に加えて、Dockerfileの拡散に対処することはあまり快適ではありません。 あなたはそれについて何ができますか? 明らかなオプションは、個別のBashスクリプトのアセンブリコードを作業ディレクトリに転送し、そこからシステムのインストールと構成を直接行うことです。 もう1つの方法は、chefやansibleなどの構成管理ツールを側面に「ねじ込む」ことです。 これらの選択肢を評価して(賛否両論ある私見)、Sparrowを使用する3番目の方法を提案するのは読者にお任せします。







実装の詳細を説明する前に、次のことを言いたいと思います。









実装例



そのため、特定のシステム上のすべてを表示します。 CentOSディストリビューションを使用してイメージを構築し、 Rubyバージョン2.3で記述されたアプリケーションをインストールする必要があります。 その後、選択したユーザーの下からメインアプリケーションスクリプトを実行します。 アプリケーションのソースコードは、アーカイブサーバーからダウンロードされます。 この例は実際の生活から取られていますが、記事が資料で過負荷にならないように、一部の詳細は意図的に省略されています。







基本的なシステム構成



プラグインコードを記述する前に、Dockerfileを作成します。 基本的なイメージでは、その明るさのためにtutum / centosを撮りました 。 同じ理由で、パッケージの一部を配信する必要がありますが、一般にこれは問題ではありません。







 $ cat Dockerfile FROM tutum/centos MAINTAINER "melezhik" <melezhik@gmail.com> RUN yum clean all RUN yum -y install nano git-core RUN yum -y install make RUN yum -y install gcc RUN yum -y install perl perl-devel \ perl-Test-Simple perl-Digest-SHA perl-Digest-MD5 perl-CPAN-Meta \ perl-CPAN-Meta-Requirements perl-Getopt-Long \ perl-JSON perl-Module-CoreList perl-Module-Metadata perl-parent perl-Path-Tiny perl-Try-Tiny \ perl-App-cpanminus perl-JSON-PP perl-Algorithm-Diff perl-Text-Diff \ perl-Spiffy perl-Test-Base perl-YAML perl-File-ShareDir-Install perl-Class-Inspector \ perl-File-ShareDir perl-File-ShareDir-Install perl-Config-General RUN cd /bin/ && curl -L https://cpanmin.us/ -o cpanm && chmod +x cpanm RUN cpanm Sparrow -q
      
      





Dockerfileに関するいくつかのコメント。









それでは、画像を作成してみましょう。







 $ docker build -t ruby_app . ... ... Successfully built 25e7cd784c99
      
      





プラグインの開発を始めましょう



基本的なインフラストラクチャを備えたイメージがあります。Dockerコンテナーを起動し、その上で直接プラグインの開発を開始できます。







 $ docker run -t -i ruby_app /bin/bash $ mkdir ruby-app $ cd ruby-app $ git init . $ git remote add origin https://github.com/melezhik/ruby-app.git $ touch README.md $ git add README.md $ git config --global user.email "melezhik@gmail.com" $ git config --global user.name "Alexey Melezhik" $ git commit -a -m 'first commit' $ git push -u origin master
      
      





上記のコマンドを使用して、プラグインのプロジェクトテンプレートを作成し、すべてをリモートgitリポジトリにコミットしました。 リポジトリのURLを覚えておいて、後でdocker build



して本格的なイメージアセンブリを実行するときに必要になります。







それでは、少し余談します。 タスクを思い出してください。 便宜上、独立した部分に分割してみましょう。









論理的に独立したタスクのために、Sparrowにはモジュールメカニズムがあり、それを使用します。 しかし、最初に、タスクの実行を異なるモジュールに委任するメインストーリーを作成しましょう。 したがって、すべてが同じ実行中のDockerコンテナー上にあります。







 $ nano hook.bash action=$(config action) for s in $action do run_story $s done set_stdout install-ok $ nano story.check install-ok
      
      





コードに関するいくつかのコメント。 フックファイル(hook.bash)で指定された3つのセカンダリストーリー(モジュール)と1つのメインストーリーがあり、すべてがどのように機能するかを示すために、モジュール内のスクリプトのスタブを作成します。 はい。入力パラメーターaction



のデフォルト値はsuite.ini



ファイルで設定する必要があります。







 $ nano suite.ini action create-user install-ruby install-app
      
      





スクリプトスタブを作成します。







 $ mkdir -p modules/create-user $ mkdir -p modules/install-ruby $ mkdir -p modules/install-app $ nano modules/create-user/story.bash echo create-user-ok $ nano modules/install-ruby/story.bash echo install-ruby-ok $ nano modules/install-app/story.bash echo install-app-ok
      
      





また、テストファイル:







 $ nano modules/create-user/story.check create-user-ok $ nano modules/install-ruby/story.check install-ruby-ok $ nano modules/install-app/story.check install-app-ok
      
      





すべてをstrunで実行します-Sparrowスクリプトを実行するコンソールスクリプト:







 $ strun /tmp/.outthentic/93/ruby-app/story.t .. # [/ruby-app/modules/create-user] # create-user-ok ok 1 - output match 'create-user-ok' # [/ruby-app/modules/install-ruby] # install-ruby-ok ok 2 - output match 'install-ruby-ok' # [/ruby-app/modules/install-app] # install-app-ok ok 3 - output match 'install-app-ok' # [/ruby-app] # install-ok ok 4 - output match 'install-ok' 1..4 ok All tests successful. Files=1, Tests=4, 0 wallclock secs ( 0.00 usr 0.02 sys + 0.09 cusr 0.01 csys = 0.12 CPU) Result: PASS
      
      





素晴らしい。 すべてのスクリプトが正常に動作したことがわかります。これが将来のプラグインの骨組みになります。 モジュールのプラグをシミュレートするだけです。







ユーザー作成スクリプト



ユーザー名はカスタマイズ可能であり、デフォルト値はファイルsuite.ini



決定されるという事実から進めます。







 $ cat suite.ini action create-user install-ruby install-app user_name app-user
      
      





スクリプトの実装:







 $ nano modules/create-user/story.bash user_id=$(config user_name) echo create user id: $user_id useradd -r -m -d /home/$user_id $user_id || exit 1 ls -d /home/$user_id || exit 1 id $user_id || exit 1 echo create-user-ok
      
      





そして、起動します(ここでは、 action



パラメーターを使用して別のスクリプトを実行する機会を取りました)。







 $ strun --param action=create-user /tmp/.outthentic/135/ruby-app/story.t .. # [/ruby-app/modules/create-user] # create user id: app-user # /home/app-user # uid=997(app-user) gid=995(app-user) groups=995(app-user) # create-user-ok ok 1 - output match 'create-user-ok' # [/ruby-app] # install-ok ok 2 - output match 'install-ok' 1..2 ok All tests successful. Files=1, Tests=2, 0 wallclock secs ( 0.03 usr 0.00 sys + 0.11 cusr 0.04 csys = 0.18 CPU) Result: PASS
      
      





スクリプトが機能し、ユーザーが作成されたことがわかります。 スクリプト内のほとんどのBashコマンドは、慣用的なcmd || exit 1



終わることに注意してください。 cmd || exit 1



strun



はスクリプト実行コードをチェックし、失敗した場合、対応するテストは次のように失敗します-システムに対して無効な名前のユーザーを作成してください:







 $ strun --param action=create-user --param user_name='/' /tmp/.outthentic/160/ruby-app/story.t .. # [/ruby-app/modules/create-user] # create user id: / # useradd: invalid user name '/' not ok 1 - scenario succeeded not ok 2 - output match 'create-user-ok' # [/ruby-app] # install-ok ok 3 - output match 'install-ok' 1..3 # Failed test 'scenario succeeded' # at /usr/local/share/perl5/Outthentic.pm line 167. # Failed test 'output match 'create-user-ok'' # at /usr/local/share/perl5/Outthentic.pm line 213. # Looks like you failed 2 tests of 3. Dubious, test returned 2 (wstat 512, 0x200) Failed 2/3 subtests Test Summary Report ------------------- /tmp/.outthentic/160/ruby-app/story.t (Wstat: 512 Tests: 3 Failed: 2) Failed tests: 1-2 Non-zero exit status: 2 Files=1, Tests=3, 0 wallclock secs ( 0.02 usr 0.00 sys + 0.10 cusr 0.00 csys = 0.12 CPU) Result: FAIL
      
      





ここで少し余談します。 本質的に、スクリプト完了コードの検証で十分な場合、検証ファイルが必要な理由を自問してみましょう。 合理的な質問。 Sparrowフレームワークの検証ルールは、スクリプトの実行を制御または検証する代替方法と考えることができます。 Sparrowのイデオロギーでは、実行されるスクリプトは実行されるスクリプトであるという意味で履歴であり、ほとんどの場合、その作業について何かを「報告」します。比fig的に言えば、「歴史に跡を残す」。 このトレースは標準出力ストリームの標準出力であり、その内容を検証できます。 なぜ役立つのか:









具体例として、rvmを介してRubyインストールスクリプトを引用することができます。これは、計画のリストの次に進みます。







rvmからのRubyインストールスクリプト



インストールスクリプトは次のようになります。







 $ nano modules/install-ruby/story.bash yum -y install which curl -sSL https://rvm.io/mpapis.asc | gpg2 --import - || exit 1 \curl -sSL https://get.rvm.io | bash -s stable --ruby || exit 1 source /usr/local/rvm/scripts/rvm gem install bundler --no-ri --no-rdoc echo ruby version: $(ruby --version) bundler --version echo install-ruby-ok
      
      





そして、これは検証ファイルです:







 $ nano modules/install-ruby/story.check regexp: ruby version: ruby 2\.3 install-ruby-ok
      
      





次に、このスクリプトを実行します。







 $ strun --param action=install-ruby #    #   # ... # ... # ... # ruby version: ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-linux] # Bundler version 1.12.5 # install-ruby-ok ok 1 - output match /ruby version: ruby 2\.3/ ok 2 - output match 'install-ruby-ok' # [/ruby-app] # install-ok ok 3 - output match 'install-ok' 1..3 ok All tests successful. Files=1, Tests=3, 91 wallclock secs ( 0.03 usr 0.00 sys + 3.24 cusr 1.03 csys = 4.30 CPU) Result: PASS
      
      





インストールされているRubyのバージョンを検証するために、検証ルールを正規表現として使用したことに注意してください。







 regexp: ruby version: ruby 2\.3
      
      





もちろん、rvmを使用すると、必要なバージョンを明示的にインストールできます。テストファイルで定義されたチェックにより、最小限の労力でスクリプトの追加検証を追加できる場合、ここに例を挙げます。







これで、アプリケーションのインストールスクリプトに進むことができます。







アプリケーションインストールスクリプト



思い出させてください。 以下が必要です。









以上です。 もちろん、実際のアプリケーションでは、何らかの種類のサービスを開始するか、追加の操作を実行する必要がありますが、これでプラグインの操作を実証するには十分です。







繰り返しますが、簡単にするために、次のもので構成されるRubyアプリケーションを用意します









アーカイブ全体をパックし、すべてをアーカイブサーバーとローカルnginxにアップロードします。これで、配布がURLで利用可能になります。







 127.0.0.1/app.tar.gz
      
      





スクリプトコードを更新します。







 $ cat suite.ini action create-user install-ruby install-app user_name app-user source_url 127.0.0.1/app.tar.gz $ cat modules/install-app/story.bash user_id=$(config user_name) source_url=$(config source_url) yum -y -q install sudo echo downloading $source_url ... sudo -u $user_id -E bash --login -c "curl -f -o ~/app.tar.gz $source_url -s" || exit 1 echo unpacking tarball ... sudo -u $user_id -E bash --login -c "cd ~/ && tar -xzf app.tar.gz" || exit 1 echo installing dependencies via bundler sudo -u $user_id -E bash --login -c "cd ~/app && bundle install --quiet --path vendor/bundle " || exit 1 sudo -u $user_id -E bash --login -c "cd ~/app && bundle exec ruby hello.rb " || exit 1 echo install-app-ok $ nano modules/install-app/story.check install-app-ok Hello World
      
      





小さなスクリプトコメント:









そのため、スクリプトを実行します。







 $ strun --param action=install-app /tmp/.outthentic/16462/ruby-app/story.t .. # [/ruby-app/modules/install-app] # Package sudo-1.8.6p7-17.el7_2.x86_64 already installed and latest version # downloading 127.0.0.1/app.tar.gz ... # unpacking app ... # installing dependencies via bundler # Hello World # install-app-ok ok 1 - output match 'install-app-ok' ok 2 - output match 'Hello World' # [/ruby-app] # install-ok ok 3 - output match 'install-ok' 1..3 ok All tests successful. Files=1, Tests=3, 2 wallclock secs ( 0.01 usr 0.00 sys + 1.61 cusr 0.50 csys = 2.12 CPU) Result: PASS
      
      





アプリケーションが実際にインストールされ、 hello.rb



スクリプトhello.rb



起動されるのがhello.rb



ます。 別の「偏執病」アサートをテストファイルに追加して、Sparrow検証システムの機能を実証します。







 $ nano modules/install-app/story.check install-app-ok Hello World generator: <<CODE !bash if test -d /home/$(config user_name)/app; then echo assert: 1 directory /home/$(config user_name)/app exists else echo assert: 0 directory /home/$(config user_name)/app exists fi CODE
      
      





そして、スクリプトを再度実行します。







 $ strun --param action=install-app
      
      





出力では次のようになります。







 $ ok 3 - directory /home/app-user/app exists
      
      





Sparrowプラグインの公開



これでプラグインの作成が完了しました。 変更をコミットし、gitリポジトリにプッシュします。







 $ git add . $ git commit -a -m 'all done' $ git push $ exit
      
      





不要になったdockerコンテナは残しました。削除できます:







 $ docker rm 5e1037fa4aef
      
      





Dockerコンテナーの完全なイメージビルドサイクル



Dockerfileをわずかに変更します。Sparrowプラグインのコードを配置したリモートgitリポジトリへのリンクが必要であることを忘れないでください。最終バージョンは次のようになります。







 FROM tutum/centos MAINTAINER "melezhik" <melezhik@gmail.com> RUN yum clean all RUN yum -y install nano git-core RUN yum -y install make RUN yum -y install gcc RUN yum -y install perl perl-devel \ perl-Test-Simple perl-Digest-SHA perl-Digest-MD5 perl-CPAN-Meta \ perl-CPAN-Meta-Requirements perl-Getopt-Long \ perl-JSON perl-Module-CoreList perl-Module-Metadata perl-parent perl-Path-Tiny perl-Try-Tiny \ perl-App-cpanminus perl-JSON-PP perl-Algorithm-Diff perl-Text-Diff \ perl-Spiffy perl-Test-Base perl-YAML perl-File-ShareDir-Install perl-Class-Inspector \ perl-File-ShareDir perl-File-ShareDir-Install perl-Config-General RUN cd /bin/ && curl -L https://cpanmin.us/ -o cpanm && chmod +x cpanm RUN cpanm Sparrow -q RUN echo ruby-app https://github.com/melezhik/ruby-app.git > /root/sparrow.list RUN sparrow plg install ruby-app RUN sparrow plg run ruby-app
      
      





これで、すべてのイメージアセンブリサイクルを実行して、すべてを新たに「失う」ことができます。







 $ docker build -t ruby_app --no-cache=true .
      
      





その結果、目的のシステムでDockerイメージを取得します。







おわりに



Sparrow多目的スクリプトシステムを使用すると、Dockerイメージを構築するための効果的なツールとなります。 主要なDockerfileをシンプルかつ簡潔なままにして、必要なシステムの実際の構成スクリプトを開発するプロセスを簡素化して、複雑な構成を構築できます。







ご清聴ありがとうございました。







いつものように、私は質問と建設的な批判を待っています! :)







アレクセイ








All Articles