ツナワタリマイライフ

日常ネタから技術ネタ、音楽ネタまで何でも書きます。

開発合宿にいってきます

友人と一泊でもくもく開発をやることにした。最高か。

f:id:take_she12:20180714224834p:plain

f:id:take_she12:20180714224836p:plain

なぜかとりあえずプロジェクターを買う元同期氏。最高か。

f:id:take_she12:20180714225046p:plain

シュっと決まった。泊まる先も選んでくれた。最高か。ってことで湯河原にいってきま!

f:id:take_she12:20180714225156p:plain

何をやっていき

Nginx Up and Running v0.2 Release

blog.chaspy.me

  • nginxのソースコードビルド&ngx_mrubyのインストール
  • CircleCIによるインフラテスト
  • nginxの代表的なconfigとテスト
  • ドキュメント作成

たぶんこれはそこまで時間かけずにできると思う、3,4h?

Deis Up and Running

Up and Running言いたいだけか。

現職、Deisで動いてて、さすがに最低限のCLIと、アーキテクチャの理解ぐらいはしておかないと現状把握に困るのでシュっとキャッチアップすることにする。

とりあえずオフィシャルのドキュメント眺めてチュートリアルをやる。

deis.com

いまいまの理解はオンプレというか、自分で入れるHeroku。であればAWS上に作って、前段nginx + deis(rails + unicorn + DB)を動かす、ぐらいまでできれば御の字か。

まだあんまりよくわかってないが、Kubernetes上に動かせるとなおのこと現状に近い気がするので、できればやってみる。

deisに関してはhakoberaさんが記事を書いているので参考にしつつ。

qiita.com

Sidekiq and Resque

「なるほどUNIXプロセス」の付録を流して、非同期処理をプロセスという視点でどのように実現しているのかを理解する。

tatsu-zine.com

で、いまざっとググった感じ、いずれもRailsと一緒に使われるパターンが多そうなので、Railsと合わせて動きを理解する。

アウトプット

それぞれブログ書きます。

まとまったら月末なんらかの勉強会で LT発表します。

おわりに

たのしみだー

NginxをAWS上に作って壊すリポジトリ「nginx-up-and-running」リポジトリを作った

はじめに

作った。

github.com

とりあえず適当に0.1.0のタグをつけてリリースらしきことをしてみた。

これは何

雑な図がREADMEにありますが、NginxをAWS(EC2 instanceとして)上に作って、挙動をテストするリポジトリです。

モチベーションは何

社内ではNginxを結構派手に使っています。で、自前でもNginxを好きにできる庭が欲しい。しかし、Web application(ex. rails...)とのセットだと敷居が高い。ならば!terraform + ansible + infratasterでインフラCIを実現する学習用リポジトリを作ろう!といった感じです。

心がけてること

誰もがCloneして、すぐにドシャーって作って、ドシャーって壊せる。そしてForkしてアレンジして自分にあったものをすぐに試せる。そんな学習用リポジトリを目指したい。Nginx on AWS with CI/CDをシュっと試せる、そういう書籍で実際に動かすリポジトリ、といったイメージです。なので、ドキュメントもちゃんと作って、同人誌として出したいぐらいの気持ちもあります。

v0.1.0でできること

本当にシンプルで、最低限のところまでです。

  • terraformでVPC上にEC2 instanceをdeploy
  • ansibleでEC2 instanceにnginxをinstall
  • infratasterでGETできることをテスト

こんなもんです。最低限。

今後

で、v0.2.0に向けて何すっかなーってのを考えるために今ここでブログを書いている、という次第です。

  • nginxのソースコードビルド&ngx_mrubyのインストール
  • CircleCIによるインフラテスト
  • nginxの代表的なconfigとテスト
  • ドキュメント作成

こんなもんかな。悩んでるのはCircleCIで何をやるか、といったところで、実際にdeployまでできればいいけど、それ以外でも普通に壊して作ったりしたい。毎回壊して作ってするか、それともテスト目的にするか、を悩んでる。テストだとしても、terraform部分のテストはやっぱり実際のAWSに対して打つしかできないと思うし、ansible/terraformのところもCircleCIコンテナでやるの、若干めんどくさいなーって感じ。targetをCIとそうでないときでわけないとできない気がする。

おわりに

Nginx Up and Runningというイキったリポジトリ名にしたからには使い倒せるような学習用リポジトリを目指したい。

シュっと試す。本を読みながらシュッと実行できるって、キャッチアップする人間にとってありがたいと思うんです。今時クラウド上で、CI/CDまでできて当たり前なので、誰かに役にたつリポジトリになればいいな、という思いで、少しずつ育てていこうと思います。

2018年7月の目標

やるぞー。

技術

今回からはテーマを決めて、そのテーマをじっくりやることにする。

技術書を読んで、なんとなくなぞる、じゃなくて、テーマを実現するために参考にする書籍、という風に使う。すっげー当たり前だよな、しにたい。

非同期処理を行うsidekiqとresqueの挙動を実現する技術を理解する

現職で(確か)使われてるのもあるが、最近読んだ「なるほどUNIXプロセス」の付録で取り扱う内容でもある。UNIXプロセスの理解の延長にもなるはずだ。プロセスという観点でどのように非同期処理が実現されているのか、内部の仕組みを見て、実際に動かしてみて理解したい。

blog.chaspy.me

UNIXプロセスとは何で、何ができるものなのか?をまとめる

前述した書籍で一通りなぞったが、もう一段まとめをしておきたい。できるならコンテナ実装とも絡めて理解したい。

hello! AWS

AWS、趣味でほーーーーんの軽く触ってただけだったので、自動化基盤含めて自分自身の趣味サービスならぬ、趣味インフラを作る。含める技術スタックは以下。

  • AWS
    • S3
    • EC2
    • ECS
    • Route53
    • and AWS-CLI
  • nginx
  • CircleCI
  • Terraform
  • Docker
  • Ansible
  • Infrataster

CIを含めたインフラのデプロイを一通り触って、練習用リポジトリを作る。

副読書としてこれ読もうかなーと思ったけど高いな。どうしよ。

インフラCI実践ガイド Ansible/GitLabを使ったインフラ改善サイクルの実現

インフラCI実践ガイド Ansible/GitLabを使ったインフラ改善サイクルの実現

実際に動くアプリケーションまでは作れないと思うので、nginxで静的なWebサイトを返すところぐらいまではやる。

全部現職で触る技術なので、自分でも触って強化しとくってのが目的。

登壇

技術と登壇が並んでるの、MECEじゃない気がするがまぁいいです。

おそらく上記技術内容のUNIXプロセスについて、主催のクローズド勉強会のLTでしゃべります。

たぶん間に合わないけど、前職が会場でGitLabのMeetUpがあるので、LTネタ浮かんで間に合えば登壇したいです。

gitlab-jp.connpass.com

とはいえ今ぱっと浮かぶのは。。。

  • GitLab + Document CI(mkdocs, sphinx, etc...)
  • GitLab + Mermaid.jsで設計書管理
  • GitLab + Kubernetes
  • GitLab11.0新機能試しみる

ぐらいですかね。現職ではGitLab使わないので、優先度はやや低め。(現職に役立つ学習を優先したい)

勉強会

参加するときって脊髄反射で申し込むから気づいたらかなり多いって月があって、7月はかなり多いです、正直今は勉強会に登壇じゃなく参加でいくような時期じゃない(自分の技術をしっかり高める)ので迷いますが、かといってキャンセルも躊躇するのよね。

cloudnative.connpass.com

運営手伝ってます。

engineers-x-designers.connpass.com

k8sjp.connpass.com

正直Railsエンジニアってわけじゃないんですが、弊社のひとも登壇するので、設営ボランティア枠で申し込んでいます。

techplay.jp

弊社イベント!お手伝いもしますし、何より自分も聞きたいセッションばかりです。

techplay.jp

去年も行った、好きなイベントです。憧れの方もたくさん登壇されます。(CfPをはじめて出したけど、ちゃんと落ちました)

2018.techfesta.jp

多すぎるので反省しつつ、一度手を挙げたものはちゃんと行って吸収したい。

音楽

やってるバンドで2nd albumを7/11(Wed)にリリースしまーす!

あとは特にここで宣言しなくてもスタジオに合わせてやれてるな。。。

そっちではPM的なことやっててうまくまわってるから個人ブログに書かなくてもよくなってきた。ので次回から減らす。

英語

Seeking SREはもういいかなって感じなので、次はCloud Native Infrastructure読んでみる。

Cloud Native Infrastructure: Patterns for Scalable Infrastructure and Applications in a Dynamic Environment

Cloud Native Infrastructure: Patterns for Scalable Infrastructure and Applications in a Dynamic Environment

全部で9章ある。全部はこれまでの感じだと無理そう。。。1/3なのか1/2なのか。頑張ります。

AWSのくだりでTerraformは触るし、Terraform Up and runningもあるなーどうしようかなー多分やんねーなー詰まったら気になる章読みます。

Terraform: Up and Running: Writing Infrastructure as Code

Terraform: Up and Running: Writing Infrastructure as Code

あとはアウトプット、これも変わらず月4本にする。日記的なやつはmedium、技術ネタはdev.toへ。

自分の中のしょぼい英語をアウトプットし続けてもしゃーないのできちんとインプットする。

瞬間英作文1冊終わらせる。

どんどん話すための瞬間英作文トレーニング (CD BOOK)

どんどん話すための瞬間英作文トレーニング (CD BOOK)

ついでに目に入ったからこれも一通り目を通して消化する。

ITエンジニアが覚えておきたい英語動詞30

ITエンジニアが覚えておきたい英語動詞30

kyannyさんも読んでたし。

blog.kyanny.me

健康

ジムにいってお金をかけて少しでも意識をあげる作戦でいく。

安定した60kg台と19%台が欲しい。

お金

海外旅行で派手に使ったものの(20万+渡航費)それ以外でだいたいの支出がわかったので、改善を試みる。

  • 食費 合計 38,662円 → 25,000円

。。。いやそんだけかって感じだけど他は削る気がない。。。

  • 交際費 合計 43,664円

これ3万ぐらい目指すだけ目指してもいいけど、会いたいひとに会うためなら惜しまないしなぁ。一応記録して目指してみます。

仕事

まぁこれは職場でやりゃいい話なんだけど、今んところすぐ活躍するにはほど遠い感じなのでちゃんと個人のほうでも書いておく。

  • AWS、および周辺技術の理解(これは技術のところに盛り込んだ)
  • reverse proxy(nginx)の設定内容理解
  • CircleCI 2.0化
  • プロダクトブログ
  • Microservices および Kubernetesの理解
  • 監視内容の理解
  • 定期ジョブの理解

SREって、新しい分野を、キャッチアップしながら取り入れながらっていう領域と、古くなって負債を返していくような領域(改善?)と、通常運用と呼ばれる領域(WebDevからの依頼)に分かれる気がしている。せめて通常運用ぐらいは任してもいいぐらいになって、負債も少しずつ手を出せるようになりたい。新領域はそれからだ。

おわり

いい職場で働けています。がんばるぞ。

blog.chaspy.me

blog.chaspy.me

2018年6月振り返り

6月も終わった。

blog.chaspy.me

技術

  • (できてない)railsで簡単なサービスを実際に作る
  • OSレイヤーの学習
    • (半分読んだ)[試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識
    • (読んでない)Goならわかるシステムプログラミング
    • (読んだ)なるほどUnixプロセス ― Rubyで学ぶUnixの基礎

blog.chaspy.me

  • 新しい会社に向けたキャッチアップ
    • 残りとしてあげた部分は結局できてないが、やりながら覚えていく感じになってる

登壇

目標通り、できた。

blog.chaspy.me

音楽

2nd albumリリースがもろもろの都合でできてない。2nd liveノーミスはできなかったなー。

英語

  • (できた)Seeking SREから2つ

blog.chaspy.me

blog.chaspy.me

  • (できた)英語Writing月4本

medium.com

medium.com

medium.com

dev.to

夏休みの宿題さながら月末にバタバタ追い込んだし、最後についてはdev.toに初投稿、qiitaに書いたメモを移植した感じで済ませたのは反省。

健康

一番ダメ。海外旅行で普通にリバウンドしてるわ。あと結局運動してない。

f:id:take_she12:20180703022320p:plain

f:id:take_she12:20180703021640p:plain

お金

使途不明金なし、マネーフォワードでしっかり管理できてます。可視化はできたので次はどの分野をどれぐらい減らすか、を目標に設定していこう。

振り返り的な

6月は半ば10日は海外旅行に、そして21日からは新会社入社ということであまり時間が取れなかったのもあり、予想通りあまりできませんでした。とりあえずカイゼン・ジャーニー・ライトニングトークスでLT登壇できたのはよかった。これまでいろいろ改善とか組織とかチームとかやってきたことをシメておきたかったので。

英語については今まで1mmもしなかったのがようやく何かしらするようになったのでやっぱり必要性にかられるって大事だなーと思いました。やるぞー。

健康がやばい。これからもやばそう。いくらでも言い訳できるし。可視化しても結果出さなきゃダメなわけで。どうやって毎日運動するように自分を落とし込めるかが課題。

お金に関しても可視化まではうまくいっているので、分析して改善をして効果を見ていきたいと思う。

ついでに2Qも終わったので2Q目標も見ておく。

blog.chaspy.me

うーん、技術的なところは半分ぐらいはやったかなーでもあとは実践で入って必要なものを埋めていくって感じ。

健康に関しては全然未達成って感じです。四半期ごとの目標あんまり意味ない気がしてきた。

次のエントリで7月の目標立てます。

おまけ

書いた記事

blog.chaspy.me

ブログは18件。うち8件が海外ひとり旅日記。あとは勉強会したとか、退職エントリとか、入社して感じたこととか。シュっと書いてるのがいくつかって感じ。

あとはqiitaに3本。これも本当にメモな感じでシュっと書いただけ。qiitaには仕事でぶつかったちょっとしたTipsを書いていこうと思っている。

qiita.com

qiita.com

qiita.com

読んだ本

いい加減読書メーターのしょぼいまとめやめたい。別のサービス使おうかなあ。

美意識の本と外国語学習の科学の本はよかった。

6月の読書メーター
読んだ本の数:11
読んだページ数:2633
ナイス数:37

人生の勝算 (NewsPicks Book)人生の勝算 (NewsPicks Book)感想
あんまり面白くなかった。「仕事の基本は思いやり」は同意。
読了日:06月30日 著者:前田 裕二
世界のエリートはなぜ「美意識」を鍛えるのか? 経営における「アート」と「サイエンス」 (光文社新書)世界のエリートはなぜ「美意識」を鍛えるのか? 経営における「アート」と「サイエンス」 (光文社新書)感想
非常に説得力のある本だった。個人的に、言葉、言語化は大切だと思うし、好きだけど、それの限界を感じることも多く、一方で感覚的なものに対する信頼も年々増している。ビジネスという現場においても、大企業では上層部の意思決定のために多くの情報を提供しなければならず、現場が疲弊しているうちに市場が変わるという現場を見てきた。ビジネスの現場でも、あるいは一個人が生きる上でも、論理"だけでなく"美的感覚あるいはビジョンが必要だというのは重要なメッセージだと思う。
読了日:06月30日 著者:山口 周
外国語学習の科学―第二言語習得論とは何か (岩波新書)外国語学習の科学―第二言語習得論とは何か (岩波新書)感想
この本で書かれている分析はまだわかっていないことも多いが、感覚的に一致することも多いので自分自身の学習に反映させたい。文法/言語が完璧じゃないことを踏まえつつ、まず生の英語に大量に触れて感覚をアップデートし、その上でアウトプットをちゃんとしていく。補助的に(?)発音/単語のトレーニングは学習としてやる、というスタイルでやっていこうと思う。
読了日:06月30日 著者:白井 恭弘
インターネット的 (PHP文庫)インターネット的 (PHP文庫)感想
まさにこの本でかかれている内容こそが「インターネット的」であり、メタな本になっていて非常に面白いです。インターネットによって多種多様な表現が、ビジネスが可能になるが、エッジの人間も、市場となる人間もたいして変わらない。その中でどう生きるのか?論理/言語で表現できるところじゃなくて、感情、魂といったところがより重要になるし、かっちりしなくてもいい、不完全でもいい、より自由に生きれるけど、発信が必要で、それをしないと自由を得づらくなっていくかもしれない。それがインターネット的に発信されている本。面白かった。
読了日:06月30日 著者:糸井 重里
松浦弥太郎の仕事術 (朝日文庫)松浦弥太郎の仕事術 (朝日文庫)感想
「おとなのきほん」をベースに、仕事に対する考え方もいいですね。停滞しないよう、努力・勉強を続け、"ちゃんと"成果を出す。約束を守る。  時間を守る。  相手を喜ばせる。
読了日:06月30日 著者:松浦弥太郎
おとなのきほん 自分の殻を破る方法おとなのきほん 自分の殻を破る方法感想
自分と近い考えも多く、追いかけたい、目指したい50代の、「おとな」だなぁと思った。20代は形だけのおとなで、30を目前に、何か違うな、30以降の「おとな」ってなんだろう?ってことを漠然と考え始めたときのこの本と出会い、なるほど参考になる点がたくさんあった。美学、哲学は各個人違うにせよ、それを持ち、安定と変化を、確実に行う、そんなおとなになりたいと思った。
読了日:06月20日 著者:松浦 弥太郎
DTMerのためのド派手なバンドアレンジがガンガン身に付く本DTMerのためのド派手なバンドアレンジがガンガン身に付く本感想
ポップスのアレンジとして、参考になる。歌えるフレーズを散りばめることと、それに関して、シナジーとプライオリティを考えることは大切だと思う。
読了日:06月07日 著者:熊川 ヒロタカ,石田 ごうき
世界でいちばん旅が好きな会社がつくった ひとり旅完全ガイド世界でいちばん旅が好きな会社がつくった ひとり旅完全ガイド感想
はじめてひとりで海外旅行をするときに一通り読んでおくと、才芸元の心構えと準備ができると思う。
読了日:06月06日 著者:TABIPPO
情報を活かす力 (PHPビジネス新書)情報を活かす力 (PHPビジネス新書)感想
直近に読んだ佐藤優との僕らが毎日やっている最強の読み方―新聞・雑誌・ネット・書籍から「知識と教養」を身につける70の極意と重複が多かった * 銀の弾丸はない。インプットし、思考し、アウトプットして、ブラッシュアップしていって自分の身にする。そして問題意識を持てばまたそれに関連するインプットをする。それを繰り返すしかない。
読了日:06月05日 著者:池上 彰
会話もメールも 英語は3語で伝わります会話もメールも 英語は3語で伝わります感想
3語にするというよりは、明快なコミュニケーションをとるための取捨選択を促してくれる、良い本だと思った * 実際英会話するときは、相手が自分の言葉を待ってくれてる。具体的で、明快な言葉を、結論から先に出す、という意識だけでも違ってくると思う
読了日:06月05日 著者:中山 裕木子
ファーストラヴファーストラヴ感想
環菜が受けたことは救えないし、やったことも救えない。もう戻れないところからはじまる物語は、少しは環菜を救ったのだろうか。自分と向き合っていいことに気づけたことですら、救いかもしれない。償ったあとの8年後に彼女が自分の気持ちとともに生きられることを願う。 由紀と迦葉の関係性、それがファーストラヴだったんだと思う。謝れない。何もなかったことにしたい。なんで男と女になってしまったんだとすら思う2人は、男と女であり、信頼があり、信用があり、絆があった。死ぬまで言えない真実を抱え込んだ関係、尊いと思う。
読了日:06月04日 著者:島本 理生

読書メーター

「Seeking SRE Chapter 11. Immutable Infrastructure and SRE」メモ

はじめに

Seeking SREで気になる章を読んでいます。

Sre in Practice

Sre in Practice

前回はサービスをメッシュしていました。

blog.chaspy.me

今回はImmutable Infrastructureがテーマ。

結論、あんまり真新しいことは言っておらず、「Immutable Infrastructure最高!!!いろんな面で!!!」って感じで、まぁ内容も確かになって感じでした。

個人的にはConfiguration Managent Tool(like Chef, Puppet)との比較がされていて、そちらと対するようなことを言っていて、別に対立するものではなく両立するものでは?と思いました。あくまでアプリケーションの話だろうけど。周辺のインフラの設定に対してはどういう考えなんだろう。そこはConfiguration Managent Toolを使うべきだと思うけどなぁ。

あとは利点ばかりではなく(たった2つだけど)不利な点も述べられていてよかった。まぁそりゃそうだって感じだけど。ここでデータベースが出てくるってことはやっぱりELBみたいなものの設定変更もイメージに固めてしまえって感じなのかなぁ。ELB自体もイメージから再作成する感じで。まぁ悪くはないけど、設定変更して再起動するだけ、であれば別にConfiguration Managent Toolで十分感はある。

では以下簡単なメモ。

Chapter 11. Immutable Infrastructure and SRE

  • Immutable Inftastractureは大規模なサーバを管理するコストを減らしたよ
  • システム内の変数を減らして、同一のサーバを作り出すことで変更可能性を高めたよ

Scalability, Reliability, and Performance

  • SREは大変だけど、Immutable Infrastractureの効果は絶大だよ
  • 小さなイメージに必要なソフトウェアをインストールしたものをリリースし、その後Puppet, Chef, SSHなどあらゆる方法でも一切変更がされない方法をImmutable Infrastractureというよ。
  • Immutable Infrastructureはスケーラビリティとパフォーマンスを提供するよ。手動で数十台なら変更できたとしても、100台、1000台は骨が折れるし、エラーを起こしがちだけど、Immutable Infrastactureであればそれを回避できるよ。
  • ChefやPuppetのような構成管理ツールは最初はうまくいくけど、規模が大きくなると、特に動的に拡張するときにうまくいかなくなるよ。

Failure Recovery

  • Immutable infrastructureは障害からすぐに復旧するのにも役立つよ。ハードウェア障害が起きてもイメージからすぐに再作成すればいいからね。加えてNetflixのChaos Monkeyテストのように耐障害性を高める取り組みもできるよ。

Simpler Operations

  • Immutable infrastructureであれば変更操作もシンプルになるよ。だって新しいものに置き換えるだけだから、状態変化に気を使う必要がなくなるよね。

Faster Startup Times

  • Immutable infrastructureであれば、ビルドには時間がかかるけど、起動時間ははるかに短縮できるよ。このおかげで、短い起動時間の範囲のみ予想すればよく、スケールアウト/ダウンが容易かつ効果的になるよ。

Known State

  • SREやセキュリティーチームにとってもImmutableでないサーバの管理は懸念がたくさんだよ。

Continuous Integration/Continuous Deployment with Confidence

  • Immutable infrastructureでない場合、微妙な変更差分がデプロイの失敗を招き、「テスト環境ではうまくいったんだ!」ということを起こしかねないよ。Immutable infrastructureであれば、Blue/Green Deploymentによってロールアウトとロールバックがスムーズにできるからいいよ。

Security

  • セキュリティの観点でもImmutable infrastructureは大切だよ。
    • 一時的にインストールしたライブラリがあったりして脆弱性を放置してしまうことを防ぐ
    • セキュリティパッチの適用も通常のデプロイと同じフローで行えるから安全
    • 何よりKernelのアップデートのような再起動を伴うパッチ適用も、事前にインストールした状態で配れるから安全だし速いよ

Multiregion Operations

  • 複数リージョンでもImmutable infrastructureであれば複製が容易だよ。構成管理だと難しいよ。

Release Engineering

  • 開発者にとってインフラの設定変更はおそろしいものであり、運用者のレビューなしでは適用できず、設定管理ツールが持つ言語を習得する必要があるよ。Immutable infrastructureであればこういった懸念事項はなくなるよ。

Building the Base Image

  • immutable infrastructureを行う最初の一歩は良いイメージを作ることだよ。
  • 小規模なサービス(shop)であればLinux Dist.のイメージを使うといいよ。
  • それなりに規模のあるサービスであれば、
    • 不要なパッケージを取り除き、
    • セキュリティアップデートがされ、
    • 共通ライブラリや内部で使うパッケージをインストールされたイメージを作るといいよ。
  • 新しいイメージを展開するときは、優先度の低いサービスに対して、カナリアでリリースするといいよ。

Deploying Applications

  • 必要なパッケージはベースイメージにインストールされ、展開するコードも何らかのパッケージングシステムにより更新されるよ。

Disadvantages

  • 永続的なデータレイヤーにはImmutable Infrastructureの適用は難しいよ。1台ずつ変更すべきで、構成管理の方法が向いてるよ。
  • イメージの更新に時間がかかるのも問題だよ。開発者がちょっとした変更を行うのにビルドを待つのはやりたくないよね。一時的に開発環境へのコードの変更を容易にすることでバランスをとりたいよね。

Conclusion

  • 導入できたら開発者はよりプロダクト開発に集中でき、アプリケーションの展開時間を短縮でき、信頼性のあるインフラを実現できるね! :+1

「なるほどUNIXプロセス」を読んだ

はじめに

読んだ。

tatsu-zine.com

ずいぶん前に買っていて、途中までやって放置していた。3時間ほどで読み通せた。 モチベーションとしては、「プロセス」って正直よくわかってないな、と思ったから。そのあたりをちゃんと学ぼうと思った。 コンテナを使うことが当たり前になった今、コンテナはプロセスだーって言っても、そもそもプロセスって何なのか。こういうOSレイヤーの知識は長く活きるので、学習効果が高いと思い、最近はこのあたりを学んでいきたいと思っている。

感想

プロセスとはUNIX上の全てのプログラムの実行単位としての抽象概念であることがわかった。

この本はUNIXプロセスの様々な挙動をRubyプログラムから試す本である。さくさく進めて気持ちいいし、著者のユーモアの効いた表現が読んでいて楽しい。ただその特性からRubyプログラムを深く理解するものでも、UNIXプロセスの詳細を理解できるものでもなく、あくまでRubyプログラマUNIXプロセスの仕組みを理解するための最初の一歩を手助けしてくれる本である。必要に応じて別のサイトを参考にしながら進めたほうがいい。

副読書としてはLinuxのしくみのプロセスの部分に先に目を通しておくと良さそうだ。

[試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識

[試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識

この本には付録がついている。おそらく実際のアプリケーションを通じた応用的な内容だと思う。現職でもWebサーバや非同期ジョブシステムは使っているので、また別の機会に学ぶ。

  • 付録
    • Resque
    • Unicorn
    • preforkサーバ
    • Spygrass(学習用アプリ)

以降は動かしながらのメモ。

3章 すべてのプロセスにはIDがある

rubyプロセスのid

irb(main):001:0> puts Process.pid
12512
=> nil

psで確認

$ ps -p 12512
  PID TTY           TIME CMD
12512 ttys001    0:00.17 irb

4章 プロセスには親がいる

irb(main):002:0> puts Process.ppid
9825
=> nil

irbプロセスの親プロセスはbash

$ ps -p 9825
  PID TTY           TIME CMD
 9825 ttys001    0:00.15 -bash

5章 プロセスにはファイルディスクリプタが ある

Unix の世界では「すべてがファイルである」。これは Unix の哲学の一つだ。

ファイルディスクリ プタはプロセスとともに生き、プロセスとともに死ぬ運命にある。

/etc/passwdを開いたときのファイルディスクリプタ番号を取得する。

irb(main):003:0> passwd = File.open('/etc/passwd')
=> #<File:/etc/passwd>
irb(main):004:0> puts passwd.fileno
9
=> nil

このファイルを閉じないまま、/etc/hostsを開く

irb(main):005:0> hosts = File.open('/etc/hosts')
=> #<File:/etc/hosts>
irb(main):006:0> puts hosts.fileno
10
=> nil

1つ増える。

クローズするとファイルディスクリプタ番号は再利用される。

irb(main):005:0> hosts.close
=> nil
irb(main):006:0> profile = File.open('/etc/profile')
=> #<File:/etc/profile>
irb(main):007:0> puts profile.fileno
10
=> nil

通常、ファイルディスクリプタ番号の最小は3であり、0, 1, 2は標準入力、標準出力、標準エラー出力に割り当てられている。

irb(main):008:0> puts STDIN.fileno
0
=> nil
irb(main):009:0> puts STDOUT.fileno
1
=> nil
irb(main):010:0> puts STDERR.fileno
2
=> nil

第6章 プロセスにはリソースの制限がある

1プロセスあたりのファイルディスクリプタ上限を調べる。

irb(main):011:0> p Process.getrlimit(:NOFILE)
[4864, 9223372036854775807]
=> [4864, 9223372036854775807]

ソフトリミットとハードリミットが得られる。

ちなみにOSのファイルディスクリプタ上限は以下の通り、256。こっちのほうが少ない。

$ sudo launchctl limit
Password:
    cpu         unlimited      unlimited
    filesize    unlimited      unlimited
    data        unlimited      unlimited
    stack       8388608        67104768
    core        0              unlimited
    rss         unlimited      unlimited
    memlock     unlimited      unlimited
    maxproc     709            1064
    maxfiles    256            unlimited

第7章 プロセスには環境がある

ここでいう「環境」とはいわゆる「環境変数」のことだ。環境変数はキーとバリューが 対になっており、プロセスで使えるデータを保持している。

$ MESSAGE='wing it' ruby -e "puts ENV['MESSAGE']"
wing it

ENV には Hash のようにアクセスできる API が用意されているが、実際には Hash オ ブジェクトではない。

第8章 プロセスには引数がある

$ cat /tmp/argv.rb
p ARGV
$ ruby /tmp/argv.rb foo bar -va
["foo", "bar", "-va"]

前章で紹介した ENV は Hash オブジェクトではなかったが、ARGV は普通の Array だ。

所感:引数はプログラムのものと思っていたが、プロセスの概念だったのははじめて知った

第9章 プロセスには名前がある

プロセスのレベルで情報を伝えるための仕組みは二つある。一つはプロセス名。もう一 つは終了コードだ。

RubyではPROGRAM_NAMEというグローバル変数に格納されている。

irb(main):001:0> puts $PROGRAM_NAME
irb
=> nil
irb(main):002:0> puts Process.pid
13146
=> nil
irb(main):003:0> $PROGRAM_NAME = "irbirb"
=> "irbirb"

この変数を変更すれば、psコマンドでも変更が確認できる。

$ ps -p 13146
  PID TTY           TIME CMD
13146 ttys001    0:00.17 irbirb

第10章 プロセスには終了コードがある

プロセスが終了時にこの世に残す最後のしるし、それが終了コードだ。あらゆるプロセ スは、正常終了か異常終了かを示す終了コード値(0-255)と共に終了する。

  • Kernel#exit: デフォルトでは終了コード0を返す。任意の終了コードを返すこともできる。
  • Kernel#exit! デフォルトでは終了コード1を返す。任意の終了コードを返すこともできる。Kernel#at_exit で定義されたブロック は実行されない。
  • Kernel#abort デフォルトでは終了コード1を返す。メッセージを渡すことができ、STDERRに出力される。
  • Kernel#raise デフォルトでは終了コード1を返す。呼び出し元に送出される。メッセージを渡すことができ、STDERRに出力される。
irb(main):004:0> exit
$ echo $?
0
$ irb
irb(main):001:0> exit!
$ echo $?
1

第11章 プロセスは子プロセスを作れる

子プロセスは親プロセスで使われているすべてのメモリのコピーを引き継ぐ。親プロ セスが開いているファイルディスクリプタも同様に引き継ぐ。

irb(main):001:0> puts "parents process pid is #{Process.pid}"
parents process pid is 13273
=> nil
irb(main):002:0> if fork
irb(main):003:1> puts "entered the if block from #{Process.pid}"
irb(main):004:1> else
irb(main):005:1> puts "entered the else block from #{Process.pid}"
irb(main):006:1> end
entered the if block from 13273
=> nil
entered the else block from 13286
irb(main):007:0> => nil

何が起きたのか?

  • forkは子プロセスを生成し、1つは呼び出し元に、1つは子プロセスに返る
    • 親プロセスに対しては、生成した子プロセスのpidが返す
    • 子プロセスではforkはnilを返す
irb(main):001:0> puts fork
13383
=> nil
irb(main):002:0>
=> nil

第12章 孤児プロセス

親プロセスが死んだら、子プロセスには一体何が起きるのだろうか? 端的に言えば「何も起きない」。どういうことかというと、オペレーティングシステム は子プロセスを特別扱いしない。だから親プロセスが死んでも子プロセスは生き続ける。 親プロセスは死ぬ時に子プロセスを道連れにしない。

第13章 プロセスは優しい

CoW は fork(2) で子プロセスを生成するときにリソースを節約できるのがとても便利 だ。親プロセスの物理メモリを一切コピーしなくて構わないので、fork(2) は速い。子プ ロセス側で必要になるデータだけコピーすればよく、残りは共有すればいいのだ。

第14章 プロセスは待てる

Process.wait は何をしたのだろうか? Process.wait は、子プロセスのどれ か 1 つが終了するまでの間、親プロセスをブロックして待つ。

Process.wait には Process.wait2 という親戚がいるん だ! どうしてこんな紛らわしい名前なのだろうか? だが、戻り値(pid)を 1 つ返すの が Process.wait で、2 つ(pid と終了ステータス)を返すのが Process.wait2 だと説 明すれば納得してもらえると思う。

動かしてみる。

$ cat /tmp/orphan.rb
# 子プロセスを 5 つ生成する
5.times do
  fork do
# 子プロセスごとにランダムな値を生成する。
# もし偶数なら 111 を、奇数なら 112 を終了コードとして返す。
    if rand(5).even?
      exit 111
    else
      exit 112
    end
  end
end

5.times do
# 生成した子プロセスが終了するのを待つ。
  pid, status = Process.wait2
# もし終了コードが 111 なら、
# 子プロセス側で生成された値が偶数だとわかる。
  if status.exitstatus == 111
    puts "#{pid} encoutered an even number!"
  else
      puts "#{pid} encoutered an odd number!"
  end
end
$ ruby /tmp/orphan.rb
13530 encoutered an odd number!
13529 encoutered an odd number!
13528 encoutered an odd number!
13527 encoutered an even number!
13531 encoutered an odd number!

Process.wait2はいずれかの子プロセスが終了するまで待つ、というのがポイントだ。

ま だ 話 は 終 わ ら な い 。実 は Process.wait に は さ ら に 2 人 の 親 戚 が い る 。 Process.waitpid と Process.waitpid2 だ。

!?

違いは、任意の子プロセスの終了 を待つのではなく、指定した子プロセスの終了を待つという点になる。このとき、終了を 待つ子プロセスは pid で指定する。

2 つのメソッドの実体は同じかもしれないが、任意 の子プロセスを待つ場合には Process.wait を、特定のプロセスを待つ場合には Process.waitpid を使おう。

親プロセスがProcess.waitにたどり着く前に子プロセスが終了したとしたら?これは問題ない。

カーネルは終了したプロセス の情報をキューに入れておくため、親プロセスは子プロセスの終了時点の情報を必ず受け 取ることができる。

逆に、子プロセスがない状態でProcess.waitを行うと例外となる。

終了を待つ子プロセスが 1 つも無い状態で Process.wait の一族のどれかを呼び出 すと Errno::ECHILD 例外が送出されることに気をつけておこう。生成した子プロ セス数を控えておいて、この例外が送出されないようにしておこう。

第15章 ゾンビプロセス

カーネルは、親プロセスが Process.wait を使ってその情報を要求するまで、終了し た子プロセスの情報をずっと持ち続ける。すなわち、親プロセスが子プロセスの終了ス テータスをいつまでも要求しなければ、その情報はカーネルから決して取り除かれない。 となると、子プロセスを「撃ちっ放し」方式で生成して、子プロセスの終了ステータスを 放置しているのは、カーネルのリソースの無駄使いになるというわけだ。

Process.detach は何をしているのだろうか? Process.detach は新しいスレッドを 生成している。生成されたスレッドに与えられた唯一の仕事は、 pid で指示された子プ ロセスの終了を待ち受けることだ。こうすることで、カーネルは誰からも必要とされない 終了ステータスを持ち続けなくてよくなる。

整理。ゾンビプロセスとは、

  • 親プロセスからforkされた子プロセスであり
  • 終了した子プロセスであり
  • 親プロセスが子プロセスの終了を要求していない状態である

本当?

プロセス - Wikipedia

UNIXオペレーティングシステムにおいて、ゾンビプロセスZombie Process)は、処理を完了したがプロセステーブル(プロセス制御ブロック相当)が残っていて、終了ステータスを読まれるのを待っているプロセスである[1][5]。この用語のメタファーに従えば、ゾンビプロセスは「死んでいる」が、まだ「死神」が到着していないということになる。

本当だった。

所感:今まで子プロセスの終了を始末するという場面に出会ったことがなかった。子プロセスを生成するシステムではうまくゾンビとならないようになっているのだろう。

第16章 プロセスはシグナルを受信できる

Process.wait はブロッキング呼び出し だ。つまり、子プロセスが終了するまで親プロセスは処理を続行できない。 親は親で忙しい場合はどうすればいいだろうか? すべての親が日がな一日、ぶらぶら している子供たちを待てるわけもない。そんな忙しい親のための解決策を紹介しよう! Unix シグナルの出番だ。

子プロセスが終了した時に、カーネルから送られるSIGCHLDを親プロセスで補足すれば良い。

Unix シグナルの世界への第一歩を踏み入れることができた。シグナルは非同期通信だ。 プロセスはカーネルからシグナルを受けたとき、以下のいずれかの処理を行なう。

  1. シグナルを無視する
  2. 特定の処理を行なう
  3. デフォルトの処理を行なう

シグナルはある特定のプロセスから別のプロセスへと送られるものであり、 カーネルはその仲介役となっている。

2つのrubyプログラムで、片方のプログラムから片方のプログラムにkillシグナルを送ってみる。

$ cat /tmp/sleep.rb
puts Process.pid
sleep
$ ruby /tmp/sleep.rb
13797
$ cat /tmp/kill.rb
Process.kill(:INT,13797)
$ ruby /tmp/kill.rb

実行すると、1つめのプログラムは終了する。

Traceback (most recent call last):
    1: from /tmp/sleep.rb:2:in `<main>'
/tmp/sleep.rb:2:in `sleep': Interrupt

INTシグナルが送られたことがわかる。

Signalにはたくさん種類があるが、killとstopとuser1/2ぐらいしか使ったことがない。

Man page of SIGNAL

第17章 プロセスは通信できる

プロセス間通信(IPC、Inter Process Communication)と呼ばれる分野の話 になる。IPC はさまざまな方法で実現できる。この章ではよく使われる 2 つの方法を紹 介しよう。パイプとソケットだ。

パイプを使ってwriterからreaderへ文字列を送る。

irb(main):001:0> reader, writer = IO.pipe
=> [#<IO:fd 9>, #<IO:fd 10>]
irb(main):002:0> writer.write("Into the pipe I go...")
=> 21
irb(main):003:0> writer.close
=> nil
irb(main):004:0> puts reader.read
Into the pipe I go...
=> nil

readerからwriterへ送ることはできない。そもそも、IO.pipeの返却値はreader, writerの順に返るようだ。

docs.ruby-lang.org

戻り値の配列は最初の要素が読み込み側で、次の要素が書き込み側です。

また、親プロセスはforkした子プロセスとメモリを共有するため、パイプでメッセージをやり取りすることが可能だ。

パイプは一方向だが、ソケットは両方向で読み書きができる。

第18章 デーモンプロセス

デーモンプロセスは、ユーザーに端末から制御されるのではなく、バックグラウンドで 動作するプロセスだ。デーモンプロセスのよくある例には、Web サーバやデータベース サーバのように、リクエストを捌くためにバックグラウンドで常に動作するプロセスが挙 げられる。

オペレーティングシステムにとって特別重要なデーモンプロセスが一つある。前の章 で、すべてのプロセスは親プロセスがあることを説明した。これはあらゆるプロセスに あてはまる真実だろうか? システム上のまさに一番最初のプロセスについてはどうだろ うか。

initプロセスである。pidは1だ。

$ ps -p 1
  PID TTY           TIME CMD
    1 ??         2:52.00 /sbin/launchd

Macだとlaunchdというものだった。

launchd - Wikipedia

launchdデーモン)、アプリケーションプロセススクリプトの起動・停止・管理を行う、オープンソースのサービス管理フレームワークである。アップル)のDave Zarzyckiによって作られ、Mac OS X Tiger (Mac OS X v10.4) で導入された。Apache Licenseのもとで公開されている。

Process.setsid は次の 3 つの処理をおこなう。

  1. プロセスを新しいセッションのセッションリーダーにする
  2. プロセスを新しいプロセスグループのプロセスグループリーダーにする
  3. プロセスから制御端末を外す

???

  • プロセスグループ:プロセスのグループ。基本的に子プロセスは親プロセスと同じグループになる。プロセスはシグナルを受け取ると、グループ内のすべてのプロセスにシグナルを送る。
  • セッショングループ:プロセスグループよりさらに一段抽象化したグループ。親子関係はないが、パイプでつなげられた一連のコマンドが該当する。
    • セッションリーダーにシグナルが送られると、同じセッショングループのプロセスにもシグナルが送られる

はじめて知った。デーモンプロセスを作るには、新規セッション・グループのリーダーにし、端末の関連を外すことで独立させるということをしている。

第19章 端末プロセスを作る

Ruby プログラムでよくある他のプログラムとの連携方法に、端末から外部コマンドを 動かす「シェルに出る(シェル・アウトする)」というやり方がある。Ruby スクリプトで いくつかのコマンドを自分用に組み合わせて使う場合などに、こうした光景によく遭遇す る。Ruby から外部コマンドを実行するためにプロセスを生成する方法は複数提供されて いる。

この章でこれから説明していく手法はすべて、fork(2) + execve(2) の応用だ。

一度 Ruby プロセ スを execve(2) で他のプロセスに置き換えたら、それはもう決して元には戻せないのだ

irbで実行するとirbプロセスは終了した。

$ irb
irb(main):001:0> exec 'pwd'
/Users/take
$

execve(2) は、現在のプロセスを別のものに置き換える、とても強力で効果的な方法だ。唯一の難点 は、現在のプロセスが終了してしまうことだ。そこで fork(2) が活躍する。

rubyプログラムからpythonプログラムを実行する例。

$ cat /tmp/exec.rb
hosts = File.open('/etc/hosts')
python_code = %Q[import os; print os.fdopen(#{hosts.fileno}).read()]
# 引数の最後のハッシュは exec を介して開きつづける
# ファイルディスクリプタを指定している
exec 'python', '-c', python_code, {hosts.fileno => hosts}

結果、ちゃんと動く。

$ ruby /tmp/exec.rb
##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting.  Do not change this entry.
##
127.0.0.1   localhost
255.255.255.255 broadcasthost
::1             localhost

ポイント

  • Ruby での exec 呼び出しは、デフォルトで標準ストリームを除くすべての ファイルディスクリプタを閉じる。

    • execのオプションとしてファイルディスクリプタとIOオブジェクトのハッシュを渡すことで、execで呼び出したpythonプログラムからも対象ファイルをopenできる
  • fork(2) と違い、execve(2) は新しいプロセスとメモリを共有しない。

  • execに引数として配列を渡す。

    • 外部コマンドを文字列としてまとめて exec に渡した場合は、実際にシェルプロセスが 起動して、渡された文字列を解釈する。配列にして渡した場合には、シェルの起動は行わ れずに配列を直接 ARGV にして新しいプロセスに渡す。

そういえばcapistranoで実行コマンドを文字列にするか配列にするかで挙動に違いがあるって話があった気がする。

これらの手法には一つだけ難点があって、それは fork(2) に依存していることだ。

シェルアウトする場合、いかなる場合でもforkを使うので、メモリを全てコピーされる。それが単純なlsだったとしても。

fork(2) にはコストがかかり、パフォーマンスのボトルネックになる可能性がある、と いうことを頭の隅に入れておこう。

第20章 おわりに

Unix のプロセスについて「なるほど」と合点がいくというのは、次の 2 つを会得する ということだ。つまり、抽象化と情報伝達だ。

  • Kernelから見るとプログラムは全て同じに見せるのがプロセスという抽象化である
  • シグナルや名前、パイプやソケットを使ってプロセス同士は情報伝達ができる

入社して7日

blog.chaspy.me

今しか書けないこともあるだろうから、シュっと書く。しっかりは書かない。

7営業日が経った。業務はGitHubとSlackとGSuiteで完結しており、全ての仕事はGitHub issueで行う。で、細々とした依頼をissueでアサインされて、説明してもらい、やりながら学びながら、プルリクを出して終わる。そういう感じだ。

これが出来るのもInfrastructure/Configure as a codeがしっかりできているからだろう。まだまだスピードは遅いが、わからなければコードを読めばいいので、読んで読んで、わからないものは聞いて、プルリクでレビューもらって、バシーって感じ。

特に前回の記事と変わったことはない。少しずつ、少しずつ。社員同士の交流の機会も多いと思う。業務でなくてもイベントがあったり、急に呼ばれたり、もちろん全ては強制ではないが、僕はひとと話すのが好きだし、新人だから覚えてもらいたいし、覚えたいし、ということでなるべく顔を出すようにしている。

ちゃんと他人に、チームメンバーに関心を持っている感じがする。これはslackの絵文字のリアクションの効果も手伝っているのは見逃せないが、それでも、ちゃんと。自分のことだけ考えるとかじゃなくて、ちゃんと、まわりのひとを気にかけていることがわかる。ありがたい。

変わらない不安は、やっぱり自分ができること、自分ができるスピード、自分が知ってること、自分のことばかりだ。チームにはどうやって勝つねんみたいな強いひとばかりだが、焦らずやっていこうと言い聞かせる他ない。

いい感じだ。