ブログ

ryuzeeによるブログ記事。不定期更新
アジャイル開発に取り組むチーム向けのコーチングや、技術顧問、認定スクラムマスター研修などの各種トレーニングを提供しています。ぜひお気軽にご相談ください(初回相談無料)

オープンソースのAPI Gateway「Kong」

全国100万人のモノリシック巨大アプリケーションに苦しむみなさんこんにちは。

世の中猫も杓子もマイクロサービスだ!!とかAPIだ!!とか言っていますが、実際にマイクロサービス環境にしようとすると、どのようにしてAPIのサービスを取りまとめるかが課題になります。

一般的には以下のようなやり方になります。

  • 複数のサービスに分散しているAPIを統合するゲートウェイを用意する
  • そのゲートウェイでは以下のようなことをおこなう
  • クライアントからのアクセスのシングルエンドポイントの役目を果たす
  • APIの実体へのルーティング
  • 認証
  • アクセス記録の収集
  • スロットリング(過度なアクセスの抑止)
  • 実体がダウンしている場合のデグレーション

このようなAPIゲートウェイの機能は既にAWSではAmazon API Gatewayとして提供されていますが、オープンソースでもいくつかのプロダクトがあります。今回はそのうち一番開発が活発そうな、Kongについて紹介しましょう。

Kongとは?

KongはオープンソースのAPI管理ツールです。2015/10/14時点の最新バージョンは0.5.1になります。GitHubのレポジトリは https://github.com/mashape/kongです。

主な特徴としては

  • NginxとCassandraを使って実装
  • APIの管理などの各種操作は全てREST APIを使っておこなう
  • プラグインによる機能拡張が可能
  • 動作環境を選ばずオンプレミスでもクラウドでも動作する

などがあげられます。

Kongのインストール

では早速試してみましょう。簡単に試せるようにDockerのイメージやAWS CloudFormationのテンプレートなども用意されていますが、Vagrant用のスクリプトも用意されているので今回はそちらを使います。

単純に以下のようにしてレポジトリをチェックアウトしてください。

git clone https://github.com/Mashape/kong-vagrant

それが終わったら、チェックアウト先のディレクトリに移動し、

vagrant up --provision

を実行してください。precise64のボックスを利用するので、もし未登録の場合はダウンロードがおこなわれるため少し時間がかかるかもしれません。 プロビジョニングが終わったら、vagrant sshで仮想マシンにログインし以下のようにしてサービスを起動します。

sudo kong start

初回の場合は、データベースのマイグレーションが行われます。以下のようなログが出れば正常です。

[INFO] Using configuration: /etc/kong/kong.yml
[INFO] Kong version.......0.5.1
       Proxy HTTP port....8000
       Proxy HTTPS port...8443
       Admin API port.....8001
       dnsmasq port.......8053
       Database...........cassandra keepalive=60000 timeout=1000 contact_points=localhost:9042 keyspace=kong
[INFO] Connecting to the database...
[INFO] Database not initialized. Running migrations...
[OK] core migrated up to: 2015-01-12-175310_skeleton
[OK] core migrated up to: 2015-01-12-175310_init_schema
[OK] jwt migrated up to: 2015-06-09-jwt-auth
[OK] acl migrated up to: 2015-08-25-841841_init_acl
[OK] oauth2 migrated up to: 2015-08-03-132400_init_oauth2
[OK] oauth2 migrated up to: 2015-08-24-215800_cascade_delete_index
[OK] key-auth migrated up to: 2015-07-31-172400_init_keyauth
[OK] hmac-auth migrated up to: 2015-09-16-132400_init_hmacauth
[OK] basic-auth migrated up to: 2015-08-03-132400_init_basicauth
[OK] rate-limiting migrated up to: 2015-08-03-132400_init_ratelimiting
[OK] response-ratelimiting migrated up to: 2015-08-21_init_response-rate-limiting
[INFO] Auto-generating the default SSL certificate and key...
[INFO] dnsmasq started (dnsmasq)
[WARN] ulimit is currently set to "1024". For better performance set it to at least "4096" using "ulimit -n"
[OK] Started

これで準備は完了です。Vagrantfileの中でローカル環境の8000番ポートと8001番ポートをポートフォワードしてVagrant側の環境にアクセスできるようになっています。

使い方

各種の設定は全てREST API経由で行ないます。

公開されているAPIの確認

現時点でどんなAPIが利用者に公開されているかは以下のようなリクエストを投げます。

curl -i -X GET --url http://localhost:8001/apis

この時点では何も公開されていないので、

{"data":[]}

という応答が返ります。

APIを追加する

では次に実際に利用者が使えるようにAPIを公開しましょう。

APIの追加の追加は以下のようなコマンドを実行します。

curl -i -X POST \
  --url http://localhost:8001/apis/ \
  -d 'name=slides' \
  -d 'upstream_url=https://slide.meguro.ryuzee.com/api/v1/slides' \
  -d 'request_host=slide.meguro.ryuzee.com' \
  -d 'request_path=/slides'
  • 最初の--urlは管理用のエンドポイントを指定します。
  • 次のnameパラメータはAPIを一意に識別する名前です。実際のリクエストURLとは関係ありません。
  • 次のupstream_urlがこのAPIの実体のアクセス先です。今回の例では、以前作っておいたスライド公開アプリのスライド一覧取得APIを指定してみました
  • 次のrequest_hostはリクエスト先のホスト名です
  • 最後のrequest_pathは、このAPIのゲートウェイでどんなパスでリクエストを受けるかを指定します。

つまりこの例では、http://localhost:8000/slidesにアクセスすると、実際はupstream_urlで設定したAPIをコールします。実際に以下のようにAPIにアクセスしてみると、jsonが返ってくるのがわかります。

curl -i -X GET \
  --url http://localhost:8000/slides

APIを削除する

APIを削除する場合も管理用のエンドポイントにリクエストを投げればOKです。 末尾の箇所にAPIを作成するときにnameで指定した値を利用します。

curl -i -X DELETE --url http://localhost:8001/apis/削除したいAPI名

APIの利用時に認証を必須にする

利用者がAPIを呼び出す際に誰が呼び出しているかを識別したいケースは多々あるはずです。その場合もKongのプラグイン機構を使うことで簡単に対応できます。 たとえばKey認証を行う場合は、まずKongの設定を変更します。

/etc/kong/kong.ymlに以下を追加して再起動します(先ほど作成したVagrant環境では既に有効になっています)

plugins_available:
  - key-auth

次に認証を有効化します。認証をするかどうかはAPI単位で決めることができます。 たとえば先ほどの/slidesのAPIに認証を設定する場合は、

curl -i -X POST \
  --url http://localhost:8001/apis/slides/plugins/ \
  --data 'name=key-auth'

とします。この時点でもう一度APIにアクセスしてみると認証情報がないのでエラーになるはずです。

{"message":"No API Key found in headers, body or querystring"}

認証情報を作成する

認証情報を作成するには、まずユーザーを作成した上で、そのユーザー用のKeyを発行します。

認証用のユーザーを追加するには、以下のようにします。ここではryuzeeというユーザーを追加しています。

curl -i -X POST \
  --url http://localhost:8001/consumers/ \
  --data "username=ryuzee"

以下のような結果が返ってきます。

{"username":"ryuzee","created_at":1444714266000,"id":"addc1363-fbb4-441b-c4ef-20410692d9d8"}

この時点では認証用のキーは存在していないので、以下のようにしてキーを発行します。--urlの箇所でconsumersのあとにユーザー名を指定し、--dataの箇所でkey=キーの値という形で設定します。

curl -i -X POST \
  --url http://localhost:8001/consumers/ryuzee/key-auth/ \
  --data 'key=sushikuitai12345'

実行すると以下のような形で帰ってきて、キーの発行が完了しました。

{"created_at":1444714396000,"consumer_id":"addc1363-fbb4-441b-c4ef-20410692d9d8","key":"sushikuitai12345","id":"117beaab-b2ac-4380-c312-d7b0cf07da23"}

なお、当然のことながら実際のサービスで利用する場合は、別の画面でユーザー用のキーを発行するような仕掛けを作る必要があります。その中でKongの認証用ユーザーとキーの発行APIを呼び出すということになります。

これで以下のようにすればアクセスできます。

curl -i -X GET \
  --url http://localhost:8000/slides \
  --header "apikey: sushikuitai12345"

もしくは以下のようにクエリストリングで設定してもOKです。

curl -i -X GET \
  --url http://localhost:8000/slides?apikey=sushikuitai12345

APIへのリクエスト数を制限する(スロットリング)

大量のAPIリクエストは時としてサービスの問題発生につながります。 そういった事態を避けるために、1ユーザーからの秒あたり・分あたり・時間あたりのAPIリクエスト数を制限するのはベストプラクティスの1つです。

これもプラグインの機能で実現できます

/etc/kong/kong.ymlに以下の設定を行って再起動してください。

plugins_available:
  - ratelimiting

実際のスロットリングの設定は以下のようにします。この例では、slidesという名前のAPIにおいて秒間5件、一時間あたり10000件のリクエスト数までに制限しています。

curl -X POST http://localhost:8001/apis/slides/plugins \
    --data "name=rate-limiting" \
    --data "config.second=5" \
    --data "config.hour=10000"

これで試しに大量リクエストを投げると、閾値を超えたものは以下のような応答を返します。

HTTP/1.1 429
Date: Tue, 13 Oct 2015 06:07:37 GMT
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
X-RateLimit-Limit-hour: 10000
X-RateLimit-Remaining-hour: 9995
X-RateLimit-Limit-second: 5
X-RateLimit-Remaining-second: 0
Server: kong/0.5.0

{"message":"API rate limit exceeded"}

なお、APIのスロットリングを解除する場合は、最初にAPIの内部IDを取得してそれを引数にして削除します。

curl -i -X DELETE http://localhost:8001/apis/slides/plugins/814b46d2-84a3-4034-c075-60f9e2916314

まとめ

ここまで紹介したのはごく一部の機能ですが、プラグインを使うことで、アクセスコントロールを詳細におこなったり、アクセス元IPアドレスを制限したり、ログを他のサーバに飛ばしたりといったことも可能です。

このツール自体がAPIでできているので、監視システムなどと組み合わせて公開用のAPIの設定を自動で変更して固定の応答を返したりといったこともできます。

  • スクラム実践者が知るべき97のこと
  • 著者/訳者:Gunther Verheyen / 吉羽龍太郎 原田騎郎 永瀬美穂
  • 出版社:オライリージャパン(2021-03-23)
  • 定価:¥ 2,640
  • スクラムはアジャイル開発のフレームワークですが、その実装は組織やチームのレベルに応じてさまざまです。本書はスクラムの実践において、さまざまな課題に対処してきた実践者が自らの経験や考え方を語るエッセイ集です。日本語書き下ろしコラムを追加で10本収録
  • プロダクトマネジメント ―ビルドトラップを避け顧客に価値を届ける
  • 著者/訳者:Melissa Perri / 吉羽龍太郎
  • 出版社:オライリージャパン(2020-10-26)
  • 定価:¥ 2,640
  • プロダクト開発を作った機能の数やベロシティなどのアウトプットで計測すると、ビルドトラップと呼ばれる失敗に繋がります。本書ではいかにしてビルドトラップを避けて顧客に価値を届けるかを解説しています。
  • SCRUM BOOT CAMP THE BOOK 【増補改訂版】
  • 著者/訳者:西村直人 永瀬美穂 吉羽龍太郎
  • 出版社:翔泳社(2020-05-20)
  • 定価:¥ 2,640
  • スクラム初心者に向けて基本的な考え方の解説から始まり、プロジェクトでの実際の進め方やよく起こる問題への対応法まで幅広く解説。マンガと文章のセットでスクラムを短期間で理解できます。スクラムの概要を正しく理解したい人、もう一度おさらいしたい人にオススメ。
  • みんなでアジャイル ―変化に対応できる顧客中心組織のつくりかた
  • 著者/訳者:Matt LeMay / 吉羽龍太郎、永瀬美穂、原田騎郎、有野雅士
  • 出版社:オライリージャパン(2020-3-19)
  • 定価:¥ 2,640
  • アジャイルで本当の意味での成果を出すには、開発チームだけでアジャイルに取り組むのではなく、組織全体がアジャイルになる必要があります。本書にはどうやってそれを実現するかのヒントが満載です
  • レガシーコードからの脱却 ―ソフトウェアの寿命を延ばし価値を高める9つのプラクティス
  • 著者/訳者:David Scott Bernstein / 吉羽龍太郎、永瀬美穂、原田騎郎、有野雅士
  • 出版社:オライリージャパン( 2019-9-18 )
  • 定価:¥ 3,132
  • レガシーコードになってから慌てるのではなく、日々レガシーコードを作らないようにするにはどうするか。その観点で、主にエクストリームプログラミングに由来する9つのプラクティスとその背後にある原則をわかりやすく説明しています。
  • Effective DevOps ―4本柱による持続可能な組織文化の育て方
  • 著者/訳者:Jennifer Davis、Ryn Daniels / 吉羽 龍太郎、長尾高弘
  • 出版社:オライリージャパン( 2018-3-24 )
  • 定価:¥ 3,888
  • 主にDevOpsの文化的な事柄に着目し、異なるゴールを持つチームが親和性を高め、矛盾する目標のバランスを取りながら最大限の力を発揮する方法を解説します
  • ジョイ・インク 役職も部署もない全員主役のマネジメント
  • 著者/訳者:リチャード・シェリダン / 原田騎郎, 安井力, 吉羽龍太郎, 永瀬美穂, 川口恭伸
  • 出版社:翔泳社( 2016-12-20 )
  • 定価:¥ 1,944
  • 米国で何度も働きやすい職場として表彰を受けているメンローの創業者かつCEOであるリチャード・シェリダン氏が、職場に喜びをもたらす知恵や経営手法、より良い製品の作り方などを惜しみなく紹介しています
  • アジャイルコーチの道具箱 – 見える化の実例集
  • 著者/訳者:Jimmy Janlén / 原田騎郎, 吉羽龍太郎, 川口恭伸, 高江洲睦, 佐藤竜也
  • 出版社:Leanpub( 2016-04-12 )
  • 定価:$14.99
  • この本は、チームの協調とコミュニケーションを改善したり、行動を変えるための見える化の実例を集めたものです。96個(+2)の見える化の方法をそれぞれ1ページでイラストとともに解説しています。アジャイル開発かどうかに関係なくすぐに使えるカタログ集です
  • カンバン仕事術 ―チームではじめる見える化と改善
  • 著者/訳者:原田騎郎 安井力 吉羽龍太郎 角征典 高木正弘
  • 出版社:オライリージャパン( 2016-03-25 )
  • 定価:¥ 2,138
  • チームの仕事や課題を見える化する手法「カンバン」について、その導入から実践までを図とともにわかりやすく解説した書籍。カンバンの原則などの入門的な事柄から、サービスクラス、プロセスの改善など、一歩進んだ応用的な話題までを網羅的に解説します。
  • Software in 30 Days スクラムによるアジャイルな組織変革“成功"ガイド
  • 著者/訳者:Ken Schwaber、Jeff Sutherland著、角征典、吉羽龍太郎、原田騎郎、川口恭伸訳
  • 出版社:アスキー・メディアワークス( 2013-03-08 )
  • 定価:¥ 1,680
  • スクラムの父であるジェフ・サザーランドとケン・シュエイバーによる著者の日本語版。ビジネス層、マネジメント層向けにソフトウェア開発プロセス変革の必要性やアジャイル型開発プロセスの優位性について説明
  • How to Change the World 〜チェンジ・マネジメント3.0〜
  • 著者/訳者:Jurgen Appelo, 前川哲次(翻訳), 川口恭伸(翻訳), 吉羽龍太郎(翻訳)
  • 出版社:達人出版会
  • 定価:500円
  • どうすれば自分たちの組織を変えられるだろう?それには、組織に変革を起こすチェンジ・マネジメントを学習することだ。アジャイルな組織でのマネージャーの役割を説いた『Management 3.0』の著者がコンパクトにまとめた変化のためのガイドブック