Python-izm 基礎編を Lambda で試してみた

Python-izmなる勉強になるサイトを見つけたため、AWS Lambdaで試してみた。

基礎編

文字列

def lambda_handler(event, context):
	    testnum = "123"
	    testnum = testnum + "456"
	    testnum	= testnum + "789"
	    testnum += "0"
	    print(testnum)
	    print(testnum.replace('1234567890','0123456789'))
	    print(testnum.rjust(20,'0'))
	    print(testnum.zfill(20))
	    
	    teststr = 'this-message'
	    print(teststr)
	    print(teststr.startswith('this'))
	    print(teststr.split('-'))
==========================================================================
Response:
null

Request ID:
"ebe00f2f-3fda-11e8-b0be-112860d9c610"

Function Logs:
START RequestId: ebe00f2f-3fda-11e8-b0be-112860d9c610 Version: $LATEST
1234567890
0123456789
00000000001234567890
00000000001234567890
this-message
True
['this', 'message']
END RequestId: ebe00f2f-3fda-11e8-b0be-112860d9c610
REPORT RequestId: ebe00f2f-3fda-11e8-b0be-112860d9c610	Duration: 0.83 ms	Billed Duration: 100 ms 	Memory Size: 128 MB	Max Memory Used: 21 MB

数値

def lambda_handler(event, context):
		testint = 100.5
		print(float(testint) + 100)
		
		testcomp = 100 + 5j
		print(testcomp.real)
		print(testcomp.imag)
==========================================================================
Response:
null

Request ID:
"98ecdea0-3fde-11e8-84a6-6331306e40e3"

Function Logs:
START RequestId: 98ecdea0-3fde-11e8-84a6-6331306e40e3 Version: $LATEST
200.5
100.0
5.0
END RequestId: 98ecdea0-3fde-11e8-84a6-6331306e40e3
REPORT RequestId: 98ecdea0-3fde-11e8-84a6-6331306e40e3	Duration: 0.42 ms	Billed Duration: 100 ms 	Memory Size: 128 MB	Max Memory Used: 21 MB

日付・時間

import datetime
import calendar

def lambda_handler(event, context):
		today = datetime.date.today()
		todaydetail = datetime.datetime.today()
		print(today)
		print(todaydetail)
		print(todaydetail + datetime.timedelta(hours=9))
		print(todaydetail.year)
		print(todaydetail.strftime("%Y/%m/%d %H:%M:%S"))
		print(calendar.isleap(2018))
==========================================================================
Response:
null

Request ID:
"cb3365b8-3fdf-11e8-9ef3-f786a1acc5e8"

Function Logs:
START RequestId: cb3365b8-3fdf-11e8-9ef3-f786a1acc5e8 Version: $LATEST
2018-04-14
2018-04-14 12:31:45.698769
2018-04-14 21:31:45.698769
2018
2018/04/14 12:31:45
False
END RequestId: cb3365b8-3fdf-11e8-9ef3-f786a1acc5e8
REPORT RequestId: cb3365b8-3fdf-11e8-9ef3-f786a1acc5e8	Duration: 9.95 ms	Billed Duration: 100 ms 	Memory Size: 128 MB	Max Memory Used: 21 MB

タプル

import datetime

def lambda_handler(event, context):
		test_tuple = get_today()
		print(test_tuple)
		print(test_tuple[0])

def get_today():
		today = datetime.datetime.today()
		value = (today.year, today.month, today.day)
		return value
==========================================================================
Response:
null

Request ID:
"2e249bf9-3fe2-11e8-ac44-514731084dd0"

Function Logs:
START RequestId: 2e249bf9-3fe2-11e8-ac44-514731084dd0 Version: $LATEST
(2018, 4, 14)
2018
END RequestId: 2e249bf9-3fe2-11e8-ac44-514731084dd0
REPORT RequestId: 2e249bf9-3fe2-11e8-ac44-514731084dd0	Duration: 28.05 ms	Billed Duration: 100 ms 	Memory Size: 128 MB	Max Memory Used: 21 MB

リスト


def lambda_handler(event, context):
		test_list = ['this','-','is','-','test']
		print(test_list)
		
		for i in test_list:
			print(i)
		
		test_list.append('.')
		print(test_list)
		print(test_list.index('test'))
==========================================================================
Response:
null

Request ID:
"126169e5-3fe3-11e8-8df7-4d4c2b06e81b"

Function Logs:
START RequestId: 126169e5-3fe3-11e8-8df7-4d4c2b06e81b Version: $LATEST
['this', '-', 'is', '-', 'test']
this
-
is
-
test
['this', '-', 'is', '-', 'test', '.']
4
END RequestId: 126169e5-3fe3-11e8-8df7-4d4c2b06e81b
REPORT RequestId: 126169e5-3fe3-11e8-8df7-4d4c2b06e81b	Duration: 0.48 ms	Billed Duration: 100 ms 	Memory Size: 128 MB	Max Memory Used: 21 MB

ディクショナリ


def lambda_handler(event, context):
		test_dict = {'year':'2018','mon':'04','day':'14'}
		for i in test_dict:
			print(i)
			print(test_dict[i])
		
		print(test_dict.get('year','NOT FOUND'))
		print(test_dict.get('years','NOT FOUND'))
		
		print(test_dict.keys())
		print(test_dict.values())
		
		for key,value in test_dict.items():
			print(key,":",value)
==========================================================================
Response:
null

Request ID:
"be57689a-3fe5-11e8-a508-7926ec266421"

Function Logs:
START RequestId: be57689a-3fe5-11e8-a508-7926ec266421 Version: $LATEST
year
2018
mon
04
day
14
2018
NOT FOUND
dict_keys(['year', 'mon', 'day'])
dict_values(['2018', '04', '14'])
year : 2018
mon : 04
day : 14
END RequestId: be57689a-3fe5-11e8-a508-7926ec266421
REPORT RequestId: be57689a-3fe5-11e8-a508-7926ec266421	Duration: 0.58 ms	Billed Duration: 100 ms 	Memory Size: 128 MB	Max Memory Used: 21 MB

セット


def lambda_handler(event, context):
		test_set = {'this','-','is','-','set'}
		print(test_set)
		
		for i in test_set:
			print(i)
		
		test_set.discard('-')
		print(test_set)
		
		test_set_frozon = frozenset({'can','not','add','and','discard'})
		print(test_set_frozon)
==========================================================================
Response:
null

Request ID:
"84c22b12-3fe8-11e8-b96a-af1c8c10d84a"

Function Logs:
START RequestId: 84c22b12-3fe8-11e8-b96a-af1c8c10d84a Version: $LATEST
{'is', 'set', '-', 'this'}
is
set
-
this
{'is', 'set', 'this'}
frozenset({'discard', 'can', 'not', 'add', 'and'})
END RequestId: 84c22b12-3fe8-11e8-b96a-af1c8c10d84a
REPORT RequestId: 84c22b12-3fe8-11e8-b96a-af1c8c10d84a	Duration: 0.43 ms	Billed Duration: 100 ms 	Memory Size: 128 MB	Max Memory Used: 21 MB

スライス


def lambda_handler(event, context):
		test_list = ['this','is','python','slice','set']
		print(test_list[:])
		print(test_list[:4])
		print(test_list[1:])
		print(test_list[::2])
		print(test_list[-1::])
		print(test_list[::-1])
==========================================================================
Response:
null

Request ID:
"1467b80a-3ffc-11e8-8f0b-d9cd7250656b"

Function Logs:
START RequestId: 1467b80a-3ffc-11e8-8f0b-d9cd7250656b Version: $LATEST
['this', 'is', 'python', 'slice', 'set']
['this', 'is', 'python', 'slice']
['is', 'python', 'slice', 'set']
['this', 'python', 'set']
['set']
['set', 'slice', 'python', 'is', 'this']
END RequestId: 1467b80a-3ffc-11e8-8f0b-d9cd7250656b
REPORT RequestId: 1467b80a-3ffc-11e8-8f0b-d9cd7250656b	Duration: 0.40 ms	Billed Duration: 100 ms 	Memory Size: 128 MB	Max Memory Used: 21 MB

インポート

class TestClass:
    def __init__(self):
        print('Create TestClass')
        
    def test_method(self,val):
        print('call test_method')
        print(val)
==========================================================================
import testmod

def lambda_handler(event, context):
		test_class = testmod.TestClass()
		test_class.test_method('1')
==========================================================================
Response:
null

Request ID:
"da5fbad7-3ffe-11e8-99e4-f124716fdbac"

Function Logs:
START RequestId: da5fbad7-3ffe-11e8-99e4-f124716fdbac Version: $LATEST
Create TestClass
call test_method
1
END RequestId: da5fbad7-3ffe-11e8-99e4-f124716fdbac
REPORT RequestId: da5fbad7-3ffe-11e8-99e4-f124716fdbac	Duration: 0.34 ms	Billed Duration: 100 ms 	Memory Size: 128 MB	Max Memory Used: 21 MB

コマンドライン引数
Labmdaではeventを利用する。

def lambda_handler(event, context):
		print(event)
		print(event['msg'])
==========================================================================
Response:
null

Request ID:
"bd98380a-3fff-11e8-b8af-798937c861d6"

Function Logs:
START RequestId: bd98380a-3fff-11e8-b8af-798937c861d6 Version: $LATEST
{'msg': 'Hello World'}
Hello World
END RequestId: bd98380a-3fff-11e8-b8af-798937c861d6
REPORT RequestId: bd98380a-3fff-11e8-b8af-798937c861d6	Duration: 0.38 ms	Billed Duration: 100 ms 	Memory Size: 128 MB	Max Memory Used: 21 MB

パスの結合・連結

import os

def lambda_handler(event, context):
		directory = "/etc/python"
		file = "setting.ini"
		print(os.path.join(directory,file))
		print(os.path.join(directory,"3.6",file))
==========================================================================
Response:
null

Request ID:
"9176f4fd-4000-11e8-aa7d-f996117ce1ed"

Function Logs:
START RequestId: 9176f4fd-4000-11e8-aa7d-f996117ce1ed Version: $LATEST
/etc/python/setting.ini
/etc/python/3.6/setting.ini
END RequestId: 9176f4fd-4000-11e8-aa7d-f996117ce1ed
REPORT RequestId: 9176f4fd-4000-11e8-aa7d-f996117ce1ed	Duration: 0.35 ms	Billed Duration: 100 ms 	Memory Size: 128 MB	Max Memory Used: 21 MB

if文

def lambda_handler(event, context):
		value = 1
		if value == 1:
			print("value is 1")
		elif value == 2:
			print("value is 2")
		elif value == 3:
			pass
		else:
			print("value is not 1,2,3")
==========================================================================
Response:
null

Request ID:
"7c158508-4001-11e8-90fc-11102c6f7f98"

Function Logs:
START RequestId: 7c158508-4001-11e8-90fc-11102c6f7f98 Version: $LATEST
value is 1
END RequestId: 7c158508-4001-11e8-90fc-11102c6f7f98
REPORT RequestId: 7c158508-4001-11e8-90fc-11102c6f7f98	Duration: 0.39 ms	Billed Duration: 100 ms 	Memory Size: 128 MB	Max Memory Used: 21 MB

while文

def lambda_handler(event, context):
		counter = 0
		while counter < 10:
			counter += 1
			print(counter)
		
		# タイムアウトになるまで実行されてエラーメッセージが出力された
		while True:
			print("test")
==========================================================================
Response:
{
  "errorMessage": "2018-04-14T16:39:04.666Z 460c8d7e-4002-11e8-80d8-d3914a20416b Task timed out after 30.01 seconds"
}

Request ID:
"460c8d7e-4002-11e8-80d8-d3914a20416b"

Function Logs:

test
....

continue

def lambda_handler(event, context):
	for num in range(100):
		if num % 10:
			continue
		
		print(num)
==========================================================================
Response:
null

Request ID:
"1504b6c1-4003-11e8-a3ab-67ba43bfb4bb"

Function Logs:
START RequestId: 1504b6c1-4003-11e8-a3ab-67ba43bfb4bb Version: $LATEST
0
10
20
30
40
50
60
70
80
90
END RequestId: 1504b6c1-4003-11e8-a3ab-67ba43bfb4bb
REPORT RequestId: 1504b6c1-4003-11e8-a3ab-67ba43bfb4bb	Duration: 0.40 ms	Billed Duration: 100 ms 	Memory Size: 128 MB	Max Memory Used: 22 MB

例外処理

import sys
import traceback

def lambda_handler(event, context):
	
	def except_test(value1,value2):
		result = 0
		try:
			result = value1 + value2
		except:
			print("計算できません")
			raise
		finally:
			print("計算終了")
	
		return result
	
	print(except_test(200,100))
	
	try:
		print(except_test(200,'100'))
	except:
		print("Error")
==========================================================================
Response:
null

Request ID:
"deb4f5cb-4007-11e8-8bc4-fde8b1a9daf5"

Function Logs:
START RequestId: deb4f5cb-4007-11e8-8bc4-fde8b1a9daf5 Version: $LATEST
計算終了
300
計算できません
計算終了
Error
END RequestId: deb4f5cb-4007-11e8-8bc4-fde8b1a9daf5
REPORT RequestId: deb4f5cb-4007-11e8-8bc4-fde8b1a9daf5	Duration: 0.31 ms	Billed Duration: 100 ms 	Memory Size: 128 MB	Max Memory Used: 21 MB

Docker for Window で稼働しているローカルLinuxコンテナをAWSへ移動させてみた

クライアント端末(Windows 10)必要なソフトをインストールする

Microsoft Windows で AWS Command Line Interface をインストールする
windows10へのdockerインストール
 記事を参考に「Kitematic(カイトマチック)」もインストールした。

Kitematic(カイトマチック)のイメージ



hello-world-nginxのコンテナをローカルで実行する

PS C:\Users\shimizu> docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username (xxxx): xxxx
Password:
Login Succeeded

PS C:\Users\shimizu> docker search hello-world
NAME                                       DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
hello-world                                Hello World! (an example of minimal Dockeriz…   489                 [OK]
kitematic/hello-world-nginx                A light-weight nginx container that demonstr…   97
...

PS C:\Users\shimizu> docker pull kitematic/hello-world-nginx
Using default tag: latest
latest: Pulling from kitematic/hello-world-nginx
77c6c00e8b61: Pull complete
9b55a9cb10b3: Pull complete
e6cdd97ba74d: Pull complete
7fecf1e9de6b: Pull complete
6b75f22d7bea: Pull complete
e8e00fb8479f: Pull complete
69fad424364c: Pull complete
b3ba6e76b671: Pull complete
a956773dd508: Pull complete
26d2b0603932: Pull complete
3cdbb221209e: Pull complete
a3ed95caeb02: Pull complete
Digest: sha256:ec0ca6dcb034916784c988b4f2432716e2e92b995ac606e080c7a54b52b87066
Status: Downloaded newer image for kitematic/hello-world-nginx:latest

PS C:\Users\shimizu> docker images
REPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE
kitematic/hello-world-nginx   latest              03b4557ad7b9        2 years ago         7.91MB

PS C:\Users\shimizu> docker run --name mydocker -d -p 80:80 kitematic/hello-world-nginx
cfbb354fff9823393377d4e2dfe70cb7962d9732ae8cba089f2da07f934c8724

PS C:\Users\shimizu> docker ps -a
CONTAINER ID        IMAGE                         COMMAND             CREATED             STATUS              PORTS                NAMES
cfbb354fff98        kitematic/hello-world-nginx   "sh /start.sh"      34 seconds ago      Up 33 seconds       0.0.0.0:80->80/tcp   mydocker

PS C:\WINDOWS\system32> docker stop mydocker
mydocker

localhostにアクセスするとコンテナが動作していることがわかる。

AWSユーザを作成し、AWS CLIに認識させる

特定IPアドレスにadministrator権限を与えるIAMポリシーを作成し、ユーザに紐づける。
そのユーザでアクセスキーを作成し、AWS CLIに設定する。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AdministratorAccess",
      "Effect": "Allow",
      "Action": "*",
      "Resource": "*"
    },
    {
      "Sid": "SourceIPRestriction",
      "Effect": "Deny",
      "Action": "*",
      "Resource": "*",
      "Condition": {
        "NotIpAddress": {"aws:SourceIp": "x.x.x.x"}
      }
    }
  ]
}
PS C:\Users\shimizu> aws configure
AWS Access Key ID [None]: AKIAxxxxxxxx
AWS Secret Access Key [None]: 9Qexxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Default region name [None]: ap-northeast-1
Default output format [None]: json

Amazon Elastic Container Service (ECS)

ECSはEC2が必要であるが、Fargateを利用するとEC2の管理が不要となる。
Fargateは2018年4月現在東京リージョンにないためECSを利用する。

Elastic Container Registryにローカルのimageを登録する

ECRを作成する。

指示に従ってローカルのimageをECRへ登録する。

PS C:\WINDOWS\system32> aws ecr get-login --no-include-email --region ap-northeast-1
docker login -u AWS -p e...z https://377343199566.dkr.ecr.ap-northeast-1.amazonaws.com
PS C:\WINDOWS\system32> docker login -u AWS -p e...z https://377343199566.dkr.ecr.ap-northeast-1.amazonaws.com
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
Login Succeeded

PS C:\WINDOWS\system32> docker images
REPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE
kitematic/hello-world-nginx   latest              03b4557ad7b9        2 years ago         7.91MB
PS C:\WINDOWS\system32> docker tag kitematic/hello-world-nginx 377343199566.dkr.ecr.ap-northeast-1.amazonaws.com/hello-world-nginx
PS C:\WINDOWS\system32> docker images
REPOSITORY                                                            TAG                 IMAGE ID            CREATED             SIZE
377343199566.dkr.ecr.ap-northeast-1.amazonaws.com/hello-world-nginx   latest              03b4557ad7b9        2 years ago         7.91MB
kitematic/hello-world-nginx                                           latest              03b4557ad7b9        2 years ago         7.91MB

PS C:\WINDOWS\system32> docker push 377343199566.dkr.ecr.ap-northeast-1.amazonaws.com/hello-world-nginx:latest
The push refers to repository [377343199566.dkr.ecr.ap-northeast-1.amazonaws.com/hello-world-nginx]
5f70bf18a086: Pushed
b51acdd3ef48: Pushed
3f47ff454588: Pushed
f19fb69b288a: Pushed
b11278aeb507: Pushed
fb85701f3991: Pushed
15235e629864: Pushed
86882fc1175f: Pushed
9e8c93c7ea7e: Pushed
e66f0ebc2eef: Pushed
6a15a6c08ef6: Pushed
461f75075df2: Pushed
latest: digest: sha256:583f0c9ca89415140fa80f70f8079f5138180a6dda2c3ff3920353b459e061a3 size: 3226

クラスターを作成する






タスク定義とクラスターへのタスク登録





EC2インスタンスにアクセスするとコンテナが動作していることがわかる。

参考URL

【初心者向け】Dockerを速習しよう
初心者か゛伝えるDocker超入門
AWS管理コンソールへのアクセスをIPアドレスで制限したい

Error response from daemon: Get https://registry-1.docker.io/v2/library/hello-world/manifests/latest: unauthorized: incorrect username or password.

以下のエラー時はdocker loginすべし。

PS C:\Users\shimizu> docker run hello-world
Unable to find image 'hello-world:latest' locally
C:\Program Files\Docker\Docker\Resources\bin\docker.exe: Error response from daemon: Get https://registry-1.docker.io/v2/library/hello-world/manifests/latest: unauthorized: incorrect username or password.
See 'C:\Program Files\Docker\Docker\Resources\bin\docker.exe run --help'.

PS C:\Users\shimizu> docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username (xxxx): xxxx
Password:
Login Succeeded

PS C:\Users\shimizu> docker run hello-world
... imageのダウンロードが開始される ...

docker Client.Timeout exceeded while awaiting headers

Windows10 の docker でエラーとなったため対応した。

PS C:\Users\shimizu> docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username (xxxxxxxx):
Password:
Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)

Docker Hubにloginしようとしたら、net/http: request canceled while waiting for connectionを参考に以下画像のように
dockerのDNSサーバに 8.8.8.8 を指定したところ、docker loginが成功するようになった。

ConoHaでKUSANAGIを立ち上げてみた

ConoHaでKUSANAGIを利用してサイトを立ち上げてみた。

ConoHa登録と設定

ConoHaにアクセスする。
[お申し込み]から登録する。

個人情報と支払情報を入力するとコントロールパネル画面に移動する。
左上の[サーバ追加]を選択する。

スペックとOS、ルートパスワードを入力して[追加]する。

約1分ほどで起動した。

KUSANAGI初期設定

KUSANAGI の初期設定の通り実施した。
wp.akat.infoというサイト名としている。

login as: root
root@150.95.155.226's password:

     __ ____  _______ ___    _   _____   __________
    / //_/ / / / ___//   |  / | / /   | / ____/  _/
   / ,< / / / /\__ \/ /| | /  |/ / /| |/ / __ / /
  / /| / /_/ /___/ / ___ |/ /|  / ___ / /_/ // /
 /_/ |_\____//____/_/  |_/_/ |_/_/  |_\____/___/

    Version 8.0.0, Powered by Prime Strategy.

[root@150-95-155-226 ~]# yum --enablerepo=remi,remi-php56 update -y
[root@150-95-155-226 ~]# reboot
...
[root@150-95-155-226 ~]# kusanagi init
...
Search or select timezone:  tokyo                                                                                       Asia/Tokyo
...
Applying Location: Asia/Tokyo.
Select your using language.

1 : English
2 : 日本語

q : quit

Which are you using?: 2

You choose: Japanese
Select your keyboard layout.

1 : English
2 : Japanese

q : quit

2

You choose: Japanese
kusanagi user password using in software update.

Changing password for user kusanagi.
New password:kusanagi
BAD PASSWORD: The password contains the user name in some form
Retype new password:kusanagi
passwd: all authentication tokens updated successfully.

Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:

Your identification has been saved in /root/kusanagi.pem.
Your public key has been saved in /root/kusanagi.pem.pub.

...
KUSANAGI can choose middlewares.
Please tell me your web server option.
1) NGINX(Default)
2) Apache

Which you using?(1):1

You choose: NGINX
use nginx
Done.
Then, Please tell me your application server option.
1) HHVM(Default)
2) PHP7
3) PHP5

Which you using?(1):1

You choose: HHVM
use hhvm
Done.
Then, Please tell me your ruby version.
1) Ruby2.4

Which you using?(1):1
You choose: Ruby2.4
use ruby24
Done.
Then, Please tell me your Database system.
1) MariaDB(Default)
2) PostgreSQL

Which you using?(1):1
...
Enter MySQL root password. Use [a-zA-Z0-9.!#%+_-] 8 characters minimum.
Re-type MySQL root password.
Password has changed.
...
Do you want to install Mroonga ?: [y/N]y
...
Enter password:password
Enter password:password
...
KUSANAGI initialization completed
Done.

[root@150-95-155-226 ~]# kusanagi provision kusanagi
Target directory is /home/kusanagi/kusanagi.
Choose the installation language of WordPress.
1 : en_US
2 : ja

q : quit

Which do you choose?:  2
You choose: ja

Enter hostname(fqdn) for your website. ex) kusanagi.tokyo
wp.akat.info
Re-type hostname(fqdn) for your website.
wp.akat.info

In order to use Let's Encrypt services, you must agree to Let's Encrypt's Term of Services.
If you agree to this TOS, type your email address; if not, hit enter twice.
TOS of Let's Encrypt : https://letsencrypt.org/repository/
shimizu.r.hiroaki@gmail.com
Re-type mail address.
shimizu.r.hiroaki@gmail.com

Enter the name of your database.
wpakatinfo
Re-type database name you create.
wpakatinfo

Enter user name for database wpakatinfo.
wordpress
Re-type user name for database wpakatinfo
wordpress

Enter password for database user 'wordpress'. USE [a-zA-Z0-9.!#%+_-] 8 characters minimum.
Re-type password for database user 'wordpress'.

...

Enabling auto renewal certificate
Provisioning of kusanagi completed. Access wp.akat.info and install WordPress!
Done.

WordPress初期設定

先ほど設定したURLにアクセスすると、WordPressの初期セットアップが開始される。




cesi(Centralized Supervisor Interface)をインストールした

今までpy-supervisord-monitorを利用していたが、
・認証画面がないこと
・グループ化して管理できないこと
から変更した。ポイントのみ記載する。

cesiインストール

# aptitude install sqlite3 python python-flask
# cd /usr/local/src/
# git clone https://github.com/Gamegos/cesi
# cd cesi/
# cp -R cesi /etc/
# sqlite3 /etc/cesi/userinfo.db < userinfo.sql
# vi /etc/cesi.conf
==================================
[node:node1]
username = username
password = password
host = x.x.x.x
port = 9001

[environment:production]
members = node1

[cesi]
database = /etc/cesi/userinfo.db
activity_log = /var/log/cesi-activity.log
host = 127.0.0.1
;port = 5000
;name = what name mean?
==================================
# cd /etc/cesi/
# python web.py

cesiの永続起動

supervisordに以下を追加する。

# vi /etc/supervisor/conf.d/cesi.conf
==================================
[program:cesi]
directory=/etc/cesi
command=python web.py
user=root
group=root
autostart=true
autorestart=true
redirect_stdout=true
redirect_stderr=true
stopasgroup=true
stopsignal=QUIT
stdout_logfile=/var/log/supervisor/%(program_name)s_%(process_num)s.log
stdout_logfile_maxbytes=10MB
stdout_logfile_backups=5
stderr_logfile=/var/log/supervisor/%(program_name)s_%(process_num)s_error.log
process_name=%(process_num)s
stderr_logfile_maxbytes=10MB
stderr_logfile_backups=5
==================================

cesiの80番ポート動作

nginxでリバースプロキシした。configは以下。

location / {
    try_files $uri @cesi;
}

### cesi(supervisor) ###
location @cesi {
    proxy_pass http://127.0.0.1:5000;
    include /etc/nginx/proxy_params;
}

参考URL

GitHub:gamegos/cesi
consul-template & supervisorでプロセスの可視化
nginxでURLでリバースプロキシ先を振り分ける設定

今だからこそ!サーバ仮想化入門に参加した

今だからこそ!サーバ仮想化入門に参加したときの会話内容やメモ。
ESXiをベースにした仮想化の説明があった。

開催企業

・株式会社セラクさん。
・農業向けIoTのみどりクラウドやサーバ構築業務などが得意。

サーバ仮想化について

・日本で流行り始めたのは、Windows98のサポートが終了したとき。仮想化して動かそうというところから。
・仮想化のメリットの1つは、新しいサーバ購入時にシステムの移行が簡単になること。(ドライバがハードウェアに依存しないため)
・仮想化にはハイパーバイザー型とホスト型がある。
・ハイパーバイザー型はリソースを効率よく利用できる。(ハイパーバイザーはOSのようなもの)
 Hyper-VはRootPartitionがある珍しいハイパーバイザー型。
・仮想マシンがCPUを利用する場合は、実CPUにアクセスして処理している。
 そのためESXiの仮想マシンの最大CPU数は、物理サーバのCPU数となる。

ESXiについて(Hyper-Vとの比較)

・ESXiのBSODをPSOD(Purple Screen of Death)と呼ぶ。画面が紫色のため。
・「クローン」「テンプレート」といった仮想マシンの雛形を作る機能(AWSで言うとAMI)はHyper-Vにはないし、ほしい。
・Storage vMotion(Hyper-Vでいう記憶域の移行)はStandard以上のライセンスが必要。(約4種類のライセンス形態らしい)
・DRS(Distributed Resource Scheduler、Microsoftだとクラスターの負荷分散)について、最近ではCPUやメモリだけでなくネットワーク帯域も監視して分散する。
・DRSは予測機能もあり、例えば出社時間の9時頃にアクセスが増えるサーバを予測して負荷分散してくれるらしい。
・DRSはアメリカでは9割くらい利用されているポピュラーな機能とのこと。中小企業が多い日本ではそこまで流行っていない。
・vSphere FTについて、別ホストサーバにサーバの複製を作成し、プライマリサーバがダウンしたらセカンダリを自動的に起動させる。
 ミッションクリティカルの観点で、手動でセカンダリを起動させるHyper-Vレプリカよりも優秀。(ただしHyper-VレプリカはBCP観点機能のため比較したら怒られるかも)
・vSphere FTは便利ではあるがその他機能が利用できなくなる。
・プロアクティブHAは、部分的なホスト障害を予測してvMotionを実施する機能であるが、監視ソフトの設定など敷居が高い。
・vSphere Web Clientは廃止され(Flashを利用しているため)、vSphere Client(HTML5)に切り替わっていく。
・あまり知られていないが、個人アドレスで登録可能なオンラインハンズラボがある!!
 http://labs.hol.vmware.com/

MANABIYAに参加した(1)

MANABIYAに参加した。その時のメモ。

CrossSession – エンジニアにとっていい制度ってなんだろう?-

以下テーマと関連質問にスピーカーの3名が答えていた。
・フレックス制度
・エンジニアの評価制度
・社内エンジニアの教育制度

以下ざっくばらんなメモ。

小賀昌法氏 – 株式会社VOYAGE GROUP執行役員CTO

・チームを縦割りにした際に、技術力を正しく評価できない上司がいるチームもあった。
 評価に納得していないエンジニアがいるという意見が増えはじめた。
 そのため社内で技術力を客観的に判断できるようにするために、技術評価会を立ち上げた。

・評価方法について、1人のエンジニアを別部署から2人のエンジニアが評価する。
 評価に時間をかけ、その結果はレポートとして提出される。
 そのレポートは評価者からの声(よりよい評価をするために他者のレポートを見たい)により全社公開している。

・エンジニアがビジネスチームに調整する際は「どうやったらビジネスが成長するんだっけ」と問いかけが効果的かも。

・ダイレクトコミュニケーションには勝てないと思っているが、リモートワークの環境は整えている。
 悪天候時はリモートワークという選択肢もある。

・ダイレクトコミュニケーションだと構築、運用の中で、当初の目標が変わっていくことが多い。
 リモートワークだとこのブラッシュアップが発生しにくい。

・会社の制度をつくることすらエンジニアリング。

成田一生氏 – クックパッド株式会社執行役CTO

・教育方針は研修ではなく、成長の機会を与えること。
 やるべきこと・やりたいこと・得意なことが重なった場合に人は一番成長する。
 そのため成長を妨げない環境が大切。海外カンファレンスなどを後押しできる環境になっている。

・全社員フレックス制度を利用することが可能で、タイムゾーンなどチームごとに働きやすい時間帯は違うため
 コアタイムはなくなった。ルールはチームごとに決めてもらっている。

・フレックスについては、フェーズによって使い分けても良いかも。
 決めることが多い場合は、全員いる時間帯が長い方が良く、開発フェーズは各々が集中できる時間帯に出社すればよい。
 答えはないので自分たちで考えていく必要がある。

・リモートよりは会社に来てほしい。
 ただしリモートでやれることはリモートでやったほうが効率的ではある。

・正しく成果を定量化(生産性を数値化する)することは幻想だと考えている。

・現状の評価方法は部長と技術リーダーがビジネス面、技術面から評価している。
 評価の頻度をあげるという取り組みをしている。(年2回だと被評価者も忘れる。)

・評価は公開していない。もしかしたら本人にすら評価結果を見せないほうがよいのかもしれない。
 評価の透明性は、馴れ合いを生む可能性がある。

・例えば会社が勉強会に行けというのではなく、若い人たちは勝手に行くので、支援できる制度があったほうがよい。
 自分が何をすれば成長できるかは自分で考えるべし。ただそう言うからには、支援する。という考え方。

・新しく会社を作る場合は、昇給も降給も考えたほうが良い。降給は、強いメッセージが含まれている可能性が高い。
 自分の会社の場合は、次に行ったほうが良いよという意味が強く含まれている。

・挑戦したい人の足を引っ張らない制度が一番良い制度ではないか。

・家賃補助の範囲を0.5km広げることで、2口コンロの地域に住みやすくなって
 「毎日の料理を楽しみにする」というミッションに近づいたと感じている。

梶原賢祐氏 – 株式会社メルカリ

・学生のレベルを考えると一律の初任給はおかしいという流れからMergradsを導入している。

・ストックオプションなどが昇給以外のモチベーションになりうるかも。
 仕事のやりがいが一番のモチベーション。

感想

・どうやったら働きやすくなるかの、答えの一つがリモートワークなのかも。
・どの企業もエンジニアの成果を定量化するよりも、納得感を求めている模様。
・多様性と評価の定量化は矛盾している言葉だなと。
・リモートワークよりもオフィスを魅力的なものにしようという考え方もある。
・今後は働きがいよりはともかく、働きやすさにも注力しなければならない。

JAWS DAYS 2018 に参加した (5)

AWSセキュリティ事始め~基礎からはじめてクラウドセキュリティの恩恵を受ける~

クラウドを利用しないことについて、セキュリティ的に不安という声

・クラウドよりもオンプレミスがセキュリティ面で優れている理由を上司に聞いてみよう。
・最近、日本法の適用も可能になった。
https://aws.amazon.com/jp/blogs/news/how-to-change-aws-ca-by-artifact/

いくつかのマネージメントサービスの紹介する。
これらを単独や組み合わせて使っていくことでセキュリティを向上させるべし。

Amazon Inspector

・1エージェント1評価0.30USDから
・各サーバで月1回定期スキャンしても良いかも

WAFマネージメントルール

・常に最新のルールにメンテナンスされる

AWS Shield

・L3/L4レベルのDDoSは無料で防がれている
・なぜAWSがDDoSに強いか
 https://www.slideshare.net/AmazonWebServicesJapan/aws-shield-managed-ddos-protection

GuardDuty

・機械学習で怪しい通信を検知する
・機械学習には膨大なデータが必要となるが、一企業で用意することは難しい。
 AWSの膨大なデータの学習データを利用することができる。

Macie

・S3に保存されているデータを機械学習で自動的に発見するサービス
 S3の漏洩などに早めに気が付けるかも

JAWS DAYS 2018 に参加した (4)

Amazon Rekognitionを使って親御さんの写真探しのお手伝いができた話

はいチーズ!とは

全国5000団体が利用する写真販売サービス
写真販売がいつでもどこでも気楽に可能となる。

顔検索機能

ミッションは、園児一人一人が主人公の写真を撮る。
大規模園であると10000の写真の中から子供を見つけないといけない。
親は忙しいため、顔検索機能を実現しようとした。

これまで顔認識製品を検証してきたが、速い、安い、高精度がなかなか見つからない。
エンジンの自社開発は技術的に難しい。
あきらめかけていた時にAmazon Rekognitionを知った。

Amazon Rekognition

学習済みのAIが3種類。
Lex・Polly・Rekoginition(画像の物体やシーン、顔の検出)
Rekoginitionに顔と顔が似ているかどうかの判定する機能があった。

主に利用するAPIは3つ。
CreateCollection:顔コレクションを作成
IndexFaces:顔メタデータ(顔の特徴を表すベクトル)を顔コレクションに追加
SearchFacesByImage:類似顔画像を探す

優位点

他社製品と比較して、Rekognitionが優位なポイント
・S3上の画像を処理可能
・顔メタデータ作成がスケール可能
・顔メタデータ保持コストが安い
・精度が高い
・検索が速い
 数万件のデータから1,2秒で検索可能

問題点

導入当時は問題があった。
・東京リージョンになかった(2月28日より利用できるように)
・1画像から同時検出できる顔の数が上限15である問題(当時)
 そのため集合写真が扱えなかったため、画像を分割して探すような処理を入れていた。
 ⇒人混みモードがリリースされ、1画像あたり100個検出されるようになった。

利用されるまで

ベータリリースで一部の顧客へ利用してもらった。
効果がなかなか現れず、使用率が低い時期が続いた。

「画像をアップロードが手間なのではないか」
⇒注文履歴を分析して、必要な子供の顔を取得して、オススメ写真として表示するようにしたところ
 ユーザの使用率が上がり、コンバージョン率がアップした。