Kengo's blog

Technical articles about original projects, JVM, Static Analysis and TypeScript.

元toB系プログラマが医療情報技師の勉強をして面白かった部分

今年の医療情報技師能力検定試験に向けて、医学医療編・医療情報システム編の学習を進めてきました。toB系プログラマとして働き始めてから見てこなかった単語や発想がたくさんあって面白かったので、印象的だったところをまとめます。

医療現場はロールベースかつイベントドリブン

医療現場では(乱暴に言うと)各部門やシステムの間を「オーダ」をはじめとしたメッセージが飛び交っている、というモデル化ができそうです。 多くの役職だと何ができるかが法で定められていて、そうした役割をどう組み合わせるかも予め想定されており、そのコラボレーションをメッセージで行っているということです。

これはけっこう医療現場というものを特徴づけるものだと思っていて、パッと思いつくところでも以下のような事が考えられます:

  • 業務の属人性を下げるための仕組みとして機能することが期待される。
    • アクターのTODOや期待されるアウトプットが明確。特に医療行為や看護行為は国際的なマスタがあり、世界的に定義が明確っぽい。
    • アクターの専門性に対する期待も明確なので、教育や評価も(簡単とは言わないけど)比較的やれそう。
  • アクターのロールやコミュニケーション方法が全医療機関共通なので、転職も比較的しやすそう。
    • プログラマだと言語や利用してるクラウドが同じでも現場の働き方はぜんぜん違うけど、医療現場だと少なくとも部署間コミュニケーションは似ていると期待できそう。
    • 紙カルテ&電子カルテみたいな、採用している仕組みが違うと細かいやり方は大きく違ってくるとは思うけど。
  • アクター=部署あるいは資格持ちの人間なので、病院というシステムを動かすための最低限の人数が多くなる。
    • コーダー兼デザイナー兼テスター兼広報です!みたいなことが法的にやりにくい。医師ひとりの診療所で在宅医療やるぞみたいな例はあるみたいだけど……。
    • 情報の交通整理や決断が困難かつボトルネックになる可能性が高い。実際医師や看護師の長時間労働などが問題になっている。

Team Topologiesに親しんでるとStream-aligned Teamに権限を移譲していかにスムーズに動かすかという発想になるんですけど、病院というシステムだとそもそもどこがStreamなんだっけとか、各種検査というComplicated Subsystemをどう動かすべきなんだろうとか、普段使ってない頭の部分を使っている感じがしていいですね。

科学的知見を幅広く活用するための「ガイドライン」

コロナ禍を通じて私にもランダム化比較試験が強いらしいみたいな雑な理解はあったのですが、医療情報技師の学習をきっかけにEvidence-Based Medicine(EBM)という考え方があってランダム化比較試験よりも強いやつがあるということを知りました。システマティックレビューやメタアナリシスがそれです。強い研究を統合してもっと強くするみたいな雑な理解でいますが、人間の叡智を集結して現在のベストを導き出すというのはなんか知性の総力戦という感じでいいですね。

さて医療の世界には診療ガイドラインというものがあり、医療機関ごとの医療の質を底上げしたり医療資源を効率的に扱ったり提供された医療の評価に使ったりしています。日本では医師会や厚生労働省から出ているものが多数あるようです。国立研究開発法人国立がん研究センターがシステマティックレビューやメタアナリシスも含めた説明をしているのでおすすめです:

ganjoho.jp

医療が研究の山の上に成り立っていることはなんとなく知っていたつもりでも、医療関係者がどう知識をアップデートしているかとかはイメージがなかったため、なるほどこうやって国として知識を共有し医療の質を保っているのだと感心しました。

ちなみに医療機関向け情報セキュリティの世界でも3省2ガイドラインというものが提供されています。医療情報技師なら内容を把握していることが求められますし、医療業界向けのサービス提供をする場合も必ずこれを読むことになります。これは診療ガイドラインではないのでメタアナリシスとかは関係ないかもしれないですが、少なくともIT業界標準の考えは多く盛り込まれているように感じます:

www.mhlw.go.jp

www.meti.go.jp

医師の相互監視に課題がありそう

転職する前に医療業界に抱いていたイメージとしては、インシデント対応ができてなさそうというのがありました。いや、個人的体験としては特に不満を感じることもなかったですし、インシデントにぶち当たったこともたぶん無いのですが、「失敗の科学」の印象が強かったのです。この本は「航空業界にあって、医療業界にないもの」とデカデカと書いてあるレベルで(アメリカの)医療業界にダメ出ししています。

失敗の科学

失敗の科学

Amazon

ところで医療情報技師の学習範囲にはインシデントの扱いや医療安全や医療過誤、原因分析や再発防止などが含まれています。RCA(Root Cause Analysis)やProblem SolvingあたりはtoBプログラマなら扱ったことあることも多いと思うのですが、これに加えて4M5E分析とかSHELモデルとかも扱っていて自分は初見だったので勉強になりました。また国内の事例や記事なんかを追いかけても真摯に課題に向かっている方が多く、結構やれてるじゃんという感想になった、んですが、残念ながらこの事件が起こってやっぱダメなところはダメなんだなという現実を思い知ったところがあります:

www3.nhk.or.jp

少なくとも医師同士の相互監視は、セカンド・オピニオン(厳密には監視ではない)やカウンターサインを除けばあまりなさそうだなというのが今の自分の認識です。もちろん日頃から院内で情報交換(カンファレンス)を行っていたり、インシデントレポートが提出されれば然るべき検討が行われたりするはずですが、少なくとも前述の事例ではカルテを読み合うようなことはやっていなかったのでしょう。

医師が長時間労働していることを踏まえるとここはシステムが余力を創出することで貢献できる部分かもしれないなとは思いますし、カルテ記載事項の質の判断とかは機械学習でなんとかできそうな気もします。

病院の壁を超えたPDCAサイクルが回せるように情報が公開されている

診療ガイドラインの実施率であるとか、病床機能の割合であるとか、様々な各病院から提出されたデータが統計されたうえで公開されています。例えばこのへんとかです:

hospia.jp www.mhlw.go.jp

これ普通の企業の活動だとちょっと考えにくいというか。強いて言えば離職率とか初任給とかは他と比較して改善の参考にはすると思うのですが、じゃぁ他社製品の単体テストカバレッジとか変更のリードタイムとかMTTRとかはそもそも公開されていないので参照できない事が多いと思うのですよね。ところが医療機関の場合は医療サービスというコア機能のデータが世に出ているわけで、いやこれすごいなって思います。もちろん病院側だけじゃなくて、ガイドラインとか政策とかの側でも参考にしているのでしょう。

ちなみに海外だと病院ごとだけじゃなくて医師ごとのデータとかも見られるらしいです。すごい。

まとめ

元toB系プログラマが医療情報技師の勉強をして面白かった部分として、医療現場がロールベースかつイベントドリブンっぽいなぁということと、診療ガイドラインやデータに基づく改善が回る仕組みがあってすごいなということを書きました。またインシデントを隠さず業界全体として次に活かすための体制や仕組みはありそうなので、あとは実行の浸透が重要=やっぱり医療DX大事だなぁと改めて感じました。

医療情報技師の資格試験は医学・医療編がちょっと重いものの、医療システムのおおまかな構造や他施設との連携などについても学べるので、私みたいに医療業界の外から来たプログラマは齧って損はないと思いました。おすすめです。

私がとあるOSS開発から手を引いた経緯

ホットな話題に乗っかって、私がSpotBugsというJava向け静的解析ツールのOSS開発から手を引いた理由をまとめてみます。

自分がJavaを使わなくなった

先のブログでも指摘されている通りで、自分がそのソフトウェアを必要としなくなったというのは大きな理由になりました。Kotlinに乗り換えたことでJavaを書く機会がなくなり、Kotlinが生成したclassファイルの解析はSpotBugsには向かなかったので、SpotBugsを使わなくなりました。

SpotBugsにKotlin対応させることは技術的には可能ですが、ソースコードも考慮して解析できるdetekt(ktlint, diktat)がある世界でわざわざやることではないという感想です。

リターンが無かった

自分が使わないツールのメンテナンスを継続するには、やはりある程度の見返りを求めたいというのが自分の気持ちとしてありました。Github Sponsorsをはじめてみたり、Who uses SpotBugs?をまとめてみたりしましたが、いずれも自分が納得できる程度には至りませんでした。

冗談半分で「控えめに言っても日本人で、ひょっとするとAPACでもclassファイル静的解析で片手の指に入るんじゃないですかね」とか言うことがあるんですが、これは6年間の活動の結果を分かりやすく人に伝えることで少しでもリターンを稼ぎたいなという気持ちが裏にあるわけです。

まぁ世の中にはOSS開発者を表彰するような動きもいくつかありますし、金銭的フィードバックをコントリビュータに返せているコミュニティもいくつかあるようなので、あと数年続けていれば結果が出た可能性はあります。ただ私としてはその時間を新しいことに使いたいと思い、資格試験や副業に充てることにしました。

個人的には、Javaで中~大規模開発してる会社なんてだいたいSpotBugsを使ってるだろうし、Javaバージョンを上げる際などに課題もいくつか出ているだろうし、ひとつくらいSponsorしてくれる会社が出てきてもおかしくなかったんじゃないかなぁどうかなぁとは未だに思っています。が、そういうところもSonarQubeのような有償ソリューションに鞍替えした方がトータルではベターだろうなとも思います。Java使ってる会社だと、有償ソリューションの方が稟議の通りが良さそうというかなんというか。

ユーザ対応がきつい

どこでも言われていることなので割愛します。リリース依頼を有償化する動きが一部であって、これがあたりまえになるのもひとつの解決のカタチなのかもしれないですね。

次があったらどうするか

コントリビュータを大切にする企業のプロジェクトに絞って貢献するとか、not open contributionなプロジェクトを立ち上げるとかを試してみたいと思っています。

それはそれとして課題を見つけたプロジェクトに対して“辻PR”を送る活動は続けていますし、Github Sponsorsで四半期ごとに自分の活動を報告すること自体は自分自身学びも多く継続していきたいと思っていますので。少しでも面白そうだなと思った方は、ご支援いただけると嬉しいです。スポンサーの方は報告のバックナンバーをご覧いただけるようにもしています。

追記

ティール組織わからん、を掘り下げる

組織の話が好物なので色々読んできたのですが、結局ティール組織はよくわからないままでした。最初に本を読んだのが5年も前なんですね。

で、自分なりに考えた結果、大きく2点においてよくわからないのだと思ったのでメモしておきます。

以下、「ティール組織」と書いた場合は書籍「ティール組織」を指します。なお昔読んだ本を読み返しながら書いているので読み飛ばしによる誤解などはあるかもしれませんし、ここ5年で新しい発見があったとしても私はそれをキャッチアップできていないことにご留意ください。

組織に人間の弱みを補う機能を求めたいのに、スキル常時発動を前提に議論が展開される

やっぱ組織を作るのは「専門家を集めてひとりじゃできないことをやる」に加えて「ひとりがダメでも他の人がいる」ことを実現したいというのはあると思うんですよ。 多様性だVUCAだバス係数だなんて難しい話は置いといて、さて自分や家族が体調を崩したときにどうするんだっけ?って単純な話ですよね。

体調管理ができてないなんて社会人失格だァなんて考え方もあるにはありますが、自分はもちろん特に家族の体調はcontrollableではないなぁというのがひとりの父親としての実感としてあります。 のでやはり柔軟にスケジュールを調整できたり他の人がフォローに入れたりしたほうが、組織としては強いと思うわけです。

で、ティール組織では以下の記述があります:

私達が自分自身のエゴから自らを切り離せるようになると、進化型への移行が起こる

進化型では、意思決定の基準が外的なものから内的なものへと移行する

なるほど。で、自らをエゴから切り離せない日はどうするんですかね? 意思決定が外的なものになってしまいがちな日は?

階層型組織では組織を機能させられない場合のためにエスカレーションがあり、Scrumだと透明度・検査・適応ができない日のためにスクラムマスターがいます。うまくいかないときに他者の助力を得る仕組みがあるわけです(そしてこれが上司の能力が組織の能力のキャップとして機能するとか、スクラムマスターに超人性を求めてしまうとかの失敗に繋がったりする)。

しかしティール組織の記述には、「上司の不在」の節におけるビュートゾルフをはじめとしたいくつかの具体的な事例が出てくるだけで、一般化が見られません。「たしかにそこに難しさがあるよね、でもうまく行ってる組織もあるしなんとかなるよ!」と言われてハイそうですかとは、さすがにならないかなと。

個人的には、組織の構成員がお互いがカバーしあうことや「助言プロセス」による意思決定を期待するのであれば、適切なタイミングでカバーに入るための情報公開・共有であったり持続可能な評価制度であったりまで踏み込んで初めて組織論と呼べるものになると思います。こうした事柄に関する記述は確かにこの本にもありますが、いずれも既存組織に多く共通するものを紹介するに留まっていて、個人的には再現性を感じませんでした。

問題解決のための手法ではない

めちゃくちゃ粗い理解として、この手の本は「上司が存在しない」ことに一定の価値を見出しています。上司がなくても組織は回る、そのために意思決定や権限管理や解雇をどうするか?という論理展開が行われます。これは一見課題に対する解決案の提示に見えますが、そもそもの「なぜ上司がいると問題なのか」の掘り下げが行われていませんし、「上司を取り除くことで解決されるのか」「上司がなくなって表面化するリスクとどう向き合うか」もあまり検討されていません。

例えば「経営陣はなく、ミーティングもほとんどない」の節にはミーティングが増えて生産性が下がることを問題として、定例ミーティングをなくし有機的なコミュニケーションで置き換えることで解決とする記述がありますが、これは上司がいるからダメというよりはマネジメントとリーダシップを混同するからコミュニケーションがうまくいってなかったやつなのでは?というように私には見えます。Team Topologyのようなチーム間コミュニケーション整理であったりチームへの権限移譲(Empowerment)であったりは今どきの階層型組織でも普通に行われることなので、何も上司をなくすなんて劇薬を持ち出さなくても……という「目的と手段のはき違い」感があるのです。

ので「上司がいなくても組織は回る」のは真だと思いますが、「上司がいても組織は回る」のも「上司がいると便利」なのも真なので、あまり組織論としては魅力的ではないなという感想になりました。Project Oxygenにぶつけて打ち勝てる本じゃないなというか。

個人的にはやっぱりこういう本は問題に対する解決手法を提示してほしいんですよね。わかりやすい例としては組織論ではないですがドラッカーの「お前の仕事は顧客の創造だ、顧客の創造にはマーケティングとイノベーションが必要だ、それぞれのためにこう考えて動け」というMECEな説明が入りやすかったです。 仮に解決を論理的に提示できず、世の成功事例を集めてその傾向を分析するに留まるとしても、Accelerateくらいのファクトに立脚した考察はほしいですね。

まとめ

結局は良い上司に恵まれてきたので「上司、いいじゃん!」が自分の意識の根底にあって、これが違和感を作ってるんだろうなと。あとまぁ人間の可能性を信じすぎというか、負の可能性から目を離しすぎというか。

今から読み直すような本ではないと思うので、マネジメントだけがリーダシップを握ることに限界を感じている方には「チームワーキング」をおすすめします。これは再現性があると感じさせてくれるというか、問題を要素に分解したうえで現状を変えるためのTODOが整理されているのでとっつきやすいです。

Threaddump, JFR, JMC周りの知識のアップデート

久々に古い知識を整理していて、けっこう更新されているものが多いのでここにまとめる。

JDK Mission Control (JMC)

JMCはOracleのウェブサイトからダウンロードできる。

標準ではOS標準のロケールが利用される。UIを日本語化する場合は jmc.iniuser.language システムプロパティを設定する。これはJVMに渡す設定なので必ず -vmargs よりも後ろに書く(Eclipseの設定と同じ)。

-Duser.language=ja

利用するJVMは jmc.ini-vm システムプロパティを設定する。これはJVM起動前に使うので -vmargs よりも前に書く。

-vm
C:\Program Files\Java\jdk-17.0.7.7\bin\javaw.exe

ThreaddumpとJFR

昔はThreaddumpファイルを複数取ってIBM Thread Dump Analyzerなどで解析していたが、今ならJFRファイルにスレッドダンプの情報が含まれるためJFRを取得すれば充分そう。

JMCで取得したJFRファイルには、期間中のスレッドダンプの情報が含まれている

JFRファイルはJMCで取得するのが一番手軽。

Gradle用のGitHub Actions勘どころ(2023年夏)

前回書いたのがもう4年前でビビったのと、最近いろいろ進展があったのでまとめてみます。

actions/setup-java の依存キャッシュを使わない

これ自分が実装した機能なのでホント申し訳ないんですけど、今なら gradle/gradle-build-action を使ったほうが良いです。 利点は公式が説明しているので読んどいてください。

github.com

spotlessApplyして差分が出たらSuggest Changeする

reviewdogが action-suggester という素敵なアクションを提供しています。GitHub Actionsでフォーマッタを実行して差分ができた状態でこのアクションを実行すると、GitHub Pull RequestのSuggest Change機能を使ってフォーマットを提案してくれます。

github.com

フォーマット適用箇所が多いと手元で ./gradlew spotlessApply したほうが早いなってケースもまぁあるとは思うんですが、やって損は無さそうです。 もちろんSpotlessに限らずktlintやPrettierのような他のフォーマッタでも利用できます。

まとめ

だいたいこんな感じじゃないですかね。リリース自動化には release-please とか semantic-release とかお好きなソリューションをご利用いただければと思います。

on:
  pull_request:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read # actions/checkoutのために必要
      pull_requests: write # reviewdog/action-suggesterのために必要
    steps:
      - uses: actions/checkout@v3
      - uses: gradle/wrapper-validation-action@v1
      - uses: actions/setup-java@v3
        with:
          distribution: microsoft
          java-version: 17 # toolchainで指定したバージョンと同じものを使う
      - uses: gradle/gradle-build-action@v2
        with:
          arguments: spotlessApply build --scan
      - uses: actions/upload-artifact@v3
        if: always()
        with:
          name: Gradle reports
          path: build/reports
      - uses: reviewdog/action-suggester@v1
        if: github.event_name == 'pull_request'
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          tool_name: spotless

またワークフロー最適化の観点ではGradleのRemote Build Cacheが非常に効果的です。勤め先ではgradle-gcs-build-cacheを使ってGoogle Cloud Storageを活用した最適化を行っています。

両利きの経営を読んだ

両利きの経営(増補改訂版)―「二兎を追う」戦略が未来を切り拓くを読みました。自分の15年間の社会人経験は探索と深化が半々という感じだったこともあり、マネジメントに加えて現場の人間の感覚でも楽しく読むことができました。

この本の結論はとても単純で、おそらくA4用紙1枚にまとまると思います。また言っていることには特に驚きはないので、うんそりゃそうだよねという感想で自分が流してしまいそうだなという直感がありました。ので自分の言葉でまとめて記憶の定着を狙おうと思います。

両利きの経営、できなくて誰が困るのか

両利きの経営ができないとビジネスが先細ってやがて食えなくなる、それ自体は別に自然であり、悪いことでもないはずです。経営者としてはたまったものではないでしょうが、従業員は次の職場でまた深化を極めていくこともできるでしょう。

私が読み始めたころは自分がERPベンダ経験者ということもあり、潰れたらインフラと化したサービスが継続できなくなると考えて、現存する顧客に対しての責任から両利きの経営を目指そうという話だと思ったんですね。ただ「カネボウはとっとと繊維から撤退すればよかったのに」などの描写から、本書の問題意識はそうではなさそうです。あくまでも法人が存続することに主眼が置かれています。

株主に対する責任であるとか、従業員の雇用を守るであるとか、激動の時代に誰も探索しなかったらほとんどの企業が破綻してしまうなどの問題意識もありますが。この本を読んでなるほどと思ったのは、両利きの経営は「大企業の組織能力や資源、顧客基盤を持ったスタートアップ」という機会を生み出す経営手法だということです。時代のニーズに応えるべく生まれたスタートアップが応えられないまま潰れていくのはよくありますし、より体力のある大企業がイノベーションに挑戦することは、社会貢献の観点からも重要な経営手法でもあるのでしょう。

のでできないと困るというよりは、できることで大企業が新たな存在価値を生み出せる経営手法だという認識を持ちました。

組織がひとつの目標に向かって動く、ときの「組織」と「目標」の捉え方

この本では深化する人と探索する人との間に適度な距離感を持たせることの必要性が語られています。「適度な」というのは、近すぎても遠すぎてもだめだということです。近すぎると深化のためのベストプラクティスや運用の工夫が探索を殺してしまいますし、遠すぎると探索が必要な資源や支援を得ることができません。私の経験を振り返っても、こういう問題は確かにあると思いました。

この本の例ではハイアールの小微(シャオウェイ)のような独立企業やHPの準部門の例が紹介されていますが、一貫しているのはそれぞれの組織が独立した目標や運用を抱えている一方で、すべての組織に共通する価値観・文化があるという点でしょう。各々の組織で直近の目標ややっていることは違っていても、企業体としての存在意義が一緒なのでひとつのまとまりとして存続し協力しあうことができると理解しました。つまり存在意義を持つ企業体の中に、目標を持つ組織が入れ子になって存在している形です。組織の間には協力関係はあっても従属関係はなさそうです。

これを普通に運用すると、組織を束ねる上級幹部はとても仕事がしにくいと思いました。なぜなら:

  • 自分のところの工数や資源を他の「組織」に貸す必要があるが、そのリターンが見えないことが多い(自分の成果を犠牲にしてほか組織の成果に賭けることを意味する)
  • 特に深化の組織は持ち出しが多く、顧客や市場からのプレッシャーと板挟みになることが容易に想像できる
  • 深化の組織ではその部下から「探索の組織が自由気ままにやっているが自分は規律のもとに数字を追いかけている」という不満が出てきそう
  • 探索の組織でも同様に、安定した深化の組織を横目に「売上が上がらない、結果が出ない」ことに対するプレッシャーと向き合わなければならない

この本で出している解決策は「上級幹部の評価を自部門の成績で行わない」こと、すなわち企業体としての成績を持って評価することなのですが。責任を負うものと評価対象がねじれていて本当に機能するのか(他部門の悪状況に引っ張られている場合に上級幹部が転職を検討しそう)とか、じゃぁその下の管理層はどう評価するのか?とか考えると、やはり一筋縄では行かないですよね。上級幹部の下に深化と探索の両部門を置いて上級幹部の裁量でよしなにやってくれ、ということにする誘惑はけっこうありそうですが、それでは失敗するというのが第8章のハヴァスの事例から明らかなので、企業体として向き合わなければなりません。

考えられる最善は、上級幹部が人事評価の裁量を持ったうえで、他の組織に資源を貸し出したことを前提に本業の成績を持って部下を評価する……というものでしょうか。不満や不安も上級幹部が粘り強いコミュニケーションで自組織内で解消させる必要があります。これも言うのは簡単だがというやつで、上級幹部に人徳や公平性,タフネスといった超人性を求める運用になりそうです。

まとめると、この本では「組織を入れ子構造にすることで、存在意義や組織能力などの共有を実現しつつ運用や目標は分けると」いう矛盾を管理可能な形に落とすことを推奨しています。 この矛盾を維持するにはCEOや上級幹部の献身が欠かせません。特に組織(我々)という主語がコンテキストによって変わるであろうことを考えると、上級幹部にかかる部下への説明責任は非常に大きいものと感じました。マイシスの事例の「我々は800万ドル削減する必要がある、ただし探索組織の予算には手を付けない」が象徴的で、都合のいいときだけ一心同体だと言いやがってみたいな反応は普通に出てきそうだなと思います。この問題こそが両利きの経営が難しい理由であり、優秀なトップひとりではなく上級幹部を巻き込んで組織を作っていく必要性を強く裏付けるものだと思いました。

上級幹部ではない従業員として何ができるのか

やっぱり気になるのはここなんですが、直属の上級幹部ときちんと話をして両利きの経営を意識してもらう、くらいしかできることがない気がします。トップが変わったときに探索部隊をどうするか、深化と探索のバランスを考える人なのかを見る上ではこの本が紹介する知識や事例は役に立つと思いますが、その結果探索を縮小・停止する人だなと判明したときに、それを覆すのはほぼ無理ですよね。その人が入った時点で既定路線のはずなので。

ので自分が深化を極めたいのか、探索で結果を出したいのか、両利きの経営を実践するリーダーとして伸びていきたいのかを日頃から考えておいて、深化や探索のバランスが変わったらそのシグナルを早期にキャッチして動いていく、しかない気がします。

あとは深化と探索は異なるものでそもそも相容れないのだ、ということを頭に入れておくとコミュニケーションがやりやすい局面はありそうですね。多様性多様性と言われますが、何がどう多様でコミュニケーション上の要配慮点はどこかを知っておくだけでも助かることは多いので。深化は厳しいんだ、探索は心細いんだ、ということをざっくり踏まえておくだけでも、同僚の仕事を知って尊敬する機会はすごく増えると思います。

Cloud RunがImage not foundと言ったときの原因事例集

Cloud Runはとても便利なのですが、エラーメッセージがわかりにくいことがあります。特にデプロイしたときに遭遇するこちらのエラーが厄介です:

ERROR: (gcloud.run.deploy) Image 'asia-northeast1-docker.pkg.dev/foo/bar/baz' not found.

コンテナを引っ張ってこれなかったときは原因が何であれこのメッセージだけ残してデプロイが失敗するので、自分で切り分けなければなりません。ここ数ヶ月で複数の原因に遭遇したので記録を残します。

指定したタグを持つコンテナがない

docker build はしたけど docker push はしてなかったケース。見つからなかったのは指定したタグを持つイメージなのですが、エラーにはアクセス先レジストリそのものが見つからなかったかのように出てくるので要注意です。

Cloud Run Service Agentに権限がない

公式にはこちらのページで説明されています

project-aのCloud Runから他のプロジェクトproject-bにあるArtifact RegistryやContainer Registryからコンテナを引っ張ってくるときに、project-aのCloud Run Service Agentに適切な権限がないと失敗します。なおCloud Run Service Agentは service-PROJECT_NUMBER@serverless-robot-prod.iam.gserviceaccount.com という名前を持っています。

Artifact RegistryであればArtifact Registry Readerロールが、Container RegistryであればStorage Object Viewerロールが必要になります。

イメージのマニフェストがおかしい

docker/build-push-action を導入したときに遭遇しました。docker/setup-buildx-actionと組み合わせると application/vnd.oci.image.index.v1+json media typeを持つイメージにタグが打たれるようになり、これをCloud Runは扱えないようです。イメージが使えるものだということは docker run で確認したし、公式によるとOCI image formatはサポートしているようなのですが。

docker/build-push-action 単体だと docker build 時と同様に application/vnd.docker.distribution.manifest.v2+json media typeを持つイメージにタグが打たれるため、Cloud Runでも扱えるイメージができます。

2023/01/23更新

こちらはbuildx 0.10の挙動変更による影響でした。

github.com

対策としては docker/build-push-action の設定に provenance: false を追加することが推奨されています。