はじめに
はじめまして。ニコニコ生放送でマイクロサービスチームのグループリーダーを務めています、 ビビる(@vivil@friends.nico) です。以前歌舞伎座.techでニコニコ生放送フロント レガシーシステムの改善の発表をさせていただきました。
ニコニコ生放送(以下「生放送」)ではバックエンド・フロントエンドのサーバーを建てる環境として、2016年からDocker Swarmを採用し始めています。ここではその際に得た知見等を書いていきます。 ご意見・ご質問等あればコメント・トゥート等でお声をおかけ下さい。
何故docker化を始めたの?
マイクロサービス化の機運
生放送は肥大化したモノリシックなサービスが2つ並列運用されており、それぞれロジックを保有する見通しの悪い状態になっていました。 そこで、各種のロジックをマイクロサービスとして切り出すことで、サービス全体の見通しを良くする為にマイクロサービス化を進めることになりました。
ポータビリティ
生放送は機材の関係で色々な環境で動くのが要求されるため、フロントエンド/バックエンドともにポータビリティ性の高いコンテナ化が求められ、技術的にはDockerが妥当であろうという結論に達しました。
フロントエンドの分離
フロントエンドサービスをScalaから脱却する / バックエンドサービスはScalaを引き続き使う
従来、フロントエンドエンジニアはサーバーサイドも触る必要があったため、Scala/TypeScript/SCSS/Rakeを理解している必要がありました。(一部PHPが必要なこともありました) フロントエンドエンジニアが複数言語を覚える負荷を下げるため・Scalaのコンパイル時間を減らす為に、サーバーサイドをTypeScriptで書きたい要望が出ました。
一方、バックエンドサービスに関しては利便性等を考慮して、引き続きScalaを利用していく方針の為、それぞれ独立した環境で実行できるDockerを利用することになりました。
スケーラビリティの向上
超会議や人気アニメ一挙放送など、多数の来場者が予想される際にはインスタンスを増やして、たくさんの方に視聴していただけるようにし、人が少ない時間帯はスケールダウンさせて、別用途に利用する等、柔軟に対応出来るようにしたい意図がありました。
なんでSwarmなの?
2016年当時、Dockerのクラスタリング技術としてはKubernetes or Swarmの二択であり、
- Docker公式のSwarmのほうが後々廃れにくいだろう
- 知見が社内にほぼない状態だったので、挑戦していきたい
と考えたため、Swarmを選定しました
サービス構成
マシン数
現状70台以上のサーバーでクラスタを組んで運用されています。
構成
Blue-Green Deploy
フロントエンドサービスについて、 Blue-Greenの2系統準備しています。 Coldインスタンスにデプロイして動作確認後、Hotとスワップすることで無停止で新バージョンの動作確認/デプロイを行うことが出来ます。
また、問題が発覚した際、従来のScalaベースのシステムでは数十分デプロイに時間がかかっていたのが、Blue-Greenデプロイを実装した現在では3分程度でロールバックできるようになりました。
監視
コンテナについてはcAdvisor -> Prometheus -> Alertmanager -> Slack の流れでアラートを飛ばすようにしています。
Web上でも、Grafanaを使ってPrometheusの情報をリアルタイム監視できるように整えています。
ホスト単位での監視はインフラチームが構築したZabbixで行っています。
Swarmについての知見
以下に、半年以上Swarmを本番運用して得られた知見を紹介します。
未解決
Dockerのバージョンアップで不具合が出ることがある
無停止で更新すると、Ingressネットワークが不通になったり、jobが不安定になったりと不具合が出ることがあったため、Dockerのバージョンアップは一度サービスを止めてメンテナンスを行っています。
vip/ingress network周りが不安定になることがある
現在進行系で不安定になることがあります。ネットワークが極稀に数秒詰まったりします。安定稼働に向けて引き続き改善を進めています。
解決済み
アクセス元IPの取得ができない
Swarmの仕様上、アクセス元IPがSwarmのvipになっていた問題がありました。ネットワーク設定をhostmodeにすることで、解決しました。
カーネルパラメータ
Docker機材にはカーネルパラメータのチューニングが必要でした。(未だに試行錯誤はしています)
具体的に一部事例を紹介させていただくと、コンテナを多数建てるとホストマシンのARPキャッシュが溢れる事があったため、GCの閾値を上げています。
"net.ipv4.neigh.default.gc_thresh1": 4096 "net.ipv4.neigh.default.gc_thresh2": 8192 "net.ipv4.neigh.default.gc_thresh3": 8192
個人的な感想
以下は個人的な感想です。
Docker / Swarm 使ってみてどうだった?
色々アプリケーションを追加する必要なく、Dockerさえ入れられれば立ち上げられるので、とても便利でした。
アプリケーション開発者も、サーバー側の心配をせずにアプリケーション実装に集中できるので楽になったと思います。(特に、この変更によってフロントエンドエンジニアはTypeScript/SCSSに集中できるようになり、効率が上がったと言われています)
今まで1つのモノリシックサービスのデプロイを週に3回やる、と言うかたちから、毎日特定のサービスのみ複数回更新できる、というかたちになったので、更新頻度をあげられるようになったのは良かったと思っています。
今後はどうする?
マイクロサービスをどんどん増やす方針なので、より使いやすいプラットフォームになるよう、改善を進めていきたいと考えています。
10月16日から開催されているDockercon EU 17で、Kubernetesの公式サポートが発表されました。
今後、KubernetesとSwarmがどうなっていくのか、ますます目が離せないとても刺激的な状況です。