Docker Actionを利⽤して
Apache OpenWhiskをあれこれする
Serverless Meetup Tokyo #5
2017.9.6
@tokida
自己紹介
常⽥秀明 (@tokida)
⽇本情報通信株式会社 / エンジニア
Bluemix User Group 代表 / IBM Champion
会社で取り組んでいること
✓⽇本情報通信株式会社は、IBM,NTT系のいわゆるSIer、受託開発メイン。
ネットワーク系は⾃動⾞⼯業ネットワークのプロバイダやEDIなどでサー
ビス事業を営んでいます。
✓いろいろ経験の多い⼈も沢⼭いるけど外部には出ていかない。なので、社
内でIT勉強会開いたりアプリ開発コンテストしたり、外部の勉強会を紹介
したり、Bluemix User Groupに狩りだしたり。(社内コミュニティって
ムズカシイ)
✓⾃社でこういった活動している⼈いたらお話したいです
Serverless界隈への最近の興味
✓インフラの側⾯から⾒る、FaaSとPaaSの相違
✓オンプレミス(またはプライベートクラウド)環境におけるFaaSの意義
✓もしOSSのDataStoreなどとイベント連携したら盛り上がりそう
Apache OpenWhisk
✓IBMがBluemix上でのFunction as a Serviceとして開発したソフトウェ
ア
✓現在では、Apache OpenWhisk として提供されている
✓単純なサーバソフトウェアじゃなく様々なコンポーネントで成り⽴ってい
るが全て含まれた状態で提供されている
✓Functionの実体は「Dockerコンテナ」で実現される
主な提供や事例
✓Apache OpenWhiskの完全なマネージドサービスとしての提供は、IBM
Bluemix 上の Cloud Functions (サービス名が変更になりました)
✓最近のトピックスとしては、RedHat社が開発への参⼊を表明
✓発表がされている代表的な事例は、Adobe社
https://developers.redhat.com/blog/2017/06/07/red-hat-and-apache-openwhisk/
FaaSとしての特徴
✓Function
✓利⽤できる⾔語:JavaScript, Python , PHP, Docker ( Java, Go )
✓呼び出し⽅法:SDK, HTTP Request, REST API
✓作成されたFunctionをつなぎ合わせる、Chain機能
✓イベント駆動
✓Bluemixの幾つかのサービスと密結合された動作をサポート(Cloudant, IoTP, Message
Hub, Alert 等)
✓OSS版においてもイベント駆動型の仕組みを作る事が可能
OpenWhiskはDockerで出来ている
✓インフラとしてのOpenWhiskを⾒てみると、その内容は Platform as a
Serviceそのものの構成をしています。https://console.bluemix.net/docs/
openwhisk/openwhisk_about.html#cloud-functions-
✓OpenWhiskが「Function」を動かすためには、Dockerコンテナを利⽤し
ています。実⾏(Invoker)⽤のコンテナ上に各⾔語を動作させる仕組みが
組み込まれています。 
✓そしてPaaSと違いFunction単位で動くために起動⽅法が⼯夫されていま
す(ワームスタート・コールドスタート)
OpenWhisk Tips
✓Functionを作っていく時には、Packageという塊にしておきましょう!	
✓wsk	package	create	demo
Docker Action
✓OpenWhiskでは、通常はコードのみを管理するFaaSですがDocker Action
を利⽤するとコンテナイメージをActionとして指定することが出来ます。
これも内部的にはInvokerのコンテナの仕組みがあるおかげです。
普通のDocker Action の書き⽅
⽅法1)dockerSkeleton コンテナをベースに開発
✓DockerActionは、カレントに exec という名前の実⾏ファイルがある
と実⾏がされるように設計/実装されている。
⽅法2)ゼロから作る
Baseイメージにdockerskeletonの利⽤
#	Dockerfile	for	example	whisk	docker	action	
FROM	openwhisk/dockerskeleton	
ENV	FLASK_PROXY_PORT	8080	
###	Add	source	file(s)	
ADD	example.c	/action/example.c	
RUN	apk	add	--no-cache	--virtual	.build-deps		
								bzip2-dev		
								gcc		
								libc-dev		
###	Compile	source	file(s)	
	&&	cd	/action;	gcc	-o	exec	example.c		
	&&	apk	del	.build-deps	
CMD	["/bin/bash",	"-c",	"cd	actionProxy	&&	python	-u	actionproxy.py"]
#include	<stdio.h>	
int	main(int	argc,	char	*argv[])	{	
				printf("This	is	an	example	log	message	from	an	arbitrary	C	program!n");	
				printf("{	"msg":	"Hello	from	arbitrary	C	program!",	"args":	%s	}",	
											(argc	==	1)	?	"undefined"	:	argv[1]);	
}
実⾏される exec のコード
✓wsk	sdk	install	docker	
✓./buildAndPush.sh	tokida/dockerskeleton	
✓wsk	action	create	demo/execAction	--docker	tokida/
dockerskeleton	
✓wsk	action	invoke	demo/execAction	-r	-b
{	
				"args":	{},	
				"msg":	"Hello	from	arbitrary	C	program!"	
}
じゃあexecを置き換える
✓シェルで exec を作る
✓zip	exec.zip	exec	
✓bx	wsk	action	create	demo/noPullAction	exec.zip	—native	
✓wsk	action	invoke	demo/noPullAction	-r	-b
#!/bin/sh	
echo	"{	"result":	"shell	code"	}"
{	
				"result":	"shell	code"	
}
dockerSkeletonの場合にはコンテナイメージを作成し
なくてもexecだけを使ってActionを作れる
ゼロから作る
✓ 所定のルールを守って作る
✓/init と /run をパスに持つ Webアプリケーションを作る
✓ /run の内容が実⾏される
✓Node.jsの場合には app.post('/run',	function	(req,	res) な感
じで定義して json形式で応答を戻す
Python flaskを使って作る
✓ Python Flaskでコードを書いて、Docker化
✓Dockerイメージを docker hub に push
✓ wsk createコマンドでDockerアクションを作成
from	flask	import	jsonify	
from	flask	import	Flask	
app	=	Flask(__name__)	
@app.route('/init',methods=['GET',	'POST'])	
def	init():	
				return	"init"	,200	
@app.route('/run',methods=['GET',	'POST'])	
def	hello_world():	
				str	=	{	
								"result"	:	{	"payload"	:	"Run.	Hello	World!"	}	
				}	
				return	jsonify(str)	,	200	
if	__name__	==	'__main__':	
				app.run(host="0.0.0.0",	port=8080)
app.py
click==6.6	
Flask==0.11.1	
itsdangerous==0.24	
Jinja2==2.8	
MarkupSafe==0.23	
Werkzeug==0.11.10
requirements.txt
FROM	python:3.5.2-alpine	
ARG	project_dir=/web/hello/	
ADD	requirements.txt	$project_dir	
ADD	app.py	$project_dir	
WORKDIR	$project_dir	
RUN	pip	install	-r	requirements.txt	
RUN	apk	update	
RUN	apk	add	zsh	vim	tmux	git	tig	
CMD	["python"	,	"app.py"]
Dockerfile
✓docker build -t tokida/flaskaction .
✓docker push tokida/flaskaction
✓wsk action create demo/flaskAction --docker tokida/flaskaction
✓wsk action invoke demo/flaskAction -r -b
wsk	action	invoke		flask	-r	-b	
{	
				"result":	{	
								"payload":	"Run.	Hello	World!"	
				}	
}
Nodejsを使って作る
✓ Nodejsでコードを書いて、Docker化
✓Dockerイメージを docker hub に push
✓ wsk createコマンドでDockerアクションを作成
var	express	=	require('express');	
var	app	=	express();	
var	bodyParser	=	require('body-parser');	
app.use(bodyParser.json());	
app.post('/init',	function	(req,	res)	{	
			res.status(200).send();	
});	
app.post('/run',	function	(req,	res)	{	
			var	meta	=	(req.body	||	{}).meta;	
			var	value	=	(req.body	||	{}).value;	
			var	payload	=	value.payload;	
			if	(typeof	payload	!=	'string')	
						payload	=	JSON.stringify(payload);	
			console.log("payload:	"	+	payload);	
			var	result	=	{	'result'	:	{	'msg'	:	'echo',	'payload'	:	payload}	};	
			res.status(200).json(result);	
});	
app.listen(8080,	function	()	{	
})
app.js
{	
		"name":	"openwhisk-docker-node",	
		"version":	"1.0.0",	
		"main":	"app.js",	
		"dependencies":	{	
				"express":	"^4.11.2",	
				"body-parser":	"^1.11.0"	
		},	
		"scripts":	{	
				"test":	"echo	"Error:	no	test	specified"	&&	exit	1"	
		},	
		"author":	"",	
		"license":	"ISC",	
		"devDependencies":	{},	
		"description":	""	
}
package,json
FROM	registry.ng.bluemix.net/ibmnode	
ADD	./app.js	./	
ADD	./node_modules/	./node_modules/	
ENV	NODE_ENV	production	
EXPOSE	8080	
CMD	["node",	"app.js"]
Dockerfile
✓bx cr login
✓npm install
✓docker build -t tokida/nodeaction .
✓docker push tokida/nodeaction
✓wsk action create --docker demo/nodeAction tokida/nodeaction
✓wsk action invoke -r -b demo/nodeAction ̶param payload tokida
$	wsk	action	invoke	-b	docker-node	--param	payload	tokida	-r	-b	
{	
				"result":	{	
								"msg":	"echo",	
								"payload":	"tokida"	
				}	
}
作ったパッケージは公開しよう
✓wsk package update custom --shared yes
✓wsk package get demo publish
✓別のアカウントのユーザで実⾏することが出来ます。
✓bx wsk action invoke -r -b /solct3_demo/demo/flaskAction
✓ちなみに、実⾏するのは「実⾏ユーザのアカウント」で⾏わますので上記のPackageへガンガ
ンアクセスが来ても作成者はコスト負担はありません。
APIとして公開する
✓APIとして公開するのは⾮常に簡単!(しかも無料)
✓作成したActionは、通常ではSDK(wskの認証トークンを元に実⾏する
REST ful経由の操作)、またはWebAction(HTTPプロトコル経由のアク
セス/ユーザ認証不要)、そしてREST API(トークン個別発⾏可能)で利
⽤可能です。SDK等はiOSやNode-REDから利⽤できるようにライブラリ
やnodeモジュールが提供されています。
{	
				"swagger":	"2.0",	
				"basePath":	"/api",	
				"info":	{	
								"title":	"node",	
								"version":	"1.0"	
				},	
				"paths":	{	
								"/hello":	{	
												"get":	{	
																"operationId":	"getHello",	
																"responses":	{	
																				"200":	{	
																								"description":	"A	successful	invocation	response"	
																				}	
																},	
																"x-openwhisk":	{	
																				"action":	"nodeAction",	
																				"namespace":	"solct3_demo",	
																				"package":	"demo",	
																				"url":	"https://openwhisk.ng.bluemix.net/api/v1/web/solct3_demo/demo/nodeAction.json"	
																}	
												}	
								}	
				},	
				"x-ibm-configuration":	{	
(中略)	
							"cors":	{	
												"enabled":	true	
								}	
				}	
}	
APIを設定するためのSwaggerファイル
curl	https://service.us.apiconnect.ibmcloud.com/gws/apigateway/api/
51f17508ac5ba0579267cb006adf53c592b59c440ed0c43afdf8b34fd2807fd4/api/hello	2>/dev/
null	|	jq	.	
{	
		"result":	{	
				"msg":	"echo"	
		}	
}
✓設定は標準的なSwagger(GUIでも設定可能、GUIで設定した後に wsk
api get <name> でSwaggerファイルを取得できる)
✓セキュリティの設定でTokenキーを払い出す
あんなこと、こんなこと
✓ たまにしか動かさないような処理をアクション化しておこう(特に細か
い設定なく REST APIや Webアクションとして実⾏可能)
✓ サポートされてない⾔語やライブラリがあってもDocker Actionを使え
ば簡単にアクション化出来る。
✓ Bluemixならすぐに使ってみることが出来る。
✓最近では kubernetes上でも動くらしいよ (OpenWhisk on k8)
宣伝
 本を出版しました。
 Bluemixの全体像が掴めるように⼼がけてい
ます。最初に⼿にとって頂ければ幸いです。
 なお、OpenWhink (Functions)についての
解説はありません (´;ω;`)
@tokida
ご清聴ありがとうございました
参考⽂献
✓Creating and invoking OpenWhisk actions
‣https://github.com/apache/incubator-openwhisk/blob/master/docs/
actions.md#creating-docker-actions
✓Creating Docker Actions with OpenWhisk
‣http://heidloff.net/article/how-to-create-docker-actions-openwhisk-bluemix
✓Understanding and using Docker actions in IBM Bluemix OpenWhisk
‣https://www.ibm.com/blogs/bluemix/2017/01/docker-bluemix-openwhisk/
✓James Thomas
‣http://jamesthom.as
✓Node.js, Pythonなどで初期導⼊されているライブラリ
‣https://console.bluemix.net/docs/openwhisk/openwhisk_reference.html#openwhisk_reference

Docker Actionを利用してOpenWhiskをあれこれする