解せぬ日記

雑な話をする

Web APIにおける認可の現状確認 2019 春

最近Web APIの認可について思いを馳せる機会があったのだけど、どの方法で認可を実装するのがスタンダードなのか、そもそもそんなものは最初からないのか、よく分からなくなったので自分なりの考えをまとめることにした。

ファーストパーティのアプリが使うWeb API(プライベートなWeb API)の場合はセッションを使うケースもあるだろうが、セッションを使うケースでは悩むことも少なかったので、ここではアクセストークンを用いた認可にフォーカスして考えてみたい。ケースとしてはユーザー毎にアクセストークンが発行され、Browser-BasedアプリやNativeアプリからWeb APIが叩かれることを想定している。

追記 2019/03/04

認証や認可周りについてよく拝見させてもらっている方にブログで言及していただきました。合わせて読むことをお勧めします。

ritou.hatenablog.com

特にResource Owner Password Credentialsの説明はよく目を通してください。僕が混同している可能性があります。頭の中で整理できたら記事を訂正したいと思ってますが、まだできておらずそのままになっています。すいません。

認証/認可の現状について

普段、開発をしていると色々なサービスがサードパーティへ公開しているWeb API(パブリックなWeb API)をよくさわる都合上、OAuth 2.0を用いた認可の実装、OpenID Connect 1.0を用いた認証/認可の実装の様子を目にすることが多い。それぞれOAuth2とOpenID Connectとここからは呼ぶことにするが、パブリックなWeb APIを作るシナリオを考えている場合はOAuth2、または OpenID Connectのプロバイダになるのがスタンダードだと認識している。ただ多くのサービスで最初に用意するのはプライベートなWeb APIだろう。

ここで一つの疑問が湧いてきた。プライベートなWeb APIの認可はどう実装していくのがスタンダードなのか?ファーストパーティのアプリのためだけにOAuth2やOpenID Connectを実装するのか?

例えばSPAのようなBroswer-Basedアプリに対してのOAuth2について書かれたDraftには以下のようなことが書かれている。

While OAuth and OpenID Connect were initially created to allow third-party applications to access an API on behalf of a user, they have both proven to be useful in a first-party scenario as well.

https://tools.ietf.org/html/draft-ietf-oauth-browser-based-apps-00#section-5

Draftでかつ00ではあるが、OAuth2とOpenID Connectがファーストパーティにとっても有用であるという主張は分かるし、現にAuth0などでもOAuth2を使うことで自分たちのアプリケーションへAPIアクセスを提供できるとドキュメントで言及されている。

auth0.com

その一方で、それなりの割合で独自の認可方式を実装していたりするのを見かける。僕自身も独自の認可方式を実装したことがある。OAuth2の仕様を調べれば調べるほどプロバイダの実装が大変であることが分かり、独自の認可方式を用意するほうが楽なように思えたからだった。そしてOAuth2を実装するライブラリが揃ってきたとは言え、2019年現在でも実装は楽ではないなと思っている。だからこそ認証/認可のマネージドサービスが生まれているんだろう。

独自の認可方式を実装することは楽なのか?

上記で述べたようにOAuth2を実装することはそれなりに大変だなと思ったので、独自の認可方式を実装するならどうなるのかということを改めて考えてみた。例えば以下のようなものがパッと思いつくプリミティブな実装だろう。

  • OAuth2で言うところのResource Owner Password CredentialsのようなSomethingでusername/passwordを渡すとアクセストークンのみが払い出される

OAuth2のResource Owner Password Credentialsは以下のようなフローでアクセストークンが発行される。

     +----------+
     | Resource |
     |  Owner   |
     |          |
     +----------+
          v
          |    Resource Owner
         (A) Password Credentials
          |
          v
     +---------+                                  +---------------+
     |         |>--(B)---- Resource Owner ------->|               |
     |         |         Password Credentials     | Authorization |
     | Client  |                                  |     Server    |
     |         |<--(C)---- Access Token ---------<|               |
     |         |    (w/ Optional Refresh Token)   |               |
     +---------+                                  +---------------+

要はこれと同じようなものを実装する。これはめちゃめちゃ実装が楽だと言える。ただOAuth2のResource Owner Password Credentialsの説明を眺めていると、どうやらこれだけでは足りないということが分かってくる。セキュリティ的な問題をクリアするためには以下のようなものを実装したほうがいいだろう。

さらに、Browser-Basedアプリでアクセストークンを使う場合は、セキュアにログイン状態を維持するための仕組みが必要になる。例えばユーザーの認証を通してアクセストークンを更新する仕組みだ。OpenID Connectを実装してSilent Authenticationのような仕組みを用意したり、それに近しい仕組みが必要になる。

auth0.com

これはBrowser-BasedアプリがPublicなクライアントなのでリフレッシュトークンは発行すべきではないからだ。そろそろ役目を終えそうなImplicitでもリフレッシュトークンは発行すべきではなく、もしどうしても発行したいなら頻繁にリフレッシュトークンを変えるような方法を取るように書いてある。もっともファーストパーティのBrowser-Basedアプリではセッションを使うという方法も取れるので必須ではないと思う。

この他に実装上の問題点も分かってくる。

  • ファーストパーティのクライアントのなりすましに気づくポイントが少ないことにどう対応するか
  • 自然と中間者攻撃の様相を呈していないか
  • 独自の実装で生まれうる脆弱性にどう気づくか

これらを考慮しながらアクセストークンの期限、リフレッシュトークン、クライアントの特定方法まで実装してくるとほとんどOAuth2の実装に足を踏み入れ始めているのではないかと思う。これに加えて独自の実装で生まれる脆弱性についても思いを馳せる必要があるが、それを考慮しきれるのかという不安がとにかくヤバイ。Bearトークンを採用しようがJWTを採用しようが考えないといけないことだと思っていて、JWT便利でしょといってリフレッシュの仕組みも用意せず、生存期間の長いアクセストークンを用意しているとかだとかなり問題があるのではないかと思っている。つまり独自の認可方法を用意するのは全然楽ではない。認可それ自体がセキュリティとセットで意味をなすので、そもそも楽な方法などなく歯を食いしばって実装する類のものなのだろう。

ちなみに、OAuth2のRFC6749の中でResource Owner Password Credentialsは以下のように説明されている。

The credentials should only be used when there is a high degree of trust between the resource owner and the client (e.g., the client is part of the device operating system or a highly privileged application), and when other authorization grant types are not available (such as an authorization code).

https://tools.ietf.org/html/rfc6749#section-1.3.3

大事なのは「他のGrantが利用できないとき」という部分で、これはAuthorization CodeがBroswer-BasedなアプリやNativeアプリに対してほとんど場合で適用できることを考えると選択しないほうが好ましいということだと思うし、Nativeアプリに対するOAuth2について書かれたBCP212はAuthorization Code前提で書かれている。

https://tools.ietf.org/html/bcp212#section-4.1

したがって簡単に実装できると思っていたResource Owner Password Credentials方式はOAuth2では限定利用に留める方向になっていて、独自に実装する際はこの限定利用の壁を壊す俺の最強武器を用意する必要があり、セキュリティに明るくない僕には無理ゲーな上に新規プロダクトのコアにほとんどなりえない認証/認可に時間を吸われる結果になるのではという思いに至った。

まとめ

ここまで考えてみると、実装はそれなりに大変だが認可のフローや脆弱性をたくさんの目を使って議論しているOAuth2やOpenID Connectなら仕様は既にあるし、プロバイダになるにあたって気をつけるべきことは論じられているので、ファーストパーティが使うWeb APIだとしてもOAuth2やOpenID Connectを採用しつつ、Authorization CodeやPKCEなど必要最低限の実装を持ったプロバイダを実装するのが2019年春現在考えうる最良の認可なのではないかと思う。あくまで最初に想定しているケースの場合なので、Confidentialなクライアントだけしか存在しない場合だったりするとClient Credentialsのような仕組みで十分なこともあり得るだろう。

途中で湧いた疑問

ちなみにOAuth2を採用してAuthorization Codeを使う場合、ファーストパーティのアプリに対して認可の画面が出てくるのはもしかしたら少し違和感があるかもしれない。ファーストパーティのアプリのみ認可の画面をスキップするとかという話も耳にしたことがあるのだけど、正しい方法はちょっと分からないので知りたい。Client IDが漏れる可能性を考えても、Redirect URIの完全一致を検証することにより、スキップしても問題ないような気がするがどうなのだろうか?

最後に

僕は認証/認可に明るいわけではないので、間違っていたりおかしい箇所についてはぜひアドバイスをくださいと思っている。OAuth2やOpenID Connectを実装しようという結論にしてもめちゃめちゃ自信があって言ってるわけではないので、より良い方法があるならぜひ知りたい。サードパーティが使うWeb APIならOAuth2なり実装するでしょという感じだと思うのだが、ファーストパーティに関してもOAuth2で実装するのが当たり前すぎるのかあまり言及されてない気もする。たぶん当たり前なのかも知れない。あるいは既に当たり前な別の方法があるのかもしれない。基本的に最初から認証/認可系のマネージドサービス使っててハッピーですとか。正直なところ、認証/認可の話をブログに書いたりするのは個人的にめちゃめちゃ勇気が必要だった。知り合いしか見てないと分かっていても。

ロールベースアクセス制御を試せるサンプルを書いた

世の中には便利最高なサイトが存在していて、 SaaSやるにあたっての用意したほうがよい機能群を網羅したサイトがある。

www.enterpriseready.io

その中で権限管理に関する言及もあって、RBAC(ロールベースアクセス制御)について書かれている。RBACに関してはググれば出てくるので割愛するが、割とこういったスタンダードな実装をしてるケースは個人的な体感ではあまり出会ったことがなくて、組織やロールで権限を判断する実装とかをよく見かける。ロールで権限を判断する実装というのは、例えばManagerというロールだったらこのオペレーションの実行を許可するみたいな感じ。僕自身もそういった実装をしたことがあるが、そういう実装だと割と自由度が低く、すこしイレギュラーなケースではもにょる実装をしてしまうことになりがちだった。RBACで実装しておくと色々応用が効くので便利だと思う。GCPAWSの権限管理とかもRBACがベースになっている感じがする。

ということで基本となるRBACのプリミティブな実装をRubyで用意して色々実験できると捗るなと思ってそういうサンプルを書いてみた。データベースにおける登場人物は以下のような感じ。

  • Users
  • Roles
  • Permissions
  • RolesとPermissionsの交差テーブル(中間テーブル)

あくまでこれらのテーブルはプリミティブな実装にすぎず、テーブルを追加することでユーザーが複数のチームに所属して、チーム毎にメンバーのロールを変えたいとかって要件を表現できるようになる。この辺の詳しい解説はいくらでもあるので、そっちに任せることにする。

サンプルではMarioがAdmin、PeachがManager、LuigiがMemberみたいな感じにしていて、Roleを管理する権限を前提にMarioはRoleのCRUDができる、PeachはRoleのDができないだけ、LuigiはRoleのRができるみたいな感じになってる。

正直Rails界隈ではcancancanみたいなライブラリもあるので、わざわざサンプル書いたことをブログにアウトプットして価値あるのかなとも思うけど、RBACを色々試したい人にとっては参考になるかなと思って筆をとった。

Rubyでの実装を試すruby-sandoxという個人のリポジトリ内にコードがあり、余計なコードまでcloneされるので覚悟してほしい。ぶっちゃけ僕の怠慢です。すいません。

github.com

よければ試してみてください。何か僕が間違っていればぜひフィードバックがほしいので、よろしくお願いします。

近況報告

僕の知り合いへ向けての報告です。去年の12月末で前職を退職してフリーランスになりました。ここまで書いて、前回の近況報告でお知らせした無職から職を得た話をしてなかったことを思い出しましたが、また職を失ったのでもうその話はいいですね。

年末の最終出社日から1月中旬ぐらいまで開業準備をしていました。ググればすぐ出てくるんですが、もしフリーランスをやるならちゃんと無職になる前に準備したほうがちょっとだけ幸せになれます。なお僕はしませんでした。僕みたいな雑に生きてるタイプの人間は無職になる前に準備せずとも、たぶんまあいいかで済むので別に準備しなくていいです。開業Freeeとか使えば特に面倒な手続きもなく準備できます。有り難しですね。ただ健康保険の任意継続と開業費や電子帳簿保存の手続きについては調査しときましょう。開業費に関してだけはちょっと失敗したなと思っています。

開業準備も終えたので、とりあえずちょっとだけ仕事をしながら子供との時間を作りたいなと思ってることもあり、現在は時間にすると週1日ぐらい働いていて、プロダクト開発の技術的な部分に関するアドバイザーみたいなことをしてます。これはちょっと特別な事情もあっての仕事で、メインの働き方はプログラマとしてコードを書くという感じをイメージしています。

フリーランスでの仕事をそろそろ探そうかなと思っているので、一応前職で何やってたかぐらいは書いておきます。

  • DockerとGolangでのAPIの開発
  • Clean Architectureでの設計の改善
  • TerraformでのGCPのインフラ管理
  • k8sへのアプリケーションのデプロイ
  • CircleCI上でのテストを3倍高速化
  • RailsアプリケーションのN+1の撲滅
  • ドキュメントの整理とそれに関する技術書典への執筆
  • 技術的課題に対する方針の決定
  • スクラムにおけるプロセスの改善

以上のようなことを大まかにはやってました。 主にサーバーサイドの仕事をやっていましたが、以前はiOSアプリ開発などもやってました。最近はフロントエンドのキャッチアップができてなかったので、暇な時間でTypeScriptやら触っています。職歴はLinkedInとかにまとめてあります。

https://www.linkedin.com/in/terunori-togo/

これはオブラートに包んで言うと「僕に仕事をください!!!!!1」ということです。あとサバンナに入ってみたいんですが、誰か招待してくれませんか…ぼっち力が高くてですね…。

どうでもいい話をすると職があったときは定期的に職場の人を誘ってフットサルをしてたんですが、フリーランスの人ってフットサルとかどうしてるんですか?

Arch Linuxでffmpegの依存解決に失敗する

今日、ArchLinuxのパッケージをいつものようにアップデートしようとしてハマった。解決策がネット上に見当たらなかったので書いておく。

遭遇したエラーは以下のような感じだった。

$ yaourt -Syua                                                                  
[sudo] password for terut:                                                      
:: Synchronizing package databases...                                           
 core is up to date                                                             
 extra is up to date                                                            
 community is up to date                                                        
 multilib is up to date                                                         
 archlinuxfr is up to date                                                      
error: failed to prepare transaction (could not satisfy dependencies)           
:: Starting full system upgrade...                                              
resolving dependencies...                                                       
looking for conflicting packages...                                             
error: failed to prepare transaction (could not satisfy dependencies)           
:: unable to satisfy dependency 'libx265.so=160-64' required by ffmpeg          
No database errors have been found!

どうやら依存が上手く解決できないように見える。 ffmpegのバージョンは 4.0.2-3 が入っていて、ffmpegのパッケージのバグページを見てみると 4.0.2-6 で直るらしいことが分かった。

bugs.archlinux.org

データベースのアップデートをしてもffmpeg4.0.2-4 しかなかったので、仕方なくffmpegのパッケージサイトからミラー経由でダウンロードして直接入れた。

Arch Linux - ffmpeg 1:4.0.2-6 (x86_64)

右上の [Download From Mirror] からダウンロードできる。 ダウンロードしたら直接インストールしてしまう。

$ yaourt -U ~/Downloads/ffmpeg-1_4.0.2-6-x86_64.pkg.tar.xz                      
resolving dependencies...                                                       
looking for conflicting packages...                                             
error: failed to prepare transaction (could not satisfy dependencies)           
:: installing x265 (2.9-1) breaks dependency 'libx265.so=160-64' required by ffm
peg                                                                             
loading packages...                                                             
resolving dependencies...                                                       
looking for conflicting packages...                                             
                                                                                
Packages (2) x265-2.9-1  ffmpeg-1:4.0.2-6 
...

エラーが出ているが、これは現在のffmpegのバージョンによるエラーっぽい。ffmpeg4.0.2-6libx265.so=165-64 に依存しており、x265-2.9.1libx265.so=165-64 として提供している。依存関係からすると同時にインストールしてしまえば問題なさそうだったのでインストールした。 結果として、ffmpeglibx265.so=165-64 版の共有ライブラリに依存するようにインストールされていたので良さそうに見える。 ひとまずこれで全体のアップデートができるようになった。 すでに ffmpeg4.0.2-6 がデータベース側にも反映されてるので、同じように依存でアップデートできないぞという人は参考にしてほしい。

GCPの検証・本番環境をTerraformで上手く管理する方法

Goodpatch Advent Calendar 2017 - Qiita の24日目は @terut がお送りします。

さてさて12月24日ですが、みなさんリア充してますか? 24日は若者に書かせるわけにいかないので、24日のアドベントカレンダーはおっさんの仕事というのが相場のようです。

最近GCPの管理のためにTerraformに入門しました。入門しながら思ったのが、検証の目的に合わせて複数の環境を作るのが面倒くさいということです。Terraformで管理する場合、Terraform用のサービスアカウントを用意したりするのですが、普通にやってしまうとプロジェクト毎にTerraform用のサービスアカウントを準備しなくてはならず、さらにビリングアカウントへの紐付けをある特定の人へお願いしたりという作業が発生します。もうちょっといい方法がないものかと思って色々と調査をしたところ、GCPのリソースは階層構造を持っておりIAMポリシーは継承されるので、それを上手く使うのがよさそうな雰囲気を感じて、試してみました。

TL;DR

前提条件

組織で管理する中でどのように階層と権限を設計するかという話だったので、一応環境を揃えるために組織で管理する環境を作りました。自分のドメインがあれば、Cloud Identityを使って申請できます。ドメインを自分のものであると証明するために、DNSへTXTレコードかCNAMEを登録する必要がありますが、15分程度あれば登録して、組織で管理された環境を作れます。なおドメインに関連したアカウントを作る必要があり、そのアカウントにも$300が有効にできるので、今回のこの方法でお金がかかることはないですが、ロボットでないことを証明するためにクレジットカードは入れなければなりません。

support.google.com

環境の構築方法

基本的は上に紹介した Managing GCP Projects with Terraform  |  Google Cloud Platform Community  |  Google Cloud Platform の流れに沿って環境を作っていくことになります。IAMのポリシーの継承を上手く使うため、Adminプロジェクトを作り、その中でTerraformで管理するためのサービスアカウントを発行し、他のプロジェクトを管理する権限を与え、すべてのプロジェクトをそのサービスアカウントで管理するというイメージになります。

https://storage.googleapis.com/gcp-community/tutorials/managing-gcp-projects-with-terraform/diagram.png

一通りリンクの手順を試してみると分かりますが、このままではAdminプロジェクトで管理された一つのtfstateファイルに変更が反映されていきます。そこでTerraformのworkspaceの出番です。

$ terraform workspace new staging

これを実行するとAdminプロジェクトのCloud Storage上には staging.tfstate が出来ているのが分かると思います。workspaceの値はtfファイル内で参照できるので、ディレクトリでtfstateファイルの置き場所を分けたりといったことも出来そうです。Terraformのworkspaceを上手く使いながら、一つのTerraform用のサービスアカウントを用意することで、すべてのプロジェクトが管理できるような感じがしますね。

まとめ

GCPのリソース階層へのIAMポリシーの継承などを使い、管理用のサービスアカウントを用意することで、すべてのプロジェクトで同じような手作業をするということが避けられ、ほぼすべてをTerraformに任せられそうです。入門したてなので、もっといい方法や普通はこうやるんやでなど、色々なアドバイスをお待ちしてます。

そういえばまったく関係ないんですが、12月25日は僕の誕生日でした。いつものやつ貼っておきますね!

http://amzn.asia/8zIyv8F

「ですます」であまり書かないので不思議な気持ちやな〜。

画像ビューアを作ってみている話

macOS用の見開き画像ビューアがほしいなぁと思い、車輪の再発明をすべく画像ビューアを作り始めた。最初Electronで作っていて、最小の機能の付いたそれっぽいものを作った段階でいかんともしがたい問題にぶつかり、一旦、他の技術も見てみようと、QtのGoバインディングで作り直してみてる。

成果

何はともあれ成果です。

vimeo.com

vimeo.com

Electronの問題

Electronで一通り作り終えた時に、サムネイル画像のキャッシュなどを作らずにオリジナルで表示してたので、メモリの使用量がどんなものになるのか気になって調べた。いろいろ調べているうちに、macOSで画像を切り替えまくると爆速でメモリが1.5GBぐらいまで増加していくことが分かった。画像自体は全体で110MBほどなのでいくら何でもひどい。待っていても開放される気配は一切なく、Chromeのプロファイラを見た限りではJS Heapなどはたいしてメモリを食っていなかったのとGCは走ってるように見えたので、DOMリークなのかなと思っている。とにかく何をしても解消しなかった。Chromiumの複数バージョンを試して、それっぽいバグは再現できたけど、既にバグ報告はしてあり最新版では再現しない。加えてWindowsLinuxでは特に問題なくてメモリも開放されてるので、内部のChromiumのバージョンが上がったら直りそう。ちなみに次のバージョンでは直ってなかった。

QtのGoバインディング

github.com

上記のやつを使っている。ただデバッグがやりにくくて萎えそう。独特の文法みたいなものが必要にはなるものの、サンプルも結構用意してあるので、それを読めば割とイケる。

https://github.com/therecipe/qt/tree/master/internal/examples

Qt自体はQMLというインターフェースのためのマークアップ言語を用意していて、Javascriptが利用可能でJavascriptにロジックを追いやったりできるので、そこはとっつきやすい。ちなみにQtの最新版である1.9.1を使っていたら、QMLのImageでメモリリークが起こっていて、笑うしかなかった。バージョンを下げて対応した。

今後

QtのGoバインディングのデバックについて、もうちょっといいやり方がないか調べたりして、知見ためたい。もう少し試してみて、ElectronかQtのGoバインディングにするか決めようと思っている。

雰囲気でマイクロサービス入門をやってみた

ごんげお兄さんのエントリーを見て、興味あったのでやってみた。

gong023.hatenablog.com

TL;DR

  • お兄さんのエントリー通りやると、雰囲気が分かるので超お勧め
  • 動かしてからドキュメント眺めたらいいと思う
  • GCP初めての人は$300のクレジットが貰えるぞ!

ありがたいなぁ。

補足

僕の環境はArch Linuxでかつ、GCPを触るのが初めてだったこともあって、いくつか追加の作業が必要だったのでそれだけ書いておく。最初にGCPのアカウントを開設して$300のクレジットを貰っておくように。

コマンドラインツールのインストール

AURにある。

$ yaourt -S google-cloud-sdk
$ gcloud auth login

# /opt以下に入るのでsudoで実行
$ sudo gcloud components install kubectl

初めてのコマンド前に認証が必要。ターミナルのコマンドからブラウザが起動してターミナルに処理が戻るの初めて見たかも知れない。

結構頑張ってついて行ってるのに、out-of-dateフラグ立てられてるのがかわいそう。僕もheroku-cliパッケージでたまに立てられるので気持ちは分かる。

コマンドラインツールの設定

リージョンやらプロジェクトやら色々設定しておいたほうが毎回オプションを渡さなくて済む。configの設定については https://cloud.google.com/sdk/gcloud/reference/config/set を眺める。

$ gcloud config set project micro-sample-XXXXX

Container Registry 有効化

dockerのimageをpushする際、Container Registryというサービスにpushするのだけど、これは有効化されてないとpushできない。ブラウザのコンソールから有効化するとよい。

環境変数の設定

対象のコードではBACKEND_SERVICE_NAMEという環境変数を使ってるので、その設定がいる。暗号化の仕組みも用意されてそうだった。バックエンドのIPを見たら設定しておく。たぶんドキュメントとかにコマンドラインとかから渡す方法が書いてあるんじゃないのって思ってるんだけど、どうなんすかね?

2017/10/06 追記

お兄さんにDNSあるよって教えてもらったので、そっちを使うほうが良さそう。IP変わるのでおっしゃる通りすぎる。コメントを参照のこと。ハマりどころがあって勉強になったぞ!!!!!!!1

ドキュメントによればKubernetes 1.3からDNSがビルトインされたようで、Serviceの名前がfooでKubernetesのネームスペースがbarの場合、foo.barで対象のServiceのクラスタIPが解決できる模様。ネームスペースやDNSの様子は以下のコマンドで眺められた。

$ kubectl get namespaces                                                                                         
NAME          STATUS    AGE                                                                                    
default       Active    19m                                                                                      
kube-public   Active    19m                                                                                      
kube-system   Active    19m 

$ kubectl get svc --namespace=kube-system                                                                        
NAME                   CLUSTER-IP      EXTERNAL-IP   PORT(S)         AGE                       
default-http-backend   10.31.249.157   <nodes>       80:31925/TCP    21m
heapster               10.31.247.113   <none>        80/TCP          21m
kube-dns               10.31.240.10    <none>        53/UDP,53/TCP   21m
kubernetes-dashboard   10.31.245.255   <none>        80/TCP          21m

$ kubectl get svc --namespace=default                                                                            
NAME                            CLUSTER-IP     EXTERNAL-IP    PORT(S)        AGE                                 
kubernetes                      10.31.240.1    <none>         443/TCP        22m                                 
micro-sample-service-backend    10.31.244.62   <none>         8000/TCP       17m                                 
micro-sample-service-frontend   10.31.249.64   XX.XX.XX.XXX   80:32186/TCP   21m

ということで、バックエンドはmicro-sample-service-backend.defaultで引けることになる。 ちなみにPodの中にはresolv.confが用意してあって、ドキュメントに書いてあるように以下のような定義になっている。

$ kubectl get pods
NAME                                               READY     STATUS    RESTARTS   AGE
micro-sample-backend-deployment-3300239719-22qdm   1/1       Running   0          38m
micro-sample-backend-deployment-3300239719-mpjh9   1/1       Running   0          38m
micro-sample-frontend-deployment-836517767-3vgzv   1/1       Running   0          10m
micro-sample-frontend-deployment-836517767-vbbrp   1/1       Running   0          10m

$ kubectl exec -ti micro-sample-frontend-deployment-836517767-3vgzv -- cat /etc/resolv.conf
nameserver 10.31.240.10
search default.svc.cluster.local svc.cluster.local cluster.local c.micro-sample-XXXXX.internal google.internal
options ndots:5

なのでネームスペースがdefaultの場合は、micro-sample-service-backendだけでも引けるわけだけど、ネームスペースがいつもdefaultとは限らないので、ネームスペースと組み合わせた名前で指定しておくのがいいと思う。

追記終わり。

...
     containers:
      - name: micro-sample-frontend
        image: gcr.io/micro-sample-XXXXX/micro-sample-frontend:v0.1
        env:
          - name: BACKEND_SERVICE_NAME
            #value: 10.31.XXX.XXX
            value: micro-sample-service-backend.default
        ports:
...

Podの削除

せっかくなので、Podを消してみると不死鳥のように蘇る様子を見ることが出来る。

$ kubectl get pods
NAME                                               READY     STATUS    RESTARTS   AGE                            
micro-sample-backend-deployment-3300239719-ghw8q   1/1       Running   0          5m                             
micro-sample-backend-deployment-3300239719-h8nwp   1/1       Running   0          5m                             
micro-sample-frontend-deployment-602895698-qrwfk   1/1       Running   0          4m                             
micro-sample-frontend-deployment-602895698-ts2kr   1/1       Running   0          4m

$ kubectl delete pod micro-sample-backend-deployment-3300239719-ghw8q 
pod "micro-sample-backend-deployment-3300239719-ghw8q" deleted

$ kubectl get pods
NAME                                               READY     STATUS    RESTARTS   AGE                            
micro-sample-backend-deployment-3300239719-h8nwp   1/1       Running   0          6m                             
micro-sample-backend-deployment-3300239719-ppzf9   1/1       Running   0          9s                             
micro-sample-frontend-deployment-602895698-qrwfk   1/1       Running   0          5m                             
micro-sample-frontend-deployment-602895698-ts2kr   1/1       Running   0          5m

ありがたいなぁ。