Docker + Nginx + Let’s EncryptでHTTPS対応のプロキシサーバーを構築する

Docker上にNginxコンテナをプロキシサーバーとして構築し、Let’s EncryptでHTTPS対応しました。構築にあたって かなり苦戦した ので、そのノウハウを記事としてまとめました。

「Nginx」とは

Apacheなどの従来のWebサーバーは、クライアントの数が多くなるとサーバーがパンクする 「C10K問題(クライアント1万台問題)」 を抱えていました。「Nginx」はこの問題を解決するために誕生した、静的コンテンツを高速配信するWebサーバーです。2017年10月現在、そのシェアは Apacheとほぼ同等 となっています。

wpid-wss-share13.png

Webサーバー シェア
Micosoft IIS 49.44%
Apache 18.78%
Nginx 18.40%

「Let’s Encrypt」とは

「Let’s Encrypt」は すべてのWebサーバへの接続を暗号化する ことを目指し、SSL/TLSサーバ証明書を 無料 で発行する認証局(CA)です。シスコ、Akamai、電子フロンティア財団、モジラ財団などの大手企業・団体がスポンサーとして支援しています。


本稿が目指すシステム構成

本稿ではAmazon EC2、Dockerコンテナを使用して以下のようなシステムを構築することを目標とします。

DockerでNgixのプロキシサーバーを構築する.png

前提条件

  • 独自ドメインを取得していること(本稿で使用するドメインはexample.comとします)
  • IPv4パブリックIP(Elastic IP)がEC2インスタンスに設定されていること
  • EC2インスタンスにDocker、docker-composeがインストールされていること

事前に準備すること

DockerでHTTPS対応のプロキシサーバーを構築するにあたり、事前に以下の設定をしておく必要があります。

  • EC2のインバウンドルールで443ポートを開放する
  • DNSのAレコードを設定する
  • プロキシ用のネットワークを構築する

EC2のインバウンドルールで443ポートを開放する

インバウンドルールを以下のように設定し、443ポートを外部へ公開します。

タイプ プロトコル ポート範囲 ソース
HTTPS TCP 443 0.0.0.0/0
HTTPS TCP 443 ::/0

DNSのAレコードを設定する

DNSの設定方法は利用しているドメイン取得サービスによって異なります。例えばバリュードメインの場合、DNSの設定方法は「DNS情報・URL転送の設定 | VALUE-DOMAIN ユーザーガイド」に記載されています。

DNSのAレコードを以下のように設定します。xx.xx.xx.xxにはEC2インスタンスに割り当てられているIPv4パブリックIPを設定します。

a @ xx.xx.xx.xx
a www xx.xx.xx.xx

上記設定は以下を意味します。

  • example.com(サブドメイン無し)をIPアドレスxx.xx.xx.xxにポイントする
  • www.example.com をIPアドレスxx.xx.xx.xxにポイントする

プロキシ用のネットワークを構築する

プロキシサーバーとWebサーバー間のネットワークは外部との通信を行う必要がありません。そこで
プロキシサーバーとWebサーバー間の 内部ネットワーク を構築するため、EC2のインスタンスにログインし、以下のコマンドを入力します。

$ docker network create --internal sample_proxy_nw

上記コマンドは以下を意味します。

  • --internal: ネットワーク外との通信が行えないネットワークを作成します。
  • sample_proxy_nw: 任意のネットワーク名です。

以下のコマンドを入力し、ネットワークの設定情報がコンソールに出力されていることを確認しましょう。

$ docker network inspect sample_proxy_nw

Dockerコンテナの定義ファイルを作成する

事前準備が完了したら、Dockerコンテナの定義ファイルを作成しましょう。本稿におけるディレクトリ構成は以下のとおりです。

/path/to/dir/

.
├── docker-compose.yml // プロキシサーバーとWebサーバーのコンテナを定義するファイル
└── proxy
    ├── default.conf // プロキシサーバー上にあるNginxのデフォルト定義ファイル
    ├── Dockerfile // プロキシサーバーのイメージを構築するためのファイル
    └── entrypoint.sh // プロキシサーバーにSSL証明書を取得するためのファイル

以下では、各ファイルの内容を解説します。

./docker-compose.yml

docker-compose.ymlでは、以下のコンテナを定義しています。

  • proxy: プロキシサーバー(Nginxベース)
  • web1: Webサーバー(httpdベース)
  • web2: Webサーバー(httpdベース)
version: '3'
services:
  proxy:
    build: ./proxy
    tty: true
    image: sample_proxy
    container_name: sample_proxy
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    ports:
      - "443:443"
    volumes:
      - '/srv/letsencrypt:/etc/letsencrypt'
    networks:
      - default
      - sample_proxy_nw
    depends_on:
      - "web1"
      - "web2"
    command: ["wait-for-it.sh", "sample_web1:80", "--", "./wait-for-it.sh", "sample_web2:80"]
  web1:
    image: httpd
    container_name: sample_web1
    tty: true
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    networks:
      - sample_proxy_nw
  web2:
    image: httpd
    container_name: sample_web2
    tty: true
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    networks:
      - sample_proxy_nw
networks:
  proxy_nw:
    external: true

上記コマンドは以下を意味します。

  • サービスproxyports: 外部からのHTTPSアクセスとproxyサーバーの内部ポートを疎通させるため、443:443を定義します。
  • サービスproxyvolumes: /srv/letsencrypt:/etc/letsencryptを定義します。/etc/letsencryptLet’s Encryptで取得した証明書が生成されるディレクトリ です。
  • networks: 上述の説明で生成したsample_proxy_nwを各サービス(proxy, web1, web2)に定義します。
  • depends_on: コンテナの起動順序を制御するオプションです。 Nginxのproxy_passに設定されているWebサーバーが起動していない状態でプロキシサーバーが起動した場合にエラーとなる ため、web1, web2を設定します。

./proxy/default.conf

./proxy/default.confはNginxのデフォルト定義ファイル(/etc/nginx/conf.d/default.conf)を書き換えるためのファイルです。

server{

    server_name example.com www.example.com;

    proxy_redirect off;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-Server $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    location / {
        proxy_pass    http://sample_web1/;
    }

    location /example/ {
        proxy_pass    http://sample_web2/;
    }

}

上記設定は以下を意味します。

  • server_name: ユーザーから要求されるHTTPリクエストのヘッダに含まれるHostフィールドとserver_nameが一致した場合、該当するサーバ設定を採用します。Nginxではキャッチオールサーバーとして_を定義することもできますが、 certbot-autoがサーバー情報を正しく取得することができない ため、上記のようにドメイン名を入力します。
  • location: ルートディレクトリ(example.com/)とサブディレクトリ(example.com/example/)にアクセスした際の振り分け先URIを設定します。proxy_passには、http://[コンテナ名]/を設定します。コンテナ名はdocker-compose.ymlのcontainer_nameで設定した名前となります。
    また、http://sample_web1/のように 末尾に/を入れる ことに注意しましょう。例えばlocation /example/において、プロキシパスの末尾に/が含まれていない(http://sample_web2)場合、振り分け先は http://sample_web2/example/となってしまいます。

./proxy/Dockerfile

FROM nginx
COPY default.conf /etc/nginx/conf.d/default.conf
RUN apt-get update && apt-get install -y \
        wget && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*
ADD https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh /usr/local/bin/wait-for-it.sh
RUN chmod +x /usr/local/bin/wait-for-it.sh
ADD https://dl.eff.org/certbot-auto /usr/local/bin/certbot-auto
RUN chmod a+x /usr/local/bin/certbot-auto
RUN certbot-auto --os-packages-only -n
COPY ./entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]

上記設定は以下を意味します。

  • ADD https://dl.eff.org/certbot-auto /usr/local/bin/certbot-auto: Let’s Encryptが発行するSSL/TLSサーバ証明書を自動で取得・更新するツール「 certbot-auto 」をダウンロードします。

./proxy/entrypoint.sh

#!/bin/bash
certbot-auto --nginx -d example.com -d www.example.com -m your-account@gmail.com --agree-tos -n
certbot-auto renew
/bin/bash

上記設定は以下を意味します。

  • --nginx: プロキシサーバーにNginxを使用する場合のオプションです。default.confの設定を自動的に書き換えます。(2017年12月現在、アルファ版のプラグイン)
  • -d example.com -d www.example.com: SSL/TLSサーバ証明書の取得を申請するドメイン名を指定します。
  • -m your-account@gmail.com: アカウントの登録や回復などに使用する電子メールアドレスを指定します。
  • --agree-tos: Let’s Encryptの利用規約に同意します。
  • -n: インタラクティブ設定をオフにします。
  • ./certbot-auto renew: 3ヶ月で失効する SSL/TLSサーバ証明書を自動で更新します。

以下のコマンドを入力してentrypoint.shに 実行権限を付与する ことを忘れないようにしましょう。

$ chmod +x entrypoint.sh

Dockerコンテナを起動する

それでは以下のコマンドを入力してDockerコンテナを起動しましょう。

docker-compose up -d

しばらく時間をおいてから、以下のコマンドを入力します。

docker-compose logs

以下のように出力されていれば成功です。

-------------------------------------------------------------------------------
Congratulations! You have successfully enabled https://example,com and
https://www.example.com

You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=example.com
https://www.ssllabs.com/ssltest/analyze.html?d=www.example.com
-------------------------------------------------------------------------------

HTTPSでアクセスする

ブラウザを起動し、実際に以下のURLにアクセスしてみましょう。

Chromeブラウザの場合はデベロッパーツール > Security > View certificateからSSL/TLSサーバ証明書を確認することができます。

「発行元: Let’s Encrypt Authority X3」となっているはずです。

続きを読む

TerraformでAWS AMIの最新を常に使うようにする

TerraformとAWSに同時入門する
の続きで、

最新のAMIが常に指定されるようなami設定にする

を行えるようにします。

確認環境

$ terraform version
Terraform v0.11.1
+ provider.aws v1.5.0

取得するAMIのスペック

今回は2017/12/10時点でのAmazon Linuxの下記スペックにおける最新AMI ID(ami-da9e2cbc)を取得します。
最新AMI IDはこちらで確認できます: Amazon Linux AMI ID

  • リージョン: アジアパシフィック東京
  • 仮想化タイプ: HVM
  • ルートデバイスタイプ: EBS-Backed
  • アーキテクチャ: x86_64
  • ボリュームタイプ: gp2

:warning: 注意点
AMI IDはリージョン毎に異なるようなので複数リージョンにまたがった環境の場合は注意が必要かもしれません

結論

簡易版

フィルタ条件はAMI Image名の条件のみ

aws_ami.tf
data "aws_ami" "amazon_linux" {
  most_recent = true
  owners = ["amazon"]

  filter {
    name   = "name"
    values = ["amzn-ami-hvm-*-x86_64-gp2"]
  }
}

詳細版

フィルタ条件として今回の指定スペックをすべて指定

参考: Terraformでもいつでも最新AMIからEC2を起動したい

aws_ami.tf
data "aws_ami" "amazon_linux" {
  most_recent = true
  owners = ["amazon"]

  filter {
    name   = "architecture"
    values = ["x86_64"]
  }

  filter {
    name   = "root-device-type"
    values = ["ebs"]
  }

  filter {
    name   = "name"
    values = ["amzn-ami-hvm-*"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }

  filter {
    name   = "block-device-mapping.volume-type"
    values = ["gp2"]
  }
}

EC2側の設定

ec2.tf
resource "aws_instance" "web-server" {
  ami                    = "${data.aws_ami.amazon_linux.id}"
  instance_type          = "t2.micro"
}

確認

$ terraform plan

  + aws_instance.web-server
      id:                           <computed>
      ami:                          "ami-da9e2cbc"
      ...

AWS CLIでAmazon Linux AMI image名を取得してみる

準備

AWS Command Line Interface のインストール

簡易版のフィルタ条件の説明

AWS CLIで最新のAmazon LinuxのAMI IDを取得する
上記でのシェルを参考に今回取得したい条件に変更します

get-aws-ec2-image.sh.sh
...

describe_images(){
    echo $timestamp > $timestamp_file
    aws ec2 describe-images 
-       --owners self amazon 
+       --owners amazon 
        --filters 
+         Name=name,Values="amzn-ami-hvm-*" 
          Name=virtualization-type,Values=hvm 
          Name=root-device-type,Values=ebs 
          Name=architecture,Values=x86_64 
-         Name=block-device-mapping.volume-type,Values=standard
+         Name=block-device-mapping.volume-type,Values=gp2
}

...

実行結果

$ zsh ./get-aws-ec2-image.sh

amzn-ami-hvm-2014.03.2.x86_64-gp2: ami-df470ede
amzn-ami-hvm-2014.09.0.x86_64-gp2: ami-45072844
amzn-ami-hvm-2014.09.1.x86_64-gp2: ami-4585b044
amzn-ami-hvm-2014.09.2.x86_64-gp2: ami-1e86981f
amzn-ami-hvm-2015.03.0.x86_64-gp2: ami-cbf90ecb
amzn-ami-hvm-2015.03.1.x86_64-gp2: ami-1c1b9f1c
amzn-ami-hvm-2015.09.0.x86_64-gp2: ami-9a2fb89a
amzn-ami-hvm-2015.09.1.x86_64-gp2: ami-383c1956
amzn-ami-hvm-2015.09.2.x86_64-gp2: ami-59bdb937
amzn-ami-hvm-2016.03.0.x86_64-gp2: ami-f80e0596
amzn-ami-hvm-2016.03.1.x86_64-gp2: ami-29160d47
amzn-ami-hvm-2016.03.2.x86_64-gp2: ami-6154bb00
amzn-ami-hvm-2016.03.3.x86_64-gp2: ami-374db956
amzn-ami-hvm-2016.09.0.20160923-x86_64-gp2: ami-1a15c77b
amzn-ami-hvm-2016.09.0.20161028-x86_64-gp2: ami-0c11b26d
amzn-ami-hvm-2016.09.1.20161221-x86_64-gp2: ami-9f0c67f8
amzn-ami-hvm-2016.09.1.20170119-x86_64-gp2: ami-56d4ad31
amzn-ami-hvm-2017.03.0.20170401-x86_64-gp2: ami-859bbfe2
amzn-ami-hvm-2017.03.0.20170417-x86_64-gp2: ami-923d12f5
amzn-ami-hvm-2017.03.1.20170617-x86_64-gp2: ami-bbf2f9dc
amzn-ami-hvm-2017.03.1.20170623-x86_64-gp2: ami-3bd3c45c
amzn-ami-hvm-2017.03.1.20170812-x86_64-gp2: ami-4af5022c
amzn-ami-hvm-2017.03.rc-0.20170320-x86_64-gp2: ami-be154bd9
amzn-ami-hvm-2017.03.rc-1.20170327-x86_64-gp2: ami-10207a77
amzn-ami-hvm-2017.09.0.20170930-x86_64-gp2: ami-2a69be4c
amzn-ami-hvm-2017.09.1.20171103-x86_64-gp2: ami-2803ac4e
amzn-ami-hvm-2017.09.1.20171120-x86_64-gp2: ami-da9e2cbc
amzn-ami-hvm-2017.09.rc-0.20170913-x86_64-gp2: ami-d424e7b2

最新AMI ID(ami-da9e2cbc)が取得できているのがわかります。

amzn-ami-hvm-2017.09.1.20171120-x86_64-gp2: ami-da9e2cbc

取得結果からわかるようにImage名にはスペック名も含まれていることがわかります。

よって今回のスペックのAMI IDはImage名でのフィルタ条件のみで取ることができるため、簡易版ではImage名の値が"amzn-ami-hvm-*-x86_64-gp2"とするフィルタ条件1つで最新のAMI IDを取得していました。

また、aws_ami.tfではmost_recent = trueという設定により取得した中で最新のAMI IDが取得されます。

:warning: Image名の命名規則が変更された場合に指定スペックの最新が取得できなくなるので注意ください

フィルタ条件をnameのみにしてAWS CLIでも確認

AWS CLI側でも一応確認

get-aws-ec2-image.sh
describe_images(){
    echo $timestamp > $timestamp_file
    aws ec2 describe-images 
        --owners amazon 
        --filters 
          Name=name,Values="amzn-ami-hvm-*-x86_64-gp2" 
-          Name=virtualization-type,Values=hvm 
-          Name=root-device-type,Values=ebs 
-          Name=architecture,Values=x86_64 
-          Name=block-device-mapping.volume-type,Values=gp2
}
$ zsh ./get-aws-ec2-image.sh | grep ami-da9e2cbc

amzn-ami-hvm-2017.09.1.20171120-x86_64-gp2: ami-da9e2cbc

最新AMI ID(ami-da9e2cbc)が取得できているのがわかります。

その他の参考

続きを読む

re:Invent 2017 TUESDAY NIGHT LIVEまとめ

Fusic Advent Calendar 2017 の3日目の記事です。

re:Invent 2017では下記の3つの基調講演で様々なサービスや新機能が発表されました。
・TUESDAY NIGHT LIVE
・KEYNOTE DAY1
・KEYNOTE DAY2

本日はTUESDAY NIGHT LIVEについてまとめました。

TUESDAY NIGHT LIVE

大きく下記の3テーマが語られます。
・COMPUTING AT SCALE
・LOAD BALANCING AT SCALE
・SECURIRY AT SCALE

「SCALE」という言葉が強調されてますね。

ANATOMY OF AN AWS REGION

https://www.youtube.com/watch?time_continue=124&v=dfEcd3zqPOA#t=7m23s

・AWSは最初の5年で4リージョン、次の5年で7リージョンを開設してきました。(10年で11リージョン)
・そして、2016年、2017年、2018年でさらに11リージョンを開設します。
・これらのリージョン間のネットワークを強化してグローバルなよりネットワークにしていく

COMPUTING AT SCALE

https://www.youtube.com/watch?time_continue=124&v=dfEcd3zqPOA#t=14m01s

・ここ数年でGPU & FPGAの利用が急成長している
・P3インスタンスの利用方法についての説明
 -> 機械学習
  -> 自動運転に関する企業の紹介

 1. ハードウェアの進化
 2. 機械学習フレームワーク
 3. 急成長するコミュニティ(GLUON)

AMAZON EC2 INSTANCES

https://www.youtube.com/watch?time_continue=124&v=dfEcd3zqPOA#t=27m33s

・Amazon EC2の基本的なアーキテクチャの説明
・EC2の進化
 1. EC2 Hosts
 2. EC2 Managment Services
 3. Amazon EBS
 4. Nitro System(AWS独自開発のクラウド基盤)

・EC2の目標
1. セキュリティ
 AWSの最も大事な品質はセキュリティとも語っている
2. パフォーマンス
 EC2インスタンスパフォーマンスは、他のパフォーマンス全てに関わる重要事項
3. 親しみやすさ

・Nitro System
1. C3インスタンス
 -> ネットワークパケットのプロセスをNitro Systemに移行
 -> レイテンシーの50%向上
2. C4インスタンス
 -> ストレージのプロセスをNitro Systemに移行
 -> EBS最適化がデフォルト化
 -> 12.5%計算力向上
3. C5インスタンス
 -> Custom Nitro ASICを選択
 -> Annapurna labsが開発
 -> Custom Nitro ASICを導入したのがC5インスタンス(Nitro Hypervisor)
  -> コアの技術はKVM
4. Bare Metal Instances

例) AUTODESK

https://www.youtube.com/watch?time_continue=124&v=dfEcd3zqPOA#t=48m44s
・機械学習による設計
・GENERATIVE DESIGN
・GENERATIVE DESIGNによって飛行機のドアなどを設計

https://www.autodesk.co.jp/solutions/3d-design-software?referrer=%2Fsolutions%2F3d-design-software

LOAD BALANCING AT SCALE

https://www.youtube.com/watch?time_continue=124&v=dfEcd3zqPOA#t=1h04m32s
・AWS最初のLOAD BALANCING紹介(32MB)

THE GOLDEN AGE PF HARDWARE LOAD BALANCIERS

・GOOD
・信頼性、スケーラビリティ、俊敏性を実現する簡単な方法
・プロバイダの増加、パフォーマンスの向上、機能の向上、コストの削減

・BAD
・ロードバランサーのコストの割合が増加している
・運用上の課題

ロードバランサーの問題点① BLACK BOX

・ハードウェアがブラックボックス化しており、問題を課題を解決できない
・他のユーザの真ん中ぐらいで利用して最初に問題に直面しないようにしていた

ロードバランサーの問題点② Virtual IPの数

・設定が煩雑
・10年前のVIP数 6,000
・現在のVIP数 600,000

Hyperplane

HARDWARE LOAD BALANCIERS
・2Nアーキテクチャでは最大で50%の利用率になる

S3 LOAD BALANCIERS
・Hyperplane(S3 分散型 ロードバランサー)

下記のサービスで利用されている
1. Amazon Elastic File System(EFS)
2. AWS Managed NAT
3. AWS Network Load Balancer(NLB)
4. AWS PrivateLink

PrivateLink (個人的に大注目)

・インターネットを介さずにサービスにアクセス可能
・複数アクセス間のVPCに対してサービス提供が可能
・APNはもっと簡単にサービス提供が可能

SECURIRY AT SCALE

https://www.youtube.com/watch?time_continue=124&v=dfEcd3zqPOA#t=1h22m50s
・自動化とツール化
・機械学習
・ベストプラクティス
・パートナー

・開発者もセキュリティエンジニアでもある
・AWSはセキュリティ対策を自動化している

AMAZON MACIE

・データアクセスアクティビティのモニタリング

AMAZON GuardDuty

・AWSアカウント全体の監視

※ セキュリティのポイント:人をデータから引き離す
※ AWSの文化はセキュリティを非常に大切にする

参考サイト
https://aws.amazon.com/jp/about-aws/events/reinvent2017-1128/
https://dev.classmethod.jp/cloud/aws/aws-reinvent-tuesdaynightlive-engineers-eye/
https://dev.classmethod.jp/cloud/aws/aws-reinvent-2017-keynote-day-1/
https://dev.classmethod.jp/cloud/aws/aws-reinvent-2017-keynote-day-2/
https://www.youtube.com/playlist?list=PLhr1KZpdzukfZxFGkA796dKaUufAgnU4c

続きを読む

クラウドベンダーの比較

はじめに

3大クラウドと呼ばれているAWS、GCP,Azureのリソースを比べてみました。
2017年11月時点の比較となります。

インフラ・サービスレベル

比較項目 AWS GCP Azure 備考
データセンター 各地で借りている すべて自前 各地で借りている(一部自前)
仮想化技術 Xen KVM Hyper-V
リージョン(国内) 1個所 1個所 2個所
リージョン(全国) 15個所 12個所 36個所
SLA 99.95 99.95 99.95 仮想サーバ

サービス面

比較項目 AWS GCP Azure 備考
仮想サーバ Amazon EC2 Google Compute Engine Azure Virtual Machines
仮想サーバ対応OS Amazon Linux,CentOS,RedHat,Windows Server,等 CentOS,RedHat,SLES,Windows Server,等 CentOS,RedHat,Windows Server,等
仮想サーバディスク SSD,HDD SSD,HDD SSD,HDD
仮想サーバスナップショット
仮想サーバオートスケール
コンテナ Amazon ECS Container Engine Container Service
RDB RDS Cloud SQL SQL Database
RDB冗長化
RDBリードレプリカ
RDB DB種別 Aurora,MySQL,MariaDB,Oracle,SQL Server,PostgreSQL MySQL,PostgreSQL SQL Server
NoSQL DynamoDB Cloud Datastore Cosmos DB
ビックデータ Redshift BigQuery App Service
メール Amazon SES
モニタリングツール CloudWatch Stackdriver Azure Monitor
ロードバランサー(L4) CLB Network load balancing Azure Load Barancer
ロードバランサー(L7) ALB HTTP load balancing Application Gateway
CDN Amazon CloudFront Google Cloud CDN Azure CDN
VPN Amazon VPC Google Cloud VPN VPN Gateway
DNS Route53 Google Cloud DNS Azure DNS
専用線 Direct connect Dedicated Interconnect Express Route

サポート面

比較項目 AWS GCP Azure 備考
ランク低 開発者 ($29/月 or 利用料の 3%/月) シルバー ($150/月) Standard($300/月)
ランク中 ビジネス($100/月 or 利用料 の10%/月) ゴールド($400/月) Professional Direct($1,000/月)
ランク高 エンタープライズ($15,000/月 or 利用料の10%) プラチナ(問合せ) Premier(問合せ)

費用面(リージョン日本)

比較項目 AWS GCP Azure 備考
課金単位
ディスカウント リザーブドインスタンス(前払い) 継続利用割引、利用確約の割引(前払い) エンタープライズ契約(前払い)
仮想サーバ(Type) t2.medium(2vCPU,4GB) n1-standard-2(2コア,7.5GB) A2 V2(2コア,4GB)
仮想サーバ(時) $0.0464(5.336円)※1 $0.0950(10.925円)※1 $0.15(17.25円)※1
仮想サーバ(月) $33.408(3841.92円)※1 $48.17(5539.55円)※1,※2 $108(12,420円)※1
インターネットへの転送量 $0.140/GB(10TBまで) $0.12/GB(1TBまで) $0.138/GB(5GB-10TB、5GBまでは無料)
ストレージ利用料 $0.025/GB (最初の50TB/月まで) ※S3 $0.016/GB 月 ※Regional Storage $0.2/GB(最初の50TB/月まで) ※BLOG Storage

※1 $1=115円換算
※2 継続利用割引含む

総括

 AWS、GCP,Azureでのサービス面では同じようなサービスを展開していることが判明。
 インフラ・サービスレベルでは、Azureがリージョン36個とTOPに。
世界的に見て幅を利かせているように思えた。
ただ、GCPはすべて自前のセンターでクラウドサービスを展開していることから、
新しいことをやるにも制約が低いように思えた。
私のイメージ的に一番シェアが高いAWSは、インフラ面ではGCP,Azureに劣っている結果となった。
 費用面では、Azureは割高。AWSが思ったよりも頑張っているように思えた。
 イメージ的にGCPは費用は安いと思っていたが、仮想サーバ比較だと、継続利用割引を使用してもAWSのほうが安い結果となった。
 ただ、費用に関しては、日々値下げ合戦が繰り広げられているので、今後のベンダーさんの努力に期待です。

最後に、費用面での算出に使用した見積もりツールです。
【AWS】http://calculator.s3.amazonaws.com/index.html
【GCP】https://cloud.google.com/products/calculator/?hl=ja
【Azure】https://azure.microsoft.com/ja-jp/pricing/calculator

続きを読む

AWS re:Invent 2017 HPC(+α)関連セッション資料リンク集

AWS re:Invent 2017に行ってきました。これから各種報告会で話すにあたり、自分の参加したセッションの資料リンク集を作りました。せっかくなので公開しておきます。主にHPC関連で、少しDeep LearningやBig Data関連を含みます。

AMF304 – Optimizing Design and Engineering Performance in the Cloud for Manufacturing

CMP207 – High Performance Computing on AWS

AMF305 – Autonomous Driving Algorithm Development on Amazon AI

STG205 – #EarthonAWS: How NASA Is Using AWS

STG206 – Big Data: Data Lakes and Data Oceans

CMP323 – AWS Batch: Easy and Efficient Batch Computing on AWS

CMP333 – How to Get the HPC Best-in-class Performance via Intel Xeon Skylake Processors and AWS C5 Instances with Ease of Deployment Through Rescale

CMP306 – Architectures for HPC/HTC Workloads on AWS

CMP402 – Accelerate Your C/C++ Applications with Amazon EC2 F1 Instances

MCL212-R2 – [REPEAT 2] NEW LAUNCH! AWS DeepLens workshop: Building Computer Vision Applications

続きを読む

AIで抜きん出る、Googleクラウドの活用事例が増加中

AWSでは、仮想マシン「Amazon EC2」やストレージ「Amazon S3」、データウエアハウス「Amazon Redshift」などを利用。オンプレミス環境にあった分散処理ソフト「Hadoop」で構築した分析基盤を同様のAWSサービス「Amazon Elastic MapReduce(EMR)」に移行したうえで、「リクナビやカーセンサーといったサービスで … 続きを読む

AWS、新しい3つのAmazon EC2インスタンスを発表

AWS、新しい3つのAmazon EC2インスタンスを発表. @IT 12/4(月) 8:00配信. H1インスタンスで提供される4つのインスタンスサイズ. 【関連記事】. M5インスタンスで提供される6つのインスタンスサイズ · 日本マイクロソフト、Microsoft Azure GシリーズとSAP HANA on Azureの推進を発表 · 国内でもSAP on Azureが実現 … 続きを読む

【AWS】【EMR】スポットインスタンスでの安定稼働を目指して(1/3):スポットインスタンスとは

こちらはフロムスクラッチ Advent Calendar 2017の3日目の記事です。

EEEEEEEEEEEEEEEEEEEE MMMMMMMM         MMMMMMMM RRRRRRRRRRRRRR
E::::::::::::::::::E M:::::::M       M:::::::M R::::::::::::::R
EE:::::EEEEEEEEE:::E M::::::::M     M::::::::M R:::::RRRRRR:::::R
  E::::E       EEEEE M:::::::::M   M:::::::::M RR::::R      R::::R
  E::::E             M::::::M:::M M:::M::::::M   R:::R      R::::R
  E:::::EEEEEEEEEE   M:::::M M:::M:::M M:::::M   R:::RRRRRR:::::R
  E::::::::::::::E   M:::::M  M:::::M  M:::::M   R:::::::::::RR
  E:::::EEEEEEEEEE   M:::::M   M:::M   M:::::M   R:::RRRRRR::::R
  E::::E             M:::::M    MMM    M:::::M   R:::R      R::::R
  E::::E       EEEEE M:::::M           M:::::M   R:::R      R::::R
EE:::::EEEEEEEE::::E M:::::M           M:::::M   R:::R      R::::R
E::::::::::::::::::E M:::::M           M:::::M RR::::R      R::::R
EEEEEEEEEEEEEEEEEEEE MMMMMMM           MMMMMMM RRRRRRR      RRRRRR

当記事に興味を持っていただきありがとうございます。

この記事では、AWS EMR利用者向けにスポットインスタンスを使いつつも、それら安定的に稼働させることを目指して私が取り組んでいることを紹介する記事です。
AWS EMRが何モノで、何をすることできるのか、ということは知っていることを前提として記載していますので、ご了承ください。(その辺を知りたい方は、記事末尾にリンクくっつけときますのでどうぞ。)

そもそもスポットインスタンスとは何なのか

この辺りの紹介記事は星の数ほどありますが、改めて紹介しておきます。

AWS EMRを特に何も考えずに採用すると、オンデマンドと呼ばれる課金形態で構築され、インスタンスサイズごとに定義されている固定額(以下、オンデマンド価格)が利用時間に応じて課金されていきます。
価格表を見ると、1時間単位での課金額が記載されていますが、実際には秒単位での課金となるようです。(最近変わったそうです:AWSの方からの情報)

一方でスポットインスタンスは、AWS EMRに限らずAmazon EC2などのサービスででも使用できる利用形態のオプションの1つで、AWSの余剰インスタンスを入札制で安価に利用できるというものです。
その値引率は・・・オンデマンド比で最大で90%にもなります。

ものすごい割引率ですが、Amazonからすると、余剰リソースを腐らせておくぐらいだったら、安くてもいいから使ってもらったほうがいい、ということなのでしょう。

スポットインスタンスの設定方法

ここではAWSコンソール上から設定する方法について述べます。

  1. スポットインスタンスはEMRクラスター作成時に、クイックオプションでは選択することができないため、作成フォーム上部の「詳細オプション」を選択します。
    quick.png

  2. 「ステップ2:ハードウェア」の項目で、EMRクラスターの各ノードに対して「スポット」を選択します。
    detail.png

  3. あとはよしなに作ります。

  4. 作成した後に確認する場合はスポットの詳細画面を開き、「ハードウェア」タブを選択することで確認できます。
    confirm.png

スポットインスタンスのデメリット

メリットは前述の通り安価であることです。が、しかしデメリットもあります。それは安定性です。

スポットインスタンスは前述の通り、余剰リソースに対する入札制であるため、需給のバランスによって課金額(以下、スポット価格)が増減します。
価格決定のロジックは以下のようになっているようです。(公式ドキュメント、及びAWSの方からの情報)

  1. AWS全体で抱えているリソースの中から、オンデマンドに割り当てられていないものを、入札額が高い人から順に割り当てる。
  2. 実際に割り当てられた人の中でもっとも入札額が低い人の入札額が、その時点での価格となる。(図の例では$2.50を入札額に設定していた人であっても、実際には$0.03が課金される。)

[価格決定のロジック例]
Untitled (4).png

なお、上図でも表現しているのですが、オンデマンドとスポットは同じリソースプールを共有するため、スポット価格はオンデマンドを使っているユーザーが増加した場合でもスポット価格は上昇します。

この価格決定のロジックによって、このスポット価格がオンデマンド価格を超えてしまう(最大でオンデマンド価格の10倍程度まで上昇する)こともあるのです。(キャプチャ参照)

[スポットインスタンス価格変動状況例]
スクリーンショット 2017-12-03 15.59.39.png

しかし、キャプチャから見てみたいただいても分かる通り、一時的に高騰することもあるものの、総じて言えば安価で稼働させていくことができます。

スポット価格高騰時の振る舞い

では、このスポット価格が入札額を超えるとどうなるか、ですが、

【起動時に、スポット価格が設定されている入札額を超えている】
EMRインスタンスは起動中の状態となり、各ノード(マスター・コア・タスク)はスポット価格が入札額以下になるまでプロビジョニング状態で待機する。
 
【起動後に、スポット価格が設定されている入札額を超えた】
入札額を超えてから、2分後にEMRインスタンスは強制的に停止する。

という振る舞いになります。

どちらも使いたい時に使えないという意味ではかなり手痛いのですが、特に後者はせっかく時間かけて処理をさせていたものが無駄になってしまいます。

成功するまでリトライすれば良いものであれば良いのですが・・・、ある日時までにできていなければならないなど、一定安定性をもって使うことが求められる場合にはスポットインスタンスは諦めるしかないのだろうか?

いやいや、諦めたら試合終了だよ?ということで、次回から本格的に対策を説いていきます。
(応援してくれたら、きっと書き上げるの早くなると思いますので、よろしくお願いします!!)

明日のフロムスクラッチ Advent Calendar 2017の4日目は@nrk_babyさんです。

参考文献

EMR

・EMR: AWS上のマネージド型のHadoopフレームワークhttps://qiita.com/uenohara/items/36aadaa8884359b8674b
・AWS EMR(公式)
https://aws.amazon.com/jp/emr/details/
・Amazon EMR 料金(公式)
https://aws.amazon.com/jp/emr/pricing/
・AWS CLI Command Reference – create-cluster (公式:英語)
http://docs.aws.amazon.com/cli/latest/reference/emr/create-cluster.html

EC2スポットインスタンス

・Amazon EC2 スポットインスタンス(公式)
https://aws.amazon.com/jp/ec2/spot/
・スポットインスタンスを安定して利用するための取り組みhttps://qiita.com/megadreams14/items/766ce04ca6cb418e95ca

続きを読む

TerraformとAWSに同時入門する

GMOペパボ、ムームードメインのエンジニア@litencattです。

昨日は@dp42による、“Hello, World.”の次としてのチャットボットでした。

今日は、入社以来専らWeb開発がメインでやってきたけど、最近興味のあるAWSやTerraformによるインフラ構築について読んだ本をベースにやってみたことについて書いていきます。

やること

Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂版のインフラ環境や手順を参考に、AWS環境構築をTerraformを用いて行います。

なお今回はApacheなどEC2インスタンスに対する各種インストールは直接インスタンス内に入ってコマンド実行しています。

ゴール

AWS上に以下の環境構築を行ないます

  • EC2インスタンス x 2台

    • Webサーバ

      • インターネットゲートウェイを持つ
      • Apache(httpd)上でWordPressが動作している
    • DBサーバ
      • NATゲートウェイを通してインターネットに接続する
      • MySQLが起動している

具体的には以下のAWSリソースを扱います。

  • EC2
  • VPC
  • サブネット
  • ルートテーブル
  • インターネットゲートウェイ
  • セキュリティグループ
  • Elastic IP
  • NATゲートウェイ

今回参考にした本について

ネットワークにつての基礎的な用語について詳しい説明があったり、AWSで構築していく環境についての図がとてもわかりやすいのでこのあたり初めてな人にはおすすめな本だと思いました!

Terraformとは

  • AWSなど様々なサービスProviderに対して、サーバの構築・変更・管理を行うためのツール
  • HashiCorpのプロダクト
  • Enterprise版もあるみたい

ペパボではプライベートクラウドとしてOpenStackを自社運用しています。
TerraformはOpenStackにも対応しており、最近は各サービスのインフラ管理がTerraformで行われるようになってきています。

今回はこのTerraformをAWSに対して使っていきます。
https://www.terraform.io/docs/providers/aws/index.html

今回のコードのレポジトリ

https://github.com/litencatt/terraform-aws-templates

準備

Terraformのインストール(Mac)

$ brew install terraform

使用バージョン

2017/12/3の執筆時点での最新リリースバージョンをつかいます

$ terraform version
Terraform v0.11.1
+ provider.aws v1.5.0

https://github.com/hashicorp/terraform/blob/master/CHANGELOG.md#0111-november-30-2017

主にVim向け

HCL扱う場合は入れとくと便利そうです
https://github.com/hashivim/vim-hashicorp-tools

AWSの準備

terraform.tfvarsの設定

今回はAWSのアクセスキーなどの秘匿情報をterraform.tfvarsに持つようにしています。
ここに作成したアクセスキーとシークレットアクセスキーを設定してください。
リージョンなども変更したい場合は必要に応じて変更してください。

terraform.tfvars
access_key = "AWS_ACCESS_KEY"
secret_key = "AWS_SECRET_KEY"
region     = "ap-northeast-1"
key_name   = "KEY_PAIR_NAME"

:warning:実際のアクセスキーなどが書かれたterraform.tfvarsはレポジトリには登録しないよう注意ください

EC2インスタンスへのログイン時に必要な鍵ファイルについて

今回はAWSのダッシュボード上のキーペアで鍵を作成し、それをEC2インスタンス作成時に使用するように指定しています。そのため、key_nameには作成したキーペア名を設定してください。

VPC作成

まずはVPCを作成します
https://github.com/litencatt/terraform-aws-templates/pull/1

main.tf
+variable "access_key" {}
+variable "secret_key" {}
+variable "region" {}
+
+provider "aws" {
+  access_key = "${var.access_key}"
+  secret_key = "${var.secret_key}"
+  region     = "${var.region}"
+}
+
+resource "aws_vpc" "vpc-1" {
+  cidr_block = "10.0.0.0/16"
+  tags {
+    Name = "vpc-1"
+  }
+}

main.tfファイル作成後$ terraform initを実行し、AWSのpluginを取得します。

その後、$ terraform applyを実行して成功するとVPCが作成され、AWSのVPCダッシュボードのVPCページでも確認することが出来ます。
image

ちなみにv0.11.0より$ terraform applyした場合は下記のようにyesを入力しないとapplyが実行されないように変更されています。

$ terraform apply

(省略)

Plan: 15 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value:

initせずにplanなどを実行した場合のエラー

$ terraform initを先に実行してください

$ terraform plan
Plugin reinitialization required. Please run "terraform init".
Reason: Could not satisfy plugin requirements.
...(略

以降の作業

すべて記事内に書くと結構なボリュームになりそうなので、以降の作業内容については各PRを参照ください。
PRを作成して手順や差分をわかりやすくし、必要に応じて説明を入れています:nerd:

WordPressページの表示確認

NATゲートウェイの作成のPR内の作業までをすべて完了後、
WebサーバのURLに対してブラウザよりアクセスするとWordPressのスタートページの表示を確認することが出来ます。
image

:warning:この記事で作成したインスタンスは既にdestroy済みなのでPR上のURLにはアクセスできませんのでご注意ください

TerraformでAWSの環境構築してみて

今後のやっていき

最後に

今回、WordPress環境をAWS上にTerraformを主に使って構築してみましたが、
こんなWordPress環境だけでなく、Node.jsやRails環境などがなんと約10秒で出来上がってしまうというロリポップ!マネージドクラウドのβ版が現在無料公開中ですので、そちらも是非宜しくお願いします:smile:
https://mc.lolipop.jp/

参考にさせて頂いたサイト

など多数

続きを読む