さくらのクラウド「エンハンスドLB」を作った話(前編)

この記事は [さくらインターネット Advent Calendar 2019](https://qiita.com/advent-calendar/2019/sakura) 4日目の記事です。

さくらインターネット研究所に所属している大久保です。お久しぶりです。

~~自分、研究は全くやってなくて、~~ ひたすら弊社のIaaSである「さくらのクラウド」の運用、開発、コーディング、お客様サポート、構築、ラックマウント、配線、障害対応、その他あらゆる全てをやっています。よろしくおねがいします 😇

せっかくAdvent Calendar空いてたので、最近作ってるサービスの紹介をさせていただこうと思います。

# HTTPSの終端って大変だし面倒じゃないですか。

今回のネタは、お客様からご要望いただいて1年前から開発スタートしたサービスなんですね。当時、L4のロードバランサは提供していましたが、要件として、

- インターネット向け大規模コンテンツ配信に使える高性能なもので、
- DDoS対策ができて、
- SSLの終端もできて。。。

というようなロードバランシング機能が欲しいとのことでした。他社さんのクラウドでは、当然ラインナップされているような機能ですよね 😇

で、作ったのが今回ご紹介するさくらのクラウド「エンハンスドロードバランサ」機能です。

# さくらのクラウド「エンハンスドロードバランサ」とはなにか？

2018/10くらいから開発を始めて2019/2/28よりベータ提供を行ない、はれて **2019/4/1より正式版として提供開始** しました。上で触れたようにインターネット向けコンテンツ配信に特化したL7ロードバランサです。

![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108990/54d6d690-9c4e-9253-d507-d170f32af9a6.png)

弊社のグローバルネットワークに配置され、VPSやクラウド、専用サーバやハウジングなど任意の弊社のIPアドレスを実サーバとして指定可能です。2019/12/4現在、以下のような機能に対応しています。

* 設置リージョンの選択（石狩/東京）
* 最大40サーバーのバランシング
* DDoS攻撃対策
* HTTPS(SSL)終端
* 無料SSL証明書（Let's Encrypt）登録、自動更新機能
* セッション維持機能
* 無停止プラン変更
* ソーリーサーバー設定
* カスタムレスポンスヘッダー設定
* TLS1.2、TLS1.3、HTTP/2、WebSocket対応
* TLSセッション再開対応(セッションチケット方式)
* HTTP to HTTPSリダイレクト機能

まー、他社さんのクラウドでもありがちな機能で、特にコレといったものはないんですが 😇

DDoS攻撃へのミティゲーションや、Let's Encryptで無料SSL証明書を自動で発行・更新できたりと、かゆい所に手が届く機能を若干盛り込んでいます。

また、TLS1.3やHTTP/2といった新プロトコルにもちゃんと対応していますし、BCP対策でご利用いただけるように石狩と東京を選べるようにもしています。~~飽きずに~~ 引き続き開発を続けていて、今月も細かいアップデート2件予定しています。

以下、どういうふうに作ったか、開発の裏側の話をしていきます。

# 特別な物理機器を一切使わずIaaS上のVMだけで超スケールするLBを目指して

エンハンスドLBのシステム構成は以下のようになっています。これらのサーバ群は全て「さくらのクラウド」上の普通のサーバ(VM)として動いています。エンハンスドLB固有の物理機器は一切ありません。

![dp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108990/dc8e66fe-c096-2538-1c9e-19b6067c0c41.png)

開発当初、ハードウェアのロードバランサ製品を買って構築することも考えました。マルチテナントで、1台の物理機器に複数のお客様の設定を投入するような構成ですね。既成のものを使うので開発工数は圧倒的に削減できます。

しかし、見積もりをとってみるとやはり製品導入のコストは高く、その割にSSLの性能が ~~ごみみたいなスループットしかでない~~ とても低いという感じでした。これではお客様への提供価格を押し上げてしまうだけでなく、もし売れなかったときには投資を回収できないというリスクも抱えてしまいます。

それに、今どきネットワークファンクションを物理でゴリゴリ実装する時代でもないし、ソフトウェア実装されたハイパースケーラーのロードバランサ実装例の情報も多々あります。

当時参考にさせていただいた文献:

ロードバランサのアーキテクチャいろいろ - yunazuno.log
http://yunazuno.hatenablog.com/entry/2016/02/29/090001

エンハンスドLBもそれらを参考にソフトウェアベースのアーキテクチャで検討を進めました。チャレンジングな要素も多々ありますが、エンジニアとしてはそっちの方が絶対面白いと思うんです😇

# 3段階のバランシング処理

さて、超スケールするための仕組みとして、エンハンスドLBでは以下の3つのバランシングステージを設けています。前記の先行事例を参考にしたので、まぁ最近のありがちな構成になってます。

![d.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108990/ead6c74b-f2c8-b2f8-50f1-0b31b4c526da.png)

### 1段目: 物理ルータによるECMP

インターネットから入ってきたエンドユーザさんからのHTTPリクエストパケットは、弊社グローバルバックボーンを経てさくらのクラウドを収容している末端のエッジルータ(物理ルータ)まで届きます。これはハードウェアで処理を行っているため回線容量限界までパケットフォワーディング処理が可能です。

この物理ルータは、次のステージである複数のL4バランサ(VM)とBGPピアを張っていて、お客様毎にアサインされるVIP(ロードバランサの終端IPアドレス)となる経路を/32単位で受信しています。ルータのECMP(Equal Cost Multi Path)により、L3でのパケット分散処理を行ないL4バランサに渡します。

なお、弊社で運用しているルータも含め、たいていの物理ルータはパケット単位ではなくフロー単位でECMPが行われます。あるTCPセッションを構成するパケット群は必ず同じL4バランサに着信するんですね。それによりL4バランサ間でのセッションの同期を行う必要がなく、スケールしやすい構成となります。

障害によりL4バランサがダウンした際は、BGPのピアがダウンし経路情報がwithdrawnされることで他のL4バランサ群にパケット転送が切り替わります。BGPにより冗長性(高可用性)と負荷分散を実現している形になります。

### 2段目: L4バランサ

この部分は上記物理ルータから受け取ったトラフィックを処理し、さらに後段のL7バランサに振り分けを行う部分です。クラウド上のVMとしてLinuxサーバが複数動作しています。ヘルスチェックはkeepalivedを、L4分散処理はLinuxのIPVS(L2 DSR構成)を用いています(めっちゃ普通)。

エンハンスドLBでは料金プラン毎にCPS(Connection Per Second≒秒間アクセス数)の上限値が定められています。実はこのL4バランサにおいて、iptablesを用いたTCP SYNパケットの流量制限を行う形で性能制限の実装を行っています。

ところで、このL4バランサもパケットの集中する箇所であり、安定したスループットが求められます。そのため、ハイパーバイザを専有する形で1VMにつき1物理サーバをアサインするようなプロビジョニングを行っています。

参考：専有ホスト機能について
https://manual.sakura.ad.jp/cloud/server/private-host.html
https://cloud.sakura.ad.jp/specification/server-disk/#server-disk-content01

さらに、VMでのパケット処理性能を向上させるために、vNICのマルチキューにも対応しました。

マルチキューに対応していない場合、パケットの処理が1コアに偏っていくらvCPU数を増やしても性能が伸びません。マルチキューに対応したことにより、vCPU数に対して性能がスケールするようになります。PoCではさくっと3倍の性能になったを確認できたので、この部分の原価が1/3になったことになりますね :-)

マルチキューは、このエンハンスドLB実装のために欲しくて対応したのですが、一般のお客様のサーバでも普通に使えるようにしております。詳細は以下ページをご覧いただければ幸いです。

サーバの仮想NICがマルチキューに対応しました(2019/3/14)
https://cloud-news.sakura.ad.jp/2019/03/14/hostserver-irqbalance-enhanced/

### 3段目: L7バランサ

その名の通り、HTTPの処理やTLSの終端(HTTPSの場合)、お客様指定の実サーバへのプロキシ処理を行うパートとなります。これもLinuxサーバがクラウド上のVMとしてたくさん動いており、HAproxyを使っています(nginxじゃないの？って聞かれそう😇)

一番重い処理がTLSの終端で、鍵交換(ECDHE)が性能の支配的要因となります。性能上のワーストケースとして、全てがフルハンドシェイクを想定した収容設計をしています。構成を決めるにあたっての予備試験でベンチマークをとったところ、vCPU数は8コアくらいまで性能がリニアに伸びる結果だったので、8コアのVMをクラウド上に大量にばらまく構成をとっています。

エンハンスドのLB料金体系が、帯域ではなくCPS(秒間アクセス数)になっているのも、主にこれが理由です(ECDHE/secでコスト負担をいただいている感じ)。

# 多数のVMにテナント設定をプロビジョニングする仕組み

データプレーンについて前節で説明したとおり、超スケールさせるためにクラウド上に多数のVMをたてています。これら全てに一貫性をもってお客様の設定を各ミドルウェアに反映する仕組みが必要です。

エンハンスドLBでは、以前からさくらのクラウド内部システムで稼働実績のあるMQ(Message Queue)を活用することにしました。実際のコントロールプレーンの構成は以下のようになっています。

![cp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108990/0c06fb86-d744-1361-396b-648140524b24.png)

MQはRabbitMQを使っています。Erlangで書かれていてめっちゃ簡単に高可用クラスタを組むことができます。UIやCLIもしっかりしていてオペレーションもしやすく、非常によくできたソフトウェアだと感じます。

APIサーバは、エンハンスドLB固有の処理を行うものを社内ネットワークにたてています(RESTful)。お客様がクラウドコンパネから設定変更などの操作をするとCloud APIサーバ経由でリクエストが到着します。このAPIサーバからお客様の設定情報をMQを通じてデータプレーンVM群に配信したり、MQを通じてメトリクス(負荷情報)を収集したりします。なお、この部分はお客様のSSL証明書(の秘密鍵)なども扱うため、MQを介した通信には暗号化を施しています。

L4ロードバランサ、L7ロードバランサのVMは、お客様の収容状況、負荷状況によって増減させたり、あるいは障害によってダウン、アップしたりします。MQにより疎結合な構成になっているため、各VMはMQをサブスクライブしておくだけでよく、APIサーバもいちいちVMが増えた、減った、を意識しなくてすみます。

# 後編に続く・・

今回はさくらのクラウド「エンハンスドロードバランサ」の概要と全体的な構成について紹介させていただきました。後編(明日公開予定)では各パートの細部に踏み込んで、実装例やミドルウェアの設定について引き続き紹介したいと思います。

2019/12/5追記：後編公開しました。
https://qiita.com/jh1vxw/items/99d0fe5727ae157dbfd9