TECH PLAY

NTTドコモビジネス

NTTドコモビジネス の技術ブログ

613

この記事では、内製でソフトウェアを開発するチームにジョインして間もないエンジニアが受託開発と内製開発の違いについて感じたことを紹介したいと思います。 目次 目次 はじめに これまでの経験 NeWork 開発チームにジョインきっかけ いいなと感じたこと 報告のための資料作成や調整作業がない 価値ある変更は積極的に受け入れていること 毎日リリースができること 当初の想定と違ったこと ドキュメント類の決定事項が分かりづらい 不具合やバグの優先順位が相対的に高くないときがあること 意外と打ち合わせが多いこと おわりに はじめに こんにちは、NeWork 開発チームの栄です。普段はオンラインワークスペースサービス NeWork の開発エンジニアをしています。NeWork の開発エンジニアを担当することになってから 1 ヶ月が経過しようとしています。 そこでこの記事では、私がこれまで経験してきた受託開発と現在 NeWork で経験している内製開発の違いについて感じたことを振り返りたいと思います。 これまでの経験 これまではウォーターフォールで受託開発をする部署でシステムエンジニアとして中小企業の DX 化を推進するためのプラットフォーム開発をメインの案件として携わっており、担当業務としては提案や要件定義などの上流工程やシステムテスト、リリースなどを担当しておりました。 幸い?なことに忙しく働かさせてもらい、担当業務だけでなく、新たな業務アプリケーションを導入するために全国のユーザーを訪問して勉強会を実施したり、アプリケーション導入後のさらなる改善を図るために実際の利用者のところまで訪問してインタビューをしたりと非常に多くの経験ができたと思います。 最終的にはメイン機能の開発やその他別案件でも小さな案件であれば 1 人でも業務を任せてもらえるようになり、やりがいを感じながら充実感を持って業務に取り組めておりました。 NeWork 開発チームにジョインきっかけ 業務に不満があったわけでは無いのですが、次第に次のようなことを思うようになりました。 自分自身が実際に手を動かして開発できるようになりたい ユーザーから得た反応をスピーディーに反映できるようになりたい 1 つめは担当案件では設計・コーディング・単体テストなどの工程は外部に委託をしており、実際に手を動かして開発をする工程になると進捗管理などのマネジメントがメインとなっておりました。しかし、自分が考えた要件や機能を実装できない、実装する方法がわからないことに危機感を感じるようになり、もっとエンジニアとして技術的に成長できる環境に身を置きたいと思うようになりました。 2 つめは受託開発の一次受けだったため基本的にはユーザー主導のスケジュールで進んでいくのですが、すべての工程で報告や確認や承認などが必要になります。(ユーザーからお仕事を頂いているので当然ですが。) そのため、どうしても開発スケジュールが長くなる傾向にありました。さらに、複数ベンダーが開発するプロジェクトだったため、1 つの機能を開発するにしても各社間で設計を合わせて、テストの実施も日程やテスト環境を調整するなども必要でしたので、よりスケジュール長くなってしまっていたと思います。 実際に利用者にインタビューをしてフィードバックを貰っても、それを解決するためには次のリリースまでの数ヶ月の期間が必要であり、すぐにユーザーに価値を提供できないもどかしさを感じておりました。 そんなとき、NTT グループには社員自らが自律的にキャリアを築き新たな挑戦ができるように各組織が必要とするポストに対して社員が手を上げて応募できる制度があることを知り、そこで NeWork 開発チーム が新たな開発エンジニアの募集をしていたため、自ら応募することで 現在は NeWork の開発チームにジョインしております。 いいなと感じたこと ここからは、NeWork の開発にジョインしていいなと感じたことを受託開発と内製開発の観点から述べていきたいと思います。 報告のための資料作成や調整作業がない 私が経験した受託開発ではユーザーと何かしらの契約を交わしており、ほとんどの場合で成果物を納品する義務があります。そのためか細かく進捗を管理しながら多くの成果物を作成するのですが、1 つ 1 つの報告ごとにパワーポイントで資料を作成しておりました。また、テスト結果報告のときはすべてのテストを 1 つずつスクリーンショットで撮ってエクセルに貼り付ける作業をしており、かなりの時間を要します。さらに、大規模開発にもなるとステークホルダーがどんどん増えていき、報告をするためにも社内・社外問わず多くの関係者との各種調整をする必要があり、報告するまでにも多くの時間を要しました。 それが NeWork の開発だとほとんどありません。実際に動くソフトウェアを見て進捗を判断してもらえるので新たに報告資料を作成する必要がなかったり、内製かつスクラムで開発をすることにより定期的にプランニングとレビューですべての関係者が揃うため、各種調整をすることなくすぐに関係者とコミュニケーションをとれます。 資料を作成することは少しでも相手に対してわかりやすく伝えるために重要ですが、その報告のために不必要な時間をかける必要がないため、より開発作業に対して集中できるようになっていると思います。 価値ある変更は積極的に受け入れていること IPA が公開している アジャイルソフトウェア開発宣言の読み解き方 にもあるように、開発者にとって一番大事なことは、「価値あるソフトウェアを素早く継続的に提供し、ユーザーに ビジネスゴール達成の観点で満足してもらうこと 」だと思います。 しかし、受託開発をしているときはどうしてもビジネスゴールの達成よりも QCD(品質・費用・納期)の達成を優先してしまうこともありました。納期を守るために開発後期の段階で仕様変更すること対しては消極的であることがあったのですが、それがユーザーのビジネスゴール達成に大きく貢献できているか?と問われるともっと他にやり方があったのではないかと今にしては思います。 一方で NeWork の開発ではユーザーのビジネスゴールの達成を最優先するために、改善に繋がる仕様変更は新たな価値を見つけられたとして、積極的に受けいれております。また、短い時間間隔で定期的にリリースをすることで、ユーザーからのフィードバックもすぐに適用でき、結果としてユーザーが本当に必要なものを作れているのではないかと思います。 毎日リリースができること 受託開発時は、本当にリリースをしていいのかをチェックするために品質報告会議やリリース判定会議があったり、リリースがあるたびにリハーサルを何度も行ったりなど、多くのプロセスをすべてクリアしてリリースの承認を得る必要がありました。品質を保つためには必要な工程だとは思いますが、やはりすべてのプロセスをクリアするには時間がかかるため、どうしてもリリースまで時間がかかってしまいます。 以下の記事にもあるように、NeWork では毎日リリースをできる体制が整っており、とても驚きました。 リリース頻度を毎週から毎日にしてみた 毎日リリースする機会があれば、ユーザーからのフィードバックもすぐに反映できます。また、毎日効率よくリリースするためにリリース作業が完全自動化されております。以前は深夜に起きて何時間もリリース作業をする必要があったため、この差は個人的にはかなり大きいです。 当初の想定と違ったこと これだけでは NeWork の業務はいいところだけ述べており、以前の業務は悪いところしかないようにみえるので、ここからは NeWork にジョインして当初の想定と違って驚いたことを述べたいと思います。 ドキュメント類の決定事項が分かりづらい ドキュメントが内部の開発者だけでしか見られないこともあり、ドキュメントそのものに対してレビューをすることはほぼありません。そのためか、議論の途中までしか文章化していないこともあって、あとで振り返ったときに決定事項がわかりづらいこともあります。また、開発者全員に開発スキルがあるためか、文字だけで仕様を決めていき絵や図を書かずに設計を進めていたため、後から関係者間で実装内容の認識が異なっており認識合わせに時間がかかったこともあります。 一方で受託開発では基本的に行うべきタスクを明確にしないと次の工程に進まないため、要件定義や設計で詳細に作りたいものを決めていきます。また、すべての関係者が技術に明るいわけではないため、理解しやすく認識齟齬が起きないように絵や図を書きながら議論をしていきます。そのため、タスクの割り振りや知識の共有などはしやすかったです。 そのため、受託開発での経験を活かし、記載内容をテンプレート化する、文字だけでなくホワイトボードツールなどで絵や図を書くなどして少しでもドキュメントがわかりやすくなるような工夫を導入していきたいと思います。 不具合やバグの優先順位が相対的に高くないときがあること 不具合やバグがあっても発生するケースが稀であったり、影響の小さいものであれば他のタスクより優先度が下がることもあることに驚きました。以前は金融業界だったこともあり、高い信頼性が求められたため、不具合やバグはすべて対応しておりました。 ソフトウェアごとに求められる品質は異なるため、どちらがいい悪いと決めるのは難しいかとは思いますが、そもそも不具合はあってはいけない、不具合を発見したら早急に修正するという環境にいた身としてはこの差にはかなりギャップを感じました。 意外と打ち合わせが多いこと これも悪いというわけではないのですが、NeWork の開発では日々のスケジュールとしては午前中の大半は定例会議などで過ごしており、週に 1 回はイベントデーとして 1 日打ち合わせだけの日もあります。自分が想定していた内製開発ではもっと打ち合わせ回数は少なく、開発に充てる時間が大半だと思っておりました。1 週間でのトータル打ち合わせの時間だけでいえば、受託開発のときと大きな差はないと思います。 しかし、打ち合わせの内容は結構異なるなと感じました。受託開発時は基本的には社外の方と打ち合わせをすることが多く、打ち合わせのために何回もレビューをして準備を整えてから臨んでいました。内容としても進捗管理や課題管理がメインとなり、長い計画のなかでいかに QCD を満たすかを目指すことが多かったです。 一方で NeWork では社内の方との打ち合わせがほとんとです。1 回の計画期間が 2 週間と短いため、計画と振り返りを短いスパンで繰り返すイメージが強いです。 おわりに この記事では、私自身が NeWork の開発にジョインして感じた受託開発と内製開発の違いについて紹介させていただきました。受託開発・内製開発と一口に言ってもさまざまな企業があり、開発現場が異なれば上で挙げた内容が当てはまるとは限りませんが、この記事が読者の皆さまのお役に立てば幸いです。 最後に、2024 年 3 月現在、NeWork では一緒に開発を進めてくれる仲間を募集しています。詳細は以下のリンクをご覧ください。皆さまのご応募を心からお待ちしています! hrmos.co
NeWork 開発チームでは開発時間の 20%を主体的にプロダクトの改善に当てています。この取り組みの導入の背景や 1 年間運用して見えてきた良かったことや課題などをご紹介します。 目次 目次 はじめに NeWork とは 開発チーム改善活動 背景 活動内容 導入して良かったことと課題 良かったこと スプリントに積んだバックログアイテムが基本的に消化できるようになった エンジニアのモチベーション向上 インタラクションの改善もプロトタイプを通して納得感を与えられる コードの品質が上がる 課題 新機能を作った場合に他チームとの連携が難しい 新機能が放置されがち コンフリクトが起きる おわりに はじめに こんにちは。NeWork 開発チームの 2 年目エンジニアの中里です。普段はアジャイル開発エンジニアとしてフロントエンド・バックエンドを問わず、機能開発や改善を行っています。 この記事では、NeWork 開発チームが開発時間の 20%を主体的にプロダクトの改善に当てている取り組みの導入の背景や、1 年間運用して見えてきた良かったことや課題などをご紹介します。 NeWork とは NeWork は、コロナ禍に誕生したオンラインワークスペースサービスです。ワークスペース上のルームにワンクリックで入室でき、チームメンバーと気軽に話し始められる体験が売りのプロダクトです。 NeWork は、話し始めるまでの手軽さや打ち合わせ前後のコミュニケーションのしやすさ、メンバーのプレゼンスがわかることによる孤独感の緩和やコラボレーションのしやすさなど、リモートワークの課題感を解決できる設計がされています。 私の NeWork との出会いは学生の頃、コロナ禍に突入してからしばらく後でした。研究室の活動もリモート前提になり、ゼミや打ち合わせの度に打ち合わせ用 URL を発行する手間に辟易としていたところでこのサービスを知りました。 リモートワークに必要なのはこれだ!と当時の私は感銘を受け、インターンシップに参加・入社し、今では作る側になるくらいには良いプロダクトだと思っています。 開発チーム改善活動 NeWork の開発チームでは、1 年ほど前からプロダクトのためになることであれば、開発時間の 20%を費やして良いというルールを設けています。 チーム内ではこの活動を開発チーム改善活動と呼んでいます。 背景 開発チーム改善活動ができた経緯について。 NeWork では 2 週間スプリントのスクラムを行っています。プロダクト(企画)チームが立てた計画に基づき優先度を決めて、スプリントプランニングで次の 2 週間で開発するバックログアイテムを決めています。 計画通りに順調に開発が進むこともあれば、工数見積もりのブレやたまに降ってくる開発以外の社内業務によって開発が遅れることもありました。プランニングで積んだアイテムをスプリント内で終わらせようとして技術的負債を残すこともありました。実際に過去のレトロスペクティブを見ると次のスプリントプランニングの直前まで開発していることもあったようです。 また、特にプロダクトチームの事業計画的におしりが決まっている開発では、後々のスプリントでリファクタリングをやらせてもらう約束をプロダクトチームと決めた上で、スピードを優先させることもありました。 しかし、技術的負債を解消するためのバックログアイテムの優先度は永遠に上がらない上、リファクタリング前提で進めた箇所もどのタイミングでリファクタリングをするのか、どのくらいの時間をかけて良いのかをプロダクトチームと合意を取ることが難しいこともありました。 (※もちろん開発をしていない人にとってはコードがクリーンであることよりもお客さんに新しい価値を提供することの方が大切に見えるのは自然で仕方ないと思います) 他にもエンジニアが自主的に動くための時間を取りづらい問題もありました。 例えば、エンジニアが改善したい点(リファクタリングやライブラリのアップデート、機能改善など)を見つけた場合は、バックログアイテムを作成して、そのアイテムの価値をプロダクトオーナーに理解してもらいスプリントに積んでもらう必要もありました。改善に着手するためのハードルが高く、着手までのリードタイムが大分長くなっていました。 以下は実際にレトロスペクティブで出た課題です。 これらの問題に課題意識を持っている人が多く、レトロスペクティブで議題に挙がりました。 NTT Com 技術顧問の吉羽さんも自身のブログの スクラムで開発チームが自由な取り組みをするには? というポストで、「スプリントのキャパシティを見直して、開発チームが持続可能なペースで働けるようにする」ことを推奨されていることも話題に挙がり、 NeWork チームでも 1 スプリントで一律 20%の時間を開発チームが自由に使って改善を行えるようになりました 🎉 活動内容 開発チームの課題意識から生まれた開発チーム改善活動では、具体的に以下を活動内容と定めています。 機能改善 新機能開発 リファクタリング 技術動向を調査 優先度の低いバックログアイテムを先取り 実際に課題意識があったようにリファクタリング、次点で機能改善や新機能開発をする人が多い印象です。 我々 NeWork チームは日々の業務でドッグフーディングを兼ねて NeWork を利用しています。毎日使っているからこそ、各々が使いづらく感じるところを改善しているようでした。 例えば、以下の機能は開発チーム改善活動で生まれた/実装中の機能です。 ピクチャ・イン・ピクチャ機能 (ベータ機能としてリリース済み) タイル表示スタイル選択機能 (ベータ機能としてリリース済み) タイル表示スタイル: オート カメラ映像や画面共有の映像を自動的にタイル表示する (全員が顔出しする会議などで便利です) タイル表示スタイル: フォーカス 選択したユーザを排他的にタイル表示する (小さい画面で複数の画面を見比べる際に便利です) タイル表示のレスポンシブ対応 (リリース済) 改善前: 事前に用意されたグリッドレイアウトに映像ストリームを順番に割当 改善後: ウィンドウサイズや映像ストリームをのサイズ考慮して各ストリームの面積の和が最大化されるレイアウトを動的に作成して割当 タイル表示中の映像をズームする機能 (リリース済) ルームメッセージへのカスタムリアクション (リリース済) メッセージのリッチテキスト対応 (実装中) メッセージでのメンション機能 (実装中) メッセージでのリンクのプレビュー機能 (実装中) 日頃から NeWork をご利用していただいている方には、馴染のある機能もあったかもしれません。エンジニアならではの視点での改善や新機能開発が上手く回っており、良い取り組みだと感じています。 ちなみに、上 3 つは私が開発しました。私は自分のアイデアを形にするのが好きで、よく使いにくいところを改善したり欲しいと思った機能を開発したりしていました。(楽しい!) 導入して良かったことと課題 良かったこと スプリントに積んだバックログアイテムが基本的に消化できるようになった スプリントプランニングの段階でベロシティの 80%をバックログに積み、余った時間を開発チーム改善活動に充てる運用をすることで、工数見積もりのブレを吸収し、スプリント内にバックログアイテムを消化できないことはほぼなくなりました。リリーススケジュールの見通しが良くなったといえます。 スプリント内にすべてのバックログアイテムを消化しようと急ぐことがなくなり、精神的余裕ができました。 エンジニアのモチベーション向上 リファクタリングやライブラリのアップデートなどをやりたいと思ったらそのスプリント内でできるため、リードタイムがありません。リードタイムがないので構想したものを忘れたり、熱意が覚めることもありません。 20%の時間は自分で裁量を持って好きな開発をできるため、シンプルにモチベーションが上がります。 インタラクションの改善もプロトタイプを通して納得感を与えられる 操作体験が絡む、インタラクションが重要になる改善をバックログアイテムにして計画的に取り組むことは難しいと考えています。プロダクトに使いづらさを感じていても、プロダクトの人がデザインや実装に詳しくないと改善できることに気付けないし、気づけても言語化もし辛いのでバックログにもし辛いからです。 それに対して、エンジニアが自由に使える時間の中で、作りながら体験を模索していけるので手触りの良いものが作りやすいです。 ステークホルダーにプロトタイプを触ってもらって、納得感を持ってもらった状態でリリースに踏み切れるのも大きいです。 コードの品質が上がる プロダクトバックログアイテムに取り掛かっているときに、気になる実装を見つけたときにすぐにリファクタリングできるのでコードの品質が保たれます。 課題 新機能を作った場合に他チームとの連携が難しい 基本的に、開発チーム改善活動で取り組む内容はスプリントプランニングを通さないので、他のチームの人はスプリントレビューで初めて新機能の内容を知ることになります。 計測やリリースノートなどはプロモーションチームが担当しているため、事前に相談したり、リリースを遅らせることもありました。 エンジニアがプロトタイプを作り、スプリントレビューに持っていき、リリースすることが決まってからデザイナが UI を作ることが多かったため、リリースまでのリードタイムがかかります。それを踏まえ、最近はレビュー前に事前にデザインしてもらうこともあります。 新機能が放置されがち 開発チーム改善内容で新機能を作ると、それに関わる人が少なくチーム内での影が薄くなりやすいです。とりあえずベータ機能としてリリースした場合に忘れ去られてることもあります。これは開発した人がアフターフォローをしっかりするべきなのかなと思います。私の開発したベータ機能も本格採用するか削除するかしないと… コンフリクトが起きる 自由な活動ができるといってもスプリント内の 20%の時間しか使えないので、開発が数スプリントに跨ることも多く、コンフリクトが起こることもしばしばあります。これは仕方ないですね。 おわりに NeWork 開発チームでは約 1 年間、開発時間の 20%をエンジニアが自由に使える時間、開発チーム改善活動を運用してきました。 チームの一エンジニアとしては、コードの品質向上やエンジニアのモチベーション向上、価値創造につながっており、非常に良い取り組みだと感じています。 実は、この活動を通してできた改善・新機能のうち、機能自体や内部のアルゴリズムなどで 3 件の特許出願を行っています。私も 2 件出願しています。現在審査中で特許として認められるかはまだわかりませんが、それなりに価値のあるアウトプットが自発的にできたこともこの仕組みのおかげだと思っています。 NeWork は 20 人までのフリープランは無料でお試しいただけます。もしご興味を持っていただけた方はぜひお試しください。 また、2024 年 3 月現在、NeWork では一緒に開発を進めてくれる仲間を募集しています。詳細は以下のリンクをご覧ください。皆さまのご応募を心よりお待ちしています! hrmos.co
サマリ 概要 Inter-AS Option B における (b) の実現方法 (1) ASBR で next-hop ごとの VPN ラベルを生成する方法 (2) ASBR で Egress Peer に対する EPE ラベルを生成し、 VPN ラベルは対向 AS の ASBR が生成したものを利用する方法 検証 (1) の検証 1. ルートポリシーの設定 2. VPN ラベルの確認 3. traceroute による VPN の通信経路確認 (2) の検証 1. EPE ラベルを生成する設定 2. BGP-LU の設定 3. ルートポリシーの設定 4. PE での EPE ラベル確認 5. traceroute による VPN の通信経路確認 まとめ サマリ Multi-AS の SR-MPLS + VPNv4 環境で AS 間での TE を実現するため、ASBR 間 next-hop を PE で選択する方法を検証 next-hop ごとに VPN ラベルを生成する Nokia ASBR と、 BGP-LU で ASBR 間 next-hop をそのまま広告する Cisco ASBR の 2 通りで動作確認に成功 この記事は Multi-AS Segment Routing 検証連載の第 20 回です。 過去の記事一覧は こちら にあります。 概要 イノベーションセンターの吉田 晴信です。 業務では Multi-AS Segment Routing に関する技術検証をしています。 本記事では、Multi-AS での Segment Routing を活用した Traffic Engineering(SR-TE)の実現方法について紹介します。 Multi-AS での SR-TE で実現したい要求として、 第 5 回の記事 では下記の 2 点を挙げています。 (a) AS 内で意図した経路を選択したい(AS 内での TE) (b) 他 AS との接続経路を選択したい(AS 間での TE) (a) の実現方法については 第 5 回の記事 で説明しています。本記事では (b) の実現方法を説明します。 Inter-AS Option B における (b) の実現方法 本記事では MPLS Inter-AS Option B を前提に SR-MPLS + VPNv4 で (b) を実施する方法を紹介し動作検証を行います。 はじめに、Option B で (b) を実施する際の課題を説明します。 (b) を実施する場合、下記の 3 種のラベルが必要です。 ASBR に到達するまでのラベル ASBR から先を示すラベル VPN を識別するラベル ラベルの処理としては、「 ASBR に到達するまでのラベル」は ASBR 到達までに Pop されますが、 「 ASBR から先を示すラベル」と「 VPN を識別するラベル」は Pop されません。 「 ASBR から先を示すラベル」は ASBR で next-hop を選択する際に Pop され、 「 VPN を識別するラベル」は ASBR 間 で VPN を識別するのに必要であるため Swap されます。 つまり、ASBR では Pop と Swap の 2 つの処理を同時に行う必要があります。 ですが、現状 Cisco/Juniper/Nokia 機器では「 ASBR から先を示すラベル」と「 VPN を識別するラベル」を同時に ASBR で処理する機能がありません。 つまり、(b) を 1 つの ASBR につき 1 ラベルのみ処理する方法で実現する必要があります。 実現方法として、本記事では下記の 2 点を紹介します。 (1) ASBR で next-hop ごとの VPN ラベルを生成する方法 (2) ASBR で Egress Peer に対する EPE ラベルを生成し、 VPN ラベルは対向 AS の ASBR が生成したものを利用する方法 (1) ASBR で next-hop ごとの VPN ラベルを生成する方法 1 点目の方法では、next-hop ごとに受信した NLRI 単位で経路に異なる VPN ラベルを生成します。 これにより、VPN ラベルは ASBR 間 next-hop に対応します。 そして経路を PE に広告することで、PE で ASBR 間 next-hop を選択できます。 この方法は Nokia ASBR で使用できることを確認しています。 (2) ASBR で Egress Peer に対する EPE ラベルを生成し、 VPN ラベルは対向 AS の ASBR が生成したものを利用する方法 2 点目の方法では、自 AS の ASBR で Egress Peer に対応する EPE ラベルを生成します。 EPE ラベルを生成した経路は RFC3107 で標準化されている BGP-LU を使用し PE に広告します。 VPN 経路は対向 AS の ASBR から Inter-AS の VPN ラベルがついた状態で自 AS の ASBR で受信されます。 自 AS の ASBR から PE にこの経路を広告しますが、このとき経路の next-hop-self を使用せずそのまま広告します。 PE は 対向 AS の ASBR のアドレスを EPE ラベルがついた状態で学習できているため、 next-hop を書き換えない状態でも経路の解決が可能です。 以上により、PE で対向 AS の ASBR を選択でき、自 AS の ASBR では EPE ラベルを処理するだけなので転送可能となり、 VPN ラベルも 対向 AS の ASBR で解釈可能なため問題なく通信できます。 この方法は Cisco ASBR で使用できることを確認しています。 検証 本記事では (1) と (2) の方法で PE において ASBR 間 next-hop を選択できることを確認します。 前提である Multi-AS の SR-MPLS + VPNv4 の設定は  第 12 回の記事 をご参照ください。 また、(1) と (2) 両方で経路選択するため、ルートポリシーを用いて weight/LP を変更する方法を採用しています。 (1) の検証 (1) は下記のトポロジーで検証します。 使用した各ルーターのバージョンは下記の通りです。 1-PE01: IOS XR 7.9.2 1-PE02、1-ASBR02、1-ASBR03、1-PE04: Junos OS 22.3R1.11 1-PE03、1-ASBR01: SR OS 22.7.R1 検証の手順は下記の通りです。 ルートポリシーの設定 VPN ラベルの確認 traceroute による VPN の通信経路確認 1. ルートポリシーの設定 1-ASBR01 から受信した経路を選択するため、各 PE でルートポリシーを設定します。 今回設定するルートポリシーは下記の 2 つです。 BGP で vrf-100 に対して、次に経由する AS が 65002 の経路を広告されたとき、その経路の weight を 10000 にする。 BGP で vrf-200 に対して、次に経由する AS が 65003 の経路を広告されたとき、その経路の weight を 10000 にする。 これにより、vrf-100 の通信では AS65002 に直接転送する経路が選択され、 vrf-200 の通信では AS65003 を経由して AS65002 に転送する経路が選択されます。 トラフィックの流れは下記の通りです。 1-PE01 におけるルートポリシーの設定例です。 as-path-set as-65002 neighbor-is '65002' end-set ! as-path-set as-65003 neighbor-is '65003' end-set ! route-policy asbr-selection-based-rd if rd in rds-select-65002 and as-path in as-65002 then set weight 10000 endif if rd in rds-select-65002 and as-path in as-65003 then set weight 1000 endif if rd in rds-select-65003 and as-path in as-65003 then set weight 10000 endif if rd in rds-select-65003 and as-path in as-65002 then set weight 1000 endif pass end-policy ! また、ASBR が広告した経路にルートポリシーを適用するため、下記を設定します。 router bgp 65001 neighbor-group ibgp address-family vpnv4 unicast route-policy asbr-selection-based-rd in ! ! ! 本記事では紹介していませんが、1-PE02 と 1-PE03 についても同じ内容を設定します。 なお、この節で紹介した設定は経路選択するためのものであり、(1) 実現のために第 12 回の記事から追加設定はありません。 2. VPN ラベルの確認 1-ASBR01 で生成された VPN ラベルを確認します。 下記の通り ASBR 間 next-hop ごとに異なる VPN ラベルが生成されていることがわかります。 [/] A:user@1-ASBR01# /show router bgp inter-as-label =============================================================================== BGP Inter-AS labels Flags: B - entry has backup, P - entry is promoted =============================================================================== NextHop Received Advertised Label Label Label Origin ------------------------------------------------------------------------------- 10.100.1.2 36 524280 External 10.100.1.2 37 524279 External 10.100.2.2 22 524278 External 10.100.2.2 23 524277 External 10.255.1.1 24002 524284 Internal 10.255.1.1 24003 524283 Internal 10.255.1.2 16 524274 Internal 10.255.1.2 17 524273 Internal 10.255.1.3 524284 524276 Internal 10.255.1.3 524286 524275 Internal ------------------------------------------------------------------------------- Total Labels allocated: 10 =============================================================================== 1-PE01 に上記で生成された VPN ラベルが広告されているか確認します。 下記は 1-PE01 における vrf-100 の経路ですが、1-ASBR01 で確認した VPN ラベルが広告されていることがわかります。 RP/0/RP0/CPU0:1-PE01#show bgp vpnv4 unicast rd 65002:100 labels (snip) Status codes: s suppressed, d damped, h history, * valid, > best i - internal, r RIB-failure, S stale, N Nexthop-discard Origin codes: i - IGP, e - EGP, ? - incomplete Network Next Hop Rcvd Label Local Label Route Distinguisher: 65002:100 Route Distinguisher Version: 525 *>i192.168.4.0/24 10.255.1.4 524280 nolabel * i 10.255.1.4 524278 nolabel Processed 1 prefixes, 2 paths vrf-200 も同じです。 RP/0/RP0/CPU0:1-PE01#show bgp vpnv4 unicast rd 65002:200 labels (snip) Status codes: s suppressed, d damped, h history, * valid, > best i - internal, r RIB-failure, S stale, N Nexthop-discard Origin codes: i - IGP, e - EGP, ? - incomplete Network Next Hop Rcvd Label Local Label Route Distinguisher: 65002:200 Route Distinguisher Version: 524 * i192.168.14.0/24 10.255.1.4 524279 nolabel *>i 10.255.1.4 524277 nolabel Processed 1 prefixes, 2 paths 1-PE02 と 1-PE03 の vrf-100 と vrf-200 でも同様の経路が確認できます。 3. traceroute による VPN の通信経路確認 PE から ASBR 間 next-hop が選択できているか確認するため、 traceroute コマンドを実行します。 1-PE01 vrf-100 -> 1-PE04 vrf-100 1-PE01 の vrf-100 から 1-PE04 の vrf-100 に対して traceroute を実行します。 結果、AS65002 へ直接転送されました。 また、1-PE02 と 1-PE03 の vrf-100 でも同様の結果となりました。 RP/0/RP0/CPU0:1-PE01#traceroute 192.168.4.254 vrf 100 Fri Jan 26 10:19:06.080 JST Type escape sequence to abort. Tracing the route to 192.168.4.254 1 10.100.1.1 [MPLS: Labels 16004/524280 Exp 0] 4 msec 3 msec 3 msec 2 10.100.1.2 [MPLS: Label 36 Exp 0] 3 msec 3 msec 3 msec 3 192.168.4.254 3 msec 3 msec 4 msec 1-PE01 vrf-200 -> 1-PE04 vrf-200 1-PE01 の vrf-200 から 1-PE04 の vrf-200 に対して traceroute を実行します。 結果、AS65003 を経由し AS65002 へ転送されました。 また、1-PE02 と 1-PE03 の vrf-200 でも同様の結果となりました。 RP/0/RP0/CPU0:1-PE01#traceroute 192.168.14.254 vrf 200 Fri Jan 26 10:19:10.027 JST Type escape sequence to abort. Tracing the route to 192.168.14.254 1 10.100.2.1 [MPLS: Labels 16004/524277 Exp 0] 3 msec 2 msec 2 msec 2 * * * 3 10.100.3.1 [MPLS: Label 37 Exp 0] 4 msec 3 msec 4 msec 4 192.168.14.254 4 msec 3 msec 3 msec (2) の検証 (2) は下記のトポロジーで検証します。 なお (1) と検証時期が異なるため、環境が少し違います。 各ルーターのバージョンは下記の通りです。 2-PE01、2-ASBR01、2-ASBR02、2-ASBR03、2-PE04: IOS XR 7.9.2 2-PE02: SR OS 23.3.R3 2-PE03: Junos OS 22.3R1.11 検証の手順は下記の通りです。 EPE ラベルを生成する設定 BGP-LU の設定 ルートポリシーの設定 PE での EPE ラベル確認 traceroute による VPN の通信経路確認 1. EPE ラベルを生成する設定 Egress Peer に対して EPE ラベルを生成するため、2-ASBR01 に下記を設定します。 router bgp 65001 neighbor 10.100.1.2 egress-engineering peer-node-sid index 100 ! neighbor 10.100.2.2 egress-engineering peer-node-sid index 200 ! ! mpls static interface GigabitEthernet0/0/0/2 ! interface GigabitEthernet0/0/0/3 ! ! 生成された EPE ラベルは下記のコマンドで確認できます。 RP/0/RP0/CPU0:2-ASBR01#show bgp egress-engineering Mon Dec 4 19:46:30.145 JST Egress Engineering Object: 10.100.1.2/32 (0x7f38b4250e28) EPE Type: Peer Nexthop: 10.100.1.2 Version: 30, rn_version: 30 Flags: 0x00000026 Local ASN: 65001 Remote ASN: 65002 Local RID: 10.255.1.3 Remote RID: 10.255.1.3 Local Address: 10.100.1.1 First Hop: 10.100.1.2 NHID: 2 IFH: 0x1000028 Label: 15100, Refcount: 4 rpc_set: 0x7f3858002300, ID: 14 Egress Engineering Object: 10.100.2.2/32 (0x7f38b4250f20) EPE Type: Peer Nexthop: 10.100.2.2 Version: 31, rn_version: 31 Flags: 0x00000026 Local ASN: 65001 Remote ASN: 65003 Local RID: 10.255.1.3 Remote RID: 10.255.1.1 Local Address: 10.100.2.1 First Hop: 10.100.2.2 NHID: 3 IFH: 0x1000020 Label: 15200, Refcount: 4 rpc_set: 0x7f3858002570, ID: 15 2. BGP-LU の設定 生成した EPE ラベルを PE に広告するため、2-ASBR01 で BGP-LU を設定します。 router bgp 65001 address-family ipv4 unicast advertise epe-bgp labeled-unicast allocate-label all ! neighbor 10.255.1.1 use neighbor-group ibgp address-family ipv4 labeled-unicast ! neighbor 10.255.1.2 use neighbor-group ibgp address-family ipv4 labeled-unicast ! neighbor 10.255.1.4 use neighbor-group ibgp address-family ipv4 labeled-unicast 下記は 2-PE01 における BGP-LU の設定です。 本記事では紹介していませんが、2-PE02 と 2-PE03 についても同じ内容を設定します。 router bgp 65001 address-family ipv4 unicast allocate-label all ! neighbor 10.255.1.3 use neighbor-group ibgp address-family ipv4 labeled-unicast 3. ルートポリシーの設定 経路を選択するため、ルートポリシーを設定します。 設定は (1) と同じなので省略します。 トラフィックの流れは下記の通りです。 4. PE での EPE ラベル確認 2-ASBR01 で生成された EPE ラベルが BGP-LU で PE に広告されているか確認します。 2-PE01 で下記のコマンドを実行すると、 2-ASBR01 から EPE ラベルが広告されていることがわかります。 RP/0/RP0/CPU0:2-PE01#show bgp ipv4 labeled-unicast 10.100.1.2/32 Mon Dec 4 20:08:01.877 JST BGP routing table entry for 10.100.1.2/32 Versions: Process bRIB/RIB SendTblVer Speaker 3 3 Last Modified: Dec 4 19:57:00.035 for 00:11:01 Paths: (1 available, best #1) Not advertised to any peer Path #1: Received by speaker 0 Not advertised to any peer Local 10.255.1.3 (metric 20) from 10.255.1.3 (10.255.1.3) Received Label 15100 Origin IGP, localpref 100, valid, internal, best, group-best, labeled-unicast Received Path ID 0, Local Path ID 1, version 3 RP/0/RP0/CPU0:2-PE01#show bgp ipv4 labeled-unicast 10.100.2.2/32 Mon Dec 4 20:07:41.067 JST BGP routing table entry for 10.100.2.2/32 Versions: Process bRIB/RIB SendTblVer Speaker 2 2 Last Modified: Dec 4 19:57:00.035 for 00:10:41 Paths: (1 available, best #1) Not advertised to any peer Path #1: Received by speaker 0 Not advertised to any peer Local 10.255.1.3 (metric 20) from 10.255.1.3 (10.255.1.3) Received Label 15200 Origin IGP, localpref 100, valid, internal, best, group-best, labeled-unicast Received Path ID 0, Local Path ID 1, version 2 また、vrf-100 と vrf-200 の経路を確認すると、 VPN ラベルを付与する経路の次に、EPE ラベルを付与する経路が選択されることを確認できます。 RP/0/RP0/CPU0:2-PE01#show route vrf 100 (snip) C 192.168.1.0/24 is directly connected, 13w5d, GigabitEthernet0/0/0/1 L 192.168.1.254/32 is directly connected, 13w5d, GigabitEthernet0/0/0/1 B 192.168.2.0/24 [200/0] via 10.255.1.2 (nexthop in vrf default), 1d01h B 192.168.2.254/32 [200/0] via 10.255.1.2 (nexthop in vrf default), 1d01h B 192.168.3.0/24 [200/0] via 10.100.1.2 (nexthop in vrf default), 03:25:39 (snip) RP/0/RP0/CPU0:2-PE01#show route vrf 200 (snip) C 192.168.11.0/24 is directly connected, 13w4d, GigabitEthernet0/0/0/2 L 192.168.11.254/32 is directly connected, 13w4d, GigabitEthernet0/0/0/2 B 192.168.12.0/24 [200/0] via 10.255.1.2 (nexthop in vrf default), 00:01:45 B 192.168.12.254/32 [200/0] via 10.255.1.2 (nexthop in vrf default), 00:01:45 B 192.168.13.0/24 [200/0] via 10.100.2.2 (nexthop in vrf default), 00:03:15 (snip) 2-PE02 と 2-PE03 でも同じ情報が広告されています。 5. traceroute による VPN の通信経路確認 PE から ASBR 間 next-hop が選択できているか確認するため、traceroute コマンドを実行します。 2-PE01 vrf-100 -> 2-PE04 vrf-100 2-PE01 の vrf-100 から 2-PE04 の vrf-100 に対して traceroute を実行します。 結果、AS65002 へ直接転送されました。 また、2-PE02 と 2-PE03 の vrf-100 でも同様の結果となりました。 RP/0/RP0/CPU0:2-PE01#traceroute 192.168.3.254 vrf 100 Tue Dec 5 21:31:08.445 JST Type escape sequence to abort. Tracing the route to 192.168.3.254 1 10.1.1.2 [MPLS: Labels 15100/24007 Exp 0] 3 msec 2 msec 2 msec 2 10.100.1.2 [MPLS: Label 24007 Exp 0] 3 msec 2 msec 2 msec 3 10.1.1.1 4 msec * 4 msec 2-PE01 vrf-200 -> 2-PE04 vrf-200 2-PE01 の vrf-200 から 2-PE04 の vrf-200 に対して traceroute を実行します。 結果、AS65003 を経由し AS65002 へ転送されました。 また、2-PE02 と 2-PE03 の vrf-200 でも同様の結果となりました。 RP/0/RP0/CPU0:2-PE01#traceroute 192.168.13.254 vrf 200 Tue Dec 5 21:31:26.660 JST Type escape sequence to abort. Tracing the route to 192.168.13.254 1 10.1.1.2 [MPLS: Labels 15200/32004 Exp 0] 3 msec 2 msec 2 msec 2 10.100.2.2 [MPLS: Label 32004 Exp 0] 3 msec 3 msec 2 msec 3 10.100.3.1 [MPLS: Label 24009 Exp 0] 2 msec 2 msec 2 msec 4 10.1.1.1 4 msec * 4 msec まとめ 本記事では、Multi-AS の SR-MPLS + VPNv4 環境で AS 間での TE を実現するため、 ASBR 間 next-hop を PE で選択する方法と検証結果を紹介しました。 (1) の方法では、ASBR 間 next-hop ごとに受信した NLRI 単位で経路に異なる VPN ラベルを生成し、PE に広告できました。 こちらは Nokia ASBR を使用し確認しました。 (2) の方法では、まず自 AS の ASBR で Egress Peer に対応する EPE ラベルを生成し、BGP-LU で PE に広告しました。 また、対向 AS の ASBR から広告される VPN ラベルを付与する経路の next-hop を書き換えずに PE へ広告しました。 結果、PE で対向 AS の ASBR を選択できるようになり、自 AS の ASBR では EPE ラベルを処理するだけでよくなりました。 こちらは Cisco ASBR を使用し確認しました。 以上の方法に加えて、Cisco/Juniper/Nokia PE でルートポリシーを設定し、 選択したい VPN 経路の weight を大きくすることにより、PE から次に経由する AS を選択できました。
はじめに はじめまして。クラウド&ネットワークサービス部 データプラットフォームビジネス推進部門で IoT Connect Mobile Type S (以下 ICMS)の販売推進を担当している、櫻井幸大です。普段はICMS/モバイル回線の開発~運用を担当しているのですが、今回はOJT(別部署で勤務をする社内研修)のためICMSの販売推進として記事執筆をすることとなりました。 今回は、 ICMSを使い販売推進担当で遠くからカメラを動かすシステムを作ってみました ので(機器を他社から購入し、ICMSと組み合わせて自分たちでプログラムを作りました)、その様子をお伝えします。 ICMSとは? ICMSとは、NTT Comが提供するIoTデバイス向けのSIMカード/通信回線です。SIMカードと通信回線を管理するためのポータルもセットで提供しています。お客さまの用途に合わせて柔軟に 料金プラン や 接続方式 を選択できることが、ICMSの特長です。 さまざまな料金プラン 選べる3つの接続方式 ICMSで何ができるの? ICMSを使えば、IoTデバイスをセキュアにクラウドへと接続できます。IoTデバイスが測定&収集したデータを遠隔地にあるサーバーやデータセンターにアップロードする、ということですね。またICMSでは、IoTデバイスから送られた非暗号化データを暗号化したり、インターネットを通らずに閉域網へとつなぐ接続方式が選択可能で、お客さま通信の安全性・秘匿性を高めることができます。 例えば、山奥のダムや河川の水位を監視する場合を考えてみましょう。遠く離れた山奥まで毎日毎日様子を見に行くのは大変で、稼働的にも無駄が大きいです。大規模災害時に瞬時に様子を確認しづらい、という問題点も考えられます。 ICMSとIoTカメラ機器を使えば、誰でも手軽に遠くの場所を確認できます。 そこで今回の記事では、会社に置いてある私たち販売推進担当のロッカーを離れた場所から確認してみたいと思います。 準備したもの 使用した機材はこちらになります。 1. ICMS 先ほどご紹介をした、当社のIoT向け SIMカード/通信回線です。 2.IoT Connect Gateway(ICGW) IoT Connect Gateway (以下 ICGW)は、ICMS(SIMカード)の刺さったデバイスがデータを簡単に・セキュアにアップロードするためのIoT向けのゲートウェイです。ICGWはICMSとセットで利用しやすいよう設計されており、簡単な設定だけでIoTデバイスICGW経由でクラウドめがけてデータを転送してくれるようになります。 ICGWを経由してクラウドに接続することには、以下の2つのメリットがあります。 本来はデバイス側で実施する暗号化の処理を、ICGW上で実施できる クラウド接続のための認証情報を、デバイスの代わりにICGWで管理できる ICGWを活用することで、IoTデバイスの設定の手間や処理の負荷を軽減できるのです。 ICGWはAWS、Azureなどさまざまなクラウドとの接続に対応していますが、今回はWasabiオブジェクトストレージとの接続機能 =「ストレージ機能」を活用してみます。 3.Wasabiオブジェクトストレージ Wasabiオブジェクトストレージ (以下 Wasabi)はNTT Comが提供するAWS S3互換APIを提供する業界最安値水準のパブリッククラウド型オブジェクトストレージサービスです。データの書き込み・読み込みが速くでき、かつ、低価格で大容量データを保存できることが特長です。 4.KC4-C-100A(KC4) KC4-C-100A (以下 KC4)はセンサー・GNSS・ビーコン・Webカメラをクラウドへとつなぐ際の中継となる、京セラ社製(以下 京セラ)のデバイスです。 多様なインターフェイスを備えているため、さまざまな測定機器との接続が可能です。また、難しいプログラミングをせずとも機器の制御ができることも特長のひとつです。(プログラミングのサンプルレシピが 京セラのWebサイト に多数公開されているので、簡単に設定可能です。) 5.USBカメラ 今回の構成では、普段Web会議で使用しているUSBカメラをそのまま使用しました。(KC4で動作確認済みのUSBカメラの一覧は、 メーカーのサイト をご覧ください。) 以上すべての機器をまとめたシステム構成が、下の画像のようになっています。IoTデバイスがICMS(モバイル回線)を通してICGWへと画像データを送り、ICGWがWasabiにデータを転送することで、ストレージに記録がどんどん蓄積されていく、ということですね。 構築手順 次に、上で紹介した5つの道具をもとに、どうすればロッカーの遠隔様子見システムが構築できるのかを説明します。 ICMS SIMにICGW利用申し込みをする ICGWに接続するSIMカードは事前に申し込みを実施する必要があります。ICMS, ICGWをはじめとしたNTT Comのサービスは、お客さまへ提供しているSmart Data Platform(以下 SDPF)ポータルのサイトから一括管理ができますので、そちらを通して申し込みをしていきましょう。 SDPFポータルに移動をして、ご契約中のワークスペースを選択。 「メニュー」のタブからIoT Connect Mobile Type Sを選択。 すると、SIMカードの利用状況一覧を表すサイトに移動します。 ここではSIMカードをグループごとにまとめて管理でき、例えば利用拠点や用途ごとに契約中のSIMカードを分類できます。便利ですね。 今回開通しようとしているSIMカードがあるグループのところに移動します。 HSN(シリアルナンバー)がSIMカードに印字されているものと合っていることを確認して、「ICGW利用」のタブを選択。 「NTTCの計1プロファイルに対しICGW利用申込しようとしています」のチェックボックスにチェックを入れ、確定ボタンを押下。これにてICGWの利用設定が完了です。 SIMカード(ICMS)の開通 ICMSはSIMカードが未開通(通信ができない)状態でお手元に届きます。 私たちが今回使ったSIMカードもお客さまに届く際と同様に未開通状態だったので、開通の処理を行います。 先ほどの、開通したいSIMカードが表示されるSIMグループのところに移動します。シリアルナンバーが正しいことを確認して、上の「開通」のボタンをポチリ。 すると接続プラン・通信量の上限・ICGWの利用有無を確認するサイトに移動します。 ご希望のプランを選択し(今回は従量・無制限・ICGW接続を選択)、「入力内容を確認する」を押します。これでSIMカード側の設定は完了です。 Wasabiオブジェクトストレージの設定 次にデータの蓄積をするWasabi(ストレージサーバー)側の設定をしていきます。 Wasabiには送られてくるデータを格納する場所である「バケット」と送り主が本当に正しい人なのかを判断するための「認証キー」を設定する必要があります。 まずはWasabi Console(管理画面)へと移動し、メニューバーから「バケット」の部分をクリックします。 右上の「バケットを作成」のボタンを押すとバケットの名前を入力するタブが開きます。適切なバケット名(英数小文字で入力)・地域(Tokyo ap-northeast-1 または Osaka ap-northeast-2のうち近い方を選択)を選択し、「バケットを作成」を押します。 これでバケットが作成できました。 バケットの中にフォルダーを作成することで、データによって格納先を変えることが可能です。データをどのフォルダーに格納するのかはICGWで一括管理できるので、いちいちIoTデバイスのプログラミングを変更する必要はありません。 今回はロッカーの写真をまとめて撮影したいので「31F_Locker」のフォルダーをバケットの中に作成します。 バケットの設定が終わったら、最後にアクセスキーの設定です。Wasabiへのアクセス時、アクセスキーと秘密鍵で認証することで、第三者からの不正アクセスを防ぎます。 まずは左のメニューバーから「アクセスキー」をクリックし、右上の「アクセスキーを作成する」のボタンからアクセスキーを発行します。 このアクセスキー・秘密鍵をICGWに設定すれば、鍵認証の仕組みが完了です。(秘密鍵は認証のための鍵ですので、大切に保管してください。) ICGWストレージ機能の設定 1. 「認証」の新規作成 Wasabiに接続するための認証情報をICGWに登録します。 まずはICGWポータルの左側のメニューの「認証」をクリックします。証明書種別は、「AWS認証」を選択し、先ほど保存しておいたWasabiに接続するためのアクセスキーID、シークレットアクセスキー(秘密鍵)を入力し、「作成」をクリックします。 ICGWを利用しない場合、アクセスキーなどの認証情報はデバイスに設定する必要があります。10台デバイスがあると10回設定作業をしなければなりません。ICGWを使えば、接続先が同じであれば複数のデバイス分まとめて登録作業が可能です。 2. SIMグループ新規作成 ICGWを利用する場合、接続先が同じSIMカードはグループ化したうえで接続情報を管理できます。 今回は「ux20240115」というグループを作成し、利用するSIMカードをそのグループの中に追加したいと思います。メニューの中の「グループ」を選択し、「グループ名」を入力し、「SIM設定」にて新規グループに入れたいSIMカードを選択し、「作成」をクリックします。 今回利用するSIMカードの情報を見てみると、先ほど新しく作成したグループに所属できていることが確認できました。 3. グループのデータ転送設定 2.で新規作成したSIMのグループからどのようにデータを転送するかの詳細設定をしていきます。ますは、メニューから「グループ」を選択し、先ほど作成した「ux20240115」というグループを選択します。 グループの中に入ったら、今回利用する「ストレージ」のタブを選択。右側の「新規作成」をクリックし、 必要な項目を入力していきます。 必要な項目が多く、少し複雑に感じるかもしれませんが、 「エントリーポイント」= デバイスからICGWに接続するための情報 「宛先設定」= ICGWからWasabiの特定のフォルダーに接続するための情報 という風に分けて考えると分かりやすいと思います。 これでICGWの設定は完了です! デバイスの設定 1. デバイス設定の下準備 KC4の設定は、設定用PCから実施します。まずは、設定用PCに対して、デバイス設定のために必要なアプリケーションをインストールしておきましょう。詳細については、 メーカーのサイト をご参照ください。 2. SIMカードの差し込み、ケーブル結線 KC4にICMS(nano SIMサイズ)を挿入して、KC4と設定用PC、Webカメラ、電源を接続し、電源をONにします。 3. APN(Access Point Name)、ID/Passの設定 ICMSとICGWを利用する際に必要となるAPNとID/Passを設定します。設定用PC上でKC4設定用アプリケーションを立ち上げ、「設定値読込/書込み」をクリックします。 「設定項目」の中の「APN」を選択し、 SDPF ナレッジセンター に掲載されているICMS、ICGW利用時のAPN、ID/Pass情報を入力します。 入力ができたら、「書込み」をクリックします。そうすると、設定が反映された状態でデバイスが再起動されます。 起動後、デバイスのモニター上に「Hello!」と表示されていれば完了です。 4. デバイスの振る舞いを定義するプログラム作成 続いて、KC4の振る舞いを定義するプログラムを作成します。KC4のプログラムの作成方法には以下の3つがあります。 「ノーコード」:Webサイトに掲載されているレシピ(すでに作成されているプログラムデータ)を活用する方法 「ローコード」:画面操作でプログラミングができる「ブロックプログラミング」を活用する方法 「レシピ言語」:柔軟にKC4の振る舞いを定義するため、自分でプログラムを作成する方法 今回は「レシピ言語」を活用してプログラムを作成しました。 メーカーのWebサイト からサンプルコードをダウンロードし、コード同士を組み合わせたり、必要なところを書き換えたりしていきます。 サンプルコードの中の 「08_ボタン」:ボタンを押下するとデバイスを動作させるコード 「04_カメラ」:カメラを起動させ画像を送信するコード を組み合わせてプログラムを作成します。 プログラムを書き換えた主な箇所は、こちらです。 // 通信先設定値 #define CONN_HOSTNAME "an1.icgw.ntt.com" // 接続先ホスト名(ICGWで指定されているエンドポイント) #define CONN_PORT 8081 // 接続先ポート番号(ICGWで指定されているポート番号) #define CONN_PROTOCOL MMG_PROTOCOL_HTTP // HTTP通信を利用する #define HTTP_STR_URL "/ux20240115" // URL(ICGWのPath設定にて入力した値) #define HTTP_STR_METHOD MMG_METHOD_HTTPPUT // HTTPメソッド(HTTP PUTを利用 *元々POSTだったがPUTに修正) #define HTTP_STR_HEADER "Content-Type: image/jpeg" // HTTPヘッダ(jpegのtype指定) デバイスからのデータ送信先がICGWになるように書き換えています。 作成したプログラムの一部をご紹介しますと・・・ // キー押下時の処理 func event_key () { // <OLED> // カメラ制御開始をOLEDに文字表示(ボタンを押したら"CAMERA_START"とLEDに表示) OLC_DisplayChar (OLC_CHAR_USER, 0 , 0 , "CAMERA_START " ); OLC_DisplayChar (OLC_CHAR_USER, 18 , 0 , " " ); // <USBカメラの撮影要求> // カメラ撮影スタート(解像度:HD, フレームレート:10[fps]) UVC_VideoStreamCtrl (UVC_STREAM_CTRL_START, UVC_STREAM_CODEC_MJPEG, 1280 , 720 , 100 ); // カメラ起動~画像が取得できるまで10秒ほど待つ rcplib_SYS_Sleep ( 10 * 1000 ); // <HTTP PUT要求> // 送信設定 l_databuf_id = MMG_MOVIE_BUF_ID; l_send_id = SEND_ID_SORA_STR; l_burst = 1 ; l_session = MMG_SESSION_CONNECT; l_retain = MMG_DATA_NOTRETAIN; l_http_send_result = 0 ; // <OLED> // 画像のHTTP送信開始をOLEDに文字表示(画像送信開始したら"IMAGE_SENDING"とLEDに表示) OLC_DisplayChar (OLC_CHAR_USER, 0 , 0 , "IMAGE_SENDING " ); OLC_DisplayChar (OLC_CHAR_USER, 18 , 0 , " " ); // <モデム HTTP送信> // データ送信(HTTP PUTリクエスト)を実行 http_send (EXE_CONNECT, EXE_SEND, EXE_DISCONNECT); rcplib_LOG_Print ( "HTTP PUT done" ); // <OLED> // 通信結果をOLEDに文字を表示 if (l_http_send_result) { // 通信に成功した場合("SEND_SUCCESS"とLEDに表示) OLC_DisplayChar (OLC_CHAR_USER, 0 , 0 , "SEND_SUCCESS " ); OLC_DisplayChar (OLC_CHAR_USER, 18 , 0 , " " ); } else { // 通信に失敗した場合("SEND_FAIL"とLEDに表示) OLC_DisplayChar (OLC_CHAR_USER, 0 , 0 , "SEND_FAIL " ); OLC_DisplayChar (OLC_CHAR_USER, 18 , 0 , " " ); } // <USBカメラの停止要求> // カメラ撮影ストップ UVC_VideoStreamCtrl (UVC_STREAM_CTRL_STOP, 0 , 0 , 0 , 0 ); return ( 0 ); } デバイスのボタンを押下するとカメラの画像が送信され、デバイスのディスプレイ(OLED)に状況が表示されるようになっています。 ≪なぜ「レシピ言語」を使うことにしたのか?≫ はじめは、ローコードのブロックプログラミングでプログラム作成をしようとしていたのですが、思わぬつまずきポイントがありました。ブロックプログラミングにてWasabiのストレージ宛にデータ送信しようとすると、リクエスト方式は自動で「POST」が指定されます。ただ、Wasabiは「POST」ではなく、「PUT」でデータ送信する必要があり、何度トライしても送信エラーになるという事象が発生してしまいました…。ブロックプログラミングでは、リクエスト方式を書き換えることができなかったので利用を諦め、「レシピ言語」でのプログラム作成を利用することにしました。 5. 設定プログラムをデバイスに書き込む プログラムが完成したら、実行ファイルの形式に変換し、デバイスに書き込みます。KC4設定用アプリケーション上で「レシピの更新」をクリックし、 「書込むレシピ実行ファイルを指定」のところで今回作成したプログラムを指定して、書き込み対象のデバイスも選択し、「書込む」をクリックします。 デバイスが再起動され、「Hello!」と表示されたら設定完了です。 ボタンを押して撮影実行 それでは実際に動作検証してみます! ボタンを押して、 CAMERA_START と表示されて・・・ IMAGE_SENDING と表示されて・・・ SEND_SUCCESS! 成功しました! Wasabiを見てみると、デバイスから送信された写真データがきちんと格納されていますね。 定期実行に設定変更して撮影 せっかくなのでカメラが定期的に自動撮影をしてくれるように設定してみましょう!作成したコードにタイマーの設定を入れて、再度設定&書き込みし、実行してみます。今回は10分に1回カメラからの写真データを送信する設定に書き換えてみます。この撮影間隔は、最短1ミリ秒から最長約1.6カ月まで幅広く設定できます。 // Timer #define UA1_TIMER_GPIO_MONITOR 0 // Timer動作を変えるタイミングの閾値 #define TIMER_CYCLE_MODE1 600000 // 10分周期のTimerを動作させる そうすると・・・ PM 3:40に1回目、PM 3:50に2回目の撮影データが格納され、 10分ごとに自動でカメラが写真を撮影してくれるようになりました! 1回目の撮影時 2回目の撮影時 こんな形でロッカーの写真が撮影できています。 これで誰がいつ物品を取りに来たかが遠隔からでも確認できますね。 まとめ 以上のようにNTT ComのICMS、ICGW、WasabiとKC4、USBカメラを組み合わせて、社内のロッカーの遠隔監視ができるIoTシステムを構築できました。 私自身IoTシステムを構築した経験は全くありませんでしたが、ナレッジセンターやマニュアルなどを確認しながら、1人で簡単にロッカーの遠隔様子見システムを組み立てることができました。 データ転送がうまくいかない際に、どこでつまずいているのかがすぐに判別できなかったところには苦労しました。けれど、設定の作業自体は全工程含めて慣れれば3~4時間程度で完了できるものになっています。IoT導入を検討されている皆さまへ、まずはこの記事を参考にしながら実際にサービスやデバイスに触ってみることを、ぜひおすすめしたいです。 特に、今回活用したICMS・ICGWは1回線からお試しできてWebから注文可能です。Webからのご購入についてはぜひ こちら をご参照ください。 最後までお読みいただきありがとうございました。 お問い合わせ先 サービスに関するお問い合わせ IoT Connect Mobile Type S: 資料請求・お問い合わせフォーム IoT Connect Gateway: 資料請求・お問い合わせフォーム Wasabiオブジェクトストレージ: 資料請求・お問い合わせフォーム 今回構築したシステムや記事に関するお問い合わせ iot-connect@ntt.com  までメールでご連絡ください ※お手数ですが、@を半角文字に置き換えてください
こんにちは、NTT Comイノベーションセンターの小崎です。検証網を活用したセキュリティ技術の評価、運用などを担当しています。この記事では、イノベーションセンターで運用する検証網内でのインシデント発生を想定したインシデント対応演習についてご紹介します。 目次 目次 検証網について インシデント対応演習の目的 演習検討の進め方 検討のステップ 参加者について シナリオ検討の前提条件 演習の準備 演習 演習からの課題 まとめ 検証網について イノベーションセンターでは、新技術の評価などを目的とした全社検証網を運用しています。この検証網は国内に約30の拠点を持ち、1000台以上のノードなどによって構成されています。 インシデント対応演習の目的 インシデント対応演習は、大きく2つの目的で検討、準備を進めました。 自組織でインシデント(恐れ)が発生した際の連絡体制を確認する、インシデント対応者からの指示などがインシデント発生時に迅速/効率的に機能するかどうかを評価する 自組織で運用する検証網のセキュリティ検知機能や封じ込め機能が、インシデント発生時に機能するかを評価する 演習検討の進め方 検討のステップ 演習の作成にあたっては、 日本シーサート協議会(NCA) のインシデント対応演習訓練 WGにてまとめられているサイバー攻撃演習/訓練実施マニュアルを参考にしました。主な検討のステップは以下となります。 シナリオ検討、レビュー 開催準備 演習 演習後の対応、課題抽出 これらのステップを、以下のスケジュールに展開しました。 参加者について 演習には、組織のインシデント対応を担当する方達に参加してもらいました。参加者には次のいずれかの役割を割り当てました。 インシデント対応者 : 情報収集・分析者からの情報をもとに、インシデントに対しての判断、指示する 情報収集・分析者 : セキュリティアラートをモニタリングし、インシデント担当者へのエスカレーションや指示に従った解析、封じ込め対処などを行う シナリオ検討の前提条件 演習の作成にあたっては目的に合わせ、事前にいくつかの条件を設定しました。 演習シナリオ: 過去に検証網内で発生した(恐れとして報告された)インシデントを模擬することにより、アラートの検出から対処までをシナリオ化しました。 演習範囲: 自組織内のインシデント対応者までの報告、対応を演習範囲としました。実際のインシデント発生時に必要となる社内組織への報告や、被害の把握などのプロセスは対象外としました。 演習当日のスケジュール: 演習参加者には演習の日時を事前に共有し、参加の稼働を確保してもらいました。 演習場所: 現在は在宅からの勤務が主流であることから、関係者が集合して演習するのではなく、自宅から情報収集、指示などのハンドリングを行いました。 演習開始のトリガー: セキュリティ検知機能側のチューニングなどにより、演習実施時に生成する通信からアラート生成、被疑端末を作成しました。アラートを生成させるためだけに、実際に端末をマルウェアに感染させたり、悪性サイトへのアクセスを行ったりしないこととしました。 条件が多くあると限定的な演習のように感じられるかもしれませんが、目的や実施体制に合わせて事前に条件を決めておくことが重要になります。 演習の準備 作成したシナリオを週に1回レビューし、次週までに修正を繰り返し行うことで2つの演習シナリオを作成しました。レビューを繰り返すことにより、シナリオ上の矛盾や実際の運用上では起きえないことなどが修正されていきました。 セキュリティ機能の評価については、シナリオで想定したアラート生成や封じ込めができるかどうかを個々のパートに分けて機能検証を実施しました。個々のパートでは上手くいった機能検証も、シナリオを通したシミュレーションでは上手くつながらないことも発生し、複数回検証する必要もありました。 演習の時間配分については、事前に実施したシミュレーションなどからシナリオ単位でのタイムテーブルを作成しました。タイムテーブルに沿ったチェックポイントを作ることで、演習が予定した時間内に完結できるよう準備をしました。 演習全体のイメージは以下となります 演習 準備したシナリオに沿い、演習しました。シナリオの1つを紹介します。具体的にどのような装置で検知や隔離したかなどの情報は省略しています。 1: 以下のアラートの受信からスタートします。 セキュリティ検知装置から、外部に存在する悪性度の高いサイトへのアクセスが複数発生していることが情報収集・分析者にアラートとして通知される。情報収集・分析者は、アラートの初期調査をすることで悪性サイトへアクセスをしている端末が存在するセグメントを特定するが、外部への通信が暗号化されているため詳細を特定できない。情報収集・分析者はインシデントの恐れがあるとしてインシデント対応者に初報通知を行った。 2: インシデント対応者は、初報の段階ではインシデントであるかどうかの判定ができないため、情報収集・分析者に追加の調査を指示し、以下の情報を得ます。 調査指示内容 情報収集・分析者からの情報 具体的な調査方法 悪性通信を発生させているセグメントはどこか ゲスト利用が可能なセグメント トラフィック分析から特定 セグメント外への影響の可能性はあるか 他の内部セグメントへの通信は不可のため、可能性は低い 構成情報、セキュリティポリシーから回答 悪性通信を発生させている被疑端末は複数か 被疑の端末は1台 セグメントのトラフィック分析から特定 被疑端末は特定できるか 端末のIP、MACアドレスを特定できる 被疑端末が繋がっている物理機器から特定 被疑端末が接続している場所はどこか オフィスの某フロアである 被疑端末が繋がっている物理機器から特定 被疑端末から外部へのアクセスは継続しているか 初報時点から継続している トラフィック分析から特定 被疑端末からのトラフィックはあるか ダウンロード方向のトラフィックを発生させている トラフィック分析から特定 被疑端末の利用者は特定できるか 特定できない インベントリ情報の調査から回答 3: インシデント対応者は、得られた情報から 端末の封じ込め(ネットワークからの隔離)を行う判断 をし、情報収集・分析者に作業指示をしました。 4: 情報収集・分析者は、該当端末のMACアドレスをフィルタリングすることでネットワークから隔離しました。被疑端末の隔離後、悪性サイトへのトラフィックが停止したことを確認しています。 5: インシデント対応者は、詳細を把握するためオフィスにいる社員へ被疑端末とその利用者の特定を依頼しました。被疑端末の利用者が発見され、ヒヤリングにより被疑端末が社内管理のインベントリに未登録の端末であること、悪性通信と判断される暗号通信は個人の検証目的で発生させていたことが判明しました。 6: インシデント対応者は全ての情報から、今回は マルウェア感染や情報漏洩などのインシデントは発生していない と判断し、未登録の端末を利用していたことに対しては厳重注意することでシナリオをクローズとしました。 以上が演習の大まかな流れになります。今回の被疑端末はシャドーIT的な利用を想定しました。シナリオの中では封じ込めの判断、対処方法などが判断ポイントとなるよう作成していましたが、適切な判断と対処指示がなされたと思います。 以下は、事前に作成した演習のタイムテーブルになります。 演習からの課題 演習終了後の参加者で意見交換を行い、いくつかの意見、課題が挙げられました。 演習の作成においては、シナリオのレビュー、事前準備の重要性があげられました。特に実環境での演習においては、想定したシナリオどおりにアラートが検出できないことなども発生したため、事前のシミュレーション、確認作業が重要になります。 また、オンラインを前提としたインシデントハンドリング、対応時のルールの不備が課題に挙げられました。複数の対応者がいる場合、オンライン上で誰がどの対応をしている状況かなどの状況も見えにくかったため、インシデント対応時のコミュニケーションツールの使い方、ルールなどの取り決めが必要になります。 改善すべき点として、セキュリティ検知、対策機能などのドキュメント不足があがりました。特に、インシデント担当者がスムーズに判断、指示できるよう、最新化したドキュメントを事前に共有しておく必要があります。 まとめ 今回、自作のシナリオによるインシデントハンドリング演習を企画、実施しました。インシデント(恐れ)発生時の連絡体制やインシデントハンドリング時の検知、対策機能の課題や改善点を洗い出すことができ、当初の目的は達せられたと思います。 今後は、今回の演習で課題となった点の改善をすすめます。次回の演習としては、インシデントを突発的に発生させることを実施したいと考えています。また、新たに発生したインシデント(恐れ)を擬似したシナリオを作成することにより、演習の最新化も行っていく予定です。
はじめての方、はじめまして。久しぶりの方、お久しぶりです。 イノベーションセンターの何縫ねの。( @nenoMake )です。 普段の業務ではソフトウェアエンジニアとして Node-AI という WEB アプリケーションの開発をしています。 パブリックな活動としては、好きな言語である C# 関係の OSS 開発や 技術ブログ の投稿、 登壇 などをしています。 ですが、今回は C# ではなくフロントエンドのお話をします...! この記事では今まで Vue.js 2.x で開発されていた Node-AI の WEB フロントを 完全に捨て去り 、 React にリプレイス したお話をつらつらとしていきます。 まずは前編ということで、リプレイスプロジェクト発足時の課題感からはじめ、プロジェクトの進め方や選定技術などについてお話しします。 後編には内部の設計などのより技術的なお話をしたいと思います。では前編スタート...! Node-AI とは 今までのフロントエンドの課題 リプレイスプロジェクトの進め方 フェーズ1 フェーズ2 バックエンドにも手を入れる事を躊躇わない 選定技術 リプレイスを通して得たもの まとめ 後編予告 Node-AI とは Node-AI はノーコードでAIモデルを作成できる WEB アプリケーションです。以下の図のようにカードを直感的につなげるだけで時系列データの前処理からAIモデルの学習・評価までの一連のパイプラインを作成・実行できるようなものとなっています。 各データ処理(例えば正規化やデータ分割など)がそれぞれカードとして表現されており、それを繋げてパイプラインを作成します。 視覚的に処理の流れを追いやすく、データ分析者の(往々にしてカオスな)コードを解読する行為から解放されるため、業務が捗るでしょう。 また複数人での同時作業にも対応しているため、コラボレーションが活性化し、ステークホルダーを巻き込んだ効率的なデータ分析やAIモデル開発ができるようになるはずです。 現在 β 版 として公開しているので、気になる方は是非使ってみてください。 今までのフロントエンドの課題 すこし歴史的経緯から。 私は新卒2年目なのですが、その入社より遥か以前、Node-AI の開発プロジェクトが爆誕したのは機械学習エンジニアたちがいろいろ案件を回していく中での課題感からだったそうです。 なのでいざ Node-AI というアプリケーションを開発するぞ!となった時、発案者たちである機械学習エンジニア達がアサインされるのは言うに及ばずなのですが、さてアプリケーションエンジニアないし WEB 系エンジニアはどう調達するか。 課題感が発生したチームには、そのような人材はいなかったそうです。機械学習専門のチームだからそれはそうという感じ。 このような場合、社内から適切な人間を引っ張ってきてどうにか解決するのがベストなわけですが、残念ながらそうはいかなかったそうです。 ではどうするか。そう、外注です。 そんなこんなでプロジェクト発足当初は Node-AI のフロントエンドは完全に外注していたそうです。 発注元にコード書ける人間がいない中で外注するとどうなるかは火を見るよりも明らかで、以下のような状態に陥ってしまいました。 発注側にコードの品質を管理できる人間がいないため、コードが徐々にカオスへ 指示された機能さえ出来てればいい、の積み重ね コードがカオスになるにつれ、少しの修正に多くの時間と金がかかるように このような状態が続いたわけですが、とあるタイミングで「全部内製開発するぞ!」という事になり、弊チームの人間がフロントエンドの開発をするようにもなったそうです。 内製開発に倒したはとても良い事だと思うのですが、結局今までのカオスの上に増改築をするような状況となるので、フロントエンドの機能開発に時間がかかるのなんの。 この時、フロントエンドが抱えていた技術的な課題は以下のようなものでした。 問題ある DOM 構造や CSS 手を加えると意図しない箇所の描画が壊れたりする砂上の楼閣 問題あるコンポーネント設計 単一責務になっていなかった 結果として生まれる神コンポーネント 具体的には 3000 行を超える SFC (.vue ファイル) が存在していた むやみに複雑な props と emit のスパゲッティ 厳しい開発体験 Vue.js 2.x の低い TypeScript ビリティ 型が分からず、動かしてみないとデータ構造が分からないケース多数 にも関わらず、デバッガが使えない VSCode の intellisense や Find All References 等の機能が効かない 迫る Vue.js 2.x の EoL この技術的な課題の結果として、度々ユーザからリクエストを受けるフロントエンドマターな機能が実装できないという問題や、デザイナーと開発者との連携、例えば Figma で提示された CSS が使えない等の問題も生じていました。 という事で、 これらすべての問題 を解消するため、フロントエンドをリプレイスするプロジェクトが動きました。リファクタリングじゃなくてリプレイスですからね、すべての解消を狙って然るべきでしょう...! そしてただのリプレイスじゃねぇぞ、ド級のリプレイスだ...! という事で、度々ユーザからリクエストを受けていた機能もこれを機会に実装しちゃうぞ!という形で進める事となりました。 GUI アプリケーションの開発を組んだ事ある開発者の方はいろいろ分かると思いますが、最初から考慮していないと厳しいものはいろいろありますよね。 後から入れるとコストが大爆発するやつ。 リプレイスプロジェクトの進め方 まず前提として、 現在の Node-AI はスクラムを用いたアジャイル開発をしていて、開発チームはフロントエンドチーム、バックエンドチーム、インフラチームといったような技術領域での分割を していません 。 フロントエンドはできるがバックエンドは全くできない、あるいはバックエンドはできるがフロントエンドは全く出来ない、みたいなエンジニアは 現在では 弊チームに存在しません(採用を頑張っている事が伺えますね)。 まぁ、もちろん得手不得手はありますし、専門領域も異なるのですけどね。 そしてこのプロジェクトは主に2つのフェーズが存在しました。 それぞれどのような感じであったかを書いていきます。 予め断っておくと、いわゆる設計工程と開発工程とは異なったものです。 フェーズ1 期間としては 2022年6月~10月 です。 この期間は開発チームから私含めた4人を切り出し、主に以下のような事を行っていました。主には技術的な下地を作っていたといえるでしょう。 既存機能の整理 技術選定のためのサーベイ 不確実性の高い箇所についての設計やプロトタイプ実装 各既存機能の再実装にかかるコストの見積もり 技術選定の内容としては Vue.js 3.x/Nuxt.js, React/Next.js のどちらで行く?から始まり、UI ライブラリは?グラフライブラリは?とかとか。選定技術については後述します。 また技術的に不確実性が高い箇所については、実実装に入る前のこのフェーズで実際に手を動かしていろいろ試していました。 たとえば Node-AI のキャンバス画面 (カードを配置する画面) は素朴に DOM をくみ上げればいいというわけでもないので、その描画をどのように実現するか、具体的には html の <canvas> で行くのか <svg> で行くのかとか、フルスクラッチするかライブラリに乗っかるか等です。 他にも今までのフィードバックから需要が高い事は分かっているが今まで実装できなかった undo/redo や 複数人でのリアルタイム共同編集機能といった、さまざまな要求を実現するための技術的な不確実性を解消していました。 一個人のエンジニアとしては、とりあえず実装してみてそれをベースに開発メンバで頭突き合わせてあーだこーだと議論して、不確実性の解消し、完成度を高めていくというこのフェーズの活動はめちゃくちゃ楽しかったです。 そしてこれらの活動を通じて実装のおおよその感覚をつかみ、フェーズ2にて実装する全ての機能それぞれに実装コストの見積もりました。 とはいえ見積もり自体は大味ですが。 フェーズ2 期間としては 2022年11月~2023年12月 です。 まずはフェーズ1と同じ4人のエンジニアで実装をすすめ、2023年6月ごろから徐々に開発者の人数を増やし、12月にリプレイス完了!といった形です。 このフェーズの開発は Vue.js 2.x の EoL が 2023年12月であったことからも、とにかく開発速度が求められていました。 EoL までには何としてもリリースしたい。 そこでこのプロジェクトでは、これまで行っていた通常のスクラムとは一部異なる進め方をする事にしました。 これまでの進め方では、優先順位の高いプロダクトバックログアイテム(機能など)から順番に、複数の開発者で協力して開発してきました。 この進め方は必然的にチームの中で多くのコミュニケーションが発生するため、それが結果的に「コードをみんなのもの」にし、チームとしてのレジリエンスを高める事に寄与してくれていました。 しかし裏を返せば、コミュニケーションコストがそれなりにかかっているということですから、開発速度を最優先事項に据えた場合、最適ではなくなります。 そこでリプレイスプロジェクトでの開発においては「一人一殺」という標語の下に、特定の機能は特定の人が一気通貫で作るというスタイルで開発を進め、開発速度を高めていきました。 とはいえ当然レビューは行うので、実装者とレビュアーの間でのコードの共有はなされていましたし、誰かが悩んだりした際には随時メンバー間で相談や壁打ちは行っていたため(心理的安全性が確保されていると言えますね...!)、完全に一人しか知らないコード、というのはほぼないと思われます。 なお、インクリメントという名のアウトプットをステークホルダーにお見せしフィードバック貰ってプランニングして...、といったスクラム一般の一連の所作は今まで通りやっていました。 ところで一人一殺という進め方、技術的な視点で見ると、そのやり方で進めると実装取っ散らばらないか?と思ったりもするのではないでしょうか。 それについてはフェーズ1にて一定のレールを敷くことに成功し、基本的にはそれらのレールに沿って実装したため問題になりませんでした。 特に量産が必要なところ、例えばキャンバス上に配置されるカードなどのオブジェクトの操作や、各カード毎(=データ処理や機械学習に必要な処理毎)に対して作る必要があるカード詳細画面などは、それがよく機能していたと感じるところです。 また前述のとおり、2023年6月ごろから追加の開発者がこのプロジェクトに投入されたのですが、投入されたメンバーはいままで Vue.js で開発をしていたため、React には不慣れでした。 しかしながらメンバーそれぞれの React に対するモチベが高く優秀であった事に加え、コード上に一定のレールを敷くことが出来ていたため、スムーズにキャッチアップでき、最終的なゴールまで加速できたのではと思います。 その結果として2023年12月末、Vue.js 2.x の EoL というタイムリミットの前になんとかリリースできました、という感じです。 いやはやよかったよかった。 バックエンドにも手を入れる事を躊躇わない フロントエンドのリプレイスは既存のフロントエンドの負債を解消する事と、今まで実現できなかった機能を実装する事を主だった目的としていました。 しかしそもそも、なぜ負債の解消をするのでしょうか?それは今後の継続的な機能開発を加速可能な状態にするためです。 せっかくリプレイスしても新機能の追加が大変なものが出来上がったのでは、コストを支払った意味がありません。 そういった視点で考えたとき、既存のフロントエンドが利用しているエンドポイントをそのまま利用する事がそれに寄与するのか?というのはリプレイスプロジェクトを進める上で当然議題にのります。 フロントエンドの実装を進める上でぶつかった既存のエンドポイントに関する課題は以下のようなものでした。 複数のエンドポイントのレスポンスが闇鍋 いくつかのエンドポイントはレスポンスが極めて動的 エンドポイント単位で型を与えるのが困難 これは今後も新たに機能を追加する際、都度闇鍋 JSON に新機能由来のデータが追加され、それをデシリアライズした後に解釈するためのコードを加筆し続ける必要があるという事です。 これは継続的な開発及びバグ防止の観点から避けたいです。 そこでこの課題を解決するべく、バックエンド実装に対して以下の方策をとりました。 新規に実装してもたいしたコストがかからないものについては新規実装 新規実装にコストがかかりそうなものについても新規エンドポイント実装 ただし内部では BFF のような仕事をするレイヤを作成するだけに留め、ロジック自体は既存実装を使いまわす これによりレスポンスを比較的シンプル化 & 強く型付け もともとフロントエンドのリプレイスプロジェクトですから、コストをあまりかけないようにしました。 このようにバックエンドの実装も修正しながら進められた事は、フロントエンドだけでなくバックエンドも一定以上に書けるエンジニアでプロジェクトを進める事が出来た利点でしょう。 また上記の課題とは別軸に、以下に対応するためにもバックエンド実装は必ず通る道でした。 リプレイスで生まれる新機能向けバックエンド実装 リアルタイム通信系機能 ストレージ節約マイクロサービス リアルタイム通信に纏わる機能は既存の実装にはほぼ無いものでしたから、必然的に新規実装する事になりました。 また Node-AI のキャンバス上に配置されたカードのデータ処理や機械学習の結果にまつわる生成物がバックエンド上では伴うのですが、フロントの新機能としてキャンバス内操作の undo/redo を実現すると、それらを即座に削除する訳にもいかなくなりました。 つまり定期的に不要になったそれらを片付けるマイクロサービスなどが必要でした。 このようなものもフロントエンドのリプレイスプロジェクトだからといって躊躇わずに実装しました。 選定技術 選定した技術はおおよそ以下のような感じです。 TypeScript React/Next.js Redux Mantine ECharts SignalR Tailwind CSS Mock Service Worker Storybook React Testing Library Playwright もともと Vue.js 2.x を用いていた事から、Vue.js 3.x/Nuxt.js と React/Next.js のどちらを使うのかはプロジェクト発足時、当然議題にあがりました。 結果としては React/Next.js を選んでいるのですが、理由としては以下の通り。 TypeScript との親和性 世界的な潮流 Vue.js 3.x が JSX を取り込んだことからも分かる通り。 メンバーのモチベ 個人的には React の「GUI は純粋関数として表現できる」という思想及び単方向データフローである点は極めて有益であると感じ、関数型コンポーネント + hooks 登場以降の React は大好きです。 もちろん実装上は全てのコンポーネントが純粋関数とはいかないのですが、Node-AI の実装では純粋なコンポーネントとそうでないところは徹底して分離する事で、読みやすさと保守性の向上に努めています。 またグラフライブラリには ECharts を利用しています。 Node-AI は時系列データを取り扱うアプリケーションなので、そこそこ大きいデータも問題なく描画できるグラフライブラリを選択する必要があります。 そこで10個弱のグラフライブラリでそれなりのサイズのデータを描画し、パフォーマンスバトルを行いつつ、GUI としての操作感や今後実現したいグラフが描画できるか等を検討しました。 結果的にパフォーマンス的にもグラフ表現の幅も広かった、ECharts を採用しました。 リプレイスを通して得たもの 整理整頓された DOM 構造や CSS 綺麗になったコンポーネント達 TypeScript による徹底した静的な型付け Storybook による UI カタログ 統一された開発環境 もともと課題になっていた、いわゆる汚いコードというやつは当然ながら全て払拭しました。 上記で「綺麗になったコンポーネント達」というふんわりした事を書いているのですが、ここでは以下のような事を徹底しました、という事です。 単一責務 container と presenter の分離 message と service の分離 イベントハンドラ等の関数名による明示的な意味づけ 上2つについては特にいう事はないでしょう。 多くの人が頭で理解はしていても、なんやかんやで徹底されず、多くのコードではそうなっていないというだけで。 3つめの message と service の分離については、要はデータと処理の分離です。 データ指向プログラミングとも言いますね。 リプレイスされた TypeScript のコードの多くは純粋関数で出来ているため、これは自然と守られます。 とはいえそれが全てではなく、当然 class も使っています。 その場合でも、それらのインスタンスを「状態を持って振る舞うオブジェクト」として用いるのではなく、あくまで「immutable な message と service」といった形で分離し利用する事で、これを徹底してます。 そして最後のイベントハンドラ等の関数名による明示的な意味づけについてですが、これはたとえば useEffect の第一引数に処理をべた書きした無名関数を渡すのではなく、 コンポーネントの外で名前が与えられた関数を定義し、それを useEffect の引数内で用いるといったコードの書き方をしたという事です。 もう少し具体例をだすと onChange のような props があった時、そこに onChangeHandler みたいな情報量ゼロな関数オブジェクトを渡すのではなく、たとえば validateXxx のような何をする事を意図しているのか瞬時に判別できる名前のついた関数オブジェクトを渡すようにする、とかです。 こういった命名を積み重ねていくことで、初見でも渡されている関数が何を意図しているのかがすぐに分かります。 また同時に名前がついていることから、別の処理を追加しようとした際に心理的な抵抗感が生まれるため、1つのメソッドにさまざまな処理が追加され、結果的に単一責務からかけ離れた多重責務になってしまうといった状況が発生する事を防げます。 ラムダをべた書きしたり、情報量ゼロの名前を関数につけてしまった場合に発生しがちな複数の責務が押し寄せてくる事象も、小さな命名の積み重ねで防げると私は考えています。 そしてもう1つ、地味に大事な収穫の1つとして、統一された開発環境を提供できるようになりました。 現代の TypeScript によるフロントエンド開発する上で VSCode 上での開発体験は極めて重要です。 IntelliSense によるコード補間、Find All References や Go to Definition といったシンボルでコードを飛び回る機能、そしてデバッガ。 これらは生産性にダイレクトに響いてきます。せっかくゼロベースでやるのであれば、そのあたりは整備して全開発者にばら撒いてしまった方がなにかと良いです。 各々で開発環境をカスタムするのは止めませんが、標準的な開発環境は揃えた方が何かと幸せ。 という事で dev container で必要な設定や拡張が一式揃った開発環境を提供しています。 今までは標準的にはこれ使ってね、みたいのも無く、VSCode の便利機能を活用しきれていないケースが多々あったのですが、これにより全ての開発者はコストゼロで生産性の高い環境を手に入れられるようになりました。 まとめ Node-AI のフロントエンドは Vue.js 2.x を捨て、React/Next.js に移行を果たしました。 この記事では主にプロジェクトの進め方や技術選定、結果として得られたものについてお話しました。 私個人としては入社してから殆どこのプロジェクトに付きっ切りでしたので、いろいろやり切った感があります。 頑張った偉い。 とはいえ React にリプレイスされた Node-AI のフロントエンドはこれで終わりではなく、むしろこれからの機能追加がドシドシ行われるフェーズこそが本番であり、設計したものの真価が問われるので、気が引き締まりますね。 そして EoL を迎えた Vue.js 2.x を捨てなければならない案件は各所で発生している問題かと思いますので、この記事が読者の皆さまの役に立てば幸いです。 後編予告 前編であるこの記事では、主にプロジェクトの進め方等について書いていきました。後編ではもうちょい技術よりのお話をする予定です。今のところ、以下の内容の設計だったり開発フロー等についてを予定しています。それではまた後編で会いましょう...! ライブラリ依存無しでキャンバスを SVG で表現している話 キャンバスのリアルタイム共同編集機能の話
この記事では TypeScript ver4.x にて実験的な機能である decorator を使い、ログ出力コードを削減・コードの可読性を上げた経験を紹介します。 はじめに 背景 decorator とは decorator を使ったログ出力方法の検討 decorator を使ったログ出力の実装 実装時にハマったこと等 関数定義方法の変更 非同期・同期両方に対応 クラス名の取得 ログメッセージの統一 その他考慮した点 ライブラリの利用 実践結果 良かった点 悪かった点(苦労した点) まとめ 参考文献 はじめに こんにちは、NeWork 開発チームの加藤です。普段はオンラインワークスペースサービス NeWork の開発エンジニアをしています。 今回は TypeScript ver4.x にて実験的な機能である decorator を使った事例紹介をします。我々開発チームではログ出力のためのロジックの記述がコード全体の可読性を下げているという課題があり、decorator を活用することでこの課題を解決しました。その経験をもとに、良かった点・悪かった点(苦労した点)含めて紹介したいと思います。 背景 NeWork 開発チームでは、TypeScript を用いて開発しています。その中で開発中のコードの挙動を確認したり、エラー発生の監視その後の原因特定のために、ログ出力を行っています。 ログ出力は router, service, gateway などの各レイヤーで行っており、それぞれのレイヤーでログ出力を行うために以下のようなコードを書いていました。(※コードはサンプルです) const async getUser = (userId:string): Promise<MyUser> => { // 呼び出しログ表示ロジック Logger.getInstance().info( `getUser start: userId ${userId}`, // ログメッセージ LOG_POSITION.SERVICE, // ログ出力レイヤー(レイヤーごとに定数を用意しています) LOG_PADDING.START, // 開始/終了のログを判別するための定数 ); const outEndLog = () => // 終了ログ表示ロジック Logger.getInstance().info( 'getUser end', LOG_POSITION.SERVICE, LOG_PADDING.END, ); // 処理 const user = await MyGateway.getUserData(userId).catch(() => { outEndLog(); // 終了ログ表示ロジックの呼び出し throw new MyError(); }); outEndLog(); // 終了ログ表示ロジックの呼び出し return user; } このコードでは以下のような問題がありました。 エラーが発生するタイミングや、early return するタイミングでログ出力をしなければならないため、記述忘れが発生しやすい。 簡単な関数であっても、ログ出力のための記述が多くなり、可読性が下がっている。 開発者がログ出力のためのコードを書くのが面倒。 関数を作成するたびにログ出力を記述するので、人によってログメッセージの記述がバラついてしまうことがあった。(get user start と getUser start など) エラー発生時のログ出力漏れの対策としては、try-finally を書くことがあげられますが、結局のところ毎回関数を記載するたびに try-finally を書くのは大変であり、他の問題にもアプローチ可能な decorator を使ってログ出力を試してみました。 decorator とは TypeScript ver4.x の decorator は関数などに対して処理を追加する記述方法で、以下の 5 種類があります。 Class Decorators Method Decorators Accessor Decorators Property Decorators Parameter Decorators それぞれ、クラス・メソッド・アクセサ・プロパティ・パラメータに対して処理を追加可能です。 クラス・メソッド等の定義時に、decorator を @hogehoge という形式で記述することで、その decorator が適用されます。 decorator を利用することで、対象のクラスやメソッドに対して共通の処理を追加できます。 例えば method decorator の場合以下のように定義・利用します。 // decorator の定義 function logging(target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor) { const originalMethod = descriptor.value; // メソッドの処理を上書き descriptor.value = function (...args: unknown[]) { console.log('処理開始'); // 元のメソッドを呼び出す originalMethod.apply(this, args); console.log('処理終了'); } } class MyClass { // loggingというdecoratorをhelloメソッドに適用 @logging hello() { console.log('hello'); } // loggingというdecoratorをbyeメソッドに適用 @logging bye() { console.log('bye'); } } これにより、hello メソッドや bye メソッドの実行時には必ず 処理開始 と 処理終了 が出力されるようになります。 他の decorator の利用方法や具体例等は、 公式 に提示されていますので興味があればご覧ください。 今回は、メソッドに対して処理を追加するための Method Decorators を利用しました。 decorator を使ったログ出力方法の検討 Method Decorators にてログ出力を行うにあたり、以下の要件をもとに実装しました。 decorator を適用したメソッドの開始・終了時には必ずログ出力が行われる。 ログメッセージの形式を統一する。 非同期関数に対しても適用できるようにする。 ログ出力の際には、必ずクラス名・メソッド名が出力されるようにする。 decorator を使ったログ出力の実装 NeWork の実際の実装では、以下の serviceLogging , gatewayLogging という decorator を新規作成しました。 /** * @description ログ出力デコレーターファクトリーの共通処理部分,外部から呼び出す際はserviceLogging関数等を呼び出すこと * @param position ログ出力位置 * @returns デコレーター */ function logging(position: string): MethodDecorator { return ( target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor ) => { const originalMethod = descriptor.value; // ログ出力するクラス名を取得 // static関数の場合はtype of targetがfunctionに、それ以外はobjectになる const isStatic = typeof target === "function"; const className = isStatic ? target.name : target.constructor.name; // 関数呼び出し時のログ表示ロジック const startLog = () => Logger.getInstance().info( `${className}.${String(propertyKey)} start.`, position, Constants.LOG_PADDING.START ); // 関数終了時のログ表示ロジック const endLog = () => Logger.getInstance().info( `${className}.${String(propertyKey)} end.`, position, Constants.LOG_PADDING.END ); // async functionの場合、ログ出力前にawaitする const isAsync = descriptor.value.constructor.name === "AsyncFunction"; if (isAsync) { descriptor.value = async function (...args: unknown[]) { startLog(); // 仮引数の値もログ出力。ただし、オブジェクトの場合はログが煩雑になるので出力しない const argString = args .map((arg) => (typeof arg !== "object" ? util.format(arg) : "object")) .join(`, `); Logger.getInstance().debug(`args: ${argString}`); try { return await originalMethod.apply(this, args); } finally { endLog(); } }; return; } descriptor.value = function (...args: unknown[]) { startLog(); // 仮引数の値もログ出力。ただし、オブジェクトの場合はログが煩雑になるので出力しない const argString = args .map((arg) => (typeof arg !== "object" ? util.format(arg) : "object")) .join(`, `); Logger.getInstance().debug(`args: ${argString}`); try { return originalMethod.apply(this, args); } finally { endLog(); } }; }; } /** * @description サービスクラスのログ出力デコレーター * @param target クラス * @param propertyKey メソッド名 * @param descriptor ディスクリプター * @returns なし */ export const serviceLogging = ( target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor ): void => { // ログ出力位置をサービス用に指定して呼び出す logging(Constants.LOG_POSITION.SERVICES)(target, propertyKey, descriptor); }; /** * @description ゲートウェイクラスのログ出力デコレーター * @param target クラス * @param propertyKey メソッド名 * @param descriptor ディスクリプター * @returns なし */ export const gatewayLogging = ( target: Object, propertyKey: string | symbol, descriptor: PropertyDescriptor ): void => { // ログ出力位置をゲートウェイ用に指定して呼び出す logging(Constants.LOG_POSITION.GATEWAYS)(target, propertyKey, descriptor); }; 上記で定義した decorator を使った実装例は以下です。ここでは背景の項目で記載した getUser 関数を例に書き換えています。 class MyService { @serviceLogging static async getUser(userId: string): Promise<MyUser> { const user = await MyGateway.getUserData(userId).catch(() => { throw new MyError(); }); return user; } @serviceLogging static async setUser(user: MyUser): Promise<void> { ・・・中略・・・ } } このように記述することで getUser 関数の開始・終了時には必ずログが出力されるようになり、同じ定義を用いて各関数でログを出力できます。 実装時にハマったこと等 実装する際に困ったことや、想定外だったことを紹介します。 関数定義方法の変更 従来我々はアロー関数を利用し関数定義していたのですが、method decorator はアロー関数に対しては適用できず、関数定義を function で行うことで対応しました。 // 修正前 const async getUser = (userId:string): Promise<MyUser> => { ・・・中略・・・ } // 修正後 async function getUser(userId:string): Promise<MyUser> { ・・・中略・・・ } 非同期・同期両方に対応 非同期関数かどうかによって、元の関数に対して await を行うかどうかや、descriptor.value に代入する関数を非同期にするかどうかを判定する必要がありました。 // async functionの場合、ログ出力前にawaitする const isAsync = descriptor.value.constructor.name === "AsyncFunction"; if (isAsync) { descriptor.value = async function (...args: unknown[]) { ・・・中略・・・ try { return await originalMethod.apply(this, args); } ・・・中略・・・ }; return; } descriptor.value = function (...args: unknown[]) { ・・・中略・・・ try { return originalMethod.apply(this, args); } ・・・中略・・・ }; descriptor.value.constructor.name で関数の種類を判定しています。非同期関数の場合は AsyncFunction となります。 クラス名の取得 ログのメッセージにどのファイルの関数なのかを含めるために、関数のクラス化とクラス名を取得処理を追加しました。 各ファイルで定義していた関数を class でまとめ、default export するように修正し、既存の関数は class の static 関数として定義しました。 // 修正前 const async getUser = (userId:string): Promise<MyUser> => { ・・・中略・・・ } // 修正後 class MyService { static async getUser(userId:string): Promise<MyUser> { ・・・中略・・・ } } クラス名は static 関数の場合は target.name 、それ以外の場合は target.constructor.name から取得できます。 // ログ出力するクラス名を取得 // static関数の場合はtype of targetがfunctionに、それ以外はobjectになる const isStatic = typeof target === "function"; const className = isStatic ? target.name : target.constructor.name; ログメッセージの統一 ログメッセージについては、クラス名・メソッド名を必ず含めるようにしました。メソッド名は、propertyKey から取得できます。 Logger.getInstance().info( // クラス名.メソッド名 start. `${className}.${String(propertyKey)} start.`, position, Constants.LOG_PADDING.START ); また開始ログ出力後に、引数の値を出力するようにしました。 ただし引数がオブジェクトの場合は出力されるログが煩雑になるため、出力しないようにしました。もしログが必要な場合は decorator ではなく、関数内で個別にログ出力するなどの代替案で対応することとしました。 // 仮引数の値もログ出力。ただし、オブジェクトの場合はログが煩雑になるので出力しない const argString = args .map((arg) => (typeof arg !== "object" ? util.format(arg) : "object")) .join(`, `); Logger.getInstance().debug(`args: ${argString}`); 出来れば仮引数名も出力したいところですが、仮引数名を取得する方法が見つからなかったため、今回は実装を見送りました。 その他考慮した点 ライブラリの利用 decorator を直接利用するのではなく、logger-decorator というライブラリを利用することも検討しましたが、今回は我々独自のログ出力を行いたいため、ライブラリは利用しませんでした。 実践結果 実際に decorator を利用した結果、我々にとっての良かった点・悪かった点(苦労した点)は以下のようになりました。 良かった点 今回 decorator を適用したことで、元々の課題は解決できました。 関数のエラー発生時や、early return するタイミングでログ出力を意識する必要がなくなった。 関数の定義がシンプルになり、可読性が上がった。 開発者がログ出力のためのコードを書く必要がなくなった。 ログメッセージの記述が統一された。 それだけではなく、副次的に以下のようなメリットもありました。 ログの形式に、必ずクラス名が入るように修正したため、実際にログを見るときの可読性が上がった。 大きな破壊的変更をせずに適用できる方式であったため、開発速度を落とさずに無理のない範囲から順に適用できた。 コード量が多いことから、順次適用が可能だったのは特に大きなメリットでした。 悪かった点(苦労した点) 以下のような苦労点もありました。 アロー関数では method decorator が適用できない。 今回は関数定義方法を function に変更しましたが、既存のコードを大量に修正する必要がありました。この作業は単純ですが非常に作業時間がかかってしまいました。 ログ出力の完全な自動化はできていない。 関数の引数がオブジェクトの場合に中身を表示しないようにしましたが、一部、オブジェクトの内容をログに含めたい場合には結局ログ出力のためにコードを書く必要があります。 decorator を利用すると仮引数名が表示不可となりログを見た時に arg の意味が分かりづらい。 (現時点において我々には)仮引数名を取得する方法が見つけられていないことから、仮引数名をログに含めることができませんでした。 これらの問題はありましたが全体としては、decorator を利用したログ出力の実装は上手くいったと言えます。 まとめ 今回 NeWork 開発チームの課題であったログ出力コードに関して、decorator を利用したログ出力の実装について紹介しました。 我々のチームでは TypeScript v4 で実験的な decorator を利用したログ出力を実装し、コードの可読性向上に貢献できました。 一方で decorator とアロー関数の相性の悪さといったような苦労した点もありました。 方式に関して、TypeScript v5 では実験的ではなく正式に decorator を利用できるようになっています。 またログ出力には log-decorator というライブラリや、何かしらのフレームワークを導入するという手段もあると思います。 この記事が、皆さんのログ出力の実装についての 1 つの参考になれば幸いです。 NeWork チームでは、今後も開発の中で課題となっていることを解決するために、さまざまな技術を試していきたいと考えています。今回紹介した内容についても、今後も改善を続けていきます。 また、 NeWork はどなたでも無料でお試しできますので、もしプロダクトや使われている技術に興味を持っていただけたらぜひ触ってみてください。 最後に、2024 年 2 月現在、NeWork では一緒に開発を進めてくれる仲間を募集しています。詳細は以下のリンクをご覧ください。皆さまのご応募を心からお待ちしています! hrmos.co 参考文献 https://www.TypeScriptlang.org/docs/handbook/decorators.html https://bobbyhadz.com/blog/javascript-check-if-function-is-async
はじめに こんにちは、イノベーションセンターでノーコード分析ツール「Node-AI」開発チームの林です。 業務としては Node-AI のフロントエンドやバックエンド開発、最近では監視/可視化のプラットフォーム開発に携わっています。(興味ある方は こちら の記事もご覧ください。) 本記事では、2023 年 12 月 18 日に開催した NTT ドコモ・NTT コミュニケーションズ・NTT コムウェアからなるドコモグループ(以下、DCC グループ)内の Google Cloud のユーザーコミュニティ「GINGER」 の第 6 回目のイベントをご紹介します。 はじめに GINGER 紹介 オープニング 運営メンバー紹介 LT1:Google Cloud 生成AI Updates, Gemini 紹介 LT2:Google Cloud Next Tokyo'23 の 1 日目に行ってみた LT3:Google Cloud Next Tokyo'23 に行ってみた LT4:C&N部のデータ収集・可視化基盤開発およびデータ活用部の取り組み クロージング ↓ ↓ 過去イベントの開催報告はこちら ↓ ↓ DCC グループの Google Cloud ユーザーコミュニティイベント報告【GINGER Event#5】 GINGER 紹介 GINGER は Google Cloud Community In NTT Group Enterprise の頭文字をとって命名しました。経緯の詳細は こちらの記事 に掲載しています。 活動の中でも 特にイベントでのオフラインのつながりを重要視 しています。Google Cloud に関するノウハウ共有を実施しつつ、 このコミュニティに参加したからこそ得られる業務を超えたつながりを価値 として感じてほしいと思っています! では、本題である GINGER Event#6 の開催報告に入りたいと思います! オープニング Event#6 では下記のアジェンダで開催しました! 今回は 11 月 15 - 16 日で開催された「Google Cloud Next Tokyo ‘23」に行ってみた感想や面白いセッションの共有にフォーカスした LT 大会となりました。 トップバッターは グーグル・クラウド・ジャパン合同会社様のカスタマーエンジニアである仲根さん による 「生成 AI Updates & Gemini 紹介」 をお話しいただきました。仲根さんにはドコモ時代からお世話になっており、 本コミュニティ「GINGER」 の立ち上げを全面的に支援いただいており、感謝が尽きません。 次にコミュニティメンバー枠として 2 本の LT をしていただきました。1 本目は 2 回目の登壇となる NTT ドコモ データプラットフォーム部(以下、ドコモ DP 部)三浦さん から 「Google Cloud Next Tokyo ‘23 1 日目に行ってみた」 、2 本目は初参加で初登壇の NTT コミュニケーションズ イノベーションセンター 會澤さん から 「Google Cloud Next Tokyo ‘23 に行ってみた + 生成 AI 試してみた」 となっており有益な情報を共有していただきました。 最後にニューメンバー枠として NTT コミュニケーションズ クラウド&ネットワークサービス部(以下、C&N部) 渡邉さんと櫻田さん から 「C&N部のデータ収集・可視化基盤開発およびデータ活用部の取り組み」 ということで普段の業務と Google Cloud を絡めた内容を発表いただきました。 年内最後のイベントでもあったため LT 4 本の盛りだくさんなイベントとなりました!また、オフラインでの現地参加者数は過去最多の 18 名となっておりコミュニティの成長も感じられました。 アジェンダを見ただけでもワクワクするような LT 4 本立てとなっていて、振り返ってもとても濃密な時間となっていました! (執筆者 NTTコミュニケーションズ/林 知範) 運営メンバー紹介 今回の運営メンバーの紹介になります!前回同様にコミュニティメンバーへの呼びかけに応じてくれた森さんと中村さんの 2 名です。コミュニティ経験豊富なメンバーだったのでイベント運営が今まで以上に円滑でした。 —-------------------------------- NTT ドコモ サービスデザイン部(以下、ドコモ SD 部)の森と申します。元々ドコモ CCoE として Google Cloud の組織管理を担当し、当初よりグーグル・クラウド・ジャパン合同会社様とも密に連携をしておりました。また、Google Cloud の社内事例共有会を開催するなど、Google Cloud 利用者とも繋がりがあり、GINGER でも主要メンバーとして毎回参加しています。現在は別業務を担当していますが、Gemini の発表など Google 技術の変化は大変興味深く、同じモチベーションをもっているメンバーと交流できる GINGER は楽しみの1つとなっています。 本活動を支援いただいている全ての方々に、お礼申し上げるとともに、GINGER が皆さまに好影響を与えるコミュニティであり続けることを願っております。 —-------------------------------- (執筆者 NTTドコモ/森 健史) LT1:Google Cloud 生成AI Updates, Gemini 紹介 LTのトップバッターであり Googler 枠として登壇いただいたのは グーグル・クラウド・ジャパン合同会社様のカスタマーエンジニアである仲根さん になります。 「Google Cloud 生成AI Updates, Geminiご紹介」 のタイトルで発表いただきました。 はじめに、既存の生成 AI の Update として PaLM2 に chat-bison-002 と Unicorn のモデルが登場したこと、PaLM から Vertex AI Search を グラウンディング(モデルの出力を特定のデータに紐づける根拠付け)可能になったこと 、画像生成モデルの Imagen に Imagen2 が登場したことなどを説明いただきました。下図では Imagen よりも Imagen2 の方が生成される画像の精度が高いことが分かります。 続いて、2023年12月に発表された Gemini について説明いただきました。Ultra, Pro, Nano の 3 つのサイズが用意されており、 Gemini Pro については Google の会話型生成 AI サービスである Bard(英語版) や Google Cloud の Vertex AI で利用できるとのことです。 発表の中では Gemini のマルチモーダル機能について多くの説明がありました。2色の毛糸の画像を入力して「ここから何を作るべきか」の Gemini からのアイデア提案を受けたり、手のひらでコインを隠すマジックを複数の画像として入力して Gemini に説明・推論させたりといったものです。加えて Gemini Pro in Vertex AI のデモとして、Gemini が「ハイコンテキストな画像をどのように解釈するか」、「図形の意味をどこまで理解できるのか」の2つを実演いただきました。 図形の読み解きについてはシーケンス図とプロンプト(問題文)を入力としてGeminiが各問題に正しく回答する様子を実際に見せていただきました。 最後に、Sales Update として 2023 年 11 月に東京ビッグサイトで開催された Google Cloud Next Tokyo'23 参加の御礼と、ラスベガスで開催される Google Cloud Next'24 の案内で発表が締め括られました。 【感想】 Gemini の提供形態やマルチモーダル機能についてデモを交えてご説明いただき、とても分かりやすく参考になりました。MMLU(Massive Multitask Language Understanding) のベンチマークとして高いスコアを出していることを踏まえ、グラフ画像を含むレポートや文章の読み解き・生成にも利用できるといったところは今後試してみたいと思います。 (執筆者 NTTコミュニケーションズ/櫻田 真士) LT2:Google Cloud Next Tokyo'23 の 1 日目に行ってみた 次の LT は、 NTT ドコモ DP部の三浦さん です。Google Cloud Next Tokyo'23 の 1 日目に行ってみた感想を発表していただきました。 本人は大規模なイベントには初参加で、東京ビッグサイトで開催していることで「イベントやっている」感があり、楽しく参加できたとのことでした。 セッションは 業務で利用しているCI/CD周りを中心に聴講してきた とのことです。 1 つ目の参加セッションは、製造業での Cloud Run 周りの事例セッションです。 Cloud Run については知見がある中での参加とのことでしたが、小さなことでも知らなかった学びがあったり、セミナーの構成がとてもきれいであったという学びがあったようです。 ( Cloud Run を中心とした、製造業でのシステム開発コラボレーション事例 ) 2 つ目は、Organization を利用したガバナンスとセキュリティの事例セッションです。 あまり知見のない領域での参加とのことでしたが、役に立ちそうと前向きなコメントをしてくださっていました。Organization 機能は単一プロジェクトを利用しているだけでは意識することはないと思いますが、 Google Cloud のリソース管理体系は階層構造になっている点を理解して利用してもらえると、今後効果的な複数プロジェクト運用ができることがあるかも しれませんね。 ( 新米管理者の奮闘記のその後 〜 Organization の秩序を維持する試み 〜 ) 3 つ目は Google Cloud の CI/CD を利用したソフトウェアデリバリーについて、Google Cloud の方が講師を務めるセッションです。ここで触れられた各サービスについては三浦さん本人の業務でも利用しており、 「訳あってCI/CDをCloud BuildからGitHub Actionsに変えてみた」というタイトルで ドコモ開発者ブログ にもなっているため、皆さんも是非見てみてください!( 最新 Google Cloud CI/CD を利用したソフトウェア デリバリー ) (画像中のサービス群の引用元: Software Delivery Shield のコンポーネント ) 最後に全体を通して、「今回は業務で利用している領域中心だったけど、次はあえて自分が知らない領域も聞きたい」と前向きなコメントを残してくださいました! 【感想】 Google Cloud Next Tokyo には今回初参加ということで、色々刺激を受けたことが伝わってくる発表でした。実際に参加すると元々業務で利用している領域だけでなく、知らなかった領域への興味も湧いてきますね。全体的に前向きな姿勢を感じる発表で、聞いている側の私も刺激になりました。素晴らしい LT ありがとうございました! (執筆者 NTTドコモ/森 健史) LT3:Google Cloud Next Tokyo'23 に行ってみた LT 発表者は NTT コミュニケーションズ イノベーションセンター の會澤さん です。 今回 Google Cloud Next Tokyo'23 に行ってみた感想を発表していただきました。2 日間基調講演に参加しており、紹介しきれないのですが今回の Google Cloud Next Tokyo'23 の見どころであった生成AI部分を中心に紹介させていただきます。 會澤さんは NTT コミュニケーションズで Qmonus Value Stream という DevOps プラットフォームを開発 しています。 會澤さんには基調講演で聞いた 「生成AIによるアシスト Vertex AI」 を実際に自分のプロダクトのドキュメントで利用した様子をデモしていただきました。 ここで利用されていたのは 「 Vertex AI Search and Conversation 」というGoogle Cloudのプロダクト でした。本プロダクトには大きく分けて 「Vertex AI Search」「Vertex AI Conversation」 の 2 機能があります。 その中で會澤さんは 「Vertex AI Search」 を利用されていました。これは LLM(Large Language Model) がドキュメントを読み込み、利用者の質問に対して回答を生成するものです。 実際に Qmonus Value Stream のドキュメントを Vertex AI に学習させ、対話で内容を理解できる 様子をデモしていただきました。 デモの結果は上記の通り、無事に学習した内容を参照して対話形式で必要とする情報を取り出せていました。 最新技術をまずは自分のプロダクトで試してみることで、その技術の適用範囲を理解することができたとのことです! 【感想】 ドキュメント管理の問題は開発をしているとよくぶつかる問題です。 最新仕様のドキュメントはどれなのか、そもそも知りたい仕様はどこにあるのか、プロダクトが大きくなるにつれ膨大な量のドキュメントから探さなければなりません。 今回デモしていただいたように、知りたい情報をチャットボットで回答させるという方法は、この問題を解決する方法の 1 つと感じました。 「私もさっそく自分のプロダクトのドキュメントで活用したい」と感じさせる、ワクワクする LT でした! (執筆者 NTTコミュニケーションズ/渡邉 佑典) LT4:C&N部のデータ収集・可視化基盤開発およびデータ活用部の取り組み 最後の LT は、 NTT コミュニケーションズの渡邉さん、櫻田さん です。C&N 部のデータ収集・可視化基盤開発およびデータ活用部の取り組みについて発表していただきました。 まずは渡邉さんから NTT コミュニケーションズのクラウド・ネットワークサービス向けデータ収集・可視化基盤における、Google Cloud を利用したソフトウェアデリバリーについて話してもらいました。 渡邉さんも Google Cloud Next Tokyo'23 に参加し、自分たちのシステムの CI/CD をどう進化させられるかという観点で 「最新GoogleCloud CI/CD を利用したソフトウェアデリバリー」 セッションを聴講したとのことです。 そこで以下2点について見直しを行ったとのことでした。 CD にはデリバリーとデプロイの 2 種類がある セキュリティとCIを率先して実施すべき すると、 本番環境までの自動デプロイは実現できていない点、セキュリティについてはコンテナの脆弱性スキャン機能を使えていない点について気づいた とのことです。 「まだまだ改善すべきこと、やりたいことが たくさんあります」と締め括っていただきました。クラウドサービスやベストプラクティスは進化スピードが早いため、常に情報更新して適用していく姿勢が大事ですね。 続いて、櫻田さんからC&N部『データ活用部』 の取り組み事例について発表していただきました。 C&N部の『データ活用部』は、有志が公募制で参加し、データ利活用スキルを学び、教え合い、本業に活かしていく社内活動(部活) です。データドリブン化に向けた課題設定、解決に向けた活動だけではなくデータ利活用人材のキャリア形成サポートも行っているとのことです。 今の世の中、キャリア形成が大事なのでこのようなサポートはエンジニア一個人としてありがたいですよね。 また、取り組み事例として、 Google Cloud の Vertex AI を利用して、機械学習モデルを構築し、トラフィックデータの将来予測・可視化ワークフローを自動化する試みについて 話してもらいました。 最後に今後について、グーグル・クラウド・ジャパン合同会社様とさらなるコミュニケーションを活性化させて、Duet AI、BigQuery での PaLM 活用、BigQuery DataFrames、Vertex AI Search 等の新機能についても検証したいと語ってくれました。 【感想】 今回、LT2 の三浦さんも CI/CD 周りが中心でしたが、皆さん開発初期段階からしっかり CI/CD まで考えて構築されてるんだなぁと感心しました(CICD を考えてないプロジェクトも結構あるという認識でした)。セキュリティに関しては Artifact Registry の脆弱性スキャンなどまだまだ新サービスも出てきている状況なので、一度構築したらおしまいではなく、継続的に情報更新して適用していく姿勢が大事ですね。 また、データ活用に関しては私自身あまり知見のない領域ですが、LT1 の仲根さんもAI周りが中心で、今後 Vertex AI 周りも詳しくならないとなぁと感じ、発表を聞いているだけでも勉強になりました。 お二人とも素晴らしい LT ありがとうございました! (執筆者 NTTドコモ/森 健史) クロージング これにて LT パート終了となりました。 生成系 AI のホットな情報から Google Cloud Next Tokyo の有益なセッション共有、社内での利用事例といったバラエティに富んだイベントとなり非常に満足度が高いもの でした! また、冒頭でも記載しましたが徐々にオフラインでの現地参加者が増えており、業務だけでは出会えない DCC グループ内のメンバーとの交流の輪が広がっていることも肌で感じられて嬉しく思っています。 次回のイベント開催報告にもご期待ください! (執筆者 NTTコミュニケーションズ/林 知範)
こんにちは、NTT Com イノベーションセンターのNetwork Analytics for Security(NA4Sec)プロジェクトです。Team NA4Secでは2024年1月25日・26日に開催されたセキュリティカンファレンスJSAC2024に参加しました。この記事では、聴講した中で特に印象深かった講演について紹介します。 また、Team NA4Secでは2件の講演についても登壇しており、その内容は セキュリティカンファレンス「JSAC2024」に参加してきた話(登壇編) で紹介しています。今回参加したJSACとTeam NA4Secの概要についても 登壇編 の冒頭に記載がありますので興味のある方は合わせてご確認いただければと思います。 JSAC2024に参加してみて JSAC2024において印象深かった講演 A Study on Long-Term Trends about Amadey C2 Infrastructure Unveiling TeleBoyi: Chinese APT Group Targeting Critical Infrastructure Worldwide Workshop: Infrastructure Tracking With Mihari Workshop: Investigation Techniques and Practice on External Attack Surface おわりに JSAC2024に参加してみて 今回のJSAC2024も多くの参加者で賑わっており会場は活気に満ち溢れていました。セキュリティ業界で活躍する著名な方を見かけることも度々あり、改めてこのJSACが業界において重要なカンファレンスであることを認識しました。また、JSACは多くのアナリストが現地交流できる場ともなっているようで、特に登壇後の講演者の周りには多くの参加者が集まり情報交換がされていました。 講演・ワークショップではいずれも多数の聴講者が参加しており、新しい情報の数々を食い入るように聞いていました。特に一部のワークショップでは開始前から参加希望者が行列を作っており、開催されるワークショップの期待度の高さが伺えました。 このように数多くの興味深く、貴重な講演・ワークショップが実施されましたが今回はその中から一部を紹介したいと思います。 JSAC2024において印象深かった講演 A Study on Long-Term Trends about Amadey C2 Infrastructure (BlackBerry Japan, Masaki Kasuya氏) 本講演はAmadeyというマルウェアの長期観測(50ヶ月の観測)により得られた知見に関する発表でした。 活性化までに4年ほどかかったこと、Amadey上で使われた各種マルウェアがGitHubやDiscordなどのよく使われるサービス上に設置されていたこと、さらにAmadeyのボットネット上で100種類以上のマルウェアファミリーが拡散されており、一度感染すると複数のマルウェアに同時感染するリスクがある点などが紹介されており、マルウェアの挙動を長期視点で理解できる良い講演でした。特にAmadeyとRedlineが協調して動いている分析は興味深い発表と感じます(資料のp.30前後を参照)。 詳細は、こちらに資料がありますのでご参照ください。 https://jsac.jpcert.or.jp/archive/2024/pdf/JSAC2024_1_1_kasuya_en.pdf Unveiling TeleBoyi: Chinese APT Group Targeting Critical Infrastructure Worldwide (TeamT5, Yi-Chin Chuang氏およびYu-Tung Chang氏) JSAC常連の台湾のセキュリティベンダーTeamT5からは中国のAPTグループTeleBoyiに関する調査内容が共有されました。 TeleBoyiは発足当初、APAC(Asia-Pacific)に標的を絞っていました。発表者によると2023年には日本国内企業に関心を窺わせる攻撃インフラが確認されたとのことです。また、業界で見ると主に通信事業を主とした重要インフラを攻撃しており、一昨年あたりからエネルギー業界にも手を出し始めていることは注目に値します。 攻撃者の使うテクニックには目新しい印象はなく、マルウェアも中国系アクターの利用が多いPlugXなど多岐に渡っているとのことです。TeleBoyiも漏れなく他の中国系APTとの関連について講演で言及されていましたが、一方でTeleBoyiの特徴としてKCPプロトコルを使うユニークなマルウェアの使用も取り挙げられました。 台湾へのAPTの時期や対象は日本へのAPTと共通するケースがあります。台湾のベンダーの調査は日本の有事の際に正確なアトリビューションを行うための貴重なインプットとなりました。 詳細は、こちらに資料がありますのでご参照ください。 https://jsac.jpcert.or.jp/archive/2024/pdf/JSAC2024_1_8_yi-chin_yu-tung_en.pdf Workshop: Infrastructure Tracking With Mihari (Manabu Niseki氏) 本ワークショップは、shodanやCensysなどを利用したモニタリングツールである Mihari の作者である二関氏によるものです。 Mihariのコンセプトや利用方法、Mihariを使った実際のトラッキングの手法について学習することができました。 ワークショップ用のRepositoryが用意されており、参加者はドキュメントを参照しながらMihariのコンセプトを学んだり、実際にMihariを使ったトラッキングを実践することができました。 Shodan/Censysを利用した情報収集、 Nuclei と連携した調査など、ツールの使い方に留まらない充実したコンテンツが用意されていました。 本ワークショップの内容はVSCodeのDev Containersを利用して容易に環境を構築できるようになっているため、誰でも簡単に実習に取り組めます。興味がある方は下記の資料よりぜひ試してみてください。 こちらが当日の資料ですのでご参照ください。 https://ninoseki.github.io/jsac_mihari_workshop/ Workshop: Investigation Techniques and Practice on External Attack Surface (MACNICA, Inc., Kenzo Masamoto氏およびTakeya Yamazaki氏, Yutaka Sejiyama氏, Takeshi Teshigawara氏) 株式会社マクニカからEASM(External Attack Surface Management)についての解説と、実践ワークショップが開催されました。 EASMとはネットワーク機器や公開サーバ等の外部から攻撃される可能性がある領域(Attack Surface)を把握・対処するための取り組みであり、Attack Surfaceを起点としたインシデントの発生が確認されている昨今において、EASMが重要であることとその具体的な手法について解説されました。特に製品別にそのOSのバージョンを推測する方法については興味深く、貴重な情報であると感じました。 また本ワークショップでは、参加者が複数のツール・サービスを実際に使用して、社内の外部公開資産の調査およびリスク評価を実践するパートがあり、特にここでは重要なスキルを習得できたと考えています。それに加えて、外部から特定組織への調査が可能であることを再認識することでEASMの重要性を骨身にしみて理解できたという点においても、本ワークショップは貴重な経験となりました。 おわりに 以上より、この記事ではJSAC2024における特に印象深い講演・ワークショップを紹介しました。 今回のJSAC2024への参加を通して、セキュリティ業界の最前線で活躍するセキュリティアナリストから最新のアクターの動向や重要な解析結果など、参加した今となれば必聴とも思える貴重な情報をインプットできました。 今回は聴講という形での参加となりましたが、次回以降の開催では登壇することを目標としてコミュニティへの還元とセキュリティ業界への貢献ができればと考えています。
こんにちは、NTT Com イノベーションセンターのNetwork Analytics for Security(NA4Sec)プロジェクトです。Team NA4Secでは2024年1月25日・26日に開催されたセキュリティカンファレンスJSAC2024に参加しました。この記事では、聴講した中で特に印象深かった講演について紹介します。 また、Team NA4Secでは2件の講演についても登壇しており、その内容は セキュリティカンファレンス「JSAC2024」に参加してきた話(登壇編) で紹介しています。今回参加したJSACとTeam NA4Secの概要についても 登壇編 の冒頭に記載がありますので興味のある方は合わせてご確認いただければと思います。 JSAC2024に参加してみて JSAC2024において印象深かった講演 A Study on Long-Term Trends about Amadey C2 Infrastructure Unveiling TeleBoyi: Chinese APT Group Targeting Critical Infrastructure Worldwide Workshop: Infrastructure Tracking With Mihari Workshop: Investigation Techniques and Practice on External Attack Surface おわりに JSAC2024に参加してみて 今回のJSAC2024も多くの参加者で賑わっており会場は活気に満ち溢れていました。セキュリティ業界で活躍する著名な方を見かけることも度々あり、改めてこのJSACが業界において重要なカンファレンスであることを認識しました。また、JSACは多くのアナリストが現地交流できる場ともなっているようで、特に登壇後の講演者の周りには多くの参加者が集まり情報交換がされていました。 講演・ワークショップではいずれも多数の聴講者が参加しており、新しい情報の数々を食い入るように聞いていました。特に一部のワークショップでは開始前から参加希望者が行列を作っており、開催されるワークショップの期待度の高さが伺えました。 このように数多くの興味深く、貴重な講演・ワークショップが実施されましたが今回はその中から一部を紹介したいと思います。 JSAC2024において印象深かった講演 A Study on Long-Term Trends about Amadey C2 Infrastructure (BlackBerry Japan, Masaki Kasuya氏) 本講演はAmadeyというマルウェアの長期観測(50ヶ月の観測)により得られた知見に関する発表でした。 活性化までに4年ほどかかったこと、Amadey上で使われた各種マルウェアがGitHubやDiscordなどのよく使われるサービス上に設置されていたこと、さらにAmadeyのボットネット上で100種類以上のマルウェアファミリーが拡散されており、一度感染すると複数のマルウェアに同時感染するリスクがある点などが紹介されており、マルウェアの挙動を長期視点で理解できる良い講演でした。特にAmadeyとRedlineが協調して動いている分析は興味深い発表と感じます(資料のp.30前後を参照)。 詳細は、こちらに資料がありますのでご参照ください。 https://jsac.jpcert.or.jp/archive/2024/pdf/JSAC2024_1_1_kasuya_en.pdf Unveiling TeleBoyi: Chinese APT Group Targeting Critical Infrastructure Worldwide (TeamT5, Yi-Chin Chuang氏およびYu-Tung Chang氏) JSAC常連の台湾のセキュリティベンダーTeamT5からは中国のAPTグループTeleBoyiに関する調査内容が共有されました。 TeleBoyiは発足当初、APAC(Asia-Pacific)に標的を絞っていました。発表者によると2023年には日本国内企業に関心を窺わせる攻撃インフラが確認されたとのことです。また、業界で見ると主に通信事業を主とした重要インフラを攻撃しており、一昨年あたりからエネルギー業界にも手を出し始めていることは注目に値します。 攻撃者の使うテクニックには目新しい印象はなく、マルウェアも中国系アクターの利用が多いPlugXなど多岐に渡っているとのことです。TeleBoyiも漏れなく他の中国系APTとの関連について講演で言及されていましたが、一方でTeleBoyiの特徴としてKCPプロトコルを使うユニークなマルウェアの使用も取り挙げられました。 台湾へのAPTの時期や対象は日本へのAPTと共通するケースがあります。台湾のベンダーの調査は日本の有事の際に正確なアトリビューションを行うための貴重なインプットとなりました。 詳細は、こちらに資料がありますのでご参照ください。 https://jsac.jpcert.or.jp/archive/2024/pdf/JSAC2024_1_8_yi-chin_yu-tung_en.pdf Workshop: Infrastructure Tracking With Mihari (Manabu Niseki氏) 本ワークショップは、shodanやCensysなどを利用したモニタリングツールである Mihari の作者である二関氏によるものです。 Mihariのコンセプトや利用方法、Mihariを使った実際のトラッキングの手法について学習することができました。 ワークショップ用のRepositoryが用意されており、参加者はドキュメントを参照しながらMihariのコンセプトを学んだり、実際にMihariを使ったトラッキングを実践することができました。 Shodan/Censysを利用した情報収集、 Nuclei と連携した調査など、ツールの使い方に留まらない充実したコンテンツが用意されていました。 本ワークショップの内容はVSCodeのDev Containersを利用して容易に環境を構築できるようになっているため、誰でも簡単に実習に取り組めます。興味がある方は下記の資料よりぜひ試してみてください。 こちらが当日の資料ですのでご参照ください。 https://ninoseki.github.io/jsac_mihari_workshop/ Workshop: Investigation Techniques and Practice on External Attack Surface (MACNICA, Inc., Kenzo Masamoto氏およびTakeya Yamazaki氏, Yutaka Sejiyama氏, Takeshi Teshigawara氏) 株式会社マクニカからEASM(External Attack Surface Management)についての解説と、実践ワークショップが開催されました。 EASMとはネットワーク機器や公開サーバ等の外部から攻撃される可能性がある領域(Attack Surface)を把握・対処するための取り組みであり、Attack Surfaceを起点としたインシデントの発生が確認されている昨今において、EASMが重要であることとその具体的な手法について解説されました。特に製品別にそのOSのバージョンを推測する方法については興味深く、貴重な情報であると感じました。 また本ワークショップでは、参加者が複数のツール・サービスを実際に使用して、社内の外部公開資産の調査およびリスク評価を実践するパートがあり、特にここでは重要なスキルを習得できたと考えています。それに加えて、外部から特定組織への調査が可能であることを再認識することでEASMの重要性を骨身にしみて理解できたという点においても、本ワークショップは貴重な経験となりました。 おわりに 以上より、この記事ではJSAC2024における特に印象深い講演・ワークショップを紹介しました。 今回のJSAC2024への参加を通して、セキュリティ業界の最前線で活躍するセキュリティアナリストから最新のアクターの動向や重要な解析結果など、参加した今となれば必聴とも思える貴重な情報をインプットできました。 今回は聴講という形での参加となりましたが、次回以降の開催では登壇することを目標としてコミュニティへの還元とセキュリティ業界への貢献ができればと考えています。
こんにちは、NTT Com イノベーションセンターのNetwork Analytics for Security(NA4Sec)プロジェクトです。 この記事では、2024年1月25日・26日に開催されたセキュリティカンファレンス JSAC2024 にTeam NA4Secから登壇した2件の講演について紹介します。 Operation So-seki: You Are a Threat Actor. As Yet You Have No Name. Analysis of Activities and Tools of Phishing Actors Targeting Japan JSACとは Team NA4Secとは Team NA4SecによるJSAC2024講演 講演1: Operation So-seki: You Are a Threat Actor. As Yet You Have No Name. 講演2: Analysis of Activities and Tools of Phishing Actors Targeting Japan おわりに 興味を持たれた方へ 出張講演承ります 脅威情報を配信しています 仲間を募集しています JSACとは JSACはJPCERT/CCが主催するセキュリティカンファレンスで、 現場のセキュリティアナリストが集い、高度化するサイバー攻撃に対抗するための情報を共有すること を目的に開催されています。 毎年300-450名の定員が事前に埋まって参加申し込みが締め切られるほど関心を集めているイベントで、今年は7回目の開催でした。 本日、予定通り開催です。みなさまのご来場お待ちしております。 #JSAC2024 pic.twitter.com/0KNBqKv2ed — Analysis Center (@jpcert_ac) 2024年1月24日 もともとはJapan Security Analyst Conferenceの略称としてJSAC(ジェイサック)と呼称していましたが、日本に閉じず国際会議としての位置付けを目指すためにJSAC2023からはJSACを正式名称としています。 実際に毎年、海外からも応募・登壇があり、今年も海外から複数のスピーカーが登壇されていました。 特にAPAC(Asia-Pacific)に関係するセキュリティ脅威について他では得られない深い知見の集まるイベントの1つと言えます。 なお、過去開催の様子は JPCERT/CCのブログ でも紹介されています。 一部非公開のものもありますが、各回のWebサイトでは講演資料が公開されており、 JPCERT/CCのYoutube公式チャンネル には講演動画も公開されています。 Team NA4Secとは NA4Secプロジェクトは「NTTはインターネットを安心、安全にする社会的責務がある」を理念として、攻撃インフラの解明、撲滅を目指すプロジェクトです *1 。 NTT Com イノベーションセンターを中心としてNTTセキュリティ・ジャパンやエヌ・エフ・ラボラトリーズ(以下、NFLabs.)からもメンバーが参画し、日夜攻撃インフラを追跡しています。 今回、JSAC2024においてTeam NA4Secが追跡してきた脅威アクターに関する講演が2件採択され、登壇してきました。 なお、NTT ComのJSAC採択は今回が初で、いきなり合計5名での登壇となりました。 / イベント登壇情報✨ \ ​ 国内有数のセキュリティカンファレンス #JSAC2024 にて、 NTT Com、NFLabs.の社員が2つのセッションに登壇✨ ​ ハクティビスト、フィッシング被害について 調査で得られた知見を来場者限定で公開します! ​ 詳細はこちら⬇ https://t.co/zGuh2fOImO pic.twitter.com/6Iz3ta9BSH — NTTドコモビジネス (@NTTCom_online) 2024年1月23日 Team NA4SecによるJSAC2024講演 講演1: Operation So-seki: You Are a Threat Actor. As Yet You Have No Name. 1件目の講演は、親ロシア派ハクティビストを長期追跡した内容でした。 DDoS攻撃を用いるハクティビストという非常にセンシティブな話題を扱うため、多くの情報を参加者限定としましたが、選考委員や運営の方々にもご理解いただき、発表の機会を得ることができました。 昨年来、DDoS攻撃による被害は日本でもたびたびメディアに取り上げられるなど、関心が高まっていたこともあってか、うなずきながら話に耳を傾けてくださる参加者が何人も壇上から見えました。 「複数の観点からの分析や考察がとてもわかりやすく解説されていて非常に良かった」といった声を得ることもでき、このタイミングでこの話を持って来られてよかったです。 講演の中では昨今アクティブサイバーディフェンスの議論などでも注目を集めているフロー情報の活用についても触れ、その有効性や限界についてセキュリティ実務者の視点から共有しました。 前述の理由からほとんどの情報は伏せられていますが、JSAC2024の公式サイトに講演資料( 日本語版 ・ 英語版 )が掲載されていますので、気になる方はダウンロードしてみてください。 講演1登壇者の皆川(左: @strinsert1Na )、 神田(中央: @ashy0x41 )、 鮫嶋(右: @islairand ) 講演2: Analysis of Activities and Tools of Phishing Actors Targeting Japan 2件目の講演は、日本を狙ったフィッシングに関して、フィッシングアクター同士が交流する「フィッシングコミュニティ」やフィッシングに使われるツール(フィッシングキット)を調査した内容でした。 日本を狙ったフィッシングを取り巻くコミュニティがどのように形成され分業化されているのか、その実態を明らかにするとともに、フィッシングキットの挙動について実例を挙げて紹介しました。 参加者からは「フィッシングコミュニティやフィッシングアクターの活動状況についての話は大変興味深い」「フィッシングキットの分析内容の共有やIoCの活用例についても解りやすく説明されていた」「IoCの活用方法としてそういうツールがあるのか」などポジティブな反応を得ることができました。 講演内で取り上げたフィッシングキットに関するIoCについては講演資料( 日本語版 ・ 英語版 )内のAppendixにも記載していますので、もし参加ができなかった方は是非ダウンロードしてみてください。 講演2登壇者の益本(左: @masaomi346 )、 坪井(右: @ytsuboi0322 ) おわりに 多くの優秀なセキュリティアナリストが発表するカンファレンスに登壇し、コミュニティに貢献する機会を得たことは、登壇したメンバー各人だけでなくチームにとっても大きな出来事でした。 実を言えば昨年JSAC2023が開催されていた頃はプロジェクトの本務メンバーが1名しかいない状態でした。 そこから縁にも恵まれ、チームの活動を拡大・加速させることができ、今回の結果につながりました。 実際、今回の登壇者5名のうち3名はこの1年で新たにチームに加わったメンバーです(もっと言えば1名は今年度入社の新卒社員です)。 この短期間で一定の成果を上げられたことは、チームビルディングや環境・風土作りの方向性がチームメンバーや業務の性質にマッチしている表れと考えています。 今後も引き続き、セキュリティアナリストのスキルの底上げに貢献し、セキュリティ業界を盛り上げていければと考えています。 興味を持たれた方へ 出張講演承ります 今回の講演(特に1件目のハクティビスト)は、情報の性質上、攻撃者の詳細に関わる情報は公開していません *2 。 他方、サイバー攻撃に係る情報を(非公開に)共有することは今後の被害の未然防止や被害低減につながる価値があると考えています *3 。 出張講演なども前向きに検討しますので、興味のある方はNA4Secプロジェクトまでお気軽にご相談ください。 脅威情報を配信しています NA4Secプロジェクトでは兄弟プロジェクトであるMetemcyber *4 と連携してマルウェアやフィッシングに関する脅威情報を配信しています( @Metemcyber ) *5 。 情報配信に関する経緯や思いはブログ記事を公開していますので、興味のある方はそちらもぜひご覧ください。 サイバー脅威インテリジェンス(CTI)配信はじめました 日本を狙ったフィッシングサイトの情報配信はじめました 仲間を募集しています NA4Sec/Metemcyberプロジェクトではそれぞれ一緒に働く仲間を募集しています。 「脅威インテリジェンス」をキーワードに活躍の場を探している方、プロジェクトの理念に共感していただける方のご応募をお待ちしています。 Threat Intelligence Analyst / 脅威インテリジェンスアナリスト (NA4Sec) Threat Intelligence Engineer / 脅威インテリジェンスエンジニア (Metemcyber) NFLabs. ではセキュリティエンジニア/セキュリティインストラクター/マネージャーを募集中です。 Xやエンジニアブログでも情報を発信していますのでこちらも合わせてご覧ください。 NFLabs. RECRUIT NFLabs. 公式Xアカウント(@NFLaboratories) NFLabs. エンジニアブログ *1 : 社内では親しみを込めて「NA4Sec(なよせ)」と呼んでいます *2 : DDoS攻撃に関する情報共有の問題については、JPCERT/CCのブログ記事「 注意喚起や情報共有活動における受信者側の「コスト」の問題について ー情報発信がアリバイや成果目的の自己目的化した行為にならないためにー 」がおすすめです。 *3 : このあたりはNISCから公開されている「 サイバー攻撃被害に係る情報の共有・公表ガイダンス 」にて論点が整理されています。 *4 : 最近のMetemcyberの活動については、「 ソフトウェア開発におけるサプライチェーンセキュリティの実践 」をご覧ください。 *5 : 最近では TweetFeed にもデータソースとして取り込まれるようになったので、以前よりも扱いやすくなりました。
こんにちは、NTT Com イノベーションセンターのNetwork Analytics for Security(NA4Sec)プロジェクトです。 この記事では、2024年1月25日・26日に開催されたセキュリティカンファレンス JSAC2024 にTeam NA4Secから登壇した2件の講演について紹介します。 Operation So-seki: You Are a Threat Actor. As Yet You Have No Name. Analysis of Activities and Tools of Phishing Actors Targeting Japan JSACとは Team NA4Secとは Team NA4SecによるJSAC2024講演 講演1: Operation So-seki: You Are a Threat Actor. As Yet You Have No Name. 講演2: Analysis of Activities and Tools of Phishing Actors Targeting Japan おわりに 興味を持たれた方へ 出張講演承ります 脅威情報を配信しています 仲間を募集しています JSACとは JSACはJPCERT/CCが主催するセキュリティカンファレンスで、 現場のセキュリティアナリストが集い、高度化するサイバー攻撃に対抗するための情報を共有すること を目的に開催されています。 毎年300-450名の定員が事前に埋まって参加申し込みが締め切られるほど関心を集めているイベントで、今年は7回目の開催でした。 本日、予定通り開催です。みなさまのご来場お待ちしております。 #JSAC2024 pic.twitter.com/0KNBqKv2ed — Analysis Center (@jpcert_ac) 2024年1月24日 もともとはJapan Security Analyst Conferenceの略称としてJSAC(ジェイサック)と呼称していましたが、日本に閉じず国際会議としての位置付けを目指すためにJSAC2023からはJSACを正式名称としています。 実際に毎年、海外からも応募・登壇があり、今年も海外から複数のスピーカーが登壇されていました。 特にAPAC(Asia-Pacific)に関係するセキュリティ脅威について他では得られない深い知見の集まるイベントの1つと言えます。 なお、過去開催の様子は JPCERT/CCのブログ でも紹介されています。 一部非公開のものもありますが、各回のWebサイトでは講演資料が公開されており、 JPCERT/CCのYoutube公式チャンネル には講演動画も公開されています。 Team NA4Secとは NA4Secプロジェクトは「NTTはインターネットを安心、安全にする社会的責務がある」を理念として、攻撃インフラの解明、撲滅を目指すプロジェクトです *1 。 NTT Com イノベーションセンターを中心としてNTTセキュリティ・ジャパンやエヌ・エフ・ラボラトリーズ(以下、NFLabs.)からもメンバーが参画し、日夜攻撃インフラを追跡しています。 今回、JSAC2024においてTeam NA4Secが追跡してきた脅威アクターに関する講演が2件採択され、登壇してきました。 なお、NTT ComのJSAC採択は今回が初で、いきなり合計5名での登壇となりました。 / イベント登壇情報✨ \ ​ 国内有数のセキュリティカンファレンス #JSAC2024 にて、 NTT Com、NFLabs.の社員が2つのセッションに登壇✨ ​ ハクティビスト、フィッシング被害について 調査で得られた知見を来場者限定で公開します! ​ 詳細はこちら⬇ https://t.co/zGuh2fOImO pic.twitter.com/6Iz3ta9BSH — ドコモビジネス|NTTコミュニケーションズ (@NTTCom_online) 2024年1月23日 Team NA4SecによるJSAC2024講演 講演1: Operation So-seki: You Are a Threat Actor. As Yet You Have No Name. 1件目の講演は、親ロシア派ハクティビストを長期追跡した内容でした。 DDoS攻撃を用いるハクティビストという非常にセンシティブな話題を扱うため、多くの情報を参加者限定としましたが、選考委員や運営の方々にもご理解いただき、発表の機会を得ることができました。 昨年来、DDoS攻撃による被害は日本でもたびたびメディアに取り上げられるなど、関心が高まっていたこともあってか、うなずきながら話に耳を傾けてくださる参加者が何人も壇上から見えました。 「複数の観点からの分析や考察がとてもわかりやすく解説されていて非常に良かった」といった声を得ることもでき、このタイミングでこの話を持って来られてよかったです。 講演の中では昨今アクティブサイバーディフェンスの議論などでも注目を集めているフロー情報の活用についても触れ、その有効性や限界についてセキュリティ実務者の視点から共有しました。 前述の理由からほとんどの情報は伏せられていますが、JSAC2024の公式サイトに講演資料( 日本語版 ・ 英語版 )が掲載されていますので、気になる方はダウンロードしてみてください。 講演1登壇者の皆川(左: @strinsert1Na )、 神田(中央: @ashy0x41 )、 鮫嶋(右: @islairand ) 講演2: Analysis of Activities and Tools of Phishing Actors Targeting Japan 2件目の講演は、日本を狙ったフィッシングに関して、フィッシングアクター同士が交流する「フィッシングコミュニティ」やフィッシングに使われるツール(フィッシングキット)を調査した内容でした。 日本を狙ったフィッシングを取り巻くコミュニティがどのように形成され分業化されているのか、その実態を明らかにするとともに、フィッシングキットの挙動について実例を挙げて紹介しました。 参加者からは「フィッシングコミュニティやフィッシングアクターの活動状況についての話は大変興味深い」「フィッシングキットの分析内容の共有やIoCの活用例についても解りやすく説明されていた」「IoCの活用方法としてそういうツールがあるのか」などポジティブな反応を得ることができました。 講演内で取り上げたフィッシングキットに関するIoCについては講演資料( 日本語版 ・ 英語版 )内のAppendixにも記載していますので、もし参加ができなかった方は是非ダウンロードしてみてください。 講演2登壇者の益本(左: @masaomi346 )、 坪井(右: @ytsuboi0322 ) おわりに 多くの優秀なセキュリティアナリストが発表するカンファレンスに登壇し、コミュニティに貢献する機会を得たことは、登壇したメンバー各人だけでなくチームにとっても大きな出来事でした。 実を言えば昨年JSAC2023が開催されていた頃はプロジェクトの本務メンバーが1名しかいない状態でした。 そこから縁にも恵まれ、チームの活動を拡大・加速させることができ、今回の結果につながりました。 実際、今回の登壇者5名のうち3名はこの1年で新たにチームに加わったメンバーです(もっと言えば1名は今年度入社の新卒社員です)。 この短期間で一定の成果を上げられたことは、チームビルディングや環境・風土作りの方向性がチームメンバーや業務の性質にマッチしている表れと考えています。 今後も引き続き、セキュリティアナリストのスキルの底上げに貢献し、セキュリティ業界を盛り上げていければと考えています。 興味を持たれた方へ 出張講演承ります 今回の講演(特に1件目のハクティビスト)は、情報の性質上、攻撃者の詳細に関わる情報は公開していません *2 。 他方、サイバー攻撃に係る情報を(非公開に)共有することは今後の被害の未然防止や被害低減につながる価値があると考えています *3 。 出張講演なども前向きに検討しますので、興味のある方はNA4Secプロジェクトまでお気軽にご相談ください。 脅威情報を配信しています NA4Secプロジェクトでは兄弟プロジェクトであるMetemcyber *4 と連携してマルウェアやフィッシングに関する脅威情報を配信しています( @Metemcyber ) *5 。 情報配信に関する経緯や思いはブログ記事を公開していますので、興味のある方はそちらもぜひご覧ください。 サイバー脅威インテリジェンス(CTI)配信はじめました 日本を狙ったフィッシングサイトの情報配信はじめました 仲間を募集しています NA4Sec/Metemcyberプロジェクトではそれぞれ一緒に働く仲間を募集しています。 「脅威インテリジェンス」をキーワードに活躍の場を探している方、プロジェクトの理念に共感していただける方のご応募をお待ちしています。 Threat Intelligence Analyst / 脅威インテリジェンスアナリスト (NA4Sec) Threat Intelligence Engineer / 脅威インテリジェンスエンジニア (Metemcyber) NFLabs. ではセキュリティエンジニア/セキュリティインストラクター/マネージャーを募集中です。 Xやエンジニアブログでも情報を発信していますのでこちらも合わせてご覧ください。 NFLabs. RECRUIT NFLabs. 公式Xアカウント(@NFLaboratories) NFLabs. エンジニアブログ *1 : 社内では親しみを込めて「NA4Sec(なよせ)」と呼んでいます *2 : DDoS攻撃に関する情報共有の問題については、JPCERT/CCのブログ記事「 注意喚起や情報共有活動における受信者側の「コスト」の問題について ー情報発信がアリバイや成果目的の自己目的化した行為にならないためにー 」がおすすめです。 *3 : このあたりはNISCから公開されている「 サイバー攻撃被害に係る情報の共有・公表ガイダンス 」にて論点が整理されています。 *4 : 最近のMetemcyberの活動については、「 ソフトウェア開発におけるサプライチェーンセキュリティの実践 」をご覧ください。 *5 : 最近では TweetFeed にもデータソースとして取り込まれるようになったので、以前よりも扱いやすくなりました。
目次 目次 はじめに NeWork とは リリース頻度変更の背景 それまでの運用 課題 実現方法 解説 日次でワークフローが起動するようにする main ブランチの HEAD にタグが付与されていなければ付与する develop に差分があれば main へのマージを自動で行う 細かな工夫点 main の内容を develop に自動で取り込む 祝日はリリースしないようにする 自動リリース・自動 develop → main マージの制御 Slack にリリース結果を通知する stg 環境に変更内容を通知する その他の考慮 上司への事前説明の省略 スプリントレビュー前のリリース リリースノート 品質面 リリース頻度を変えてみて おわりに はじめに こんにちは、NeWork 開発チームの藤野です。普段はオンラインワークスペースサービス NeWork のエンジニアリングマネジメントをしています。 この記事では、それまで毎週新バージョンのリリースをしていた NeWork Web 版のリリース頻度を(最大で)毎日に変更した事例を紹介します。 NeWork とは NeWork はコロナ禍で誕生したオンラインワークスペースサービスです。 従来の Web 会議ツールとは異なり、手軽に話しかけられることを重視したサービスになっており、Web・デスクトップアプリ・モバイルアプリで提供されています。 サービスの基盤は GC(Google Cloud) 上で提供しており、フロントエンドは Next.js 、バックエンドは Node.js+Express を採用しています。 音声基盤は NTT Com の別チームが開発している SkyWay を利用しています。 リリース頻度変更の背景 それまでの運用 NeWork では 2021 年 7 月以降(ほぼ)毎週のリリースを実現し、大きなインパクトのある機能だけでなく、細かな改善やバグ修正を継続して実施してきました。 具体的には git flow ライクなブランチ運用をしながら毎週リリース作業をしていました。 develop から feature ブランチをきって開発し、完了したら develop にマージ。develop にマージされると自動で stg 環境にデプロイ 毎週水曜のリリース日 朝 : develop ブランチから main ブランチにマージ 日中 : NeWork チーム全員で stg 環境を 普段利用 し、致命的なバグがないことを普段利用の範囲で確認 夕方 : リリースタグを付与して prod 環境に自動デプロイし、動作確認 重大なバグがあれば、main ブランチから hotfix ブランチをきって修正 上長に状況を説明し、許可を得た上でリリース 課題 しかし 2 年以上この運用を続けてきていて以下の課題があると感じていました。 お客さまからのフィードバックに即応してもすぐリリースできない バグがあっても重大なものじゃなければ、次のリリースまで待つ必要がある リリース直前にバタつくことがある 来週まで延期したくないので、どうしても今週リリースしておきたい → 水曜の午後まで develop ブランチから main ブランチにマージできないこともあった この駆け込み乗車によってバグがあるままリリースしてしまう可能性があった 複数のスクラムチームのスケジュールに縛りを与える スプリントレビューを通過したものだけリリースになるので、必然とスプリントの終了日が固定され重複する → 複数チームのステークホルダーは全部のイベントに参加できなくなる リリース作業の一部は手動で面倒 & ミスする可能性がある develop ブランチから main ブランチへのマージを忘れたことがある (起きたことはないが) 付与するタグのフォーマットを間違える可能性がある それ以外でも、DevOps Research and Assessment が提唱する Four Keys のうちの「デプロイの頻度」「変更のリードタイム」を改善すべきと考えていました。 実現方法 上述の背景を考慮して、2023 年 9 月から以下を毎日完全自動で実施する運用に変更しました。 平日の夕方に、前日の夕方以降で develop ブランチにマージされたすべての変更を main ブランチに自動でマージする main ブランチへのマージをトリガーに stg 環境へ自動デプロイ NeWork チームは基本的に stg 環境を普段から利用しているので、普段使いの範囲の中で致命的なバグがないか丸一日確認できる 翌日の夕方、main ブランチにリリースタグを自動で付与 リリースタグをトリガーに prod 環境へ自動デプロイ 具体的には日時で起動する以下のようなワークフローを GitHub Actions で用意して実現しました。 name : daily-release on : # 平日 18:00 JST schedule : - cron : "0 9 * * 1-5" run-name : daily-release/${{ github.event.schedule }} # release タグが JST ベースの日付になるようにタイムゾーンを設定 env : TZ : "Asia/Tokyo" jobs : daily-release : runs-on : ubuntu-latest steps : - name : Checkout uses : actions/checkout@v3 with : ref : main # 全部 fetch しないと rev-list が動作しない fetch-depth : 0 # token を指定することで protected branch の設定を bypass できるようにする token : ${{ secrets.GH_TOKEN }} # 最新のタグと最新のコミットを取得 - name : get latest tag and commit id : get_latest_tag_and_commit run : | echo latest_tag_commit=$(git rev-list --tags --max-count=1) >> $GITHUB_OUTPUT echo latest_commit=$(git rev-parse HEAD) >> $GITHUB_OUTPUT - uses : actions/setup-node@v3 with : node-version : "20" - run : npm install @holiday-jp/holiday_jp - uses : actions/github-script@v3 id : is_holiday with : script : | const holiday_jp = require(`${process.env.GITHUB_WORKSPACE}/node_modules/@holiday-jp/holiday_jp`) core.setOutput('holiday', holiday_jp.isHoliday(new Date())); # Release tag の付与 - name : Create release tag id : create_release_tag if : | steps.get_latest_tag_and_commit.outputs.latest_tag_commit != steps.get_latest_tag_and_commit.outputs.latest_commit && vars.DAILY_RELEASE == 'true' && steps.is_holiday.outputs.holiday != 'true' env : # token を指定することで release 後の workflow が起動するようにする # デフォルトのリポジトリが所有するトークンでは他のワークフローがトリガーされないのは # GitHub Actionsの安全性のための仕様 GH_TOKEN : ${{ secrets.GH_TOKEN }} run : | release_tag=`deployment/scripts/get_release_version.sh` latest_tag=$(gh release list -L 1 | awk '{print $3}' ) gh release create $release_tag --title $release_tag --target main --generate-notes --notes-start-tag $latest_tag echo released_version_url=`gh release view --json url -q .url` >> $GITHUB_OUTPUT - name : Create pull request if : vars.DAILY_MERGE == 'true' env : GH_TOKEN : ${{ secrets.GITHUB_TOKEN }} id : create_pull_request run : | release_tag=stg.`deployment/scripts/get_release_version.sh day "+%Y%m%d%H%M" ` echo release_tag=$release_tag >> $GITHUB_OUTPUT latest_tag=$(gh release list -L 1 | awk '{print $3}' ) release_note=`gh api /repos/${{ github.repository }}/releases/generate-notes -f tag_name=dummy_tag -f target_commitish=develop -f previous_tag_name=${latest_tag} --jq .body | grep -Ev "dummy_tag$" | sed -e :a -e '/^\n*$/{$d;N;ba}' ` # || true をいれて失敗しても stderr.txt に書き込みがされるようにしている gh pr create --title "【定期実行】 $release_tag" --body "${release_note}" --base main --head develop -l 'auto merge' > /tmp/stdout.txt 2> /tmp/stderr.txt || true echo pull_request_uri=`cat /tmp/stdout.txt` >> $GITHUB_OUTPUT rm -f /tmp/stdout.txt continue-on-error : true - name : merge remote/main into develop if : ${{ steps.create_pull_request.outputs.pull_request_uri != '' }} run : | git config --local user.email "github-actions[bot]@users.noreply.github.com" git config --local user.name "github-actions[bot]" git checkout develop git merge main - name : push changes to remote repository if : ${{ steps.create_pull_request.outputs.pull_request_uri != '' }} uses : ad-m/github-push-action@master with : # bypass できるユーザで実行することが重要 github_token : ${{ secrets.GH_TOKEN }} branch : develop - name : Merge pull request if : ${{ steps.create_pull_request.outputs.pull_request_uri != '' }} id : merge_pull_request env : # token を指定することで release 後の workflow が起動するようにする # デフォルトのリポジトリが所有するトークンでは他のワークフローがトリガーされないのは # GitHub Actionsの安全性のための仕様 GH_TOKEN : ${{ secrets.GH_TOKEN }} # push が反映されるように5秒待ってからマージ run : | sleep 5s gh pr merge ${{ steps.create_pull_request.outputs.pull_request_uri }} --merge --subject "Merge to main for ${{ steps.create_pull_request.outputs.release_tag }}" --body "Merge to main for ${{ steps.create_pull_request.outputs.release_tag }}" - name : Get PR error if : ${{ steps.create_pull_request.outputs.pull_request_uri == '' }} id : create_pull_request_error run : | echo error=$(cat /tmp/stderr.txt) >> $GITHUB_OUTPUT rm -f /tmp/stdout.txt /tmp/stderr.txt - name : Send Slack Notification uses : 8398a7/action-slack@v3 if : always() with : status : custom fields : job,took custom_payload : | { attachments : [ { color : '${{ job.status }}' === 'success' ? 'good' : '${{ job.status }}' === 'failure' ? 'danger' : 'warning' , text : ` Github Daily Release result : $ {{ job.status }} in $ { process.env.AS_TOOK } `, } , { color : '${{ steps.create_release_tag.conclusion }}' === 'success' ? 'good' : '${{ job.status }}' === 'failure' ? 'danger' : 'warning' , text : ` Release : $ {{ steps.create_release_tag.conclusion }} $ {{ steps.create_release_tag.outputs.released_version_url }} `, } , { color : '${{ steps.create_pull_request.outputs.pull_request_uri }}' === '' ? 'danger' : 'good' , text : ` PR Creation : $ {{ steps.create_pull_request.outputs.pull_request_uri }} $ {{ steps.create_pull_request_error.outputs.error }} `, } , { color : '${{ steps.merge_pull_request.conclusion }}' === 'success' ? 'good' : '${{ job.status }}' === 'failure' ? 'danger' : 'warning' , text : ` PR Merge : $ {{ steps.merge_pull_request.conclusion }} `, } ] } env : SLACK_WEBHOOK_URL : ${{ vars.SLACK_WEBHOOK_URL }} 解説 日次でワークフローが起動するようにする GitHub Actions のトリガーを schedule を使ってワークフローを自動起動するようにしています。 on : # 平日 18:00 JST schedule : - cron : "0 9 * * 1-5" main ブランチの HEAD にタグが付与されていなければ付与する 以下の手順でリリースタグを付与しています。 main ブランチ HEAD のコミットハッシュと最新のリリースタグがふられているコミットハッシュを取得 上述の値が合致していない = リリースできるものがあると判断してリリースタグを付与 リリースタグの付与をトリガーに別のワークフローで prod にデプロイが走るようにしてあります リリースタグの付与を secrets.GITHUB_TOKEN でやってしまうと別ワークフローの起動をトリガーできないので、個人のトークンを利用しています リリースタグの計算はスクリプトを用意して自動計算するようにしています # 最新のタグと最新のコミットを取得 - name : get latest tag and commit id : get_latest_tag_and_commit run : | echo latest_tag_commit=$(git rev-list --tags --max-count=1) >> $GITHUB_OUTPUT echo latest_commit=$(git rev-parse HEAD) >> $GITHUB_OUTPUT # Release tag の付与 - name : Create release tag id : create_release_tag if : | steps.get_latest_tag_and_commit.outputs.latest_tag_commit != steps.get_latest_tag_and_commit.outputs.latest_commit env : # token を指定することで release 後の workflow が起動するようにする # デフォルトのリポジトリが所有するトークンでは他のワークフローがトリガーされないのは # GitHub Actionsの安全性のための仕様 GH_TOKEN : ${{ secrets.GH_TOKEN }} run : | release_tag=`deployment/scripts/get_release_version.sh` latest_tag=$(gh release list -L 1 | awk '{print $3}' ) gh release create $release_tag --title $release_tag --target main --generate-notes --notes-start-tag $latest_tag 余談ではありますが、 .github/release.yml と PR への自動タグ付与ワークフローを利用して、それっぽいリリースノートを自動生成するようにもしています。 develop に差分があれば main へのマージを自動で行う develop ブランチから main ブランチへの Pull Request 作成 作成時のタイトルはリリースのときにも使ったタグ計算ロジックを応用しています Pull Request の description もリリースノートを自動算出するロジックを応用しています 作成がエラーにならなければ (基本的にはマージできる差分があるとき) マージする main ブランチへのマージをトリガーに別のワークフローで stg にデプロイが走るようにしてあります マージを secrets.GITHUB_TOKEN でやってしまうと別ワークフローの起動をトリガーできないので、個人のトークンを利用しています - name : Create pull request env : GH_TOKEN : ${{ secrets.GITHUB_TOKEN }} id : create_pull_request run : | release_tag=stg.`deployment/scripts/get_release_version.sh day "+%Y%m%d%H%M" ` echo release_tag=$release_tag >> $GITHUB_OUTPUT latest_tag=$(gh release list -L 1 | awk '{print $3}' ) release_note=`gh api /repos/${{ github.repository }}/releases/generate-notes -f tag_name=dummy_tag -f target_commitish=develop -f previous_tag_name=${latest_tag} --jq .body | grep -Ev "dummy_tag$" | sed -e :a -e '/^\n*$/{$d;N;ba}' ` # || true をいれて失敗しても stderr.txt に書き込みがされるようにしている gh pr create --title "【定期実行】 $release_tag" --body "${release_note}" --base main --head develop -l 'auto merge' > /tmp/stdout.txt 2> /tmp/stderr.txt || true echo pull_request_uri=`cat /tmp/stdout.txt` >> $GITHUB_OUTPUT rm -f /tmp/stdout.txt continue-on-error : true ...(中略)... - name : Merge pull request if : ${{ steps.create_pull_request.outputs.pull_request_uri != '' }} id : merge_pull_request env : # token を指定することで release 後の workflow が起動するようにする # デフォルトのリポジトリが所有するトークンでは他のワークフローがトリガーされないのは # GitHub Actionsの安全性のための仕様 GH_TOKEN : ${{ secrets.GH_TOKEN }} run : | gh pr merge ${{ steps.create_pull_request.outputs.pull_request_uri }} --merge --subject "Merge to main for ${{ steps.create_pull_request.outputs.release_tag }}" --body "Merge to main for ${{ steps.create_pull_request.outputs.release_tag }}" これによって、こんな Pull Request の作成・マージまで自動で行っています。 細かな工夫点 main の内容を develop に自動で取り込む main ブランチに直接行った hotfix やその他のコミットを develop に取り込むのも自動化しています。 そのために専用のステップを設けてマージ・プッシュをしています。 - name : merge remote/main into develop if : ${{ steps.create_pull_request.outputs.pull_request_uri != '' }} run : | git config --local user.email "github-actions[bot]@users.noreply.github.com" git config --local user.name "github-actions[bot]" git checkout develop git merge main - name : push changes to remote repository if : ${{ steps.create_pull_request.outputs.pull_request_uri != '' }} uses : ad-m/github-push-action@master with : # bypass できるユーザで実行することが重要 github_token : ${{ secrets.GH_TOKEN }} branch : develop 余談ではありますが、我々の運用では develop ブランチは基本的に Pull Request なしでコミットできない設定にしてあるので、予めそのルールを迂回できるユーザを設定して、そのユーザのトークンを利用してプッシュするようにしています。 祝日はリリースしないようにする この運用のひとつの肝は、自動テストに頼りきらず(音声系の機能もあるため自動テスト一本に頼れるほど充実していないのが原因ですが)、stg 環境をチーム全体で丸一日にわたって通常利用したうえでリリースするところにあります。 なので、単純に月曜から金曜まで毎日実行してしまうと、祝日はまったく確認しないままリリースすることになってしまいます。 この問題に対応するため、以下のステップで祝日かどうかを判定しています。 - uses : actions/setup-node@v3 with : node-version : "20" - run : npm install @holiday-jp/holiday_jp - uses : actions/github-script@v3 id : is_holiday with : script : | const holiday_jp = require(`${process.env.GITHUB_WORKSPACE}/node_modules/@holiday-jp/holiday_jp`) core.setOutput('holiday', holiday_jp.isHoliday(new Date())); # Release tag の付与 - name : Create release tag id : create_release_tag if : | steps.is_holiday.outputs.holiday != 'true' 自動リリース・自動 develop → main マージの制御 全部自動で動くのは基本とても良いのですが、リリースやマージを制御したいことも稀にあるかもしれません。 stg 環境で事前に確認していたら大きなバグ見つけちゃった stg 環境での確認をもっと長めにしたい 働いている人が少ない状態ではリリースしたくない (年末年始とか) この要望に対して、ワークフロー自体を無効化してもいいのですが、各機能だけ個別に制御できるようにしています。(今のところ一度も活躍してないですが) 具体的には、 GitHub Actions 変数 を利用してこの値を変更するだけで制御可能にしています。 Slack にリリース結果を通知する 全部自動だと予期せぬエラーに気づけず大変です。 なので、以下のアクションがそれぞれうまくいったかどうかを Slack で通知するようにしています。 - name : Send Slack Notification uses : 8398a7/action-slack@v3 if : always() with : status : custom fields : job,took custom_payload : | { attachments : [ { color : '${{ job.status }}' === 'success' ? 'good' : '${{ job.status }}' === 'failure' ? 'danger' : 'warning' , text : ` Github Daily Release result : $ {{ job.status }} in $ { process.env.AS_TOOK } `, } , { color : '${{ steps.create_release_tag.conclusion }}' === 'success' ? 'good' : '${{ job.status }}' === 'failure' ? 'danger' : 'warning' , text : ` Release : $ {{ steps.create_release_tag.conclusion }} $ {{ steps.create_release_tag.outputs.released_version_url }} `, } , { color : '${{ steps.create_pull_request.outputs.pull_request_uri }}' === '' ? 'danger' : 'good' , text : ` PR Creation : $ {{ steps.create_pull_request.outputs.pull_request_uri }} $ {{ steps.create_pull_request_error.outputs.error }} `, } , { color : '${{ steps.merge_pull_request.conclusion }}' === 'success' ? 'good' : '${{ job.status }}' === 'failure' ? 'danger' : 'warning' , text : ` PR Merge : $ {{ steps.merge_pull_request.conclusion }} `, } ] } env : SLACK_WEBHOOK_URL : ${{ vars.SLACK_WEBHOOK_URL }} これによって、こんな風に失敗した理由や作成されたリリースタグ・PR の情報を通知してくれます。 stg 環境に変更内容を通知する 上述のワークフロー外でやっているので詳しく説明できないですが、我々が開発・普段利用している NeWork の機能のひとつであるワークスペース全体へのメッセージ機能を利用して変更内容を通知しています。 ここでも GitHub のリリースノート作成機能を利用して通知内容を作成しています。 これによって NeWork チームのメンバーが今日この後リリースされる内容を把握し、必要に応じて重点的な確認やバグ出しをしてくれることを狙って実施しています。 その他の考慮 上記の運用への変更を検討時、以下のような点についても考慮したうえで実行にうつしました。 上司への事前説明の省略 それまでは、週に 1 回のリリースの前に内容の説明と実際のチケットや PR のリンクを共有して上司の許可を得た上でリリースという手順を踏んでいました。 頻度があがるとこれは難しくなったのですが、上司に相談したところ、運用が改善するならぜひやっていこうとのお言葉をいただき、内容の共有は週に一度かつ事後で良い(=リリースの判断に関して権限委譲して頂いた?)となりました。 スプリントレビュー前のリリース NeWork は開発をスクラムで進めていました。それまでは、リリース日前日にスプリントレビューがあったので、その場でリリース可否を決めていました。 1 リリース頻度があがることでこれまでと同様のメンバーのレビューがはいったうえでリリース可否を決めるという運用はできなくなりました。 ただ、スプリントプランニングにて実装する内容は事前に合意していること、リリース前に一日 stg 環境で確認ができること、リリース後に問題があってもすぐ直す or 切り戻しすればいいという意識あわせをチーム全体で行い、このフロー自体をなくしました。 また、そもそもスプリントレビューしないでリリースしていいのという疑問もチーム内であがりましたが、NTT Com の技術顧問でもある吉羽さんの情報も参考に、そのような縛りがないことを確認したうえですすめました。 www.ryuzee.com リリースノート NeWork Web 版は  リリースノート を公開しています。 それまではリリース毎にプロモーションチームがユーザに伝わりやすい言葉でリリースノートを作り、リリースと同時に公開していました。 これもリリース頻度があがることで同じ運用を維持することが難しいのは明らかでした。 これについては、リリースノートを後追いで出す運用にすることで対処しました。 一方でプロモーションの理由でリリースノートや サービスサイト ・ ご利用ガイド 等とタイミングを揃えたりものについては開発のロードマップレベルであわせてリリースすることにしています。 昨年から feature flag も活用して、重要な機能のロールアウトとデプロイを分離できているのも一役買っています。 品質面 これまでは長いと一週間弱 stg 環境に将来リリースする機能が先行してデプロイされており、その中でバグが見つかりリリースまでの直して対処したこともありました。 リリース頻度があがることでこの確認期間が短くなり、品質が悪化するのではとの声もありましたが、逆に駆け込み乗車を撲滅し、必ず確認期間が一定以上設けられるようになること・確認すべき対象が常にアナウンスされることからほぼ影響がないと判断しました。 リリース頻度を変えてみて 2023 年の 9 月からこの運用をしています。 元々課題に感じていた点・懸念していた点・それ以外の影響について振り返ってみます。 課題 1 : ユーザからのフィードバックや軽微なバグに即応できない → 最短で翌日にはリリースできるようになって対応速度は確実に向上しました。 課題 2 : リリース直前のバタつき → リリース頻度があがることで無理やりリリースにねじ込むことがほぼ 0 になりました。 課題 3 : スクラムチームのスケジュールの縛り → これについては、スケジュール変更がちょっと面倒なこともあり、まだ実行に移せていません。次回チーム構成を変更する際に改めて意識していきたいと考えています。 課題 4 : リリース作業の一部が手動 → 完全に自動化され快適になりました。 考慮 1 : 品質面の劣化 → 今のところ以前の運用であれば防げたはずのバグの流出は一切なく、むしろ駆け込み乗車撲滅の恩恵が大きいと感じています。現在は並行して E2E テストの充実化も進めているので、この懸念はさらに小さくなっていっています。 副産物 : チームの残業時間が他チームと比較して目立って減りました。(この施策だけの影響ではないかもしれませんが、) リリース作業の完全自動化の恩恵と思っています。 基本的に良い影響しか出ていないので、今後も継続していこうと思っています。 おわりに この記事では、リリース頻度を毎週から毎日単位に変更した事例について紹介させていただきました。 ただ、毎日リリースできればゴールではないので、引き続き自動テストの範囲拡充・信頼性向上とそれに伴うリリース頻度の向上をさらに検討できればと思っています。(そもそもリリース頻度がすべてではないですが) NeWork はどなたでも無料でお試しできますので、もしプロダクトや使われている技術に興味を持っていただけたらぜひ触ってみてください。 また、2024 年 1 月現在、NeWork では一緒に開発を進めてくれる仲間を募集しています。詳細は以下のリンクをご覧ください。皆さまのご応募を心からお待ちしています! hrmos.co スクラムガイド にも「スプリントレビューのことを価値をリリースするための関門とみなすべきではない」とある通り、いわゆるアンチパターンです。 ↩
こんにちは、イノベーションセンターのメディアAI プロジェクト(以下、PJ)の小林です。普段はコンピュータビジョンの技術開発やAI/機械学習(ML)システムの検証に取り組んでいます。 我々メディアAI PJでは技術力の向上および業務で得られた知見の共有のために毎週チーム内で勉強会を行っています。本記事では2023年の上期に開催した勉強会の概要と勉強会で発表された資料をSpeaker Deckで公開したので紹介したいと思います。 目次 目次 メディアAI PJの紹介 メディアAI PJ勉強会の概要 2023年上期で発表された資料公開 おわりに メディアAI PJの紹介 最初に私たちメディアAI PJについて簡単に紹介したいと思います。メディアAI PJは名前の通り、画像・動画・3D・音声・言語 1 などのメディアに関連するAIの技術開発をメインに行っているチームです。事業部から来る技術相談を通してお客さまの課題を解決するための技術開発やメディアに関連するAIの新規技術創出を目指して取り組んでいます。本ブログで過去には技術動向調査のために参加したCVPRの記事 2 なども投稿していますので、興味ある方はそちらも見ていただけると嬉しいです。 メディアAI PJ勉強会の概要 さて、そんな私たちメディアAI PJでは課題解決に資する技術の開発を加速させるために「メディアAI PJ勉強会」を毎週開催しています。この勉強会はメンバーが気になる技術や話題について調査・検証した内容を発表し、チームで知見を共有する場となっています。 2023年上期は毎週30分ほど勉強会の時間を確保し、各回で1名が発表し、質疑応答・議論する形で開催しました。勉強会のテーマ・トピックは特に設定をせず内容は個人が自由に設定して発表しました。テーマ指定は行いませんでしたが発表する際は内容の背景が分かるように「なぜそのテーマを調べたか」という自分の発表内容のモチベーションについて言及することをルールとしました。モチベーションの中には「業務で必要になりそう」といった直近の開発に必要となるような案件ベースの内容から「世間・研究者の中で流行っている、面白そう」といった個人の興味ベースの理由などさまざまでした。 2023年上期で発表された資料公開 今回は2023年上期の勉強会で発表された資料のいくつかをSpeaker Deckで公開したので簡単に紹介したいと思います。公開した資料リストは以下のようになっています。興味のある資料がありましたら、ぜひ見ていただけると嬉しいです。 Embodied AIについて Embodied Cognitionと呼ばれる知能は感覚システムを通じてエージェントと環境の相互作用によって形成されると言う考えがあります。その考えを元に視覚、触覚、聴覚等の複数センサーを備えた自律的に学習するAIを研究するEmbodied AIについて調査してまとめた内容です。Embodied AIのタスクや環境シミュレータ、共通的なアプローチについてまとめられています。 Webスケールデータセットに対する実用的なポイズニング手法 Webスケールデータセットに対して、攻撃者がデータを操作して機械学習モデルを攻撃するポイズニング攻撃の実現可能性について調査した内容です。データセットに登録されているがすでに失効しているドメインを買い取る、Wikipediaのダンプデータに偽情報を差し込むなどの手法が紹介されており、それらを実際に行うための費用や成功率などが考察されています。 論文紹介 DISN: Deep Implicit Surface Network for High quality Single-view 3D Reconstruction コンピュータビジョンの分野で画像から3次元情報を復元することは重要なタスクとなっており、機械学習アプローチをはじめとしてさまざまな手法が研究されています。この資料では、3次元座標点に対して3DモデルSurfaceからの距離(Signed Distance Function)を推論することによって単一視点画像からの3次元形状を復元を試みたDISNという手法を紹介しています。 3D Human Mesh Estimationについていくつかまとめてみた 画像から人の3Dモデルのメッシュを推論することで、モーションキャプチャーのように画像から3Dアバターを動かすことが可能になると考えられます。このような画像から人の3Dメッシュ推論(3D Human Mesh Estimation)は体のパラメータを元にメッシュを変換する方法や、画像から直接メッシュを推論する方法などさまざま取り組まれています。この資料では3D Human Mesh Estimationのサーベイ論文を元にいくつかの手法について調べてまとめています。 CVPR2023 EarthVision Workshopより衛星画像関連論文紹介 近年、センシングデータの1つとして衛星やドローン空撮画像の活用が試みられています。この資料では2023年のCVPR EarthVision Workshopから衛星画像処理に対する論文を調査した内容となっています。具体的には複数時間の衛星画像をもとに雲を除去する手法、ハイパースペクトル画像に対してVision Transformerの学習についての論文をピックアップして紹介しています。 公開した資料リストから分かるようにテーマを指定しなかったためデータポイズニング攻撃から、3Dモデル、衛星画像処理など幅広い分野について各人が調査・検証した内容が発表されました。また、公開した資料以外にもさまざまなテーマについて発表されており、チーム内での知見共有・技術議論の場となっています。私自身もこの勉強会で自分では調べなかった分野についての知見を取り入れることができて非常に勉強になると同時に、普段とは違った分野に触れられるのが面白く感じています。このメディアAI PJ勉強会は23年下期も引き続き開催しており、今後もPJ内での活発な意見交換をしていく予定です。 おわりに 本ブログでは、私たちメディアAI PJで実施している勉強会とSpeaker Deckでの資料公開について紹介させていただきました。メディアAI PJでは画像や映像、さらには音声言語も含めたさまざまなメディアAI技術の論文調査や研究開発に今後も積極的に取り組んでいきます。 2024年1月現在、メディアAI PJでは一緒に技術開発を進めてくれる仲間を募集しています。詳細は以下のリンクをご覧ください。皆さまのご応募を心からお待ちしています! hrmos.co 現在は画像・動画をターゲットにした開発が多くなっています。 ↩ https://engineers.ntt.com/search?q=CVPR ↩
この記事は、 NTT Communications Advent Calendar 2023 26 日目の記事です。 みなさんこんにちは、イノベーションセンターの @Mahito です。普段は社内のエンジニアが働きやすくなることを目標に、コーポレートエンジニアとしての活動やエンジニア向けイベントの企画・運営をしています。 今回は、 NTT Communications Advent Calendar 2023 を振り返りつつ、今年のブログ運営チームが新たに行った取り組みを紹介します。 今年の Advent Calendar 振り返り Advent Calendar 開始前の検討 ページごとの PV 数共有 OGP 画像 ハッシュタグ まとめ 今年の Advent Calendar 振り返り 今年も無事に 25 日を走りきることができました。 運営スタッフとしては、アドベントカレンダーの記事以外にもやってくる通常記事のレビュー対応で週2本の記事をレビューしたり、 諸事情で記事の順番を急遽入れ替えたりと、大変なこともありましたが無事に終わって一安心しています。 記事としてはセキュリティから始まり、今年も話題になった生成系 AI を含む AI 関連、運用自動化、組織論、etc.. 多岐にわたりました。 そんな中でも、下記の3つは多くの方に読んでいただけた記事でした。 高専かるたを作ってみた TypeScript未経験でもスムーズに業務に取り組める、最強の学習用コンテンツを作った話 サーバレスにおけるRustについて 高専かるたについては、これは個人ブログで書くべきかという相談もありましたが、 面白いことをしている人が NTT Com 社内にいることを知ってもらうことも大事だということで、 本ブログにて執筆・掲載しました。 TypeScript は TypeScript 未経験のインターン生向けのオンボーディング用コンテンツとして作成された物の紹介でしたが、 考え込まれて作られた内容になっており、学習コンテンツを作る参考になる内容でした。 Rust はエネルギー効率という視点を交えつつ、各クラウドベンダーにおけるサーバレスでの Rust の取り組みや比較を紹介しており、 非常に面白い内容でした。 私個人としては以下の2つも趣味や仕事の工夫などが伝わってきておすすめな記事です。 おうち電力の Observability: parser combinator をガリガリ書いてスマートメーターとおしゃべりする 複雑な事業を解釈するためにチームで取り組んだこと この他にも、さまざまな記事がありますので、ぜひお時間がある時に読んでみてください。 Advent Calendar 開始前の検討 今年の Advent Calendar の取り組みは Slack のリマインダーを元に1ヶ月前から始まりました。 昨年の執筆者アンケート結果をまとめた際に今年実施・検討をする事項をまとめていたので、 ブログ運営チームの定例で資料を読みながら、今年はどういう取り組みにするかを話し合いました。 昨年のアンケートからは下記がメインの改善点として挙がっていました。 ページごとの PV 数共有 OGP 画像 ハッシュタグ 今年の Advent Calendar ではこのうち上の2つを改善しつつ、 昨年を踏襲する形で運営することにしました。 以下では、それぞれの取り組みと、ハッシュタグを採用しなかったことについて紹介します。 ページごとの PV 数共有 昨年の執筆者アンケートの中に、 「自分の書いた記事がどれぐらい読まれているのかを知りたい」 という声がありました。 運営側としても、記事を執筆してくれた人に少しでも記事を書いた効果を感じてもらいたいと考えており、 今年は Advent Calendar 期間の PV 数を執筆者へ共有することにしました。 PV 数は Google Analytics から見ることができるように設定しているため、 Google Analytics の閲覧権限を執筆者に付与することを検討しましたが、 権限を付与する会社用 Google Workspace アカウントを執筆者全員が所持をしていないという問題がありました。 また、昨年の執筆者アンケートの中に「少し作業感を感じた」という声もあり、 せっかく参加してくれた執筆者や、興味を持ってくれた人にも楽しんでもらえるようにしたいと考えていました。 このため、Advent Calendar の執筆者や興味を持ってくれている人に対して、 日々の PV 数を共有するため、Google Analytics の 12/1~12/n 日の PV 数を PDF でエクスポートし、 毎日 Slack へ通知することにしました。(手動) Slack で毎日 12/1 から前日までの PV 数やランキングの変化を共有することで、 Advent Calendar の Slack チャンネルに興味を持って参加してくれている人が楽しめるようになったのではないかと思います。 また、この取り組み自体は今回の Advent Calendar で初めて行ったものでしたが、 通常のブログ運営においても取り入れることで記事執筆に興味を持ってもらい、 もっとブログを盛り上げられないかと考えています。 個人的にはそのためにも、冬休みに自動化の仕組みを考えたいと思っています。 OGP 画像 昨年は記事のサムネイルとなる OGP 画像を特に指定していなかったのですが、 他社の Advent Calendar で OGP 画像のフォーマットを揃えて表示しているところなどがあり、 今年は我々も真似してみようかという話になりました。 また、X(旧 Twitter) で記事がシェアされた際にタイトルが欠落してしまう問題(下記 Post 参照)がありました。 私のチームに来てくれた方がblogに寄稿してくれました! #techlunch で話した内容を経験いただくとともに、さらなる改善にチャレンジしてもらいました。大規模なSDNコントローラの内部を見てもらえて、僕としてもすごく楽しかったです。興味ある人は是非読んでみてくだい https://t.co/8e2ts7A7fS — tobioka yoshiaki (@yosiaki6) March 16, 2023 そのため、今回の Advent Calendar では OGP 画像にタイトルを記載することで、タイトルが欠落しても記事の内容が伝わるようにしました。 “サーバレスにおけるRustについて - NTT Communications Engineers' Blog” (7 users) https://t.co/5awYoou8Qn — Mahito / まひと (@Mahito) December 22, 2023 なお、今年はお試しということもありパワポで OGP 画像を作成しましたが、 リリース直前のタイトル変更などもあり、犬の散歩中だった私が慌てるという小ネタもありました。 また、勘のいい方ならお気づきかもしれませんが、 今回の OGP 画像の背景色はコーポレートカラーの1つ #CC0033 にしています。 とても覚えやすいカラーコードなので、 ぜひみなさんも覚えて使ってくださいね! ハッシュタグ 昨年のアンケートでハッシュタグをタイトルに入れるのはどうかというアイデアもいただいていたのですが、 こちらに関しては今年の実施は見送りました。 実は 2021 年の Advent Calendar ではタイトルにハッシュタグをつけていたのですが、 昨年は実施しなかったという背景があります。 その理由として例えば、 #nttcom_ac2023 というハッシュタグをタイトルに付けることで、 記事のタイトルによっては表示が長くなりすぎてしまうためです。 ただ、一律禁止にしたわけではなく、入れる・入れないは任意という形を取りましたが、 今年のタイトルには一度も入ることはなかったという結果に終わりました。 まとめ 今年の Advent Calendar は、昨年のアンケート結果を踏まえ、 読者の方だけでなく執筆者や社内で興味を持ってくれている人にも楽しんでもらえるような取り組みを行いました。 その結果、今後のブログ運営にも取り込めるような発見があり、 運営も楽しく運営ができました。 また来年も、より良いブログ運営を通じて、 みなさんに NTT Com の面白い取り組みを発信していければと思います。 それではみなさん、よいお年を!
この記事は、 NTTコミュニケーションズ Advent Calendar 2023 25日目の記事です。 はじめに こんにちは、イノベーションセンター テクノロジー部門 メディアAI PJ所属の和田、小林です。 普段は画像/映像/言語/音声 等メディアを入力としたAI技術(メディアAI技術)を用いて、事業部/関連部支援や最新技術の調査/研究開発を行なっています。 今回は技術調査の一環として参加した「ViEW2023」について、ワークショップの概要や発表された論文について紹介したいと思います。 ViEW2023は2023年12月7日~8日にパシフィコ横浜で開催されました。詳細は下記サイトをご覧ください。 ViEW2023 公式Webサイト https://view.tc-iaip.org/view/2023/index.html . 目次 はじめに 目次 ViEWについて 流行りのテーマ 小田原賞 概要 外観検査 手法 In-Context Learning Large Vision-Language Model Otter 実験 課題・所感 未知データへの対応 概要 手法 実験 課題・所感 おわりに ViEWについて ViEW (Vision Engineering Workshop) は、1989年に「外観検査の⾃動化ワークショップ」としてスタートし、2003年より「ビジョン技術の実利⽤ワークショップ」と変わりました。 (外観検査とは、製品や部品の表面を確認する検査業務のことを指します。) 外観検査技術をはじめとした産業応用を根幹に据えながらも、現在では極めて幅広い分野をカバーしています。 今年のワークショップは2日間に渡り開催され、それぞれの日程のプログラムは以下のようなものでした。 (出典: https://view.tc-iaip.org/view/2023/index.html より引用) 各オーラルセッションではテーマが決められており(OS1は「産業応用」、OS2は「3次元・計測」等)、研究発表に加え基調講演も行われました。 インタラクティブセッションは現地でのポスター発表となっており、さまざまな大学や企業から2日間で計79件の発表が行われました。 さらに、特別講演では数理工学の世界的権威とも呼ばれる甘利 俊一 氏(帝京大学先端総合研究機構)の「脳と人工知能」に関する講演や、 満倉 靖恵 氏(慶應義塾大)による「脳研究の観点からみた生成型AI」ついての講演があり、興味深い内容を聴講できました。 流行りのテーマ 今回のViEW2023で発表された全ての研究タイトルに対してWord Cloudを適用し、どんなキーワードが流行しているのかを分析してみました。 Word Cloudによる結果を見ると、「画像」や「検出」(検知)等の単語が大きく見えています。 ViEWは2002年までは外観検査の自動化を目的とするワークショップであったため、 ViEW2023でも画像から製品の状態を検出するような、産業分野での実利用を想定した研究が多く発表されました。 また、「学習」や「精度」等の単語も大きく見えており、これらは検出精度を改善させるためにモデルの学習方法に対してアプローチした発表が多かったことが起因していると考えられます。 これらを踏まえて、今回は最優秀論文に選ばれた研究と未知データに対するアプローチに関する研究の2つの論文を紹介します。 小田原賞 ViEWでは毎年、最優秀論文に対して「小田原賞」が授与されています。 第29回(ViEW2023)の小田原賞に選ばれたのは以下の発表でした。 本節ではこちらの研究について紹介します。 山田 悠正,et al,大規模視覚言語モデルのIn-Context Learningによる少量データからの外観検査 概要 こちらの研究では Large Vision-Language Model(LVLM)とIn-Context Learning(ICL)を組み合わせることで、汎用的な外観検査における新しいアプローチを提案しています。既存の Large Vision-Language Model(LVLM) に外観検査の知識を付与するため、Web 上から収集した多様な良品・不良品画像で追加学習し、In-Context Learning(ICL)を用いて良品・不良品を例示し、これらに基づいて検査画像に対して良否判定をする枠組みとなっています。 外観検査 外観検査手法の例として良品の画像データのみから学習されるPaDiM 1 や画像と言語を組み合わせたSAA 2 が挙げられていますが、 前者には検査対象の製品ごとに学習サンプルの収集とモデルの学習が必要であること、また後者には製品ごとにハイパーパラメータの調整が必要であるという課題があり、どちらも汎用外観検査モデルとはなりえないと考えられています。 手法 これから論文中で用いられている各手法について紹介します。 In-Context Learning In-Context Learning(ICL) 3 とは、与えられた少数の例を用いてモデルのパラメータを更新せずに学習し、未知のデータに対して推論をする手法を指します。 Large Vision-Language Model Large Vision-Language Model(LVLM)はLLMの知識を活用し、視覚的特徴を言語空間にマッピングすることで、CaptioningやVisual Question Answeringなどのさまざまな視覚言語タスクにおいて優れた性能を示しています。 本研究では、この既存のLarge Vision-Language Model(LVLM)に対して外観検査タスクを追加学習させることで外観検査に関する専門的な知識を強化したLarge Vision-Language Model(LVLM)とIn-Context Learning(ICL)を組み合わせることで汎用的な外観検査モデルを提案しています。 (出典:元論文 図1 より引用) Otter OtterはIn-Context Learning(ICL)能力と指示追従能力を合わせ持つマルチモーダルモデルの開発を目的とし、Open Flamingo 4 をIn-Context Learning(ICL)かつInstruction Tuning 5 形式のデータセットで追加学習したモデルです。 Instruction Tuningは、さまざまなタスクにおいて、入力の指示に従った出力をするようにモデルの追加学習する手法です。 これにより、未知のタスクに対しても指示を与えることでタスクを実行することが可能となります。 (出典:元論文 図2 より引用) Otterは、画像特徴を抽出するための画像エンコーダと言語を生成するための言語モデルと、画像エンコーダと言語モデルを接続するためのPerceiver Resamplerから構成されます。 使用する画像エンコーダは CLIP ViT-L/14 6 であり、言語モデルは MosaicML Pretrained Transformer 7B 7 となっています。 実験 実験のデータセットはWeb上から収集した多様な製品の良品、不良品画像(計4,693枚)を学習データと検証データとして8:2に分割して使用しています。 また、学習データ3,738枚のうち1,834枚を例示画像として使用し、1,904枚を検査画像として使用しています。 提案手法の有効性を検証するために、データセットによる追加学習の前後で、Otterの性能比較を行っています。 また、評価には外観検査画像データセットであるMVTec-AD 8 を使用しています。 実験の結果、追加学習なしの場合は"Yes"や"No"で答えることができず、定量的評価が不可能な結果となっています。(例えば、"Carpet"の"Color"に対して、"This is a close-up image of a carpet, but it does not provide enough information to determine if the carpet has any specific defects."と回答) 一方で、追加学習ありの場合は一貫した出力形式が得られ、出力形式を統一したデータセットで学習することで、定量的評価が可能であることを確認しています。 定量的評価が可能であった、追加学習後の性能を製品ごとに評価した結果が以下のように示されています。 (出典:元論文 表1 より引用) 各行はMVTec-ADの各製品を表し、"Acc"の列は、各製品に対する良否判定の平均正解率を指しており、 "Carpet"、"Leather"、"Wood"において提案手法は高精度に良否判定が可能なことを確認しています。 課題・所感 論文中の実験結果では学習データに含まれていない物体を検知できていないため、従来手法のように検査対象ごとに学習サンプルを収集しモデルを学習する必要があります。 汎用外観検査モデルとするためには、学習方法の改善が必要であると感じました。 未知データへの対応 ViEWでは製品検査や物体検出に関する発表が多く見られましたが、なかでも未知データに対する検出や学習のデータ作成などの工夫が見られました。機械学習による実問題の解決を考えた際にデータ不足や未知データへの対応は多くの研究者の中で課題となっていると感じます。 本節では、未知物体の検出を試みた以下の発表を紹介したいと思います。 堀内 裕生, et al, 未知物体の検出とクラスタリング機能を備えた物体認識手法の提案 概要 この研究は既知物体の識別性能を維持したまま、未知物体を検出してクラス識別するモデルを提案しています。工事現場や工場などの自立型作業車では周囲の環境を認識して適切に動作する必要がありますが、そのような現場では一般の画像認識データセットに含まれない特有の物体も存在しており、それらの認識が必要になります。 手法 この手法では2つのステージから構成されていました。 第1ステージでは、教師ありデータを用いた未知物体検出モデルのVirtual Outlier Syhthesis(VOS) 9 によって公開大規模データセットから未知データを収集します。 第2ステージでは、まず第1ステージで取得したデータに対してDeep Clustering 10 を用いてラベル生成をします。 具体的には画像をCNNに入力して特徴量を作成し、その特徴量を主成分分析(PCA)および正規化で次元圧縮します。それに対してk-meansによって疑似ラベルを生成し、エポックごとに疑似ラベルを更新します。 次に既知・未知物体を含む画像のResNet、Region Proposal Networkによって特徴量と提案領域を取得し、物体ごとのクラス尤度を算出して学習しています。ResNetの重みは共有されるため、疑似ラベルはエポックスが進むごとに良いラベルへと更新される様になっています。 (出典:元論文 図2 より引用) 実験 実験では既知・未知物体の識別精度を確認しています。ステージ1に15クラスを既知、5クラスを未知と設定したPASCAL VOCデータセット 11 を使用し、ステージ2の推論にMS COCOデータセット 12 を使用していました。 比較手法はResNet50を用いたFaster R-CNN 13 です。 識別精度の比較は下図に示します。IDが既知クラスを示し、OODが未知のクラスを示しています。これを見ると提案手法は従来手法と同等の既知クラスへの精度を維持するとともに、未知物体への識別も可能としていることがわかります。 (出典:元論文 表1 より引用) 課題・所感 提案手法の課題としては疑似ラベル作成の設定があります。k-meansにおけるクラス数はユーザによる指定が必要です。未知物体のクラス数が把握できるような閉鎖的なシーンでは、ある程度指定は可能ですが他の環境・現場では未知クラス数を柔軟に変化させる必要があります。また、本来は別クラスの物体が同一クラスに分類されてしまう場合や、同一クラスの物体が別クラスに分類されてしまうと誤ったラベルで学習することになるため、疑似ラベル作成する際の分類の精度向上が必要だと感じました。 おわりに 本記事では「ViEW2023」に参加することで経験した、ワークショップ全体の内容やピックアップした研究発表を紹介しました。 このような場でしか得られない知見を技術開発や支援の業務に活かしていきたいと考えています。 また、今回のViEWだけではなく、私たちのチームでは技術調査としてさまざまなイベントに参加しているため、今後も機会があれば投稿したいと考えています。 ありがとうございました。 Thomas Defard, et al, "PaDiM: a Patch Distribution Modeling Framework for Anomaly Detection and Localization", ICPR, 2021. ↩ Yunkang Cao, et al, "Segment Any Anomaly without Training via Hybrid Prompt Regularization", arXiv:2305.10724, 2023. ↩ Tom B. Brown, et al, "Language Models are Few-Shot Learners", Advances in neural information, NeurlPS, 2020. ↩ Anas Awadalla, et al, "OpenFlamingo: An Open-Source Framework for Training Large Autoregressive VisionLanguage Models", arXiv:2308.01390, 2023. ↩ Jason Wei, et al, "Finetuned Language Models Are Zero-Shot Learners", arXiv:2109.01652, 2022. ↩ Alec Radford, et al, "Learning Transferable Visual Models From Natural Language .Supervision", PMLR, 2021. ↩ The MosaicML NLP Team, "Introducing MPT-7B: A New Standard for Open-Source, Commercially Usable LLMs", https://www.mosaicml.com/blog/mpt-7b accessed 2023. 12.20. ↩ Paul Bergmann, et al, "MVTec AD — A Comprehensive RealWorld Dataset for Unsupervised Anomaly Detection", CVPR, 2019. ↩ Xuefeng Du, et al," VOS: LEARNING WHAT YOU DON'T KNOW BY VIRTUAL OUTLIER SYNTHESIS ", ICLR, (2022). ↩ Mathilde Caron, et al,"Deep Clustering for Unsupervised Learning of Visual Features ", ECCV, (2018). ↩ Mark Everingham, et al, "The pascal visual object classes (VOC) challenge", IJCV, (2010). ↩ Tsung-Yi Lin, et al, "Microsoft coco: Common objects in context", ECCV, (2014). ↩ Shaoqing Ren, et al, " Faster R-CNN: Towards RealTime Object Detection with Region Proposal Networks ", IEEE Trans. PAMI, (2017). ↩
この記事は、 NTTコミュニケーションズ Advent Calendar 2023 23日目の記事です。 はじめに はじめまして。イノベーションセンター テクノロジー部門 OsecT-Ops プロジェクトの鄭(GitHub: nbhgytzheng )です。2021年度入社で、現在はオペレーショナルテクノロジー(OT)セキュリティリスク可視化サービス OsecT(オーセクト )の開発・保守運用業務に取り組んでいます。OsecTについては過去にブログで紹介していますので、ご興味がある方はご覧ください。 制御システムのセキュリティと対策技術OsecTのご紹介(前編) 制御システムのセキュリティと対策技術OsecTのご紹介(後編) OsecT、サービスリリースしました OTセキュリティリスク可視化サービス OsecT、リニューアルしました 今回は技術ブログへの2回目の投稿で、前回はOsecTで利用している Zeek とZeekのプロトコル拡張ツールである Spicy について紹介しました。パケット解析に興味がある方は是非 【日本初紹介】Zeek・Spicyの使い方まとめ をご覧になってください。 本稿では定形作業化された保守運用の作業を自動化したことについて紹介します。GCP(Google Cloud Platform)のみで実現しているため、OsecTだけでなく異なるサービス・プロダクトにも適用できます。 自動化前の保守運用 はじめに自動化前の保守運用についてお話します。なお、ここでは原因及び対処方法がマニュアルレベルで確立されている保守運用のみについて言及しています。 OsecTのシステムでは障害時などの原因分析に必要なSyslogなどログをCloud Loggingで収集しています。また、システムが特定のログを検知した場合、保守運用チームにCloud Monitoringで通知して、保守運用チームが作業をしています。 自動化後の保守運用 サービス契約数が増えるにつれて、保守運用の負担も増えていくため、すでにマニュアルレベルで対応が確立されている部分の自動化をしようと考えました。マニュアルを使って人手で対応すると、オペレーションミスの可能性もあるため、この点でも自動化は有効です。 GCPの機能を調査した結果、Cloud Pub/SubとCloud Functionsを利用すれば、自動化できることがわかりました。各機能を追加した後のイメージは以下のとおりです。 Cloud Pub/SubとCloud Functionsを追加することで、アラートの発生から対応までのプロセスが自動化できました。これにより保守運用チームの負担およびオペレーションミスの軽減につながります。 今回は「Cloud Pub/Subからtesttestというメッセージが転送されたら、GCP上のメッセージが出しているインスタンスにアクセスし、実行中の全てのコンテナを再起動する」という例で自動化のしくみを紹介します。 自動化に利用したGCPの機能紹介 本章では自動化に利用したGCPの機能を紹介します。エラー発生から復旧までの各機能間のつながりは以下のとおりです。 Cloud Logging Cloud Logging はストレージ、検索、分析、モニタリングをサポートするリアルタイムのログ管理システムです。Cloud Loggingを利用すると、対象リソースから自動的にログを収集できます。 Opsエージェント のインストール及びコンフィグファイルの設定により利用できます。これにより、ログが収集されてGCPログエクスプローラーでログ検索などができるようになります。 ログルーター ログルーター はCloud Logging内の特定のログを転送する機能です。以下のように設定すると、inclusion filterで設定した testtest を含むログが指定されたCloud Pub/Subに転送されます。 Cloud Pub/Sub Cloud Pub/Sub は、メッセージを生成するサービスを、それらのメッセージを処理するサービスと切り離す、非同期のスケーラブルなメッセージング サービスです。今回の自動化では特定の文字列に対して、後述のCloud Functionsを動かすために利用しています。 Cloud Functions Cloud Functions はクラウドサービスの構築と接続に使用するサーバーレスのランタイム環境で、Python、Ruby、Javaなどさまざまなプログラミング言語をサポートしています。今回はCloud Pub/Subから転送されたメッセージを確認し、特定の操作をできる環境を作成しました。以下はPythonで実装したコードの一部です。転送されたメッセージはJSON形式でcloud_event.dataに保存されていおり、辞書型として中身の情報をアクセスできます。 なお、Cloud FunctionsからインスタンスへのアクセスはVPCコネクタの設定が必要です。具体的なコーディングは Cloud Functions の公式サイトを参照してください。 以上の設定により、エラーが発生すると自動で対応できるようになります。 自動化による実行結果 インスタンス上でSyslogにtesttestというメッセージを書き込むと、ログエクスプローラに以下のメッセージが表示されます。これは自動対応済みであることを意味しています。 インスタンスにアクセスしてコンテナの状態を確認すると、正しく再起動されていることがわかりました。 USER@instance-demo:~$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES xxx image_name "/usr/bin/testtest" 21 seconds ago Up 19 seconds test_container_name1 xxx image_name "/usr/bin/testtest" 21 seconds ago Up 18 seconds 0.0.0.0:8000->8000/tcp, :::8000->8000/tcp test_container_name2 ... ... まとめ 今回はGCPの機能のみを活用して、マニュアルなど手順が確立された障害対応を自動化しました。自動化のポイントであるCloud Functionsは汎用性が高く応用範囲も幅広いです。引き続き、定形作業を自動化しつつ、より障害が発生しにくい仕組みや構造に向けた取り組みを続けていきます。
この記事は、  NTT Communications Advent Calendar 2023  22日目の記事です。 はじめに こんにちは、イノベーションセンターの鈴ヶ嶺です。普段は、クラウド・ハイブリッドクラウド・エッジデバイスなどを利用したAI/MLシステムに関する業務に従事しています。 本記事は、各クラウドベンダーのサーバレスにおけるプログラミング言語Rustについて調査・比較した結果を紹介します。 まず初めにサーバレスでRustを利用するメリットをエネルギー効率の観点から説明し、次に各クラウドベンダーの関連記事をピックアップします。 さらに、それぞれのクラウドでRustを使ったサーバレスアプリの代表的な作成方法を紹介して比較します。 Rustのエネルギー効率 Rustは、次の公式ページでも宣伝している通りパフォーマンスを強くアピールしています。 Rustは非常に高速でメモリ効率が高くランタイムやガベージコレクタがないため、パフォーマンス重視のサービスを実装できますし、組込み機器上で実行したり他の言語との調和も簡単にできます。 https://www.rust-lang.org/ja ポルトガルのポルト大学にある研究機関 INESC TEC から発表されたプログラミング言語別にエネルギー効率を比較した論文からも上位に位置する性能を示していることが分かります。 Ranking programming languages by energy efficiency Table 4 1 多くのサーバレスの課金体系はリソースの実行時間に依存するため、エネルギー効率がよく高速に処理可能なRustはコスト的な観点から非常に有用です。 関連記事 このセクションでは各クラウドベンダーがRustに言及している記事をピックアップしました。 Why AWS loves Rust, and how we’d like to help AWSはRustを高く評価しており、Rustコミュニティに積極的に貢献していくことを表明したブログ記事です。 具体的には、オープンソースプロジェクトへのスポンサーやTokioコミッターの雇用などを行なっています。 AWS re:Invent 2023 - “Rustifying” serverless: Boost AWS Lambda performance with Rust (COM306) 2023年のAWSの年次会議AWS re:Invent 2023で発表されたBreakout sessionです。 内容はAWS SAMと cargo-lambda を使用してRust関数をデプロイする方法やPyO3, maturin, AWS SDK for Rustを使って既存のPythonで実装されたAWS Lambda関数にRustを組み込む方法を紹介しています。 発表中にはPythonとRustをコスト面で比較して、Rustがより経済的であることも示しています。 “Rustifying” Serverless: Boost AWS Lambda performance with Rust Rust on Cloud Run Google Cloudの公式Youtubeチャンネル Google Cloud Tech でCloud Run上においてRustを動作させる方法を解説する動画を公開しています。 次のようにRustのメリットとして 高速な起動による、バースト時のスケールアップ シングルバイナリによる扱いやすさ メモリ、CPU利用の高い効率による低コスト クリティカルタスクに対するパフォーマンス などが挙げられています。 https://www.youtube.com/watch?v=rOMroL3mhO4&t=262s Do We Need Rust Language Support for Azure? Microsoft Build 2023で行われたAzureにおけるRustのニーズを議論するセッションです。 残念ながらセッション内容自体は動画が配信されていないため把握できませんがRustコミュニティへのサポートや貢献がここから伺えます。 以上の様に、各クラウドベンダーはRustの高速性に伴うコストメリットなどに着目してコミュニティへの貢献やニーズ調査を積極的に行なっていることが分かりました。 次のセクションでは実際にそれぞれのクラウドでRustを使ったサーバレスを利用する代表的な方法を紹介します。 Amazon Web Services(AWS) AWSでは、 AWS Lambda を利用してサーバレスアプリを作成します。 Lambdaは課金単位が1ミリ秒単位のため高速に実行可能なRustによる低コスト化が期待できます。 AWS Lambdaの開発を円滑に進める周辺ツールにcargo-lambdaがあるため、今回はこちらを利用します。 実際のコマンド例 # install cargo-lambda brew tap cargo-lambda/cargo-lambda brew install cargo-lambda # create project cargo lambda new new-lambda-project --http cd new-lambda-project # debug cargo lambda watch curl http://localhost:9000 # deploy cargo lambda build --release cargo lambda deploy --enable-function-url # function url発行 option cargo lambda invoke --remote new-lambda-project --data-example apigw-request # デプロイされたlambdaをテスト実行 テンプレートとして以下のようなものが作成されます。 main.rs use lambda_http :: {run, service_fn, Body, Error, Request, RequestExt, Response}; /// This is the main body for the function. /// Write your code inside it. /// There are some code example in the following URLs: /// - https://github.com/awslabs/aws-lambda-rust-runtime/tree/main/examples async fn function_handler (event: Request) -> Result < Response < Body > , Error > { // Extract some useful information from the request let who = event . query_string_parameters_ref () . and_then ( | params | params. first ( "name" )) . unwrap_or ( "world" ); let message = format! ( "Hello {who}, this is an AWS Lambda HTTP request" ); // Return something that implements IntoResponse. // It will be serialized to the right response event automatically by the runtime let resp = Response :: builder () . status ( 200 ) . header ( "content-type" , "text/html" ) . body (message. into ()) . map_err ( Box :: new) ? ; Ok (resp) } #[tokio::main] async fn main () -> Result < (), Error > { tracing_subscriber :: fmt () . with_max_level ( tracing :: Level :: INFO) // disable printing the name of the module in every log line. . with_target ( false ) // disabling time is handy because CloudWatch will add the ingestion time. . without_time () . init (); run ( service_fn (function_handler)).await } また、他AWSサービスと連携する場合は、 AWS SDK for Rust を用います。 注目するポイントしてAWS SDK for Rustは2023年11月27にGAとなっています。 今まで性能は良い一方で、SDKがプレビューという理由で採用を見送ってきたケースを解決すると思われます。 AWS SDK for Rust の一般提供を開始 https://aws.amazon.com/jp/about-aws/whats-new/2023/11/aws-sdk-rust/ Microsoft Azure Azureでは、 Azure Functions の カスタム ハンドラー を利用してサーバレスアプリを作成します。 Azure Functionsは課金単位が1ミリ秒単位のためAWS Lambdaと同様に低コスト化が期待できます。 ツールとして Azure Functions Core Tools を利用します。 プロジェクト構成は次の様に準備します。 host.json ファイル: アプリのルート local.settings.json ファイル: アプリのルート function.json ファイル: 関数ごとに必要 (関数名と一致する名前のフォルダー内) コマンド、スクリプト、または実行可能ファイル: Web サーバーを実行 | /MyQueueFunction | function.json | | host.json | local.settings.json | handler.exe https://learn.microsoft.com/ja-jp/azure/azure-functions/functions-custom-handlers#application-structure HttpExample/function.json { " bindings ": [ { " authLevel ": " function ", " type ": " httpTrigger ", " direction ": " in ", " name ": " req ", " methods ": [ " get " ] } , { " type ": " http ", " direction ": " out ", " name ": " res " } ] host.json defaultExecutablePath で実行バイナリを指定しています。 { " version ": " 2.0 ", " logging ": { " applicationInsights ": { " samplingSettings ": { " isEnabled ": true , " excludedTypes ": " Request " } } } , " extensionBundle ": { " id ": " Microsoft.Azure.Functions.ExtensionBundle ", " version ": " [3.*, 4.0.0) " } , " customHandler ": { " description ": { " defaultExecutablePath ": " handler ", " workingDirectory ": "", " arguments ": [] } , " enableForwardingHttpRequest ": true } } local.settings.json { " IsEncrypted ": false , " Values ": { " FUNCTIONS_WORKER_RUNTIME ": " Custom " } } 今回は、次の様なRustアプリを用意します。 環境変数 FUNCTIONS_CUSTOMHANDLER_PORT でポートを指定するところがポイントになります。 HTTP イベントを処理するために Web サーバーを実行し、FUNCTIONS_CUSTOMHANDLER_PORT を介して要求をリッスンするように設定されています。 https://learn.microsoft.com/ja-jp/azure/azure-functions/functions-custom-handlers main.rs use actix_web :: {get, web, App, HttpServer, Responder}; use serde :: Deserialize; use std :: env; #[derive(Deserialize)] struct Info { name: String , } #[get( "/api/HttpExample" )] async fn greet (info: web :: Query < Info > ) -> impl Responder { format! ( "Hello {}!" , info.name) } #[actix_web::main] async fn main () -> std :: io :: Result < () > { let port_key = "FUNCTIONS_CUSTOMHANDLER_PORT" ; let port: u16 = match env :: var (port_key) { Ok (val) => val. parse (). expect ( "Custom Handler port is not a number!" ), Err (_) => 8080 , }; HttpServer :: new ( || App :: new (). service (greet)) . bind (( "127.0.0.1" , port)) ? . run () .await } 実際のコマンド例 # install Azure Functions Core Tools brew tap azure/functions brew install azure-functions-core-tools@4 # create project cargo new handler cd handler cargo add actix-web cargo add serde --features derive ## edit src/main.rs # project setup mkdir HttpExample ## edit HttpExample/function.json touch host.json ## edit host.json touch local.settings.json ## edit local.settings.json # debug cargo build cp target/debug/handler . func start --custom --verbose curl "http://localhost:7071/api/HttpExample?name=World" # deploy ## Linux muslでcross build brew tap messense/macos-cross-toolchains brew install x86_64-unknown-linux-musl export CC_x86_64_unknown_linux_musl=x86_64-unknown-linux-musl-gcc export CXX_x86_64_unknown_linux_musl=x86_64-unknown-linux-musl-g++ export AR_x86_64_unknown_linux_musl=x86_64-unknown-linux-musl-ar export CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER=x86_64-unknown-linux-musl-gcc cargo build --release --target=x86_64-unknown-linux-musl cp target/x86_64-unknown-linux-musl/release/handler . ## Resource Group, Storage Account, Azure Functionを事前に作成 az group create --name xxxxxxxxxxxxxxxxxx --location japaneast az storage account create --name yyyyyyyyyyyyyyy --location japaneast --resource-group xxxxxxxxxxxxxxxxxx --sku Standard_LRS az functionapp create -g xxxxxxxxxxxxxxxxxx -n zzzzzzzzzzzzzzzzz -s yyyyyyyyyyyyyyy --functions-version 4 --consumption-plan-location japaneast --os-type Linux --runtime custom ## Azure Functions Core Toolsでdeploy func azure functionapp publish zzzzzzzzzzzzzzzzz --custom また、他Azureサービスと連携する場合は、 Azure SDK for Rust を利用するのが一般的かと思います。 こちらはunofficialなSDKのため継続した利用や新しいサービスへの対応については注意が必要です。 Google Cloud Google Cloudでは、 Cloud Run を利用してサーバレスアプリを作成します。 今回は次のようなRustアプリを用意しました。 環境変数 PORT でポートを設定します。デフォルトは8080を利用します。 use actix_web :: {get, web, App, HttpServer, Responder}; use serde :: Deserialize; use std :: env; #[derive(Deserialize)] struct Info { name: String , } #[get( "/" )] async fn greet (info: web :: Query < Info > ) -> impl Responder { format! ( "Hello {}!" , info.name) } #[actix_web::main] async fn main () -> std :: io :: Result < () > { let port_key = "PORT" ; let port: u16 = match env :: var (port_key) { Ok (val) => val. parse (). expect ( "PORT is not a number!" ), Err (_) => 8080 , }; HttpServer :: new ( || App :: new (). service (greet)) . bind (( "0.0.0.0" , port)) ? . run () .await } Cloud Runではコンテナを利用します。 FROM rust:1.74.1 WORKDIR /usr/src/app COPY . . RUN cargo install --path . CMD ["helloworld-rust"]% 実際のコマンド例 # create project cargo new helloworld-rust cd helloworld-rust cargo add actix-web cargo add serde --features derive ## edit src/main.rs tourch Dockerfile ## edit Dockerfile # build docker build --platform=linux/amd64 -t gcr.io/xxxxxxxxxxxxxxxxx/helloworld-rust . # debug docker run -it --rm -p 8080:8080 gcr.io/xxxxxxxxxxxxxxxxx/helloworld-rust . curl "http://localhost:8080/?name=world" # deploy docker push gcr.io/xxxxxxxxxxxxxxxxx/helloworld-rust gcloud run deploy --image=gcr.io/xxxxxxxxxxxxxxxxx/helloworld-rust . また、他Google Cloudサービスと連携する場合は、 Google Cloud SDK for Rust を利用するのが一般的かと思います。 こちらはMicrosoftと同様にunofficialなSDKのため継続した利用や新しいサービスへの対応については注意が必要です。 比較 それぞれのサーバレスアプリの作成方法を比較した表が次の様になります。 Amazon Web Services Microsoft Azure Google Cloud サーバレスサービス AWS Lambda Azure Functions Cloud Run 課金単位 1ミリ秒単位 1ミリ秒単位 100ミリ秒単位 SDK(他クラウドサービスとの連携) AWS SDK for Rust(2023-11-27 GA) Azure SDK for Rust(unofficial) Google Cloud SDK for Rust(unofficial) AWS Lambda, Azure Functionsについては、1ミリ秒単位で課金がされるためエネルギー効率の高いRustによるコストメリットを受けやすいのかと思います。 SDKについては唯一AWSが公式ツールを提供している様な状況です。今まで性能面ではRustのメリットを理解はしていたが、他クラウドサービスとの連携面で採用が難しいと考えていた面を再考しても良いのではと思いました。 まとめ 本記事では、Rustの高いエネルギー効率によるサーバレスの低コスト化のメリットや各クラウドベンダーのRustへの取り組みを紹介しました。 また、それぞれのクラウドでRustを使ったサーバレスアプリの代表的な作成方法を紹介して比較しました。 それでは、明日の記事もお楽しみに! Pereira, Rui, et al. "Ranking programming languages by energy efficiency." Science of Computer Programming 205 (2021): 102609. ↩
この記事は、 NTT Communications Advent Calendar 2023 21日目の記事です。 IOWN推進室では、NTTグループ一体となり取り組んでいるIOWN®︎ 1 構想 2 (Innovative Optical and Wireless Network)の認知度向上・案件化に向けたプロモーション戦略業務を行っています。 本記事では、IOWN構想の複雑な事業を理解する・伝えるために実践した取り組みをご紹介します。 異動や転職、新規プロジェクトの参画で事業や技術の理解・伝え方に苦戦する方の参考いただければ幸いです。なお、内容は個人の見解に基づくものであり、所属組織の総意ではないことをご了承ください。 はじめに みなさんこんにちは。イノベーションセンター IOWN推進室の塚越と申します。 NTTグループ一体となり取り組んでいるIOWN構想のプロモーション戦略業務をしています。 2022年4月にNTTコミュニケーションズに新卒入社し、デザイン部門「 KOEL 」でデザインリサーチャーをしておりましたが、今年の7月にIOWN推進室に移りました。 今回はイノベーションセンターのValues 3 の1つである 「枠」を越えように焦点を当て、6ヶ月前に異動するまで未知なる領域であった「IOWN構想」を理解し、伝えることにチャレンジした経験をお話しします。 複雑な事業をシンプルに捉えることの難しさ 私たちは「変動性が高く、未来が予測しにくい」現代に、柔軟に対応できるようIOWN構想を推進しています。しかし現代をうまく捉えられないことと同様に、私にとってIOWN構想を解釈することはとっても難しいことでした。 なぜなら、自身の知識不足や情報過多、相互に関連する多くの要因が絡み合うことで複雑化しており、IOWN構想を明確に解釈することができなかったからです。 このように、前例のない複雑な事業を解釈する際に「自分自身が理解が深められない」や「難解な説明になってしまい聞き手を戸惑わせてしまう」といった状態に陥ること、みなさんはありませんか。 私の状況 IOWN構想との出会いは、異動する1年ほど前デザイン部門で携わっていた先端技術リサーチです。そのリサーチでは、「XR が人々の生活や社会に何をもたらすのか」XR を取り巻くさまざまな事例を参考に、XR がもたらす価値について分析をしました。 その際にIOWNに対して、以下のような印象を持ちました。 メタバースのようなデータ量が大きいものをぬるぬる動かすことができてストレスフリーになる 高度情報化が進み、SNSが当たり前に活用されることによって生まれた歪みをなくし、人それぞれの心地よさを追求できる情報社会のための基盤ができる 一方で、光電融合技術や光通信技術などIOWN構想を支える技術の理解は進んでいませんでした。 異動して苦労したIOWN構想全体像の把握 異動を機に最初に取り掛かったことは、IOWN構想の背景や技術に関する知識等全体像の理解です。それらを理解するために、IOWN構想に関するありとあらゆる文献に当たりました。しかし時間をかけてもなかなか理解が進みません。理解が進まない原因は大きく2つあると考えました。1つ目は自身の知識不足、2つ目はアクセス容易な文献の認知負荷 4 が高いということです。 具体例としては、専門的な用語・横文字の多用、文章が冗長、色調やレイアウトに一貫性がないといった事象が重なり、私にとって情報を処理しきれない難解な文献でした。1つ目の知識不足は、新しい領域に挑戦する時は誰しもぶつかる壁だと思いますが、2つ目の認知負荷が高いに関しては個人の問題のみならず、プロモーションを推進する上で障壁になっているのではと推測しました。 資料改善に取り組む これらを踏まえ、お客様説明用スライド資料の改善を進めることにしました。スライド資料改善の営みは、これからIOWNに関する業務を進めていく上で必要な知識を深め、ビジュアルでわかりやすく伝えることがほんの少しだけ得意な私がすぐに貢献できる絶好の機会でした。 情報の整理・分析 既存資料の分析 まずは何がスライドを複雑にさせているのか、現在の構成を整理してみます。 整理してみるとこのような障壁がありました。 シーズに偏った説明になっている 共感できるストーリーになっていない 理解の下地となる知識や情報が不足している 内容が取捨選択できておらず、70ページほどの巨大なスライドになっている etc... これらの問題が聞き手が共感しにくく難しいと思ってしまう原因になっているのではないかと考えました。 お客様、営業さんの声を聞く 次にチームメンバーがスライドを使ってご提案する場に同席し、お客様や営業さんの声を聞きました。特に多くご意見をいただいたのが「利用シーンを想起しにくい」ということでした。技術的な説明の割合が多い一方、ユースケースの割合が少ない構成になっており共感や納得につながらないこと、また聞き手が求めていることを想定できていないという課題を認識しました。 資料化 分析を通して既存のスライドに不足している事柄を把握し、いざ資料化を進めていこうとすると知識不足の壁を感じ、私一人の目線や知識では限界を感じました。 そこで、IOWN推進室のメンバーに協力を仰ぐと皆さん快く引き受けてくださりました。一人ではなくチームで改善を進めていくことにしました。 一方、チームで進めていくと新たな困難に当たります。それは、それぞれ専門分野や経験してきた領域の異なるメンバー間での喧々諤々の議論が起こり、議論が思うように進まないということです。そこで、個々人がIOWN構想に対する認識や価値観・思考方法に違いがあることに気づきました。 ですが、相手の知識や専門用語を知りそれを使って理解し合うことで、新たな気づきを得て手段の選択肢の幅を広げることができるのではないかと可能性を感じました。 ブレイクスルーの方法 立場や専門性の違いを強みにする IOWN全体で見ると情報が複雑で難しいと感じてしまいますが、各々の専門分野に関することであれば、情報が整理されていて要点が明確になっていると考えました。IOWN推進室には「光電融合の技術やデバイスの観点」「ネットワークサービスとしての観点」「コンピューティングの発展経緯としての観点」「戦略マーケティングとしての観点」「研究開発としての観点」を持つメンバーがいてそれぞれの観点からお話ししていただきました。 そして、お話を聞く中で「どういう方向性にするか」「どこを深掘りしていくか」「どこを重要視したらいいか」整理していきました。そして、議論の中で得た新しい視点と自分の専門分野の知識を重ねてIOWN構想に対する知識を深め、気づいたことをアウトプットする。この営みを何週も繰り返しました。すると、次第に情報が整理されたスライドを形作れるようになりました。 なぜその方法にたどり着いたのか? 「 サピア=ウォーフ仮説 」と「 非ゼロ和ゲーム 」というキーワードからこの方法に辿り着きました。 「サピア=ウォーフ仮説」は、人は言語を通してのみ思考するのだから、異なる言語を使えば認識する世界観が変わるという考え方。一方「非ゼロ和」は、複数の人が相互に影響しあう状況の中で、ある1人の利益が必ずしも他の誰かの損失にならないこと・状況のことです。 「サピア=ウォーフ仮説」は、言語に着目していますが、同様に専門性の違いがあれば認識する世界観が変わるのではないかと考えました。 この「サピア=ウォーフ仮説」と「非ゼロ和ゲーム」という2つのキーワードから、複雑な事業を理解・伝えていくためには、専門性の違いで分断するのではなく互いの分野を絶えず行き来して相互に影響し合い、チームとして複数の視点を持つことが重要なのだと感じました。 試した結果、周囲の反応はどうだったのか? 作成したスライド資料を運用し始めると、運用前と比べて以下の変化が起きました。 資料請求が増加した 資料を活用した説明が容易になった 社内外からわかりやすいとお声がけいただくことが増えた 営業さんからの引き合いが増え、共創支援等関係性構築につながった スライド資料が、チームを超え他部門・社外とのハブになってきていると感じています。 また、資料作成のプロセスを通じて「別の案件を一緒にやりたい」や「アドバイスが欲しい」とチームメンバーからお声がけいただくことが増えました。 まとめ 今回取り上げた資料改善の事例を通して、 自分の「枠」にとどまらずチームとして複数の視点を持って新たな価値観を得ることで、理解の深化やわかりやすく伝えることにつながる というお話しをしました。 前例のない複雑な事業に必要なことは、既成概念を取り払いイノベーションを起こしていくということだと思います。自分の意思を曲げて誰かの意思に従うことなく、不協和音に立ち向かう。しかし、争うのではなく互いの視点を絶えず行き来し、妥協するのではなく相互に影響しあって組織力を向上するということは一つの解決手段ではないでしょうか。 自身の展望 私の長期的な目標は、「今は使う人を選ぶ先端技術を、誰もが使える公共性の高いサービスに活用して、世の中の当たり前にしていくこと」です。 IOWNの社会実装で貧富の差を生み出すことなく、誰もが平等に享受できるものにしていけるように、さまざまな「枠」を超え、世の中の潜在的な課題に目を向けていきたいと思います。 IOWN構想について ところで、IOWNってなんだろう?そう思った方いらっしゃいますよね。 IOWN構想について少しだけお話しします。 IOWN構想とは、ひと言で言うと「現在のネットワークインフラでは実現できない、新たな世界・豊かな社会を実現する革新的な取り組み」です。 IOWNはその名の通り 革新的な光と無線のネットワーク で、 光電融合技術 と 光通信技術 を用いて 大容量・低遅延・低消費電力 を実現する、 次世代通信・コンピューティングプラットフォーム です。(かなり砕けた表現をすると、「とっても早くて、一度にたくさん情報が送れるのに、かなり省エネ」なすごい技術です) 現代は市場の競争が激化し技術の進歩が早まり、ビジネスは日々変化を求められます。さらに、経済や政治の不安定さ、自然災害などのリスクも存在しています。こうした現状には、従来の思想や方法・技術だけでは対応ができなくなってしまいました。 想定外なことが起きてもしなやかに対応し豊かな社会を実現するために、NTTを中心として世界の各企業と一緒に「IOWN構想」を推進しています。 5 IOWN推進室について NTTコミュニケーションズのイノベーションセンターに属するIOWN推進室は、2023年4月にイノベーションセンターに設立されました。 IOWNの早期社会実装に向けて、以下の3つに取り組んでいます。 1. IOWNに関する技術開発・検証 2. 認知度向上・案件化に向けたプロモーション戦略の立案/実行 3. 実証実験の推進 私の所属するチームでは、認知度向上・案件化に向けたプロモーション戦略の立案/実行を担っております。 みなさんに「IOWNを使えば今抱えている課題を解決できる!」と思っていただき、IOWNで世の中を豊かにするビジネスを一緒に作り上げていきたい!その一心で活動しています。 6 今年は、docomo business Forum’23 7 やOPEN HUB Park 8 で体験型の展示を設計し、みなさんに「IOWNが拓く未来の世界」をご体感いただきました。 宣伝 IOWN推進室では、IOWN構想の早期社会実装に向けて共に尽力するメンバーを募集しています! IOWNやIOWN推進室の取り組みにご興味持ってくださった方がいたら、ぜひ一度お話ししましょう! IOWN構想展開におけるストラテジー・プロフェッショナル 光伝送ネットワークインフラおよびサービス開発エンジニア IOWN/APN(All Photonic Networks)を支えるネットワークエンジニアIOWN/APN(All Photonic Networks)を支えるネットワークエンジニア 最後まで、ご覧頂きありがとうございました! それでは、明日の記事もお楽しみに! 「IOWN®」は、日本電信電話株式会社の商標又は登録商標です。 ↩ IOWN構想(アイオン:Innovative Optical and Wireless Network)とは、あらゆる情報を基に個と全体との最適化を図り、光を中心とした革新的技術を活用し、高速大容量通信ならびに膨大な計算リソースなどを提供可能な、端末を含むネットワーク・情報処理基盤の構想です。 ↩ イノベーションセンターのValues ↩ 認知負荷とは、読み手が情報を理解する際にかかる精神的なエネルギー量のこと ↩ 「IOWNのこと、もっと知りたいよ〜!」って思ってくださったらぜひ。 OPEN HUB RADIO 「IOWN特集」をお聞きください。IOWN推進室の羽石さんがIOWNについてお話ししています。 ↩ その他IOWN推進室の取り組みは、 こちら で紹介しています。 ↩ docomo business Forum :ドコモグループの法人事業ブランド「ドコモビジネス」のもと事業を展開するNTTコミュニケーションズが、最新テクノロジーとユースケースを紹介するイベント。 ↩ OPEN HUB : 社会課題を解決し、わたしたちが豊かで幸せになる未来を実現するための新たなコンセプトを創り、社会実装を目指す事業共創の場。各領域に精通した専門家であるカタリストやパートナー企業に所属する「人」とともに、多様なアイデアや最先端の「技」を組み合わせて、リアルに、時にバーチャルな「場」で思考を重ね、ビジネス課題の解決に向けた取り組みを行っている。 ↩
イノベーションセンターの三島と深川です。 普段の業務では、Segment Routing を始めとする経路制御技術や、IPFIX や Streaming Telemetry などの監視技術の検証・運用、高速ソフトウェアルーター「 Kamuee 」の開発をしています。 我々は 2023/11/04-10 に行われた IETF 118 Prague へ参加しました。 この記事では、IETF 118 の参加報告として、主に Hackathon での成果と各 WG の動向などをご紹介します。 (出典: https://www.ietf.org/) IETF の概要や IETF 117 については IETF117 参加報告とおもしろワーキンググループ紹介 をご覧ください。 IETF 118 参加報告 以下では、我々が現地で参加した IETF meeting の内容をご紹介します。 IETF 118 の全スケジュールは IETF 118 Meeting Agenda を参照ください。また、IETF の onsite meeting ならではの用語は Guide to IETF Meetings で紹介されています。 Day1-2: Hackathon IETF meeting では、本会議である Meeting Week に先んじて2日間の Hackathon が開催されます。 IETF Hackathon は、集まった多くの開発者や専門家が、アイデアや便利なツール、標準化にあたっての running code 開発、相互接続性を検証するための場です。 IETF Hackathon では、各自が自由なテーマを設定し、開発に取り組むことができます。 テーマは事前に Hackathon Wiki で募集することもできますし、現地で新たにテーマを定めて開発することもできます。 我々は IETF 116 Hackathon 以降、SRv6 ネットワークにおける情報取得や高度な Traffic Engineering (TE) を目的とし、IPFIX exporter を開発しています。 それぞれの技術は、Operations and Management Area Working Group (opsawg) にて標準化が行われているため、Hackathon では、opsawg の I-D 著者の方々と連携しながら、パラメータの調整や相互接続試験を実施しています。 我々は IETF 116 Hackathon において、汎用の Linux ルーター上でのアイデアの迅速な実装を目的とし、eBPF/XDP ベースの IPFIX exporter として「Fluvia Exporter」を開発しました。 Fluvia Exporter は NTT Com より OSS として公開しています( リポジトリ )。 より詳しい開発背景や設計・実装手法については、 ENOG79 SRv6 対応の IPFIX exporter を開発した話 をご覧ください。 IETF 117 Hackathon では、IPFIX を用いた SRv6 フローの情報取得を目的とし、 Export of Segment Routing over IPv6 Information in IP Flow Information Export (IPFIX) の実装と nfacctd・WireShark との相互接続を実現しました。 この実装により、Segment List や Segment Left などによる SRv6 フローの識別や追跡が可能となりました。 IETF 118 では、「 IPFIX On-Path Telemetry with SRv6 」というテーマを主催しました。 このテーマでは、SRv6 フローの hop-by-hop な遅延メトリックの取得を目的とし、 Export of On-Path Delay in IPFIX の各機能を開発します。 Hackathon 開始時点では、2 つの exporter(FD.io VPP・Huawei VRP)と、collector(nmacctd)の実装が存在していました。 今回我々は、以下の2つのモチベーションで Hackathon に取り組みました。 1つめは、Fluvia Exporter への on-path delay の Information Element (IE) の実装、2つめは、WireShark dissector の実装です。 この2つの実施により、SRv6 ネットワークにおける on-path delay の取得と、取得したパケットのプロトコル解析が可能になります。 Fluvia Exporter への IE 実装 Fluvia Exporter に対し、今回対象となる IE を実装します。 実装したコードは こちら です。 実装対象である IE の Element ID は、IANA での割り当て待ち(TBD)となっているため、今回は相互接続用に仮に定めた番号を用いて実装し、OSS の IPFIX collector である nfacct の既存実装との相互接続を目指します。 今回実装する on-path delay 取得の仕組みを図に示します。 on-path delay では、遅延の取得のため、IPv6 の拡張ヘッダである hop-by-hop options header で Encapsulation された In-situ OAM (IOAM) と呼ばれるプロトコルを利用し、パケットに送出時のタイムスタンプを埋め込みます。 そのタイムスタンプと、各ルーターでのパケット受信時のタイムスタンプの差を取得することで、図の D1/D2/D3 のような送信遅延を取得できます。 (ごく短いタイムスタンプの差を取る関係上、機器間で PTP 等での高精度な時刻同期が行われていることが前提となります。) on-path delay を取得するための IPFIX exporter のパイプラインを上図に示しました。 パイプラインは、capturer・meter・exporter の3つのコンポーネントから構成されます。 capturer: パケットを取得するコンポーネント。IOAM timestamp を取得し、受信時のタイムスタンプと共に meter に送信する meter: パケットを処理し、IPFIX data を生成するコンポーネント。IOAM で付与されたタイムスタンプと機器のシステムクロックのタイムスタンプの差から送信時の遅延を算出し、SRv6 SRH の情報と共に IPFIX data を生成する。 exporter: IPFIX packet を生成し、collector に送信するコンポーネント。 Fluvia Exporter のアーキテクチャを上図に示しました。 Fluvia Exporter は eBPF/XDP ベースに実装されており、eBPF プログラムとして動作する capturer によりパケットを取得し、User land の meter/exporter で IPFIX パケットを生成します。IPFIX のパケットフォーマットは Go のライブラリとして実装しています。 今回は、capturer への IOAM パケットの取得機構の実装・meter へのタイムスタンプ計算処理の実装・IPFIX ライブラリへの IE の実装を行いました。 上図に、実装した IPFIX ライブラリの例を示しています。 相互接続用の仮の Element ID として、521・523・525・527 の4種を実装しています。(注: 522・524・526・528 として実施済みの nanoseconds は draft-ietf-opsawg-ipfix-on-path-telemetry-01 にて廃止されたため、Fluvia Exporter からも今後削除予定です。) それぞれの IE のデータ構造と処理を IPFIX ライブラリに定義します。 その他、今回の PR には eBPF によるパケットの取得や、タイムスタンプの計算処理なども含まれているので、もし興味があれば是非読んでみてください。 上図の通り、nfacctd との相互接続を確認しました。 ログから、すでに実装されていた SRv6 SRH の Element ID (495・498・492・493・496) と、今回実装した Element ID (521・523・525・527) がそれぞれ確認できます。 これにより、Fluvia Exporter に on-path delay の IE が正しく実装できたことが確かめられました。 WireShark dissector の実装 WireShark は、GUI のネットワークプロトコル解析ツール(network protocol analyzer)です。 リアルタイムに取得したパケットや pcap ファイルに記録したパケットの解析ができます。 WireShark は多くのネットワークプロトコルに対応していますが、今回対象とする I-D のように、標準化中などの最新プロトコルには未実装なものも存在します。 そのような場合は、dissector と呼ばれるパケットの解析プラグイン追加することで、新たなプロトコルを扱えるようになります。 Hackathon にて実装したコードは こちら です。 IPFIX 自体の dissector はすでに存在しているため、今回必要となる IE に関するコードのみを、I-D で定義されたデータ型を参考に実装しています。 dissector を追記実装した後、WireShark をビルドし実行しました。図の通り、今回実装した on-path delay に関する IE が表示されています。 これにより、Fluvia Exporter への IE 実装と、WireShark dissector 実装をそれぞれ完了し、動作確認を実施できました。 最終発表 IETF Hackathon 2日目の後半2時間(14:00-16:00)には、それぞれのチームによる最終発表が行われます。 発表の希望者は、 IETF Hackathon の GitHub organization に参加し、締め切りまでに IETF Hackathon 118 のリポジトリ に資料を投稿することで最終発表にエントリーできます。 最終発表では、Hackathon で達成した内容や成果を共有できました。 資料は こちら です。 発表は開発時間が終わった直後に始まるため、開発と並行して資料を用意する必要があり少し大変でしたが、とても良い経験となりました! Hackathon を通じて得られたことと今後について Fluvia Exporter の実装を I-D の Implementation 例として追記していただきました! 今後は IANA による Element ID の払出し後に Fluvia Exporter の実装を修正するとともに WireShark の実装も修正し PR を提出しようと思います。 Hackathon を通じて得られた経験としては、前回に引き続き、I-D 著者の方々と事前のメールや現地会場での交流ができました。 その中で、I-D に関連する取り組みを教えていただけたと共に、I-D に関する勘違いを指摘して頂き、実装をより良いものに修正できました。 また、Hackathon Wiki にて募集をかけたことで、他の参加者から取り組みについてメールで質問をいただき、現地にて交流できました。 この開発により、当初目標としていた、SRv6 網の IPFIX による解析と、hop-by-hop の遅延を得ることがそれぞれ達成できました。 次回以降の Hackathon では、現在 執筆中の SRv6 SFC の I-D に関する実装や、IPv6 に関する別の I-D の実装などを検討しています。 IETF Hackathon は、I-D の著者や機器の開発者など、最先端のスキルを持つエンジニアと交流し、議論ができる貴重な機会です。今後も是非活動を続けていければと考えています。 Day3-7: WG session Day3 以降の Meeting Week では、それぞれの WG session が開催されます。 他の WG session を含め、全てのスライドや I-D などの資料は IETF 118 の Agenda ページ から確認できます。 以降では、我々が参加した WG session のうち、SR に関連して特に面白かったテーマをいくつかご紹介します。 Source Packet Routing in Networking (spring) spring WG は、セグメントルーティング (Segment Routing: SR) と呼ばれる TE 技術の標準化と拡張を目的とする WG です。 SRv6 compression・ICMP による SRH 情報の報告・SRv6 MUP・SR Policy Candidate Path の検証などのトピックが扱われていました。 その中でも、ICMP の SR Policy 拡張は、SR 網のトレーサビリティを高め、トラブルシューティングに役立てることのできる面白いトピックです。提案では、SID の Endpoint behavior や VPN prefix、Flex-Algorithm なども解析できるような提案がされていました。 ICMP は任意の宛先に対してアクティブな検証ができますが、同じくアクティブに検証する TWAMP や、実トラフィックを用いてパッシブに解析する IPFIX との機能の差なども含め、利点を考慮すべきテーマだと考えています。 Internet Area Working Group (intarea) intarea WG は、インターネット全体に影響するトピックを議論するための WG です。 アドレス空間・IP レイヤーの機能などのテーマが扱わます。 この枠では、Trusted Domain SRv6 (draft-raviolli-intarea-trusted-domain-srv6-02) についての発表が行われていました。 この I-D は、外部からの不正な SRv6 パケットによる攻撃(DoS の送信元詐称や悪意のあるループ等)を防止するため、 trusted domain という概念を導入しています。 trusted domain では、現行の MPLS のように、あるプロトコルはデフォルトでは drop され、明示的に有効化されたインターフェースでのみ転送が行われます。 trusted domain の実装として、本 I-D では SRv6 専用の ether type を割り当てることで、一般の IPv6 パケットと識別可能にすることを提案しています。 一方、ether type によるアプローチは SRv6 が持つ IPv6 ネットワーク上に部分的に組み込むことができる利点を妨げるものであり、SRv6 の自由度を下げることが懸念されます。 ether type によるアプローチでは、SR-MPLS 同様に、明示的に有効化するよう設定されたネットワークでしか SRv6 を活用できなくなります。 SR-MPLS と比べた利点として、SID が持つ Function/Argument 領域や Prefix Aggregation、Path Tracing などは残りますが、SRv6 が持つ IPv6 ネットワーク上に部分的に組み込むことができる利点を妨げるものであり、SRv6 の自由度を下げることが懸念されます。 SRv6 の routing security は、今後 SRv6 が広く用いられる技術となる際に重要となる観点です。 一方、security のトレードオフとして技術の持つ利点が大きく損なわれることは望ましくないため、より良いアプローチや SRv6 に求める利点について、我々も引き続き注目し検討していきたいと考えています。 Side Meeting 「 Segment Routing Deployment and Operation discussion 」という Public Side Meeting に参加し、さまざまな SRv6 の運用者による発表を聴講できました。 テーマとしては、uSID の利点や SRv6 の Multi-domain での活用、EANTC での相互接続検証の成果、データ活用基盤( 前回の記事で紹介した取り組み )などが扱われており、各社の利用状況や実装などを知ることができました。 参加してみての感想と今後について IETF 118 では、IETF 116 から行っていた Hackathon の目標を達成すると共に、SRv6 に関する標準化動向を調べることができました。 Hackathon のまとめでも触れましたが、今後は執筆中の I-D を提出し、標準化を目指して活動を進める予定です。 次回、IETF 119 Brisbane の参加登録は 12/04 より開始済みです。 Super Early Birds の締切は 01/29 23:59 (UTC) なので、参加される方は忘れずにご登録ください。 ( IETF 119 Register ) JANOG 53 にて、IETF 118 の参加報告を実施予定です。もし興味があれば、こちらも是非ご参加ください! 若人が1年間に渡って IETF における標準化活動に関わってきた話