Edited at

KONGでニフクラスクリプトもチームもマネジメントする話

More than 1 year has passed since last update.

この記事は富士通クラウドテクノロジーズ Advent Calendar 2017の12日目の投稿です。

11日目は@yaaamaaaguuu今年一年間の知見に関する記事でした。私の過去10年間の知見よりも多くて正直焦りました。


はじめに

私はニフクラのサービス開発エンジニアとして携わっていますが、様々な内外的要因とタイミングとあれやこれやあり今年の7月からマネージャーというポジションで仕事しています。

マネージャーであるからには、言いづらいけど言わないといけないこともはっきりとチームメンバーに伝える必要があります。しかし新米へっぽこマネージャーはひとくせもふたくせもある優秀なエンジニアのチームメンバを相手にいつも四苦八苦してしまいます。

今回は私のようなヘタレでもチームメンバーに伝えたい事を伝えらるようなお話です。


手段

エンジニアチームの話なのでコミュニケーションにもエンジニアリングを極力用いるのがいいでしょう。今回はニフクラのサーバーレスサービスのスクリプトとオープンソースで豊富なプラグインが魅力的なAPIGateWay基盤であるKONGを活用して言いたいことを言ってみようと思います。やっとタイトル通りの記事っぽくなってきましたね。


環境


  • Docker version 17.11.0-ce

  • KONG 0.11.2

  • Postgresql 9.4

  • ニフクラスクリプト


導入

まずはKONGとそのデータストアであるPostgresql9.4マニュアルを基にDockerで構築します。


Postgresql構築〜起動

$ docker run -d --name kong-database \

-p 5432:5432 \
-e "POSTGRES_USER=kong" \
-e "POSTGRES_DB=kong" \
postgres:9.4


スキーマなどをマイグレーション

$ docker run --rm \

--link kong-database:kong-database \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-database" \
-e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \
kong:latest kong migrations up


KONG構築〜起動

$ docker run -d --name kong \

--link kong-database:kong-database \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-database" \
-e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \
-e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \
-e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \
-e "KONG_PROXY_ERROR_LOG=/dev/stderr" \
-e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \
-p 8000:8000 \
-p 8443:8443 \
-p 8001:8001 \
-p 8444:8444 \
kong:latest

docker ps -a をして確認してみましょう。kongkong-databaseがUPしてればOKです。


スクリプト作成

今回はクイックスタートにあるスクリプトをそのまま使ってみようと思います。

上記ページに従ってスクリプトを作成します。


KONGにnifcloud-script pluginを配備して再イメージ化

KONGはデフォルトでaws-lambdaという公式プラグインがありますが、残念ながらニフクラスクリプト用のプラグインはありません。

なので新規にプラグインを作成してインストールさせる必要があります。

プラグインの作成にあたっては公式のPlugin development - Introductionを読みながら作成します。

今回は他のlua-nginx-moduleを参考にこちらを作りました。

配備後はcommitしておきます。


$ git clone https://github.com/Ken-Moriizumi/kong-nifcloud-script-sample.git nifcloud-script
$ docker cp nifcloud-script kong:/usr/local/share/lua/5.1/kong/plugins/
$ docker commit kong kong:nifcloud


KONGへプラグインをインストール

上とほぼ同じですがKONG_LOG_LEVELKONG_CUSTOM_PLUGINSという環境変数が追加になっています。

また、立ち上げるのは先程commitしたイメージから立ち上げます。


$ docker run -d --name kong \
--link kong-database:kong-database \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-database" \
-e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \
-e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \
-e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \
-e "KONG_PROXY_ERROR_LOG=/dev/stderr" \
-e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \
-e "KONG_LOG_LEVEL=debug" \
-e "KONG_CUSTOM_PLUGINS=nifcloud-script" \
-p 8000:8000 \
-p 8443:8443 \
-p 8001:8001 \
-p 8444:8444 \
kong:nifcloud

立ち上がったらdocker logs kongを実行してnifcloud-scriptプラグインがロードされていることを確認します。

環境構築はこれで完了です。


実行


API作成

KONGのマニュアルに従って新規APIを作成します。upstream_urlは通常転送先のURLを設定するのですが、今回はaws-lambda同様プラグイン内で強制的にニフクラスクリプトに転送するのでなんでも構いません。

curl -i -X POST \

--url http://localhost:8001/apis/ \
--data 'name=nifcloud-api' \
--data 'hosts=nifcloud' \
--data 'upstream_url=http://nifcloud.com'


nifcloud-script プラグイン有効化

次に上記で作成したAPIに対してnifcloud-scriptプラグインを有効化します。

この時アクセスキーとシークレットキーを指定します。


curl -X POST http://localhost:8001/apis/nifcloud-api/plugins \
--data "name=nifcloud-script" \
--data-urlencode "config.access_key=<nifcloud-access-key>" \
--data-urlencode "config.secret_key=<nifcloud-secret-key>" \
--data "config.region=jp-east-1" \
--data "config.function_name=dummy"


クライアント作成〜実行

これでKONGを使用したニフクラスクリプトのAPIGateWayができました。

curlを使ってAPIGateWay経由でニフクラスクリプトを叩いてみます。

$ curl -i -X POST  --url http://${KONG_HOSTNAME}:8000/${EXEC_SCRIPT_NAME}   --header 'Host: nifcloud'

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Connection: keep-alive
ETag: W/"27a-Wjd06nqimAWgaLmPnQYR1T3HGno"
Content-Length: 634
Access-Control-Allow-Origin: *
Date: Thu, 07 Dec 2017 07:25:36 GMT
Connection: keep-alive
Server: kong/0.11.2

<?xml version="1.0"?><ExecuteScriptResponse><requestId>5f08a68c-ea04-41e6-9374-615059356498</requestId><ExecuteScriptResult><Result><console><log/><err/></console><ResponseStatus>200</ResponseStatus><ScriptIdentifier>test1.js</ScriptIdentifier><RequestQuery><![CDATA[{"name":"merryChristmasAndHappyNewYear!!"}]]></RequestQuery><RequestBody><![CDATA[{}]]></RequestBody><ResponseHeader><![CDATA[{"Content-Type":"text/plain"}]]></ResponseHeader><RequestHeader><![CDATA[{}]]></RequestHeader><ResponseData><![CDATA[merryChristmasAndHappyNewYear!!]]></ResponseData><Status>200</Status></Result></ExecuteScriptResult></ExecuteScriptResponse>c

KONG_HOSTNAME はAPIGateWayを構築したドメインもしくはIPアドレス、

EXEC_SCRIPT_NAME は上で保存したニフクラのスクリプト名を設定します。

無事200応答が帰ってきましたが、これではさすがのエンジニアもちょっと何言ってるのかわかりません。

なので簡単なクライアントを作りました。


api-gateway-client.rb

#!/bin/ruby

require "httpclient"
require "rexml/document"

client = HTTPClient.new

body = ""
header = {
"Host" => "nifcloud"
}

res = client.post(
"http://#{ENV['KONG_HOSTNAME']}:8000/#{ENV['EXEC_SCRIPT_NAME']}",
body,
header
)

doc = REXML::Document.new res.body

puts doc.elements['ExecuteScriptResponse/ExecuteScriptResult/Result/ResponseData'].text


# bundle exec ruby api-gateway-client.rb

merryChristmasAndHappyNewYear!!

これでシンプルかつ明確にみんなへクリスマスと新年の挨拶をすることができました。

挨拶はマネジメントというよりそもそもコミュニケーションの基本ですし、lowerCamelにすることでちょっと親密なprivate感も醸せます。TPOに応じて使い分けましょう。

難点といえば自作プラグインの作りが少々雑なため他のメッセージを送信できないことくらいでしょうか。


おわりに

今回は必要であったためプラグインを作成しましたが、KONGはデフォルトで豊富なプラグインが同梱されているため、ライトな用途であればほぼそのまま現場に導入可能な印象を受けました。

ただJavaを一切使っていないのに出力をlowerCamelにしてしまったことは反省しています。

是非みなさんもKONGを使ったコミュニケーションでAPIマネジメントだけでなくチームのマネジメントをしてみましょう。

あしたは@tunakyonnの「Unity WebGLをmBaaSで使ってみた」です。お楽しみに!