[コンテナ再入門]Ubuntu 18.04 に Docker CE をインストールする

今さらもいいところだが、コンテナを活用した開発フローやアーキテクチャについて基礎から再入門している。 Dockerについては、過去にもちょこちょこ触ってみたり社内のサーバで使ってみたりはしていたものの、ちゃんと実運用できるレベルで理解できていなかったので、勧められた以下の書籍で改めて勉強しなおしている。

Docker/Kubernetes 実践コンテナ開発入門

Docker/Kubernetes 実践コンテナ開発入門

せっかくなので勉強のログをメモしておこうと思う。

Ubuntu 18.04 に Docker CE をインストールする

基本的に公式ドキュメントの「Install using the repository」の手順をなぞるだけ。 docs.docker.com

前準備

  • 古いバージョンのDockerをアンインストールする
$ sudo apt-get remove docker docker-engine docker.io containerd runc

レポジトリを設定する

  • まずは apt パッケージのインデックスを更新する
$ sudo apt update
  • 依存するパッケージをインストールする
$ sudo apt install  apt-transport-https   ca-certificates   curl  gnupg-agent   software-properties-common
  • GPG key の登録
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
  • stable(安定版) のレポジトリをセットアップする。( nightly や test といった引数を最後のstable の後に追加すればそれらのチャンネルもセットアップされる模様)
$ sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

Docker CEをインストールする

  • レポジトリを追加したので、もう一度 apt パッケージのインデックスを更新する
$ sudo apt update
  • 最新版の Docker CEをインストールする
$ sudo apt install docker-ce docker-ce-cli containerd.io

Dockerを一般ユーザで実行できるようにする

Docker のコマンドを一般ユーザで実行すると権限が足らずエラーが発生する。

$ docker info
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.39/info: dial unix /var/run/docker.sock: connect: permission denied

これを回避するには、毎回sudoをつけてroot権限で実行するほか、Dockerを実行したい一般ユーザを docker グループに所属させれば良い (と、公式ドキュメントに普通に書いてあった)。

If you would like to use Docker as a non-root user, you should now consider adding your user to the “docker” group with something like:
sudo usermod -aG docker your-user

結果確認

バージョン 18.09.3 がインストールされた。

$ docker version
Client:
 Version:           18.09.3
 API version:       1.39
 Go version:        go1.10.8
 Git commit:        774a1f4
 Built:             Thu Feb 28 06:53:11 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          18.09.3
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.8
  Git commit:       774a1f4
  Built:            Thu Feb 28 05:59:55 2019
  OS/Arch:          linux/amd64
  Experimental:     false

Proxyの設定

docs.docker.com

公式ドキュメントを参考に、dockerd (Daemon) にProxyを設定する場合の例。
上記手順でUbuntuにDockerをインストールした場合、systemd でDaemon化されているため、service設定を更新する。

$ sudo mkdir /lib/systemd/system/docker.service.d
$ sudo vi /lib/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment="HTTPS_PROXY=http://your.proxy.url:port/"

Proxy設定ファイルを作ったらdockerd を再起動して読み込ませる。

$ sudo systemctl daemon-reload
$ sudo systemctl restart docker.service

Ubuntu 18.04 の日本語版デスクトップ環境を Vagrant + VirtualBox で作成する

Ubuntu 14.04 LTS のサポート期間が2019年4月末で切れるため、それを利用しているプロジェクトではアップデート計画を立てているのですが、いくつかのプロジェクトでは Ubuntu 16.04 LTS を飛ばして Ubuntu 18.04 LTS にジャンプアップする*1可能性が出てきたため、とりあえず Ubuntu 18.04 LTS の開発環境を準備していくことにしました。

普通に開発環境として使うだけであれば、Ubuntu Japanese Team が提供してくださっている 日本語 Remixバージョンを直にインストールするなりVirtualBoxなどにインストールするなりするのが一番はやいし確実なのですが、Windows/Mac/Linux を母艦とする環境間で開発環境のマシンイメージを共有したり移動したりしたいという要件があったりなかったりなので、Vagrant で管理できるようにします。(が、結構手作業が残ってしまったのであまり意味がn...)

前提

母艦となるマシンへのVirtualBoxVagrant のインストールについては完了しているものとします。
まだインストールが完了していない場合は、以下の公式サイトからダウンロード・インストールしてください。 (Windows/Mac/Ubuntu など母艦の環境によってインストールするパッケージファイルや手順が異なるので細かいことは省略します)

最新版にはバグがあったり、VagrantVirtualBox のバージョンの組み合わせによってはうまく動かないことがあったりするので、そういった場合は最新版にこだわらず古いバージョンをインストールし直して確認してみてください。

母艦の環境

以下の手順は私の手元の以下の環境下で動作確認済みです。

手順

流れとしては、

  • Box を選ぶ
  • Vagrantfile を作成する
  • 起動する
  • 日本語環境化を仕上げる

となります。

Boxを選ぶ

Ubuntuのboxを探すのであれば、以下のレポジトリ(?)から探すのが良いでしょう。

今回は chef社公式の bento/ubuntu-18.04 を使います。
https://app.vagrantup.com/bento/boxes/ubuntu-18.04

Vagrantfileを作成する

Vagrantを実行する母艦にて Vagrantfileを作成します。
肝は日本語化のための仕込みをプロビジョニングスクリプトに入れ込んでいる点で、その他は特に変わった内容はありません。 ホスト名の他、メモリの搭載量やネットワークの設定、Proxy設定の有無などは母艦の環境などによっても異なるためこの記事では省略しています。

# -*- mode: ruby -*-
# vi: set ft=ruby :

# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.
Vagrant.configure("2") do |config|
  config.vm.box = "bento/ubuntu-18.04"
  config.vm.provider :virtualbox do |vb|
    vb.gui = true  # デスクトップ環境を使うので、GUIを有効にする
    vb.customize [
      "modifyvm", :id,
      "--vram", "256",
      "--clipboard", "bidirectional",
      "--accelerate3d", "on",
      "--hwvirtex", "on",
      "--nestedpaging", "on",
      "--largepages", "on",
      "--ioapic", "on",
      "--pae", "on",
      "--paravirtprovider", "kvm",
    ]
  end

  # 初期構築スクリプト
  config.vm.provision :shell, :inline => <<-EOS
    # 日本語化 https://www.ubuntulinux.jp/japanese のための準備
    wget -q https://www.ubuntulinux.jp/ubuntu-ja-archive-keyring.gpg -O- | sudo apt-key add -
    wget -q https://www.ubuntulinux.jp/ubuntu-jp-ppa-keyring.gpg -O- | sudo apt-key add -
    sudo wget https://www.ubuntulinux.jp/sources.list.d/bionic.list -O /etc/apt/sources.list.d/ubuntu-ja.list
    sudo apt update -y
    sudo apt-get upgrade -y
    sudo apt-get install ubuntu-desktop -y
    sudo apt-get install ubuntu-defaults-ja -y

    # タイムゾーンを日本時間に変更
    sudo timedatectl set-timezone Asia/Tokyo
    # デフォルトのエディタを nano から vim に変更
    sudo update-alternatives --set editor $(update-alternatives --list editor | grep 'vim.basic')

EOS
end

起動する

Vagrantfile を作成したディレクトリで vagrant up コマンドを実行します。
初回は box のダウンロードやデスクトップ環境のインストールなどがあるためものすごく時間がかかりますが、しばらく待てば終わりますので、同じディレクトリで vagrant reload コマンドを実行し仮想ホストを再起動します。
上手く行けばここまでで Ubuntu 18.04 の仮想ホストの GUI が起動したはずです(ただし英語)。
vagrantユーザ(初期PW:vagrant) でログインし、vagrantユーザのパスワードを変更するなり、自分用のログインアカウントを作成しておくなりしてください。

日本語環境化を仕上げる

ここまでは母艦で作業してきましたが、ここからは起動した仮想ホストのGUIで操作を行います。
Vagrantfile 内の初期構築スクリプトにて、Ubuntu Japanese Team が提供する日本語用パッケージをインストールするところ(https://www.ubuntulinux.jp/japanese)までは完了していますので、あとはそれらを適用・有効化していくだけです。

日本語化に関してはこちらの記事を大変参考にさせていただきました。ありがとうございます。

kledgeb.blogspot.com

  • 使用する言語を日本語に設定する
    • デスクトップ画面左上の「Activities」をクリックし「Language Support」を検索して起動します。
    • 「The language support is not installed completely」というダイアログが表示されるので、「Install」を押してインストールします(root権限が必要なため、パスワードの入力を求められます)。
    • インストールが完了したら、「Language Support」のダイアログが表示されているので、表示されている「Language」タブの「Language for menus and windows:」のリストから「日本語」を探してリストの一番上になるようにドラッグします。
    • 「Apply System-Wide」ボタンを押してシステム全体に適用します(root権限が必要なため、パスワードの入力を求められます)。
    • 「Keyboard input method system:」が「IBus」になっていることを確認してください。
    • 続いて「Regional Formats」タブに移り、「Display numbers, dates currency amounts in the usual for:」を「日本語」に変更したら、「Apply System-Wide」ボタンを押してシステム全体に適用します(root権限が必要なため、パスワードの入力を求められます)。
  • 言語設定の確認と入力ソース(キーボードレイアウトと言語)の追加
    • デスクトップ画面左上の「Activities」をクリックし「Settings」を検索して起動します。
    • メニューから「Region & Language」を選択します。
    • 「Language」が「Japanese」、「Formats」が「Japan」になっていることを確認してください。
      • もしそうなっていなければ、それぞれの項目をクリックして選択肢から日本に該当するものを選択してください
    • 「Input Sources」の「+」ボタンを押して「Japanese」->「Japanese (Mozc)」を追加してください。
  • 日本語入力できるようにする
    • デスクトップ画面の右上にある言語インジケーター(おそらく「en▼」と表示されている)をクリックし、表示されるメニューから(Japanese (Mozc))を選択してください。
  • ここまで来たら、一度仮想ホストのOSを再起動する
    • 起動すると、「Downloads」「Desktop」などデフォルトで作成されるホームディレクトリ下のディレクトリ名を日本語に更新するかを尋ねるダイアログが表示されますが、更新しない(「次回から表示しない」にチェック&「古い名前のままにする」を選択)ことを推奨します。
    • かなと英数の切り替えは「半角/全角」ボタンで行います。

これで一通り表示が日本語化され、日本語入力が可能な状態になっているはずです。

まとめ

  • Ubuntu 18.04 LTS をVagrant + VirtualBox で作成する手順をまとめました
  • が、日本語化する設定が自動化できていないのでイマイチ

*1:標準化のために Ubuntu 14.04 LTS で開発しているものの、まだPoC段階で一般公開までにはまだまだ時間がかかりそうなプロジェクトなど。普通に一般公開しているサービスではこんな冒険はできません...

AWS DevDay Tokyo 2018 Software Design/Serverless & Mobile トラック+α まとめ

(2018/11/12 更新) Amazon Web Services ブログで資料が公開されましたので、末尾にリンクを追記しました。

AWS DevDay Tokyo 2018 が10/29-11/2 の5日間に渡って行われました。 私は10/31(水)のみ現地で参加し、11/1(木),2(金) はライブストリーミングでちょこちょこ参加しました。 aws.amazon.com

非常に内容が濃く、素晴らしいイベントでしたので、10/31(水)のSoftware DesignトラックとServerless & Mobile トラックについて自分の聴講メモと公開された資料をまとめて残したいと思います。

10/31(水) Software Design トラック

セキュア開発プロセスアジャイル開発に適用するには

講師: 徳丸 浩 さん(EGセキュアソリューションズ株式会社代表、独立行政法人情報処理推進機構IPA)非常勤研究員)

アジャイルのような段階的に機能を作り込んだり追加していったりするプロセスにおいて、セキュリティ施策をどう組み込んでいくか現実的な落とし所を考えるセッションでした。

聴講メモ

  • アジャイル開発とセキュアプログラミングは相性が悪い?
  • セキュリティ施策を分類する
    • セキュリティ方針決定系や教育系、予算確保は1回のみ
    • それ以外は繰り返す → 自動化したい
  • セキュリティ施策の優先度
    • エアバッグのない自動車は販売できる(法令上は)が、ブレーキのない自動車は販売できない
    • ログイン機能のないWebサイトはリリースできないが、二要素認証がないWebサイトはリリースできる
  • アジャイル型開発での脆弱性対処
  • 脆弱性診断をインクリメンタルに実施する
    • アジャイル開発の場合は新規にコミットしたソースコードが対象になる
    • リリースごとにサイト全体の診断をするのは現実的ではない
    • が、リグレッションの可能性もある
    • → 汎用の脆弱性診断ツールを用いる(OWASP ZAPのAPIを活用)
    • 汎用のテストツールで脆弱性診断できないか?
    • 継続的テストに特化したツール・サービスを用いる
    • ソースコード診断ツールを用いる
      • 高価
      • 誤検知が多い
  • プラットフォームのセキュリティ
    • OpenVASやNessusで自動化
  • デモ: OWASP ZAP で脆弱性診断したときのURLをPHPUnitで叩いて単体テスト脆弱性診断を組み込む
  • が、ツールによる診断では十分とは言えない

ドメインモデリングの始め方

講師: 加藤 潤一 さん(ChatWork株式会社) speakerdeck.com

あなたの推しテクをもっと伝えるプレゼンテーション術

講師: 長沢 智治 さん(エバンジェリズム研究所 代表) speakerdeck.com

The Twelve-Factor App で考える AWS のサービス開発

講師: 千葉 悠貴 さん、畑 史彦 さん(アマゾン ウェブ サービス ジャパン株式会社 ソリューションアーキテクト)

外部に依存したコードもテストで駆動する

講師: 和田 卓人 さん(タワーズ・クエスト株式会社 取締役社長、プログラマテスト駆動開発者)

Alexa Skillのコードを元にTDDでコードを改善していくセッションでした。

speakerdeck.com

聴講メモ

  • Alexa Skillのフレームワークに依存している
  • 網羅性はいらない。脳天気な正常系(Happy Path)でいいので動くテストがほしい
    • alexa-skill-test-framework
      • 高機能かつ抽象化されており、かゆいところに手が届きにくい
      • Easy指向
    • aws-lambda-mock-context
      • 機能が少なく、レイヤが薄い
      • Simple指向
    • 今回はaws-lambda-mock-contextを採用
  • ランダムな応答を返すもののテストはどうやるか?
    • レガシーコードのジレンマ
    • 接合部(Seam)を作る
    • 固定値を外からねじ込めるように書き換える
  • テストで品質は良くならない
    • テストは品質がよくなるためのきっかけ
  • モデルを分離する
    • Lambdaレベルのテストをグリーンに保ちながら、ロジックをモデルクラスに引き剥がしていく
    • モデルクラスはテスト駆動開発で新規開発する
  • 環境依存を減らす
  • アーキテクチャを定める
    • 安定依存の原則 … 変化しやすいものに依存しない
    • 情報 を扱うレイヤと 事実 を扱うレイヤを分ける

日経電子版におけるPWA活用事例

講師:安田 竜 さん (株式会社日本経済新聞社

実践!リーンなプロダクト開発 ~リーンでアジャイルなUI/UXデザイン検証~

講師: 奥原 拓也 さん (dely 株式会社) speakerdeck.com

10/31(水) Serverless & Mobile トラック

浸透するサーバーレス、実例に見るユースケースと実装パターン

講師: 杉 達也 さん (アマゾン ウェブ サービス ジャパン株式会社 事業開発マネージャ (サーバーレス担当))

Serverless Application Security on AWS

講師: 桐山 隼人 さん(アマゾン ウェブ サービス ジャパン株式会社 技術統括本部 ソリューションアーキテクト)

AWS Well-Architected Framework の Serverless Applications Lens を読み解くセッションでした。

聴講メモ

  • セキュリティの柱
  • IDとアクセス管理
    • APIアクセスの認証認可をどのようにしていますか
      • Cognito User Pools Authorizer
      • AWS IAM Authorization
      • Lambda Authorizers
    • LambdaファンクションがアクセスできるAWSサービスをどのように保護していますか
  • 発見適当性の考慮事項
    • サーバーレスアプリケーションのログをどのように分析していますか
      • アプリケーションログはCloudWatch Logsをつかう、とか
      • AWSサービスAPI呼び出しは CloudTrailをつかう、とか
      • ログに機微情報が含まれる可能性、とか
    • アプリケーションの依存関係や脆弱性をどのように監視していますか
  • インフラストラクチャー保護の考慮事項
    • LambdaファンクションがアクセスできるVPC内のAWSリソースに関して、どのようにネットワーク境界を保護していますか
      • ネットワークACLやセキュリティグループによるネットワーク境界保護
  • データ保護
    • サーバーレスアプリケーション内の機微な情報をどのように保護していますか
    • どのように入力値チェックをしますか
      • 通信データの暗号化
      • クライアントサイド暗号化
      • 保護すべきデータの外部化
        • AWS SystemManager Parameter Store
        • AWS Secrets Manager
        • Secrets Manager を使える場合はSecrets Managerを使うのがオススメ
  • インシデントレスポンスの考慮事項

開発者におくるサーバーレスモニタリング

講師: 小梁川 貴史 さん(アマゾン ウェブ サービス ジャパン株式会社 技術統括本部 ソリューションアーキテクト)

AWS Lambdaを中心にmetricsの意味や監視ポイントを解説するセッションでした。

聴講メモ

  • 自分が作ったものがどう使われているのか・動いているのかを把握できることが重要
  • AWS Lambdaの起動パターン
    • イベントベース
      • API Gateway
      • S3
      • など
      • イベント数:Lambda = n:n
    • ストリームベース
      • Kinesis Streams
      • DynamoDB Streams
      • ストリームのシャード数:Lambda = 1:1 -シャードの追加に自動追従 SQSベース
      • SQS
      • log polling型、Queueの数に応じてLambda起動数がAutoScaling
  • duration の意味
    • ENIの作成~ランタイム起動・初期化 までの時間はdurationに含まれない
  • SQS起動における注意
    • メッセージ数 > 処理量 の傾向が続いて処理が追いつかない状況になるとコンカレンシーリミットまでスケールする
    • コンカレンシーリミットを設定していないと、アカウントの上限までスケールして他のLambdaに影響を与えてしまう
  • AWS X-Ray
  • CloudWatch Logs filter pattern
    • 大文字・小文字は区別される
    • 正規表現は利用できない
    • 簡単なパターンマッチのみ利用可能
    • 検索しやすいログ設定を!
    • Amazon Elasticsearchに投げたりLambda経由でS3に投げて解析したりとか

ZOZOTOWN の膨大な画像ファイルを移行したときの過程の話(オンプレミスからクラウドへ)

講師: 柴田 翔 さん(株式会社ZOZOテクノロジーズ《旧:株式会社スタートトゥデイテクノロジーズ》ZOZOバックエンド部ネットワークブロック)

数億点の画像ファイルをS3に移行した事例についてのセッションでした。

聴講メモ

  • 移行背景
    • 容量不足
      • ZOZOUSED(中古=同じ商品が無い)のサービスが好調
      • 画像数億点 約60TB (オリジナル画像+リサイズ画像)
    • 監視したくない
      • 逼迫の恐怖
      • 画像アップロードの量が多い
        • オンプレミス画像サーバが耐えられない
      • オンプレミスの保守
      • 夜間アラート
        • 夜間アラートの60%が画像サーバ関連
    • スケーラビリティが必要
      • サービス拡大による画像アップロード数の増加
  • なぜS3なのか
    • 高い耐久性、容量制限がない
    • 公開ナレッジが多い
    • AWS SAの手厚い技術的サポート
  • 移行する上で重要視したポイント
    • 運用コスト削減のため、なるべくマネージド
    • 画像データの容量を気にしなくていい
    • 短期間での移行のため、開発対象を少なくし、テスト工数も削減したい
  • 画像移行パターン
    • パターン1:Snowballでの移行 → ボツ
      • 転送速度の計算
        • 約60TB
        • 平均オブジェクトサイズ 128KB
        • 転送速度 10MB/s
        • → 72日
      • 暗号化に時間がかかる
      • 出す・入れる で2倍
      • 移行用クライアントが必要
      • オフライン同期のため、差分同期が面倒
    • パターン2:S3に直接PUT → ボツ
      • 転送速度を計算
        • 転送速度 42MB/s(バッチ3並列の実測値)
        • → 17.3日
      • 転送速度4倍
      • Snowballの手配が不要に
    • パターン3:オリジン画像のみS3直接PUT、リサイズはLambda → 採用
      • 転送速度を計算
        • 約30TB(オリジナル画像のみ)
        • 転送速度 42MB/s(バッチ3並列の実測値)
        • → 8.6日
      • Snowballの8倍、全画像PUTの2倍 リサイズ用オンプレサーバ不要に
  • 移行後の構成
    • 1次受けバケット → Lambda → オリジナル画像、リサイズ画像バケット
    • オリジナル画像のコピーとリサイズ処理が終わったら1次受けバケットから画像を消す
    • 破損した画像ファイルや何らかの事情でLambdaが起動しなかった画像ファイルが1次受けバケットに残る
  • ポイント
    • Lambdaの修正の楽さ
      • 属人化が排除できた
    • 公開ナレッジの多さ
    • 画像変換用サーバが不要に
  • 移行過程で発生した問題
    • S3バケットの制限
      • S3 GET制限とPrefix
        • 800GET/sec
      • 現サーバへのリクエスト数(オリジナル画像+リサイズ画像)
        • 795GET/sec
      • バケットを分けてGET数を分散
      • S3 GET/PUTのパフォーマンス向上 のリリース
        • → クリア

クックパッドの動画事業での AppSync 活用事例 - Firebaseからの移行 -

講師: 渡辺 慎也 さん (メディアプロダクト開発部部長 CookpadTV株式会社取締役 CTO)

AppSyncをMicrservicesの一部として組み込んで使う事例のセッションでした。 speakerdeck.com

聴講メモ

  • コメントやハートの実装
    • Firebase Realtime Databaseを使っていた
    • 当時はまだAppSyncが東京リージョンに来ていなかった
  • 移行のモチベーション
    • データをAWSとFirebaseに分散させたくなかった
    • AppSyncはDynamoDBやLambdaなどコントローラブルな点が多い
  • WRITEはサーバー経由、READは直接
    • コメントはNGワードのフィルタリングなどをかけたいので
    • スタンプはポイントが必要なのでチェックが要る
  • AppSyncのボトルネック
    • Cognitoの制限
      • Cognitoの GetCredentialsForIdentityの同時実行数
      • API Keyを利用すれば回避できる
    • Mutation per second制限
    • アプリへのファンアウト数
      • 細かいメッセージをたくさん飛ばすより、ある程度バッファリングした方が良い
  • Service Mesh
    • SDK実装ではなくSidecar Proxy(Envoy)経由で通信する
  • cookpadTV message and MBR
    • メッセージ送信サービスはGoで実装
    • MBW ... Message Buffer Writerの略
      • AppSyncへの mutations per seconds を軽減させるため
      • 47分の放送時間中にハートが150万回送信された
        • 単純計算すると平均 532rps
      • 設計方針
        • コメントの反映は送らせない
        • 順序保証は行わない
        • 最悪データのロストを許容
          • 永続化は別で行っている
          • リアルタイ性がないコメントはあまり意味がない
          • ストレージ不要でオンメモリ処理が可能
        • Subscribeで流れてくるメッセージは番組毎
  • AppSync Shcema
    • 複数 Subscriptions
      • コメント、ハート、スタンプ、ユーザ数 はそれぞれ別 Subscription
    • 受信データは配列
      • サーバ側でバッファリングできるように
  • AppSync Resolver
    • 当初DynamoDB Data sourceを使っていたがwriteがボトルネック
    • 結局 Data source type None にした
  • サーバサイドからAppSyncに書き込むことが想定されてないのでSDKなどがなく、自前で書いた(Go)

Serverlessを極めるためにDynamoDBデータモデリングを極めよう

講師: 照井 将士 さん (株式会社サーバーワークス Solution Specialist)

AWS上のServerlessアプリケーションのデータストア層として採用されることが多いDynamoDBにおけるモデル設計についてのセッションでした。 speakerdeck.com

  • DynamoDB Best Practicesを読もう
  • Partition Keyのハッシュでパーティションが分散される
    • なので、Partition Keyに連番を振ってもあまり意味がない
    • 論理的に一意であればOK
  • DynamoDB内のデータは Partition Keyで分散した中で Sort Keyで整列 しているというイメージを持つ
  • 結果整合性 って大丈夫なの?
    • RDBでもリードレプリカから読み込む場合は結果整合性なので、変わらない
  • DynamoDBの設計アプローチとRDBの設計アプローチ
    • RDB
    • DynamoDB
      • スキーマレス
      • 非正規化
      • まずアクセス(使われ方)を考えて、それに合わせたデータを作る
      • アプリケーションとデータモデルは同時に設計する
  • ACIDトランザクションが無い問題
    • ACIDとは 原子性・一貫性・独立性・永続性
    • DynamoDBの場合、非正規化して1つの実体について1つのアイテムに収める
    • 1アイテムの更新はアトミックであり原子性は保たれる
  • 非正規化してあるので読み込みツラい問題
    • CQRS (Command Query Responsibility Segregation)
    • 書き込むデータと読み込むデータは同じである必要は無い
      • 結果整合性を受け入れて非同期で読み込みデータを作る
    • Command の完了をもってQuery用のデータを作る
      • マテビュー的な
    • とはいえ、複数の実体にまたがるトランザクションはできない

その他

ライブストリーミングで以下のセッションを聴講しました。
どれも素晴らしかったですが、DynamDB 関連のセッションが特に最高でした。

Amazon DynamoDB Advanced Design Pattern

講師: 江川 大地 さん(アマゾン ウェブ サービス ジャパン株式会社 技術統括本部 ソリューションアーキテクト)

DynamoDBの設計についてのセッションでした。

www.slideshare.net

おそらく昨年の re:Inventの以下↓ のセッションが基になっているのだと思うのですが、元のセッションも素晴らしかったですし、説明の順序が改善されて日本語になった本セッションは今まで聞いたDynamoDBの説明の中で一番わかりやすいと感じました。

www.youtube.com

DynamoDB Backed なテレコムコアシステムを構築・運用してる話

講師: 安川 健太 さん(株式会社ソラコム CTO)

あのSORACOMのバックエンドでDynamoDBをどのように使っているかのセッションでした。
複数の値を一度に更新したい場合の対処法 で紹介されていた方法は初見で、直接情報をアイテムに残すことが難しければデータ(事実)を記録してあとで必要な情報が生成できるようにすればよい、と理解しました。

www.slideshare.net

マイクロサービス時代の認証と認可

講師: 都元 ダイスケ さん(クラスメソッド株式会社 事業開発部 シニアシステムアーキテクト

認証と認可とは何か、から始まってよくあるWebシステムで必要とされる認証・認可について考えるセッションでした。
後半Twitchの中継が止まってしまって聞けなかったのが残念でした…

www.slideshare.net

さいごに

時間がかぶった関係で観られなかったセッションも多かったので、動画の公開が楽しみです!

Amazon Web Services ブログで公開された資料

aws.amazon.com

aws.amazon.com

Mackerel の1分粒度メトリックデータをCSVでバックアップする

私が現在運用しているシステムではシステム・サービス監視やキャパシティ管理のツールとして Mackerel https://mackerel.io/ というSaaS型のサービスを使っています。 各サーバのCPU利用率やメモリ利用率といったホストメトリック情報はもちろん、特定のサーバには紐付かない情報、例えばサービス利用ユーザ数やお問い合わせの件数といった値もサービスメトリックとしてMackerelに投稿し、Mackerel上でグラフ化したりしきい値を設定してアラートを上げたりできるので便利です。

サーバについてはパブリッククラウド上でインスタンスがぽこぽこ入れ替わるので、ホストメトリックを永続的に保管したい要求はあまりないのですが、ユーザ数の推移といったサービス運営状況に関わるデータは Mackerelのデータ保持期間( 2018年10月13日現在では460日間) を超えた長期間分のデータを確認したい場合があるため、常にMackerelと自分たちで管理できる他のDBの両方にデータを登録し続けるか、データを登録するのはMackerelのみにして定期的にMackerelからデータをバックアップするか、といった対処が必要になります。

今回は後者の、Mackerelから定期的にメトリックデータをバックアップする方法について調べてみました。 といっても、サービスメトリックもホストメトリックもデータを取得するためのAPIが公開されていますので、それをいかに効率よく叩くかだけを考えればOKです。

mackerel.io mackerel.io

APIドキュメントを参考にパラメータを変えながらAPIを叩いていると、from と to で指定するデータ取得対象期間の長さによって取得できるメトリックデータの粒度が変わることを発見しました。

例えば from = 1538319600 (epoch秒。日本時間で2018/10/01 00:00:00) 、to = 1538362800 (日本時間で2018/10/01 12:00:00) として12時間分のデータを取得した場合は60秒間隔のメトリック値が返ってきますが、from = 1538319600 (日本時間で2018/10/01 00:00:00) 、to = 1538406000 (日本時間で2018/10/02 00:00:00) として24時間分のデータを取得した場合は300秒間隔のメトリック値(おそらく60秒間隔のメトリック値5個分の平均値) が返ってきていました。1年前から今日までの1年間分データを取得した場合は86,400秒間隔、つまり1日間隔のメトリック値が返ってきました。

そこでもう少しいろいろ試して調べてみたところ、どうもサービスメトリック、ホストメトリック共に、以下のような仕様になっているようでした。

取得できるメトリックデータの粒度(秒) 最大データ取得期間(秒) 備考
60 72,239 1,204分(≒20時間強)未満までは1分粒度のデータを返す。
300 599,999 1,204分以上 10,000分(≒7日間弱)未満では5分平均のデータを返す。
600 866,999 10,000分以上 14,450分(≒10日間強)未満では10分平均のデータを返す。
3,600 7,199,999 14,450分以上 120,000分(≒2,000時間≒12週間弱)未満では1時間平均のデータを返す。
7,200 14,399,999 120,000分以上 240,000分(≒4,000時間≒約5.5ヶ月間)未満では2時間平均のデータを返す。
14,400 20,807,999 240,000分以上 346,800分(=5,780時間≒約8ヶ月間)未満では4時間平均のデータを返す。
86,400 20,808,000~ 346,800分以上の期間のデータを要求すると1日平均のデータを返す。

サービスメトリックで記録するようなデータのうち、ユーザ数の推移などは長期期間で眺める場合は1日間隔のデータで全く問題ないのですが、もし仮に最も細かい粒度である1分間隔のメトリックデータを長期期間分保存しておかなければならなくなった場合はどうやるのが良いか、を考えてみました。
上の表で見てわかるとおり、fromからtoまでの間隔が 72,239秒以内であればAPIは1分間隔のメトリック値を返してくれるので、このfrom とto を72,239秒づつずらしながらAPIを叩くようなバッチを作れば良さそうです。
また、APIのレスポンスはJSON形式なのでそのまま非エンジニアである企画・営業系のメンバーに共有しても集計やグラフ化などを行うにあたって扱いにくいため、CSV形式で保存できるようにします。

というわけで書いてみたスクリプトがこちら。curl コマンドと jq コマンドがインストールされている必要があります。

gist.github.com

いたってシンプルに、curlAPIを叩いてそのレスポンスをjqでCSVに変換する という処理をwhile文で繰り返しているだけです。 ここではMackerel のAPI Keyや各種パラメータをコード内にべた書きにしていますが、実際は環境変数コマンドライン引数として渡せるようにしてcronで定期実行させるのが楽かと思います。

あとは注意点として、2017年12月1日以前のデータについては1分粒度のメトリックデータは取得できないようです。

mackerel.io

Ubuntu14.04にCloudMapperをインストール

同僚が社内チャットで教えてくれたCloudMapperが面白そうだったのでインストールして試してみました。

www.publickey1.jp

インストールするまで微妙にハマったのでメモを残します。

CloudMapper を動かすまで

$ sudo apt-get install autoconf automake libtool python-dev jq python-pip
  • AWS CLI のインストール
$ sudo pip install awscli
$ aws configure  
AWS Access Key ID [None]: (各自の環境に応じて)  
AWS Secret Access Key [None]: (各自の環境に応じて)   
Default region name [None]: (各自の環境に応じて)  
Default output format [None]: (各自の環境に応じて)  
  • CloudMapperのインストール
$ git clone https://github.com/duo-labs/cloudmapper.git
$ cd cloudmapper/
$ pip install -r requirements.txt
  • 後々必要になるpipモジュールのインストール
    • この後の手順でいろんなPythonスクリプトを実行するが、pipライブラリが足りなければその都度エラーで怒られるのでインストールしていく
    • 自分の環境の場合、以下の3つを入れたら最後まで進めました
$ sudo pip install boto3 pyjq netaddr
  • AWSのアカウント情報をCloudMapperの設定ファイルに書く
    • config.json.demo を config.json にコピーして自分のAWSのアカウントIDに書き変える
    • name は自由につけてOK。例えば dev とします
    • ciders のところはよくわからず。変更しなくても動作はしてるっぽい?
$ cat config.json
{  "accounts":
    [
        {"id": "xxxxxxxxxxxx", "name": "dev", "default": true}
    ],
    "cidrs":
    {
        "1.1.1.1/32": {"name": "SF Office"},
        "2.2.2.2/28": {"name": "NY Office"}
    }
}
  • AWSアカウント内の構成情報を集める
$ python cloudmapper.py gather --account-name dev
  • CloudMapper表示用にデータを整形する
$ python cloudmapper.py prepare --account dev
  • Web サーバを立ち上げて公開する
$ python cloudmapper.py serve
  • これだとローカルホストから http://127.0.0.1:8000 でならアクセスできるものの、リモートからアクセスできない。 リモートからアクセスする場合は --public オプションをつける。
$ python cloudmapper.py serve --public

結果

f:id:kmiya_bbm:20180223171914p:plain

ちゃんと情報取れてそう! 吐き出された図はそのままでは見にくいところもあるので、手でグリグリ修正するほうが良さそうです。

Amazon Cognito の SDK for JavaScript と CLI と API と、それらに対応するIAMポリシーを整理する

Cognito まわりのSDKCLIは、AWSのサービスの中でもなんだかすごくややこしい気がする。
公式ドキュメントを読み込んだところ、まとめるとたぶん下の表みたいになるはずなんだけれど、合っているか非常に自信がない。

SDK for JavaScript CLI API IAM
User Pool AWS.CognitoIdentityServiceProvider aws cognito-idp Amazon Cognito User Pools API cognito-idp:**
Federated Identities AWS.CognitoIdentity aws cognito-identity Amazon Cognito Federated Identities API cognito-identity:**
Sync AWS.CognitoSync aws cognito-sync Amazon Cognito Sync API cognito-sync:**

さらに Higher-Level Client SDKs としてAmazon Cognito SDK for JavaScript amazon-cognito-identity-js というSDKがあり、SDKs for Amazon Cognito User Pool App Integration and Federation ?として Amazon Cognito Auth SDK for JavaScript amazon-cognito-auth-js というのがある模様。

docs.aws.amazon.com

きびしい・・・。

AWS re:Invent2017 の会場でソリューションアーキテクト - アソシエイト を受験して合格した

年末年始のバタバタにかまけてすっかりブログを書く機を逸してしまいましたが、昨年、念願だったAWS re:Invent に初めて参加しました。 イベント自体からも他の参加者からもいろんな刺激を受けまくって、とても充実した一週間でした。

あまりにも刺激を受けすぎて、当初全く受験する予定のなかったAWS認定試験を、その場の勢いでre:Invent最終日に滑り込みで受験したのでその顛末を記そうと思います。
なお、試験対策的な情報は一切ありません。実際受験する流れはどんな感じなのかについての単なる自分用の記録ですが、もしもAWS認定試験に興味がある方のお役に立つことがあれば望外の喜びです。

受験のきっかけ

re:Invent最終日の前日(11/30)、前々から興味はあったAWSの認定試験を受けてみようと急に決めました。そう思い立った要因はいくつかあったのですが、AWS re:Inventの会期中ずっとAWSの情報漬けになっていたので、それらのアウトプットとして何か形に残したくなったのと、道中で知り合って滞在中ずっと仲良く付き合ってくれた日本からの参加者の方の一人がソリューションアーキテクト のプロフェッショナルを持ってらしたのに刺激を受けたのが大きいです。ラスベガスとre:Inventの空気感で受験費用がなんか安いと錯覚できたのもあったかもしれません。いや、確実にありました。勢いは大事だなと思います。

受験までの流れ

で、いきなり Mirage の試験会場に行って「今から試験受けられる?」と聞いてみましたが、事前に登録が必要なことがわかりました。そのへんは通常の認定試験のフローと何ら変わらないようです。

webからAWS認定アカウントの作成と試験予約を行うことができます。 AWS認定アカウントのマイページにある「新しい試験の予約」というボタンから試験の会場と日程を決める画面に遷移します。 普通なら、ここで自宅から近い会場を選択すれば良いわけですが、今回はre:Inventの会場で受験するため The Mirageを探す必要があります。

The Mirageの住所は以下の通り。

3400 S Las Vegas Blvd
Las Vegas, NV 89109

個人的には試験そのものよりもこの事前登録のほうが難しかったと感じました。

当日のうちに受験したかったのですが、あいにくその日の日程は埋まっていたため翌日12/1の午前中の日程に申し込みました。

受験当日

試験開始時間の30分前には受付に来るよう言われていたのですが、到着するとすでに受付には結構な行列ができていて、なるほど30分の余裕は必要かなと思いました。受付では写真付きの身分証明書を2つ提示すること求められますが、re:Inventの会場では re:Inventの参加証 + パスポート でOKでした。無事に受付が済むと、番号が書かれた紙のカードを貰えます。これが試験会場で着席する席の番号となっています。 会場が乾燥しているからか、受付では自由にもらえるトローチが用意されていました。

f:id:kmiya_bbm:20180112125817j:plain 受け付け・待合場所の様子

時間になると待合室に試験監督の方が来て受験者に注意事項をアナウンスします。それが終わると、別室の試験会場に移動します。自分が受験した回の受験者は30人ほどはいたでしょうか。結構な人数がいた気がします。

スマホなどは電源を切らなければいけないので写真は撮ってないのですが、試験会場はかなり広い部屋にデスクトップPCが置かれた長机が何列かズラーっと並んでおり、自分の番号の席を自分で探します。隣の席との間につい立て等はなく、本当に長机にPCが並べて置いてあるだけ、という感じでした。

リュックなどの大きな荷物は壁際の棚に、ウェストポーチのような小さな荷物は自席の椅子の下におきます。バッグを持っていない場合は、受付で透明なビニール袋がもらえるのでそこにスマホや財布を入れて自席の椅子の下に置きます。

最初、自席のPCで、試験を受けるためにAWS認定アカウントにログインして間違いがないか確認するよう指示が出るのですが、その後は試験開始の合図等はなく、各々試験を始めていました。これには最初ちょっと戸惑ったのですが、試験時間が異なるアソシエイトレベルとプロフェッショナルレベルの受験者が同じ試験会場にいたっぽいことと、試験を開始したところからPCの画面上に残りの試験時間が表示される形式になっていたことから、各々勝手に試験を始めてよかったのだろうと安心しました。

試験の内容については公式の情報や参考書、いろんな方のブログに載っているので割愛しますが、自分の場合はEBSについての知識があやふやで勉強し直す必要を感じました。

全ての問題の回答と確認が終わったら、PC上で終了ボタンを押して合否の結果を確認します。そして挙手して試験監督さんに退出する旨を申告します。 合否はすぐに表示されるのですが、合格していても試験会場なので声に出して大喜びすることが出来ず、試験会場を退出するまでひとりニヤニヤしていました。 試験会場を退出したら、受付に戻って合格した旨を伝えます。受付の人たちがハイテンションで祝福してくれたのでとても嬉しかったです。その場でTシャツがもらえるので、サイズを申告して受け取ります。

f:id:kmiya_bbm:20180112131537j:plain
かわいいドット絵が描かれたTシャツ。やったー

合格すると

Tシャツやステッカーなどの記念品がもらえるほか、会場内に設置されている認定者ラウンジに入ることができるようになります。 認定者ラウンジはAWS Summit Tokyoなどでも設置されていますが、どの種類・レベルでもいいので1つでもAWS認定を持っていれば入ることができます。 中では電源や軽食、ドリンクなどが用意されている他、認定者同士で交流しやすくするためか休憩スペースやゲームなども設置されています。
f:id:kmiya_bbm:20180112221004j:plain f:id:kmiya_bbm:20180112221048j:plain

随感

AWS re:InventというAWSの各種イベントの中でも最も熱量が高いであろう空気感に当てられて受験しましたが、無事に合格できてよかったです。

IT系の資格というのはなかなかとらえ方が難しく、資格を持っていれば実力があるというわけでもないですし、実力はめちゃくちゃあっても資格の類を一切取ってない人もいます。自分が勤めている会社は製造業で、IT企業や、ましてSIerの会社ではないので、IT系の資格は受験料も自腹ですし、合格しても一時金や昇給などの実利はありません。
それでも自分はIT系の資格試験に挑戦すること、合格することには一定の意義があると思っています。

  • 業務 +αの勉強をする習慣をつけることができる
  • 業務では触れない分野の知識も試験のために勉強することがあり、見識が広がる
  • 合格すると、一定の知識量や実力を必要とする資格に合格できる程度の「学習力があること」を対外的にも自分自身にも示せる

つまり、継続して学ぶ習慣をつけるきっかけとして資格試験というのはいいモチベーションになるのではないかと考えています。

今回、AWSの認定試験を受験すること自体は突発的に決めたことでしたが、AWSなどのクラウドサービスについて調べたり学んだりすることはずっと続けていた(AWSは東京リージョンができる前から追っていた)ことであり、アソシエイトレベルではありますが今回ソリューションアーキテクトの認定に合格できたのは継続的な学習の成果だと思っているのでとても嬉しかったです。

まとめ

AWS re:Invent2017の会場でAWS認定試験を受験したときの流れをまとめました。
AWSの認定資格は初級レベルでもなんでも1つ持っていれば認定者ラウンジに入ることができたり記念品がもらえたりするので、普段AWSを利用している方は認定試験を受けてみるのもよいのではないでしょうか。