signal を http で受ける process wrapper 書いた

結局使わなかったので供養のためにブログ化しておく.

github.com

docker を始めとするコンテナ環境では,設定を適用するため signal を送ることで graceful reload をする仕組みは相性が悪いことがある.ホスト環境から動作中のコンテナに対してなんらかの働きかけが必要だからだ.なので,例えば systemd 環境下で動作しているアプリケーションをそのままコンテナ化することが難しかったりする. 特に,複数のアプリケーションが強調して動作する仕組みが必要である場合,side car コンテナなどでアプリケーションを分割すると途端に困難さが増す*1. アーキテクチャの刷新をするのが最も健全な手段であるが,そうもいかない場合に対処するため,signal のインターフェースを http に露出させるプロセスの wrapper を書いた.

mvp

signal を露出させたいプロセスの例として signal_echo.rb を用意

# signal_echo.rb

running = true

Signal.trap('INT') do |signo|
  puts 'Traped SIGINT'
  running = false
end

loop do
  break unless running
end

signal_echo.rb を http-signal-proxy から立ち上げる Dockerfile を用意

# Dockerfile

FROM ruby:2.5

RUN wget -q https://github.com/s4ichi/http-signal-proxy/releases/download/v0.1.0/http-signal-proxy_v0.1.0_linux_amd64.tar.gz && \
  tar -zxvf http-signal-proxy_v0.1.0_linux_amd64.tar.gz && \
  mv http-signal-proxy_v0.1.0_linux_amd64/http-signal-proxy /usr/local/bin/http-signal-proxy && \
  chmod +x /usr/local/bin/http-signal-proxy

COPY ./signal_echo.rb /signal_echo.rb
CMD ["http-signal-proxy", "--port=8080", "--command=ruby signal_echo.rb"]

実行

$ docker run -d --rm -p 8080:8080 -t http-signal-proxy-test:latest 
81f3d8507baa9c2a945c20d920824b6ca18f3be4ef04c7b853ac9b33c0480356

$ docker ps
CONTAINER ID        IMAGE                           COMMAND                  CREATED             STATUS              PORTS                    NAMES
81f3d8507baa        http-signal-proxy-test:latest   "http-signal-proxy -…"   4 seconds ago       Up 3 seconds        0.0.0.0:8080->8080/tcp   jolly_spence

$ curl http://localhost:8080/http-signal/sigint
Successed to proxy sigint to destination command%             

$ docker ps                                    
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

実装は entrykit とか supervisord を参考にした.entrykit はなかなか厳しそうなコードがそこそこあることがわかった.

push or pull

コンテナ外部から reload したいとき(push 型)はこういう手段がいいのかなぁと思って書いた.結局使わなかったというのは,コンテナ内部で reload が必要かどうかを polling すれば(pull 型)十分であることがわかったからだ.push 型はいつか必要になるのかな….

アイデンティティを発破解体した

学生気分が薄くなっていくにつれて,id と自分自身になんとなくギャップが生まれているなと感じることが多くなり, 将来的に 30 代になってもこの id を名乗り続けるのは厳しいという気持ちが芽生えたので,アイデンティティを発破解体して無難なものへと変更した.

変更すると決断するまでは,どうせ中途半端になるか何か問題が発生するだろうという諦め(怠惰の言い訳?)のもと,1ヶ月くらい悩んでいた. 色んなサービスの id 変更について調べたり,自分の気持ちにどうなんだと問いかけたり,今までになく足が重かったと思う.

自分でも覚えていないくらい様々なサービスに登録していたり,そもそも id を変更しきれない部分*1もあったり,変更すると混乱を招きそうな部分はそのままにするつもりなので,しばらくごちゃまぜになります⚠

*1:ちなみにはてなIDは変わらないそうなので独自ドメインにした

Summer Internship 2018 at mercari

8/2 から 8/31 までの間、mercari で開催された今年度のインターンシップへ参加してきた。 業種は募集記事にもある "Software Engineer (Microservices Platform)" で、 社内の Kubernates 基盤や Microservices における開発・運用全体に携わる業務を中心に行うチームを選択した。

mercan.mercari.com

簡単にまとめると、とにかく "Be Professional" を体感できた良いインターンシップだった。 以下に参加記という体で自分の感じたこととやったこと、そして上記の理由をまとめる。

動機と選考と印象

今年の夏は長期インターンシップに参加したいという漠然とした心意気だけがあり、 魔法スプレッドシートを見ながら迷ったりしていた。 正直ハッカソン形式や講義形式はそんなに興味が無く、実務をしたいという気持ちのもとで色々見てみると、 研究開発系は「機械学習で〜」とか「AIが〜」という決まり文句が多くて研究分野とマッチしないし、 開発系はふわっとした要項が多いためにどこも同じように見えてしまって、内容というよりは企業のネームバリューで選択する他なかった。 そんな中で "Microservices Platform" という文字列を見つけて「これは!」と思ったのが申し込んだきっかけだった *1

申し込みフォームからの書類選考兼 GitHub その他の選考があり、 それを通過すると簡単なコーディングの選考、最後に選択したチームのメンバーやテックリードと面接をして合否決定という流れだった。 後になって知ったけど、インターンシップを複数の会社応募するのはあるあるらしい。 自分は mercari しか応募しておらず、落ちたら暇だなーと考えていたので悲しいですね。

期間は 8 月いっぱいの予定だったが、月初に学会発表を控えていたので1日だけ遅らせてもらった。 これは働き方とか業務全般に感じたけど、色々な融通が(常識的な範囲内なら)だいたい OK と返事を貰えることが多くて、ストレスフリーな職場でかなり体験が良かった。

入社説明時に「成果を残してください」風なことを何度も言われたのが印象に残っている。 もちろん通常業務でという話なので、目標設定と自分のやり遂げ力が必要っぽいなというのを感じさせられて結構緊張していた。

あとは、メンターランチという制度があって、それを利用して入社後に何度か他のチームや社員の人と六本木の高めなお店へランチへ行くことができる。 下のようなヤバそうなご飯が食べれて、もちろんお金も出るし、誰と行きたいか困ったらメンターさんにお願いすることもできる(自分は結局ほとんどおまかせしていた)。

f:id:everysick:20180911235803j:plain

開発

上記でも書いた通り、自分の配属された Microservices Platform Team では、社内で推進されている Microservices 化に必要な基盤を整える業務を中心としていた。 直近にどういうことをしているかというのは 7 月に開催されていたイベントの資料が詳しい。

tech.mercari.com

入社後にアーキテクチャの説明とか軽い on-boarding を受けた後、目標設定の段階で「あ、これは Kubernetes の前提知識が全然足りない」という現実に直面した。 業務の流れとかアーキテクチャの構成を表面的に理解するまでは良いのだけど、じゃあそれを説明してくださいと言われるとスムーズに行かない感じである。 メンターの方はそれをすっぱり見抜いて、まずは構成把握を兼ねた周辺知識のインプットからというタスク割をしてくださったので助かりました…。

開発では Golang を使っていたのだけど、実は Golang も production-ready なソフトウェアを書いたことがない状態だった。 レビューを通してオレオレコードから Golang らしい丁寧なコードを書く方法や精神論(?)を享受してもらえたのは本当に良い経験だったし、 自身の作業をこなしながらレビューをしてくださったので、全然頭が上がりそうにない。へこへこするしかない。

成果物

メンターさんやチームの方の指導の下で、一ヶ月という間でインプットから当初目標していたアウトプットまでを達成することができた。 成果物の内容は OSS として公開されているし、mercari の tech-blog にも投稿しているので説明は省略する。 忙しさが抜けてきたので OSS の開発も進めていくぞ!

github.com

tech.mercari.com

感想

mercari は新卒だからとかインターンだからという垣根は本当に無くて、 当人が見通しを持てているなら、課題を見つけて解決するという点においてとにかくフラットな場だと思う。 だから、社内でも良い意味で競い合えるような環境が多いし、成果を聞いてから「え、この人若い…」という発見が結構あった。

最も印象に残っていたのは、チームの開発に対する姿勢で、 「これを導入しよう」「これを検証しよう」という段階で時間をかけて必要なインプットを行って、インプットに基づいた試作をチームで共有して議論をして、 課題を解決する"良い形"を見つけるまでそれを繰り返してドキュメントや運用方法をまとめて、最後にそれらを外部発表やブログ化といった外部へのアウトプットまで持っていく。 開発では、この一連のフローを通してその技術の Professional になっていくぞ!というをひしひし感じられたので、何かをやっていく姿勢の手本として見習っていきたい…!

インターンシップの目的として掲げられていた「自分の価値を知る、高める」という課題は個人的に十分に達成できたと思う。 価値を知るという観点では、企業の取り組みと自分の技術スタックの関係を客観的に見れるようになったので就活の参考にもなったし、 高めるという点ではインプットとアウトプットを通して、しっかり達成できていると言いたい。


表面的なことしか書いていない参加記になってしまったけど、こうしてインターンシップに参加してみて、 毎月人々が吸い込まれていく理由とその魅力がわかった気がする。

まだ学生でやっておくべきことも大量に見つかったので Be Professional でやっていくぞ!

*1:元々 Microservices に関わる内容に興味があったことと、外部発表の資料を見ていたというバイアスも大きい気がする