Questions and feedbacks

Altech
Altech commented over 1 year

ふりがなサービスとかutil的なサービスもあるような気がするのですが、gemじゃなくてmicroservice化されているのは理由がありますか?

こちらセッションで答えたのですが、gem にしてないのは単純に Ruby ではなく Python で実装しているためですね。

あとは、仮に gem にすると Ruby でしか利用できなくなってしまうのと、ふりがなの振り方自体も独立して精度改善の余地があるので、miscroservice にしておく意味があるかなと個人的には考えています(ライブラリだと改善したときに利用側を全てバージョンアップしなければいけないので)。

Like(1)

expajp
expajp commented over 1 year

「テストがしっかりしているのでアップデートに問題が起きにくい」とのことでしたが、テストコードの実装にカバレッジなどの基準は設けられていますか?

Like(0)

Altech
Altech commented over 1 year

セッションテーマとちょっとずれた質問ですが、「Dockerの薄いラッパー」って具体的にどんなものなんでしょう? シェルやMakefileでサブコマンド、みたいなのがよくあるユースケースかと思っているのですが何かツールとか作られてますか?

具体的には弊社のエンジニアが https://github.com/creasty/rid (run-in-docker) というソフトウェアを作っているのですが、ほぼネイティブのコマンドのように Docker 内でコマンドを実行できるものです。bundle exec のように prefix を付けて実行すると docker 内のコマンドとして実行されます。

$ rid rails c

あとは Docker 内でのセットアップ(image pull 後の bundle install など)はシェルスクリプトを libexec というサブディレクトリに bootstrap script を置いて rid bootstrap で全てセットアップできるようにしています。docker image 内での bootstrap なので環境依存性が低いのと、シェルスクリプトであることを意識させないところが便利な印象です。

Like(1)

mumoshu
mumoshu commented over 1 year

@morimorihoge 質問ありがとうございます!

多分発表で出てきそうですがAWSならFargateとself managed Kubeのpros. cons.みたいな話に興味があります!

EKS+Fargate(まだ開発中)、EKS(またPreview=Privateベータ)、セルフマネージの3つの選択肢があると思うのですが、

基本的にマネージドサービスが使えるようになったら、マネージドがいいです。 いまはそういうものがないので、セルフホストするしかない状態です(´;ω;`)

こちらも参考になるかもしれません

https://speakerdeck.com/mumoshu/kubernetes-on-aws-in-2018-for-startups?slide=45

ただ、EKSはおそらくGAまで時間がまだ掛かりそうなので、待てないならセルフマネージになりますね。

たとえばIAM連携などの機能があるのですが、こんな感じで絶賛開発中で、matureといえるような状態ではない。 https://github.com/heptio/authenticator/issues

また、EKS+Fargateに関しては、さらに時間がかかりそうです。

Azureは既に同等のアーキテクチャに対応している(AKSがマネージするK8Sコントロールプレーンと、virtual-kubeletという仮想ノードごしにFargate的なサービスが起動したコンテナを無限にぶら下げられる)のですが、

ref: https://github.com/virtual-kubelet/virtual-kubelet

理論上はEKS+Fargateにもこのような仕組みがないといけないのですが、見る限りvirtual-kubeletにはAWSサポートは含まれていないので、今からAWSさんがキャッチアップなり再実装するのは時間かかるだろうなぁ・・と。

なので、繰り返しになりますが、基本的にマネージドサービスが使えるようになったら、マネージドがいいです! でも、待てない場合はセルフマネージしか今は選択肢がないという感じです。

Like(0)

Altech
Altech commented over 1 year

peopleっていうserviceは、今思うと細かいserviceに切り分けたいと考えますか?切り分けた事例があればその中で辛かった部分を教えて欲しいです

まだサービスを出して1年程度なので、切り分けた事例はまだないですね。ただ、今回紹介した複数サービス(People, Visit)の間で共有するデータに移したい箇所はいくつかあります。

Like(0)

mumoshu
mumoshu commented over 1 year

@morimorihoge

スモールスタートだったり社内システムなんかだとRails Consoleを使いたくなったりすると思うんですが、そういう場合はどうするのがbest practiceなんでしょうか? ※SQLだけだとARのValidationとか通らないので、interactive rubyしたい

fat container的な軽量VM感覚で良ければsshしてrails c という手もありますが、コンテナにsshログインするってのもアレな気がしています。

いまのところkubectl run -it $image interactive-rails-$(datetime %+s) rails cみたいな感じでクラスタに自分の権限で一時的なpodにrails consoleを起動する、という運用でやってます!

ただ、よりエンタープライズ的な用途ではsshもありかな、と最近思い始めています。なぜかというと、K8SのRBACより細かな権限管理ができたり、Gravitational Teleport(https://gravitational.com/teleport/)などを使えばセッションのキャプチャ(セッション中で何を実行して何を見たか)ができるためです。そこまで必要ないケースでは、kubectl runでrails consoleが良いと思います。

Like(0)

Altech
Altech commented over 1 year

Wantedly Peopleの方はかなりサービス数多いと思うんですが 今振り返ってみてサービスの分け方は成功したと思いますか? また、運用してみてサービス数が多いことによるつらみみたいなのはありますか?

@nabuchi セッションの中で言えば良かったですが、基本的には新しく作ったサービスの分け方は成功したという感覚です。サービスが多いことに対しては、 Kubernetes を運用している SRE チームが継続的に対処しています。特に、サービス数に対して O(n) での作業量が必要になるものの割合を一定以下に抑えると言った観点があり、こちらは弊社の @koudaiii による以下のスライドなどで説明しています。 https://speakerdeck.com/koudaiii/number-jtf2017

つらみで言うと、セッションでも触れていた別の事業部の中にある中核ドメインに関する変更ですね。テーブルにカラムを1つ追加して read / update するまでに4つのリポジトリに PR を出したこともありました…。

あとはサービス横断的な不具合に対しては分散トレーシングはやはり無いと辛いので、その辺りは現在整えているところです。

Like(0)

mumoshu
mumoshu commented over 1 year

@yuemori

AWS on Kubernetes、ECSやGKEといった選択肢もあったと思うんですがその選択肢をとられた経緯が気になります

K8S on AWSかECSか、という選択肢については、「分散システムのプラットフォーム」なので「周辺ツールが多い」「共通言語が多い」というメリットを活かせると思ったということと、「学習コスト」というデメリットは筋肉で乗り越えられそうだったのでK8Sにした、という感じです!

ぼくの別の登壇内容も文脈として参考になるかもしれません

https://speakerdeck.com/mumoshu/kubernetes-on-aws-in-2018-for-startups?slide=43

AKS、GKE、その他マネージドK8Sにするかどうかということに関してですが、前提として「マネージドでいけるときは基本マネージドがおすすめ」です。

ただ、ぼくがK8Sを導入する結果になったケースではいずれも、「既に重要なデータが大量にAWSにロックインされてしまっているので、それをK8Sのためだけに別のクラウドに移行する辛さと、K8S on AWSをセルフマネージする辛さを天秤にかけて、後者のほうがマシと判断した」から、です。

そこで「まし」と判断できるかどうかに、

  • 英語力(まだ日本語の情報少ない)、
  • ベースの分散システム・AWSの経験(良くも悪くもAWS上でK8Sという分散システムをいかに本番用途に耐えるように構築・運用するかという話だから、そのあたりのベースがない状態だとそこからキャッチアップが必要になってしまう)
  • 周りのサポート(いざという時に運用を助けてくれるメンバーがいるか
  • K8Sを補完するシステムの利用・運用の知見があるか(たとえばVMベースインフラの監視にDatadogを使ってる場合、K8S以後の監視にもDatadogがそのまま使えるので楽、とか

といったことも絡んできます。

Like(0)

mumoshu
mumoshu commented over 1 year

@nobuhikosawai 質問ありがとうございます!

Docker作る時の秘匿情報の管理、具体的にどのように行われているのか気になります

ランタイムで必要な秘匿情報と、ビルド時に必要な秘匿情報があり、前者の話だと仮定してすすめます。

どのようなCIシステムを使うかにもよるとは思うのですが、

・CIジョブ内のdocker buildなどからプライベートgitレポジトリにアクセスするとして、  ・そのCIジョブにどのようにgitレポジトリへのアクセス権を付与するか、  ・そのための認証情報(SSH秘密鍵、GitHubトークンなど)をどこにどのように保存するか  ・どのようにCIジョブからdocker buildコンテキストに認証情報を渡すか

という問題に分解できると思います。

ポイントは「認証情報も可能な限りバージョン管理する」ということと、バージョン管理する場合には暗号化する(暗号文のまま漏れても問題がないようにする)ということと、できるだけ利用するタイミングに近いところまで復号を遅らせる、の3点です。

実装例としては、AWS KMSなどクラウドプロバイダーなどが提供するデータの暗号化サービスを使います。 これを使って、SSH秘密鍵を暗号化したうえで、アプリケーションと同じGitレポジトリにcommitしてしまいます。CIジョブでは

  • git clone
  • AWS KMSでSSH秘密鍵の復号(このために、CIジョブの環境変数などでAWSクレデンシャルを設定しておく必要がある。手動管理はここだけになり、SSH秘密鍵自体はGitでバージョン管理できる)
  • 復号したSSH秘密鍵を環境変数やディスクに書く(環境変数のほうがどちらかといえばセキュア)
  • docker run -e SSH_PRIVATE_KEY my-builder-imaeg -v $(PWD)/build/vendor/bundle:/src/vendor/bundle -w /src bundle install --deployment
  • 復号した秘密鍵をディスクに書いたのであれば、消す

という感じになります!

さらに復号するタイミングを遅らせる場合は、

  • CIジョブをAWS利用してるのであれば適切なInstance ProfileによりKMSへのアクセス権が付与されたEC2インスタンスから実行することにして、
  • CIジョブでgit clone
  • docker run -e SSH_PRIVATE_KEY my-builder-image -v $(PWD)/build/vendor/bundle:/src/vendor/bundle -w /src wrap bundle install --deployment
    • wrapの中では
    • AWS KMSでSSH秘密鍵の復号(Instance Profileに紐付いた権限でKMSを呼ぶため、AWSクレデンシャルは不要)

という感じになります。

どこで復号するにしても、jokerさんの yamlvault(https://github.com/joker1007/yamlvault)やmozillaのsops(https://github.com/mozilla/sops)のようなKMSに対応したツールを使うと楽です。

Like(1)

SyoheiYamaki
SyoheiYamaki commented over 1 year

発表して頂いた内容とは少しずれてしまうのですが、スライド中に挿入されていた手書きの画像?は何を用いて作成されているのでしょうか?

Like(0)

morimorihoge
morimorihoge commented over 1 year

ロゴ作りの時に「こういう要素・条件は最初に出しておいた方が良い」というものがあれば知りたいです。 # 例えば、スライドにもあったTシャツなどにも使うなら前からこういう条件を付けておいた方が良い、など

Like(0)

ota42y
ota42y commented over 1 year

範囲検索で二つ目のインデックスが効果ある場合(ICP狙いの場合)って具体的にどういう場合なのでしょうか?

Like(0)

taiki45
taiki45 commented over 1 year

primary id が定義されてないテーブルでは secondary index はなにを参照するのか気になります

Like(0)

Altech
Altech commented over 1 year

Wantedlyさんは、ネイティブアプリも途中からかなり分割していっている印象があるのですが、バックエンドのマイクロサービス化とネイティブアプリ・フロントアプリの関係についてもできればお聞きしたいです。 (当日は裏で司会をしている予定なので、リアルタイムでは聞けない可能性が高いのですが... >< )

こちらセッションの最後でお答えしました!基本的には分割はやってなくて、新しい事業に対してアプリとサーバーを新しく作っていて、そこで問題になる中核ドメインの共有問題に対してマイクロサービスによる解決を試みているという関係です。

Like(1)

ttwo32
ttwo32 commented over 1 year

コンセプトを決める上で、これって価値観へのカウンターになるんだろうか?とか迷ったりすることはありますか? もしあればそんな時はどうしているか、または工夫していることなんかあれば、参考までに教えていただきたいです。

Like(0)

k0kubun
k0kubun commented over 1 year

nested loop joinがnested loop join以外の手法と比べてどういうメリット/デメリットがあるのか知りたいです

Like(0)

mumoshu
mumoshu commented over 1 year

@qsona 質問ありがとうございます!

docker build中にbundle installしない理由と、どういう方法でやっているかが知りたいです!

dockerだけでやる場合は、

docker build -t my-builder-image:$VERSION -f Dockerfile.builder .
# 予めGITHUB_TOKENを設定しておき・・
docker run -v $(PWD)/build/vendor/bundle:/src/vendor/bundle -e GITHUB_TOKEN -w /src my-builder-image$VERSION bundle install --deployment
docker build -t my-runtime-image:$VERSION -f Dockerfile.runtime .

みたいな感じで、bundle installだけはdocker runで実行する(そうすると、必然的にvendor/bundleをホストボリュームに作成して、それをランタイムイメージにADDすることになるのがわかりづらいところ)といいです!

それか、先のコメントで @yuemori さんに回答したように

habitusなどの一時secret server付きでdocker multi-stage buildを実行できるツールを使う

とbundle installをdocker build中でやっても安全にできます。

Like(1)

mumoshu
mumoshu commented over 1 year

@yuemori 質問ありがとうございます!

ビルダーイメージとランタイムイメージを分けるとのことですが、Railsの場合どういうところを気をつけられていますか?

もう意識されてることもあるかもしれませんが、

  • ビルダーイメージはできるだけfatに、ビルドに必要なものをなんでも入れる
  • ランタイムイメージにはベースイメージにビルド結果以外のものは極力入れない
  • それぞれgitコミットsha1やsemantic versionでタグ付けする
  • ある時点のビルダーイメージを新しいビルダーイメージのベースイメージにする(ベースイメージは定期的に更新する。Layer Cachingの効果を保つため)
  • ある時点のランタイムイメージを新しいランタイムイメージのベースイメージにする(ベースイメージは定期的に更新する。Layer Cachingの効果を保つため)

Railsの場合、どうしてもnative extension用のパッケージなどでサイズが大きくなりがちなのですが、かなり複雑なアプローチをとらざるを得なくてつらくなりがちです (例えばビルダーイメージから必要なファイルだけとってくるとかそういうアプローチもあると思うんですがとてもつらい)

yuemoriさんがどのあたりを辛いと感じていらっしゃるか次第でもう少し具体的な回答もできそうですが、

ビルダーイメージから必要なファイルだけとってくるとかそういうアプローチ

基本的には時間かけられる場合はそのアプローチがベストだと思ってます。その上でどれだけ楽できるか・・という問題意識でやってます。

ぼく個人的には「何をビルダーからランタイムにコピーするか」がどこに書かれているかわかりづらいケースがあるというのが一番つらく感じます。それに関してはDockerのMulti-Stageビルドが一番まし(ランタイムとビルダーを同じDockerfileに書けて、どこからコピーするかというのもDockerfile内にself-containされるから)と思っています。

ただ、Multi-StageビルドやるとPrivate GitHubレポジトリに依存している場合に必ずアウトになる(Layer Cachingを諦めるか、もしくはSSH秘密鍵などがビルダーイメージに残ることを許容することになる)ので、habitusなどの一時secret server付きでdocker multi-stage buildを実行できるツールを使うのが個人的にはベストプラクティスです。

参考: https://github.com/cloud66/habitus/issues/89

native extension用のパッケージなどでサイズが大きくなりがち

これはその通りで、ぼくは時間がかけられる場合は地道にゴミファイル消してます・・。例えば、vendor/bundle内のgemには、ネイティブエクステンションビルド後の.aとか.oファイルとか、ドキュメント?がpdfファイルとして残ってたりとか、バイナリをバンドルしてるgemであればlinux用のバイナリだけあればいいのにmacOSなど他のプラットフォーム向けのバイナリがgemに残ってたりとか・・・

https://github.com/mumoshu/kubeherd/blob/729e233b34bc7d369ac62cc8e5d19e83152fff51/builds/alpine-rails/dockerimages/runtime/.s2i/bin/assemble#L57-L94

こういう泥臭い方法で消したりすると、イメージサイズが数割減ることもありますね。

Like(0)

takahashim
takahashim commented over 1 year

まつもとさんによる「楽しいプログラミング」について言及しているものとしては、1999年のJUSのworkshopの資料とかにもあるので、かなり初期からのRubyのコンセプト(この資料では「Rubyの信条」と言ってます)だったのでした。 https://www.jus.or.jp/workshop/ruby/ruby-report/ws1.pdf

Like(5)

yhirano55
yhirano55 commented over 1 year

翻訳記事の依頼ってどのようにやっているのか気になってます!

Like(1)

morimorihoge
morimorihoge commented over 1 year

発表者です。質問時間多少残せる見込みですので気軽にご質問下さい

Like(1)

yuemori
yuemori commented over 1 year

現在進められているというprofile serviceの話についてです。 「writeは該当サービスの責務を持つserviceのAPI経由で行う」とのことですが、readの方はどうされてるのでしょう? そこは妥協して直接しているのでしょうか。

あとモデルは各リポジトリで別々に管理されているようですが、例えばモデル部分はgem化しておいてインターフェースに変更があったらバージョンアップ+実装変更みたいなアプローチも考えられるんですがどう思いますか?

Like(0)

yskkin
yskkin commented over 1 year

各マイクロサービスが持つべきロギング等の共通機能を内部のリポジトリに切り出しているとのことでしたが、 この共通部分は Ruby, Python, Go それぞれでメンテしているのでしょうか? もしそうであるなら負担に感じたりはしないのでしょうか?

Like(0)

shimpei
shimpei commented over 1 year

機械学習を専門とする人がつくる Python の実装は Http で Go から呼び出せるようにしているのですか? その場合、機械学習を専門とする人たちが WebAPI も実装しているのですか?

Like(1)

naoki85
naoki85 commented over 1 year

趣旨とずれているかもしれませんが、Railsでマイグレーションすることに関してです。
大きなテーブルにマイグレーションをかける際に、何か工夫されていることなどあるでしょうか?
例えばサービス停止しているとはいえ、1億レコードあるようなテーブルだとかなりの時間を要するかと思います。

Like(0)

This software is available as open source under the terms of the MIT License.
Copyright © 2018 Yoshiyuki Hirano