TECH PLAY

電通総研

電通総研 の技術ブログ

832

電通国際情報サービス 、クロス イノベーション 本部、オープン イノベーション ラボの 比嘉康雄 です。 今回は、 ブロックチェーン に関する先週のニュースをまとめます。 Ethereum以外のブロックチェーンを使う動きが活発化 クリエーター/ファンエコノミーとDAO その他のニュース Ethereum以外の ブロックチェーン を使う動きが活発化 これまでNFTといえばEthereumでした。しかし、 スループット の低さ、手数料(ガス代)の高さがネックとなりEthereum以外の ブロックチェーン を使う動きが活発化しています。 Dapper LabsのFlowブロックチェーン活用、ミクシィとDAZNがスポーツ特化型NFTマーケットプレイスを今春提供開始 Flowは、 NBA Top Shot でも使われている ブロックチェーン です。 ゲーム特化ブロックチェーン「Oasys」発表、設立メンバーにバンダイナムコやセガも Oasys で面白いのは、レイヤー2をプライベートチェーンにして、手数料(ガス代)を無料にしているところですね。 Polygonがプライベートトークンセールを実施、ソフトバンクなどから約520億円を調達 PolygonはEthereum上のレイヤー2なので、Ethereum以外の ブロックチェーン といって良いのか微妙なところですが、Ethereumのネックを解決する動きとしては一緒ですね。 ク リエータ ー/ファンエコノミーとDAO ク リエータ ーの資金調達の手段として、これまでもNFTが利用されてきましたが、投機的な側面が強いものでした。 しかし、これからはNFTの購入者であるファンを大切にしていく流れが生まれています。 こうしたク リエータ ーとファンを結びつける組織として、DAO(Decentralized Autonomous Organization )を活用する動きが広まっています。 DAOとは分散型で自律的に機能する組織のことです。従来の組織では、中央に意思決定をする組織/人がいて、その決定に従い組織が運営されていました。これに対してDAOでは、ルールに基づいて活動を行い、中央の組織がなくても自動化された運営ができます。 ク リエータ ー/ファンエコノミーがどのようにDAOを利用しているかというと、ファンは、ファンクラブの会員証に当たるNFTを購入します。このNFTがあれば、DAOに所属できます。 DAOに所属していると、ク リエータ ーの Vlog /写真/未公開の曲など、そのDAOに所属していなければ見られないコンテンツを見ることができます。ク リエータ ーとファンが直接チャットできるようにしているDAOもあります。 セレブとビデオチャットできるCameo、限定アートワークなどが手に入るNFTプロジェクト「Cameo Pass」発表 分散型「マーベル」のようなNFTメディア帝国を目指すPixel Vault、約115億円の資金を調達 YouTubeがNFTやライブショッピングなどクリエイターツールを拡充へ、TikTokやInstagramに対抗 YouTube は、まだDAOは活用していませんがそうなっていくんじゃないかと予想します。 その他のニュース グラフィティ&ストリートアートに特化した、東京発のNFTアート専門オークション「TOTEMO」 トークンブリッジのWormhole、ハッカーが約370億円相当の暗号資産を盗んだことを確認 イーサリアム開発者ツールプラットフォーム「Hardhat」開発元、a16zなどの寄付により非営利団体「Nomic Foundation」に 執筆: @higa 、レビュー: @sato.taichi ( Shodo で執筆されました )
アバター
こんにちは、X(クロス) イノベーション 本部 ソフトウェアデザインセンター セキュリティグループ、2021年新卒入社の大西です。私は昨年10月にセキュリティグループへ配属され、3ヶ月間、技術調査として GitHub 上の機密情報を見つけ出すチェックツールを調査していました。今日は、 GitHub リポジトリ に機密情報をプッシュしてしまった場合に、それを検知するツールについてお話しします。 皆さんは、 ソースコード を書く際に機密情報をハードコードしてしまっていないでしょうか。機密情報をハードコーディングしたまま GitHub 上に公開すると、その情報を不正利用されてしまいます。例えば、 AWS のアクセスキーID、シークレットアクセスキーが漏洩すると、勝手にEC2 インスタンス を立ち上げられて仮想通貨のマイニングに使用され、莫大な請求が届くという事例が相次いでいます。これを防止するためには機密情報のハードコード防止が必要ですが、人間が注意するにしても限界があります。自動化はできないか、と考えたのが今回技術調査を行った背景です。ISIDでも業務で GitHub を利用しており、パブリック リポジトリ もいくつか所有しています。ISIDが持つパブリック リポジトリ は こちら から見られます。 技術調査記録 Gitleaks 使ってみた感想 Secret Scanning 使ってみた感想 今後の対応 技術調査記録 それでは、不正利用などから会社の資産、情報を守るためのチェックツールを調査した記録を書いていきます。 この調査のためにまず行ったことは、候補に挙がっていたチェックツールの特徴や使い方を知ることです。今回いくつかのチェックツールを対象に調査したのですが、 オープンソース ツールも含まれており、 GitHub 上で ソースコード 自体も見ることができました。 それぞれのツールの特徴を掴んだ後は、実際に様々な機密情報(もし流出しても使用できないように失効済み)を リポジトリ に仕込んでから、各ツールでスキャンし検知率や誤検知率、解析速度などを比較しました。ここで時間がかかったのが、 リポジトリ に仕込むための機密情報を様々なプロバイダーから収集してくることです。今回は、 AWS やAzure、 GCP などの クラウド 系を中心に16種類の機密情報を埋め込んだのですが、 クラウド に触るのがほぼ初めてだったのでどこにどんな情報があるのかを探すのが大変でした。社内の クラウド グループの方からもお力をお借りし、無事にターゲットとしていた機密情報をゲットしました。そして、それらを埋め込んだ リポジトリ をスキャンし、この調査で私たちがツールに求める要件が明確になってきました。その要件とは、 - 過去のコミット履歴もスキャンできること - メンテナンス、サポート等が充実していること - 費用面が安く抑えられること でした。 過去のコミット履歴のスキャンに関しては、HEADコミットやmainブランチだけでなく、全てのブランチ、そしてブランチごとの履歴も含め全てスキャンしてくれるツールであることが重要になってきます。なぜなら、履歴に機密情報が含まれていれば簡単にそれを盗めるからです。また、メンテナンス・サポートに関しては、機密情報の種類は年々変わっていくので、検出できる機密情報の種類を増やしたり、検知のルールを変えたりしなければなりません(例えば、 AWS のアクセスキーIDはAKIA, ANPAなどの プレフィックス が付いているが、将来この プレフィックス が変更されると、それに伴って検知のルールも変更しなければならない)。将来のことも考え、細かなところまできっちりメンテナンスしてくれているようなツールを選ぶことが重要であると考えました。費用面に関しては、もちろん安く抑えられた方がいいですね。 というわけで、今回は5つツールを調査しましたが、その中でも良いと判断した オープンソース ツール1つと有償ツール1つをご紹介したいと思います。 Gitleaks Gitleaks は、機密情報をハードコードすることを防ぐ静的解析ツール。 オープンソース なので無償で利用でき、HomebrewやDockerなどから簡単にインストールできる。リモート、ローカルどちらのスキャンも可能。 言語: Go 検出する機密情報の種類: AWS , GCP , SSH , GitHub , Slackなどの機密情報、約100種類(version 8.2.7) https://github.com/zricethezav/gitleaks/blob/master/config/gitleaks.toml GitHub でのStar数: 8.8k 機密情報の検出方法: 正規表現 下図のように"gitleaks detect -v"とコマンドを打つと、検出された機密情報が表示される↓ 1 使ってみた感想 メリット 過去のコミット履歴まで遡って検知してくれる メインブランチだけでなく、他のブランチ、そしてそれぞれのブランチの履歴までスキャンできる ルールのカスタマイズが可能( 正規表現 でルールを書く必要がある) ルールをカスタマイズすればより多くの機密情報をスキャンできる 8系がリリースされ、7系に比べスキャンスピードが速くなった 8系がリリースされてから検知できるシークレット数が増加した(+60種類くらい) pre-commit hookを使用すればコミットする前にスキャンされるため、 GitHub に誤って機密情報をプッシュしてしまうことがなくなる GitHub Actions が GitHub Marketplaceに登録されている ymlファイルに記述するだけで、CI/CDパイプラインの中で検出できる デメリット 8系で検知できるシークレット数が増えた分、誤検知が多くなった 具体的には、調査した リポジトリ の中にIonic API tokenという名前で45件の検出があった ソースコード の中'section ...'という文字列を含むKeyがありその中の'ion 'という文字列が 正規表現 で引っかかった Configファイルのallow listの中に上記の文字列を入れれば、スキャンはスキップされる 正規表現 をカスタマイズすれば誤検知を減らすことができる Secret Scanning Secret Scanningは GitHub が提供するスキャン機能。Secret Scanningは、すべてのパブリック リポジトリ 、および GitHub Advanced Securityが有効になっている組織が所有するプライベー トリポジ トリで利用できる。パブリック リポジトリ では自動的にSecret Scanningが有効になり、 リポジトリ をプッシュすると、コンテンツをスキャンして機密情報を探す。 検出する機密情報の種類: - パブリック リポジトリ :約100種類 - プライベー トリポジ トリ:約100種類 詳しくは、 こちら のページで! GitHub リポジトリ のメインページ -> Securityタブ -> 左サイドバーのSecret scanning alertsをクリックすると、機密情報が見つかった場合その一覧が見られる↓ 2 使ってみた感想 メリット Secret Scanningで機密情報が検出された場合、 GitHub が機密情報を発行したサービスプロバイダーと連携をとって対応に当たってくれる パブリック リポジトリ トーク ンなどの機密情報(シークレット)を発行したサービスプロバイダー( AWS , Azureなど)に通知する サービスプロバイダーは、資格情報を検証してから、シークレットを取り消すか、新しいシークレットを発行するか、直接連絡するかを決定する(ユーザーまたはサービスプロバイダーに関連するリスクによって異なる) プライベー トリポジ トリ リポジトリ 管理者と組織の所有者にメールアラートを送信する リポジトリ にシークレットをコミットしたユーザーに対し、関連するシークレットスキャンアラートへのリンクを含む電子メールアラートを送信する。コミット作成者は、 リポジトリ 内のアラートを表示し、アラートを解決できる。 GitHub は リポジトリ にアラートを表示する Secret Scanningを使用していて困った時に GitHub 社のサポートを受けられる(英語対応) ルールのカスタマイズが可能( 正規表現 でルールを書く必要がある) デメリット プライベー トリポジ トリをスキャンするためには、所属する組織が、有償の GitHub Advanced Securityをオプション購入してからSecret Scanningを有効にしなければならない リポジトリ をプッシュした後にスキャンするため、スキャンする時点ですでに機密情報が漏れている可能性がある 今後の対応 今後は、試験運用として、Gitleaksを使って機密情報のスキャンをしていくことになりました。理由としては、上記でも述べたように、過去のコミット履歴もスキャンできること、メンテナンスが充実していること、無償で利用できることがあげられます。また、 GitHub 上のコミュニケーションも活発で、例えば、投稿されたissueはアクティブに対応されています。Gitleaksで社内の リポジトリ を定期的にスキャンし、機密情報が検出された時は リポジトリ 所有者に通達するなどし、開発者のセキュリティ意識向上につなげていきます。 (もしも、機密情報を見つけたら......) もし、機密情報を GitHub にプッシュしていることに気が付いたら、その情報を完全に削除するのには手間がかかります。なぜなら、gitの仕組み上変更履歴は全てツリー中に含まれており、履歴をたどれば機密情報の含まれたコミットまでたどり着けることがあるため、履歴を全て改変する必要があるからです。機密情報の含まれたコミットをいかなるブランチやタグからも遡れないようにする必要があります。そのためにはBFGツールなどを使ってgit リポジトリ の履歴から特定の文字列やファイルを削除します。また、 GitHub 上ではgit リポジトリ そのものの他に、Pull RequestやIssueに貼られたEmbed commentなど、git リポジトリ 内のコンテンツが表示されうる機会が存在します。 これらの情報を完全に削除するには GitHub のサポートに連絡して削除してもらうしかありません。 機密情報の削除については こちら の記事が参考になりました。 今後はツールを活用し機密情報を外部に漏らさない対策を強化していきたいと思います。 執筆: @onishi.mayu 、レビュー: @higa ( Shodo で執筆されました ) 図は https://asciinema.org/a/455683 のものを引用しています ↩ 図は https://docs.github.com/en/enterprise-cloud@latest/code-security/secret-scanning/managing-alerts-from-secret-scanning?learn=secret_scanning&learnProduct=code-security のものを引用しています ↩
アバター
こんにちは、X(クロス) イノベーション 本部 ソフトウェアデザインセンター セキュリティグループ、2021年新卒入社の大西です。私は昨年10月にセキュリティグループへ配属され、3ヶ月間、技術調査として GitHub 上の機密情報を見つけ出すチェックツールを調査していました。今日は、 GitHub リポジトリ に機密情報をプッシュしてしまった場合に、それを検知するツールについてお話しします。 皆さんは、 ソースコード を書く際に機密情報をハードコードしてしまっていないでしょうか。機密情報をハードコーディングしたまま GitHub 上に公開すると、その情報を不正利用されてしまいます。例えば、 AWS のアクセスキーID、シークレットアクセスキーが漏洩すると、勝手にEC2 インスタンス を立ち上げられて仮想通貨のマイニングに使用され、莫大な請求が届くという事例が相次いでいます。これを防止するためには機密情報のハードコード防止が必要ですが、人間が注意するにしても限界があります。自動化はできないか、と考えたのが今回技術調査を行った背景です。ISIDでも業務で GitHub を利用しており、パブリック リポジトリ もいくつか所有しています。ISIDが持つパブリック リポジトリ は こちら から見られます。 技術調査記録 Gitleaks 使ってみた感想 Secret Scanning 使ってみた感想 今後の対応 技術調査記録 それでは、不正利用などから会社の資産、情報を守るためのチェックツールを調査した記録を書いていきます。 この調査のためにまず行ったことは、候補に挙がっていたチェックツールの特徴や使い方を知ることです。今回いくつかのチェックツールを対象に調査したのですが、 オープンソース ツールも含まれており、 GitHub 上で ソースコード 自体も見ることができました。 それぞれのツールの特徴を掴んだ後は、実際に様々な機密情報(もし流出しても使用できないように失効済み)を リポジトリ に仕込んでから、各ツールでスキャンし検知率や誤検知率、解析速度などを比較しました。ここで時間がかかったのが、 リポジトリ に仕込むための機密情報を様々なプロバイダーから収集してくることです。今回は、 AWS やAzure、 GCP などの クラウド 系を中心に16種類の機密情報を埋め込んだのですが、 クラウド に触るのがほぼ初めてだったのでどこにどんな情報があるのかを探すのが大変でした。社内の クラウド グループの方からもお力をお借りし、無事にターゲットとしていた機密情報をゲットしました。そして、それらを埋め込んだ リポジトリ をスキャンし、この調査で私たちがツールに求める要件が明確になってきました。その要件とは、 - 過去のコミット履歴もスキャンできること - メンテナンス、サポート等が充実していること - 費用面が安く抑えられること でした。 過去のコミット履歴のスキャンに関しては、HEADコミットやmainブランチだけでなく、全てのブランチ、そしてブランチごとの履歴も含め全てスキャンしてくれるツールであることが重要になってきます。なぜなら、履歴に機密情報が含まれていれば簡単にそれを盗めるからです。また、メンテナンス・サポートに関しては、機密情報の種類は年々変わっていくので、検出できる機密情報の種類を増やしたり、検知のルールを変えたりしなければなりません(例えば、 AWS のアクセスキーIDはAKIA, ANPAなどの プレフィックス が付いているが、将来この プレフィックス が変更されると、それに伴って検知のルールも変更しなければならない)。将来のことも考え、細かなところまできっちりメンテナンスしてくれているようなツールを選ぶことが重要であると考えました。費用面に関しては、もちろん安く抑えられた方がいいですね。 というわけで、今回は5つツールを調査しましたが、その中でも良いと判断した オープンソース ツール1つと有償ツール1つをご紹介したいと思います。 Gitleaks Gitleaks は、機密情報をハードコードすることを防ぐ静的解析ツール。 オープンソース なので無償で利用でき、HomebrewやDockerなどから簡単にインストールできる。リモート、ローカルどちらのスキャンも可能。 言語: Go 検出する機密情報の種類: AWS , GCP , SSH , GitHub , Slackなどの機密情報、約100種類(version 8.2.7) https://github.com/zricethezav/gitleaks/blob/master/config/gitleaks.toml GitHub でのStar数: 8.8k 機密情報の検出方法: 正規表現 下図のように"gitleaks detect -v"とコマンドを打つと、検出された機密情報が表示される↓ 1 使ってみた感想 メリット 過去のコミット履歴まで遡って検知してくれる メインブランチだけでなく、他のブランチ、そしてそれぞれのブランチの履歴までスキャンできる ルールのカスタマイズが可能( 正規表現 でルールを書く必要がある) ルールをカスタマイズすればより多くの機密情報をスキャンできる 8系がリリースされ、7系に比べスキャンスピードが速くなった 8系がリリースされてから検知できるシークレット数が増加した(+60種類くらい) pre-commit hookを使用すればコミットする前にスキャンされるため、 GitHub に誤って機密情報をプッシュしてしまうことがなくなる GitHub Actions が GitHub Marketplaceに登録されている ymlファイルに記述するだけで、CI/CDパイプラインの中で検出できる デメリット 8系で検知できるシークレット数が増えた分、誤検知が多くなった 具体的には、調査した リポジトリ の中にIonic API tokenという名前で45件の検出があった ソースコード の中'section ...'という文字列を含むKeyがありその中の'ion 'という文字列が 正規表現 で引っかかった Configファイルのallow listの中に上記の文字列を入れれば、スキャンはスキップされる 正規表現 をカスタマイズすれば誤検知を減らすことができる Secret Scanning Secret Scanningは GitHub が提供するスキャン機能。Secret Scanningは、すべてのパブリック リポジトリ 、および GitHub Advanced Securityが有効になっている組織が所有するプライベー トリポジ トリで利用できる。パブリック リポジトリ では自動的にSecret Scanningが有効になり、 リポジトリ をプッシュすると、コンテンツをスキャンして機密情報を探す。 検出する機密情報の種類: - パブリック リポジトリ :約100種類 - プライベー トリポジ トリ:約100種類 詳しくは、 こちら のページで! GitHub リポジトリ のメインページ -> Securityタブ -> 左サイドバーのSecret scanning alertsをクリックすると、機密情報が見つかった場合その一覧が見られる↓ 2 使ってみた感想 メリット Secret Scanningで機密情報が検出された場合、 GitHub が機密情報を発行したサービスプロバイダーと連携をとって対応に当たってくれる パブリック リポジトリ トーク ンなどの機密情報(シークレット)を発行したサービスプロバイダー( AWS , Azureなど)に通知する サービスプロバイダーは、資格情報を検証してから、シークレットを取り消すか、新しいシークレットを発行するか、直接連絡するかを決定する(ユーザーまたはサービスプロバイダーに関連するリスクによって異なる) プライベー トリポジ トリ リポジトリ 管理者と組織の所有者にメールアラートを送信する リポジトリ にシークレットをコミットしたユーザーに対し、関連するシークレットスキャンアラートへのリンクを含む電子メールアラートを送信する。コミット作成者は、 リポジトリ 内のアラートを表示し、アラートを解決できる。 GitHub は リポジトリ にアラートを表示する Secret Scanningを使用していて困った時に GitHub 社のサポートを受けられる(英語対応) ルールのカスタマイズが可能( 正規表現 でルールを書く必要がある) デメリット プライベー トリポジ トリをスキャンするためには、所属する組織が、有償の GitHub Advanced Securityをオプション購入してからSecret Scanningを有効にしなければならない リポジトリ をプッシュした後にスキャンするため、スキャンする時点ですでに機密情報が漏れている可能性がある 今後の対応 今後は、試験運用として、Gitleaksを使って機密情報のスキャンをしていくことになりました。理由としては、上記でも述べたように、過去のコミット履歴もスキャンできること、メンテナンスが充実していること、無償で利用できることがあげられます。また、 GitHub 上のコミュニケーションも活発で、例えば、投稿されたissueはアクティブに対応されています。Gitleaksで社内の リポジトリ を定期的にスキャンし、機密情報が検出された時は リポジトリ 所有者に通達するなどし、開発者のセキュリティ意識向上につなげていきます。 (もしも、機密情報を見つけたら......) もし、機密情報を GitHub にプッシュしていることに気が付いたら、その情報を完全に削除するのには手間がかかります。なぜなら、gitの仕組み上変更履歴は全てツリー中に含まれており、履歴をたどれば機密情報の含まれたコミットまでたどり着けることがあるため、履歴を全て改変する必要があるからです。機密情報の含まれたコミットをいかなるブランチやタグからも遡れないようにする必要があります。そのためにはBFGツールなどを使ってgit リポジトリ の履歴から特定の文字列やファイルを削除します。また、 GitHub 上ではgit リポジトリ そのものの他に、Pull RequestやIssueに貼られたEmbed commentなど、git リポジトリ 内のコンテンツが表示されうる機会が存在します。 これらの情報を完全に削除するには GitHub のサポートに連絡して削除してもらうしかありません。 機密情報の削除については こちら の記事が参考になりました。 今後はツールを活用し機密情報を外部に漏らさない対策を強化していきたいと思います。 執筆: @onishi.mayu 、レビュー: @higa ( Shodo で執筆されました ) 図は https://asciinema.org/a/455683 のものを引用しています ↩ 図は https://docs.github.com/en/enterprise-cloud@latest/code-security/secret-scanning/managing-alerts-from-secret-scanning?learn=secret_scanning&learnProduct=code-security のものを引用しています ↩
アバター
こんにちは。XI本部 クラウド イノベーション センターの柴田です。 最近ではアプリケーションを実行する手段としてコンテナ技術が広く用いられています。 しかし、本番環境で稼働できる品質のコンテナイメージを作る際、初学者がコンテナ設計の段階で見落としがちなポイントがいくつかあります。 そこで今回はコンテナイメージを設計する際の推奨事項をいくつかご紹介したいと思います。 コンテナとは コンテナイメージを設計する際の推奨事項 The Twelve-Factor Appに従ってアプリケーションを実装する プロセス:アプリケーションを1つもしくは複数のステートレスなプロセスとして実行する 廃棄容易性:高速な起動とグレースフルシャットダウンで堅ろう性を最大化する ログ:ログをイベントストリームとして扱う 1コンテナにつき1アプリケーション コンテナイメージに余分なパッケージを含めない 適切なベースイメージを選択する マルチステージビルドを活用する コンテナイメージに機密情報を含めない コンテナ内におけるアプリケーションの実行ユーザーを root 以外に変更する ベストプラクティスに従ってDockerfileを書く コンテナイメージの脆弱性スキャンを実施する おわりに 参考 コンテナとは コンテナは仮想化技術の一種です。あらかじめ作成したコンテナイメージをもとに、異なる環境上で環境の影響を受けずにコンテナ化したアプリケーションを実行できます。 コンテナにはいくつかのメリットがあります。 可搬性が高い :コンテナを使うことで、あらかじめ作成したコンテナイメージをもとに、異なる環境上で環境の影響を受けずにコンテナ化したアプリケーションを実行できます。例えば、開発環境と本番環境の間に差異があって開発環境で動いたアプリケーションを本番環境にデプロイしたところ動かなかった、といった事態をある程度防ぐことができます。 仮想マシン と比べて軽量 :従来のハイパーバイザー型の 仮想マシン と異なり、コンテナはホストマシンの カーネル を利用してプロセスとして起動します。そのためコンテナは 仮想マシン と比べて高速に起動・停止できます。 コンテナイメージを設計する際の推奨事項 The Twelve-Factor Appに従ってアプリケーションを実装する コンテナ化するアプリケーションは The Twelve-Factor App に従っていることが望ましいです。The Twelve-Factor Appはモダンなアプリケーション開発における12個のベストプ ラク ティスです。 コードベース :バージョン管理されている1つのコードベースと複数のデプロイ 依存関係 :依存関係を明示的に宣言し分離する 設定 :設定を 環境変数 に格納する バックエンドサービス :バックエンドサービスをアタッチされたリソースとして扱う ビルド、リリース、実行 :ビルド、リリース、実行の3つのステージを厳密に分離する プロセス :アプリケーションを1つもしくは複数のステートレスなプロセスとして実行する ポート バインディング :ポート バインディング を通してサービスを公開する 並行性 : プロセスモデル によってスケールアウトする 廃棄容易性 :高速な起動とグレースフルシャットダウンで堅ろう性を最大化する 開発/本番一致 :開発、ステージング、本番環境をできるだけ一致させた状態を保つ ログ :ログをイベントストリームとして扱う 管理プロセス :管理タスクを1回限りのプロセスとして実行する 詳細は The Twelve-Factor App を参照ください。 コンテナのライフサイクルは 仮想マシン と比べて短く 基盤障害とそれに伴う自動復旧 オートスケーリング 新しいバージョンのコンテナイメージのデプロイ などをトリガーにコンテナの終了・再作成が頻繁に発生します。アプリケーションのコンテナをいつでも安全に終了できることができるよう、特に「6.プロセス」「9.廃棄容易性」「11.ログ」は適切に実装することが望ましいです。 プロセス:アプリケーションを1つもしくは複数のステートレスなプロセスとして実行する コンテナが永続データやセッション情報を持っている場合、コンテナを安全に終了するのが難しくなります。永続データやセッション情報はできるだけ外部のデータストアで管理し、コンテナはなるべくステートレスにするのが望ましいです。 廃棄容易性:高速な起動とグレースフルシャットダウンで堅ろう性を最大化する アプリケーションのコンテナはいつでもユーザーへの影響なく安全に終了できるよう実装されていることが望ましいです。 アプリケーションを安全に終了する方法の1つにSIGTERMシグナルの適切な処理が挙げられます。多くのコンテナ オーケストレーション ツールはコンテナの終了時にSIGTERMシグナルを送信します。例えばWebアプリケーションならSIGTERMシグナルを受け取ったら現在のリク エス トを全て処理した後で安全に終了するようアプリケーションを実装するとよいでしょう。 ログ:ログをイベントストリームとして扱う アプリケーションのログをファイルとして出力している場合、コンテナの終了に伴うログ消失の恐れがあります。アプリケーションのログは標準出力・ 標準エラー出力 に出力し、コンテナ オーケストレーション ツール側で収集・保存することが望ましいです。 1コンテナにつき1アプリケーション 1つのコンテナにつき1つのアプリケーションのみを起動することが望ましいです。 仮想マシン では1つの 仮想マシン 上でWeb・AP・DBなど複数のアプリケーションを起動することがありましたが、コンテナでは1つのコンテナ上に複数のアプリケーションを起動することは推奨されません。かわりに、アプリケーションごとにコンテナを起動してください。 コンテナイメージに余分なパッケージを含めない 攻撃者による攻撃を防ぐため、本番環境で実行するコンテナイメージは、余分なパッケージがインストールされておらず、攻撃の余地は少ないことが望ましいです。 適切なベースイメージを選択する アプリケーションをコンテナ化する際、まずベースとなるコンテナイメージを選択します。ベースイメージは軽量かつセキュアなものを選択することが望ましいです。具体的にはまず distroless の使用を検討するとよいでしょう。 マルチステージビルドを活用する ソースコード や コンパイラ など、アプリケーションのビルド時には必要だけれども実行時には不要なパッケージがあります。 マルチステージビルド を活用することで、アプリケーションのビルド用コンテナイメージと実行用コンテナイメージを分離し、最終的なビルド成果物のコンテナイメージに含まれるパッケージを最小化できます。 コンテナイメージに機密情報を含めない コンテナイメージにはクレデンシャルなどの機密情報を含めないでください。かわりに、クレデンシャルなどの機密情報はコンテナの実行時に 環境変数 経由でアプリケーションへ渡すようにしてください。 また以下のようなDockerfileを書かないようにしてください。 rm コマンドで機密情報を削除してもコンテナイメージのレイヤーとして機密情報が残ります。 # 機密情報をコンテナイメージへ追加 COPY credentials ./ # 何らかの処理を実行 RUN ... # コンテナイメージから不要になった機密情報を削除(実際にはcredentialsはレイヤとしてコンテナイメージに残っている) RUN rm ./credentials コンテナ内におけるアプリケーションの実行ユーザーを root 以外に変更する コンテナ内におけるアプリケーションの実行ユーザーは root 以外に変更することが望ましいです。 万が一攻撃者にアプリケーションの 脆弱性 を悪用された場合、実行ユーザーが root だと、コンテナだけでなく、コンテナの稼働するホストマシンも攻撃される恐れがあります。 ベストプ ラク ティスに従ってDockerfileを書く Dockerfileはベストプ ラク ティスに従って記述することが望ましいです。 Best practices for writing Dockerfiles | Docker Documentation Dockerfileがベストプ ラク ティスに従っているかを 機械的 にチェックしてくれるツールも存在します。 hadolint dockle コンテナイメージの 脆弱性 スキャンを実施する コンテナイメージに 脆弱性 のあるパッケージが含まれていないか定期的にスキャンすることが望ましいです。 コンテナイメージの 脆弱性 スキャンを実行するツールには例えば以下があります。 Trivy Clair また主要なイメージ レジストリ ではコンテナイメージの登録時に自動的に 脆弱性 スキャンを実行する機能を提供しています。 Amazon ECR Azure Container Registry Google Container Registry Docker Hub (有償プランのみ) おわりに 本記事では、まだコンテナをあまり使い馴れていない初学者の方向けに、コンテナイメージを設計する際の推奨事項をいくつかご紹介しました。本記事が読んでいただいた方のお役に立てば幸いです。 参考 The Twelve-Factor App (日本語訳) Best practices for writing Dockerfiles | Docker Documentation コンテナ構築のおすすめの方法  |  Cloud アーキテクチャ センター  |  Google Cloud Dockerfileのベストプラクティス Top 20 | Sysdig ECS のアプリケーションを正常にシャットダウンする方法 | Amazon Web Services ブログ What a Windows Container looks like ? - Speaker Deck 軽量Dockerイメージに安易にAlpineを使うのはやめたほうがいいという話 - inductor's blog Kubernetes完全ガイド 第2版 - インプレスブックス Docker/Kubernetes開発・運用のためのセキュリティ実践ガイド(Compass Booksシリーズ) | マイナビブックス 執筆: @shibata.takao 、レビュー: @fhiroaki ( Shodo で執筆されました )
アバター
こんにちは。XI本部 クラウド イノベーション センターの柴田です。 最近ではアプリケーションを実行する手段としてコンテナ技術が広く用いられています。 しかし、本番環境で稼働できる品質のコンテナイメージを作る際、初学者がコンテナ設計の段階で見落としがちなポイントがいくつかあります。 そこで今回はコンテナイメージを設計する際の推奨事項をいくつかご紹介したいと思います。 コンテナとは コンテナイメージを設計する際の推奨事項 The Twelve-Factor Appに従ってアプリケーションを実装する プロセス:アプリケーションを1つもしくは複数のステートレスなプロセスとして実行する 廃棄容易性:高速な起動とグレースフルシャットダウンで堅ろう性を最大化する ログ:ログをイベントストリームとして扱う 1コンテナにつき1アプリケーション コンテナイメージに余分なパッケージを含めない 適切なベースイメージを選択する マルチステージビルドを活用する コンテナイメージに機密情報を含めない コンテナ内におけるアプリケーションの実行ユーザーを root 以外に変更する ベストプラクティスに従ってDockerfileを書く コンテナイメージの脆弱性スキャンを実施する おわりに 参考 コンテナとは コンテナは仮想化技術の一種です。あらかじめ作成したコンテナイメージをもとに、異なる環境上で環境の影響を受けずにコンテナ化したアプリケーションを実行できます。 コンテナにはいくつかのメリットがあります。 可搬性が高い :コンテナを使うことで、あらかじめ作成したコンテナイメージをもとに、異なる環境上で環境の影響を受けずにコンテナ化したアプリケーションを実行できます。例えば、開発環境と本番環境の間に差異があって開発環境で動いたアプリケーションを本番環境にデプロイしたところ動かなかった、といった事態をある程度防ぐことができます。 仮想マシン と比べて軽量 :従来のハイパーバイザー型の 仮想マシン と異なり、コンテナはホストマシンの カーネル を利用してプロセスとして起動します。そのためコンテナは 仮想マシン と比べて高速に起動・停止できます。 コンテナイメージを設計する際の推奨事項 The Twelve-Factor Appに従ってアプリケーションを実装する コンテナ化するアプリケーションは The Twelve-Factor App に従っていることが望ましいです。The Twelve-Factor Appはモダンなアプリケーション開発における12個のベストプ ラク ティスです。 コードベース :バージョン管理されている1つのコードベースと複数のデプロイ 依存関係 :依存関係を明示的に宣言し分離する 設定 :設定を 環境変数 に格納する バックエンドサービス :バックエンドサービスをアタッチされたリソースとして扱う ビルド、リリース、実行 :ビルド、リリース、実行の3つのステージを厳密に分離する プロセス :アプリケーションを1つもしくは複数のステートレスなプロセスとして実行する ポート バインディング :ポート バインディング を通してサービスを公開する 並行性 : プロセスモデル によってスケールアウトする 廃棄容易性 :高速な起動とグレースフルシャットダウンで堅ろう性を最大化する 開発/本番一致 :開発、ステージング、本番環境をできるだけ一致させた状態を保つ ログ :ログをイベントストリームとして扱う 管理プロセス :管理タスクを1回限りのプロセスとして実行する 詳細は The Twelve-Factor App を参照ください。 コンテナのライフサイクルは 仮想マシン と比べて短く 基盤障害とそれに伴う自動復旧 オートスケーリング 新しいバージョンのコンテナイメージのデプロイ などをトリガーにコンテナの終了・再作成が頻繁に発生します。アプリケーションのコンテナをいつでも安全に終了できることができるよう、特に「6.プロセス」「9.廃棄容易性」「11.ログ」は適切に実装することが望ましいです。 プロセス:アプリケーションを1つもしくは複数のステートレスなプロセスとして実行する コンテナが永続データやセッション情報を持っている場合、コンテナを安全に終了するのが難しくなります。永続データやセッション情報はできるだけ外部のデータストアで管理し、コンテナはなるべくステートレスにするのが望ましいです。 廃棄容易性:高速な起動とグレースフルシャットダウンで堅ろう性を最大化する アプリケーションのコンテナはいつでもユーザーへの影響なく安全に終了できるよう実装されていることが望ましいです。 アプリケーションを安全に終了する方法の1つにSIGTERMシグナルの適切な処理が挙げられます。多くのコンテナ オーケストレーション ツールはコンテナの終了時にSIGTERMシグナルを送信します。例えばWebアプリケーションならSIGTERMシグナルを受け取ったら現在のリク エス トを全て処理した後で安全に終了するようアプリケーションを実装するとよいでしょう。 ログ:ログをイベントストリームとして扱う アプリケーションのログをファイルとして出力している場合、コンテナの終了に伴うログ消失の恐れがあります。アプリケーションのログは標準出力・ 標準エラー出力 に出力し、コンテナ オーケストレーション ツール側で収集・保存することが望ましいです。 1コンテナにつき1アプリケーション 1つのコンテナにつき1つのアプリケーションのみを起動することが望ましいです。 仮想マシン では1つの 仮想マシン 上でWeb・AP・DBなど複数のアプリケーションを起動することがありましたが、コンテナでは1つのコンテナ上に複数のアプリケーションを起動することは推奨されません。かわりに、アプリケーションごとにコンテナを起動してください。 コンテナイメージに余分なパッケージを含めない 攻撃者による攻撃を防ぐため、本番環境で実行するコンテナイメージは、余分なパッケージがインストールされておらず、攻撃の余地は少ないことが望ましいです。 適切なベースイメージを選択する アプリケーションをコンテナ化する際、まずベースとなるコンテナイメージを選択します。ベースイメージは軽量かつセキュアなものを選択することが望ましいです。具体的にはまず distroless の使用を検討するとよいでしょう。 マルチステージビルドを活用する ソースコード や コンパイラ など、アプリケーションのビルド時には必要だけれども実行時には不要なパッケージがあります。 マルチステージビルド を活用することで、アプリケーションのビルド用コンテナイメージと実行用コンテナイメージを分離し、最終的なビルド成果物のコンテナイメージに含まれるパッケージを最小化できます。 コンテナイメージに機密情報を含めない コンテナイメージにはクレデンシャルなどの機密情報を含めないでください。かわりに、クレデンシャルなどの機密情報はコンテナの実行時に 環境変数 経由でアプリケーションへ渡すようにしてください。 また以下のようなDockerfileを書かないようにしてください。 rm コマンドで機密情報を削除してもコンテナイメージのレイヤーとして機密情報が残ります。 # 機密情報をコンテナイメージへ追加 COPY credentials ./ # 何らかの処理を実行 RUN ... # コンテナイメージから不要になった機密情報を削除(実際にはcredentialsはレイヤとしてコンテナイメージに残っている) RUN rm ./credentials コンテナ内におけるアプリケーションの実行ユーザーを root 以外に変更する コンテナ内におけるアプリケーションの実行ユーザーは root 以外に変更することが望ましいです。 万が一攻撃者にアプリケーションの 脆弱性 を悪用された場合、実行ユーザーが root だと、コンテナだけでなく、コンテナの稼働するホストマシンも攻撃される恐れがあります。 ベストプ ラク ティスに従ってDockerfileを書く Dockerfileはベストプ ラク ティスに従って記述することが望ましいです。 Best practices for writing Dockerfiles | Docker Documentation Dockerfileがベストプ ラク ティスに従っているかを 機械的 にチェックしてくれるツールも存在します。 hadolint dockle コンテナイメージの 脆弱性 スキャンを実施する コンテナイメージに 脆弱性 のあるパッケージが含まれていないか定期的にスキャンすることが望ましいです。 コンテナイメージの 脆弱性 スキャンを実行するツールには例えば以下があります。 Trivy Clair また主要なイメージ レジストリ ではコンテナイメージの登録時に自動的に 脆弱性 スキャンを実行する機能を提供しています。 Amazon ECR Azure Container Registry Google Container Registry Docker Hub (有償プランのみ) おわりに 本記事では、まだコンテナをあまり使い馴れていない初学者の方向けに、コンテナイメージを設計する際の推奨事項をいくつかご紹介しました。本記事が読んでいただいた方のお役に立てば幸いです。 参考 The Twelve-Factor App (日本語訳) Best practices for writing Dockerfiles | Docker Documentation コンテナ構築のおすすめの方法  |  Cloud アーキテクチャ センター  |  Google Cloud Dockerfileのベストプラクティス Top 20 | Sysdig ECS のアプリケーションを正常にシャットダウンする方法 | Amazon Web Services ブログ What a Windows Container looks like ? - Speaker Deck 軽量Dockerイメージに安易にAlpineを使うのはやめたほうがいいという話 - inductor's blog Kubernetes完全ガイド 第2版 - インプレスブックス Docker/Kubernetes開発・運用のためのセキュリティ実践ガイド(Compass Booksシリーズ) | マイナビブックス 執筆: @shibata.takao 、レビュー: @fhiroaki ( Shodo で執筆されました )
アバター
みなさん、こんにちは。 電通国際情報サービス (ISID)コーポレート本部システム推進部の宮井です。この記事ではISIDの基幹系システムのDB変更( Oracle → Amazon Aurora )にまつわる意思決定のお話をします。 自己紹介 なぜOracleから移行するのか おわりに 自己紹介 その前に少しだけ自己紹介を。わたくし「システム推進部」という部署の部長を務めているのですが、「システム推進部」という部署名って、これだけ聞いてもよく分からないですよね? えぇ、私もそう思います。一言で申し上げれば、「情シス+α」といったところです。社内インフラ・ネットワークに加え基幹系システムの開発/運用/保守、はたまたIT全般統制、さらには情報セキュリティといった業務領域をカバーする部署となります。 なぜ Oracle から移行するのか いま「基幹系システムの開発」と書きましたが、一般的に基幹系システムってパッケージを買ってきて必要なカスタマイズを施したうえで使うというケースが多い・・・ですよね? ですが、ISIDではなにを思ったか(!?)、十数年前になんと フルスクラッチ で自社開発してしまいました。そうして生まれた基幹系システムは、社内から寄せられる手厳しい声に耐えながらも(涙)、その後さまざまなエンハンスを積み重ね現在に至るまでいちおうISIDグループの屋台骨を裏から支えています。 で、今般、その基幹系システムのDBを Oracle から PostgreSQL 、正確に言えば PostgreSQL と互換性のある Amazon Aurora に乗り換えることとなりました。 ご承知のとおり、 Oracle は確かに抜群の実績と信頼性を誇ります。ですが、いかんせんお値段がちと高い。加えてライセンス体系も非常に複雑、さらには保守費用が毎年数%ずつ 複利 方式で上がっていくというオマケも。(涙) 基幹系システムということもあり、これまではずっと Oracle を使い続けてきました。しかし、こうしたコストやリスクの点、他の DBMS も機能面や信頼性の面で Oracle に比肩するほど充実してきている点を考慮し、今回Auroraへ乗り換える方針としました。 決定打となったのは、コストシミュレーション。 当然ながらDBを変えることにより大規模なシステム改修/テストが必要となり、それには相応のコストが掛かるわけです。それでもなお、乗り換えることで大きなコストメリットが得られるという結果になりました。(あくまで弊社での使い方を想定した場合ですので、この点は十分にご注意ください) また、わたくし個人的には 社内システムも従来の重厚長大で安全確実なガチガチ路線から、リスクを取ってより良い方向を目指して挑戦したい という思いもあります。 おわりに かくして始まった Oracle 卒業プロジェクトですが、実はまだ開発の真っ最中です。実際にやってみて技術面でどういった課題があり、それをどのようなアプローチで乗り越えていったのか等、後日に改めてこのISID Tech Blogでお伝えする予定です。 有益な情報をみなさまにご提供できるようにするためにも、なにはともあれプロジェクト関係者一同、 Oracle 卒業プロジェクトを成功させるべく、ガンバリマス。 最後までお読みいただき、ありがとうございました。 執筆: @miyai 、レビュー: @handa.kenta ( Shodo で執筆されました )
アバター
みなさん、こんにちは。 電通国際情報サービス (ISID)コーポレート本部システム推進部の宮井です。この記事ではISIDの基幹系システムのDB変更( Oracle → Amazon Aurora )にまつわる意思決定のお話をします。 自己紹介 なぜOracleから移行するのか おわりに 自己紹介 その前に少しだけ自己紹介を。わたくし「システム推進部」という部署の部長を務めているのですが、「システム推進部」という部署名って、これだけ聞いてもよく分からないですよね? えぇ、私もそう思います。一言で申し上げれば、「情シス+α」といったところです。社内インフラ・ネットワークに加え基幹系システムの開発/運用/保守、はたまたIT全般統制、さらには情報セキュリティといった業務領域をカバーする部署となります。 なぜ Oracle から移行するのか いま「基幹系システムの開発」と書きましたが、一般的に基幹系システムってパッケージを買ってきて必要なカスタマイズを施したうえで使うというケースが多い・・・ですよね? ですが、ISIDではなにを思ったか(!?)、十数年前になんと フルスクラッチ で自社開発してしまいました。そうして生まれた基幹系システムは、社内から寄せられる手厳しい声に耐えながらも(涙)、その後さまざまなエンハンスを積み重ね現在に至るまでいちおうISIDグループの屋台骨を裏から支えています。 で、今般、その基幹系システムのDBを Oracle から PostgreSQL 、正確に言えば PostgreSQL と互換性のある Amazon Aurora に乗り換えることとなりました。 ご承知のとおり、 Oracle は確かに抜群の実績と信頼性を誇ります。ですが、いかんせんお値段がちと高い。加えてライセンス体系も非常に複雑、さらには保守費用が毎年数%ずつ 複利 方式で上がっていくというオマケも。(涙) 基幹系システムということもあり、これまではずっと Oracle を使い続けてきました。しかし、こうしたコストやリスクの点、他の DBMS も機能面や信頼性の面で Oracle に比肩するほど充実してきている点を考慮し、今回Auroraへ乗り換える方針としました。 決定打となったのは、コストシミュレーション。 当然ながらDBを変えることにより大規模なシステム改修/テストが必要となり、それには相応のコストが掛かるわけです。それでもなお、乗り換えることで大きなコストメリットが得られるという結果になりました。(あくまで弊社での使い方を想定した場合ですので、この点は十分にご注意ください) また、わたくし個人的には 社内システムも従来の重厚長大で安全確実なガチガチ路線から、リスクを取ってより良い方向を目指して挑戦したい という思いもあります。 おわりに かくして始まった Oracle 卒業プロジェクトですが、実はまだ開発の真っ最中です。実際にやってみて技術面でどういった課題があり、それをどのようなアプローチで乗り越えていったのか等、後日に改めてこのISID Tech Blogでお伝えする予定です。 有益な情報をみなさまにご提供できるようにするためにも、なにはともあれプロジェクト関係者一同、 Oracle 卒業プロジェクトを成功させるべく、ガンバリマス。 最後までお読みいただき、ありがとうございました。 執筆: @miyai 、レビュー: @handa.kenta ( Shodo で執筆されました )
アバター
みなさんこんにちは、 電通国際情報サービス (ISID)X イノベーション 本部ソフトウェアデザインセンターの佐藤太一です。 この記事では、Git を使った仕事のやり方(以降は Git ワークフローと記載)を設計する上での検討事項を説明します。 これによって、読者の皆さんがGitワークフローを適切に定義できるようになることを主たる目的としています。 また、筆者の能力不足によって記載しきれなかった考慮事項について、より深く Git を使いこなしている識者からの指摘を受ける機会を得ることを副次的な目的とします。 この記事には書かれていないものの、検討すべき事項について知見のある方はブログ記事を書いたり、 Twitter 等の SNS で指摘してくださるとありがたいです。 はじめに 基本的な考え方 Git ワークフロー設計における考慮事項 チームの人数 monorepoの検討 参考文献 プロジェクト管理ツールとの連携 Pull Request ブランチ名 頻出する定型業務の自動化(CI/CD サービスとの統合) ビルド 静的解析 ソースコードの自動生成 単体テスト 結合テスト ドキュメントの自動生成 パッケージング 依存ライブラリのアップデート システムテスト アプリケーション運用との統合 Git ワークフローの実際 シングルブランチモデル 参考文献 GitHub Flow 参考文献 GitLab Flow 参考文献 Gitflow (A successful Git branching model) 参考文献 まとめ はじめに この記事は、Git や GitHub の基本的な使い方を読者が理解していることを前提に書いています。 つまり、Git サーバとしての GitHub だけでなく、その機能を十分に使うことを想定しています。 もし基本的な使い方に不安があるなら、まずは以下のサイトや書籍で学習してください。 Git でのバージョン コントロールの概要 半日程度でgitについて把握できる Microsoft の教育コンテンツです。 サル先生の Git 入門 Git の初歩の初歩を図解しながら学習できるサイトです 改訂 2 版 わかばちゃんと学ぶ Git 使い方入門 漫画で Git を学習するならこの本がおすすめです 新しい領域として Git を学ぶならとっつき易さで選ぶのがいいと個人的には考えています いちばんやさしい Git&GitHub の教本 人気講師が教えるバージョン管理&共有入門 Git と GitHub をまとめて学習するならこの本がおすすめです 基本的な考え方 Gitのワークフローを決めるのは仕事の質を上げるためです。失敗の可能性を低減し、また失敗したとしても労せずやり直せることで効率よく働けるようにしましょう。 Gitのワークフローを検討する際、常に意識してほしいのは 作りこみ過ぎない ということです。 まず、起きてもいない問題のすべてを事前に対応しようとしないでください。また、プロジェクトメンバーがワークフローの習熟に使う時間をできるかぎり減らしましょう。 プロジェクトメンバーが複雑すぎるワークフローに振り回されると仕事の生産性は確実に低減し、その結果として仕事の質が落ちていきます。 Gitのワークフローは自分のプロジェクトにおいて問題が起きてもやり直せるギリギリまで軽量化しましょう。 Git ワークフロー設計における考慮事項 この記事の主題となるGitワークフロー設計における考慮事項を説明します。 ここでは、Gitを中心にした仕事のやり方全体を指してGit ワークフローと呼んでいます。 少し抽象的な話が続きますので、Gitワークフローについて考えたことがないなら、記事の後半にある Git ワークフローの実際を読んでから戻ってくると少しわかり易くなるかもしれません。 チームの人数 仕事のやり方を考えるのですから、まずチームがどのようなメンバーで構成されているのか検討しましょう。 例えば、2,3人のチームでは労せずお互いのやっていることを正確に把握できるので、複雑なワークフローは必要ありません。ミスはするものとしてお互い補いあう想定で働くと効率がいいです。 こういった少人数であれば、最低限の ケアレスミス を防ぐためだけにワークフローを定義しましょう。 メンバーが10人を超えたあたりで、お互いの仕事内容を正確に把握しあうのは難しくなります。 これくらいの人数から、Gitワークフローを検討する上でメンバーの入れ替わり頻度について考慮しましょう。 数年間固定されていて気心の知れたメンバー10人と、この3か月で集まった10人では採用すべきワークフローに多少の違いはでるでしょう。 メンバーが固定されているチームでは少人数のチームと同じようなGitワークフローで十分です。変に手順を難しくするのはやめましょう。 メンバーが流動的なチームでは作業記録を残しやすい形でワークフローを定義すると、問題が発生した際に対処し易くなります。 メンバーが30人を超えると大抵のプロジェクトでお互いの仕事内容を正確に把握しあうのは不可能です。 チームを2つか3つに分割した上で役割と責任範囲を明確にした作業分担が必要になるでしょう。 メンバーは流動的で少なくとも四半期に一回程度は誰かが抜けて、誰かが増えます。 つまり、ワークフローに習熟していないメンバーがいつでも一定数存在することを前提にワークフロー操作が失敗しても他のチームにその影響が派生しないことを重視しましょう。 こういう状況ではチーム同士の成果を結合するワークフローはどうしても複雑なものになりがちです。 monorepoの検討 Gitでは小さい単位の開発成果物ごとに リポジトリ を作る方が大抵の場合うまくいきます。 例えば、サーバアプリケーションとクライアントアプリケーション、デプロイ スクリプト 、マニュアル類、設計ドキュメントなどをそれぞれを別な リポジトリ として管理するとよいでしょう。 成果物の種類毎に リポジトリ が分かれていれば、それらを更新するメンバーの役割と責任範囲が自然と明確で分かり易くなります。 例えば、クライアントアプリケーションの開発メンバーには、サーバアプリケーションの リポジトリ に対して読み取り専用の権限を付与することを考えてみましょう。まず、コードの読むことはできるので問題発生時に分析はできます。 一方で、クライアントアプリケーションの修正のつもりでサーバアプリケーションに修正を加えてしまうといったミスは発生しなくなります。 一方で、 リポジトリ が分かれていると問題になるケースもあります。 考えてみてください。.protoや JSON Schemaのように、サーバアプリケーションとクライアントアプリケーションが通信するための プロトコル を定義するIDLは、どちらの リポジトリ に置くのがいいでしょうか?それとも、 通信プロトコル の定義は設計ドキュメントとセットで新しい リポジトリ を作るべきでしょうか?また、クライアントアプリケーションとしてモバイルアプリケーションを実装することにしました、 Android と iOS では リポジトリ を分けるべきでしょうか? このように何かあるたびに リポジトリ を増やしていくと、 リポジトリ の増加は止まりません。 リポジトリ が増えると手元の開発環境を適切な状態に維持するための手順は煩雑になります。また、CIやCDなどのビルドプロセスも複雑になります。 これに対して、開発成果物を全て単一の リポジトリ 内に収めてしまうのがmonorepoです。 単一の リポジトリ 内にあらゆる成果物を入れて管理すれば、メンバーの新規追加時における難しさは大きく低減します。 monorepoを採用することによって、まず新しいメンバーが既存の成果物を探し回るために必要なコストが低減します。 そして、ドキュメントや ソースコード の間で 相対パス を使ったリンクを張れます。種類の成果物同士で情報の連携が取り易いことは、仕様に対する理解の速度を早めます。 Google のように依存ライブラリも含めて全てmonorepoに入れてしまうような組織もあります。 対応を検討すべきデメリットはいくつかあります。 ファイル数やコミット数が多くなるので、単純に リポジトリ が大きくなる GitHub の リポジトリ は5GB程度に収めるよう推奨されている Repository size limits cloneやfetchに時間がかかり易くなる 対応策は、 パーシャルクローンとシャロークローンを活用しよう タグの対象範囲が分かりづらくなり易い タグの 命名規則 をしっかり考える必要がある メンバーが編集できる成果物の範囲を限定するのが難しい GitHub にはCODEOWNERSという仕組みで ディレクト リ単位やファイル単位の必須レビュアーを設定できる コードオーナーについて 参考文献 Git で monorepo を扱う際の課題とヒント Why Google Stores Billions of Lines of Code in a Single Repository monorepo.tools プロジェクト管理ツールとの連携 ソフトウェア開発をするためにGitを使うのですから、プロジェクト管理ツールとGitワークフローは密接に関連します。 GitHub にはタスク管理機能が備わっていますが、ある一定以上の規模で利用しようとするには機能不足です。 ボトムアップ な管理をするにも、例えばタスクの分割と集約の機能がなかったり、チケットの検索クエリが貧弱だったりします。 トップダウン な管理という意味では、例えばタスクの進捗状況を俯瞰するのは非常に難しいですし、承認フローを構築したり WBS を引いたりといったことも出来ません。 ステークホルダー となる組織が複数あり、プロジェクトとの関係性において一定の複雑さがあるならプロジェクト管理ツールを導入すべきです。 理想的には、ソフトウェア開発系のタスクとそれ以外のタスクにおける情報連携を自動的に実施するのが望ましいでしょう。つまり、プロジェクト管理ツールに定義したワークフローとGitを使ったワークフローを上手く連携させるのが望ましいというわけです。 基本的にはプロジェクト管理ツール側に GitHub 上のPull Requestやブランチの情報を取込んでいく形になります。 例えば、広く使われているプロジェクト管理ツールであるJiraには スマートコミット という仕組みがあり、コミットメッセージを所定の書式で記述するとJiraのIssueが持つ状態を操作できます。 プロジェクト管理ツール側がWebhookに対応しているならPull Requestから情報を送信できます。 また、 GitHub Actions を使うならPull Requestでなくても情報をプロジェクト管理ツールに送信できます。 Pull Request Gitはそれぞれの開発者が持っている リポジトリ は完全に独立しており対等なものです。 SVN や CVS といった構成管理ツールを使う場合、開発者のローカルにチェックアウトされた成果物は作業用のコピーであることとは対照的です。 一方で、内部統制がしっかりと効いた開発を行うなら、プロジェクトの進捗と厳密に同期していると言える リポジトリ を一つ決めます。 その中心となる リポジトリ を GitHub 上に置くと使える仕組みがPull Request(PR)です。他のツールではMerge Requestと呼ばれることもあります。 PRを使うと、コードレビューとそれにひもづく定型作業の自動化(CI)をサーバ上で実行できます。 GitHub を使うプロジェクトでは、Gitワークフローを設計するならPRをどうやって使うかが議論の中心になるでしょう。 もしPRを使うのであれば、Issue Templateを用意するとPR自体の質を底上げできます。 About issue and pull request templates ブランチ名 Gitを利用する際にブランチ名を工夫すると、CIで作業を自動化し易くなります。 ワークフローの設計次第ではもう少しルールを追加しますが、基本的にはこれだけです。 作業内容を想像し易い単語をブランチ名に含める ブランチ名は基本的に半角英数だけを使う 意味の区切りは / を使う 区切り文字として / を使うのは、GitKrakenを始めとした GUI クライアントが / 区切りでブランチを階層表示してくれるからです。 この画像では dev/my-task 、 dev/your-task に加えて折りたたまれた test/awesome ブランチがあります。 頻出する定型業務の自動化(CI/CD サービスとの統合) Gitのワークフローを作りこむ理由は、定型業務を自動化してより効率よく働くためです。 どんな作業をCIの中に組込みたいのかをしっかりと検討することはワークフロー設計をする上で大切です。 ここでは、参考のためにCIへ組み込むと便利な定型業務を列挙しますが、最初から全てに取り組もうとしないでください。 ご自分のプロジェクトにおいて明らかに恩恵があると思われるものを少量取り入れるのがおすすめです。 PRに伴って動作するCIワークフローのパフォーマンスが悪いと開発効率は確実に低減しますので、あれもこれもと盛り込み過ぎないようにしましょう。 また、筆者が知らなかったり、列挙できなかった定型業務は非常に多岐にわたることが予想されます。 読者の皆さんがご自分のプロジェクトで定型化している業務を SNS やブログで共有して下さることを期待しています。 ビルド CIに組み込む作業として一番最初に思い浮かぶのがビルドです。 ここでいうビルドは、 ソースコード から実行可能な状態に変換する過程で発生する定型的な業務全般を指しています。 静的解析 コンパイル 型の プログラミング言語 なら コンパイラ がある程度の静的解析に基づくエラーを出力してくれます。 大抵の プログラミング言語 には、Lintと呼ばれるタイプの ソースコード の妥当性を検証するツールがあります。 特に筆者が好きなのは、ベストプ ラク ティスに基づいたコードへ矯正するタイプの静的解析ツールです。 使うことが明確に非推奨というわけではないけども、新しいコードではそのような書き方をしない方がよいという知識を複数の プログラミング言語 にわたって学習し続けるのは非常に難しいです。 例えば、ReactのuseEffectに [] を指定すべきケースは限定的で基本的に何か値を設定したほうがいいとか。 goは1.13でerrorの望ましい書き方が変わったとか。 アプリケーションとしては動作する以上、望ましくないスタイルのコードを書いていても気が付きませんよね。しかし、望ましくないスタイルのコードはソフトウェアの品質を確実に低減させます。 こういったことを学習するきっかけをえるためにLintツールはPRからトリガーされるタスクに組み込むのが望ましいでしょう。 ソースコード の自動生成 ソースコード の自動生成は、それを実施すべきかどうかを判断するのが難しいタスクです。 ジェネリック スやテンプレートなど言語の機能を利用することで、継続的な ソースコード の自動生成は不要にできる場合もあります。 また、自動生成した ソースコード をGitのような構成管理ツールにチェックインするかどうかも注意深く検討してください。 自動生成した ソースコード をチェックインする場合には、 リポジトリ のサイズが大きくなり易い代わりに、CIの実行時間を抑えられます。 一方で、自動生成した ソースコード をチェックインしない場合には、 リポジトリ のサイズを小さく保てる代わりにCIの実行時間が長くなります。 筆者としては、 ソースコード の自動生成は開発者のローカルマシンで実行しPRを出して リポジトリ にチェックインする方式を好んで使っています。それは、基本的には望ましくないことだと分かっていても、生成物に対して手を入れたいという要求を完全に消すことはできないからです。 単体テスト データベースや アプリケーションサーバ を使わない 単体テスト は、PRからトリガーされるタスクとして実行したいタスクです。開発者が実施するテストのあり方を学びたい人には 和田さんのスライド をおすすめしておきます。 QuickCheckのようなパラメタライズドテストや、コード カバレッジ の計測は実行コストが高いのでそれほど頻繁に行わなくてもいいかもしれません。そういう高コストなテストは、Gitワークフローからは切り離して夜中や早朝に定期実行するようなアプローチをおすすめします。 結合テスト ここではデータベースや アプリケーションサーバ 、リバースプロキシなどを構成した上で実施するテストを 結合テスト とします。 テストに時間がかかりすぎるとか、テストが終わらなくて タイムアウト するとか言った問題はスローテスト問題と呼ばれています。 長期間にわたって価値を生み出すソフトウェアを実装していくにあたって、スローテスト問題は避けられません。 スローテスト問題に対する基本的なアプローチは、品質を担保できるギリギリの頻度で実行し、テストの実行コストと品質の トレードオフ における妥当な割合を見つけることです。 機械学習 によってテストの実行対象を賢く選択してくれる Launchable は、この問題に対する画期的な解決策を提供してくれるかもしれないと期待しています。 筆者の個人的な好みは、 ナイトリー ビルドのような形で一日に数回は 結合テスト を実行するものの、日常的なPRトリガーのワークフローからは外すことです。 ドキュメントの自動生成 Javadoc のようなドキュメントコメントから開発者向けドキュメントを自動生成するタスクもまたビルドタスクの一部としてよく組込みます。 フレームワーク やライブラリのように繰り返し再利用されるものを実装する際にはドキュメントコメントをしっかり書くのが望ましいでしょう。一方で、アプリケーションコードのドキュメントコメントは必要最小限に留めておくのがおすすめです。 筆者の経験上、コメント部分は動作しないためかコードと整合性をもってメンテナンスされづらく、その結果コメントとコードの内容にズレがおきることでコードを理解する妨げになる事の方が多いからです。 ドキュメントの自動生成は多くても一日に一回程度、大抵の場合は一週間に一回くらいの頻度で実施すれば事足りるので、PRから実行されるCIタスクには組み込まないことが多いです。 代わりに、クーロンジョブのような形で定期的に実行してPRを自動生成する方が低コストです。 今の GitHub Pagesにはアクセス制御機能があり、許可された開発者だけが閲覧できるサイトを簡単に構築できることは知っておいてください。 Changing the visibility of your GitHub Pages site パッケージング パッケージングは、Dockerコンテナイメージや、jarのような形式で アーカイブ されたファイルを作ることです。 単に アーカイブ すればいいものから署名が必要なものまで、言語やデプロイ先によって実行すべきタスクは様々です。 ただ、大きな傾向としてパッケージングはリリース作業の一部として実行するタスクです。 パッケージングとして実施すべきタスクの内容は極めて複雑で多岐にわたるため、今回はそういうものがあるとだけ言っておきます。 依存ライブラリのアップデート 現代的なソフトウェア開発において オープンソース ソフトウェア( OSS )の利用は避けられません。 そして、 OSS のライブラリは高頻度にアップデートされます。特に緊急性の高いセキュリティパッチと呼ばれるようなアップデートは実施しなければなりません。 とはいえ、定期的な依存ライブラリのアップデートを手動でやっていると時間がどれだけあっても不足します。つまり、自動化するしかありません。そのためには、比較的高品質な 回帰テスト が必要になります。 依存ライブラリのアップデートを自動的にやってくれるサービスとしては、 Renovate や、 GitHub に標準で組み込まれている Dependabot を使うのが良いでしょう。これらのサービスを利用するとライブラリをアップデートするPRを自動的に作ってくれます。 自動的に作られるPRをGitワークフローの中でどういう位置づけにするのかは、丁寧に検討してください。深く考えずに導入すると、無限に生成されるPRに押しつぶされてしまいますよ。 これは、筆者がメンテナンスしている社内ツールの 回帰テスト が不安定なせいで自動マージが上手く動作せず蓄積してしまったPRの山です。 システムテスト Gitのワークフローを検討する上で、 システムテスト の位置づけは整理するのが望ましいでしょう。 まずは、ワークフローの一部に システムテスト を組み込むのかどうかを検討してください。 システムテスト の自動化は極めて深遠な話題ですので、大抵のプロジェクトでは組み込まないという結論になるでしょう。 ソフトウェアが価値を生み長生きするならば、規模は大きくなり複雑になっていきます。 その中で システムテスト の自動化は取り組むべき課題の一つです。 Gitワークフローの一部として システムテスト を実行すべき状況になっていないかを、ときどき気にかけてください。 アプリケーション運用との統合 Gitワークフローとアプリケーション運用の統合については、パッケージングの話題でありデプロイの話題です。 少なくとも、ワークフローの終了ステータスをどのような形で、いつ誰に通知するのかは検討してください。 伝統的にはショートメッセージサービス(SMS)や電子メールを使っていますよね。 現代的にはSlackやTeams、LINEなどチャットツールへのメッセージ送信となるでしょう。 また、アプリケーション運用側からGitに対する情報提供をどのように実施するのかを検討するのも忘れないでください。 基本的にはプロジェクト管理ツールに対するタスクの起票( GitHub Issuesなど)を介して行うことになるはずです。 Git ワークフローの実際 ここからは、ワークフロー設計の参考になるようなGitワークフローをいくつか紹介します。 ただし、具体的な作業手順については説明していません。参考文献に詳細な説明のあるページをリンクしておきましたので参考にしてください。 ここで紹介しているものは、あくまでも基本的な型であって、これをそのまま導入すべきものではありません。 とはいえ、一定の複雑さがあるワークフローを導入する際、最初のうちは基本的な型のまま何も変えずに導入することがGitワークフローのあり方をチームとして理解する助けになるでしょう。 この説明では、デフォルトのブランチをmainブランチと記載しています。 以前は、 GitHub におけるデフォルトのブランチ名はmasterでしたが、世相を反映して現在はmainをデフォルトのブランチ名とすることが推奨されています。 GitHub、これから作成するリポジトリのデフォルトブランチ名が「main」に。「master」から「main」へ変更 シングルブランチモデル シングルブランチモデルは、開発者はサーバの リポジトリ をcloneしたらmainブランチに変更作業をコミットしていき、作業が終わり次第mainブランチをサーバにpushする方式です。 これは、 SVN からGitへ ソースコード 管理ツールを移行するチームが一時的に使う方式として検討する余地があります。 単に SVN をGitで代替し、基本的なコマンドの使い方や動作を理解する期間を設けることでツールの移行に伴う生産性の低下を緩やかにできます。 一方でシングルブランチモデルはソフトウェアの設計や、作業分担次第ではあるものの非常にコンフリクトが発生し易い使い方です。 push前に必ずrebaseしてローカル ディレクト リ内でコンフリクトを解決する。もしくは、同じファイルを同時に複数の人が修正しないよう作業範囲を調整しなければなりません。 つまり、この方式を採用してプロジェクト運営を行うならプロジェクトマネージャーが、仕様の変更や追加に伴うファイルの変更範囲を厳密に理解している必要があります。 チームが2,3人で担当範囲が明確なら、この方式でGitを使い始めるのがいいでしょう。 コンフリクトさえ発生しなければ、覚えなければならないGit固有の知識が最小限で済みます。 参考文献 Centralized Workflow トランクベース開発 GitHub Flow GitHub Flowでは、サーバの リポジトリ をcloneしたらmainブランチから作業用のフィーチャブランチへswitchします。 フィーチャブランチでの作業が終わったら、それをサーバにpushしPRを使ってmainブランチにマージします。 この方式では、gitの3-way mergeが上手く働くのでシングルブランチモデルよりも断然コンフリクトが発生し辛くなります。 原義的な GitHub Flowではmainブランチにマージされた変更は本番環境を含む何らかの実行環境にデプロイすることが重要なのですが、そこまでやらなくても十分に利便性を享受できます。 参考文献 GitHub Flow 翻訳 GitHub公式 GitLab Flow ブランチの管理とデプロイをより丁寧に対応付ける形のワークフローがGitLab Flowです。 開発者がPRを使ってmainブランチに変更をマージしていくことは GitHub Flowと同じです。 GitLab Flowでは、デプロイ作業を実施するブランチを専用に設けることで、開発におけるPRのマージとデプロイの周期やタイミングを分離します。 mainブランチにマージされたアプリケーションがテスト環境にデプロイされ、そこで問題が見つからなければ本番環境にデプロイされるというようなワークフローを想定すると、このような形になるでしょう。 大規模な開発では、テスト環境が複数用意されているものです。 テストの目的や、担当者の責任範囲によって環境が分離されているようなら環境に対応したブランチを用意した上で、それらのブランチへのマージをトリガーにデプロイを実行するでしょう。 パッケージソフト ウェアのビジネスでは、リリース済みで新機能の追加がないとしても、セキュリティの問題や深刻なバグへの対応を実施するためパッチを適用して保守していくことが望まれます。 このような状況にGitLab Flowの考え方を適用すると、それぞれのリリースに応じてブランチを作り、mainブランチから必要な変更だけを取り出してマージしていく(チェリーピック)ことになります。 このバージョンブランチを伸ばしていく保守方針は変更コストが高くなり易いので、なるべく選ばない方がいいでしょう。 しかし、これはソフトウェアの収益モデルと直接関連するので、ビジネスオーナーと開発者が丁寧な議論を実施すべき話題です。 参考文献 GitLab Flow GitLab flowから学ぶワークフローの実践 Gitflow (A successful Git branching model) Gitflowはここまで説明してきたワークフローの集大成となるものです。 開発者は、サーバの リポジトリ をcloneしたらdevlopブランチから作業用のフィーチャブランチへswitchします。 フィーチャブランチでの作業が終わったら、それをサーバにpushしPRを使ってdevelopブランチにマージします。 必要な変更作業が終わったら、リリースの担当者がdevelopブランチから新しいreleaseブランチをswitchし、アプリケーションのリリースに伴う作業を実施した成果をコミットします。ここでコミットされるものは、例えば、軽微な作業ミスの修正やバグの対応、ドキュメントの修正などです。 そういった作業が全て終了したら、releaseブランチをサーバにpushしPRを使ってmainブランチにマージしてタグを打ちます。 そうです、Gitflowにおけるmainブランチはアプリケーションの静止点を記録するためだけのブランチなのです。 ただし、緊急対応を行うホットフィックスブランチだけは例外です。 緊急対応を行う開発者は、mainブランチから作業用のホットフィックスブランチへswitchします。 作業が終わったらホットフィックスブランチをサーバにpushしPRを使ってdevelopブランチとmainブランチの両方へマージします。 その上で、mainブランチにタグを打ちアプリケーションをリリースします。 Gitflowでは非常に複雑な状況が想定されています。またそれぞれの開発者がGitに対してかなり習熟していることが前提のワークフローです。 中身を詳細に理解した上で、全ての要素が必要であると判断できるなら、リリースまでの作業を何度か実施してみてください。それでもなおプロジェクトの運営方針と合致していると確信できる場合のみGitflowを採用してください。 参考文献 A successful Git branching model 翻訳 まとめ 筆者は、Gitワークフローの設計で最も重要なのは 作りこみ過ぎない ことだと考えています。 そのために、Gitワークフローにおける検討事項を適切に把握しましょう。 みなさんのプロジェクトにおいて対応すべき課題を丁寧に把握した上でプロジェクトメンバーの生産性を最大限に発揮できるワークフローを設計してください。 具体的にどのワークフローを使えばいいか分からないなら、まずは GitHub Flowを試してみてください。 GitHub Actionsを使って簡単なビルドを行いつつ、コードレビューをするとGitを使うことの利便性を享受できます。 この記事によって、読者の皆さんがご自分のチーム内におけるGitワークフローを改善するきっかけになれば、これ以上に嬉しいことはありません。 非常に長いエントリでしたが、最後までお読みいただきありがとうございます。 執筆: @sato.taichi 、レビュー: @yamashita.tsuyoshi ( Shodo で執筆されました )
アバター
みなさんこんにちは、 電通国際情報サービス (ISID)X イノベーション 本部ソフトウェアデザインセンターの佐藤太一です。 この記事では、Git を使った仕事のやり方(以降は Git ワークフローと記載)を設計する上での検討事項を説明します。 これによって、読者の皆さんがGitワークフローを適切に定義できるようになることを主たる目的としています。 また、筆者の能力不足によって記載しきれなかった考慮事項について、より深く Git を使いこなしている識者からの指摘を受ける機会を得ることを副次的な目的とします。 この記事には書かれていないものの、検討すべき事項について知見のある方はブログ記事を書いたり、 Twitter 等の SNS で指摘してくださるとありがたいです。 はじめに 基本的な考え方 Git ワークフロー設計における考慮事項 チームの人数 monorepoの検討 参考文献 プロジェクト管理ツールとの連携 Pull Request ブランチ名 頻出する定型業務の自動化(CI/CD サービスとの統合) ビルド 静的解析 ソースコードの自動生成 単体テスト 結合テスト ドキュメントの自動生成 パッケージング 依存ライブラリのアップデート システムテスト アプリケーション運用との統合 Git ワークフローの実際 シングルブランチモデル 参考文献 GitHub Flow 参考文献 GitLab Flow 参考文献 Gitflow (A successful Git branching model) 参考文献 まとめ はじめに この記事は、Git や GitHub の基本的な使い方を読者が理解していることを前提に書いています。 つまり、Git サーバとしての GitHub だけでなく、その機能を十分に使うことを想定しています。 もし基本的な使い方に不安があるなら、まずは以下のサイトや書籍で学習してください。 Git 入門 30分程度でgitについて把握できる Microsoft の教育コンテンツです。 サル先生の Git 入門 Git の初歩の初歩を図解しながら学習できるサイトです 改訂 2 版 わかばちゃんと学ぶ Git 使い方入門 漫画で Git を学習するならこの本がおすすめです 新しい領域として Git を学ぶならとっつき易さで選ぶのがいいと個人的には考えています いちばんやさしいGit&GitHubの教本 第3版 人気講師が教えるバージョン管理&共有入門 Git と GitHub をまとめて学習するならこの本がおすすめです 基本的な考え方 Gitのワークフローを決めるのは仕事の質を上げるためです。失敗の可能性を低減し、また失敗したとしても労せずやり直せることで効率よく働けるようにしましょう。 Gitのワークフローを検討する際、常に意識してほしいのは 作りこみ過ぎない ということです。 まず、起きてもいない問題のすべてを事前に対応しようとしないでください。また、プロジェクトメンバーがワークフローの習熟に使う時間をできるかぎり減らしましょう。 プロジェクトメンバーが複雑すぎるワークフローに振り回されると仕事の生産性は確実に低減し、その結果として仕事の質が落ちていきます。 Gitのワークフローは自分のプロジェクトにおいて問題が起きてもやり直せるギリギリまで軽量化しましょう。 Git ワークフロー設計における考慮事項 この記事の主題となるGitワークフロー設計における考慮事項を説明します。 ここでは、Gitを中心にした仕事のやり方全体を指してGit ワークフローと呼んでいます。 少し抽象的な話が続きますので、Gitワークフローについて考えたことがないなら、記事の後半にある Git ワークフローの実際を読んでから戻ってくると少しわかり易くなるかもしれません。 チームの人数 仕事のやり方を考えるのですから、まずチームがどのようなメンバーで構成されているのか検討しましょう。 例えば、2,3人のチームでは労せずお互いのやっていることを正確に把握できるので、複雑なワークフローは必要ありません。ミスはするものとしてお互い補いあう想定で働くと効率がいいです。 こういった少人数であれば、最低限の ケアレスミス を防ぐためだけにワークフローを定義しましょう。 メンバーが10人を超えたあたりで、お互いの仕事内容を正確に把握しあうのは難しくなります。 これくらいの人数から、Gitワークフローを検討する上でメンバーの入れ替わり頻度について考慮しましょう。 数年間固定されていて気心の知れたメンバー10人と、この3か月で集まった10人では採用すべきワークフローに多少の違いはでるでしょう。 メンバーが固定されているチームでは少人数のチームと同じようなGitワークフローで十分です。変に手順を難しくするのはやめましょう。 メンバーが流動的なチームでは作業記録を残しやすい形でワークフローを定義すると、問題が発生した際に対処し易くなります。 メンバーが30人を超えると大抵のプロジェクトでお互いの仕事内容を正確に把握しあうのは不可能です。 チームを2つか3つに分割した上で役割と責任範囲を明確にした作業分担が必要になるでしょう。 メンバーは流動的で少なくとも四半期に一回程度は誰かが抜けて、誰かが増えます。 つまり、ワークフローに習熟していないメンバーがいつでも一定数存在することを前提にワークフロー操作が失敗しても他のチームにその影響が派生しないことを重視しましょう。 こういう状況ではチーム同士の成果を結合するワークフローはどうしても複雑なものになりがちです。 monorepoの検討 Gitでは小さい単位の開発成果物ごとに リポジトリ を作る方が大抵の場合うまくいきます。 例えば、サーバアプリケーションとクライアントアプリケーション、デプロイ スクリプト 、マニュアル類、設計ドキュメントなどをそれぞれを別な リポジトリ として管理するとよいでしょう。 成果物の種類毎に リポジトリ が分かれていれば、それらを更新するメンバーの役割と責任範囲が自然と明確で分かり易くなります。 例えば、クライアントアプリケーションの開発メンバーには、サーバアプリケーションの リポジトリ に対して読み取り専用の権限を付与することを考えてみましょう。まず、コードの読むことはできるので問題発生時に分析はできます。 一方で、クライアントアプリケーションの修正のつもりでサーバアプリケーションに修正を加えてしまうといったミスは発生しなくなります。 一方で、 リポジトリ が分かれていると問題になるケースもあります。 考えてみてください。.protoや JSON Schemaのように、サーバアプリケーションとクライアントアプリケーションが通信するための プロトコル を定義するIDLは、どちらの リポジトリ に置くのがいいでしょうか?それとも、 通信プロトコル の定義は設計ドキュメントとセットで新しい リポジトリ を作るべきでしょうか?また、クライアントアプリケーションとしてモバイルアプリケーションを実装することにしました、 Android と iOS では リポジトリ を分けるべきでしょうか? このように何かあるたびに リポジトリ を増やしていくと、 リポジトリ の増加は止まりません。 リポジトリ が増えると手元の開発環境を適切な状態に維持するための手順は煩雑になります。また、CIやCDなどのビルドプロセスも複雑になります。 これに対して、開発成果物を全て単一の リポジトリ 内に収めてしまうのがmonorepoです。 単一の リポジトリ 内にあらゆる成果物を入れて管理すれば、メンバーの新規追加時における難しさは大きく低減します。 monorepoを採用することによって、まず新しいメンバーが既存の成果物を探し回るために必要なコストが低減します。 そして、ドキュメントや ソースコード の間で 相対パス を使ったリンクを張れます。種類の成果物同士で情報の連携が取り易いことは、仕様に対する理解の速度を早めます。 Google のように依存ライブラリも含めて全てmonorepoに入れてしまうような組織もあります。 対応を検討すべきデメリットはいくつかあります。 ファイル数やコミット数が多くなるので、単純に リポジトリ が大きくなる GitHub の リポジトリ は5GB程度に収めるよう推奨されている Repository size limits cloneやfetchに時間がかかり易くなる 対応策は、 パーシャルクローンとシャロークローンを活用しよう タグの対象範囲が分かりづらくなり易い タグの 命名規則 をしっかり考える必要がある メンバーが編集できる成果物の範囲を限定するのが難しい GitHub にはCODEOWNERSという仕組みで ディレクト リ単位やファイル単位の必須レビュアーを設定できる コードオーナーについて 参考文献 Git で monorepo を扱う際の課題とヒント Why Google Stores Billions of Lines of Code in a Single Repository monorepo.tools プロジェクト管理ツールとの連携 ソフトウェア開発をするためにGitを使うのですから、プロジェクト管理ツールとGitワークフローは密接に関連します。 GitHub にはタスク管理機能が備わっていますが、ある一定以上の規模で利用しようとするには機能不足です。 ボトムアップ な管理をするにも、例えばタスクの分割と集約の機能がなかったり、チケットの検索クエリが貧弱だったりします。 トップダウン な管理という意味では、例えばタスクの進捗状況を俯瞰するのは非常に難しいですし、承認フローを構築したり WBS を引いたりといったことも出来ません。 ステークホルダー となる組織が複数あり、プロジェクトとの関係性において一定の複雑さがあるならプロジェクト管理ツールを導入すべきです。 理想的には、ソフトウェア開発系のタスクとそれ以外のタスクにおける情報連携を自動的に実施するのが望ましいでしょう。つまり、プロジェクト管理ツールに定義したワークフローとGitを使ったワークフローを上手く連携させるのが望ましいというわけです。 基本的にはプロジェクト管理ツール側に GitHub 上のPull Requestやブランチの情報を取込んでいく形になります。 例えば、広く使われているプロジェクト管理ツールであるJiraには スマートコミット という仕組みがあり、コミットメッセージを所定の書式で記述するとJiraのIssueが持つ状態を操作できます。 プロジェクト管理ツール側がWebhookに対応しているならPull Requestから情報を送信できます。 また、 GitHub Actions を使うならPull Requestでなくても情報をプロジェクト管理ツールに送信できます。 Pull Request Gitはそれぞれの開発者が持っている リポジトリ は完全に独立しており対等なものです。 SVN や CVS といった構成管理ツールを使う場合、開発者のローカルにチェックアウトされた成果物は作業用のコピーであることとは対照的です。 一方で、内部統制がしっかりと効いた開発を行うなら、プロジェクトの進捗と厳密に同期していると言える リポジトリ を一つ決めます。 その中心となる リポジトリ を GitHub 上に置くと使える仕組みがPull Request(PR)です。他のツールではMerge Requestと呼ばれることもあります。 PRを使うと、コードレビューとそれにひもづく定型作業の自動化(CI)をサーバ上で実行できます。 GitHub を使うプロジェクトでは、Gitワークフローを設計するならPRをどうやって使うかが議論の中心になるでしょう。 もしPRを使うのであれば、Issue Templateを用意するとPR自体の質を底上げできます。 About issue and pull request templates ブランチ名 Gitを利用する際にブランチ名を工夫すると、CIで作業を自動化し易くなります。 ワークフローの設計次第ではもう少しルールを追加しますが、基本的にはこれだけです。 作業内容を想像し易い単語をブランチ名に含める ブランチ名は基本的に半角英数だけを使う 意味の区切りは / を使う 区切り文字として / を使うのは、GitKrakenを始めとした GUI クライアントが / 区切りでブランチを階層表示してくれるからです。 この画像では dev/my-task 、 dev/your-task に加えて折りたたまれた test/awesome ブランチがあります。 頻出する定型業務の自動化(CI/CD サービスとの統合) Gitのワークフローを作りこむ理由は、定型業務を自動化してより効率よく働くためです。 どんな作業をCIの中に組込みたいのかをしっかりと検討することはワークフロー設計をする上で大切です。 ここでは、参考のためにCIへ組み込むと便利な定型業務を列挙しますが、最初から全てに取り組もうとしないでください。 ご自分のプロジェクトにおいて明らかに恩恵があると思われるものを少量取り入れるのがおすすめです。 PRに伴って動作するCIワークフローのパフォーマンスが悪いと開発効率は確実に低減しますので、あれもこれもと盛り込み過ぎないようにしましょう。 また、筆者が知らなかったり、列挙できなかった定型業務は非常に多岐にわたることが予想されます。 読者の皆さんがご自分のプロジェクトで定型化している業務を SNS やブログで共有して下さることを期待しています。 ビルド CIに組み込む作業として一番最初に思い浮かぶのがビルドです。 ここでいうビルドは、 ソースコード から実行可能な状態に変換する過程で発生する定型的な業務全般を指しています。 静的解析 コンパイル 型の プログラミング言語 なら コンパイラ がある程度の静的解析に基づくエラーを出力してくれます。 大抵の プログラミング言語 には、Lintと呼ばれるタイプの ソースコード の妥当性を検証するツールがあります。 特に筆者が好きなのは、ベストプ ラク ティスに基づいたコードへ矯正するタイプの静的解析ツールです。 使うことが明確に非推奨というわけではないけども、新しいコードではそのような書き方をしない方がよいという知識を複数の プログラミング言語 にわたって学習し続けるのは非常に難しいです。 例えば、ReactのuseEffectに [] を指定すべきケースは限定的で基本的に何か値を設定したほうがいいとか。 goは1.13でerrorの望ましい書き方が変わったとか。 アプリケーションとしては動作する以上、望ましくないスタイルのコードを書いていても気が付きませんよね。しかし、望ましくないスタイルのコードはソフトウェアの品質を確実に低減させます。 こういったことを学習するきっかけをえるためにLintツールはPRからトリガーされるタスクに組み込むのが望ましいでしょう。 ソースコード の自動生成 ソースコード の自動生成は、それを実施すべきかどうかを判断するのが難しいタスクです。 ジェネリック スやテンプレートなど言語の機能を利用することで、継続的な ソースコード の自動生成は不要にできる場合もあります。 また、自動生成した ソースコード をGitのような構成管理ツールにチェックインするかどうかも注意深く検討してください。 自動生成した ソースコード をチェックインする場合には、 リポジトリ のサイズが大きくなり易い代わりに、CIの実行時間を抑えられます。 一方で、自動生成した ソースコード をチェックインしない場合には、 リポジトリ のサイズを小さく保てる代わりにCIの実行時間が長くなります。 筆者としては、 ソースコード の自動生成は開発者のローカルマシンで実行しPRを出して リポジトリ にチェックインする方式を好んで使っています。それは、基本的には望ましくないことだと分かっていても、生成物に対して手を入れたいという要求を完全に消すことはできないからです。 単体テスト データベースや アプリケーションサーバ を使わない 単体テスト は、PRからトリガーされるタスクとして実行したいタスクです。開発者が実施するテストのあり方を学びたい人には 和田さんのスライド をおすすめしておきます。 QuickCheckのようなパラメタライズドテストや、コード カバレッジ の計測は実行コストが高いのでそれほど頻繁に行わなくてもいいかもしれません。そういう高コストなテストは、Gitワークフローからは切り離して夜中や早朝に定期実行するようなアプローチをおすすめします。 結合テスト ここではデータベースや アプリケーションサーバ 、リバースプロキシなどを構成した上で実施するテストを 結合テスト とします。 テストに時間がかかりすぎるとか、テストが終わらなくて タイムアウト するとか言った問題はスローテスト問題と呼ばれています。 長期間にわたって価値を生み出すソフトウェアを実装していくにあたって、スローテスト問題は避けられません。 スローテスト問題に対する基本的なアプローチは、品質を担保できるギリギリの頻度で実行し、テストの実行コストと品質の トレードオフ における妥当な割合を見つけることです。 機械学習 によってテストの実行対象を賢く選択してくれる Launchable は、この問題に対する画期的な解決策を提供してくれるかもしれないと期待しています。 筆者の個人的な好みは、 ナイトリー ビルドのような形で一日に数回は 結合テスト を実行するものの、日常的なPRトリガーのワークフローからは外すことです。 ドキュメントの自動生成 Javadoc のようなドキュメントコメントから開発者向けドキュメントを自動生成するタスクもまたビルドタスクの一部としてよく組込みます。 フレームワーク やライブラリのように繰り返し再利用されるものを実装する際にはドキュメントコメントをしっかり書くのが望ましいでしょう。一方で、アプリケーションコードのドキュメントコメントは必要最小限に留めておくのがおすすめです。 筆者の経験上、コメント部分は動作しないためかコードと整合性をもってメンテナンスされづらく、その結果コメントとコードの内容にズレがおきることでコードを理解する妨げになる事の方が多いからです。 ドキュメントの自動生成は多くても一日に一回程度、大抵の場合は一週間に一回くらいの頻度で実施すれば事足りるので、PRから実行されるCIタスクには組み込まないことが多いです。 代わりに、クーロンジョブのような形で定期的に実行してPRを自動生成する方が低コストです。 今の GitHub Pagesにはアクセス制御機能があり、許可された開発者だけが閲覧できるサイトを簡単に構築できることは知っておいてください。 Changing the visibility of your GitHub Pages site パッケージング パッケージングは、Dockerコンテナイメージや、jarのような形式で アーカイブ されたファイルを作ることです。 単に アーカイブ すればいいものから署名が必要なものまで、言語やデプロイ先によって実行すべきタスクは様々です。 ただ、大きな傾向としてパッケージングはリリース作業の一部として実行するタスクです。 パッケージングとして実施すべきタスクの内容は極めて複雑で多岐にわたるため、今回はそういうものがあるとだけ言っておきます。 依存ライブラリのアップデート 現代的なソフトウェア開発において オープンソース ソフトウェア( OSS )の利用は避けられません。 そして、 OSS のライブラリは高頻度にアップデートされます。特に緊急性の高いセキュリティパッチと呼ばれるようなアップデートは実施しなければなりません。 とはいえ、定期的な依存ライブラリのアップデートを手動でやっていると時間がどれだけあっても不足します。つまり、自動化するしかありません。そのためには、比較的高品質な 回帰テスト が必要になります。 依存ライブラリのアップデートを自動的にやってくれるサービスとしては、 Renovate や、 GitHub に標準で組み込まれている Dependabot を使うのが良いでしょう。これらのサービスを利用するとライブラリをアップデートするPRを自動的に作ってくれます。 自動的に作られるPRをGitワークフローの中でどういう位置づけにするのかは、丁寧に検討してください。深く考えずに導入すると、無限に生成されるPRに押しつぶされてしまいますよ。 これは、筆者がメンテナンスしている社内ツールの 回帰テスト が不安定なせいで自動マージが上手く動作せず蓄積してしまったPRの山です。 システムテスト Gitのワークフローを検討する上で、 システムテスト の位置づけは整理するのが望ましいでしょう。 まずは、ワークフローの一部に システムテスト を組み込むのかどうかを検討してください。 システムテスト の自動化は極めて深遠な話題ですので、大抵のプロジェクトでは組み込まないという結論になるでしょう。 ソフトウェアが価値を生み長生きするならば、規模は大きくなり複雑になっていきます。 その中で システムテスト の自動化は取り組むべき課題の一つです。 Gitワークフローの一部として システムテスト を実行すべき状況になっていないかを、ときどき気にかけてください。 アプリケーション運用との統合 Gitワークフローとアプリケーション運用の統合については、パッケージングの話題でありデプロイの話題です。 少なくとも、ワークフローの終了ステータスをどのような形で、いつ誰に通知するのかは検討してください。 伝統的にはショートメッセージサービス(SMS)や電子メールを使っていますよね。 現代的にはSlackやTeams、LINEなどチャットツールへのメッセージ送信となるでしょう。 また、アプリケーション運用側からGitに対する情報提供をどのように実施するのかを検討するのも忘れないでください。 基本的にはプロジェクト管理ツールに対するタスクの起票( GitHub Issuesなど)を介して行うことになるはずです。 Git ワークフローの実際 ここからは、ワークフロー設計の参考になるようなGitワークフローをいくつか紹介します。 ただし、具体的な作業手順については説明していません。参考文献に詳細な説明のあるページをリンクしておきましたので参考にしてください。 ここで紹介しているものは、あくまでも基本的な型であって、これをそのまま導入すべきものではありません。 とはいえ、一定の複雑さがあるワークフローを導入する際、最初のうちは基本的な型のまま何も変えずに導入することがGitワークフローのあり方をチームとして理解する助けになるでしょう。 この説明では、デフォルトのブランチをmainブランチと記載しています。 以前は、 GitHub におけるデフォルトのブランチ名はmasterでしたが、世相を反映して現在はmainをデフォルトのブランチ名とすることが推奨されています。 GitHub、これから作成するリポジトリのデフォルトブランチ名が「main」に。「master」から「main」へ変更 シングルブランチモデル シングルブランチモデルは、開発者はサーバの リポジトリ をcloneしたらmainブランチに変更作業をコミットしていき、作業が終わり次第mainブランチをサーバにpushする方式です。 これは、 SVN からGitへ ソースコード 管理ツールを移行するチームが一時的に使う方式として検討する余地があります。 単に SVN をGitで代替し、基本的なコマンドの使い方や動作を理解する期間を設けることでツールの移行に伴う生産性の低下を緩やかにできます。 一方でシングルブランチモデルはソフトウェアの設計や、作業分担次第ではあるものの非常にコンフリクトが発生し易い使い方です。 push前に必ずrebaseしてローカル ディレクト リ内でコンフリクトを解決する。もしくは、同じファイルを同時に複数の人が修正しないよう作業範囲を調整しなければなりません。 つまり、この方式を採用してプロジェクト運営を行うならプロジェクトマネージャーが、仕様の変更や追加に伴うファイルの変更範囲を厳密に理解している必要があります。 チームが2,3人で担当範囲が明確なら、この方式でGitを使い始めるのがいいでしょう。 コンフリクトさえ発生しなければ、覚えなければならないGit固有の知識が最小限で済みます。 参考文献 Centralized Workflow トランクベース開発 GitHub Flow GitHub Flowでは、サーバの リポジトリ をcloneしたらmainブランチから作業用のフィーチャブランチへswitchします。 フィーチャブランチでの作業が終わったら、それをサーバにpushしPRを使ってmainブランチにマージします。 この方式では、gitの3-way mergeが上手く働くのでシングルブランチモデルよりも断然コンフリクトが発生し辛くなります。 原義的な GitHub Flowではmainブランチにマージされた変更は本番環境を含む何らかの実行環境にデプロイすることが重要なのですが、そこまでやらなくても十分に利便性を享受できます。 参考文献 GitHub Flow 翻訳 GitHub公式 GitLab Flow ブランチの管理とデプロイをより丁寧に対応付ける形のワークフローがGitLab Flowです。 開発者がPRを使ってmainブランチに変更をマージしていくことは GitHub Flowと同じです。 GitLab Flowでは、デプロイ作業を実施するブランチを専用に設けることで、開発におけるPRのマージとデプロイの周期やタイミングを分離します。 mainブランチにマージされたアプリケーションがテスト環境にデプロイされ、そこで問題が見つからなければ本番環境にデプロイされるというようなワークフローを想定すると、このような形になるでしょう。 大規模な開発では、テスト環境が複数用意されているものです。 テストの目的や、担当者の責任範囲によって環境が分離されているようなら環境に対応したブランチを用意した上で、それらのブランチへのマージをトリガーにデプロイを実行するでしょう。 パッケージソフト ウェアのビジネスでは、リリース済みで新機能の追加がないとしても、セキュリティの問題や深刻なバグへの対応を実施するためパッチを適用して保守していくことが望まれます。 このような状況にGitLab Flowの考え方を適用すると、それぞれのリリースに応じてブランチを作り、mainブランチから必要な変更だけを取り出してマージしていく(チェリーピック)ことになります。 このバージョンブランチを伸ばしていく保守方針は変更コストが高くなり易いので、なるべく選ばない方がいいでしょう。 しかし、これはソフトウェアの収益モデルと直接関連するので、ビジネスオーナーと開発者が丁寧な議論を実施すべき話題です。 参考文献 GitLab Flow GitLab flowから学ぶワークフローの実践 Gitflow (A successful Git branching model) Gitflowはここまで説明してきたワークフローの集大成となるものです。 開発者は、サーバの リポジトリ をcloneしたらdevlopブランチから作業用のフィーチャブランチへswitchします。 フィーチャブランチでの作業が終わったら、それをサーバにpushしPRを使ってdevelopブランチにマージします。 必要な変更作業が終わったら、リリースの担当者がdevelopブランチから新しいreleaseブランチをswitchし、アプリケーションのリリースに伴う作業を実施した成果をコミットします。ここでコミットされるものは、例えば、軽微な作業ミスの修正やバグの対応、ドキュメントの修正などです。 そういった作業が全て終了したら、releaseブランチをサーバにpushしPRを使ってmainブランチにマージしてタグを打ちます。 そうです、Gitflowにおけるmainブランチはアプリケーションの静止点を記録するためだけのブランチなのです。 ただし、緊急対応を行うホットフィックスブランチだけは例外です。 緊急対応を行う開発者は、mainブランチから作業用のホットフィックスブランチへswitchします。 作業が終わったらホットフィックスブランチをサーバにpushしPRを使ってdevelopブランチとmainブランチの両方へマージします。 その上で、mainブランチにタグを打ちアプリケーションをリリースします。 Gitflowでは非常に複雑な状況が想定されています。またそれぞれの開発者がGitに対してかなり習熟していることが前提のワークフローです。 中身を詳細に理解した上で、全ての要素が必要であると判断できるなら、リリースまでの作業を何度か実施してみてください。それでもなおプロジェクトの運営方針と合致していると確信できる場合のみGitflowを採用してください。 参考文献 A successful Git branching model 翻訳 まとめ 筆者は、Gitワークフローの設計で最も重要なのは 作りこみ過ぎない ことだと考えています。 そのために、Gitワークフローにおける検討事項を適切に把握しましょう。 みなさんのプロジェクトにおいて対応すべき課題を丁寧に把握した上でプロジェクトメンバーの生産性を最大限に発揮できるワークフローを設計してください。 具体的にどのワークフローを使えばいいか分からないなら、まずは GitHub Flowを試してみてください。 GitHub Actionsを使って簡単なビルドを行いつつ、コードレビューをするとGitを使うことの利便性を享受できます。 この記事によって、読者の皆さんがご自分のチーム内におけるGitワークフローを改善するきっかけになれば、これ以上に嬉しいことはありません。 非常に長いエントリでしたが、最後までお読みいただきありがとうございます。 執筆: @sato.taichi 、レビュー: @yamashita.tsuyoshi ( Shodo で執筆されました )
アバター
こんにちは! 電通国際情報サービス 金融ソリューション事業部の山下です。 今回は、 ゲームエンジン の Unreal Engine と、 iOS アプリの LiveLinkFace を用いたデジタルヒューマンのリアルタイムフェイスリグを行う手順を紹介します。 手順 MetaHuman Creator でデジタルヒューマンを作成する デジタルヒューマンを Unreal Projectにエクスポートする LiveLinkFaceアプリでデジタルヒューマンを動かす 実行環境 PC: macOS 12.1 Monterey Unreal Engine 4.27(β版のUE5でも動作可能ですが、今回は UE4 での手順を説明します) Quixel Bridge 2021.0.1 Mobile: iPhone X (ARKitとdepthAPIがサポートされているFaceID搭載機種が必要になります) iOS 15.2.1 LiveLinkFace 1.1.2 Network: PCとMobileが同じネットワークに接続していること(同一 Wifi 環境 or Lightning Ethernet など) 手順1. デジタルヒューマンの作成 まず、 MetaHuman Creator でデジタルヒューマンを作成します。 MetaHuman Creator は、 Epic Games が提供する高精細なデジタルヒューマンを誰でも簡単に作成できる クラウド サービスです。 プリセットされたデジタルヒューマンをベースにした顔や髪型などの モデリング が可能ですが、本記事における詳細な操作説明は割愛します。 今回は、以下のデジタルヒューマンを作成しました。 手順2. デジタルヒューマンを Unreal Projectにエクスポートする Unreal Engine にて、Blankプロジェクトを作成してプロジェクトを立ち上げます。 以下の プラグイン をインストールしましょう。 - 「Edit」->「Plugins」 - Apple ARKit - Apple ARKit Face Support - Live Link 次に、 Quixel Bridge アプリを立ち上げます。(UE5の場合はQuixel Bridgeが Unreal Engine 自体に組み込まれていますが、 UE4 では別途インストールが必要となります) MetaHuman Creator で利用したものと同じEpicGamesアカウントを用いてログインすると、先ほど作成したデジタルヒューマンを確認できます。 エクスポートを行う為に、以下の設定を行います。 - 「Settings」->「Download Settings」->「Modelsタブ」 - 項目「MetaHumans」 :「UAsset + Source Asset」 - 「Download」実行(完了まで数十分かかります) - Settings」->「Export Settings」->「Export Target」 - 項目「ExportTarget」 :「 Unreal Engine 」 - 項目「Engine Version」:自身の Unreal Engine バージョン - 項目「Plugin Location」:自身の Unreal Engine Plugin ディレクト リパス - 「Export」実行 - 初めて実行する場合は Unreal Engine 側で不足している プラグイン のWarningが表示されますが、全て有効(Enable Missing)を選択して必要 プラグイン をインストールして下さい Exportが完了すると、 Unreal Engine プロジェクトの「Content Browser」パネルにデジタルヒューマンのアセットが追加されます。 Unreal Engine プロジェクトに、先ほど追加されたアセットを ドラッグアンドドロップ で配置します。 Unreal Projectへデジタルヒューマンのエクスポートができました。 手順3. LiveLinkFaceアプリでデジタルヒューマンを動かす まず、Mobile側でLiveLinkFace iOS アプリを立ち上げ、以下の設定を行います。 - 「Setting」->「Live Link」-> 「TARGETS」 -> 「Add Target」 - 「IP Address」:接続先PCのプライベート IPアドレス を設定 頭の回転も連携させる為に、「Setting」->「Stream Head Rotation」をONにします。 Mobile側の設定は以上です。 次に、PC側の Unreal Engine 側で、Mobileデ バイス がSource Subjectとして追加されていることを確認します。 - 「Window」->「Live Link」 最後に、World Outlinerパネルからデジタルヒューマンのアセットを選択して、以下を設定します。 - 「LLink Face Subj」:自身が追加したSource Subjectを選択 - 「LLink Face Head」:ON 完成 Unreal Engine のプレイボタンを押すと、リアルタイムフェイスリグが確認できます! いかがでしたでしょうか。 EpicGames社が提供するUnrealEngine、MetaHuman、LiveLinkFaceを用いて、ノーコードでデジタルヒューマンのフェイスリグを行いました。 実はこのMetaHuman、既に映画やゲームなどの開発にも利用されており、先日公開されたPS5/ Xbox 向けデモ The Matrix Awakens: An Unreal Engine 5 Experience では、実際にハリウッド映画並のクオリティでリアルタイムに動くゲームが公開されており、その作品の主人公もMetaHumanで作成されています。 メタバース に対する注目が集まっている中、基盤となる ゲームエンジン や周辺システムも個人レベルで簡単にアクセスできるようになってきており、ますますこの領域に目が離せません。 現在ISID金融ソリューション事業部では ブロックチェーン や NFT関連の研究開発 を行っております。 既に Decentraland や Sandbox などの VR サービス内ではNFTアイテムが取引可能になっており、将来的なオープンな メタバース と ブロックチェーン の親和性は高いと考えられます。引き続き3DCG領域の技術もウォッチしていきたいと思います! 参考 Getting Started with MetaHumans in Unreal Engine Using the MetaHuman Facial Rig Recording Facial Animation from an iOS Device Introducing The Matrix Awakens: An Unreal Engine 5 Experience 執筆: @yamashita.yuki 、レビュー: @sato.taichi ( Shodo で執筆されました )
アバター
こんにちは! 電通国際情報サービス 金融ソリューション事業部の山下です。 今回は、 ゲームエンジン の Unreal Engine と、 iOS アプリの LiveLinkFace を用いたデジタルヒューマンのリアルタイムフェイスリグを行う手順を紹介します。 手順 MetaHuman Creator でデジタルヒューマンを作成する デジタルヒューマンを Unreal Projectにエクスポートする LiveLinkFaceアプリでデジタルヒューマンを動かす 実行環境 PC: macOS 12.1 Monterey Unreal Engine 4.27(β版のUE5でも動作可能ですが、今回は UE4 での手順を説明します) Quixel Bridge 2021.0.1 Mobile: iPhone X (ARKitとdepthAPIがサポートされているFaceID搭載機種が必要になります) iOS 15.2.1 LiveLinkFace 1.1.2 Network: PCとMobileが同じネットワークに接続していること(同一 Wifi 環境 or Lightning Ethernet など) 手順1. デジタルヒューマンの作成 まず、 MetaHuman Creator でデジタルヒューマンを作成します。 MetaHuman Creator は、 Epic Games が提供する高精細なデジタルヒューマンを誰でも簡単に作成できる クラウド サービスです。 プリセットされたデジタルヒューマンをベースにした顔や髪型などの モデリング が可能ですが、本記事における詳細な操作説明は割愛します。 今回は、以下のデジタルヒューマンを作成しました。 手順2. デジタルヒューマンを Unreal Projectにエクスポートする Unreal Engine にて、Blankプロジェクトを作成してプロジェクトを立ち上げます。 以下の プラグイン をインストールしましょう。 - 「Edit」->「Plugins」 - Apple ARKit - Apple ARKit Face Support - Live Link 次に、 Quixel Bridge アプリを立ち上げます。(UE5の場合はQuixel Bridgeが Unreal Engine 自体に組み込まれていますが、 UE4 では別途インストールが必要となります) MetaHuman Creator で利用したものと同じEpicGamesアカウントを用いてログインすると、先ほど作成したデジタルヒューマンを確認できます。 エクスポートを行う為に、以下の設定を行います。 - 「Settings」->「Download Settings」->「Modelsタブ」 - 項目「MetaHumans」 :「UAsset + Source Asset」 - 「Download」実行(完了まで数十分かかります) - Settings」->「Export Settings」->「Export Target」 - 項目「ExportTarget」 :「 Unreal Engine 」 - 項目「Engine Version」:自身の Unreal Engine バージョン - 項目「Plugin Location」:自身の Unreal Engine Plugin ディレクト リパス - 「Export」実行 - 初めて実行する場合は Unreal Engine 側で不足している プラグイン のWarningが表示されますが、全て有効(Enable Missing)を選択して必要 プラグイン をインストールして下さい Exportが完了すると、 Unreal Engine プロジェクトの「Content Browser」パネルにデジタルヒューマンのアセットが追加されます。 Unreal Engine プロジェクトに、先ほど追加されたアセットを ドラッグアンドドロップ で配置します。 Unreal Projectへデジタルヒューマンのエクスポートができました。 手順3. LiveLinkFaceアプリでデジタルヒューマンを動かす まず、Mobile側でLiveLinkFace iOS アプリを立ち上げ、以下の設定を行います。 - 「Setting」->「Live Link」-> 「TARGETS」 -> 「Add Target」 - 「IP Address」:接続先PCのプライベート IPアドレス を設定 頭の回転も連携させる為に、「Setting」->「Stream Head Rotation」をONにします。 Mobile側の設定は以上です。 次に、PC側の Unreal Engine 側で、Mobileデ バイス がSource Subjectとして追加されていることを確認します。 - 「Window」->「Live Link」 最後に、World Outlinerパネルからデジタルヒューマンのアセットを選択して、以下を設定します。 - 「LLink Face Subj」:自身が追加したSource Subjectを選択 - 「LLink Face Head」:ON 完成 Unreal Engine のプレイボタンを押すと、リアルタイムフェイスリグが確認できます! いかがでしたでしょうか。 EpicGames社が提供するUnrealEngine、MetaHuman、LiveLinkFaceを用いて、ノーコードでデジタルヒューマンのフェイスリグを行いました。 実はこのMetaHuman、既に映画やゲームなどの開発にも利用されており、先日公開されたPS5/ Xbox 向けデモ The Matrix Awakens: An Unreal Engine 5 Experience では、実際にハリウッド映画並のクオリティでリアルタイムに動くゲームが公開されており、その作品の主人公もMetaHumanで作成されています。 メタバース に対する注目が集まっている中、基盤となる ゲームエンジン や周辺システムも個人レベルで簡単にアクセスできるようになってきており、ますますこの領域に目が離せません。 現在ISIDは web3領域のグループ横断組織 を立ち上げ、Web3および メタバース 領域のR&Dを行っております(カテゴリー「3DCG」の記事は こちら )。 もし本領域にご興味のある方や、一緒にチャレンジしていきたい方は、ぜひお気軽にご連絡ください! 私たちと同じチームで働いてくれる仲間を、是非お待ちしております! ISID採用ページ(Web3/メタバース/AI) 参考 Getting Started with MetaHumans in Unreal Engine Using the MetaHuman Facial Rig Recording Facial Animation from an iOS Device Introducing The Matrix Awakens: An Unreal Engine 5 Experience 執筆: @yamashita.yuki 、レビュー: @sato.taichi ( Shodo で執筆されました )
アバター
こんにちは! 電通国際情報サービス 金融ソリューション事業部の山下です。 今回は、 ゲームエンジン の Unreal Engine と、 iOS アプリの LiveLinkFace を用いたデジタルヒューマンのリアルタイムフェイスリグを行う手順を紹介します。 手順 MetaHuman Creator でデジタルヒューマンを作成する デジタルヒューマンを Unreal Projectにエクスポートする LiveLinkFaceアプリでデジタルヒューマンを動かす 実行環境 PC: macOS 12.1 Monterey Unreal Engine 4.27(β版のUE5でも動作可能ですが、今回は UE4 での手順を説明します) Quixel Bridge 2021.0.1 Mobile: iPhone X (ARKitとdepthAPIがサポートされているFaceID搭載機種が必要になります) iOS 15.2.1 LiveLinkFace 1.1.2 Network: PCとMobileが同じネットワークに接続していること(同一 Wifi 環境 or Lightning Ethernet など) 手順1. デジタルヒューマンの作成 まず、 MetaHuman Creator でデジタルヒューマンを作成します。 MetaHuman Creator は、 Epic Games が提供する高精細なデジタルヒューマンを誰でも簡単に作成できる クラウド サービスです。 プリセットされたデジタルヒューマンをベースにした顔や髪型などの モデリング が可能ですが、本記事における詳細な操作説明は割愛します。 今回は、以下のデジタルヒューマンを作成しました。 手順2. デジタルヒューマンを Unreal Projectにエクスポートする Unreal Engine にて、Blankプロジェクトを作成してプロジェクトを立ち上げます。 以下の プラグイン をインストールしましょう。 - 「Edit」->「Plugins」 - Apple ARKit - Apple ARKit Face Support - Live Link 次に、 Quixel Bridge アプリを立ち上げます。(UE5の場合はQuixel Bridgeが Unreal Engine 自体に組み込まれていますが、 UE4 では別途インストールが必要となります) MetaHuman Creator で利用したものと同じEpicGamesアカウントを用いてログインすると、先ほど作成したデジタルヒューマンを確認できます。 エクスポートを行う為に、以下の設定を行います。 - 「Settings」->「Download Settings」->「Modelsタブ」 - 項目「MetaHumans」 :「UAsset + Source Asset」 - 「Download」実行(完了まで数十分かかります) - Settings」->「Export Settings」->「Export Target」 - 項目「ExportTarget」 :「 Unreal Engine 」 - 項目「Engine Version」:自身の Unreal Engine バージョン - 項目「Plugin Location」:自身の Unreal Engine Plugin ディレクト リパス - 「Export」実行 - 初めて実行する場合は Unreal Engine 側で不足している プラグイン のWarningが表示されますが、全て有効(Enable Missing)を選択して必要 プラグイン をインストールして下さい Exportが完了すると、 Unreal Engine プロジェクトの「Content Browser」パネルにデジタルヒューマンのアセットが追加されます。 Unreal Engine プロジェクトに、先ほど追加されたアセットを ドラッグアンドドロップ で配置します。 Unreal Projectへデジタルヒューマンのエクスポートができました。 手順3. LiveLinkFaceアプリでデジタルヒューマンを動かす まず、Mobile側でLiveLinkFace iOS アプリを立ち上げ、以下の設定を行います。 - 「Setting」->「Live Link」-> 「TARGETS」 -> 「Add Target」 - 「IP Address」:接続先PCのプライベート IPアドレス を設定 頭の回転も連携させる為に、「Setting」->「Stream Head Rotation」をONにします。 Mobile側の設定は以上です。 次に、PC側の Unreal Engine 側で、Mobileデ バイス がSource Subjectとして追加されていることを確認します。 - 「Window」->「Live Link」 最後に、World Outlinerパネルからデジタルヒューマンのアセットを選択して、以下を設定します。 - 「LLink Face Subj」:自身が追加したSource Subjectを選択 - 「LLink Face Head」:ON 完成 Unreal Engine のプレイボタンを押すと、リアルタイムフェイスリグが確認できます! いかがでしたでしょうか。 EpicGames社が提供するUnrealEngine、MetaHuman、LiveLinkFaceを用いて、ノーコードでデジタルヒューマンのフェイスリグを行いました。 実はこのMetaHuman、既に映画やゲームなどの開発にも利用されており、先日公開されたPS5/ Xbox 向けデモ The Matrix Awakens: An Unreal Engine 5 Experience では、実際にハリウッド映画並のクオリティでリアルタイムに動くゲームが公開されており、その作品の主人公もMetaHumanで作成されています。 メタバース に対する注目が集まっている中、基盤となる ゲームエンジン や周辺システムも個人レベルで簡単にアクセスできるようになってきており、ますますこの領域に目が離せません。 現在ISIDは web3領域のグループ横断組織 を立ち上げ、Web3および メタバース 領域のR&Dを行っております(カテゴリー「3DCG」の記事は こちら )。 もし本領域にご興味のある方や、一緒にチャレンジしていきたい方は、ぜひお気軽にご連絡ください! 私たちと同じチームで働いてくれる仲間を、是非お待ちしております! ISID採用ページ(Web3/メタバース/AI) 参考 Getting Started with MetaHumans in Unreal Engine Using the MetaHuman Facial Rig Recording Facial Animation from an iOS Device Introducing The Matrix Awakens: An Unreal Engine 5 Experience 執筆: @yamashita.yuki 、レビュー: @sato.taichi ( Shodo で執筆されました )
アバター
電通国際情報サービス オープン イノベーション ラボの比嘉です。 今回のテーマは、スマート コントラ クト。スマート コントラ クトとは ブロックチェーン 上にデプロイされるプログラムのことで、今回は、 Gethはじめました の続きになります。 まだ、上記の記事をやってない方は、お手数をおかけしますが先に上記の記事をやってください。GethはEthereumクライアントの中で公式に推奨されているクライアントです。 Gethの再起動 Solidityのインストール macOSの場合 Windowsの場合 スマートコントラクトのコード solc スマートコントラクトのデプロイ まとめ Gethの再起動 上記記事で、Gethのメインプロセスを終了させた方は、もう一度再起動しましょう。 $ cd private_net $ geth --networkid 1203 --nodiscover --datadir . 別のターミナルを立ち上げて、メインプロセスにコンソールで接続します。 $ cd private_net $ geth attach geth.ipc 採掘が止まっている場合は、採掘を開始しましょう。 > eth.mining false > miner.start() null Solidityのインストール Ethereumでスマート コントラ クトを書くための プログラミング言語 としては、Solidity, Vyper, Fe, lllなどがありますが、よく使われているのはSolidityです。そこで、今回はSolidityをインストールします。 Solidityをインストールするための 公式サイトはこちら macOS の場合 Homebrewを事前にインストールし、次のコマンドを実行しましょう。 $ brew update $ brew upgrade $ brew tap ethereum/ethereum $ brew install solidity $ brew linkapps solidity brew update を実行するときに Error: homebrew-core is a shallow clone. のエラーが、起きる場合があります。その場合はメッセージに、書いてあるとおりに、gitコマンドを実行しましょう。 インストールがうまくいっていれば、次のコマンドが成功します。 $ solc --version Windows の場合 ダウンロードサイト から、 solc-windows.exe を落としてインストールしましょう。 スマート コントラ クトのコード 最初のスマート コントラ クトとして、数値をスマート コントラ クトの状態変数に格納したり、取り出したりするプログラムを書いてみましょう。 NumberRegister.sol pragma solidity ^ 0.8 . 10 ; contract NumberRegister { uint num; function set( uint _num) public { num = _num; } function get() public view returns ( uint ) { return num; } } Solidityの細かい文法については、今後の記事で取り上げるので、細かいことは気にしなくて大丈夫です。この NumberRegiseter.sol をprivate_netの ディレクト リに保存しましょう。 solc SolidityのプログラムをEthereumで実行できるようにするには、 solc で コンパイル します。 コンパイル とは、 NumberRegiseter.sol のような人間が見て理解しやすいコードをコンピューターが実行できるように変更することです。 もう一つ、ターミナルを立ち上げて、 solc を実行しましょう。 $ cd private_net $ solc --abi --bin NumberRegister.sol 次のような出力が表示されたはずです。 ======= NumberRegister.sol:NumberRegister ======= Binary: 608060405234801561001057600080fd5b50610150806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806360fe47b11461003b5780636d4ce63c14610057575b600080fd5b610055600480360381019061005091906100c3565b610075565b005b61005f61007f565b60405161006c91906100ff565b60405180910390f35b8060008190555050565b60008054905090565b600080fd5b6000819050919050565b6100a08161008d565b81146100ab57600080fd5b50565b6000813590506100bd81610097565b92915050565b6000602082840312156100d9576100d8610088565b5b60006100e7848285016100ae565b91505092915050565b6100f98161008d565b82525050565b600060208201905061011460008301846100f0565b9291505056fea2646970667358221220348a0bef0ed2915311a28c4b28b351b950a27275e260ed0a915108c3b0257d2c64736f6c634300080a0033 Contract JSON ABI [{"inputs":[],"name":"get","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_num","type":"uint256"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"}] Binaryのところに書いてある 6080 ではじまり 0033 で終わる文字列の先頭に0xを付加した上で、シングルクォートでくくり、Gethのコンソールに貼り付けます。BinaryはEVM(Ethereumの 仮想マシン )が理解できる バイトコード です。 > bin = '0x608060405234801561001057600080fd5b50610150806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806360fe47b11461003b5780636d4ce63c14610057575b600080fd5b610055600480360381019061005091906100c3565b610075565b005b61005f61007f565b60405161006c91906100ff565b60405180910390f35b8060008190555050565b60008054905090565b600080fd5b6000819050919050565b6100a08161008d565b81146100ab57600080fd5b50565b6000813590506100bd81610097565b92915050565b6000602082840312156100d9576100d8610088565b5b60006100e7848285016100ae565b91505092915050565b6100f98161008d565b82525050565b600060208201905061011460008301846100f0565b9291505056fea2646970667358221220348a0bef0ed2915311a28c4b28b351b950a27275e260ed0a915108c3b0257d2c64736f6c634300080a0033' 同様に Contract JSON ABI もコンソールに貼り付けましょう。ABIはスマート コントラ クトの入出力の仕様になります。 > abi = [{"inputs":[],"name":"get","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_num","type":"uint256"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"}] ここで定義した bin と abi は、この後で使うので覚えておいてください。binはEVM(Ethereumの 仮想マシン )が理解できる バイトコード 、abiはスマート コントラ クトの入出力の仕様です。 スマート コントラ クトのデプロイ 先ほどのスマート コントラ クトをEthereumネットワークにデプロイしましょう。 > cnt = eth.contract(abi).new({from: eth.accounts[0], data: bin}) Error: authentication needed: password or unlock at web3.js:6347:37(47) at web3.js:5081:62(37) at web3.js:3021:48(134) at <eval>:1:28(16) Error: authentication needed: password or unlock が発生した場合は、アカウントをunlockAcount()しましょう。 トランザクション を実行する場合は、アカウントをunlockAccount()する必要があります。このエラーは何度も見ることになるので、どう対応すれば良いか体で覚えましょう。 > personal.unlockAccount(eth.accounts[0]) Unlock account 0x29faad1bb68151278c47df617766bf045c9b2b00 Passphrase: true > cnt = eth.contract(abi).new({from: eth.accounts[0], data: bin}) { abi: [{ inputs: [], name: "get", outputs: [{...}], stateMutability: "view", type: "function" }, { inputs: [{...}], name: "set", outputs: [], stateMutability: "nonpayable", type: "function" }], address: undefined, transactionHash: "0x13658235f5bff4afefd57b504a048f5c2bc37241bacfd9ce58177627aa1882b2" } cntの中身のaddressがundefinedになっていますね。これは、このスマート コントラ クトのデプロイがまだ終わっていないことを表しています。Gethのメインプロセスのログで採掘がきちんと行われていることを確認したら、cnt.addressを確認しましょう。 > cnt.address "0x102118ad7f8bede0158d2353660f63ea5780f966" スマート コントラ クトに、アクセスするにはABI(スマート コントラ クトの入出力の仕様)とaddressが必要です。それでは、NumberRegister コントラ クトを作りましょう。 > cnt2 = eth.contract(abi).at(cnt.address) { abi: [{ inputs: [], name: "get", outputs: [{...}], stateMutability: "view", type: "function" }, { inputs: [{...}], name: "set", outputs: [], stateMutability: "nonpayable", type: "function" }], address: "0x102118ad7f8bede0158d2353660f63ea5780f966", transactionHash: null, allEvents: function(), get: function(), set: function() } スマート コントラ クトの状態を変更しない場合は、 トランザクション なしで実行できます。それでは、NumberRegister.get()メソッドを呼び出してみましょう。 コントラクトオブジェクト.メソッド名.call() で呼びだすことができます。 > cnt2.get.call() 0 スマート コントラ クトの状態を変更する場合、 コントラクトオブジェクト.メソッド名.sendTransaction() を呼び出します。それでは、NumberRegister.set()を呼び出してみましょう。 > cnt2.set.sendTransaction(1, {from: eth.accounts[0]}) Error: authentication needed: password or unlock at web3.js:6347:37(47) at web3.js:5081:62(37) at web3.js:4137:41(57) at <eval>:1:36(10) エラーが出ていない人は気にしなくて大丈夫です。上記のエラーが出た人は、unlockAccount()を呼び出しましょう。 > personal.unlockAccount(eth.accounts[0]) Unlock account 0x29faad1bb68151278c47df617766bf045c9b2b00 Passphrase: true > txid = cnt2.set.sendTransaction(1, {from: eth.accounts[0]}) "0xf12e076acec31684bade23f3ca12c14396160a86464ce1298bbe10e795824f2e" Gethのメインプロセスのログで採掘が動いていることを確認し、NumberRegister.get()を呼び出してみましょう。 > cnt2.get.call() 1 cnt2.set.sendTransaction() の第一引数で指定した値が、設定されていることが分かります。 まとめ スマート コントラ クトを コンパイル すると、ABI(入出力の仕様)とバイナリー(EVMが理解できる バイトコード )が出力されます。 バイナリーをEthereumネットワークにデプロイするとaddressが付加されます。 ABIとaddressを使って コントラ クトオブジェクトを作成して、スマートコンタクトにアクセスします。 スマート コントラ クトの状態を変更しない場合、 コントラクトオブジェクト.メソッド名.call() を呼び出します。 スマート コントラ クトの状態を変更する場合、 コントラクトオブジェクト.メソッド名.sendTransaction() を呼び出します。 今回はここまで。Gethを止めておきましょう。コンソールはCTL-D。メインプロセスはCTL-Cで止めます。正直、GethのコンソールはNode.jsのモジュールも使えないなど、かなり不便です。次回からは、開発環境として Hardhat を使います。 僕の書いたNFT関連の記事 Gethはじめました NFT入門 執筆: @higa 、レビュー: @sato.taichi ( Shodo で執筆されました )
アバター
電通国際情報サービス オープン イノベーション ラボの比嘉です。 今回のテーマは、スマート コントラ クト。スマート コントラ クトとは ブロックチェーン 上にデプロイされるプログラムのことで、今回は、 Gethはじめました の続きになります。 まだ、上記の記事をやってない方は、お手数をおかけしますが先に上記の記事をやってください。GethはEthereumクライアントの中で公式に推奨されているクライアントです。 Gethの再起動 Solidityのインストール macOSの場合 Windowsの場合 スマートコントラクトのコード solc スマートコントラクトのデプロイ まとめ Gethの再起動 上記記事で、Gethのメインプロセスを終了させた方は、もう一度再起動しましょう。 $ cd private_net $ geth --networkid 1203 --nodiscover --datadir . 別のターミナルを立ち上げて、メインプロセスにコンソールで接続します。 $ cd private_net $ geth attach geth.ipc 採掘が止まっている場合は、採掘を開始しましょう。 > eth.mining false > miner.start() null Solidityのインストール Ethereumでスマート コントラ クトを書くための プログラミング言語 としては、Solidity, Vyper, Fe, lllなどがありますが、よく使われているのはSolidityです。そこで、今回はSolidityをインストールします。 Solidityをインストールするための 公式サイトはこちら macOS の場合 Homebrewを事前にインストールし、次のコマンドを実行しましょう。 $ brew update $ brew upgrade $ brew tap ethereum/ethereum $ brew install solidity $ brew linkapps solidity brew update を実行するときに Error: homebrew-core is a shallow clone. のエラーが、起きる場合があります。その場合はメッセージに、書いてあるとおりに、gitコマンドを実行しましょう。 インストールがうまくいっていれば、次のコマンドが成功します。 $ solc --version Windows の場合 ダウンロードサイト から、 solc-windows.exe を落としてインストールしましょう。 スマート コントラ クトのコード 最初のスマート コントラ クトとして、数値をスマート コントラ クトの状態変数に格納したり、取り出したりするプログラムを書いてみましょう。 NumberRegister.sol pragma solidity ^ 0.8 . 10 ; contract NumberRegister { uint num; function set( uint _num) public { num = _num; } function get() public view returns ( uint ) { return num; } } Solidityの細かい文法については、今後の記事で取り上げるので、細かいことは気にしなくて大丈夫です。この NumberRegiseter.sol をprivate_netの ディレクト リに保存しましょう。 solc SolidityのプログラムをEthereumで実行できるようにするには、 solc で コンパイル します。 コンパイル とは、 NumberRegiseter.sol のような人間が見て理解しやすいコードをコンピューターが実行できるように変更することです。 もう一つ、ターミナルを立ち上げて、 solc を実行しましょう。 $ cd private_net $ solc --abi --bin NumberRegister.sol 次のような出力が表示されたはずです。 ======= NumberRegister.sol:NumberRegister ======= Binary: 608060405234801561001057600080fd5b50610150806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806360fe47b11461003b5780636d4ce63c14610057575b600080fd5b610055600480360381019061005091906100c3565b610075565b005b61005f61007f565b60405161006c91906100ff565b60405180910390f35b8060008190555050565b60008054905090565b600080fd5b6000819050919050565b6100a08161008d565b81146100ab57600080fd5b50565b6000813590506100bd81610097565b92915050565b6000602082840312156100d9576100d8610088565b5b60006100e7848285016100ae565b91505092915050565b6100f98161008d565b82525050565b600060208201905061011460008301846100f0565b9291505056fea2646970667358221220348a0bef0ed2915311a28c4b28b351b950a27275e260ed0a915108c3b0257d2c64736f6c634300080a0033 Contract JSON ABI [{"inputs":[],"name":"get","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_num","type":"uint256"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"}] Binaryのところに書いてある 6080 ではじまり 0033 で終わる文字列の先頭に0xを付加した上で、シングルクォートでくくり、Gethのコンソールに貼り付けます。BinaryはEVM(Ethereumの 仮想マシン )が理解できる バイトコード です。 > bin = '0x608060405234801561001057600080fd5b50610150806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806360fe47b11461003b5780636d4ce63c14610057575b600080fd5b610055600480360381019061005091906100c3565b610075565b005b61005f61007f565b60405161006c91906100ff565b60405180910390f35b8060008190555050565b60008054905090565b600080fd5b6000819050919050565b6100a08161008d565b81146100ab57600080fd5b50565b6000813590506100bd81610097565b92915050565b6000602082840312156100d9576100d8610088565b5b60006100e7848285016100ae565b91505092915050565b6100f98161008d565b82525050565b600060208201905061011460008301846100f0565b9291505056fea2646970667358221220348a0bef0ed2915311a28c4b28b351b950a27275e260ed0a915108c3b0257d2c64736f6c634300080a0033' 同様に Contract JSON ABI もコンソールに貼り付けましょう。ABIはスマート コントラ クトの入出力の仕様になります。 > abi = [{"inputs":[],"name":"get","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_num","type":"uint256"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"}] ここで定義した bin と abi は、この後で使うので覚えておいてください。binはEVM(Ethereumの 仮想マシン )が理解できる バイトコード 、abiはスマート コントラ クトの入出力の仕様です。 スマート コントラ クトのデプロイ 先ほどのスマート コントラ クトをEthereumネットワークにデプロイしましょう。 > cnt = eth.contract(abi).new({from: eth.accounts[0], data: bin}) Error: authentication needed: password or unlock at web3.js:6347:37(47) at web3.js:5081:62(37) at web3.js:3021:48(134) at <eval>:1:28(16) Error: authentication needed: password or unlock が発生した場合は、アカウントをunlockAcount()しましょう。 トランザクション を実行する場合は、アカウントをunlockAccount()する必要があります。このエラーは何度も見ることになるので、どう対応すれば良いか体で覚えましょう。 > personal.unlockAccount(eth.accounts[0]) Unlock account 0x29faad1bb68151278c47df617766bf045c9b2b00 Passphrase: true > cnt = eth.contract(abi).new({from: eth.accounts[0], data: bin}) { abi: [{ inputs: [], name: "get", outputs: [{...}], stateMutability: "view", type: "function" }, { inputs: [{...}], name: "set", outputs: [], stateMutability: "nonpayable", type: "function" }], address: undefined, transactionHash: "0x13658235f5bff4afefd57b504a048f5c2bc37241bacfd9ce58177627aa1882b2" } cntの中身のaddressがundefinedになっていますね。これは、このスマート コントラ クトのデプロイがまだ終わっていないことを表しています。Gethのメインプロセスのログで採掘がきちんと行われていることを確認したら、cnt.addressを確認しましょう。 > cnt.address "0x102118ad7f8bede0158d2353660f63ea5780f966" スマート コントラ クトに、アクセスするにはABI(スマート コントラ クトの入出力の仕様)とaddressが必要です。それでは、NumberRegister コントラ クトを作りましょう。 > cnt2 = eth.contract(abi).at(cnt.address) { abi: [{ inputs: [], name: "get", outputs: [{...}], stateMutability: "view", type: "function" }, { inputs: [{...}], name: "set", outputs: [], stateMutability: "nonpayable", type: "function" }], address: "0x102118ad7f8bede0158d2353660f63ea5780f966", transactionHash: null, allEvents: function(), get: function(), set: function() } スマート コントラ クトの状態を変更しない場合は、 トランザクション なしで実行できます。それでは、NumberRegister.get()メソッドを呼び出してみましょう。 コントラクトオブジェクト.メソッド名.call() で呼びだすことができます。 > cnt2.get.call() 0 スマート コントラ クトの状態を変更する場合、 コントラクトオブジェクト.メソッド名.sendTransaction() を呼び出します。それでは、NumberRegister.set()を呼び出してみましょう。 > cnt2.set.sendTransaction(1, {from: eth.accounts[0]}) Error: authentication needed: password or unlock at web3.js:6347:37(47) at web3.js:5081:62(37) at web3.js:4137:41(57) at <eval>:1:36(10) エラーが出ていない人は気にしなくて大丈夫です。上記のエラーが出た人は、unlockAccount()を呼び出しましょう。 > personal.unlockAccount(eth.accounts[0]) Unlock account 0x29faad1bb68151278c47df617766bf045c9b2b00 Passphrase: true > txid = cnt2.set.sendTransaction(1, {from: eth.accounts[0]}) "0xf12e076acec31684bade23f3ca12c14396160a86464ce1298bbe10e795824f2e" Gethのメインプロセスのログで採掘が動いていることを確認し、NumberRegister.get()を呼び出してみましょう。 > cnt2.get.call() 1 cnt2.set.sendTransaction() の第一引数で指定した値が、設定されていることが分かります。 まとめ スマート コントラ クトを コンパイル すると、ABI(入出力の仕様)とバイナリー(EVMが理解できる バイトコード )が出力されます。 バイナリーをEthereumネットワークにデプロイするとaddressが付加されます。 ABIとaddressを使って コントラ クトオブジェクトを作成して、スマートコンタクトにアクセスします。 スマート コントラ クトの状態を変更しない場合、 コントラクトオブジェクト.メソッド名.call() を呼び出します。 スマート コントラ クトの状態を変更する場合、 コントラクトオブジェクト.メソッド名.sendTransaction() を呼び出します。 今回はここまで。Gethを止めておきましょう。コンソールはCTL-D。メインプロセスはCTL-Cで止めます。正直、GethのコンソールはNode.jsのモジュールも使えないなど、かなり不便です。次回からは、開発環境として Hardhat を使います。 僕の書いたNFT関連の記事 Gethはじめました NFT入門 執筆: @higa 、レビュー: @sato.taichi ( Shodo で執筆されました )
アバター
皆さん、こんにちは。 電通国際情報サービス X イノベーション 本部ソフトウェアデザインセンターの陳 欣瑩です。 業務で Amazon ECSとCodeDeployを使ってBlue/Greenデプロイを実施してみたのでその方法をご紹介します。 CodeDeployを使ったECSのBlue/Greenデプロイの手順を紹介する記事は少なくありませんが、実際にやってみると意外とハマったことが多かったです。 本記事では、ハマったことや使ってみた感想についてもご紹介したいと思います。 CodeDeployを使ったBlue/Greenデプロイについて 方法 手順の自動化 CodeDeployの設定 トラフィックの再ルーティング デプロイ設定 元のリビジョンの終了 ハマったこと CodeDeployのinstallイベントが一向に終わらない テストトラフィックの動作確認ができない リスナーポートの設定 どのドメインからテスト環境にアクセスすべきかがわからなかった Next.jsを利用する場合のAPI URL問題 使ってみた感想 デプロイの所要時間はとても短い 本番と同じ環境で動作確認できる 何よりダウンタイム0はすごい まとめ 参考にした情報 CodeDeployを使ったBlue/Greenデプロイについて CodeDeployを使ってBlue/Greenデプロイを実現するには、ターゲットグループを2つ用意する必要があります。 ALBのルーティング制御によって、 トラフィック を流すターゲットグループを切り替えることで、ダウンタイムなしで環境を切り替えることを実現できます。 図から詳しく説明します。 本番環境はユーザーがアクセス可能な環境で、テスト環境は開発者のみアクセス可能な、動作確認のための環境だと想像してください。 Target Group1とTarget Group2がありますが、初期状態では、本番環境とテスト環境の トラフィック は両方ともTarget Group1に流します。 CodeDeployを利用し、新しいコンテナイメージをデプロイすると、テスト環境の トラフィック の転送先は新しいコンテナーを持つTarget Group2に切り替えます。 本番環境の トラフィック はそのまま古いコンテナーを持つTarget Group1に流すため、デプロイ期間においても本番環境へのアクセスは可能です。 テスト環境での動作確認が完了後、CodeDeployを利用してALBの本番環境への トラフィック 転送を制御できます。本番環境もテスト環境も最新のコンテナーを持つTarget Group2に トラフィック を転送します。 トラフィック の転送の切り替えはほとんど時間がかからないため、ダウンタイムほぼ0でデプロイできます。 Blue/Greenデプロイは本番環境とテスト環境の入れ替えのイメージがありますが、CodeDeployの場合はデプロイ完了後、本番環境もテスト環境も同じターゲットグループに トラフィック を転送します。 次のデプロイを実行すると、Target Group1は最新のコンテナーを持つようになリます。 デプロイ実行後、テスト環境のリスナーは自動的にTarget Group1に トラフィック を転送し、本番環境のリスナーはそのままTarget Group2に トラフィック を転送します。 本番環境の トラフィック の転送を制御することで、テスト環境と本番環境は両方ともTarget Group1に トラフィック を転送します。 方法 AWS マネジメントコンソールから以下のリソースを作成しました。 VPC などネットワークインフラ CodeDeployにECSを更新するアクセス許可を付与するIAMロール ALB ECRレポジトリ ECS クラスタ ー ECSタスク定義 ECSサービス Route53を利用する場合は、Aレコードを作成し、ルーティング先をALBにする リソースの作成、およびBlue/Greenデプロイの実行手順は以下の記事を参考にしました。 https://aws.amazon.com/jp/premiumsupport/knowledge-center/codedeploy-ecs-blue-green-deployment/ https://aws.amazon.com/jp/blogs/news/use-aws-codedeploy-to-implement-blue-green-deployments-for-aws-fargate-and-amazon-ecs/ 今回は本番環境で HTTPS を利用したいため、本番環境のリスナーポートを443、テスト環境のリスナーポートを8443にしました。 手順の自動化 AWS for GitHub Actionsを組み合わせれば、 GitHub Actionsワークフローを利用してCodeDeployの実行までの手順を自動化できます。 Dockerfileをbuildし、タグをつけてECRにpushする amazon-ecr-login ECSタスク定義を更新する amazon-ecs-render-task-definition 更新されたタスク定義を使ってCodeDeployのデプロイを実行させる amazon-ecs-deploy-task-definition GitHub にタグをプッシュすることで、既存のECSリソースにCodeDeployを使用したBlue/Greenデプロイができます。ただし、デプロイ後の トラフィック 転送先の切り替えなど、CodeDeployに対する操作は AWS マネジメントコンソールから手動で操作する必要があります。 CodeDeployの設定 AWS マネジメントコンソールから、CodeDeployの以下の設定を変更できます。(アプリケーション>デプロイグループを選択>編集) トラフィック の再ルーティング トラフィック の再ルーティングとは、ALBで本番 トラフィック の転送先のターゲットグループを切り替えることを指します。 デフォルトでは、 トラフィック が直ちに置き換え先環境に再ルーティングされるように設定されています。 トラフィック が再ルーティングされる前に、動作確認したい場合は再ルーティングするタイミング、つまり待機する日数、時間、分数を指定できます。動作確認のために再ルーティングを保留できる時間は最短5分、最長時1日間23時間55分まで指定できます。 Lambda関数の検証テストをAppSpecファイルに追加すれば、設定した待機時間内に検証テストが自動的に実行されます。 テスト環境のポートにアクセスすれば動作確認ができます。動作確認が完了後、再ルーティングを実行するために、CodeDeployの「 トラフィック の再ルーティング」ボタンを指定した待機時間内に押下する必要があります。(CodeDeployのコンソールでデプロイIDをクリックした後の画面にあります) 待機時間が経過しても、再ルーティングが実行されない場合は、デプロイの状態は失敗になります。 デプロイ設定 デプロイの速度や、デプロイ成功または失敗の条件など、ルールを設定できます。 元のリビジョンの終了 新しいタスクのデプロイが完了後、元のタスクセットを終了するまでの時間を設定できます。デフォルトは1時間です。 設定した時間内に、デプロイしたものに問題があったら、いつでも元のタスクセットに ロールバック できます。 再ルーティングの実行後でも ロールバック はできます。 終了処理が開始すると ロールバック することはできません。 ハマったこと CodeDeployのinstallイベントが一向に終わらない CodeDeployのコンソールでは詳しいログ情報やエラーメッセージが表示されないため、最初は原因がよくわからず困りました。 今回は、Dockerfileに不備があり、起動できない状態のコンテナーをデプロイしようとしているのが原因でした。他の記事を読むと、IAMロールに必要な権限がない場合や、task-definition. json にミスがあった場合でもCodeDeoloyのinstallが延々と続くらしいです。 何かの不備があるとCodeDeployでのinstallイベントは一向に終わらなくなります。しかし、Dockerfileやtask-definition. json は変更を頻繁に加えるものではないため、デプロイが成功したものを使い続ければこのような問題は発生しないでしょう。 テスト トラフィック の動作確認ができない ECSとCodeDeployを使用してBlue/Greenデプロイを実施すると、設定した待機時間内に、テスト環境のリスナーポートにアクセスし動作確認ができます。しかし、リスナーポートの設定が不適切な場合やWebアプリケーションのURLがハードコードされる場合は、動作確認できないこともあります。 リスナーポートの設定 最初は、本番環境のリスナーポートを HTTPS /443、テスト環境のリスナーポートをHTTP/8080にしましたが、テスト環境のリスナーポートにアクセスできませんでした。 理由としては、検証で使っていた .dev の ドメイン ではHTTPが使えないからです。他にも、HTTPを HTTPS にリダイレクトする要件があれば、両方とも HTTPS のポートにしたほう望ましいでしょう。 どの ドメイン からテスト環境にアクセスすべきかがわからなかった 最初は、本番環境と同じ ドメイン でなくALBの ドメイン を使ってテスト環境にアクセスしてしまいました。 本番環境と異なる ドメイン からアクセスすると、場合によってログインできなくなったり、 API リク エス トを投げられなくなったりすることもあります。 本番環境の ドメイン は https://example.com であれば、それと同じ ドメイン のテストポート https://example.com:8443 からテスト環境にアクセスするのが正解です。 Next.jsを利用する場合の API URL問題 Next.jsのgetServerSidePropsを利用し、 API リク エス トを送信するには、 API エンドポイントのURLを次のように指定する必要があります。 axios.get(https://example.com/api/hello) https://example.com の部分を 環境変数 として設定してしまう場合は、異なるポートからアクセスし API にリク エス トを送信すると、CORSエラーが発生します。 それを回避するために、URLのハードコードをやめて、以下のようにgetServerSidePropsのcontextからホスト名とポート番号を取得しました。 axios.get(https://${ctx.req.headers.host!}/api/hello) ただし、 プロトコル はcontextから取得できないため、 https を固定するまたは 環境変数 に入れる必要があります。 使ってみた感想 デプロイの所要時間はとても短い 今回は GitHub Actionsを利用すると、ほとんどのワークフローの処理時間は1秒程度で完結できました。DockerfileのbuildおよびECRへのpushは、相対的に時間かかりましたが、Dockerfileの改善により処理速度の短縮が期待できます。 GitHub Actionsのワークフローが成功した後、CodeDeployでのデプロイ(置き換えタスクセットのデプロイ、テスト トラフィック ルーティングのセットアップ)は約2、3分間くらいかかります。動作確認を含め、デプロイの全体を数分程度に抑えることができたのですごいと思いました。 本番と同じ環境で動作確認できる テスト トラフィック で動作確認し、問題がなければ本番 トラフィック の転送先を切り替えればデプロイが完了しますので、テスト トラフィック の転送先のターゲットグループは本番に昇格するみたいなイメージですね。万が一動作確認でバグを見つけても、本番環境に影響せず ロールバック ができます。 何よりダウンタイム0はすごい また、 トラフィック の再ルーティングはほとんど時間がかからないため、デプロイで発生するダウンタイムは0に近いです。テスト トラフィック で動作確認できるため、ユーザーはデプロイ作業に影響されなくシステムを使い続けられます。 まとめ 本記事では、 Amazon ECSとCodeDeployを使ってBlue/Greenデプロイメンを実施する方法、ハマったところや使ってみた感想についてご紹介しました。デプロイの時間を短縮し、ダウンタイムなしでデプロイできるので、本当に便利だと思いました。 AWS によくまとめてある設定手順がありますので、皆さんご機会がありましたらぜひ使ってみてください。 最後までお読みいただきありがとうございました。 参考にした情報 https://aws.amazon.com/jp/premiumsupport/knowledge-center/codedeploy-ecs-blue-green-deployment/ https://aws.amazon.com/jp/blogs/news/use-aws-codedeploy-to-implement-blue-green-deployments-for-aws-fargate-and-amazon-ecs/ https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/userguide/deployment-type-bluegreen.html 執筆: @chen.xinying 、レビュー: @sato.taichi ( Shodo で執筆されました )
アバター
皆さん、こんにちは。 電通国際情報サービス X イノベーション 本部ソフトウェアデザインセンターの陳 欣瑩です。 業務で Amazon ECSとCodeDeployを使ってBlue/Greenデプロイを実施してみたのでその方法をご紹介します。 CodeDeployを使ったECSのBlue/Greenデプロイの手順を紹介する記事は少なくありませんが、実際にやってみると意外とハマったことが多かったです。 本記事では、ハマったことや使ってみた感想についてもご紹介したいと思います。 CodeDeployを使ったBlue/Greenデプロイについて 方法 手順の自動化 CodeDeployの設定 トラフィックの再ルーティング デプロイ設定 元のリビジョンの終了 ハマったこと CodeDeployのinstallイベントが一向に終わらない テストトラフィックの動作確認ができない リスナーポートの設定 どのドメインからテスト環境にアクセスすべきかがわからなかった Next.jsを利用する場合のAPI URL問題 使ってみた感想 デプロイの所要時間はとても短い 本番と同じ環境で動作確認できる 何よりダウンタイム0はすごい まとめ 参考にした情報 CodeDeployを使ったBlue/Greenデプロイについて CodeDeployを使ってBlue/Greenデプロイを実現するには、ターゲットグループを2つ用意する必要があります。 ALBのルーティング制御によって、 トラフィック を流すターゲットグループを切り替えることで、ダウンタイムなしで環境を切り替えることを実現できます。 図から詳しく説明します。 本番環境はユーザーがアクセス可能な環境で、テスト環境は開発者のみアクセス可能な、動作確認のための環境だと想像してください。 Target Group1とTarget Group2がありますが、初期状態では、本番環境とテスト環境の トラフィック は両方ともTarget Group1に流します。 CodeDeployを利用し、新しいコンテナイメージをデプロイすると、テスト環境の トラフィック の転送先は新しいコンテナーを持つTarget Group2に切り替えます。 本番環境の トラフィック はそのまま古いコンテナーを持つTarget Group1に流すため、デプロイ期間においても本番環境へのアクセスは可能です。 テスト環境での動作確認が完了後、CodeDeployを利用してALBの本番環境への トラフィック 転送を制御できます。本番環境もテスト環境も最新のコンテナーを持つTarget Group2に トラフィック を転送します。 トラフィック の転送の切り替えはほとんど時間がかからないため、ダウンタイムほぼ0でデプロイできます。 Blue/Greenデプロイは本番環境とテスト環境の入れ替えのイメージがありますが、CodeDeployの場合はデプロイ完了後、本番環境もテスト環境も同じターゲットグループに トラフィック を転送します。 次のデプロイを実行すると、Target Group1は最新のコンテナーを持つようになリます。 デプロイ実行後、テスト環境のリスナーは自動的にTarget Group1に トラフィック を転送し、本番環境のリスナーはそのままTarget Group2に トラフィック を転送します。 本番環境の トラフィック の転送を制御することで、テスト環境と本番環境は両方ともTarget Group1に トラフィック を転送します。 方法 AWS マネジメントコンソールから以下のリソースを作成しました。 VPC などネットワークインフラ CodeDeployにECSを更新するアクセス許可を付与するIAMロール ALB ECRレポジトリ ECS クラスタ ー ECSタスク定義 ECSサービス Route53を利用する場合は、Aレコードを作成し、ルーティング先をALBにする リソースの作成、およびBlue/Greenデプロイの実行手順は以下の記事を参考にしました。 https://aws.amazon.com/jp/premiumsupport/knowledge-center/codedeploy-ecs-blue-green-deployment/ https://aws.amazon.com/jp/blogs/news/use-aws-codedeploy-to-implement-blue-green-deployments-for-aws-fargate-and-amazon-ecs/ 今回は本番環境で HTTPS を利用したいため、本番環境のリスナーポートを443、テスト環境のリスナーポートを8443にしました。 手順の自動化 AWS for GitHub Actionsを組み合わせれば、 GitHub Actionsワークフローを利用してCodeDeployの実行までの手順を自動化できます。 Dockerfileをbuildし、タグをつけてECRにpushする amazon-ecr-login ECSタスク定義を更新する amazon-ecs-render-task-definition 更新されたタスク定義を使ってCodeDeployのデプロイを実行させる amazon-ecs-deploy-task-definition GitHub にタグをプッシュすることで、既存のECSリソースにCodeDeployを使用したBlue/Greenデプロイができます。ただし、デプロイ後の トラフィック 転送先の切り替えなど、CodeDeployに対する操作は AWS マネジメントコンソールから手動で操作する必要があります。 CodeDeployの設定 AWS マネジメントコンソールから、CodeDeployの以下の設定を変更できます。(アプリケーション>デプロイグループを選択>編集) トラフィック の再ルーティング トラフィック の再ルーティングとは、ALBで本番 トラフィック の転送先のターゲットグループを切り替えることを指します。 デフォルトでは、 トラフィック が直ちに置き換え先環境に再ルーティングされるように設定されています。 トラフィック が再ルーティングされる前に、動作確認したい場合は再ルーティングするタイミング、つまり待機する日数、時間、分数を指定できます。動作確認のために再ルーティングを保留できる時間は最短5分、最長時1日間23時間55分まで指定できます。 Lambda関数の検証テストをAppSpecファイルに追加すれば、設定した待機時間内に検証テストが自動的に実行されます。 テスト環境のポートにアクセスすれば動作確認ができます。動作確認が完了後、再ルーティングを実行するために、CodeDeployの「 トラフィック の再ルーティング」ボタンを指定した待機時間内に押下する必要があります。(CodeDeployのコンソールでデプロイIDをクリックした後の画面にあります) 待機時間が経過しても、再ルーティングが実行されない場合は、デプロイの状態は失敗になります。 デプロイ設定 デプロイの速度や、デプロイ成功または失敗の条件など、ルールを設定できます。 元のリビジョンの終了 新しいタスクのデプロイが完了後、元のタスクセットを終了するまでの時間を設定できます。デフォルトは1時間です。 設定した時間内に、デプロイしたものに問題があったら、いつでも元のタスクセットに ロールバック できます。 再ルーティングの実行後でも ロールバック はできます。 終了処理が開始すると ロールバック することはできません。 ハマったこと CodeDeployのinstallイベントが一向に終わらない CodeDeployのコンソールでは詳しいログ情報やエラーメッセージが表示されないため、最初は原因がよくわからず困りました。 今回は、Dockerfileに不備があり、起動できない状態のコンテナーをデプロイしようとしているのが原因でした。他の記事を読むと、IAMロールに必要な権限がない場合や、task-definition. json にミスがあった場合でもCodeDeoloyのinstallが延々と続くらしいです。 何かの不備があるとCodeDeployでのinstallイベントは一向に終わらなくなります。しかし、Dockerfileやtask-definition. json は変更を頻繁に加えるものではないため、デプロイが成功したものを使い続ければこのような問題は発生しないでしょう。 テスト トラフィック の動作確認ができない ECSとCodeDeployを使用してBlue/Greenデプロイを実施すると、設定した待機時間内に、テスト環境のリスナーポートにアクセスし動作確認ができます。しかし、リスナーポートの設定が不適切な場合やWebアプリケーションのURLがハードコードされる場合は、動作確認できないこともあります。 リスナーポートの設定 最初は、本番環境のリスナーポートを HTTPS /443、テスト環境のリスナーポートをHTTP/8080にしましたが、テスト環境のリスナーポートにアクセスできませんでした。 理由としては、検証で使っていた .dev の ドメイン ではHTTPが使えないからです。他にも、HTTPを HTTPS にリダイレクトする要件があれば、両方とも HTTPS のポートにしたほう望ましいでしょう。 どの ドメイン からテスト環境にアクセスすべきかがわからなかった 最初は、本番環境と同じ ドメイン でなくALBの ドメイン を使ってテスト環境にアクセスしてしまいました。 本番環境と異なる ドメイン からアクセスすると、場合によってログインできなくなったり、 API リク エス トを投げられなくなったりすることもあります。 本番環境の ドメイン は https://example.com であれば、それと同じ ドメイン のテストポート https://example.com:8443 からテスト環境にアクセスするのが正解です。 Next.jsを利用する場合の API URL問題 Next.jsのgetServerSidePropsを利用し、 API リク エス トを送信するには、 API エンドポイントのURLを次のように指定する必要があります。 axios.get(https://example.com/api/hello) https://example.com の部分を 環境変数 として設定してしまう場合は、異なるポートからアクセスし API にリク エス トを送信すると、CORSエラーが発生します。 それを回避するために、URLのハードコードをやめて、以下のようにgetServerSidePropsのcontextからホスト名とポート番号を取得しました。 axios.get(https://${ctx.req.headers.host!}/api/hello) ただし、 プロトコル はcontextから取得できないため、 https を固定するまたは 環境変数 に入れる必要があります。 使ってみた感想 デプロイの所要時間はとても短い 今回は GitHub Actionsを利用すると、ほとんどのワークフローの処理時間は1秒程度で完結できました。DockerfileのbuildおよびECRへのpushは、相対的に時間かかりましたが、Dockerfileの改善により処理速度の短縮が期待できます。 GitHub Actionsのワークフローが成功した後、CodeDeployでのデプロイ(置き換えタスクセットのデプロイ、テスト トラフィック ルーティングのセットアップ)は約2、3分間くらいかかります。動作確認を含め、デプロイの全体を数分程度に抑えることができたのですごいと思いました。 本番と同じ環境で動作確認できる テスト トラフィック で動作確認し、問題がなければ本番 トラフィック の転送先を切り替えればデプロイが完了しますので、テスト トラフィック の転送先のターゲットグループは本番に昇格するみたいなイメージですね。万が一動作確認でバグを見つけても、本番環境に影響せず ロールバック ができます。 何よりダウンタイム0はすごい また、 トラフィック の再ルーティングはほとんど時間がかからないため、デプロイで発生するダウンタイムは0に近いです。テスト トラフィック で動作確認できるため、ユーザーはデプロイ作業に影響されなくシステムを使い続けられます。 まとめ 本記事では、 Amazon ECSとCodeDeployを使ってBlue/Greenデプロイメンを実施する方法、ハマったところや使ってみた感想についてご紹介しました。デプロイの時間を短縮し、ダウンタイムなしでデプロイできるので、本当に便利だと思いました。 AWS によくまとめてある設定手順がありますので、皆さんご機会がありましたらぜひ使ってみてください。 最後までお読みいただきありがとうございました。 参考にした情報 https://aws.amazon.com/jp/premiumsupport/knowledge-center/codedeploy-ecs-blue-green-deployment/ https://aws.amazon.com/jp/blogs/news/use-aws-codedeploy-to-implement-blue-green-deployments-for-aws-fargate-and-amazon-ecs/ https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/userguide/deployment-type-bluegreen.html 執筆: @chen.xinying 、レビュー: @sato.taichi ( Shodo で執筆されました )
アバター
NFT入門
電通国際情報サービス オープン イノベーション ラボの比嘉です。 今回のテーマはNFT。Non-fungible tokenの略で、日本語だと非代替性 トーク ン。 これと対をなす言葉がFungible token、日本語だと代替性 トーク ン。 Bitcoin のような暗号資産は、Aさんがもっている トーク ンとBさんが持っている トーク ンは区別できません。このようにそれぞれが区別できない トーク ンを代替性 トーク ンといいます。 NFT(非代替性 トーク ン)は トーク ンごとにIDをもち、各 トーク ンを区別できます。それでは、 プログラマー の視点から、NFTを見ていきましょう。 ERC-721 本当に、NFTによってデジタルデータの所有権を証明できるようになったのか まとめ ERC-721 NFTは ERC-721 として仕様が決められています。厳密にはERC-721の仕様と異なるNFTも存在しますが、事実上、NFTの仕様といえばERC-721だと思って間違いありません。 ERC-721に準拠した コントラ クトは、ERC721とERC165のinterfaceを実装する必要があります。 コントラ クトとは、Ethereum上にデプロイされるプログラムです。interfaceは Java のような言語のinterfaceと同じで、実装しなければいけない振る舞いを定義します。 ERC165はERC721を補助するinterfaceです。ERC-721の仕様ではオプションのinterfaceが存在します。ERC165のsupportsInterface()を使って、 コントラ クトがあるinterfaceを実装しているのか調べることができます。 それでは、ERC721とERC165のinterfaceを見てみましょう。 ERC721 pragma solidity ^0.4.20; interface ERC721 /* is ERC165 */ { event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId); event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId); event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); function balanceOf(address _owner) external view returns (uint256); function ownerOf(uint256 _tokenId) external view returns (address); function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable; function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable; function transferFrom(address _from, address _to, uint256 _tokenId) external payable; function approve(address _approved, uint256 _tokenId) external payable; function setApprovalForAll(address _operator, bool _approved) external; function getApproved(uint256 _tokenId) external view returns (address); function isApprovedForAll(address _owner, address _operator) external view returns (bool); } ERC-165 interface ERC165 { function supportsInterface(bytes4 interfaceID) external view returns (bool); } 仕様上はオプションなんだけど、どの コントラ クトも実装している重要なインターフェースが、ERC721Metadataです。それではinterfaceを見てみましょう。 ERC721Metadata interface ERC721Metadata /* is ERC721 */ { function name() external view returns (string _name); function symbol() external view returns (string _symbol); function tokenURI(uint256 _tokenId) external view returns (string); } NFTが発行(mint)されたとき、tokenIdが発行されます。そのtokenIdを使ってtokenURI()を呼びだすと URI が返ってきます。その URI にアクセスすると次のような JSON データが返ってきます。 { "name": "NFT Name", "description": "NFT Description.", "image": "https://example.com/xxx.png" } imageが指しているURLにアクセスすると画像を取得できます。整理すると次のようになります。 NFTが発行されたときに、tokenIdが発行される NFT(ERC721に準拠した コントラ クト)のtokenURI()をtokenIdを引数にして呼びだすと、tokenURIが返ってくる tokenURIにアクセスすると JSON データが返ってくる。 JSON データのimageに画像のURLが格納されている。 imageに直接 Base64 でデータを埋め込むこともできます。NFTの正体がだいぶ見えてきたのではないでしょうか。NFTはデジタルデータと JSON データを通じて、緩くつながっているだけです。 本当に、NFTによってデジタルデータの所有権を証明できるようになったのか NFTによってデジタルデータの所有権を証明できるようになった という説明をどこかで聞いたことがあるかもしれません。法的な意味での所有権は有体物(物理的に存在するモノ)にのみ発生するものなので、法の専門家は「 保有 」という言葉を勧めているようです。そこで、次のように書き換えましょう。 NFTによってデジタルデータの保有を証明できるようになった これは、本当なのでしょうか。 NFTは発行されたときに、購入者のaddressとtokenIdがひもづけされます。そのため、NFT自体の 保有 は確実に証明できます。しかし、NFTとデジタルデータは JSON データで緩くつながっているだけなので、NFTだけでデジタルデータを 保有 していることは証明できません。 それでは、 NFTによってデジタルデータの保有を証明できるようになった は間違いなのでしょうか。実はそうとも限りません。 NFTの購入は、OpenSeaのようなプラットフォームを利用することがほとんどでしょう。どのプラットフォームでも購入の際に、 利用規約 が示されます。この 利用規約 に書かれていることは、デジタルデータに対する権利として認められています。この権利を持って、 NFTによってデジタルデータの保有を証明できるようになったといえる と 法律の専門家 も認めているようです。NFTを購入した時の権利は、プラットフォームの 利用規約 以外に、パブリックライセンスを使うケースもあるようです。 まとめ 今回は、NFTを プログラマー の視点から眺めてみました。NFTの正体掴めたでしょうか。NFTを プログラマー 視点から理解するうえでも、NFTを購入した時にどんな権利を得ているのかということは、どうしても理解しておく必要があります。僕は、法律の専門家ではありませんが、自分のためにNFTの法的な解釈も最小限載せました。僕のNFTの法的な解釈はうのみにせず、専門家の話を聞く/読むことを強くお勧めします。 NFTの法的解釈のおすすめ記事 増田雅史さんのNFTの記事 NFTに関する法的考察~アート、ゲーム、スポーツを題材に~ 僕の書いたNFT関連の記事 Gethはじめました スマートコントラクト入門 執筆: @higa 、レビュー: @sato.taichi ( Shodo で執筆されました )
アバター
NFT入門
電通国際情報サービス オープン イノベーション ラボの比嘉です。 今回のテーマはNFT。Non-fungible tokenの略で、日本語だと非代替性 トーク ン。 これと対をなす言葉がFungible token、日本語だと代替性 トーク ン。 Bitcoin のような暗号資産は、Aさんがもっている トーク ンとBさんが持っている トーク ンは区別できません。このようにそれぞれが区別できない トーク ンを代替性 トーク ンといいます。 NFT(非代替性 トーク ン)は トーク ンごとにIDをもち、各 トーク ンを区別できます。それでは、 プログラマー の視点から、NFTを見ていきましょう。 ERC-721 本当に、NFTによってデジタルデータの所有権を証明できるようになったのか まとめ ERC-721 NFTは ERC-721 として仕様が決められています。厳密にはERC-721の仕様と異なるNFTも存在しますが、事実上、NFTの仕様といえばERC-721だと思って間違いありません。 ERC-721に準拠した コントラ クトは、ERC721とERC165のinterfaceを実装する必要があります。 コントラ クトとは、Ethereum上にデプロイされるプログラムです。interfaceは Java のような言語のinterfaceと同じで、実装しなければいけない振る舞いを定義します。 ERC165はERC721を補助するinterfaceです。ERC-721の仕様ではオプションのinterfaceが存在します。ERC165のsupportsInterface()を使って、 コントラ クトがあるinterfaceを実装しているのか調べることができます。 それでは、ERC721とERC165のinterfaceを見てみましょう。 ERC721 pragma solidity ^0.4.20; interface ERC721 /* is ERC165 */ { event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId); event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId); event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); function balanceOf(address _owner) external view returns (uint256); function ownerOf(uint256 _tokenId) external view returns (address); function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable; function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable; function transferFrom(address _from, address _to, uint256 _tokenId) external payable; function approve(address _approved, uint256 _tokenId) external payable; function setApprovalForAll(address _operator, bool _approved) external; function getApproved(uint256 _tokenId) external view returns (address); function isApprovedForAll(address _owner, address _operator) external view returns (bool); } ERC-165 interface ERC165 { function supportsInterface(bytes4 interfaceID) external view returns (bool); } 仕様上はオプションなんだけど、どの コントラ クトも実装している重要なインターフェースが、ERC721Metadataです。それではinterfaceを見てみましょう。 ERC721Metadata interface ERC721Metadata /* is ERC721 */ { function name() external view returns (string _name); function symbol() external view returns (string _symbol); function tokenURI(uint256 _tokenId) external view returns (string); } NFTが発行(mint)されたとき、tokenIdが発行されます。そのtokenIdを使ってtokenURI()を呼びだすと URI が返ってきます。その URI にアクセスすると次のような JSON データが返ってきます。 { "name": "NFT Name", "description": "NFT Description.", "image": "https://example.com/xxx.png" } imageが指しているURLにアクセスすると画像を取得できます。整理すると次のようになります。 NFTが発行されたときに、tokenIdが発行される NFT(ERC721に準拠した コントラ クト)のtokenURI()をtokenIdを引数にして呼びだすと、tokenURIが返ってくる tokenURIにアクセスすると JSON データが返ってくる。 JSON データのimageに画像のURLが格納されている。 imageに直接 Base64 でデータを埋め込むこともできます。NFTの正体がだいぶ見えてきたのではないでしょうか。NFTはデジタルデータと JSON データを通じて、緩くつながっているだけです。 本当に、NFTによってデジタルデータの所有権を証明できるようになったのか NFTによってデジタルデータの所有権を証明できるようになった という説明をどこかで聞いたことがあるかもしれません。法的な意味での所有権は有体物(物理的に存在するモノ)にのみ発生するものなので、法の専門家は「 保有 」という言葉を勧めているようです。そこで、次のように書き換えましょう。 NFTによってデジタルデータの保有を証明できるようになった これは、本当なのでしょうか。 NFTは発行されたときに、購入者のaddressとtokenIdがひもづけされます。そのため、NFT自体の 保有 は確実に証明できます。しかし、NFTとデジタルデータは JSON データで緩くつながっているだけなので、NFTだけでデジタルデータを 保有 していることは証明できません。 それでは、 NFTによってデジタルデータの保有を証明できるようになった は間違いなのでしょうか。実はそうとも限りません。 NFTの購入は、OpenSeaのようなプラットフォームを利用することがほとんどでしょう。どのプラットフォームでも購入の際に、 利用規約 が示されます。この 利用規約 に書かれていることは、デジタルデータに対する権利として認められています。この権利を持って、 NFTによってデジタルデータの保有を証明できるようになったといえる と 法律の専門家 も認めているようです。NFTを購入した時の権利は、プラットフォームの 利用規約 以外に、パブリックライセンスを使うケースもあるようです。 まとめ 今回は、NFTを プログラマー の視点から眺めてみました。NFTの正体掴めたでしょうか。NFTを プログラマー 視点から理解するうえでも、NFTを購入した時にどんな権利を得ているのかということは、どうしても理解しておく必要があります。僕は、法律の専門家ではありませんが、自分のためにNFTの法的な解釈も最小限載せました。僕のNFTの法的な解釈はうのみにせず、専門家の話を聞く/読むことを強くお勧めします。 NFTの法的解釈のおすすめ記事 増田雅史さんのNFTの記事 NFTに関する法的考察~アート、ゲーム、スポーツを題材に~ 僕の書いたNFT関連の記事 Gethはじめました スマートコントラクト入門 執筆: @higa 、レビュー: @sato.taichi ( Shodo で執筆されました )
アバター
メリークリスマス✨ISID 金融ソリューション事業部 市場系 イノベーション 部の寺山です! 新型コロナ禍の日々ですが、クリスマスイブはちょうど金曜日でしたし、皆さま楽しく過ごせましたかね?? さて、本記事は 電通国際情報サービス Advent Calendar 2021 の最終日のポストとなります。前回は、浦本さんの「フロントエンド依存ライブラリのバージョンアップ戦略」でした。 いやぁ、Advent Calendarに参加するぜ!ってエントリーしてしばらく経ってから、あれ??トリじゃん!?って気づきましたよ。。笑 しかしながらそんなことは気にせず、私が興味を持ったことについて投稿させていただきたいと思います! はじめに EKSにホストしたマイクロサービスの構成 コンテナー型マイクロサービスの可視化 K8sおよびエコシステムのバージョン AMPのアドオン (省略) AMGのアドオン 可視化 まとめと今後の展望 おまけ:VSCodeのKubernetes拡張機能 参考文献 はじめに インフラ・ クラウド というエンジニアリング領域を担当している私は、 Kubernetes (以下 K8s )を以下のように認識しております。 インフラスト ラク チャをソフトウェアでハイレベルに抽象化して制御する強力なテク ノロ ジー コミュニティが活発であり デベロッパ ーやインフラ管理者を支援するツールが日々進化している 2点目に関連し、コンテナレベルでの監視や可視化をサポートするエコシステムである、 Prometheus と Grafana がそれぞれ AWS のマネージドサービスとしてGAされました。 Amazon Managed Service for Prometheus(以下、AMP) Amazon Managed Service for Prometheus Is Now Generally Available with Alert Manager and Ruler Amazon Managed Grafana(以下、 AMG ) Amazon Managed Grafana Is Now Generally Available with Many New Features GAされてから4カ月ほど経過しますが、EKS+AMP+ AMG という記事は以外と私の目に入っておりません。そこで、AMPと AMG を用いて Amazon EKSにホストしたマイクロサービスの可視化をやってみた!というのが、本記事の主旨となります。 K8s に対してはキャッチアップ中というスキルセット&ブログを書くのが初めてということもあり、誤りや至らぬ点もあるかと存じますが、ご指摘等はコメントいただけるとありがたいです(>人<;) EKSにホストしたマイクロサービスの構成 本題へ入る前に、モニタリング対象のマイクロサービスのインフラ構成をご説明します。 コンポーネント は全て AWS のサービスで構成しています。リージョンはアジアパシフィック(東京)です。 マイクロサービスアプリケーションは、バックエンドとして、認証/認可機能、共通機能、これらの機能を用いて ビジネスロジック を実装し機能として提供するコンテナーをそれぞれのPod内で実行しています。コンテナーのイメージは Amazon ECR(以下ECR)から取得します。 コンテナランタイムの実行環境はサーバレスコンピューティングサービスである AWS Fargate(以下Fargate)を利用しています。 ステートフルな情報は永続化層としてプロビジョニングした Amazon Aurora (以下Aurora)より取得・保管します。 EKS クラスタ ーにデプロイした AWS Load Balancer Controllerにより、 ACM 証明書を適用して SSL / TLS 接続をオフロードするApplication Load Balancer(以下ALB)をプロビジョニングしています。 ALBは、フロントエンド(クライアント)からの REST API リク エス ト トラフィック を ビジネスロジック Serviceにパスベースでルーティングします。 これらのコンテナー関連リソースを制御する K8s マスターが AWS マネージドとして作成/運用される Amazon EKS(以下EKS)で クラスタ ーを構成しています。 エンドユーザーはSPAを取得して、 REST API でバックエンドとリソースのやり取りをするというマイクロサービスにおける代表的な アーキテクチャ です。SPAはS3に格納し、CloudFrontにより HTTPS で配信します。ただし、オリジンはS3 バケット のみであり、バックエンド(ALB)は指定していません。 全体的に、(プライベートサブネットとCloudFrontの構成をサボっているところ以外は) AWS での典型的な アーキテクチャ だと思っています。ちなみに、フロントエンド・バックエンドのアプリケーションを開発したのは私ではありません。ありがとう、チームのみんな〜 コンテナー型マイクロサービスの可視化 PodのログはFluent Bitを利用すれば比較的簡単( Fargate ログ記録 参照)にCloudWatch Logsで収集可能となります。 Fluent Bitは一部のメトリクスもログストリームに含めることをサポートしています 1 。 そのため、CloudWatchでメトリクスフィルターを頑張って設定すれば、可視化もできそうです。 ただし、せっかく K8s 使用しているのですから、有用(というか人気)なエコシステムは活用したいですよね?!というのが本件のモチベーションとなります。 K8s およびエコシステムのバージョン EKS: Kubernetes 1.21、eks.3 Prometheus:14.11.1 Grafana:8.3 AMPのアドオン AMPユーザーガイドの Getting started に従って、前述のEKS クラスタ ーにPrometheusをアドオンします。ガイドと違いがある点や特にコメントしたい内容以外は単に作業内容を記述するのみにとどめて説明します。 AMP ワークスペース の作成 bash $ aws amp create-workspace --alias tech-research-workspace Prometheus 用の Namespace と ServieAccount 作成 ``` bash $ kubectl create namespace prometheus namespace/prometheus created $ kubectl create serviceaccount prometheus -n prometheus serviceaccount/prometheus created ``` サービスロールを作成して Service Account に関連付け Set up IAM roles for service accounts で案内されている スクリプト を作成して実行します。 ガイドの スクリプト では eksctl を利用しており、実際にEKSを構築や運用する際には有用な CLI ツールかと思いますが、 K8s の理解を深めるために kubectl で書き直しました。 と言っても、差分は以下のみなのですが。。。 ガイド内の スクリプト bash eksctl utils associate-iam-oidc-provider --cluster $CLUSTER_NAME --approve 私が書き直した スクリプト bash kubectl annotate serviceaccount -n ${SERVICE_ACCOUNT_NAMESPACE} ${SERVICE_ACCOUNT_NAMESPACE} \ eks.amazonaws.com/role-arn=${SERVICE_ACCOUNT_IAM_AMP_INGEST_ROLE_ARN} 実行します。 bash $ ./createIRSA-AMPIngest.sh arn:aws:iam::XXXXXXXXXXXX:role/amp-iamproxy-ingest-role serviceaccount/prometheus annotated EKSノードグループの作成 ここで、Prometheusの アーキテクチャ を確認すると、Prometeheus ServerのTSDBの保存先にストレージが要求されています。 ※下図は Prometeheus Overview - Architecture より抜粋したものです。 EKS クラスタ ーはデフォルトで Amazon EBSのStorage Classがデプロイ済みの環境となりますが、私が構築した クラスタ ーはFargateプロファイルのみを作成していたので、EBSをストレージとするPersistent Volumeを利用できません。 Amazon EFSのStorage Classを追加してFargate上で実行するか、EC2ノードでEBSを利用するか、なのですが本件では後者としました。 EC2ノードを利用する場合はEKS クラスタ ーにノードグループを追加します。ノードグループはマネージドノードグループとしました。 作成方法は AWS ユーザーガイドの ステップ 4 ノードを作成する の Managed nodes – Linux をご参照ください。 Prometheusのインストール Helm チャー トリポジ トリを追加 互換性があるということで、AMP用のHelm リポジトリ があるのではなく、コミュニティの リポジトリ を追加していますね。マネージドサービスでありながらコミュニティのアップデートを利用できるのは嬉しいですね! ``` bash $ helm repo add prometheus-community https://prometheus-community.github.io/helm-charts $ helm repo add kube-state-metrics https://kubernetes.github.io/kube-state-metrics $ helm repo list NAME URL prometheus-community https://prometheus-community.github.io/helm-charts kube-state-metrics https://kubernetes.github.io/kube-state-metrics $ helm repo update Hang tight while we grab the latest from your chart repositories... ...Successfully got an update from the "kube-state-metrics" chart repository ...Successfully got an update from the "prometheus-community" chart repository Update Complete. ⎈Happy Helming!⎈ ``` Helmチャートに渡すパラメーターファイルの作成 リモート書き込みエンドポイント( remoteWrite )は、AMPコンソールの ワークスペース の概要欄や、 aws amp describe-workspace --workspace-id <ワークスペースID> より確認可能です。 amp-ingest-values. yaml ```yml serviceAccounts: server: name: "amp-iamproxy-ingest-service-account" annotations: eks.amazonaws.com/role-arn: "arn: aws :iam::XXXXXXXXXXXX:role/amp-iamproxy-ingest-role" server: remoteWrite: - url: https://aps-workspaces.ap-northeast-1.amazonaws.com/workspaces/ws-XXXXXXXX-XXXXXXXXXXXXXXXX/api/v1/remote_write sigv4: region: ap-northeast-1 queue_config: max_samples_per_send: 1000 max_shards: 200 capacity: 2500 ``` Prometheus Serverのインストール ``` bash $ helm install tech-research-prometheus-chart prometheus-community/prometheus -n prometheus -f ./amp-ingest-values. yaml NAME: tech-research-prometheus-chart LAST DEPLOYED: Tue Dec 14 22:31:55 2021 NAMESPACE: prometheus STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: The Prometheus server can be accessed via port 80 on the following DNS name from within your cluster: tech-research-prometheus-chart-server.prometheus. svc .cluster.local (省略) ``` リソースの作成を確認 ``` bash $ kubectl get all -n prometheus NAME READY STATUS RESTARTS AGE pod/tech-research-prometheus-chart-alertmanager-646ff55c84-fmzfp 2/2 Running 0 2m19s pod/tech-research-prometheus-chart-kube-state-metrics-869b89746zhd5 1/1 Running 0 2m19s pod/tech-research-prometheus-chart-node-exporter-pft8p 1/1 Running 0 2m19s pod/tech-research-prometheus-chart-pushgateway-6cb64c488f-wrvdx 1/1 Running 0 2m19s pod/tech-research-prometheus-chart-server-76f7b57784-k8xj6 2/2 Running 0 2m19s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/tech-research-prometheus-chart-alertmanager ClusterIP 192.168.0.150 80/ TCP 2m19s service/tech-research-prometheus-chart-kube-state-metrics ClusterIP 192.168.0.47 8080/ TCP 2m19s service/tech-research-prometheus-chart-node-exporter ClusterIP None 9100/ TCP 2m19s service/tech-research-prometheus-chart-pushgateway ClusterIP 192.168.0.221 9091/ TCP 2m19s service/tech-research-prometheus-chart-server ClusterIP 192.168.0.244 80/ TCP 2m19s NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE daemonset.apps/tech-research-prometheus-chart-node-exporter 1 1 1 1 1 2m19s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/tech-research-prometheus-chart-alertmanager 1/1 1 1 2m20s deployment.apps/tech-research-prometheus-chart-kube-state-metrics 1/1 1 1 2m20s deployment.apps/tech-research-prometheus-chart-pushgateway 1/1 1 1 2m20s deployment.apps/tech-research-prometheus-chart-server 1/1 1 1 2m20s NAME DESIRED CURRENT READY AGE replicaset.apps/tech-research-prometheus-chart-alertmanager-646ff55c84 1 1 1 2m20s replicaset.apps/tech-research-prometheus-chart-kube-state-metrics-869b8974ff 1 1 1 2m20s replicaset.apps/tech-research-prometheus-chart-pushgateway-6cb64c488f 1 1 1 2m20s replicaset.apps/tech-research-prometheus-chart-server-76f7b57784 1 1 1 2m20s ``` AMG のアドオン こちらも AMG の Getting started に従って進めていきましょう! Grafana ワークスペース 作成 Create your first workspace に従って作成します。 Grafana ワークスペース ・コンソールには、SSOで認証を行いアクセスする必要があるのですが、本件ではSSOの方式に SAML を選択しました。 Amazon Grafana > Workspaces より ワークスペースを作成 を押下 名前と説明 ワークスペース 名 tech-research-grafana-workspace 認証アクセス Security Assertion Markup Language ( SAML ) アクセス許可タイプ サービスマネージド IAM アクセス許可アクセス設定 現在のアカウント データソース Amazon Managed Service for Prometheus ワークスペースを作成 を押下 ステータスが アクティブ となることを確認する ワークスペース の作成は一旦終了しますが、 SAML の設定を完了させるにあたり、 SAML IdPの構築が必要となります。 SAML IdPの構築 本件ではIDaaSである Okta を利用しました。 AWS にて動作確認済みのIdPは Connecting to your identity provider に一覧化されています。こちらに記載のないIdPは、Grafanaに必要な SAML アサーション 属性を マッピング できるかの検証が必要ですね。 Oktaコンソール > 管理者 より管理者ページにサインインする その際、多要素認証の設定を求められるので、Okta Verifyを利用しました。 Directory > Profile Editor と遷移 Users にてOkta用のプロファイルである User(default) を選択 Attributesの Add Attribute を押下 Add Attribute Display name Role Variable name Role Save を押下 Role 属性が追加されていること Directory > People と遷移 自分のアカウントを選択 Profile タブにてAttributesの Edit を押下 前述の手順で追加した Role 属性に ADMIN を設定 Save を押下 Applictions > Applications と遷移 Browse App Integration Catalog にて「 Amazon Managed Grafana」を Search して選択 アプリケーションの詳細画面にて Add を押下 General Settings デフォルトのままで Done を押下 Amazon Managed Grafana アプリケーションの Sing On タブに遷移 Settings において Edit を押下 Attributes (Optional) Attribute Statements (optional) Name:Role Value :user.Role Advanced Sign -on Settings Name Space:Grafana ワークスペース ID ※Grafana ワークスペース URLに含まれる ワークスペース IDを抜き出して設定します。 Region:ap-northeast-1 Save を押下 ユーザーの アサイ ン Amazon Managed Grafana アプリケーションの Assignments タブに遷移 Assign プルダウンメニューより Assign to People を選択 作成済みのアカウント(今回は私のOktaアカウント)を Assign Done を押下 AMG の SAML 設定 OktaをIdPとした SAML 認証に必要な設定を行います。 Amazon Grafana > Workspaces > 作成したワークスペース を選択 認証 タブの Security Assertion Markup Language (SAML) の セットアップを完了にする を押下 Security Assertion Markup Language ( SAML ) ステップ 2: メタデータ をインポートする インポート方法 URL メタデータ URL メタデータ URLは、Oktaアプリケーションの Sign On タブの Identity Provider metadata より確認可能です。 ステップ 3: アサーション 属性を マッピング する admin の アサーション 属性ロール アサーション 属性ロール:Role 管理者ロールの値:ADMIN ※Okta上で設定した属性と、アカウント(People)で入力した値を指定します。 追加設定 - オプション アサーション 属性名:displayName アサーション 属性 E メール:mail アサーション 属性のログイン:mail SAML設定を保存 を押下 Grafana ワークスペース の SAML 設定が 有効 となることを確認する Grafana workspace consoleにアクセスする SSOが設定できたかの動作確認も兼ねて、GrafaraのUI( ワークスペース ・コンソール)にアクセスします。 Amazon Grafana > Workspaces より作成した ワークスペース を選択し、 Grafana ワークスペース URL に表示されているリンクを開く Sign in with SAML を押下 Oktaと未認証状態の場合は、Oktaにサインインする Grafana ワークスペース ・コンソールが表示されることを確認する。 可視化 Grafana上でのメトリクスの可視化が行える状態になったので、実際に ダッシュ ボードを作成してみます。 AMPのデータソースを追加 Grafana ワークスペースコンソール> 左部メニューのAWSアイコン > AWS Data Sources を選択 AWS Data Sources Data sourcesタブ Service Amazon Managed Service for Prometheus Regions Asia Pacific (Tokyo) AMPの ワークスペース を選択して Add data source Provisioned data sourcesにAMPの ワークスペース が追加されていることを確認する。 ダッシュ ボードの追加 Grafana.com に公開されている ダッシュ ボードをインポートして、EKS クラスタ ーの可視化を行います。 Grafanaワークスペース・コンソール > Dashboards > Manage を選択 Import を押下 Kubernetes cluster monitoring (via Prometheus) の ダッシュ ボード ID をコピーして、 Import via grafana.com に入力し、 Load を押下 Options の Prometheus にて、AMP の ワークスペース を選択し、 Import を押下 無事、EKS クラスタ ーとPodのメトリクスを可視化することができました! CPU使用率 メモリ使用率 まとめと今後の展望 「やってみた」感想は以下のとおりです。 K8s はキャッチアップ中、PrometheusとGrafanaを触るのが初めての私でも、 クラスタ ーやPodのメトリクス収集と可視化を行うことができました。 Contributorの貢献、情報量の多さという OSS のメリットと、それを AWS がマネージドサービスとしてナレッジの集約・導入ハードルを下げて提供しているというメリットの両方を体感しました。 これはEKSにも当てはまると考えております。 今後の展望としては以下を検討しております。 各エコシステムの アーキテクチャ や仕様、制約の理解 ダッシュ ボードのカスタマイズやCloudWatchとの棲み分け整理 監視・可視化という運用機能ならなおさらFargateで実行したい 特に3点目は、調査できたら改めて記事にしたいと思っております! (実はFargateでトライして、苦戦したのでEC2で妥協したのはナイショ♡) おまけ: VSCode の Kubernetes 拡張機能 毎日 VSCode のお世話になっております。 VSCode を使い始める前の日々には戻れないです。 ご存じの方も多いかと思いますが、 VSCode には Microsoft 社製の Kubernetes 拡張機能 があります。 この 拡張機能 は YAML スキーマ で マニフェスト の入力補助を行う目的で導入していたのですが、左部パネルの K8s アイコンより、色々できることに気づきました。 K8s クラスタ ーやNamespaceの切り替え、各リソースの情報の取得もできます。 便利〜!という蛇足でした。 最後までご覧いただきありがとうございました。 この記事がお一人でも多く方の参考になる、または、弊社に少しでも興味も持った方がいらっしゃいましたら幸甚です。 それでは、良いお年を〜! 参考文献 AWS の公式ガイド Amazon Managed Service for Prometheus Amazon Managed Grafana AWS ワークショップ Monitoring using Amazon Managed for Prometheus / Grafana 執筆: 寺山 輝 (@terayama.akira) 、レビュー: @sato.taichi ( Shodo で執筆されました ) Fluent Bit - Metrics Tutorial https://docs.fluentbit.io/manual/pipeline/outputs/cloudwatch#metrics-tutorial ↩
アバター
メリークリスマス✨ISID 金融ソリューション事業部 市場系 イノベーション 部の寺山です! 新型コロナ禍の日々ですが、クリスマスイブはちょうど金曜日でしたし、皆さま楽しく過ごせましたかね?? さて、本記事は 電通国際情報サービス Advent Calendar 2021 の最終日のポストとなります。前回は、浦本さんの「フロントエンド依存ライブラリのバージョンアップ戦略」でした。 いやぁ、Advent Calendarに参加するぜ!ってエントリーしてしばらく経ってから、あれ??トリじゃん!?って気づきましたよ。。笑 しかしながらそんなことは気にせず、私が興味を持ったことについて投稿させていただきたいと思います! はじめに EKSにホストしたマイクロサービスの構成 コンテナー型マイクロサービスの可視化 K8sおよびエコシステムのバージョン AMPのアドオン (省略) AMGのアドオン 可視化 まとめと今後の展望 おまけ:VSCodeのKubernetes拡張機能 参考文献 はじめに インフラ・ クラウド というエンジニアリング領域を担当している私は、 Kubernetes (以下 K8s )を以下のように認識しております。 インフラスト ラク チャをソフトウェアでハイレベルに抽象化して制御する強力なテク ノロ ジー コミュニティが活発であり デベロッパ ーやインフラ管理者を支援するツールが日々進化している 2点目に関連し、コンテナレベルでの監視や可視化をサポートするエコシステムである、 Prometheus と Grafana がそれぞれ AWS のマネージドサービスとしてGAされました。 Amazon Managed Service for Prometheus(以下、AMP) Amazon Managed Service for Prometheus Is Now Generally Available with Alert Manager and Ruler Amazon Managed Grafana(以下、 AMG ) Amazon Managed Grafana Is Now Generally Available with Many New Features GAされてから4カ月ほど経過しますが、EKS+AMP+ AMG という記事は以外と私の目に入っておりません。そこで、AMPと AMG を用いて Amazon EKSにホストしたマイクロサービスの可視化をやってみた!というのが、本記事の主旨となります。 K8s に対してはキャッチアップ中というスキルセット&ブログを書くのが初めてということもあり、誤りや至らぬ点もあるかと存じますが、ご指摘等はコメントいただけるとありがたいです(>人<;) EKSにホストしたマイクロサービスの構成 本題へ入る前に、モニタリング対象のマイクロサービスのインフラ構成をご説明します。 コンポーネント は全て AWS のサービスで構成しています。リージョンはアジアパシフィック(東京)です。 マイクロサービスアプリケーションは、バックエンドとして、認証/認可機能、共通機能、これらの機能を用いて ビジネスロジック を実装し機能として提供するコンテナーをそれぞれのPod内で実行しています。コンテナーのイメージは Amazon ECR(以下ECR)から取得します。 コンテナランタイムの実行環境はサーバレスコンピューティングサービスである AWS Fargate(以下Fargate)を利用しています。 ステートフルな情報は永続化層としてプロビジョニングした Amazon Aurora (以下Aurora)より取得・保管します。 EKS クラスタ ーにデプロイした AWS Load Balancer Controllerにより、 ACM 証明書を適用して SSL / TLS 接続をオフロードするApplication Load Balancer(以下ALB)をプロビジョニングしています。 ALBは、フロントエンド(クライアント)からの REST API リク エス ト トラフィック を ビジネスロジック Serviceにパスベースでルーティングします。 これらのコンテナー関連リソースを制御する K8s マスターが AWS マネージドとして作成/運用される Amazon EKS(以下EKS)で クラスタ ーを構成しています。 エンドユーザーはSPAを取得して、 REST API でバックエンドとリソースのやり取りをするというマイクロサービスにおける代表的な アーキテクチャ です。SPAはS3に格納し、CloudFrontにより HTTPS で配信します。ただし、オリジンはS3 バケット のみであり、バックエンド(ALB)は指定していません。 全体的に、(プライベートサブネットとCloudFrontの構成をサボっているところ以外は) AWS での典型的な アーキテクチャ だと思っています。ちなみに、フロントエンド・バックエンドのアプリケーションを開発したのは私ではありません。ありがとう、チームのみんな〜 コンテナー型マイクロサービスの可視化 PodのログはFluent Bitを利用すれば比較的簡単( Fargate ログ記録 参照)にCloudWatch Logsで収集可能となります。 Fluent Bitは一部のメトリクスもログストリームに含めることをサポートしています 1 。 そのため、CloudWatchでメトリクスフィルターを頑張って設定すれば、可視化もできそうです。 ただし、せっかく K8s 使用しているのですから、有用(というか人気)なエコシステムは活用したいですよね?!というのが本件のモチベーションとなります。 K8s およびエコシステムのバージョン EKS: Kubernetes 1.21、eks.3 Prometheus:14.11.1 Grafana:8.3 AMPのアドオン AMPユーザーガイドの Getting started に従って、前述のEKS クラスタ ーにPrometheusをアドオンします。ガイドと違いがある点や特にコメントしたい内容以外は単に作業内容を記述するのみにとどめて説明します。 AMP ワークスペース の作成 bash $ aws amp create-workspace --alias tech-research-workspace Prometheus 用の Namespace と ServieAccount 作成 ``` bash $ kubectl create namespace prometheus namespace/prometheus created $ kubectl create serviceaccount prometheus -n prometheus serviceaccount/prometheus created ``` サービスロールを作成して Service Account に関連付け Set up IAM roles for service accounts で案内されている スクリプト を作成して実行します。 ガイドの スクリプト では eksctl を利用しており、実際にEKSを構築や運用する際には有用な CLI ツールかと思いますが、 K8s の理解を深めるために kubectl で書き直しました。 と言っても、差分は以下のみなのですが。。。 ガイド内の スクリプト bash eksctl utils associate-iam-oidc-provider --cluster $CLUSTER_NAME --approve 私が書き直した スクリプト bash kubectl annotate serviceaccount -n ${SERVICE_ACCOUNT_NAMESPACE} ${SERVICE_ACCOUNT_NAMESPACE} \ eks.amazonaws.com/role-arn=${SERVICE_ACCOUNT_IAM_AMP_INGEST_ROLE_ARN} 実行します。 bash $ ./createIRSA-AMPIngest.sh arn:aws:iam::XXXXXXXXXXXX:role/amp-iamproxy-ingest-role serviceaccount/prometheus annotated EKSノードグループの作成 ここで、Prometheusの アーキテクチャ を確認すると、Prometeheus ServerのTSDBの保存先にストレージが要求されています。 ※下図は Prometeheus Overview - Architecture より抜粋したものです。 EKS クラスタ ーはデフォルトで Amazon EBSのStorage Classがデプロイ済みの環境となりますが、私が構築した クラスタ ーはFargateプロファイルのみを作成していたので、EBSをストレージとするPersistent Volumeを利用できません。 Amazon EFSのStorage Classを追加してFargate上で実行するか、EC2ノードでEBSを利用するか、なのですが本件では後者としました。 EC2ノードを利用する場合はEKS クラスタ ーにノードグループを追加します。ノードグループはマネージドノードグループとしました。 作成方法は AWS ユーザーガイドの ステップ 4 ノードを作成する の Managed nodes – Linux をご参照ください。 Prometheusのインストール Helm チャー トリポジ トリを追加 互換性があるということで、AMP用のHelm リポジトリ があるのではなく、コミュニティの リポジトリ を追加していますね。マネージドサービスでありながらコミュニティのアップデートを利用できるのは嬉しいですね! ``` bash $ helm repo add prometheus-community https://prometheus-community.github.io/helm-charts $ helm repo add kube-state-metrics https://kubernetes.github.io/kube-state-metrics $ helm repo list NAME URL prometheus-community https://prometheus-community.github.io/helm-charts kube-state-metrics https://kubernetes.github.io/kube-state-metrics $ helm repo update Hang tight while we grab the latest from your chart repositories... ...Successfully got an update from the "kube-state-metrics" chart repository ...Successfully got an update from the "prometheus-community" chart repository Update Complete. ⎈Happy Helming!⎈ ``` Helmチャートに渡すパラメーターファイルの作成 リモート書き込みエンドポイント( remoteWrite )は、AMPコンソールの ワークスペース の概要欄や、 aws amp describe-workspace --workspace-id <ワークスペースID> より確認可能です。 amp-ingest-values. yaml ```yml serviceAccounts: server: name: "amp-iamproxy-ingest-service-account" annotations: eks.amazonaws.com/role-arn: "arn: aws :iam::XXXXXXXXXXXX:role/amp-iamproxy-ingest-role" server: remoteWrite: - url: https://aps-workspaces.ap-northeast-1.amazonaws.com/workspaces/ws-XXXXXXXX-XXXXXXXXXXXXXXXX/api/v1/remote_write sigv4: region: ap-northeast-1 queue_config: max_samples_per_send: 1000 max_shards: 200 capacity: 2500 ``` Prometheus Serverのインストール ``` bash $ helm install tech-research-prometheus-chart prometheus-community/prometheus -n prometheus -f ./amp-ingest-values. yaml NAME: tech-research-prometheus-chart LAST DEPLOYED: Tue Dec 14 22:31:55 2021 NAMESPACE: prometheus STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: The Prometheus server can be accessed via port 80 on the following DNS name from within your cluster: tech-research-prometheus-chart-server.prometheus. svc .cluster.local (省略) ``` リソースの作成を確認 ``` bash $ kubectl get all -n prometheus NAME READY STATUS RESTARTS AGE pod/tech-research-prometheus-chart-alertmanager-646ff55c84-fmzfp 2/2 Running 0 2m19s pod/tech-research-prometheus-chart-kube-state-metrics-869b89746zhd5 1/1 Running 0 2m19s pod/tech-research-prometheus-chart-node-exporter-pft8p 1/1 Running 0 2m19s pod/tech-research-prometheus-chart-pushgateway-6cb64c488f-wrvdx 1/1 Running 0 2m19s pod/tech-research-prometheus-chart-server-76f7b57784-k8xj6 2/2 Running 0 2m19s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/tech-research-prometheus-chart-alertmanager ClusterIP 192.168.0.150 80/ TCP 2m19s service/tech-research-prometheus-chart-kube-state-metrics ClusterIP 192.168.0.47 8080/ TCP 2m19s service/tech-research-prometheus-chart-node-exporter ClusterIP None 9100/ TCP 2m19s service/tech-research-prometheus-chart-pushgateway ClusterIP 192.168.0.221 9091/ TCP 2m19s service/tech-research-prometheus-chart-server ClusterIP 192.168.0.244 80/ TCP 2m19s NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE daemonset.apps/tech-research-prometheus-chart-node-exporter 1 1 1 1 1 2m19s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/tech-research-prometheus-chart-alertmanager 1/1 1 1 2m20s deployment.apps/tech-research-prometheus-chart-kube-state-metrics 1/1 1 1 2m20s deployment.apps/tech-research-prometheus-chart-pushgateway 1/1 1 1 2m20s deployment.apps/tech-research-prometheus-chart-server 1/1 1 1 2m20s NAME DESIRED CURRENT READY AGE replicaset.apps/tech-research-prometheus-chart-alertmanager-646ff55c84 1 1 1 2m20s replicaset.apps/tech-research-prometheus-chart-kube-state-metrics-869b8974ff 1 1 1 2m20s replicaset.apps/tech-research-prometheus-chart-pushgateway-6cb64c488f 1 1 1 2m20s replicaset.apps/tech-research-prometheus-chart-server-76f7b57784 1 1 1 2m20s ``` AMG のアドオン こちらも AMG の Getting started に従って進めていきましょう! Grafana ワークスペース 作成 Create your first workspace に従って作成します。 Grafana ワークスペース ・コンソールには、SSOで認証を行いアクセスする必要があるのですが、本件ではSSOの方式に SAML を選択しました。 Amazon Grafana > Workspaces より ワークスペースを作成 を押下 名前と説明 ワークスペース 名 tech-research-grafana-workspace 認証アクセス Security Assertion Markup Language ( SAML ) アクセス許可タイプ サービスマネージド IAM アクセス許可アクセス設定 現在のアカウント データソース Amazon Managed Service for Prometheus ワークスペースを作成 を押下 ステータスが アクティブ となることを確認する ワークスペース の作成は一旦終了しますが、 SAML の設定を完了させるにあたり、 SAML IdPの構築が必要となります。 SAML IdPの構築 本件ではIDaaSである Okta を利用しました。 AWS にて動作確認済みのIdPは Connecting to your identity provider に一覧化されています。こちらに記載のないIdPは、Grafanaに必要な SAML アサーション 属性を マッピング できるかの検証が必要ですね。 Oktaコンソール > 管理者 より管理者ページにサインインする その際、多要素認証の設定を求められるので、Okta Verifyを利用しました。 Directory > Profile Editor と遷移 Users にてOkta用のプロファイルである User(default) を選択 Attributesの Add Attribute を押下 Add Attribute Display name Role Variable name Role Save を押下 Role 属性が追加されていること Directory > People と遷移 自分のアカウントを選択 Profile タブにてAttributesの Edit を押下 前述の手順で追加した Role 属性に ADMIN を設定 Save を押下 Applictions > Applications と遷移 Browse App Integration Catalog にて「 Amazon Managed Grafana」を Search して選択 アプリケーションの詳細画面にて Add を押下 General Settings デフォルトのままで Done を押下 Amazon Managed Grafana アプリケーションの Sing On タブに遷移 Settings において Edit を押下 Attributes (Optional) Attribute Statements (optional) Name:Role Value :user.Role Advanced Sign -on Settings Name Space:Grafana ワークスペース ID ※Grafana ワークスペース URLに含まれる ワークスペース IDを抜き出して設定します。 Region:ap-northeast-1 Save を押下 ユーザーの アサイ ン Amazon Managed Grafana アプリケーションの Assignments タブに遷移 Assign プルダウンメニューより Assign to People を選択 作成済みのアカウント(今回は私のOktaアカウント)を Assign Done を押下 AMG の SAML 設定 OktaをIdPとした SAML 認証に必要な設定を行います。 Amazon Grafana > Workspaces > 作成したワークスペース を選択 認証 タブの Security Assertion Markup Language (SAML) の セットアップを完了にする を押下 Security Assertion Markup Language ( SAML ) ステップ 2: メタデータ をインポートする インポート方法 URL メタデータ URL メタデータ URLは、Oktaアプリケーションの Sign On タブの Identity Provider metadata より確認可能です。 ステップ 3: アサーション 属性を マッピング する admin の アサーション 属性ロール アサーション 属性ロール:Role 管理者ロールの値:ADMIN ※Okta上で設定した属性と、アカウント(People)で入力した値を指定します。 追加設定 - オプション アサーション 属性名:displayName アサーション 属性 E メール:mail アサーション 属性のログイン:mail SAML設定を保存 を押下 Grafana ワークスペース の SAML 設定が 有効 となることを確認する Grafana workspace consoleにアクセスする SSOが設定できたかの動作確認も兼ねて、GrafaraのUI( ワークスペース ・コンソール)にアクセスします。 Amazon Grafana > Workspaces より作成した ワークスペース を選択し、 Grafana ワークスペース URL に表示されているリンクを開く Sign in with SAML を押下 Oktaと未認証状態の場合は、Oktaにサインインする Grafana ワークスペース ・コンソールが表示されることを確認する。 可視化 Grafana上でのメトリクスの可視化が行える状態になったので、実際に ダッシュ ボードを作成してみます。 AMPのデータソースを追加 Grafana ワークスペースコンソール> 左部メニューのAWSアイコン > AWS Data Sources を選択 AWS Data Sources Data sourcesタブ Service Amazon Managed Service for Prometheus Regions Asia Pacific (Tokyo) AMPの ワークスペース を選択して Add data source Provisioned data sourcesにAMPの ワークスペース が追加されていることを確認する。 ダッシュ ボードの追加 Grafana.com に公開されている ダッシュ ボードをインポートして、EKS クラスタ ーの可視化を行います。 Grafanaワークスペース・コンソール > Dashboards > Manage を選択 Import を押下 Kubernetes cluster monitoring (via Prometheus) の ダッシュ ボード ID をコピーして、 Import via grafana.com に入力し、 Load を押下 Options の Prometheus にて、AMP の ワークスペース を選択し、 Import を押下 無事、EKS クラスタ ーとPodのメトリクスを可視化することができました! CPU使用率 メモリ使用率 まとめと今後の展望 「やってみた」感想は以下のとおりです。 K8s はキャッチアップ中、PrometheusとGrafanaを触るのが初めての私でも、 クラスタ ーやPodのメトリクス収集と可視化を行うことができました。 Contributorの貢献、情報量の多さという OSS のメリットと、それを AWS がマネージドサービスとしてナレッジの集約・導入ハードルを下げて提供しているというメリットの両方を体感しました。 これはEKSにも当てはまると考えております。 今後の展望としては以下を検討しております。 各エコシステムの アーキテクチャ や仕様、制約の理解 ダッシュ ボードのカスタマイズやCloudWatchとの棲み分け整理 監視・可視化という運用機能ならなおさらFargateで実行したい 特に3点目は、調査できたら改めて記事にしたいと思っております! (実はFargateでトライして、苦戦したのでEC2で妥協したのはナイショ♡) おまけ: VSCode の Kubernetes 拡張機能 毎日 VSCode のお世話になっております。 VSCode を使い始める前の日々には戻れないです。 ご存じの方も多いかと思いますが、 VSCode には Microsoft 社製の Kubernetes 拡張機能 があります。 この 拡張機能 は YAML スキーマ で マニフェスト の入力補助を行う目的で導入していたのですが、左部パネルの K8s アイコンより、色々できることに気づきました。 K8s クラスタ ーやNamespaceの切り替え、各リソースの情報の取得もできます。 便利〜!という蛇足でした。 最後までご覧いただきありがとうございました。 この記事がお一人でも多く方の参考になる、または、弊社に少しでも興味も持った方がいらっしゃいましたら幸甚です。 それでは、良いお年を〜! 参考文献 AWS の公式ガイド Amazon Managed Service for Prometheus Amazon Managed Grafana AWS ワークショップ Monitoring using Amazon Managed for Prometheus / Grafana 執筆: 寺山 輝 (@terayama.akira) 、レビュー: @sato.taichi ( Shodo で執筆されました ) Fluent Bit - Metrics Tutorial https://docs.fluentbit.io/manual/pipeline/outputs/cloudwatch#metrics-tutorial ↩
アバター