Questions and feedbacks

SyoheiYamaki
SyoheiYamaki commented over 1 year

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

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)

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)

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

@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

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

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

Like(0)

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

セッションテーマとちょっとずれた質問ですが、「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)

expajp
expajp commented over 1 year

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

Like(0)

Altech
Altech commented over 1 year

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

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

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

Like(1)

yuemori
yuemori commented over 1 year

habitusなどの一時secret server付きでdocker multi-stage buildを実行できるツールを使うのが個人的にはベストプラクティスです。

なるほど、habitus知りませんでした。勉強になります。

これはその通りで、ぼくは時間がかけられる場合は地道にゴミファイル消してます・・

つらいと感じてるのはここですね……やっぱり地道にゴミファイル消すアプローチなんですね。 native extensionに必要なファイルだけビルダーイメージからとってくるか、消すかどちらかだとは思うんですがどちらにしても時間対費用が高くないケースが多いので、、 (とはいえ、慣れてくると何が必要なやつかわかるようになりそうなので、だんだんコストが下がってきそうではありますが)

前提として「マネージドでいけるときは基本マネージドがおすすめ」 既に重要なデータが大量にAWSにロックインされてしまっている

なるほど、、サービスが別れたり移行したりはやっぱりつらいですしね。 学習コストや採用基準についての見解も納得でした。

ご回答ありがとうございました!

Like(1)

Altech
Altech commented over 1 year

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

この辺特別詳しいわけではないのですが、Postgres の場合はカラム追加はデフォルト値を設定しなければ一瞬で終わるので、デフォルト値を設定したい場合は一旦設定せずにmigration してから値を fll する script を走らせてから再度 migraiton、がよくあるプラクティスだと思っています。カラム削除は内部的に disable にされるだけなのですぐ終わると思います。

Like(0)

Altech
Altech commented over 1 year

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

はい、Web API を tornado というシンプルなフレームワークを使って機械学習チームが実装しています。

Like(1)

morimorihoge
morimorihoge commented over 1 year

せっかくなのでRailsっぽい質問です。

Railsで生SQLを発行する場合、ActiveRecord標準の #page #per が使えないと思うのですが、ページネーションなんかでこういうgemとか実装にすると良いよっていうのはありますでしょうか?

Kaminari.paginate_array 以外に最近はこういうのがいいよ、みたいなのありましたら知りたいです!

Like(1)

purintai
purintai commented over 1 year

以前の職場における話なのですが、新規に Rails + PostgreSQL のプロジェクトを立ち上げる際にDB設計に協力頂いた DBA からトリガーやマテリアルビューの使用を推奨されたとき、 Rails と DB に業務ロジックが分散してしまい将来のメンテナンス性が低下するリスクを懸念して結果不採用としました。(ロジックは Rails 側に寄せました)

仮に、 Rails プロジェクトでこれらデータベースの機能と付き合っていく場合、保守性を考慮した最適なベストプラクティスとはどのようなものがあるでしょうか。

Like(3)

joker1007
joker1007 commented over 1 year

トークでは省略されてましたが、LDAPクライアントのmrbgemsとかあったりするのでしょうか?

Like(0)

ttwo32
ttwo32 commented over 1 year

Ruby、Railsにも様々な技術要素、トピックがあると思いますが、 翻訳する記事の選定基準などあったりするのでしょうか?

Like(1)

yskkin
yskkin commented over 1 year

使ったことがないので間違っているかもしれませんが、 PostgreSQLではテーブルの継承ができたとおもうので、それを使ってもビールとワインを横断した検索ができそうな気がします。 それと比べたときのマテリアライズドビューの利点欠点を教えてください。

Like(0)

Altech
Altech commented over 1 year

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

新しく service を立てるときには毎回書かなければ行けないコードではあるので、実装コストはペイすると思っています。一方で、これが広く使われた場合に各リポジトリでバージョンを上げるのは少し面倒かもしれないです(バージョンアップで互換性が破壊されるような複雑な機能は入れていないという前提です)。

Like(0)

Altech
Altech commented over 1 year

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

モノリシックアプリケーションである Wantedly Visit 以外は Wantedly Visit に対して API 経由で profile を取得しているので、Wantedly Visit 以外は read を profile service の API 経由で取得するようにできます。

ただ Wantedly Visit では profile はコードベースの広い範囲で様々な形で使われているので、少し難しい気もしています。今回、優先して解決したい問題としては、1) 書き込みの際の整合性担保、2) Wantedly Visit に多サービスの負荷が集中しない構造にする、3) 変更のフックを書くサービスが受け取れるようにする、などがあるのですが、それらに対してはそこまでやる必要がないという事情もあります。

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

特に Rails だけを使いたいわけではないので原則は API で抽象化したいところですが、上記の Wantedly Visit と profile service の間に関しては現実的にあり得る選択肢かもしれないですね。

Like(1)

expajp
expajp commented over 1 year

翻訳記事は結構昔のものが多い(=フィードだと見つけづらい?)ですが、どのように見つけていらっしゃるのか教えてください

Like(2)

Y-Fujikawa
Y-Fujikawa commented over 1 year

記事を集める際の主要サイトはどのサイトのことでしょうか?

Like(2)

shinkufencer
shinkufencer commented over 1 year

独自のモデリングをされている様子でしたが、ActiveRecordとの棲み分け(ディレクトリやDBテーブルの使い方)はどうされているのかが気になりました

Like(0)

yiwasakita
yiwasakita commented over 1 year

Google 翻訳について 自分も IT 翻訳下いたことがありますが,自分の中で日本語訳が曖昧な単語レベルでの確認作業が軽減されると感じていますが,いかがでしょうか?

Like(1)

abicky
abicky commented over 1 year

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

うろ覚えな知識で

  1. unique key
  2. unique key がなければ内部的に作成する

という回答をしましたが、kamipo さんがマニュアルページ教えてくれました! https://dev.mysql.com/doc/refman/5.7/en/innodb-index-types.html

  1. unique key の中でも全てのカラムに NOT NULL 制約のあるもの
  2. 該当するものがなければ GEN_CLUST_INDEX という隠れた index を作成する

という感じみたいですね。

Like(0)

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