Cloud Penguins

Flying penguins in the cloud.

IBM Cloudの課金問題、解決(・・・と、DevRelはダメだという話) ※追記の追記あり

背景

一部の界隈をざわつかせたこちらの件。

IBM Cloud (旧Bluemix) のアカウントを持っている人は今すぐクレジットカードの請求を確認すべき ※追記の追記あり - Cloud Penguins

IBM Cloudからの不意打ち請求はあろうことか2重請求だった ※追記あり - Cloud Penguins

解決

IBM Cloudの利用者にはメールでも通知されていると思うが、3月4月分の返金を行うということで方針がきまったそう。一番の問題点であった、一部ユーザーにプラン変更の通知メールが飛ばなかった原因については現在も調査中とのことだが、結果がわかり次第公開してもらえるとのこと。

www.ibm.com

調査結果も纏められているので、今回の問題に当たってしまった方は読んでおくと良いかも。

ひとまず利用者にとってはベストな形の対応方法をとってもらえることになったので、個人的にはこれで解決かなと思う。

しかし上記報告の中にある

その後の調査によって、44件のクレジットカードへの二重請求があったことが分かり、うち43件は2度の決済処理が原因でした。1件は2度の決済処理のうち1回がエラーで決済できなかったため、書面での振込依頼を行ってしまいました。

よりによってその1件の特殊ケースがウチだったんだなぁ。振込依頼のメールがなければ今回の問題に気づくのは大分後になったと思うので、また違った展開になったかもしれないね。あと、二重決済をきちんとブロックした楽天カードGJ

解決に至るまでの経緯

5/15(金)

  • 昼 カード決済が出来なかったから振り込みをしろというメールが来る
  • 14時頃 メールに気づく。最初は自分のミスかと思いアチャーとなるが、調べてみると事前通知がない。そりゃー無いでしょとPaaS勉強会のSlackにボヤく。 f:id:jaco-m:20200522205841p:plain
  • 15時頃 サポートに課金が不当である旨のチケットを上げて、仕事に戻る
  • 夜 FacebookのBluemix User Groupに、『そういや3/1に有料化したからチェックしといてね~』的な投稿が行われているのに気づく。いやいやそれ有料化前に告知すべき内容でしょとイラッとする。IBMのデベロッパーアドボケイトに文句を言うがガン無視される

5/16(土)

  • 朝 カードに課金が行われていることに気づく。このときは二重課金かどうか確証がなかった。
  • 夕方 FBやTwitterで同様の課金を食らっている人が居ることに気づく。
  • 夕方 再度デベロッパーアドボケイトに文句を言うもガン無視される。埒があかないので問題をまとめて公開することを決める。
  • 一つ目の記事公開

5/17(日)

  • 朝 利用額等をチェックして二重課金であることを確信する。
  • 夕方 サポートチケットに二重課金の問題も追記する。まだ返信は無し。
  • 夕方 周囲のIBM関係者からも一切反応がない。これでは埒があかない(2度目) と感じ2つめの記事も公開

5/18(月)

  • 朝 Bluemix User Groupの投稿で、サポートチケットに日本語で送っても対応してもらえないことを知る。Blogじゃなくてもっと分かる場所に書いて欲しいな。
  • 昼 上記ブログに、電話とチャットなら日本語で受け付けしていると書いてあるのを見て、電話をする。 しかしバリバリ英語での対応であった。(こうなることは予感していたので、心の準備はしていた)。 内容が内容なので、日本人に代われない?と聞いたところ、電話では日本語対応していないがチャットならOKだよと言われる。
  • チャットを開始する。しかし英語で返ってくる。まぁそうじゃないかと思ってたよ。 billingについて聞きたいことがあるから日本人に代わっておくれと言ったところ、日本人の営業が出てくる。
  • なんで営業?と思いつつ、今回の問題と返金要求をぶちまける。返答がしばらく無く、ここで昼休憩が終わってしまう。
  • 14時ごろ 上記チャットにサポート担当から返事があることに気づく。『プラン変更についてはメールで通知したはず』『3月分の請求に関しては返金対応を行う』『4月分に関してはまだ請求を行っていないので、請求されたら返金するから再度チケットを上げて欲しい』との返信でチャットがクローズされていた。
  • 返金対応が行われる点については良かったが、メール通知を行ったという主張には不満を抱いた。
  • 夜 クラウド&コグニティブ・ソフトウェア事業本部の方から直接コンタクトがあり、対話を開始。『あるべき通知が送られていないケースを確認できており、急ぎ対応方法を検討している、ユーザーにはWebおよびメールで経過報告を行う』という旨を連絡いただく。 非常に真摯な対応でだいぶ溜飲が下がる

5/19(火)

5/22(金)

まとめ

月曜にコンタクト頂いて以降の対応はとても真摯で好感の持てるものだった。自分も外資にいる身として、本国と話し合いながら対応策を決めていく大変さは理解しているので、あの規模でこの対応速度というのは、恐らく相当な危機感をもって対応して頂けたんじゃないかなと思う。

他の利用者についても一律返金ということで、ひとまず良い形に落ちたと思う。声を上げた人しか対応してもらえないというケースもあり得たので、この点でも評価出来るのではないか。

自分としてはこの件はこれにて終了と思っている。

おまけ

それにしても、改めて感じるのが、 DevRelって何なんだろうねと。

経緯を読んでいただければ分かると思うが、初期対応が非常に悪かった。お金に関する問題というサービスとして最もクリティカルな問題に対して、完全にダンマリを決め込まれてしまった。

本来、ユーザーに近い立ち位置で信頼関係を築き上げていくのがエバンジェリストやアドボケイトという仕事なんじゃなかろうか。しかし、今回は信頼関係を築くどころか全力でぶち壊すような動きをされたため、こちらとして出来る対応が事実関係をまとめて書くくらいしか無くなってしまった。

ただ、今回の件に限らず世の中のDevRelに関する人たちの動きはこれまでもずっとモニョモニョしたものを抱えていた。もちろん全員が問題という気は全くなく、本当に技術を愛してユーザーのことを考えている、尊敬できる人たちも沢山居る。

でも、この人は本当に技術のことが好きなのか? 単にミートアップやってキャッキャウフフして、気持ちよく喋りたいだけなんでは? という人も本当に多い。本当の本当に多い。

そろそろ、DevRelのあり方について見直す時期に来てるんじゃなかろうか。そう強く感じる一件だった。自分の関わるサービスの問題に当事者意識を持てないなら、DevRelなんてやめちまえよ。

追記

(感情逆撫でしてくるようなツイートがあったので記載していたがここに書くのはアンフェアすぎる感があったので削除)

追記の追記

デベロッパーアドボケイトのようなDevRelの人にサポートを求めるのは違うんじゃない? という意見があったので補足。確かにこの部分は自分がアドボケイトに何を求めているか不明瞭だったと思う。

職掌の違いについては自分も理解していて、経緯にも書いたように問題が発覚した後は即座にサポートにチケットを上げている。ここはどのベンダーにおいても共通だと思う。

DevRelをタップしたのは、User Groupに5/15になってから『3/1にプラン変えたから改めてチェックしておいてね』という投稿があったのがきっかけ。改めてとか言いながら過去には一切の通知はなかった。1ヶ月半も経ってから言うのが遅すぎるでしょうと。 まずこの点に関して意識が希薄すぎない?というのが1点。

実際アドボケイト主催のIBM Developer Dojoが契機となって今回のトラブルに当たっている人もいるので、アドボケイトは無関係どころか当事者ど真ん中なのだ。

どういう対応を期待していたかというと、ほんの一言でいいから何らしかの反応があればそれだけで大きく違ったように思う。

また、User Groupの方が、チケットだと日本語対応していないこと、電話したほうが早く対応してくれることなどを、この記事とともに教えてくれた。

www.ibm.com

こういう適切なディレクションをすること自体も、DevRelな人に求められていることじゃなかろうか。

大きな組織になってくると、何でもかんでも一人で対応するのは難しい。一方で、組織内の壁によりユーザーへの対応が二の次になってしまうのも、また問題だ。だからこそ、ユーザーに近い立ち位置で、組織の壁をうまくカバーするようユルユルっと動く。それがDevRelなんじゃないかと思っているし、自分がすごいと思っているDevRelの方々もそう動いているように見える。

別にDevRelにサポートをしてほしいって話ではないのでした。

(解決済み) IBM Cloudからの不意打ち請求はあろうことか2重請求だった

追記の追記

本件、解決しました。

jaco.udcp.info

以下本文

事の発端は前の記事を参照

jaco.udcp.info

本人に通知のないまま行われた有料化によって突然の請求が行われたこの案件。 よくよくチェックしてみるとさらに信じ難いことが起こっていた。

クレジットカードで決済出来ないから銀行振込しろ ⇒ 普通に決済出来ていた

前回の記事にも書いたのだが、 今回の件はクレジットカード決済出来なかったから銀行振込で支払えというメールが5/15に来たことで問題が発覚した。

f:id:jaco-m:20200517190016p:plain

メールには、令和2年3月の利用分について、 3,207円を銀行振込しろと書いてある。 通知のないまま行われた決済なので、サポートに苦情を上げているのは前回書いたとおり。胸糞悪い話ではあるが、まずはサポートがどう対応するか数日待ってみようと思っていた。

週末にまで胸糞悪い思いを引きずるのは嫌なので、一旦日常生活に戻るべく、ルーチンで行っているマネーフォワードでの家計簿チェックを始めたのだが、ふと見慣れない支出があることに気づいた。

f:id:jaco-m:20200517180005p:plain

…え。

これは一体どういうことか。いや、確かに前回の記事のタイトルに『今すぐクレジットカードの請求のチェックしろ』って書いた。他の人も不正な請求が行われてるかもしれないと思ったから、そう書いた。が、自分の請求に関しては実はちゃんとチェックしていなかったのだ。だってクレカ決済失敗したから振り込めって連絡が来てたので、自分のクレカはセーフだと思い込んでしまっていた。

ちょっと信じられないが、時系列に整理するとこうだ。

  • 5/8 クレジットカードから3,207円分の引き落としが行われている
  • 5/15 クレジットカード決済失敗したから 3,207円を振り込めというメールが来た

おかしいな、なんか違う世界線に来てしまったのかな。

もうちょっと情報収集する

カードの2重請求っていうのはよく聞く話だ。決済処理中のエラーや店員が誤って端末に2回通してしまったというトラブルだ。 しかし、今回はカードの2重請求ではなくて、カード決済が出来ているのにも関わらず銀行振込を要求されているのだ。こんなザルな請求管理が大企業であり得るのだろうか。

この件に関してもまずは自分を疑った。

メールの文面には、令和2年3月分の請求と書いてある。 今は5月だ。つまり、カード側の何らしかのトラブルで3月分の決済ができず銀行振込になり、4月分がカードの請求に戻ったのではないかと。であれば納得がいく。いや、不意打ち料金変更については納得いっていないが。

しかし、時間単位のpay-as-you-goプランで3月と4月の料金が同じなんてことはあり得るのだろうか?

ポータルにログインしてBilling and usage -> Usageの中身をチェックする。

まず3月。2,916円。消費税加味すると3,207円で一致する。

f:id:jaco-m:20200517183614p:plain

次に4月。2,822円。消費税加味すると3,104円になる。

f:id:jaco-m:20200517183857p:plain

…つまり、3,207円の請求は3月のものであり4月ではない。 自分はクレジットカードで引き落とされた上に銀行振込まで要求されたということで確定した。

ちょっとこれは本当にどうなのか。IBM Cloudはごくごく基本の請求管理が出来ていない。

前回の記事では主に無料枠で運用していたユーザー向けへの注意喚起であったが、今回の件によって判明したことは IBM Cloudを業務で利用している全てのユーザーは、過去の支払いに誤りがないか、2重請求されていないかを確認する必要がある、ということだ。

この2重請求についてもサポートに苦情を上げた。しかしあまりにも度が過ぎているように思うので、サポートから真摯な対応が得られない場合は然るべき対処を取るつもりだ。

追記

やはり2重請求だったようで、ごめんなさい連絡が。 f:id:jaco-m:20200519102730p:plain

そもそも請求の正当性についてはまた別途調整が進んでいる様子。

(解決済み) IBM Cloud (旧Bluemix) のアカウントを持っている人は今すぐクレジットカードの請求を確認すべき

追記の追記の追記

本件、解決しました。

jaco.udcp.info

以下本文

ちょっと常識では考えづらいことが起こっているようなのでまとめる。

TL;DR

  • IBM Cloudの料金プランが、本人への通知がないまま変更された(無料枠の削除)
  • かつてお試しでアプリを上げたユーザーに、思わぬ課金が行われている可能性がある
  • かつて一度でも使ったことがあるユーザーは、クレジットカードの請求を確認すべし

発端

昨日突然こんなメールが届いた。

f:id:jaco-m:20200516190755p:plain

IBM Cloudは旧称であるBluemix時代からCloud Foundryベースのサービスを提供しており、クレジットカード登録をしておくことで一定分のリソースについては無償、超えた部分は課金という料金体系だった。

『カード登録しても一定以内であれば費用かからないのでどんどん試して』と言われていたので、ワークショップでちょっとしたアプリを動作確認兼ねて上げてみたのが4年ほど前。 試しで上げたアプリは存在すら忘れて今日に至っていた。

それが突然の請求だ。

自分も元々クラウドサービス提供者側におり、マネタイズの難しさは理解している。儲からないのでフリーミアムモデルを取り止めるという意思決定自体は、サービス提供側の視点に立てば特に不思議ではない。

突然の請求を受けてしまったということは、どうやら有料化のお知らせの通知を見落としてしまったようだ。 一応自分に届くメールはタイトルだけでも確認しているつもりだが、うっかり見逃していることもゼロではないだろう。やっちゃったなー、と思い過去のメールを確認した。登録していたメールアドレスには独自のエイリアスをつけているので、エイリアスで検索するだけで絞り込める。

f:id:jaco-m:20200516192954p:plain

しかし、ないのだ。 料金体系変更のお知らせが一つもないのだ。流石に目を疑って何度か確認したが、そこににあるのはメンテナンスと障害通知のみで、料金体系については一つも無かった。

今回届いたメールの文面を見るとこんなことが書いてある。

IBM Cloud Foundry Public はデフォルトの標準プランを変更しており、この内容は、2019年12月10日付のブログ(英語)にて発表しています。

IBM Cloud Foundry Public プラン変更のお知らせ | IBM ソリューション ブログ

つまりだ。IBM Cloudは、ユーザー本人に直接通知をすることなく、ブログでこそっと記載をするのみでいきなり有償化を行ったわけだ。

さすがにこれはあり得ないのではなかろうか。ユーザーのうちどれだけが公式のブログを細かくチェックしているというのだ。こんなの通知のうちに入るわけがない。

かれこれ20年近く、さまざまなWebサービスを利用してきたがこんな形で突然の課金を食らったのは初めてだ。ええぇ・・・。

Twitterでも被害にあった人がちらほら。FBでも同様な被害報告があった。

自分の場合はたまたま登録していたクレジットカードが決済できなかったため、振込依頼のメールが来て今回の件に気づいた。が、有効なクレジットカードを登録している人はいつの間にか課金が行われている可能性がある。 IBM Cloudを使ったことある人は、急ぎ不慮の請求がないか確認した方が良い。

このような通知がないままの料金改定はあまりに非常識なので、サポートに不服申し立てのチケットを上げた。こちらについても回答があり次第掲載する。

※注釈

2017年末から始まったIBM Cloudライト・アカウントについては、そもそもクレジットカード登録が不要とのことで今回の問題には当たっていないと思われる。しかし、このようなポリシーで運用しているクラウドサービスを利用し続けて良いかどうかは、検討の余地ありだろう。

追記

被害者続々見つかる。 本当になんの通知もなく行われたので、クレジットカード明細を細かく確認している人でないと気づいていない可能性が高い。IBM Cloudを使っていた方は、一刻も早く請求を確認しよう

追記の追記

jaco.udcp.info

CloudNative Days Fukuokaで、クラウドネイティブについて考え直してみた

4/16に福岡で開催されたCloudNative Days Fukuoka で登壇しました。昨年12月のJapan Container Daysでの登壇でベストスピーカー賞を頂いたこともあり、CNDFのキーノートで登壇しないかとお声がけいただいたのです。

普段は特定の技術についての登壇が多い自分ですが、今回はキーノートでの発表。そこで、より全体的な『そもそもクラウドネイティブとは』という話をしました。

speakerdeck.com

このテーマ、以前からどこかで話したいと思っていたんですよね。

このエントリーでは、↑の発表資料を基に、時間の都合で削った部分の補足を行っています。一度資料に目を通してからお読みください。

お前らのクラウドネイティブは間違っている

いきなり石を投げられそうな見出しですが。本当にクラウドネイティブな開発を実践されている方々に喧嘩をふるつもりは全くありません。それよりも問題だと思っているのが、クラウドネイティブな商材を扱っているベンダーや、ITジャーナリストな方々が訛伝している『クラウドネイティブ観』。

  • クラウドネイティブ開発ではマイクロサービスアーキテクチャで開発を行う
  • クラウドネイティブ開発ではコンテナ技術を活用し、Kubernetes上で運用する

みたいな決めつけが本当に多い。どことは言わないけれど。それっぽいキーワードで検索すれば大量に出てくると思います。

ソフトウェアアーキテクチャのみならず組織論まで踏み込んだ考え方であるマイクロサービス。柔軟性に富み、拡張性も高く非常に優れたプラットフォームであるKubernetes。これらを採用すること自体が間違いだとは言わないですし、むしろ積極的に検討すべきだと思います。が、ありとあらゆるケースにフィットする、いわゆる銀の弾丸なんてどこにも存在しません。 自身を顧みないままマイクロサービスやKubernetes採用したところで、辛さしか生みません。マジで。

Cloud Native ≠ Kubernetes

ここについては、去年のJKD v18.04で発表したこの資料で詳しく説明しています。

www.slideshare.net

KubernetesをはじめCaaSは柔軟性や拡張性に優れる一方、運用者や開発者が担わなければいけない要素が多いのです。今回の発表で言うと、『人間の関与を要求しがち』なプラットフォームなんですね。

クラウドネイティブのマインドが育っている企業であれば、Kubernetesを使っても適切な自動化を行い、生産性を高めることが出来るでしょう。ですが、そうでないフェーズの企業がKubernetesを使うとどうなるかはお察しの通り。

もしあなたが運用の中で kubectl apply を手で叩くシーンがあるのならば、何かがおかしいと考えた方が良いです。そしてその状況をすぐに改善できないと感じるのであれば、おそらくKubernetesを採用したことが間違いだったと言えるでしょう。

Kubernetes完全ガイドにもこう書いてあります。

Kubernetesを実運用する場合、手動でkubectlコマンドを実行することはほとんどありません。手動でのオペレーションはヒューマンエラーが発生しやすいことや、管理できるリソース数に限界があるため、推奨しません

Kubernetes完全ガイド 4.5.7 Pruneによるリソースの削除 より引用

Kubernetesを使わなくても、様々なPaaSやマネージドのコンテナ運用サービスがあります。そういったOpinionatedなサービスを活用したほうが、生産性が向上するケースが多いのです。

クラウドネイティブを、DevOpsを、自動化を理解したいのならばFactorioをプレイしよう

「コンテナやKubernetes採用するのも大事ですけど、ちゃんとCIやCDやるのも大事ですよ。むしろそこからですよ」 と話すと「いや、自分はコード書くわけじゃないんでそこは分からないんで・・・」 と返されることがあります。いやプラットフォームの改善するのにそこを理解しようとしないのは甘えでは・・・。

とはいえ事情は人それぞれなので、手っ取り早く自動化のエッセンスを理解する方法として、Factorioというゲームプレイをお勧めします。

store.steampowered.com

未知の星に不時着したプレイヤーが、資源を掘り、機械を作り、星を開拓していくゲームなのですが、このゲームでとにかく大事なのが自動化。 手で資源を掘って資材を作ってなんてやってると、いつまで経っても開拓が進みません。

そうこうしているうちに、星に棲んでいた生物に襲撃されます。作った機械は破壊され、かろうじて作った機関銃で対処するのが精一杯という状態に陥ります。もう開拓どころでなく、日々生き延びるだけで手一杯。


Factorio - Trailer

そうならないためにも、とにかく自動化しまくるのです。資源掘るのも、資材を作るのも、機械を組み立てるのも、全て自動化。 襲いかかってくる敵もタレットで迎撃。弾丸の供給やダメージを受けた防壁の修復も全て自動化。こうすると、序盤では考えられなかった速度で開拓が進んでいきます。

これ、今回話したクラウドネイティブの話と非常に似ているんですよね。運用していると、ありとあらゆる問題が起きます。そういった問題に都度対応していたのでは、時間がいくらあっても足りません。結果として、集中して作業できる時間が奪われ、価値のある行動(サービスの開発)は遅々として進まなくなり、ライバルに叩き潰されて終了。

ボトルネックはどこにでも発生しうること、特に人間が関わった時点でそこはボトルネック化確定というシビアな現実を実感する上でもお勧めのゲームです。

FactorioがDevOpsについて教えてくれる4つのこと datahovel.com

ちょっと前には、これを採用に活用している企業も話題になりました。

news.denfaminicogamer.jp

本当はFactorioの話もキーノートに入れたかったんですが、発表時間に収まらないこと、話の焦点がブレる可能性もあり泣く泣く削りました。 今このエントリーを書いているのは、ぶっちゃけこの話がしたかったからです。

CloudNative Days Tokyoもでもお待ちしています

7月の22日と23日には、CloudNative Days Tokyoが開催されます。CFPの採択も終わり、もう間もなく申し込みページがオープンする予定です。

今回、Kubernetes完全ガイドでも有名な@amsy810と一緒にCo-chairを務めることになりました。役に立つセッション、ワクワクするセッションを数々揃えていますので、みなさま是非お越しくださいませ。

今年のCloud Foundryを振り返る

Cloud Foundry Advent Calendar 2018の1日目

なんかついこの間2017年のAdvent Calendarを書き終わったくらいの気持ちなんですけど、時間が経つのは早いモノで、もう12月ですか。

さて2018年のCloud Foundry Application Runtimeを振り返ってみます。 細かなところ上げると切りが無いんで、大きなトピックを中心に振り返ってみましょうか。

CFCRについてはまた別途取り上げます。

cf-release廃止、cf-deploymentへ移行

2013年にCF v2が出て以降、CFのデプロイには cf-releaseを使うのが一般的でした。

しかしBOSHもv2となり、Opsfile始めさまざまな便利機能が登場したこともあり、これらの機能を最大限享受すべく作り直された cf-deployment への移行が行われました。

cf-releaseは今年2月のv287をもって終了しているため、もしcf-deploymentへ移行を行っていない方は、できるだけ早くcf-deploymentに移行しましょう。移行に際しては、このあたりのツールも参考にしてください。

github.com

Routing layerのIstio移行

これは現在進行形で開発が進んでいる機能ですが、CFのルーティングレイヤーがごっそりIstioに置き換えられるということが発表されました。

これについては、私が発表した以下の資料が参考になるかもしれません。

移行ですが、いきなりIstioに切り替わるのではなく、DEA->Diegoの時と同じように、運用者がどちらかを選択or両方をデプロイ と言う形で導入できるようにするようです。 Sidecar envoyによるmTLSなどは既に現在のバージョンで実装されていますが、Istioの導入によってさらに重み付けロードバランスやCanary releaseなどが可能になります。

SpinnakerのCFAR対応

Continuous Deliveryのツールとして人気のSpinnaker。 主にk8s向けに利用するイメージが強いこのツールですが、バージョン1.10からCFARに対しても利用できるようになりました。

Version 1.10 - Spinnaker

最初にPivotalのサイトで触れられたのが2015年のことなので、だいぶ時間がかかったなあ・・。

CF Containerization / Project Eirini

この記事を読んでいる皆さんであれば、k8sを構築・運用するためのCloud Foundryの仕組みがCloud Foundry Container Runtimeであるということはご存じでしょう。 CFで培ったBOSHの仕組みと、Kubernetesを組み合わせていいとこ取りしたのがCFCRです。

しかしそんな分類を、さらに混乱させるようなプロジェクトが登場しました。それが、CF ContainerizationとProject Eiriniです。

CF Containerization

CF Containerization | Cloud Foundry

ざっくり言うと今までBOSHで管理されてきたCFのコンポーネントをKubernetes上でコンテナとして動かしてしまおう、というプロジェクトです。

これに関しては、Advent Calendarで触れたいひともいそうなので詳細はそちらに譲ります

Project Eirini

Project Eirini | Cloud Foundry

CFARはDiegoでアプリケーションコンテナのスケジューリングを行っていますが、Diegoの代わりにKubernetesを使ってスケジューリングを行おうというのがこのProject Eiriniです。

これまた他の記事で書きたそうな人がいるので詳細はそちらで。

CF ContainerizationとEiriniという、ぱっと見よく似たプロジェクトが2つ動いていることで混乱してしまうかもしれませんが、 CFARの管理系をk8sに載せちゃおうというのがCF Containerization、 CFARに乗っかるユーザーアプリをk8sに載せちゃおうというのがProject Eiriniになります。

これについては、IBMのThinkというイベントで登壇した際に解説してますので、興味のある方はこちらもご覧ください。

さいごに

他にも書きたいことあった気がするんですが、時間も時間なので今回はこの辺で。 それぞれのネタの詳細は、また別の記事で解説できればなーと思っています。

KnativeでBuildpackを使ったデプロイを試す

Knative試してみた話2回目。

前回: jaco.udcp.info

前回は、既に存在するDocker imageを使ってアプリのデプロイを行いました。今回は、ソースコードからアプリのデプロイを試してみます。

Buildpackの話

Buildpackは、PaaSであるherokuやCloud Foundryで利用されている、アプリケーションのビルドやコンフィグレーションを行うための仕組みです。

buildpackの仕組みについては、以下のスライドでも解説しています(42ページ〜)

www.slideshare.net

herokuであればgitへのpush、Cloud Foundryでれば cf push コマンドでソースコードをデプロイすることで、あとは自動でインターネットに公開するところまで終わってしまうわけですが、その裏にはこのBuildpackの存在があります。

Buildpackを使ってKnativeにアプリのデプロイをやる

Knativeは、Buildpackを使ってのアプリやファンクションのコンテナイメージ作成をサポートしています。

ということで、今回はこちらのサンプルアプリを利用して、デプロイを試してみます。

利用するのはこちらのYAML。これを sample.yamlとして保存しておきましょう

apiVersion: serving.knative.dev/v1alpha1
kind: Configuration
metadata:
  name: buildpack-sample-app
  namespace: default
spec:
  build:
    source:
      git:
        url: https://github.com/cloudfoundry-samples/dotnet-core-hello-world
        revision: master
    template:
      name: buildpack
      arguments:
      - name: IMAGE
        value: &image DOCKER_REPO_OVERRIDE/buildpack-sample-app

  revisionTemplate:
    metadata:
      labels:
        knative.dev/type: app
    spec:
      container:
        image: *image
---
apiVersion: serving.knative.dev/v1alpha1
kind: Route
metadata:
  name: buildpack-sample-app
  namespace: default
spec:
  traffic:
  - configurationName: buildpack-sample-app
    percent: 100

このYAML、よーく読むと分かるのですが、コンテナイメージへのパスがどこにも記されていません。その代わり、こちらのリポジトリが指定されています。

github.com

これはKnativeではなくCloud Foundryのデモのために公開されている.NET Coreのアプリケーションです。リポジトリのほうには、コンテナのコの字もなく、単にソースコードが置いてあるだけです。

まずは以下のコマンドで、Buildpackを使ったデプロイを有効にします。

kubectl apply -f https://raw.githubusercontent.com/knative/build-templates/master/buildpack/buildpack.yaml

次に、以下のコマンドを使ってsample.yamlの中身を書き換えます。

REPOには、Google Container Registryのパスが入る形になります。

export REPO="gcr.io/<ここをGCPのProject名に書き換え>"

perl -pi -e "s@DOCKER_REPO_OVERRIDE@$REPO@g" sample.yaml

書き換えが終わったらデプロイしてみましょう

kubectl apply -f sample.yaml

buildpackでコンテナイメージの作成まで行っているので、全てが立ち上がるまで数分かかります。 kubectl get all で全てがRUNNINGになっていることを確認したら、以下のコマンドでアプリのホスト名とknative-ingressgatewayのIPを環境変数に格納しておきます。

export SERVICE_HOST=`kubectl get route buildpack-sample-app -o jsonpath="{.status.domain}"`
export SERVICE_IP=`kubectl get svc knative-ingressgateway -n istio-system -o jsonpath="{.status.loadBalancer.ingress[*].ip}"`

それでは、curlでホストヘッダを指定してアプリにアクセスしてみましょう。Hello worldが表示されているでしょうか?

curl --header "Host: $SERVICE_HOST" http://${SERVICE_IP}/

Hello World!

前回の記事で利用したkanative-ingressgatewayと、今回利用しているものを比較してみてください。実は同じものを叩いていることが分かるでしょう。

kubectl get svc knative-ingressgateway -n istio-system

つまり、kanative-ingressgatewayがホストヘッダを見て、紐付いているserviceにルーティングを行ってくれているわけですね。

作成したイメージをみてみる

それでは、GCRのほうをみてみましょう。

f:id:jaco-m:20180726022248p:plain

生成されたコンテナイメージが保存されていることが分かるでしょう

さて、次はBuildpackを使ったFunctionのデプロイも試してみましょうかね。

最強のServerlessプラットフォーム? Knativeを動かしてみるぞい

ということで前回の記事に引き続き、発表されたばかりのKnativeを動かしてみました。

jaco.udcp.info

GKE環境を用意する

Knativeを動かすにはk8s環境が必要ですので、今回はGKEに環境を用意します。なおk8s本体とKubectlは1.10以上が必要です。

KnativeはIstioなども含むリッチな仕組みのため、それなりのリソースを要求します。なのでやや大きめのインスタンスで立ち上げていますが、節約したい方はmachine-typeやnodeの数を編集してください。

export CLUSTER_NAME=knative
export CLUSTER_ZONE=asia-northeast1-a

gcloud container clusters create $CLUSTER_NAME \
  --zone=$CLUSTER_ZONE \
  --cluster-version=latest \
  --machine-type=n1-standard-4 \
  --enable-autoscaling --min-nodes=1 --max-nodes=5 \
  --enable-autorepair \
  --scopes=service-control,service-management,compute-rw,storage-ro,cloud-platform,logging-write,monitoring-write,pubsub,datastore \
  --num-nodes=3

k8s立ち上がったらget-credentials

gcloud container clusters get-credentials knative

カレントユーザーにcluster-adminをつけます。

kubectl create clusterrolebinding cluster-admin-binding \
--clusterrole=cluster-admin \
--user=$(gcloud config get-value core/account)

kubectlを使って、Istioをセットアップします

kubectl apply -f https://storage.googleapis.com/knative-releases/serving/latest/istio.yaml

defaultネームスペースにラベル設定

kubectl label namespace default istio-injection=enabled

Istioの諸々がRunningになっているか確認

kubectl get pods -n istio-system

NAME                                       READY     STATUS    RESTARTS   AGE
istio-citadel-7bdc7775c7-lktlt             1/1       Running   0          59s
istio-egressgateway-795fc9b47-tcp76        1/1       Running   0          1m
istio-ingress-84659cf44c-2gmlw             1/1       Running   0          1m
istio-ingressgateway-7d89dbf85f-qjpg5      1/1       Running   0          1m
istio-pilot-66f4dd866c-lr7zw               1/2       Running   0          1m
istio-policy-76c8896799-74m52              2/2       Running   0          1m
istio-sidecar-injector-645c89bc64-gz5vb    1/1       Running   0          59s
istio-statsd-prom-bridge-949999c4c-p97lv   1/1       Running   0          1m
istio-telemetry-6554768879-pmkqq           2/2       Running   0          1m

Knativeコンポーネントをセットアップ

Knative Servingをセットアップします

kubectl apply -f https://storage.googleapis.com/knative-releases/serving/latest/release.yaml

Runningになっているか確認してみましょう

kubectl get pods -n knative-serving

NAME                          READY     STATUS    RESTARTS   AGE
activator-6bb6f6755f-l4ks8    2/2       Running   0          30s
controller-79cbd84cfb-n6l6h   1/1       Running   0          29s
webhook-7c884f4554-h7tx5      1/1       Running   0          29s

なんとこれだけでKnativeのセットアップは終わりです。それでは、実際に何かデプロイしてみましょうか。

サンプルアプリのデプロイ

service.yamlを作成し、以下の内容を記述してください。

apiVersion: serving.knative.dev/v1alpha1 # Current version of Knative
kind: Service
metadata:
  name: helloworld-go # The name of the app
  namespace: default # The namespace the app will use
spec:
  runLatest:
    configuration:
      revisionTemplate:
        spec:
          container:
            image: gcr.io/knative-samples/helloworld-go # The URL to the image of the app
            env:
            - name: TARGET # The environment variable printed out by the sample app
              value: "Go Sample v1"

このサンプルアプリは、環境変数 TARGETの中身を表示するアプリケーションです。このyamlの例の場合、 "Go Sample v1" という文字を表示します。

保存した後、kubectl applyします

kubectl apply -f service.yaml

> service "helloworld-go" created

作成されたリソースをみてみます

kubectl get all

NAME                                    AGE
deploy/helloworld-go-00001-deployment   10s

NAME                                          AGE
rs/helloworld-go-00001-deployment-d47886fcb   10s

NAME                   AGE
routes/helloworld-go   10s

NAME                AGE
svc/helloworld-go   10s

NAME                           AGE
configurations/helloworld-go   10s

NAME                            AGE
revisions/helloworld-go-00001   10s

NAME                                                READY     STATUS    RESTARTS   AGE
po/helloworld-go-00001-deployment-d47886fcb-c97kx   3/3       Running   0          10s

NAME                              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
svc/helloworld-go                 ClusterIP   10.63.246.221   <none>        80/TCP         10s
svc/helloworld-go-00001-service   NodePort    10.63.252.252   <none>        80:30048/TCP   10s
svc/kubernetes                    ClusterIP   10.63.240.1     <none>        443/TCP        12h

なんかsvc/helloworld-go以外にもいっぱい作られてますね!

作成したアプリへのアクセス

istio-system namespaceを見てみると、knative-ingressgatewayというものが作られていることが分かります。

このknative-ingressgatewayが、アプリケーションへのルーティングを担うコンポーネントになります。

kubectl get svc knative-ingressgateway -n istio-system

NAME                     TYPE           CLUSTER-IP     EXTERNAL-IP      PORT(S)                                      AGE
knative-ingressgateway   LoadBalancer   10.23.247.74   35.203.155.229   80:32380/TCP,443:32390/TCP,32400:32400/TCP   2d

以下のコマンドでknative-ingressgatewayのEXTERNAL-IPを取得しておきます

export IP_ADDRESS=$(kubectl get svc knative-ingressgateway -n istio-system -o 'jsonpath={.status.loadBalancer.ingress[].ip}')

次に、以下のコマンドで、services.serving.knative.devを取得します

kubectl get services.serving.knative.dev helloworld-go  -o=custom-columns=NAME:.metadata.name,DOMAIN:.status.domain

NAME            DOMAIN
helloworld-go   helloworld-go.default.example.com

DOMAINというところに、今回のアプリ向けのドメインが記されています。 knative-ingressgatewayはリクエストを見て、このドメインへのアクセスであれば作成されたアプリケーションへのルーティングを行うという動きをします。

とはいえexample.comは例示用ドメインなので、今回はcurlでホストヘッダを指定することで動きを見てみます。

curl -H "Host: helloworld-go.default.example.com" http://${IP_ADDRESS}

Hello World: Go Sample v1!

ほら、期待した文字列が表示されていますよね?

まとめ

ということで、Knativeは簡単にセットアップできるよという話を紹介されていただきました。

ただ、ぶっちゃけ今回のサンプルアプリでは、Knativeの何がいいのか分からないですよね? うん、僕も分かりません。

そもそもServerlessって言ってたのにどこにもServerless要素ないやん、こんなん素のKubernetesと変わらんやん! ってツッコみたくなるかと思いますが、徐々に解説していきますのでもう少しお待ちください。

Knativeはさまざまな方法で利用が出来るプラットフォームです。なので、1記事ではとてもとても紹介しきれないのです。

今回は、KnativeはServerless Platformでありながらも、従来のようなアプリケーションも動かすことができる という点を理解して頂ければよいかなと思います。

次回は、Buildpackを利用したアプリケーションのデプロイについて解説する予定です。

(参考)お片付け

k8sをお片付けするには以下のコマンドで削除します

gcloud container clusters delete $CLUSTER_NAME --zone $CLUSTER_ZONE