2017年6月28日水曜日

日本語ドメインについてお勉強したのでそのまとめ

日本語.jp みたいなドメインってたまに見かけますが実際に自分が運用することになるとは思わなかったので学んだことをまとめたいと思います。
このような形式のドメイン名は「国際化ドメイン名」と呼ばれるものらしいです。

従来のアルファベット、数字、ハイフン以外にマルチバイト文字を利用できるようにする仕組みのことで、日本語の他にもアラビア文字なども利用できるようです。
ただ、毎回国際化ドメインと呼ぶのもアレだし非エンジニアのスタッフに説明する時に相手に難しそうなイメージを持たれたくないので、
日本語が含まれたドメイン名のことを日本語ドメインと会社では呼んでいます。
中国語だったら中国語ドメインですね。

この日本語ドメインをDNSサーバが理解できるようにするためには、Punycode(ピュニコード)と呼ばれる形式で、アルファベット数字ハイフンだけの、既存のドメイン名に使用できる文字だけの対応ドメインに変換してあげる必要があります。
言いたかったのはそれだけです。

たとえば、JPRSが運用している 日本語.jp はPunycodeだと xn--wgv71a119e.jp になります。

これはHTTPS接続についてほんのちょっとだけめんどくさいトラブルが発生します。
curlなどでHTTPアクセスのテストをすることはよくあると思いますが、開発している日本語ドメインのサービスがHTTPSを基本としていて、curlでもHTTPSで行う場合、通常はSSLに関するエラーが出力されます。
SSL証明書を取得するときはPunycode変換済みのドメイン名で取得することが前提となっており、変換済みのドメインは変換前のドメインとリテラル的に同等とみなされないからです。
SSL証明書エラーを回避するには curlの -k オプションを利用します。

今回私が運用することになった日本語のドメイン名は、AWSのACMで無料の証明書を取得しました。
そのドメインは お名前.com で購入したのですが、デフォルトの状態では取得不可能でした。
なぜか?それは、こちらの仕様によるもの

日本語ドメインは、A / AAAA / CNAMEレコードのみご利用いただくことが可能です。
設定方法はこちらをご参照ください。

これはMXレコードを設定できないことを意味します。
MXレコードが設定できないということは、該当ドメインでのメール受信ができないことを示します。
つまり、ACMで必須となる認証メールによるACM発行承認が得られないわけです。

なので、何らかの方法でお名前.com以外のDNSサーバ、できればRoute53でDNSレコードが管理できる状況にしなければなりません。
私は「お名前.comのドメインをAWSで使用する4つの方法 - Qiita」によるところの、2番目の方法で実質的な管理者をRoute53に変更して対応しました。

これを行うことにより、Route53上で好きなようにDNSレコードを設定することができるようになりました。
これでACMの証明書が取得できましたので、ELBやCloudFrontに登録して、快適HTTPSライフが遅れるという算段です。

以上がTDIWL(That Day I Was Learned)になります。
これから同様の仕事を行う方の参考になれば幸いです。




2017年5月4日木曜日

基本的な使い方を学ぶために速習Docker的なことをしました

MacでDockerを使うために基本的な使い方を学習しました。
下記を読みながら、適宜読み替えたりググったりしてコマンドを実行してみました。


Dockerエキスパート養成読本[活用の基礎と実践ノウハウ満載!] (Software Design plus)

Docker実行環境の構築

brew install docker
brew install docker-machine
brew install docker-compose

Dockerマシンを作成しようとして失敗

TearTheSky-MacBook:~ TearTheSky$ docker-machine create --driver virtualbox test-docker
Running pre-create checks...
(test-docker) You are using version 4.3.26r98988 of VirtualBox. If you encounter issues, you might want to upgrade to version 5 at https://www.virtualbox.org
Error with pre-create check: "VirtualBox is configured with multiple host-only adapters with the same IP \"192.168.33.1\". Please remove one."
TearTheSky-MacBook:~ TearTheSky$

VirtualBox上のDockerマシンの確認

TearTheSky-MacBook:~ TearTheSky$ docker-machine ls
NAME          ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER        ERRORS
test-docker   -        virtualbox   Running   tcp://192.168.99.100:2376           v17.04.0-ce
TearTheSky-MacBook:~ TearTheSky$

Dockerコンテナを確認しようとして失敗

TearTheSky-MacBook:~ TearTheSky$ docker ps
Cannot connect to the Docker daemon. Is the docker daemon running on this host?
TearTheSky-MacBook:~ TearTheSky$

対処法

yoshida-no-MacBook-Pro:~ TearTheSky$ eval "$(docker-machine env test-docker)"
TearTheSky-MacBook:~ TearTheSky$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
TearTheSky-MacBook:~ TearTheSky$

Dockerコンテナの作成

TearTheSky-MacBook:~ TearTheSky$ docker run -d -p 80:80 --name webserver nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
6d827a3ef358: Pull complete
f8f2e0556751: Pull complete
5c9972dca3fd: Pull complete
451b9524cb06: Pull complete
Digest: sha256:e6693c20186f837fc393390135d8a598a96a833917917789d63766cab6c59582
Status: Downloaded newer image for nginx:latest
61d1da7ae17cf573ceb51a99b213cb5e315150ce92ee8c23686898e28d603946
TearTheSky-MacBook:~ TearTheSky$

Dockerコンテナの確認

TearTheSky-MacBook:~ TearTheSky$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                         NAMES
61d1da7ae17c        nginx               "nginx -g 'daemon off"   15 seconds ago      Up 14 seconds       0.0.0.0:80->80/tcp, 443/tcp   webserver
TearTheSky-MacBook:~ TearTheSky$

Nginxの起動確認

ブラウザで「192.168.99.100」にアクセスするとNginxデフォルトページが表示される。
「192.168.99.100」はVirtualBox上のDockerコンテナホスト。

Dockerコンテナの削除

TearTheSky-MacBook:~ TearTheSky$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                         NAMES
61d1da7ae17c        nginx               "nginx -g 'daemon off"   25 minutes ago      Up 25 minutes       0.0.0.0:80->80/tcp, 443/tcp   webserver
TearTheSky-MacBook:~ TearTheSky$
TearTheSky-MacBook:~ TearTheSky$
TearTheSky-MacBook:~ TearTheSky$
TearTheSky-MacBook:~ TearTheSky$ docker rm webserver
Error response from daemon: You cannot remove a running container 61d1da7ae17cf573ceb51a99b213cb5e315150ce92ee8c23686898e28d603946. Stop the container before attempting removal or force remove
TearTheSky-MacBook:~ TearTheSky$
TearTheSky-MacBook:~ TearTheSky$ docker stop webserver
webserver
TearTheSky-MacBook:~ TearTheSky$
TearTheSky-MacBook:~ TearTheSky$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
TearTheSky-MacBook:~ TearTheSky$
TearTheSky-MacBook:~ TearTheSky$
TearTheSky-MacBook:~ TearTheSky$ docker rm webserver
webserver
TearTheSky-MacBook:~ TearTheSky$

VirtualBox上のDockerマシンの停止と削除

TearTheSky-MacBook:~ TearTheSky$
TearTheSky-MacBook:~ TearTheSky$ docker-machine ls
NAME          ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER        ERRORS
test-docker   *        virtualbox   Running   tcp://192.168.99.100:2376           v17.04.0-ce
TearTheSky-MacBook:~ TearTheSky$
TearTheSky-MacBook:~ TearTheSky$ docker-machine kill test-docker
Killing "test-docker"...
Machine "test-docker" was killed.
TearTheSky-MacBook:~ TearTheSky$ docker-machine ls
NAME          ACTIVE   DRIVER       STATE     URL   SWARM   DOCKER    ERRORS
test-docker   -        virtualbox   Stopped                 Unknown
TearTheSky-MacBook:~ TearTheSky$
TearTheSky-MacBook:~ TearTheSky$
TearTheSky-MacBook:~ TearTheSky$ docker-machine rm test-docker
About to remove test-docker
Are you sure? (y/n): y
Successfully removed test-docker
TearTheSky-MacBook:~ TearTheSky$
TearTheSky-MacBook:~ TearTheSky$ docker-machine ls
NAME   ACTIVE   DRIVER   STATE   URL   SWARM   DOCKER   ERRORS
TearTheSky-MacBook:~ TearTheSky$

Docker for Macのインストールと利用

インストール

Docker Machine でコンテナを立てたような感じでコンテナを立てる

TearTheSky-MacBook:~ TearTheSky$ docker run -d -p 80:80 --name webserver nginx
TearTheSky-MacBook:~ TearTheSky$ docker ps

Nginxの起動確認

ブラウザで「localhost」にアクセスするとNginxデフォルトページが表示される。
VirtualBoxには仮想マシンが存在しない。

Docker Machine と Docker for Mac の違い

Docker Machine は 書籍上の Boot2Docker と同じ立ち位置で、Mac上にVirtualBoxを使って仮想マシンのLinuxを起動し、それをコンテナサーバとして、その中にコンテナを立てる。
Docker for Mac は Macbook 自身がコンテナサーバになる。
なのでVirtualBox上に仮想マシンは不要だし、起動されない。
なるほどなるほど。 基本の使い方は理解できました。

2017年3月7日火曜日

AWSを使ってソーリーサーバを構築しました。割と便利だと思う…。

とてもお久しぶりです。
恵比寿のITベンチャーでサービス運営やっています。
仲間募集中です。ご興味ある方はTwitterなどでご連絡ください。

今回はAWSを使って、わりと便利なソーリーサーバを構築しましたというお話です。
構成は下の図のようになっています。



通信フローとしては、まずエンドユーザがELBにアクセスします。 このELBは既存のWebサービスやWebサイトをバランシングしていたものです。 諸事情によりメンテナンスしたり、ドメインを畳むことになったという話を想定しています。
そのELBに接続されていたWebサーバやアプリケーションサーバの代わりにソーリーサーバを接続します。 するとエンドユーザはソーリーサーバにアクセスしてきますよね。
ソーリーサーバはリクエストを受けたら、各ドメインに対応させたいCloudFrontへリクエストをパスします。 CloudFrontはS3のコンテンツを返すのですが、このS3に静的なソーリーページを格納しておきます。 それにより、ドメインにアクセスしてきたエンドユーザにソーリーページを見せることができます。
ポイントはソーリーサーバとCloudFrontですがやってることは簡単です。 まず、ソーリーサーバはただのNginxです。 proxy_pass を使って、特定ドメインに来たリクエストを対応するCloudFrontのドメインへパスします。 その設定は、/etc/nginx/conf.d/virtual.conf に書きました。
server {
        listen 80;
        server_name example.com;
        if ($http_x_forwarded_proto != https) {
                return 301 https://$host$request_uri;
        }
        location / {
                proxy_pass http://domain-a.sorry.example.com/;
        }
}
上記の server ディレクティブのかたまりを、ソーリーページの数だけ用意します。 1ドメイン1種類のページでよければ、3ドメインなら3つのディレクティブになります。
if文のおかげで、自動でHTTPSになります。
しかしここで一つ問題があります。 ELBごとにヘルスチェックエンドポイントが違うのです。 なのでそのままではそもそもNginxがヘルスチェックに合格せず、ELBがNginxにリクエストを渡してくれません。
それはNginxの素敵機能 empty_gif を使って解決します。 今回は /etc/nginx/nginx.conf に以下のように書きました。
http {
    (略)
    server { 
        (略)
        location / {
                 empty_gif;
                break;
        }
    (略)
    } 
    (略)
}
これにより、どんなパスへのアクセスに対しても 1ピクセルのgifイメージを生成して返します。 そのおかげで、ELBのどんなヘルスチェックパスも合格し、めでたく InService になることができます。
残りは CloudFront ですね。
CloudFrontはソーリーページごとにインスタンスを用意する必要があります。
理由はカスタムエラーページを利用したいからです。
CloudFrontのカスタムエラーページでは、特定のHTTPステータースコードの場合、任意のステータスコードに変更することができ、さらに任意のコンテンツを表示させることができます。
これを使って、全ての403アクセスを404へ変更して、ついでにソーリーページのhtmlを表示させちゃうことができます。
なんで403にするかというと、CloudFront + S3 でのコンテンツ配信方式で、ページが存在しない場合、CloudFront側が 403 Access Denied を返すからです。
これを404+ソーリーページにすることで、どんな存在しないURLにアクセスが来ても、自分が用意した404用のhtmlが表示されることになります。
ただし、「正しいソーリーページのパス」にアクセスされると、ステータスコードは200になってしまいます。
よほどの物好きなエンドユーザ意外はそんなことしないので、気にしないことにしました。
Nginxのコンフィグの書き方でもうちょっとCloudFrontのインスタンスを減らせる気もしますが、料金体系的にデータ転送量とリクエスト数のみで、インスタンス数による固定料金はないので、管理は面倒くさいですがこれでいいかなという感じです。

あ、あと、ACMを使って無料証明書を取得してCloudFrontに登録しています。
そのために、 sorry.example.com のような、ソーリーページ専用サブドメインを用意して、 それのワイルドカード証明書をACMから発行させてもらっています。

ところで何が便利なの?
まず、ステータスコードを任意に指定できます。404とか、500とか。それから、ソーリーページにhttpsが使えます。労力の割には些細なリターンのような気もしますが…。
NginxのコンフィグはGitで管理してAnsibleなどで配布できます。
1台に全部のソーリーページについて書かなきゃいけないですが、書いてしまえば、1台をマスターサーバにして楽にスケールアウトできます。
マスターサーバのコンフィグに全てのソーリーページの設定が書かれてあるので、ドメインに対して透過的なソーリーサーバが出来上がります。
どのELBにどのサーバを突っ込んでもOKということです。

2016年10月30日日曜日

小さな会社で一人で監視サーバ立てて運用して一年以上たったのでそのまとめ


MECE目指して書き始めたけど全然無理でした。多分、初心者向けです。
仕事で書いたドキュメントの流用です。
会社にはインフラでズバッと意見を出す人がいないので、こういう割と広いこと見れてそうな入門ドキュメントを会社のドキュメントとしてためておくことで、将来誰か監視システムを刷新するときとかの方向性になれればという考えです。

持つべきか、もたざるべきか

まず大枠の設計として、監視システムを持つべきか、持たざるべきかという点について考える必要があると思います。
これは監視をするかしないかという意味ではなく、監視システムのサーバを持つかどうかという意味を指します。
つまりZabbixやmuninといった監視サーバを構築して運用していくのか、それともMackerelやNew Relicといった SaaS監視システムにお金を払って利用するのか、という監視システム運用の方向性の問題です。
私の場合は、会社でインフラエンジニアが私一人だったので、私の興味からZabbixを立てることにしました。
Zabbixに惹かれたのは主に「ネット上に先人の記事がそれなりに上がってる」「カスタムスクリプト書けばなんでもできる」「成長したイケてるベンチャーも使ってて実はダサくない」という3点で、とくにスクリプトを書けばなんでもできそうというのは、私自身のコーディング経験の足しにもできるし、アプリケーションエンジニアにも説明すれば監視業務にコミットしてもらえそうという期待からでした。
 CTOは新しくてイケてるSaaSを使うのが大好きだったので、実はすでにNew Relicが入っていました。しかし有料プランは結構高く、財布事情が許してくれなかったので、私の提案をしぶしぶ飲んで、Zabbixとの並行運用になりました。
そしていま運用して一年ちょいになりますが、Zabbixでできることが増えてきたので、New Relicはほとんど見ていません。
エージェント自体は残っているけど…。

監視システムに欲しい機能

監視システムには下にあげる機能が基本的に存在しているでしょう。
一部の特化型システムにはないものもあるかもしれないですが…。
そして、それらができるだけ自動化されていることが望ましいです。
ここでいう自動化とは、少ない手作業で必要な多くの作業をこなしてくれるという意味を含みます。 
  • 監視対象サーバ登録削除編集
  • 監視対象サーバの監視有効無効化
  • 監視項目追加削除編集
  • 閾値に応じたアラートの登録削除編集
    • 監視システムの画面上で表示
    • メール通知
    • 電話通知
    • スマートフォンアプリケーション通知(チャットとか)
  • 監視結果のグラフ表示
  • 複数のサーバのグラフを一元表示
  • カスタム(自作)スクリプト実行
  • カスタム(自作)監視項目追加削除編集
  • ユーザ複数作成と各ユーザの利用権限編集
  • 監視結果グラフをパッと見れるダッシュボード

やっておきたい連携

メール連携

原始的だけど社会人だったら誰でも理解できる説明がもっとも容易な連携。 
私の場合はZabbixのサーバにPostfixを入れて運用する様にしてしまったけれど、今から作り直すならSESのスタック立ててZabbixはそこを使う様にするかな…。
ついでにACMも認証させてSSL証明書もゲットしておくと尚よし。

チャットシステムとの連携

具体的には、Slack、HipChat、ChatWorkなど。
私の勤務先ではSlackを使っており、かつ有料プランになっているので、メール連携が使えたのでそれを使っています。
コードを書かずに連携できて超ラクです。ありがたや。
設定を行うとSlackからメールアドレスが発行されるので、それをZabbixでアラート通知用メールアドレスとして使用するだけです。
かんたん。
 障害、復旧、閾値オーバー、レスポンス速度悪化、バッチジョブ開始、バッチジョブ完了、サーバ新規追加、などをメール連携でSlackに飛ばす様にしていますが、開発チームみんなに全部投げるのもアレなので、何個かチャンネル分けて、たとえばたくさんの人がみる監視チャンネルには障害やジョブ失敗のアラートのみを投げる様にしています。
そんで、ジョブ成功とかは私だけが入ってるチャンネルを作ってそこに流したり。
半日単位とかでガーっとスクロールして流し見したりします。

電話連携

実はできていません…。
データセンターがメルアドを持っているので、そこにメール送って電話させようぜという人力電話連携構想が社内で湧いており、とりあえずそれでいっかな…。
そのうちTwillio連携とかさせたい。
優先度低い。

分けられる要素はできるだけ別インスタンスにしたい

たとえば私の場合はAWS上にZabbixを立てたわけですが、DBはRDSを利用しています。
その方がDBで心配する確率が減っていいです。
同様にメールサーバもZabbix内に立てるのではなく、SESなどを使った方がいいです。
その辺はケチったところで運用のための監視サーバのための運用がつらくなるだけなので、ある程度お金を使わせていただきたい…。

インフラエンジニア以外に使ってもらうにはお膳立て必須

  • ログインしてぱぱっと問題ないかを確認するまでの手順
  • 全体の状況を一覧で見れるダッシュボードへのアクセス手順
  • そういうダッシュボードの作成
  • チャットアプリに飛んでくるメッセージの意味と対処方法
  • よくある障害の内容と復旧方法
私の場合は多分まだ全然足りてなくて、10割オペレーションが7.5割に減ったくらいかな…。
マネージャーの上司にZabbixのスクリーンを教えたら自分でグラフ組み立てて性能レポート画面作ってたのはいい結果だったかなと思います。
障害対応とかはアプリケーションエンジニアにも少しずつシェアできると万々歳なんだけどそもそもPCを持ち帰っていないとか色々あるので私が対応…といってもサーバ多めにしてたりするので正統派なシステムダウンはもう全然起こっていません。
平日に利用者からくるアプリケーション不具合やデータ不整合に関する問い合わせ調査なんかはむしろ他のエンジニアにやってもらっているので、多分それでバランスはとれています…。

監視項目や検知内容は育てる前提で

監視項目はググって引っ張ってきていいと思いますが、まずは基本的に
  • CPU使用率
  • メモリ使用率
  • ロードアベレージ
を見ておけばいいのかなと思います。そしてそれらの使用率高騰のアラートを設定しておく。
DBは上記に加えて、
  • コネクション数
  • ストレージ残容量
なども必要ですね。気づいたらディスクがいっぱいでDB停止からのサービス停止とか怖いですね。
Webサーバのプロセス処理方式が Prefork の場合には
  • 稼働プロセス数
も監視しておいた方がいいですね。利用者が増えてくるとそこがボトルネックになることもあると思います。
それから運用しているWebサービスの主要エンドポイント(URL)の
  • レスポンスタイム
  • レスポンスコード
を見ておきましょう。
POSTが送れる場合はテストユーザでのログインとかをZabbixにやらせることもできると思いますので、そこでエラーコードが帰ってきたらログイン機能がトラブル!?みたいな検知もできるかなと思います。

手に入れた値はCloudWatchに寄せるのか、監視スステムに寄せるのか

AWS特有の悩みです。どっちかに決めるしかないです。悩ましいことにどっちもお互いにインポートすることができます。
私の場合は、CloudWatchは課金しないと2週間分しかログが残ってくれないので、一年単位でのトレンド分析とかそういうのには向いてなさそう…という理由でZabbix側に寄せることにしました。
つまり、CloudWatchが持ってる値のうち欲しいものをスクリプト書いてそいつに持ってこさせます。
するとZabbix側で好きにアラートやアクションを設定していろいろ処理することができます。
というかそういうことやらないとわざわざZabbix立てる意味はない…。

プロセス自動復旧

Zabbixの場合は、ダウンを検知したらZabbixからコマンド実行命令を出して復旧させることで自動復旧が実現できます。
私の場合はまだまだ導入が少ないので増やしていきたいところ…。

Mackerel使わないの?

なんか料金とインベントリ数だったかグラフ数だったか外形監視数だったかのコスパを考えると見合わないかなぁと思って検討をやめました。
プログラマフレンドリーっぽいので私がいなくなったらアプリエンジニアたちが乗り換えるかもしれません??


以上。
ある程度監視項目とか増えてきて回り始めると他のことに時間を取られて監視システムの成長が鈍化するのがつらいところ。
仲間が欲しい。

2016年10月18日火曜日

一部のユーザだけ NET::ERR_CERT_REVOKED でサイトにアクセスできない

一部のユーザから、HTTPSのURLにアクセスできなくなったという連絡を受けました。
なんでも攻撃される恐れのあるサイトですとかなんとか…。

ブラウザのスクリーンショットをもらってみたら、こんな表示が。













Google Chromeでも同じ感じのエラーメッセージが表示されていました。(サイト名が出るので省略…)
Chromeの方のエラーメッセージをよく見ると、 NET::ERR_CERT_REVOKED と書かれています。ファッ!?証明書が失効している…!?

そんな馬鹿なと思い手元でアクセスしてみたら普通に繋がる…HTTPSできてるよ?なんで?何が起こってるんだろう…。

結論を言うと、SSL証明書業者が手違いで中間CA証明書を失効させてしまったことにより、私たちが購入して使っている証明書が一時的に利用不可能になり、そのネガティブキャッシュをユーザが参照している、というお話でした。

解消のための新しい中間CA証明書が公開されていたので、そちらを使って更新してみると、問題は解消されました。
ただ、自社が買っていたのはクイックSSL証明書だとばかり思っていたので、更新に失敗しまくって時間がかかりました。違うやつだった…。

SSL証明書とかドメインの周りのメンテナンスは多くても年に数回とかっていう頻度なので、いろいろ思い出すのに苦労しますね。
ていうか、そういうことあるんですね、中間証明書間違って消しちゃった!とか。
レジストラのDNSサーバダウンと合わせて、「うちのせいじゃないんだけどご迷惑をおかけしてごめんなさい案件」って感じで覚えておきたい…。



2016年9月16日金曜日

ElasticBeanstalkの速習にチャレンジ

あー、なんか環境一式作ってくれるやつねー知ってるー使ったことないけどー…。
え?新しいアプリをElasticBeanstalkでローンチするの?それの運用やれ?
アプリはもうできている…??
ということで速習にチャレンジ。
これを社内ドキュメントシステムにも残して、他のメンバーにも運用させる目論見…w


Environment Type(環境タイプ)

  • Webサーバ と ワーカーがある
  • WebサーバタイプはHTTPポートを解放して外部からアクセスを受けるようなシステム全て。ユーザがブラウザでアクセスするタイプのソースコードを動かす場合は全部これ。
  • ワーカーはバックエンドのアプリのこと。SQSを使って他アプリというかシステムのワークフロー上の前後の機能とやりとりする。

DBの構築

  • RDSのインスタンスをElasticBeanstalkの構成の一部として起動することができる
  • アプリを消すとDBも自動的に削除される。もちろん最終スナップショットは取れる
  • 既存のRDSのスナップショットからRDSインスタンスを作成してそれをElasticBeanstalkアプリのDBにすることもできる
  • ElasticBeanstalkの構成の一部としないDBを作成することもできる。その場合は、ElasticBeanstalkアプリを削除してもDBが残る。作り方は多分RDSインスタンスを普通に作り、ElasticBeanstalkからそこへ接続する。
  • その他のDBに関する仕様はRDSを参照

VPC内への構築

  • 自分の既存のVPC内に構築することができる
  • Elastic Beanstalk は、Linux プロキシ設定(HTTP_PROXY、HTTPS_PROXY および NO_PROXY)をサポートしていない。
  • 直接インターネットからアクセスさせる(外部公開)するかNAT経由にする必要がある
  • VPC全般に言えるがUDP123番ポートを利用してNTPで時刻同期している。なのでNTPが利用できるように解放しておく必要がある。
  • 明示的にVPCを指定しないと自分のVPCを作ってそこに生まれる。

サービスロール、インスタンスプロファイル、ユーザーポリシー

  • サービスロール は 1個のサービスを正常に動かすために必要なポリシーをまとめたもの
  • ElasticBeanstalkサービスロールとは、Elastic Beanstalkが正常に動くために必要な各種権限が含まれたポリシーの集合体。
  • インスタンスプロファイル はElasticBeanstalkアプリを稼働させるEC2に付与するIAMロールのこと。
  • ユーザーポリシー はユーザIAMに適用できるElasticBeanstalkの権限ポリシーのこと。AWSユーザ側の話。

アプリのデプロイ

  • 基本的にアプリケーション全体をZipファイルにしてそれをアップロードすることでデプロイが行われる。
  • Webサーバのドキュメントルートに丸ごと置かれるとイメージしてよい?
  • 過去のバージョンのソースコードをはダウンロードできる。バージョンを戻すこともできる。

ebextensionsによるインフラ構築のカスタマイズ

  • アプリケーションのパッケージ(Zipファイル)のルートディレクトリに .ebextensions ディレクトリを作って、その中に filename.config の名前で yaml を書くと、ルールにしたがってインフラの構成変更を行ってくれる。
  • yum などから必要なプログラムをダウンロードしたり、決まった内容でファイルを生成したり、デーモンの起動停止設定を変更したりくらいはできる。
  • ebextension のファイル配布では、URLダウンロードか、インライン記述しかできない模様。つまり、アプリケーション内部の特定ファイルを指定してそれを配布することができない(ほんとに?)

CLIから構築すると圧倒的楽感が得られる

  • eb cli というコマンドラインツールがある。 awsコマンドの拡張的な位置づけで、awsコマンドとは別にインストールが必要
  • pip install awsebcli
  • eb cli は最新バージョンが3.x系となっていて、前のバージョン2.6とは非互換なところがある。今から始めるのであれば3.x系を使えば良い。
  • gitリポジトリを使うことが前提になっている。デプロイしたいアプリのリポジトリディレクトリのルートで eb init を実行する。
  • eb もリポジトリのように init してからそのディレクトリに Elastic Beanstalk アプリケーションの概念を植えてから作業を行っていく。
  • eb init は アプリケーション構築枠をElasticBeanstalkに確保した状態。枠だけなのでまだネットワークも構築されていないしEC2インスタンスも存在しない。
  • eb init で すでに存在している ElasticBeanstalkアプリケーションをカレントディレクトリのGitリポジトリと紐付けることもできる。アプリをシステム丸ごと移管された場合や、既存のシステムの開発に途中から参加する場合に使うと思う。
  • eb create で 「環境」を作る。「開発環境」とか「本番環境」などの「環境」のことだと思えばいい。システムの一式が作られる。つまり、ネットワーク、ELB、EC2が構築され、リポジトリのソースコードがデプロイされる。
  • eb create 実行時は対話でいろいろ聞かれる。構築するリージョンやアプリケーションの言語やELBの種類など。
  • eb create はオプションであらかじめ指定しないと、自分専用のVPCを作ってしまい、他のEC2らがローンチされている統合的なVPCで管理したいという思惑からそれてしまう。
  • eb cli の環境さえ整ってしまえば、あとは圧倒的に楽な感じがする。
  • eb cli のコマンドリファレンスは ここ をみると良い。そんなに種類は多くない。

DNSとSSL

  • ELBみたいに、Elastic BeanstalkアプリケーションにはAWSからDNS名が発行されるので、それをCNAMEレコードとしてDNSサーバに追加することができる。
  • Route53が利用できる場合はAレコードのエイリアスとして登録できる。そちらの方が良い。新規ドメインでのアプリ開発の場合はRoute53利用を前提にしたい。
  • SSL証明書は ACM(Amazon Certificate Manager)から発行される無料の証明書が利用できるので、それを適用できる。楽。

その他気づいたこと

  • Golang 1.5 でサンプルアプリを立ち上げてみたがSNSトピックが勝手にできた。承認URLが書かれたメールが飛んできた。SNSも使う想定で構築してくれる模様。
  • Elastic Beanstalk の公式ドキュメントは他のプロダクトより説明が抽象的で具体的にどうすればいいかわかりにくい印象。エンジニア向けかと思ったら経営層向けのような表現が出てきたり…。
  • Git使ったことない人は先にそっちを覚えたほうがいい。とりあえずは init して status して add して commit して push できるだけでよい。
  • とりあえず臆せずサンプルアプリを立ち上げて、管理画面がどうなっているのかとか、どのタイミングでEC2が生まれるのかとかの挙動を観察してからドキュメント読み込みに入ったほうが理解が早いかも。

次は

  • ebextensions という yaml群 を使うことでアプリのデプロイと一緒にインフラの設定変更やミドルウェアの追加などが可能となっている。自動で構築してくれる。それのやり方とか。
  • Zabbixエージェントとfluentdのインストールを自動化したい。
  • デプロイ時の挙動が選べるけどその辺どうすべき?とか

参考

AWS公式ドキュメント、クラスメソッドさんのブログ、Qiitaの順で漁りました。

2016年9月2日金曜日

PHPで書き込みができないからSELinuxを停止してと言われた

凄く短いコマンドだけどすぐ忘れちゃうのでメモ。知人から、SELinuxを停止してほしい、できれば指定するフォルダの部分だけ停止してほしい、という依頼を受けました。

話を聞いてみると、どうやらPHPを動かしたいディレクトリがあり、SELinuxのせいで権限エラーになっているようでした。
こういう時はSELinuxを停止するのではなく、設定を変更しましょう。 コンテキストと呼ばれています。

まず今どんなコンテキストになっているのかを確認します。

ls -Z

すると、 「system_u:object_r:httpd_sys_r_content_t:s0」 になっていました。 
これだと書き込みができないみたいなので、変更します。

semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/html/app/*"
restorecon -R /var/www/html/app

このあと確認してみると、 「system_u:object_r:httpd_sys_rw_content_t:s0」 に変わってました。

これでphpのエラーが消えました。
どうやらCakePHPでアプリを作るようです。
 俺もやろっかなCake。