2024.10.10
将来は卵1パックの価格が2倍に? 多くの日本人が知らない世界の新潮流、「動物福祉」とは
リンクをコピー
記事をブックマーク
伊藤裕一氏(以下、伊藤):このCNBによるビルド作業は、大まかに2つのフェーズがあります。1つはソースコードがあって、そのソースコードをBuildpackでビルドします。このBuildpackはpackコマンドで、CNBが使えます。pack builder suggestとやると、サジェストされるBuildpackの一覧が出てきます。
これで指定したBuildpackでソースコードを判定して、JavaならJavaのビルド方法、PythonならPythonのビルド方法でイメージを作って、ベースOSはUbuntuなどですが、作成したアプリのイメージとガッチャンコして、Dockerのイメージを作るかたちでコンテナイメージが作成されています。
このスタックですが、基本的にBuildpackの中で定義されていて、あまり自分でいじることはなく、Buildpackに応じて勝手に選ばれる使い方がほとんどです。このCNBの中でどういう感じでビルドが行われているかですが、大きく分けると4つのフェーズに分かれています。
まず1つはBuildpackの中にある定義なんです。どの言語を使っているのかを検知してくれる仕組みがあり、これでどのビルド方法を使うかが判定できます。次にAnalysisです。Dockerfileはキャッシュの仕組みがあります。2度目のビルドでは1回目のビルドで得た結果を再利用することがあると思いますが、CNBでも同じことをしています。
それをするために、前回ビルドしたものと今回のビルドしたものとを照らし合わせて、必要なところだけを次のBuildフェーズで実施します。ビルドを実施したら最終的に作成された差分レイヤーを組み合わせることで、コンテナのイメージが完成するような一連の流れになっています。
この内部的な動きですが、CNBを使うことにおいてはあまり気にする必要はありません。詳細が必要な人は、Buildpack Author's GuideやBuildpack Interface Specificationなどのドキュメントを読んでもらえれば、より細かいことがわかるかと思います。
Detectionですが、先ほどGoogleのBuildpackを作成したときにサポートされる言語として、JavaやGo、Pythonなどがありました。これらを順番にチェックしていきます。最初にAPMとありますが、この言語かどうか、Yes・No。この言語か、Yes・No。この言語が、Yes・Noとやって、Yesと判断されたものでビルドする仕組みになっています。
この仕組み、要は判断する基準に自分の書くソースコードが当てはまっている必要があります。そのため、例えばJavaScriptのNode.jsのコードを書く場合であっても、ただ単に何か1個〇〇.jsというファイルを適当にポンと1個置くだけではなく、Node.jsに沿った書き方で、例えば「こういうライブラリがありますよ」といった情報を置いてあげないとビルドがちゃんとされません。フィットするようにプログラムを書いてあげる必要があります。
そんなに難しいものではないので、最初にHello,World的なものでCNBがちゃんとdetectできることが判断できたら、それをベースに本番用のアプリケーションを書くなどをしてもらえればいいんじゃないかなと思います。
次にAnalysisです。これもDockerfileの差分キャッシュと同じような感じで、前回キャッシュしたものと今回ビルドをする際に変更が発生している箇所を照らし合わせて、それで何をビルドするのかを判断するためのものです。その判断はメタ情報を起用しています。
次のBuildのフェーズですが、これはDockerfile方式の差分の積み上げ方式と若干異なるかたちでビルドをしています。そのため、例えばDockerfileでもう1回たくさんビルドしないといけないシナリオの場合でも、CNBであれば、そこがさほど発生しないという、より短縮できるシナリオがあります。他にも、たくさんのノードでビルドする際に、他のノードが作ったキャッシュを参照する機能もあります。
最後のExportのフェーズです。ここはビルドや前回のキャッシュから取ってきたイメージを、全部ガチャンコしてコンテナイメージを作成するフェーズですが、次にビルドする際に使うためのメタデータを取っておくような作業も実施しています。
こういったことを行うことで、CNBが使えます。導入は非常に簡単で、CNBを動かしたい環境にDockerをインストールして、あとはpackコマンドで下のドキュメントどおりにインストールすれば終了です。
次にkpackについて話します。kpackは、CNBをKubernetes上で動かす仕組みです。CNBは、例えばソースコードを自分のいる場所に移動して、それでビルドコマンドを走らせる。最終的にイメージを使おうと思ったらレジストリに自分でPushする必要はあります。kpackは、そのコードのPullとPushを全部Kubernetes上で一緒に実現します。
それから自分でどうビルドするのかをコマンドで指定するのではなく、YAMLで定義をする。そうすることで、管理者の人がたくさんの環境で管理をする際に、全部の環境に対してよりガバナンスを利かせやすいソフトウェアになっています。
他にもCNBであればBuildpackの中で使うOSを指定されますが、kpackであれば自分でより自由に選択できます。CNBに比べて発行するコマンドの数は少なくなるので、CIの作業を自動化させやすいといった強みもあります。
これもデモをお見せします。今、/minikubeの上にいる状態です。ここで最初にdocker image pullしていますが、このイメージはまだリポジトリにないので、failしています。このイメージをkpackで作成するためにKubernetes的にkpackのコンテナイメージの定義を行って、イメージの名前とイメージのリポジトリとリポジトリに接続するクレデンシャル。
CNBの定義が書かれているBuilderと、ソースコードをどこから取ってくるかのGitの指定です。これを指定して、リソースをkubectl applyで適用すると、このイメージリソースが作成されます。
kpackがKubernetes上でシステムのサービスとして動いているので、イメージリソースが作成されるとビルドするためのPodを立ち上げて、そのPodの中でビルド作業が実施されています。今はこのPodの中のログを表示していますが、CNBの際のログとほとんど同じで、コードをdetectしてアナライズして、ビルドして最終的にエクスポートしています。
これでコンテナのレジストリに登録されます。今回はDockerHubに登録しているので、kpackを動かす前はPullの作業は失敗していましたが、kpackがイメージをPushし終わっているので、Pullに成功している。そのPullしたイメージを今Dockerとして起動します。
これはKubernetesで起動してもいいです。linksで展開したminikube上のDockerのサービス、コンテナに対して接続すると、レスポンスがちゃんと返ってきたので、kpackがイメージをGitから取ってきてビルドしてDockerHubにPushしていることが確認できました。
このkpackがビルドを実施する流れです。最初にkpackの管理系を作成する必要があります。これはインストールの手順に書いてあるものですが、この管理系の導入をKubernetes上で行うと、kpackのリソースが作成されるかどうか、存在するかどうかを監視している。
イメージのリソースが作成されると、そのイメージのリソースに定義されているとおりにビルドを実施する、一時的なPodをデプロイメントで作成します。そのPodがGitで指定したリポジトリからPullしてきて、Pullしてきたソースコードに対してCNBを適用して、ビルドを実施する。
コードの判定は、最終的にイメージが作成されたら、指定したDockerのコンテナイメージのレジストリに対してPushを行う流れになります。
このkpackは内部的にKubernetesのリソースをいくつか使っています。使っているリソースは、「CNBで何を使っているのか」を理解していれば非常にわかりやすい、そのままなリソースになります。最初に使っているリソースとしては、Buildpackを今まで指定していたんですけど、そのBuildpackを指定するためのStoreという定義とリソース。
あとは作成したいアプリケーションを動かすためのベースOSのイメージとして、Stackで定義を行います。この2つを組み合わせてBuilderの定義を作成し、そのBuilderの定義を使ってイメージをビルドするためのGitやBuilderの指定、どこにPushするのかを指定します。
それらをするためには、当然GitHubやレジストリにアクセスするクレデンシャル情報が必要になるので、クレデンシャル情報を含んでいるSecretを定義して、Builderやイメージの中で使うかたちになっています。このイメージの定義を作成したら、先ほどのkpackのビルドをするためのPodが作成されて、手順どおりにPull、ビルド、Pushが行われるかたちです。
kpackの導入手順はそれほど難しくなく、下にドキュメントがありますが、これに沿って導入するだけです。今回みたいにDockerHubを使ってもらってもいいですが、PushやPullという作業が頻繁に発生するので、プライベートのレジストリを構築したほうが速度的にいいんじゃないのかなと思います。
ここらへんは当たり前の話ですが、作成したあとにKubernetesのクラスタを用意したら、ページからダウンロードできるYAMLを適用すると、kpackの管理系が作られるサービスが動き始めます。それが動き始めたあとでレジストリにアクセスするためのSecretを作成したり、StackとStore、Builderを定義する。
準備が完了したので、あとはイメージのリソースを作成すると、そのイメージのリソースに定義されたとおりにビルドするかたちになります。たくさんビルドする場合は、恐らくイメージのリソースは何個も作ったり更新したりを繰り返しますが、ここのSecretやStack、Store、Builderは1回定義したものは何回でも使い回しができるので、最初に1回作るとき、あとは定義を更新したい場合に変更するだけになります。
ここからは、CNBやkpackを使って、CIを構築する例の話をします。細かい手順は書きません。例えばCNBを使うと、最初にCNBを使うためのLinuxのホスト。これはDockerが動いているものを用意して、まずアプリケーションのソースコードをGitのブランチにPushする。
CIサーバーがGitブランチを監視してもいいし、GitのブランチがCIサーバーに対して「Pushされたよ」と通知を行ってもいいですが、Pushされたことを起因にして、CIサーバーが起動を開始します。
最初のステップとしてソースコードをビルドしないといけないので、コードをGitのブランチからPullしてきて、Pullされたコードに対してpackコマンドでビルドを実施する。ビルドができるとイメージが作成されるので、その作成されたイメージをレジストリに対してdocker pushコマンドで送り込む一連の流れをCI/CDで実施できます。
次にkpackの例。これもGitのブランチにPushされたら全部がkickされるところまでは同じですが、このKubernetesとkpackの仕組みを使ってGitのブランチからPull、あとはコンテナレジストリへのPushもできます。CI/CDサーバーがやる役割としては、コマンドをたくさん発行するのではなく、その一連の作業をkickするためのイメージのYAMLを更新して、applyする。それだけで一連の作業が開始されます。
CNBやkpackを使うと、最初にお話したDockerfileによるビルドの問題などを回避できますが、それを実際に使う上で、サポートなどがほしいというようなシナリオ。kpackをもう少し便利に使いたい場合には、弊社のVMwareの製品として、Tanzu Build Serviceというものが提供されているので、その導入を検討してもらえれば幸いです。
以上で、CNBとkpackに関する説明を終えたいと思います。ご清聴ありがとうございました。
関連タグ:
2024.11.13
週3日働いて年収2,000万稼ぐ元印刷屋のおじさん 好きなことだけして楽に稼ぐ3つのパターン
2024.11.11
自分の「本質的な才能」が見つかる一番簡単な質問 他者から「すごい」と思われても意外と気づかないのが才能
2024.11.13
“退職者が出た時の会社の対応”を従業員は見ている 離職防止策の前に見つめ直したい、部下との向き合い方
2024.11.12
自分の人生にプラスに働く「イライラ」は才能 自分の強みや才能につながる“良いイライラ”を見分けるポイント
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.11.11
気づいたら借金、倒産して身ぐるみを剥がされる経営者 起業に「立派な動機」を求められる恐ろしさ
2024.11.11
「退職代行」を使われた管理職の本音と葛藤 メディアで話題、利用者が右肩上がり…企業が置かれている現状とは
2024.11.18
20名の会社でGoogleの採用を真似するのはもったいない 人手不足の時代における「脱能力主義」のヒント
2024.11.12
先週まで元気だったのに、突然辞める「びっくり退職」 退職代行サービスの影響も?上司と部下の“すれ違い”が起きる原因
2024.11.14
よってたかってハイリスクのビジネスモデルに仕立て上げるステークホルダー 「社会的理由」が求められる時代の起業戦略