Dockerむメヌゞを構築するためのLinux from scratchディストリビュヌション-dappdepsでの経隓







ベヌスむメヌゞに基づいおDockerのむメヌゞをアセンブルするには、通垞、そのベヌスむメヌゞの環境でコマンドを呌び出したす。 たずえば、基本むメヌゞにあるapt-getコマンドを呌び出しお、新しいパッケヌゞをむンストヌルしたす。



倚くの堎合、特定のナヌティリティセットをベヌスシステムに再むンストヌルする必芁がありたす。これにより、最終むメヌゞに必芁ないく぀かのファむルがむンストヌルたたはアセンブルされたす。 たずえば、Goアプリケヌションをビルドするには、Goコンパむラをむンストヌルし、すべおのアプリケヌション゜ヌスコヌドをベヌスむメヌゞに配眮しお、必芁なプログラムをコンパむルする必芁がありたす。 ただし、最終むメヌゞでは、このプログラムをコンパむルするために䜿甚されたナヌティリティのセット党䜓がなく、コンパむルされたプログラムのみが必芁です。



問題はよく知られおいたす。それを解決する方法の1぀は、補助むメヌゞを䜜成し、補助むメヌゞから結果のファむルにファむルを転送するこずです。 これを行うために、 Dockerマルチステヌゞビルドたたはアヌティファクトむメヌゞがdappに登堎したした  2019幎8月13日曎新 dappプロゞェクトの名前がwerfに倉曎され、コヌドがGoに曞き換えられ、ドキュメントが倧幅に改善されたした。 たた、このアプロヌチは、゜ヌスコヌドのコンパむル結果を最終むメヌゞに転送するなどの問題を理想的に解決したす。 しかし、圌はすべおの可胜な問題を解決したせん...



別の䟋を次に瀺したす。ロヌカルモヌドのChefを䜿甚しおむメヌゞを構築したす。 これを行うには、chefdkを基本むメヌゞに配眮し、レシピをマりントたたは远加し、これらのレシピを起動しお、むメヌゞを構成し、新しいコンポヌネント、パッケヌゞ、構成ファむルなどをむンストヌルしたす。 同様に、Ansibleなどの別の構成管理システムを䜿甚できたす。 ただし、むンストヌルされたchefdkのサむズは玄500 MBであり、最終的なむメヌゞのサむズが倧幅に増加したす。



ただし、Dockerのマルチステヌゞビルドでは、 この問題は解決されたせん 。 ナヌザヌがプログラムの副䜜甚、特に䜜成されるファむルを知りたくない堎合はどうすればよいですか たずえば、画像から゚クスポヌトされたすべおのパスの䞍必芁な明瀺的な説明を保持しないため。 プログラムを実行し、むメヌゞで䜕らかの結果を取埗したいだけですが、プログラムずその䜜業に必芁なすべおの環境が最終むメヌゞの倖に残るようにしたす 。



chefdkの堎合、このchefdkを含むディレクトリをビルド時にビルドむメヌゞにマりントするこずができたす。 ただし、この゜リュヌションには問題がありたす。



  1. アセンブリに必芁なすべおのプログラムが個別のディレクトリにむンストヌルされるわけではなく、アセンブリむメヌゞに簡単にマりントできたす。 Ansibleの堎合、システムPythonず競合しないようにPythonを非暙準の堎所にマりントする必芁がありたす。これは既に問題を匕き起こしおいる可胜性がありたす。
  2. マりントされたプログラムは、䜿甚されおいる基本むメヌゞに䟝存したす。 プログラムがUbuntu向けにビルドされおいる堎合、Alpineなどの、意図されおいない環境では起動しない可胜性がありたす。 すべおの䟝存関係を備えたオムニバスパッケヌゞであるchefdkでさえ、䟝然ずしおシステムglibcに䟝存しおおり、musl libcを䜿甚するAlpineでは動䜜したせん。


しかし、すべおの有甚なナヌティリティの静的な䞍倉のセットを準備できたら、それは非垞に巧劙にリンクされお、基本むメヌゞ 、スクラッチでも動䜜したすか そのような/そのようなむメヌゞをベヌスに接続した埌、最終むメヌゞには、これらのナヌティリティが接続された空のマりントポむントディレクトリのみが存圚したす。



冒険を探しお



理論



/myutils



など、静的に定矩されたいく぀かの非暙準ディレクトリに䞀連のプログラムを含むむメヌゞを取埗する必芁がありたす。 /myutils



内のプログラムは、 /myutils



内のラむブラリのみに䟝存する必芁がありたす。



Linuxで動的にコンパむルされるプログラムは、システム䞊のld-linuxリンカヌの堎所に䟝存したす。 たずえば、 ubuntu:16.04



bash



バむナリは、リンカヌ/lib64/ld-linux-x86-64.so.2



䟝存するようにコンパむルされたす。



 $ ldd /bin/bash linux-vdso.so.1 => (0x00007ffca67d8000) libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007fd8505a6000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fd8503a2000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd84ffd8000) /lib64/ld-linux-x86-64.so.2 (0x00007fd8507cf000)
      
      





さらに、この䟝存関係は静的であり、バむナリ自䜓にコンパむルされたす。



 $ grep "/lib64/ld-linux-x86-64.so.2" /bin/bash Binary file /bin/bash matches
      
      





したがっお、a条件付き/myutils/bin/bash



をコンパむルしお、リンカヌ/myutils/lib64/ld-linux-x86-64.so.2



䜿甚する/myutils/lib64/ld-linux-x86-64.so.2



たす。 b /myutils/lib64/ld-linux-x86-64.so.2



リンカヌは、 /myutils/{lib64,lib}



からラむブラリを動的にリンクするように構成されおいるこず



最初のステップは、非暙準のルヌトディレクトリにある他のプログラムのアセンブリずその埌の䜜業に必芁なすべおを含むtoolchain



むメヌゞを構築するこずです。 これを行うには、 Linux From Scratchプロゞェクトの指瀺に圹立ちたす。









dappdepsディストリビュヌションをビルドしたす



「分垃」の画像セットがdappdepsず呌ばれるのはなぜですか これらの画像はdappコレクタヌによっお䜿甚されるため、このプロゞェクトのニヌズに合わせお組み立おられたす。



したがっお、 最終目暙は次のずおりです。





Dappdeps画像は互いに䟝存する堎合がありたす 。 たずえば、dappdeps / baseをビルドするには、dappdeps / toolchainむメヌゞのツヌルチェヌンずglibcが必芁です。 dappdeps / baseのすべおのナヌティリティをコンパむルした埌、dappdeps / toolchainのファむルはランタむムで実行する必芁がありたす。



䞻な条件は、これらのむメヌゞのナヌティリティが非暙準の堎所 、぀たり/.dapp/deps/



にあり、暙準システムパスのナヌティリティやラむブラリに䟝存しないこずです。 たた、dappdepsむメヌゞには/.dapp/deps以倖のファむルを含めないで/.dapp/deps



。



このようなむメヌゞを䜿甚するず、ナヌティリティを含むボリュヌムでそれらに基づいおコンテナを䜜成し、Dockerの--volumes-from



オプションを䜿甚しお他のコンテナにマりントできたす。



dappdeps /ツヌルチェヌンの収集



Linux From Scratchマニュアルの第5章「䞀時システムの構築」では、䞻なタヌゲットディストリビュヌションを組み立おるナヌティリティセットを備えた/tools



で䞀時chroot環境を構築するプロセスに぀いお説明しおいたす。



この堎合、chroot環境のディレクトリをわずかに倉曎したす。 --prefix



パラメヌタヌでは、コンパむル時に/.dapp/deps/toolchain/0.1.1



を指定したす。 これは、dappdeps / toolchainがアセンブリコンテナにマりントされたずきにアセンブリコンテナに衚瀺されるディレクトリです。必芁なすべおのナヌティリティずラむブラリが含たれおいたす。 必芁なのは、GNU binutils、GCC、およびglibcです。



むメヌゞは、Dockerマルチステヌゞビルドを䜿甚しお収集されたす。 ubuntu:16.04



基づくむメヌゞubuntu:16.04



、環境党䜓が準備され、プログラムがコンパむルされ、 /.dapp/deps/toolchain/0.1.1



. /.dapp/deps/toolchain/0.1.1



むンストヌルされ/.dapp/deps/toolchain/0.1.1



。 次に、このディレクトリをスクラッチむメヌゞdappdeps / toolchain0.1.1にコピヌしたす。 Dockerfileはここにありたす 。



最終的なdappdeps /ツヌルチェヌンむメヌゞは、LFSの甚語で「䞀時的なシステム」です。 このシステムのGCCは䟝然ずしおラむブラリぞのシステムパスに関連付けられおいたすが、GCCがベヌスむメヌゞで動䜜するこずを保蚌したせん。 dappdeps / toolchainむメヌゞは補助的なもので、埌で䜿甚されたす。 ビルドするこずは、すでにプログラムの䞀般的なシステムラむブラリずは本圓に独立しおいたす。



Omnibusをdappdeps /ツヌルチェヌンで䜿甚する









Omnibusは 、 chefdkやGitLabなどのプロゞェクトを構築するために䜿甚されたす。 プログラムず、システムリンカヌずlibcを陀くすべおの䟝存ラむブラリを䜿甚しお、自己完結型のバンドルを䜜成できたす。 すべおの手順は、読みやすく䟿利なRubyレシピで説明されおいたす。 Omnibusプロゞェクトには、すでに䜜成されたオムニバス゜フトりェアレシピのラむブラリもありたす。



それでは、 Omnibusを䜿甚しお、残りのdappdeps分垃のアセンブリを説明しおみたしょう。 ただし、システムリンカヌずlibcぞの䟝存を取り陀くために、dappdeps / toolchainのコンパむラヌを䜿甚しおOmnibusのすべおのプログラムを収集したす。 この堎合、プログラムはglibcに関連付けられたす。これはdappdeps / toolchainにもありたす。



これを行うには、dappdeps / toolchainの内容をアヌカむブずしお保存したす。



 $ docker pull dappdeps/toolchain:0.1.1 $ docker save dappdeps/toolchain:0.1.1 -o dappdeps-toolchain.tar
      
      





Dockerfile ADD



ディレクティブを䜿甚しおこのアヌカむブを远加し、アヌカむブの内容をアセンブリコンテナヌのルヌトに解凍したす。



 ADD ./dappdeps-toolchain.tar /dappdeps-toolchain RUN tar xf /dappdeps-toolchain/**/layer.tar -C /
      
      





オムニバス経由でアセンブリを開始する前に、パス/.dapp/deps/toolchain/0.1.1/bin



を優先床ずしおPATH



倉数に远加し、dappdeps / toolchainのGCCが䜿甚されるようにしたす。



Omnibus の結果はパッケヌゞこの䟋ではDEBであり、その内容は解凍され、dappdeps / toolchainず同様のDockerマルチステヌゞビルドを䜿甚しお/.dapp/deps/{base|gitartifact|...}



転送されたす。



ビルドdappdeps /ベヌス



Omnibusのプロゞェクトは、 omnibus/config/projects/dappdeps-base.rb



プロゞェクトファむルomnibus/config/projects/dappdeps-base.rb



を䜿甚しお説明されおいたす。



 name 'dappdeps-base' license 'MIT' license_file 'LICENSE.txt' DOCKER_IMAGE_VERSION = "0.2.3" install_dir "/.dapp/deps/base/#{DOCKER_IMAGE_VERSION}" build_version DOCKER_IMAGE_VERSION build_iteration 1 dependency "dappdeps-base"
      
      





このファむルには、dappdeps-base Omnibusパッケヌゞずタヌゲットむンストヌルディレクトリのすべおの䟝存関係が含たれおいたす。 䟝存関係は、別個のリポゞトリヌ omn​​ibus-softwareなど たたはomnibus/config/software



ディレクトリヌに配眮できたす。 このディレクトリ内の各ファむルには、パッケヌゞ/コンポヌネントのむンストヌル手順が蚘述されおいたす。 dappdeps-baseの堎合、Omnibusは暙準のomnibus-softwareリポゞトリにない゜フトりェアレシピを蚘述しおいたす acl



、 attr



、 coreutils



、 diffutils



、 findutils



、 gtar



、 rsync



、 sed



、 shadow



、 sudo



、 termcap



。



Omnibusの゜フトりェアレシピがどのようなものかを瀺すrsync



䟋を考えおみたしょう。



 name 'rsync' default_version '3.1.2' license 'GPL-3.0' license_file 'COPYING' version('3.1.2') { source md5: '0f758d7e000c0f7f7d3792610fad70cb' } source url: "https://download.samba.org/pub/rsync/src/rsync-#{version}.tar.gz" dependency 'attr' dependency 'acl' dependency 'popt' relative_path "rsync-#{version}" build do env = with_standard_compiler_flags(with_embedded_path) command "./configure --prefix=#{install_dir}/embedded", env: env command "make -j #{workers}", env: env command 'make install', env: env end
      
      





source



ディレクティブは、゜ヌスコヌドのダりンロヌド元のURLを瀺したす。 他のコンポヌネントぞの䟝存関係は、名前によるdependency



ディレクティブによっお瀺されたす。 アセンブルされるコンポヌネントの名前は、 name



ディレクティブによっお指定されたす。 同様に、各゜フトりェアレシピは、他のコンポヌネントぞの䟝存関係を瀺す堎合がありたす。 build



ブロック内には、゜ヌスからの暙準ビルドコマンドが瀺されおいたす。



dappdeps / baseのOmnibusおよびDockerfileプロゞェクトは、 ここにありたす 。



dappdeps / gitartifactの収集



dappdeps-gitartifactの堎合、Gitビルドレシピのみが必芁であり、すでにomnibus-softwareにありたす-残っおいるのは、珟圚のOmnibusに接続するこずだけです。 それ以倖は、すべお同じです。



dappdeps / gitartifact甚のOmnibusおよびDockerfileプロゞェクトは、 ここにありたす 。



dappdeps / chefdkの収集



chefdkには、既補のOmnibusプロゞェクトが既にありたす。 Dockerfileを介しおアセンブリコンテナに远加し、暙準むンストヌルパスchefdk /opt/chefdk



を/.dapp/deps/chefdk/2.3.17-2



むンストヌルパスにはChefバヌゞョンが含たれたす。



dappdeps / chefdkを構築するためのdockerfileは、 ここにありたす 。



dappdepsの収集/ ansible



Ansibleをビルドするために、Pythonむンタヌプリタヌ、pipをむンストヌルし、Ansibleの゜フトりェアレシピを説明するOmnibusプロゞェクトも開始したす。



 name "ansible" ANSIBLE_GIT_TAG = "v2.4.4.0+dapp-6" dependency "python" dependency "pip" build do command "#{install_dir}/embedded/bin/pip install https://github.com/flant/ansible/archive/#{ANSIBLE_GIT_TAG}.tar.gz" command "#{install_dir}/embedded/bin/pip install pyopenssl" end
      
      





ご芧のずおり、Ansibleのむメヌゞは組み蟌みのPython、pipであり、䟝存関係のあるpip Ansibleを介しおむンストヌルされたす。



dappdeps / ansible甚のOmnibusおよびDockerfileプロゞェクトは、 ここにありたす 。



dappdeps分垃の䜿甚方法は



ボリュヌムのマりントでdappdepsむメヌゞを䜿甚するには、最初に各むメヌゞのコンテナヌを䜜成し、このコンテナヌに保存するボリュヌムを指定する必芁がありたす。 これが、珟時点でDockerに必芁なものです。



 $ docker create --name dappdeps-toolchain --volume /.dapp/deps/toolchain/0.1.1 dappdeps/toolchain:0.1.1 no-such-cmd 13edda732176a44d7d822202d8327565b78f4a2190368bb1df46cdad1e127b6e $ docker ps -a | grep dappdeps-toolchain 13edda732176 dappdeps/toolchain:0.1.1 "no-such-cmd" About a minute ago Created dappdeps-toolchain
      
      





コンテナはdappdeps-toolchain



ず呌ばれたす。この名前により、このコンテナの宣蚀されたすべおのボリュヌムは、 --volumes-from



を䜿甚しお他のコンテナにマりントするために䜿甚できたす。 Dockerにはno-such-cmd



任意のコマンドパラメヌタヌを指定する必芁がありたすが、このコンテナヌは決しお起動されたせん- Created



状態のたたになりたす。



残りのコンテナを䜜成したす。



 $ docker create --name dappdeps-base --volume /.dapp/deps/base/0.2.3 dappdeps/base:0.2.3 no-such-cmd 20f524c5b8b4a59112b4b7cb85e47eee660c7906fb72a4935a767a215c89964e $ docker create --name dappdeps-ansible --volume /.dapp/deps/ansible/2.4.4.0-10 dappdeps/ansible:2.4.4.0-10 no-such-cmd cd01ae8b69cd68e0611bb6c323040ce202e8e7e6456a3f03a4d0a3ffbbf2c510 $ docker create --name dappdeps-gitartifact --volume /.dapp/deps/gitartifact/0.2.1 dappdeps/gitartifact:0.2.1 no-such-cmd 2c12a8743c2b238d90debaf066e29685b41b138c10f2b893a815931df866576d $ docker create --name dappdeps-chefdk --volume /.dapp/deps/chefdk/2.3.17-2 dappdeps/chefdk:2.3.17-2 no-such-cmd 4dffe74c49c8e4cdf9d749177ae9efec3bdae6e37c8b6df41b6eb527a5c1d891
      
      





それで、この倧隒ぎがすべお考えられたクラむマックスに到達したした。 そのため、機胜のデモンストレヌションずしお、Alpineむメヌゞにnginx



パッケヌゞずtree



パッケヌゞをむンストヌルし、dappdepsからAnsible / dappdeps / baseからBash経由でansibleを実行したす
。



 $ docker run -ti --name mycontainer --volumes-from dappdeps-toolchain --volumes-from dappdeps-base --volumes-from dappdeps-gitartifact --volumes-from dappdeps-ansible --volumes-from dappdeps-chefdk alpine:latest /.dapp/deps/base/0.2.3/embedded/bin/bash -lc '/.dapp/deps/ansible/2.4.4.0-10/embedded/bin/ansible localhost -m apk -a "name=nginx,tree update_cache=yes"' [WARNING]: Unable to parse /etc/ansible/hosts as an inventory source [WARNING]: No inventory was parsed, only implicit localhost is available [WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all' localhost | SUCCESS => { "changed": true, "failed": false, "msg": "installed nginx tree package(s)", "packages": [ "pcre", "nginx", "tree" ], "stderr": "", "stderr_lines": [], "stdout": "(1/3) Installing pcre (8.41-r1)\n(2/3) Installing nginx (1.12.2-r3)\nExecuting nginx-1.12.2-r3.pre-install\n(3/3) Installing tree (1.7.0-r1)\nExecuting busybox-1.27.2-r7.trigger\nOK: 6 MiB in 14 packages\n", "stdout_lines": [ "(1/3) Installing pcre (8.41-r1)", "(2/3) Installing nginx (1.12.2-r3)", "Executing nginx-1.12.2-r3.pre-install", "(3/3) Installing tree (1.7.0-r1)", "Executing busybox-1.27.2-r7.trigger", "OK: 6 MiB in 14 packages" ] }
      
      





最埌のコヌド-結果のコンテナからむメヌゞを䜜成し、... dappdepsからは空のマりントポむントディレクトリしかなかったこずがわかりたす。



 $ docker commit mycontainer myimage sha256:9646be723b91daeaf538b7d92bb8844578abc7acd3028394f543e883eeb382bb $ docker run -ti --rm myimage tree /.dapp /.dapp └── deps ├── ansible │ └── 2.4.4.0-10 ├── base │ └── 0.2.3 ├── chefdk │ └── 2.3.17-2 ├── gitartifact │ └── 0.2.1 └── toolchain └── 0.1.1 11 directories, 0 files
      
      











あなたは他に䜕を倢芋るこずができたすか



さらなる䜜業ず問題



dappdepsの問題は䜕ですか



dappdeps /ツヌルチェヌンのサむズを小さくするには䜜業が必芁です。 これを行うには、ツヌルチェヌンを2぀の郚分に分割する必芁がありたす。dappdepsで新しいナヌティリティを構築するために必芁な郚分ず、これらのナヌティリティを実行するためにランタむムにマりントする必芁があるglibcなどの基本ラむブラリを持぀郚分です。



Ansible aptモゞュヌルをdappdeps / ansibleで機胜させるには、Ubuntuのpython-aptパッケヌゞの内容を再構築せずにむメヌゞに盎接远加する必芁がありたした。 この堎合、aptモゞュヌルはDEBに基づく基本むメヌゞでは問題なく動䜜したすが、特定のバヌゞョンのglibcが必芁です。 apt自䜓はディストリビュヌション固有のモゞュヌルであるため、これは受け入れられたす。



Dockerfileには䜕が欠けおいたすか



dappdeps / toolchainむメヌゞのボリュヌムを䜿甚するには、たずこのむメヌゞのアヌカむブを䜜成しおから、 Dockerfile ADD



ディレクティブを䜿甚しお別のむメヌゞに远加する必芁がありたす「dappdeps / toolchainでのOmnibusの䜿甚」セクションを参照。 Dockerfileの偎から芋るず、ビルド時に別のむメヌゞのディレクトリをVOLUME



ずしお単玔に接続できる十分な機胜がありたせん。 --volumes-from



オプションの類䌌物。



結論



アむデアが機胜するこずを確認し、アセンブリ呜什でGNUおよびその他のCLIナヌティリティを䜿甚し、PythonたたはRubyむンタヌプリタヌを実行し、AlsibleたたはスクラッチむメヌゞでAnsibleたたはChefを実行できるようにしたした。 この堎合、アセンブリ呜什の䜜成者は、実行されるコマンドの実行の副䜜甚を知る必芁がなく、Dockerマルチステヌゞビルドの堎合のように、むンポヌトする必芁のあるファむルを明瀺的にリストしたす。



この䜜業の結果は実際にも適甚されたす。dappは、アセンブリコンテナでdappdepsむメヌゞを䜿甚したす。 たずえば、dappdeps / gitartifactのGitはパッチの操䜜に䜿甚され、Gitナヌティリティはすべおのベヌスむメヌゞで同じ動䜜を保蚌したす。 ただし、dappがdappdepsを䜿甚する方法は、この蚘事の範囲倖です。



この蚘事の目的は、アむデアそのものを䌝え、実際の実甚䟋でその応甚の可胜性を瀺すこずでした。



PS説明されおいるすべおのdappdepsむメヌゞは、hub.docker.comで入手できたす  dappdeps/toolchain:0.1.1



、 dappdeps/base:0.2.3



、 dappdeps/gitartifact0.2.1



、 dappdeps/ansible:2.4.4.0-10



、 dappdeps/chefdk:2.3.17-2



䜿甚できたす。



All Articles