ELBの資料を読んだメモ
自分が業務で使いそうな範囲でメモに起こす。
ELB = L4のロードバランサー(Classic Load Balancer = CLB) + L7ベースのロードバランサー(Application Load Balancer = ALB)
ELB
ELBは複数AZをまたいで負荷分散が可能。
ヘルスチェックは細かく指定可能。以下の表は引用。 ウェブアプリケーションで未熟な状態なら、PingパスでDBの接続とかあれこれチェックできる状態にしておくのも一つの手か?
項目 例 メモ Ping プロトコル HTTP 200が返るか? Ping ポート 80 Ping パス /index.html HTTP/HTTPS利用の場合 タイムアウト時間 20秒 ヘルスチェック間隔 30秒 異常判定までの回数 4回 正常判定までの回数 2回 正常との判定が遅いと追加したインスタンスが使える前に時間がかかる。 逆に異常との判定が厳しすぎても過負荷時に処理できるインスタンスを減らしてしまうことも。
Route 53以外でDNSを使うときは、CNAMEで設定してELBに向ける。
サーバー証明書はELBにアップロード。Let's Encryptを使うときはどうする?的な話は別途調べる。→AWS Certificate Managerを使用する。証明書に対しての料金がかからない理解。アップロード作業も不要。
サーバーへの接続のソースIPはELBのIPアドレスになるので、X-Forwarded-For
ヘッダーを見る。
ELBにもセキュリティグループを設定できるので、今までEC2に設定していたセキュリティグループはELBだけを受け付けるようにして、ELB側で制限をかける。
ALB
コンテクストベースルーティングで、ルールにURLのパスが使える。振り分け先にはターゲットグループ(バックエンドサーバーをまとめたグループ)を指定。
WebsocketやHTTP/2にも対応。
料金 ALBの使用時間と、Load Balancer Capacity Units (LCU) の使用量で課金。
LCU 以下の3つのディメンションを測定し、使用量が最も高いディメンションのみ請求。
とりあえず変なことしなければ、CLBよりちょろっと安く済ませられるらしい。
ディメンションの項目から考えると、HTTP/2にちゃんと対応したほうが安くなるのか?
Git(hub)でフォークしたリポジトリに、オリジナルリポジトリの変更を取り込む
いつも忘れて調べなおすことになるので、メモ。
ケース
例えば、こんなリポジトリ。
オリジナルのプラグインでほんのすこしだけカスタマイズしたいから、ちょっとだけ修正して使ってる、みたいな。
で、時間が経って、変更されているものもあるから取り込みたい。
というときの作業。
参照
結論、Githubのヘルプを見ればいいわけですね。はい、いつも見ます。いつもたどり着くのに時間がかかりますが。
https://help.github.com/articles/fork-a-repo/help.github.com
https://help.github.com/articles/syncing-a-fork/help.github.com
この記事のこの後の内容は、ヘルプの内容をただただ自分のためにメモしたものです。
作業
ざっくり書くとこんな感じでしょうか。
git clone ${forked_repo} ${forked_repo_dir} cd ${forked_repo_dir} git remote add upstream ${original_repo} git fetch upstream git checkout master # forked master git merge upstream/master
自分の(忘れた後の)理解のために、細かく書いていくと、、、
フォークしてカスタマイズしたリポジトリGitHub - sugilog/molokai: Molokai color scheme for Vimに、オリジナルのリポジトリGitHub - tomasr/molokai: Molokai color scheme for Vimの修正内容を取り込む。
自分のリポジトリをclone
。
git clone git@github.com:sugilog/molokai.git ~/workspace/molokai
cd ~/workspace/molokai
オリジナルのリポジトリをupstream
という名前でリモートブランチとして登録。名前はかぶらなきゃOK。
git remote add upstream https://github.com/tomasr/molokai.git git fetch upstream
自分のリポジトリのブランチをcheckout
。とりあえずmaster
。
git checkout master
最後に、オリジナルの内容をマージ。
git merge upstream/master
あとはコンフリクトを直すなりなんなり。
結論、マージ作業なわけです。
GithubのウェブUIからのプルリク作業に慣れてきった生活で、簡単なマージ作業でさえ忘れてしまう。。。
最後に
molokai、お世話になってます。
tmux 2.3のキーバインディングでちょっと困った
macでtmuxを使っていてエラーが出て解決してたら次の問題にハマって、ということがあったので一連の話をメモ。
タイトルにしたキーバインディングは結局ググってもよくわからずソースを見て解決した話。
流れ
macOS Sierra にバージョンアップ。そしたら変なWARNINGメッセージが出るようになった。
Qiitaのまとめどおり、tmuxをアンインストール&再インストールしてみた。
ちなみにこの作業をした時のHEADはDo not force symbols to width 1, from Yen Chi Hsuan. · tmux/tmux@178894b · GitHub。
この時点で、tmuxのバージョンが2.3に更新された。元のバージョンは忘れたので省略。
tmux2.3を起動したら、またもや変なエラーメッセージが出始めた。
このときの自分のtmux.conf
はdotfiles/.tmux.conf at 42f0b71a673aad45921912766acc963948d0027b · sugilog/dotfiles · GitHubこんな感じ。
ブログにまとめられているとおり、-t vi-copy
を-T copy-mode-vi
にしてあれこれして、使い始めた。
dotfiles/.tmux.conf at 33c847acf64889f012859e234576fc85d8e1d36c · sugilog/dotfiles · GitHub
で、本題
copy-mode
のときに、スクロールアップがうまくできない。正確には、
copy-mode
でのj
,k
でのカーソル移動でのスクロールはできる。copy-mode
でのCtrl+f
でのスクロールダウンはできる。copy-mode
でのCtrl+b
でのスクロールアップができない。
(バインディングはvi)。
ググっても情報が見つからないのでソースにあたる。。。と見つけたコミット。
Ctrl+b
はコンフリクトがあるから、初期設定するのやめよう、とのこと。なるほどね。
ちなみに自分は関係ない人なので、自分で追加しちゃいます。
ちなみに自分のtmuxで使うprefix
キーはCtrl+t
(C-t
)です。
解決!
お粗末さまでした。
git logをltsvにする
コミットの情報をもとにファイルチェックとかしてみよう、という感じからgitだとどうしようということでログから情報を取り出す。
subversionで、svn ls -v <URL>
してとれるような情報のイメージ。
ついでにプログラムから加工しやすいようにLTSVにする。
git log -n 1 --format="hash:%H%x09author_date:%at" <file>
分解して理解
git log
: 省略
-n 1
: とりあえず今回は、指定したファイルに対する最新のコミットを取得できればいいので、1つだけ。
--format
: ログのフォーマットを指定する。続く引数内で、%
なんとかみたいにすると情報を埋め込めたりする。くわしくは、git help log
内のPRETTY FORMATS
を参照。
hash:
: ここまでは単なる文字列。LTSVのキー。
%H
: コミットハッシュ。 %h
にすると省略形(7桁くらいになってるやつ)のコミットハッシュ。
%x09
: %x
はあとに続く16進数のコードに対応した文字を埋め込む。09
はタブ。故にLTSVの区切り文字。
author_date:
: ここも単なる文字列。LTSVのキー。
%at
: author dateをunix timestampで表示する。rubyからなら、Time.at
を使えばTimeオブジェクトに変換できる。comitter dateを使うかどうかみたいな話はここの主題ではないので省略。
使用上の前提条件というか、現在のこの記事の状況。
- リモートリポジトリの情報をfetchしたりするのは別途必要ということで。
- コミットメッセージ内にタブが含まれてたらどうしようとか思って、まだLTSV化するログの中にコミットメッセージを入れることは試していない。
Dockerを使って、AWS Lambda用のPhantomJSとfontconfigをビルドする
dockerを使ってみる。 やりたいことはこれ。
AWS LambdaでPhantomJSを使ってあれこれしたいけど、日本語フォントを扱えるようにしないと、キャプチャがうまくできない。 日本語フォントを扱える夜にするのはリクルートさんの記事のとおりにできるけど、じゃあそのためのfontconfigのビルドは?
さらに、npmのphantomjs(現在はphantomjs-prebuilt)をmacの環境でインストールしてしまうと、lambdaの環境では動かない。
ということで、Linux環境であれこれして、Lambda用のパッケージのビルドする。
そのための簡易環境としてdockerを使ってみようという魂胆。
fontconfigやらPhantomJS自体のビルドの時間はそこそこかかるけど、それを待ちさえすれば、がっつり自動化できた。
dockerの設定
Dockerfile
Linux環境にはCentosを使いたいのでDocker HubのCentosのページを参考にする。
# https://hub.docker.com/_/centos/ FROM centos:7 MAINTAINER "YOU" <you@example> ENV container docker RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \ rm -f /lib/systemd/system/multi-user.target.wants/*;\ rm -f /etc/systemd/system/*.wants/*;\ rm -f /lib/systemd/system/local-fs.target.wants/*; \ rm -f /lib/systemd/system/sockets.target.wants/*udev*; \ rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \ rm -f /lib/systemd/system/basic.target.wants/*; \ rm -f /lib/systemd/system/anaconda.target.wants/*; \ yum install -y openssh-server openssh-clients; \ yum install -y iproute iproute-devel; \ yum -y install epel-release; \ yum -y install gperf freetype-devel libxml2-devel python-lxml git-all libtool; \ yum -y install npm bzip2; \ passwd root -d; \ sed -i "s/^.*PermitEmptyPasswords.*$/PermitEmptyPasswords yes/g" /etc/ssh/sshd_config; \ sed -i "s/^.*PasswordAuthentication.*$/PasswordAuthentication yes/g" /etc/ssh/sshd_config; \ mkdir -p /src/python; mkdir -p /src/node; \ cd /src/python; \ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py; \ python get-pip.py; \ pip install -U six; \ cd /src/; \ git clone http://anongit.freedesktop.org/git/fontconfig; cd /src/fontconfig; \ ./autogen.sh --prefix=/tmp/fontconfig --sysconfdir=/tmp/fontconfig/etc --bindir=/tmp/fontconfig/usr/bin --enable-libxml2; \ make; make install; \ cd /src/node; \ npm install phantomjs-prebuilt; \ mv /src/node/node_modules/phantomjs-prebuilt /tmp/phantomjs-prebuilt; VOLUME [ "/run", "/tmp" ] CMD [ "/usr/sbin/init" ]
RUNの部分の話を自分が忘れないようにするレベルでまとめておく。
- 前半の
rm
しまくってるのは、systemdまわりの対応。Docker HubのCentosのページを参照。 yum
でインストールしているのは2種類。passwd
でパスワード消したり、sshd_config
でセキュリティ弱めているのは、ファイルを取り出すときにパスワードとかいろいろ聞かれたくないから。- 本番環境では「ダメ、絶対」な設定だけど、今回はこれで。
pip
、six
は、fontconfigのautogen
のタイミングで必要なので入れておく。- あとは、fontconfigとPhantomJSをビルド。
- ファイルを取り出しやすいように、それぞれtmpディレクトリに移動させてる。
デバッグ
簡易的に接続してみるなら、attach
は使わずに、ssh感覚でexec
+bash
。-it
(= interactive, tty)オプションをつけて実行。
本来の用途ではないらしいので、あくまで簡易的に。
docker exec -it {container_id_or_name} /bin/bash
実行
以下の様なシェルスクリプトを作って実行してみた。
docker pull centos:7 docker build --rm -t local/centos7 . docker create --name phantom --privileged -p 20022:22 local/centos7 docker start phantom sleep 2 ssh-keygen -R "[localhost]:20022"; scp -o 'StrictHostKeyChecking no' -r -P 20022 root@localhost:/tmp/fontconfig fontconfig scp -o 'StrictHostKeyChecking no' -r -P 20022 root@localhost:/tmp/phantomjs-prebuilt phantomjs-prebuilt docker rm -f phantom docker rmi local/centos7
ポイントといえば、、、
privileged
をつけてcreate
しないとうまく動かない。systemd
まわりの話(+SELinuxが絡んでたっけな?)start
後すぐにscp
してもうまく接続できない。1秒か2秒くらいあける。scp
で認証周りのことをきかれたくないから、ssh-keygen -R
でknown-hosts
をクリアして、StrictHostKeyChecking
をしないようにする。
AWS API GatewayのBody Mapping Templateで使えるテンプレート
AWSのAPI Gatewayでは、リクエストをどう受けて、どう返すか、ということが設定できる。中間処理にLambdaを使う場合は、リクエストの情報をJSONオブジェクトに変換しておいて貰わないと、情報が来ない。
ということで、Body Mapping Template(後処理に渡すデータを生成するためのテンプレート)を使うわけだけど、以前には多分なかったテンプレートが追加されていたので試している。
Method Request Passthrough
2016/05/11時点では以下のような形をしている。cognitoの情報も追加できるようになっているので、おそらく今後も変化していくのだろうと想定。
## See http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html ## This template will pass through all parameters including path, querystring, header, stage variables, and context through to the integration endpoint via the body/payload #set($allParams = $input.params()) { "body-json" : "$input.json('$')", "params" : { #foreach($type in $allParams.keySet()) #set($params = $allParams.get($type)) "$type" : { #foreach($paramName in $params.keySet()) "$paramName" : "$util.escapeJavaScript($params.get($paramName))" #if($foreach.hasNext),#end #end } #if($foreach.hasNext),#end #end }, "stage-variables" : { #foreach($key in $stageVariables.keySet()) "$key" : "$util.escapeJavaScript($stageVariables.get($key))" #if($foreach.hasNext),#end #end }, "context" : { "account-id" : "$context.identity.accountId", "api-id" : "$context.apiId", "api-key" : "$context.identity.apiKey", "authorizer-principal-id" : "$context.authorizer.principalId", "caller" : "$context.identity.caller", "cognito-authentication-provider" : "$context.identity.cognitoAuthenticationProvider", "cognito-authentication-type" : "$context.identity.cognitoAuthenticationType", "cognito-identity-id" : "$context.identity.cognitoIdentityId", "cognito-identity-pool-id" : "$context.identity.cognitoIdentityPoolId", "http-method" : "$context.httpMethod", "stage" : "$context.stage", "source-ip" : "$context.identity.sourceIp", "user" : "$context.identity.user", "user-agent" : "$context.identity.userAgent", "user-arn" : "$context.identity.userArn", "request-id" : "$context.requestId", "resource-id" : "$context.resourceId", "resource-path" : "$context.resourcePath" } }
ざっくりと展開すると、以下の様な感じになる。だいたい自分でわかった範囲で説明もつけておく。雰囲気なので間違ってたらごめんなさい。
{ "body-json": [object], "params": { "path": [Empty Object], "querystring": [object], "header": [object], }, "stage-variables": [object], "context": [object] }
Key | Description | Type |
---|---|---|
body-json |
BodyをJSON.parseしたもの。 | object, array, ... |
params |
リクエスト時のパラメーター情報。 | object |
params.path |
(おそらく)基本的に空のオブジェクト。 | {} |
params.querystring |
URLクエリを処理したオブジェクト。配列クエリ、ネストされたクエリには対応されてなさそう。 | object |
params.header |
ヘッダ情報。 Host, Origin, User-Agent, などなど。 | object |
stage-variables |
API Gateway で設定したstageの情報。 | object |
context |
API Gatewayでリクエストを受けた時の状態。 | object |
context.http-method |
リクエストメソッド。GET, POST, など。 | string |
context.stage |
API Gateway でデプロイしているステージのラベル。 | string |
context.source-ip |
リクエストしてきたIPアドレス。 | string |
context.user-agent |
ユーザーエージェント文字列。 | string |
context.resource-path |
URLパスの文字列。基本的にAPI Gatewayのリソースに一致するはず。 | string |
バグ?
テンプレートにはバグっぽい挙動が含まれていて、POST時のリクエストBodyのJSONで文字列を含んでいるとエラーする。ダブルクオーテーションで囲ってしまっているため。ダブルクオーテーションを外してしまったほうが多分良いと思われる(思われるけど落とし穴があるかも)。
ref: https://forums.aws.amazon.com/thread.jspa?threadID=221749
-"body-json" : "$input.json('$')", +"body-json" : $input.json('$'),
ちなみにエラーすると、Lambdaは起動されない。Lambdaのログを監視していてもわからない問題になるので、検証は自己責任ということで。
VMware Fusion 8.1のNATポートフォワーディングまわりのエラー対応
事象
VMware Fusion 8.1にNATポートフォワーディングまわりでエラーがある。VMware BLOGSで修正が公開されているが、2016/02/01にパッケージをダウンロードした段階では、配布されているパッケージに修正は反映されていない。
自分の手元では、VMware Fusionのネットワークを再起動すると、1度目のアクセスはできるが、そこでVMware Fusionのネットワークが落ちる、という現象。
MacをEl Capitanにアップデートして、VMware Fusionちゃんと動くか検証していて、うまくできたと思ったら落ちる、という突き落とされパターン。
事前作業
VMware Fusionのネットワーク周りの設定ファイルを再確認。変更されていたら、同じディレクトリ内に作られているバックアップファイルから必要な部分をコピーしてくるか設定し直す。
- dhcpの設定ファイル
/Library/Preferences/VMware\ Fusion/vmnet8/dhcpd.conf
- natの設定ファイル
/Library/Preferences/VMware\ Fusion/vmnet8/nat.conf
設定周りについては、過去にもエントリーを書いてるので、よろしければご参照を。
修正ファイルの設置
- こちらから、
vmnet-natd
ファイルをダウンロードDownload the NAT network component from https://www.vmware.com/go/dl_vmnet-natd (MD5: e347f5c8d86640af5102852c897e31cc)
- ダウンロードした
vmnet-natd
をVMware Fusionのアプリケーションパッケージ内に移動(置き換え)。 - アプリケーションパッケージ内に設置した
vmnet-natd
の所有者とパーミッションを変更する。
# 移動 mv -i $HOME/Downloads/vmnet-natd /Applications/VMware\ Fusion.app/Contents/Library/ # 所有者情報とパーミッションを変更。(所有者情報の部分は、環境に併せてご変更を。) sudo chown root:wheel /Applications/VMware\ Fusion.app/Contents/Library/vmnet-natd sudo chmod 755 /Applications/VMware\ Fusion.app/Contents/Library/vmnet-natd
ネットワークの再起動
vmnet-cli
で、stop&startする。
sudo /Applications/VMware\ Fusion.app/Contents/Library/vmnet-cli --stop sudo /Applications/VMware\ Fusion.app/Contents/Library/vmnet-cli --start
状態を確認。できれば、ポートフォワーディングしているVMを立ち上げて、ネットワーク越しにアクセスして、その後に確認してみると良い。
sudo /Applications/VMware\ Fusion.app/Contents/Library/vmnet-cli --status
正常に動作していれば、以下のようなメッセージ。
DHCP service on vmnet1 is running Hostonly virtual adapter on vmnet1 is enabled DHCP service on vmnet8 is running NAT service on vmnet8 is running Hostonly virtual adapter on vmnet8 is enabled All the services configured on all the networks are running
正常でない時:いくつかの行がエラーを表示する。
... NAT service on vmnet8 is not running ... Some/All of the configured services are not running