水深1024m

技術的なメモとか日記的なもの

MSPJ マイグレーションコンペティション2018winter で優勝してきた

ちょっと時間が経ってしまいましたが、2018/01/27 (土) に開催された MSPJ マイグレーションコンペティション2018winter に参加してきました。

日本MSP協会さんが主催しているイベントで、「古いシステムをいい感じに新しいものにマイグレーションする」コンペティションです。 2年ちょっと前に参加して負けて以来、また出たいなーと思っていたのですが、運良く日程が合い参加することができました。 今回は無事優勝することができました。引き続き開催していただきたいなあと思っておりますので、どういう感じだったかまとめたいと思います。

ルールとチーム

お題は変わらず「いま動いているシステムを新しい環境に移行して欲しい」です。 その他の条件を connpass から引用してみましょう。

- 要望的な何か
    - 今の環境を新しい環境に完全移行して欲しいです。
    - 実施した内容と結果については報告が欲しいです。
    - システムを止めるときは利用者に告知が必要なので連絡が欲しいです。
    - 昔から使っている古い環境なので、バージョンアップして欲しいです。
    - できれば利用者に影響を出さないように切り替えたいです。
    - できればサーバに関する資料があるとありがたいです。
    - できれば今はまったくバックアップを取っていないのでバックアップを取れるようにしたいです
    - できれば今後は利用者が増えるのでシステムを冗長化したいです。
    - できれば新しいインフラエンジニアに引継ぎするために必要な情報がまとまっていると嬉しいです。
- 担当者のコメント
    - 体制変更とかいろいろありまして、システムが分かる人がいなくなってしまいました。
    - 結構前から使っているので、いいタイミングなのでリフレッシュしたいなと思っています。
    - サイト上での商売は続いているので、できるだけ利用者さんに影響が少ないと嬉しいです。
    - そうそう、近々新しいインフラエンジニアが入社予定だから、その方に引き継げるようになっていると嬉しいですね。
    - 本当はいろいろとナウっぽいこともしていい感じにしていきたいんですよ。

これに沿うような問題が出題されます。

チームは当日ランダムなので、同僚と組んで出場!といったことはできないようになっています。 業界経験年数などをもとにチーム分けをしていくのですが、出場条件が30歳以下というところからもわかるようにかなり若く、28歳業界5年目の自分がチームでは最年長という形になりちょっと焦っていました。

Slack に運営との連絡用 channel ができており、そこを主に使うことになります。 短い時間で行うため、課題としていたことなどを忘れやすいため GitHub に private repo を作ってそこに課題を蓄積していくことなどもやっておきました。 基本的に ISUCON などと同様のコミュニケーションスタイルをやっておけばうまくいくと思います。 時間も前回と同じ 10:30 - 17:00 の6時間半。

お題

今回は EC-CUBE を中心とした EC サイトでした。 CentOS6 な Linux マシンの上に DB (MySQL 5.1) が同居しており、 Postfix, Dovecot といったメール環境が乗っていた点が厄介でした。

今回はこの環境がなんと AWS に乗っており、これを Azure に移行するという内容でした。Azure はほぼ使ったこともなかったので、適宜ドキュメントを参照しながらの戦いになりました。

開始して1時間くらいで内容を把握した上で設計を始めました。ここに時間をかけすぎた。。

設計

移行元も移行先もクラウドだし使えるサービスに特に制限はなさそう、かつ要求事項に色々夢のある話が書いてあれば、おれのかんがえたさいきょうのこうせい を作りたくなるものですが、 時間が限られておりあまり盛りすぎると時間が足りなくなることは目に見えていたのでぐっとこらえて最低限の要件を決め、その中で自然にできることを改善の対象として選びました。

  • CentOS6 を CentOS 7 に
    • epel, remi などの外部レポジトリには極力頼らない構成にする
  • ミドルウェア類のバージョンアップ
    • Apache 2.2 -> 2.4
    • MySQL 5.1 -> 5.7
      • MariaDB と悩んだけどソフトウェアのサポート状況を踏まえて MySQL にした
    • PHP 5.3 -> 5.4
      • できれば最新まで上げたかったけどちょっと厳しかった
    • Postfix, Dovecot など
  • 自動バックアップ

このあたりは達成したい事項として含めていました。

移行

メンバー間で担当を割り振り移行を進めました。それぞれ練度が高かったこともありお互い特定の作業を任せあえる状態になっていたのは良かったと思います。 自分は DB の移行などをやっていました。調べていくと root パスワードが運用の中で消失していたため (他のスクリプトに書いてあったらしいが。。) 、最初のメンテナンスは MySQL を skip-grants で再起動して root パスワードを回復するところから始まりました。

切り替えも当初はオンライン切り替えでいけるかな、と思っていましたが、作業時間や構成などを考えるとコストが高く、オンラインに拘って事故るよりはきっちりメンテウインドウを決めてその間で確実に移行しよう、ということで作業を進めました。 幸いにしてデータ量は多くなかったので mysqldump にかかる時間の見積もりをした上でまるごと移行することに。 このへんはざくざくやっていく。

システムの持ち主はあくまでお客さんですのでそれに留意して作業を進める必要があります。例えば以下のようなこと。

  • 予算
    • AWS で1サーバで動いてたシステムが Azure になった瞬間料金倍額になったらびっくりするよね
    • 実際聞いてみると予算状況は割と厳しく、サーバ自体を冗長化したり分割することはこの時点でいったん見送った
  • 使うサービス
    • RDS for MySQL 的なサービスは Azure だとまだ Preview だった
    • Preview でも使えるから選びたくなるけど、お客さんの環境に Preview 版のサービス突っ込むの厳しすぎる
      • 結構使ったチームは多かったらしい
  • お客さんの作業
    • 商品画像アップロードなどもあるサーバであることを考えると、移行漏れが発生するような要素は極力避けるべき
    • なので、変更が発生する業務 (商品作成, 設定やデザインの変更) を時間を決めて止めてもらった
  • 切り替え作業
    • なんのために、どのくらいの時間システムを止めるのか
    • どこにどんな影響があるのか
    • を明確に伝え、その中でやりきる

こんなことを考えつつ作業を進め、最終的に移行可能となったのは終了1時間前くらい。結構ギリギリでした。再起動耐性のチェックもここでやっておきました。 メンテ時間も無事狙い通りにおさまり、こちらでの確認とお客さんへの確認をしつつ問題なかったので旧環境を撤収 (料金がかかり続けるので地味に大事だと思った)。 あくまで環境は "後任に引き継がなければならない" のでドキュメントを早めに書き始めました。文書は Google Docs でそれぞれがーっと書き、最後に1人が体裁を整えるスタイル。

自動バックアップは間に合わないかな…と思っていたものの、Azure Backup が予想以上に素早く環境を作れるようになっていたため、こちらを使いました。

17時に Slack で最終的な資料を提出して終了。 懇親会で寿司などをいただきつつ結果発表があり、なんとか優勝をいただきました。

感想

第一回から運営の方も狙っているところではあると思いますが、「普段の業務でやっていること」を忠実に考えてやっていけば良い結果になるコンペティションなのだと思います。 ぱっと考えれば自明なことなんだけど、限られた時間やメンバー、予算でそれをちゃんとやっていくのは結構難しい。 さいきょうのアーキテクチャを競う会ではないというところは前回の敗戦から学んだ部分で、それを踏まえた方針がちゃんと機能して優勝まで持ってこれたという点はよかったなと思いました。

マネージャになって1年半が経ち、なかなか全力で手を動かし続けるというのも難しかったりするお年頃ということもあり、全力で1つのことに集中し続けられたのもこういう大会の良いところだと思います。良いトレーニングになりました。

環境の準備から参加チームからの問い合わせ対応まで、この大会の運営はたぶんめちゃくちゃ大変なんだろうなあと毎回思っているのですが、今回も非常にスムーズな運営で、余計なことに気を使わず楽しめました。運営いただいた日本 MSP 協会のみなさま、ありがとうございました。そろそろ出場条件的にも厳しくなるので、次回またぜひ出場して勝ち逃げとしたいなあと思う所存です。

いただいた賞金でとりあえず Anova を買いました。何も考えず温玉のせローストビーフ丼が作れておいしいです。

運営、参加者のみなさま、チームメイトの id:renjikari さんと okazaki さん、ありがとうございました。次回以降もぜひよろしくおねがいします。

2017年ふりかえりと2018年

気づけば社会人5年目になっていて、もうすぐ6年目に突入します。 これまで振り返り的なことはあまり書いていなかったのだけど、 なんとなく書くことにしました。

2017年ふりかえり

仕事

1年半前にマネージャーになり、2017年ははじめて自分がマネージャーの状態で1年を過ごすことになりました。 マネージャーとして自分がどうなのか、という自己評価をすることは色々な意味で難しいと思うのですが、部のメンバーが楽しく胸を張れる仕事に取り組めるようにやるべきことを全部やる、という部分については少しだけできるようになってきたのかなと思います。

部署がけっこうなサイズで、SRE やセキュリティだけではなく社内システムやデータ基盤も扱っています。コンテキストを切り替えながら仕事をするのは結構たいへんということもありますが、それ以上に社内システムやデータ基盤のレイヤには、SRE やセキュリティの分野だけで仕事をしていたら出会わなかったであろう話がたくさん転がっていました。オフィス設備や社内ネットワークにはじまり、ERP の話とか、CRM, SFA とか、そのデータ連携とか。もちろんそれぞれの知識が必要になることもそうなのですが、意外といわゆる Web 系では普通となりつつあるようなことを適用できる部分もあったり、難しく、また面白くとても勉強にもなりました。

エンジニアとして特に大きい仕事はサービスの完全 HTTPS 化でしょうか。仕込みは2016年以前から、変更自体は2017年が明けてすぐに完了したのですが、SRE Tech Talks#2Chrome Tech Talk Night#9 , 大規模HTTPS導入Night などに呼んでいただきました。 会社の技術ブログ記事 を書いたところで技術評論社さまからお声がけをいただき、WEB+DB PRESS Vol.100に完全 HTTPS 化に記事を書いた こともとても良い経験でした。 記事を書いて以降、多くのサービスの完全 HTTPS 化に関する記事を見ることになり、また自分が紹介していた手法が使われていたりするのを見るのはかなり嬉しかったです。 2017年初頭から2017年末にかけて、日本の (Chrome を使った) HTTPS トラフィックは約30%から約60%まで増加したようです。Chrome の仕様変更などが一番大きな材料であったとは思いますし、各社数年単位で時間をかけて実行してきたような話ですが、もしこの30%の中のわずかにでも貢献できていたならすごく嬉しいことだなあと思います。実際のところはわかりませんが…

対外発表という点では、去年に引き続き AWS Summit Tokyo 2017 に登壇したことからオファーをいただき、なんと AWS re:Invent 2017で登壇することになりました。re:Invent に参加するのは5回目ですが、人生初の英語 + 海外での発表をまさかこの場ですることになるとは思いませんでした。英語の訓練をかなり高密度でする必要にも迫られて、本番もそうですが準備段階から大変良い経験になりました。

他にも SREcon17 Americas に参加したり、 Hardening 1010 Cash Flowに出場 (スポンサー賞をいただきました) するなど社外に出るようにしたおかげか、自分の中で数年前とまったく考え方が変わったようなこと、あるいは参考事例がなくて不安だったことに自信がつく経験などが多くありました。

総じて、2017年もとても楽しくお仕事できたなあと思います。

趣味

ブログのタイトルにもするくらいスキューバダイビングが趣味だったのですが、今まで沖縄の海に潜ったことがなくて、 Hardening で沖縄出張するついでに初めて潜ってきました。 学生時代からよく潜っていた八丈島ともよく比較されるのですが、ベクトルが違うきれいさだなーと思います。 学生時代から水中では10年前くらいのふるーいコンデジを使っていたのですが、沖縄に潜ってからすぐに GoPro Hero5 を買いました。水中で何度か使いましたが、動画だけでなくちゃんと写真も撮れます。色々やってついに JMB サファイアに到達したこともあり、あまり行ってなかったエリアに潜りに行こうと思います。

f:id:kani_b:20170912113432j:plain

f:id:kani_b:20180104233135p:plain

会社にサバゲー部が誕生し、前から興味があったので行ってみたところ非常に面白くてこれも相当な趣味になりました。1年前は装備も何もなかったのですが、今では Amazonサバゲー用品ばかりおすすめされるようになりました。朝から車で千葉まで行って一日遊び、帰りに温泉に寄って焼肉食べて帰ってくるとパーフェクト休日完成という感じです。

ゲームは PS4 Pro と PSVR を手に入れてエースコンバット7がいつ出ても大丈夫になりました。ニーアオートマタとスパロボV、Farpoint、海賊無双3 あたりが特によかったなと思います。ミニスーファミが出てから深夜にちょっとずつスーパーマリオ RPG をやれたのもよかったし、 Switch も年末ついに買えた。満足な2017年でした。

2018年

去年はマネージャー業をきちんとこなすのに精一杯だった感が否めないのだけど、少し塩梅もわかってきた部分もあり、現状の動き方をよりよくしながら技術的な取り組みを増やしたいと思っています。 自分が考える理想の SRE やセキュリティに携わるエンジニアを体現できるくらいになりたいなあと思いつつ、できないことややりたくても手がついていないこともたくさんあり、まあ修行していくしかないなという気持ちです。

趣味のほうは引き続きという感じですが、30台も見えてきたのでそろそろ体をいい感じにする努力をします。。。サバゲーのためにも体力と筋力のためのトレーニングをどうにかしてちゃんと続けたい。

そんなわけで今年も楽しく過ごせればと思います。どうぞよろしくおねがいします。

AWS NLB についてあれこれ

AWS ELB (ALB, CLB) には日頃からだいぶお世話になっているわけですが、新しい Network Load Balancer (NLB) がリリースされましたね。

新しいNetwork Load Balancer – 秒間数百万リクエストに簡単にスケーリング | Amazon Web Services ブログ

雑に言えば CLB TCP モードの次世代版というとこですかね。 ざっくりドキュメントを読みつつ、いくつか気になる点があったのでまとめます。 ドキュメントに記載されていない内容は私が検証した内容です。何か間違いがあればお気軽にご指摘ください。

パケットはどのように流れるのか

一応図にしておきます。なんというか懐かしい (とか言ったら怒られそうな) 流れですね。 ALB や CLB (HTTP, TCP 両方) ではロードバランサがそれぞれの通信を終端していわゆるプロキシのような役割を果たしているのと比較すると、NLB はパケットの送信元/宛先アドレスを書き換えるのみに見えます。LVS の NAT モードと同様の挙動というところでしょうか。あくまで戻りのパケットは NLB に送出されておりいわゆる DSR ではないように見えます。

f:id:kani_b:20170920130201p:plain

internet-facing と internal の違い

基本的に ALB と変わりありません。

internet-facing

  • 起動する AZ および subnet を選ぶ
    • subnet には IGW が attach されている必要がある (いわゆる public)
  • DNS name が割り振られる
    • 返すのは各 AZ ごとに起動時に払い出された public IP もしくは起動時に追加した EIP
  • バックエンドインスタンスは private subnet に所属していても問題ないが、VPC Route Table においてデフォルトルート (0.0.0.0/0) が設定されている必要がある

internal

  • 起動する AZ および subnet を選ぶ
    • subnet に IGW, NAT Gateway などが attach されている必要はない
  • DNS name が割り振られる
    • 返すのは各 AZ ごとにランダム (DHCP?) に割り振られたプライベート IP アドレス

NLB が返す IP アドレスについて

NLB は1つの AZ につき1つのIPアドレスを持ち、それぞれの IP アドレスへのトラフィックは必ずその AZ にルーティングされます。 例えば AZ-A に 10.0.0.0/24, AZ-B に 10.0.1.0/24 の subnet を作成して設定し、A,B それぞれの AZ にまたがる NLB を作成したとすると、DNS が返す IP アドレスは以下それぞれ2つになります。

  • internet-facing
    • xxx.xxx.xxx.xxx (AZ-A 用 public IP / EIP)
    • yyy.yyy.yyy.yyy (AZ-B 用 public IP / EIP)
    • バックエンドへのヘルスチェックにはプライベート IP アドレスが適当に切り出されて使われる
  • internal
    • 10.0.0.x (AZ-A の subnet から切り出した IP)
    • 10.0.1.y (AZ-B の subnet から切り出した IP)
    • ヘルスチェック元 IP アドレスは同じ

クライアントはどちらかを選択して通信を行うことになりますが、その際選択した IP アドレスが所属している subnet と必ず通信を行うことになるわけです。例えば xxx.xxx.xxx.xxx にパケットを送出した際、それが AZ-B のバックエンドインスタンスにルーティングされることはありません。 これが NLB のリリース紹介記事にも書いてある Zonality ってことですね。

Zonality って結局どういうことなのか

先述の通り NLB から見える IP アドレスは必ず1 AZ に紐付きます。 2AZ に NLB をアタッチした状態で DNS を引いてみると必ず2つの IP アドレスが返ってきます。よって、例えば以下のように Web - App - DB のような構成にした際の接続にすべて NLB を使っている構成であれば、先頭の NLB が Zonal であっても後半の NLB で他の AZ にバランスされてしまうように見えます。

f:id:kani_b:20170920130236p:plain

これはあくまでクライアントの実装による話です。 例えば glibc の getaddrinfo(3) は RFC 3484 Rule 9 によって定義されているように、複数の IP アドレスが返された際は longest match によって IP アドレスをソートして返します。上記の図のように、それぞれのインスタンスが同じ Subnet に存在する (= NLB が同じ Subnet にある) 場合、 getaddrinfo(3) を使っているクライアントでは、同じ Subnet, 同じ AZ の NLB エンドポイントが使われるようになります。 *1

Redis や memcached をはじめとした低遅延なデータストアを利用する際には AZ またぎのレイテンシが地味に効いてくるケースがあるため、NLB と Subnet が1対1になっていることは役に立ちそうです。 NLB を利用することで、普段は同じ AZ のインスタンスに接続しつつ、AZ が全滅した際には別の AZ に接続することができます。 ただし、この挙動はあくまでクライアントに依存するものであるため、上記のような挙動をしない場合にはクライアント側での対応が必要ですし、Subnet をまたぐようなケースでもクライアント側での対応が必要です。 また、AZ 間のバランスは接続元/接続先インスタンス共に適切に保たなければ、均衡が崩れて負荷が偏ってしまうことには注意が必要ですね。

障害時に使われる IP アドレス

IP アドレスと AZ が紐付いているので、例えば AZ-B のバックエンドインスタンスが全滅したしまった際に yyy.yyy.yyy.yyy あるいは 10.0.1.y をクライアントが選択すると、どのバックエンドインスタンスにもルーティングされないことになってしまいます。 ざっと実験した感じ、NLB では以下のような挙動をするようでした。(internet-facing, internal 共通)

  • 全ての AZ に healthy なバックエンドインスタンスが存在する場合、全 AZ の IP アドレスを返す
  • healthy なバックエンドインスタンスがいない AZ が1つ以上存在する場合、その AZ を抜いた IP アドレス (上記の例だと xxx.xxx.xxx.xxx) のみを返す
  • 全ての AZ でバックエンドインスタンスが全滅した場合、全 AZ の IP アドレスを返す

よって、片方の AZ が全滅するような障害においても、DNS name をベースとして (IP アドレスを直接べた書きなどせず) クライアントが接続しようとする場合、全滅した AZ に接続しようとしてタイムアウト…といったことにはならないようです。Route53 の Alias Record にも対応しており、こちらを設定した場合でも同様の挙動をします。 NLB 自体の IP アドレスは固定ですが、複数 AZ を利用する際に複数ある IP アドレスをそのままドメインの A レコードとして設定してしまうと、AZ が全滅した際でもクライアントが接続できない AZ の IP アドレスを使ってしまうリスクが残ることになります。 そのような設定をする場合は Route53 の Healthcheck および Failover 機能 (もしくは他社 DNS における同様の機能) を一緒に使うことになるでしょう。 Active/Active な状態にしておくことで、 NLB の DNS レコードと同じような挙動を実現できそうです。

セキュリティグループについて

NLB そのものにはセキュリティグループを設定できません。バックエンドインスタンスにおいてセキュリティグループを設定する必要があります。 バックエンドインスタンスには送信元 IP アドレスがクライアントのままになっているパケットが届きますので、これをベースにして設定をする必要があります。 インターネットに公開する場合、ターゲットとなるポートは 0.0.0.0/0 からのアクセスを許可、ヘルスチェック用ポートは NLB が起動している subnet の CIDR からのアクセスを許可すれば良いでしょう。

internet-facing な NLB を使う場合、クライアントからバックエンドインスタンスへの直接アクセスを許可する必要がある?

という書き込みをちらほら見かけましたが、答えはNOです。 バックエンドインスタンスがクライアント (インターネット) からの直接アクセスを受けるためには以下の3条件が揃っている必要があります。

  • バックエンドインスタンスが所属する subnet に IGW が attach されている
  • バックエンドインスタンスに public IP もしくは EIP が割り振られている
  • バックエンドインスタンスが所属するセキュリティグループに適切な許可設定 (e.g. 80/tcp に 0.0.0.0/0 からのアクセスを許可) がされている

NLB のバックエンドインスタンスとなるためには、このうち最後の条件のみを満たしていれば良いです。 (上述の通り、 VPC Route Table においてデフォルトルート (0.0.0.0/0) が設定されている必要はあります)
よって、例えば以下のように NLB は public subnet に起動し、private subnet のインスタンストラフィックを流す (インターネットからのトラフィックは NLB のみで受ける) といった構成も問題なく行えることになります。

f:id:kani_b:20170920130251p:plain

ただし、internal においてもセキュリティグループが利用できないという制約は変わりません。つまり、バックエンドインスタンスのセキュリティグループにクライアントインスタンスのセキュリティグループを許可設定してもアクセスができません。 細かい制御を求められるところではちょっと不便ですね。

まとめ

NLB の挙動や存在する制約などについてまとめました。 アクセス制御の点で少し面倒な部分はあるものの、ALB や CLB と比較してもより普通に (X-F-F や Proxy Protocol などを考慮せず) 使え、かつ IP 固定なのは便利だなと思います。あと起動がめっちゃ早いです。 Zonality もクライアント依存な部分はありますが個人的には便利 (欲を言えばクロス AZ と選びたい) だなと思いました。 ALB で受けられない, もしくは不便なユースケースは NLB を積極的に使うと便利そう。

Simple Icons の更新もお待ちしてます!!!

*1:気になる方は glibc の getaddrinfo.c あたりを読んでみると雰囲気がわかると思います

WEB+DB PRESS Vol.100 特集「対応必須!完全HTTPS化」を執筆しました

2017年8月24日発売の WEB+DB PRESS Vol.100 に「対応必須!完全HTTPS化 - 移行手順からつまずくポイントまで」という特集記事を執筆しました。 この特集は、2017年4月に会社の技術ブログに執筆した Web サービスの完全 HTTPS 化 - クックパッド開発者ブログ という記事をベースに、中身をほぼ新規に執筆したものです。

2017年1月にクックパッドという Web サービスを完全 HTTPS 化したので、その経験を4月にブログ記事という形で公開したのですが、これをご覧になった編集部の方からご連絡をいただき今回の話に繋がりました。

WEB+DB PRESS は8年くらい前、本格的に Web 技術者を目指そうかなと思い始めた学生の頃から時折読んでおり、私にとってもかなり身近な雑誌です。しかし執筆はというとVol.92 でちょこーーっとだけ Fluentd によるログ収集話執筆のお手伝いをしたくらいで、ほぼ初執筆に近いです。

特集について

章構成はこんな感じです。全25ページ。

  • 第1章: なぜ完全 HTTPS 化が必要なのか
    • Web サービスを安心して利用してもらうために
  • 第2章: 完全 HTTPS 化はじめの一歩
    • 証明書の選び方、構成の検討、テスト環境の構築
  • 第3章: HTTP リソースの HTTPS
    • mixed content を効率的に修正するには
  • 第4章: リリース時に注意すべきこと
    • 確認すべき事項と、ミスを防ぐリリースの順序
  • 第5章: クックパッド完全 HTTPS 化の影響
    • 収益、ユーザー、パフォーマンスはどう変わったか

クックパッドにおける完全 HTTPS 化をの経験をベースに、Web サービスを完全 HTTPS 化する方法について、その前提知識などから解説しました。 主に AWS を使った環境の話をメインに書いていますが、今回pixivさんに許可をいただき、コラムという形でオンプレミス環境における完全 HTTPS 化についても執筆させていただきました。 コラムなど含め記事全体を私一人で執筆しています。

HTTPS に対して思うこと

「今の時代、新しいサービスは HTTPS であることが多いし、これから解説する必要もないのでは?」と思う方もいらっしゃる方もいるかもしれません。僕も執筆のお話をいただいた時に正直少し思いました。 が、やはりインターネット全体を見渡してみると、まだ十分とは言えない状態にあると思います。 Google が公開しているレポート でも、日本は最下位 (もちろん取り上げられている範囲でですが) です。

記事でも書いていますが、HTTPS への移行はもはや Web サービスにとって避けられないでしょう。利用者の安心や安全を守るということに加えて、これから使われるであろう新しくて面白い技術の多くは HTTPS をその前提としています。 HTTPS への移行メリットがセキュリティだけであった時代はとうに終わりました。みんながもっと楽しくて、安全な次の Web に行くためにも、HTTPS への移行は必要です。

また同時に、それはトラフィックの大小で決まるものではないと思います。「うちのサービスはトラフィックも少ないし、別に良いかな」と感じる方もいらっしゃるとは思いますが、そのサービスのユーザーも"インターネットユーザー"の一人です。 利用者が安全であることを確認しながら使うリテラシーも必要なのかもしれませんが、最低限"利用するどのサービスも HTTPS になっている"状態を作ることで、インターネットを使うために知らなければならないことをわずかでも減らせるんじゃないかなと思います。

執筆について

執筆は、編集の方と GitHub の上で行いました。既に markdown を使った快適な執筆環境ができており、執筆の上で不自由は全くありませんでした。これは本当にすごいなと思います。
進捗が悪い時期も適切にフォローいただき、その後の校正や本当に最後の最後まで修正を一緒に進めていただいた編集部の池田さんには本当に感謝しております。

また、執筆にあたり職場のみなさんや Jxck さん, catatsuy さん にもレビューをいただきました。貴重なレビューをいただき (また catatsuy さんにはブログ記事2本 前編 後編 のコラム化についても快諾いただき) 本当に助かりました。

おわりに

HTTPS というプロトコルの説明や証明書についての解説に加え、 CSP や HTTP/2, TLS1.3 など次世代の技術にも触れています。あまり下手なこと書くと槍が飛んできそうだな 😇 などと思いつつ、気をつけて書いてはいるつもりですが、なにぶん奥深い世界ですので、お気づきの点があれば温かい目でご指摘いただければなと思います。

完全 HTTPS 化について、何がボトルネックになっているかは各サービスによって当然違います。そもそも必要性が認識されていないかもしれないし、担当者は完全 HTTPS 化したいと思っていてもリソースの問題で動けないかもしれない。あるいは技術的な問題や心配で先に進めていないかもしれない。 1 しかし、かつて考慮すべきだったことの多くは現代では心配する必要がなくなっています。もちろんケースによりますが、多くの場合そんなに難しくはない、のだと思います。

本特集は、実際の構成や設定にとどまらず、同僚や上司への説明などにも利用できるよう、できる限り使いやすく書いてみたつもりです。 特集をご覧いただいて完全 HTTPS 化に進めた、なんていう声をもし聞けたなら嬉しい限りです。

記念号となる Vol.100 には、私の特集のほかにもとても面白い特集やエッセイがたくさん掲載されています。本日献本いただいた書籍を読みましたが、とてもおすすめです。 完全 HTTPS 化に興味があってもなくても、ぜひお買い求めください!


  1. このブログが HTTPS ではないのでは、というお声もあるでしょう。しかしはてなブログHTTPS 化も進んでいると伺っており、またユーザーが記事などを自由に書けるようなサービスにおける完全 HTTPS 化は難易度がかなり高いと思っていますので、気長に待つことにしています :)

MacBook (12-inch) で給電しながら 4K 60Hz 出力したい

タイトル通りの話。 仕事では持ち歩き用に MacBook (12-inch) を使っています。軽くて薄いので持ち運びには最高。

最近自宅に PS4 Pro を買ったので、思い切ってモニタを4Kに統一しました。フィリップスの31.5インチのやつ です。 で、この 4K モニタに MacBook を繋ごうとするわけです。Apple のサポートページを見てみましょう。
Mac で 4K ディスプレイ、5K ディスプレイ、Ultra HD TV を使う - Apple サポート

一見問題なく対応していそうなのですが、重要なのはリフレッシュレート。 HDMI 接続の場合ほぼ 30Hz にしか対応していない。個人的には 30Hz でモニタ使うのは無理。目が痛くなります。 というわけで、快適に 4K モニタを使うためには 60Hz で使う必要があります。 4K モニタを 60Hz で使うためには、以下の方法で出力する必要があります。

  • Displayport 1.2 (以下 DP)
  • HDMI 2.0

PC 向けでこれ以外の規格で使えるものは無いと思います。 しかし、世の中の 4K 対応製品は実際には HDMI1.4b までしか対応していないものがほとんどのため、期待して使うと 30Hz までしか出力されないことになります。 やっかいなのは、Mac 内蔵ポートはもちろんのこと、Apple から出てるいかなるアダプタでさえもまだ HDMI1.4b しか出力できないということです。

mini DP から DP への変換アダプタはサードパーティから数多くリリースされていますので、mini DP があった頃の MacBook をお使いのみなさんは 迷わずこれを使えば良いです。 問題はこのポートが全て USB-C という (現状) 地獄のポートに置き換えられてしまった新 MacBook たちです。 Apple は現状 USB-C から HDMI 出力できるアダプタをリリースしてはいますが、残念ながら前述のようにこの HDMI は HDMI1.4b なのです。よって 30Hz 止まりです。 Apple 純正, あるいは公式アナウンスしているアクセサリのみで 4K 60Hz を使いたいなら LG UltraFine 系の USB-C 対応モニタを買うしかないのです。マジか〜

さて、USB-C から DP あるいは HDMI2.0 を出力する方法について。 DP で出力するなら、USB-C から DP への変換ケーブルがありますので、これを使うと一発です。 HDMI2.0 はいくつかアダプタが出ています (必ず HDMI2.0 と明記されたアダプタを買いましょう) が、アダプタに加えて HDMI ケーブルも Premium HDMI ケーブルという 認証を通ったケーブルでないといけません。これが結構高くて、1mでも4000円くらいします。 USB-C to DP ケーブルを買うのが一番だと思います。

これでめでたしかと思いきや、 MacBook (12-inch) は最高に薄くてクールなので USB-C ポートが1つしかありません。 給電もこのポートから行うわけですので、前述のケーブルやアダプタを使うと給電できなくなってしまいます。

これを知ってから必死に探して、ついに使えるものを見つけました。それがこちら。

HyperDrive USB Type-C Hub with Mini DisplayPort (for 2016 MacBook Pro & 12" MacBook)www.hypershop.com

HyperJuice (バッテリ) とかも出してる Sanho のプロダクト。 USB-C 一つから給電可能な USB-C, miniDP, microSD, USB2.0 な USB-A を2つ出すことができます。 利用中の画像は以下です (画面きたないのは許して) 。

書いている通り、コネクタが少し浮いてたりそもそも USB-C コネクタ一つで支えるという構造がかなり不安ではありますが デスク上で固定して使う分には全く問題ないです。 使い始めてから1ヶ月くらい経ちますがまったく問題なし。 価格は送料込みで$60~70くらいだったと思います。(売り切れ中のため確認できず)

これで今のところ快適に 4K モニタを利用できています。執筆現在で売り切れ中ですが、興味のある方は登録して入荷を待ちましょう。 ただ、MacBook 自体のスペックが低い & 2015年モデルのためか、4K 出力しているとそもそも CPU を 20~30% 持っていかれてしまっているのが 結構つらいです。WWDC 2017 で新しいモデルが出たりして良い感じになるといいな。

git-secrets の Homebrew Formula 作った

最近流行りの AWS の認証情報とかを github で大公開する事故を防ぐためか AWS が作った git-secrets という git plugin があります。 インストール手順はレポジトリを clone して make install するような感じだったので、初めて Homebrew の Formula 書いて Homebrew に取り込んでもらいました。 (git-secrets 自体シンプルな git plugin なので全く大した内容ではない)
git-secrets 1.0.0 (new formula) by kanny · Pull Request #47322 · Homebrew/homebrew
というわけで Mac && Homebrew 使ってる人は

$ brew update
$ brew install git-secrets

すればインストールできます。

使い方は別の方が Qiita にまとめてくださっていますね。 クラウド破産しないように git-secrets を使う - Qiita

自分が何か作るときは認証情報はだいたい1ファイルに認証情報だけまとめて gitignore に書くようにしてるのですが、git-secrets 使うとそれでも事故るようなケースを防げてとても良いですね。 初心者向けハンズオンとかでも、

  • git init
  • git secrets —install
  • 認証情報をまとめたファイルを作る
  • .gitignore を作る

くらいまで、そんなに時間かからないと思うし紹介できると良いのかなー。

Pull Req 取り込んでもらう間に眺めてて気づいたんですが、Homebrew には毎日すさまじい量の Pull Req が来ています。 Formula 書くのも楽なので、取り込んでもらえるとみんな幸せになれそうなものは書いてみると良いかも。もちろん雑に書くのではなくちゃんとドキュメント読んで brew audit 通して、ですよ。

これを数人のメンテナで (日々寄せられる Pull Req のレビューとかも全て) 回していて、すごいなあ。

MSPJ マイグレーションコンペティション2015fall に参加してきた

MSPJマイグレーションコンペティション2015fall というイベントに出場してきました。 かなり古いシステムがオンプレっぽい環境にあるのでクラウドにいい感じに移す、というコンペティションです。 参加して敗北したのですが、初回ですし次回もぜひ開催いただければと思っているので、どういう感じだったかまとめたいと思います。

ルールやチームについて

やることは上述しましたが “古いシステムをいい感じにマイグレーションする” です。 イベントページから引用しておきます。

- お題: いま動いているふるーいシステムをバージョンアップしてね
 - できれば利用者に影響なしでやりたい
 - できれば冗長化したい
 - できればさくさく動くようになると嬉しい
 - できればプロビジョニングコードが欲しい
 - できればサーバに関する資料があると嬉しい
- 実施した内容と結果については報告してくださいね
- 背景という名の発注者の弁
 - もうすぐサポート切れるって言うし、セキュリティが心配だし、でもそんなにきちんと管理する手間もとれないし、わかるひともいないし、今のうちになんとかしておきたいんだよねー
 - あんまり何回もいじりたくないから、できるだけ長く使えるようにしてほしいなぁ

当日配布されたお題もほぼこれと同様の内容でした。 チームは当日編成されるので、あらかじめチーム組んでおいで出るみたいなことはできません。

参加者は30歳以下という縛りがあったこともあり、20代のエンジニアが幅広くという感じでした。僕のチームも社会人3年目、3年目、2年目というチームでワイワイしてました。
Slack に運営との連絡用 private chat ができ、僕らは GitHub の private repo に issue などを立ててメモを書いたりするという感じで進めました。 制限時間は10:30 過ぎから 17:00 までの6時間ちょっと。

初期環境

初期環境とさくらのクラウドのアカウント (後述) が渡されて競技開始です。お題はみんな大好き wordpress でした。
使われていたのは CentOS 5.x で、 PHP 5.1 と MySQL 5.0 の環境。PHP が古すぎるので wordpress アップデートもできないし、MySQL も特に設定はされておらず MyISAM のテーブルがあるだけという状況。
また、チームごとに teamN.example.com という単位で DNS のゾーンが分割されていて (ドメインは例です)、その NS を担う bind が立っていました。 始まって30分くらいで大体の状況は把握して新環境の設計をざっくり作り始めました。

設計

使えるサーバ台数などに特に制限もないクラウド環境だったこともあり、いわゆる普通の3層構造を当初作ろうかと話していました。
が、依頼者の背景に “趣味と実益を兼ねて作っているブログ” という話があり、お題にあるようにあまり弄りたくない、きちんと管理する手間も取れない、ということでサーバ台数とコストを抑える (ただし “できれば” の部分はできるだけ満たす) という方針で最終的には作っていました。

移行

初期環境と同時に、さくらのクラウドのアカウントを渡され (好きに使って良いとのことだった) これを使って新環境を作っていきます。 さくらのクラウドをまともに使うのははじめてだったので、とりあえずドキュメントを読みながら石狩リージョンにルータ+スイッチを作り、新環境の App サーバと DB サーバ (設計方針変更により最終的には1台に統合された) を作ります。 サポート期間が長いものを、というところと、チーム的に手に馴染んでいそうということでディストリビューションとしては CentOS7 を選びましたが、個人的には systemd や firewalld がっつり触っているわけではなかったこともあり少しもたつきました。

ディストリビューションが CentOS7 になったので、ApacheMySQL をパッケージからインストールしていけば現代で使われているバージョンになります。 CentOS7 からは MariaDB が標準採用されたという話は知っていたけどチームメイトがインストールしてくれたのは MySQL で、おや?と思ったのですが、さくらのクラウドの public image では rpmforge とか remi とか MySQL community repo とかが最初からインストールされているのですね。へーと思いました。

馴染みの道具は大体揃ったので、旧環境から新環境へのレプリを設定して (wordpress のデータベースだけ)、新環境の App を作っていきます。レプリはチームメイトがいい感じに設定してくれたので、移行先のスレーブを先にガッと InnoDB に ALTER しつつ buffer pool など基本的な設定を入れました。wordpress 本体はそのままコピーして終了。
旧環境でも新環境でも25秒くらいかかるクエリがあってこれはなんだろと思ったら、wordpress のテンプレートタグで SQL_CALC_FOUND_ROWS が使われてるみたいな話があるのですね。移行が第一目標だったので勝手にテンプレート編集するわけにもいかんよな、と思いつつクエリキャッシュが効きそうなケースだったので有効にしたら収まりました。

Web サーバはまあ無難だよねというところで Apache + mod_php になりました。APC も入れたけど先述のクエリのほうが負荷としてはとても高かったので効果は目立たなかったと思います。

新環境の準備が大体できたので、動作確認をしてとりあえず旧環境から新環境に移行していきます。さくらのクラウドでは GSLB が使えるので、そこに切り替えることにしました。

実際に気づいたのは移行よりかなり前ですが、クラウド環境への移行だし DNS サーバは立てずにさくらのクラウドに用意されてる DNS サービスに移せば自前より良いよね、という話を当初していて、いざゾーンを作ろうとしたらゾーンが登録できない旨のエラーが返ってくるというところで少しハマりました。

ドキュメント を読むと、”上位ドメインが当サービスで提供するDNSサーバにNSが向いて” いる、あるいは “上位ドメイン、および下位ドメインが当サービスで既に登録されて” いるものは使えないという記載がありました。

ハッと思い運営の方に質問したところ、予想通り移譲されているドメインの上位ドメインがそもそもさくらのクラウド DNS で既に運用されているとの回答を得た + “具体的に作業内容を伝えれば” その通りに作業をしてくださるとのことだったので、自分のチームに移譲されているドメインの NS 設定を消して自チームのサービス用ドメインへの CNAME を直接設定してもらいました。(この方法をとったのは我々だけだったらしい)

移行は無事一発で済んだので、旧環境からのレプリ設定などを消したり後始末。これで旧環境には用がなくなりました。ここまでで残り1時間30分くらいだった気がする。

冗長化

チームメイトが既に東京リージョンにもサーバを作っていてくれていたので、ネットワーク設定などをざっと入れつつアプリをコピーし、データベースは石狩リージョンに向けました。スレーブは東京リージョンのサーバにもありましたが、このフェイルオーバーまでは作りきれずドキュメントだけ書いておこうという方針になりました。
さくらのクラウドのスイッチはリージョン間接続ができるので、東京リージョンと石狩リージョンの間で L2 ネットワークを結べて便利でした。 GSLB に東京リージョンのサーバ IP を書いたので、これで「石狩が落ちると手動で切り替える必要があるけど東京が落ちても耐えられる」構成となりました。 かなり不完全ですが。。。

プロビジョニングスクリプト

当初は普段使っているItamae などでできる限りスクリプトを作るか、という話をしていたのですが、時間が足りずここは諦めることにしました。 ISUCON などで「プロビジョニングスクリプトから作っていると大抵時間がなくなって崩壊する」というのはわかっていたので、最初から手を付けず、あとから諦める判断だけしたのは良かったと思います。

終了、そして敗北

そうこうしているうちに時間は16:30と終了寸前。チームメイトがかなりきっちりしたサーバ資料を書いていてくれていたのでそちらは完全に任せきりで、こちらはざっくりと技術的な改善点や移行時の手順をメモとして残しつつ、忘れられていた運営チェック用アカウントの作成と疎通確認、再起動耐性の簡単なチェック (実際再起動している時間はなかったのですが) などをしていました。再起動耐性については特にどこにも書いてなかった項目ではありますが ISUCON のトラウマみたいなもので…

17時までに Slack 経由で資料を提出して終了となりました。 懇親会はピザや寿司やお酒などをいただきつつ、チームの構成などについて話して盛り上がっていました。

懇親会も半ばとなったところで結果発表。残念ながら我々のチームは入賞を逃しました。

講評

講評では、”MUST 要件をちゃんと考えて適切な作業やコミュニケーションをしよう” というもっともな話がまずあり、そもそも移行に失敗した (旧環境から NS を移すのを忘れていた?) チームがかなり多かったこと、移行成功したのは数チームであったものの、我々のチームは1つだけ書き込みのテストをしたテストデータが残っていたことが入賞を逃した理由として説明されました。 移行プロジェクトということで、確かに移行したアプリに勝手にテストデータ書き込まれてそれが残ってたら怒られるのはもっともだなーという感想を得ました。アプリを書き換えないという選択はしたのにテストデータはスルーしたというのも甘かったですね。。。

ただ、他チームの話を聞いている限り、ゼロダウンタイムでの移行 + 不完全とはいえ冗長化 + パフォーマンスチューニング + ドキュメントの作成、を達成したのは我々のチームだけのようでしたので、正直かなり悔しかったです。

これがなかったらおそらく優勝していたであろう内容だったので、トップスコア fail した ISUCON5 と同様、最近詰めが甘いことが多すぎるということへの反省と力不足を痛感しました。

最後に

ISUCON 同様、時間が限られた中、チームで何らかの作業をすることは、技術スキルや優先度の判断など個人の能力に加えてチームワーク(というかコミュニケーション)もかなり重要になるので、個人的にはかなり良いトレーニングになるなと感じています。チームがランダムということで若干の緊張感はありましたが、チームメイトもとても良い方々で、バランスの悪いことなどに対してお互い指摘が入れられるような形で作業が進められたのはとても良かったです。

また、さくらのクラウドをほぼ初めて使わせていただいたのですが、普段 AWS や GCE などを触っているとあまり考えることのないレイヤを触っていく必要があり、「ネットワークを作っている」感が強いなーと感じました。このあたりは、求める抽象化の度合いやコスト感 (金銭的なものだけではなく) によって他社クラウドと住み分けがされていくのだと思います。 個人的には、NIC の付け外しがオンラインでできたり、マネージドな DHCP サーバがあったりすると嬉しかったです。

長々と書いてしまいましたが、自分と同じくらいの世代のエンジニアと交流でき、かつ個人的にかなり反省するところもあり、色々と学びがありました。 運営いただいた日本MSP協会のみなさま、ありがとうございました。次回開催も楽しみにしております。