37
32

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AWS Application Load Balancer CLIメモ

Last updated at Posted at 2016-08-14

Application Load Balancer とは

AWSのロードバランサとしてはElastic Load Balancer(ELB)が従来から存在しますが、これはEC2インスタンスのみを配下に接続可能で、その接続ポートも全インスタンス共通のL4ロードバランサでした。
今回発表のApplication Load Balancerは、EC2の他、ECSによるコンテナインスタンスでポートが異なるサービスを接続したり、URLパスにより接続するインスタンスを変化させる等、L7ロードバランサとして動作します。

もちろんELB同様、ACM(無料のSSL証明書)を用いたSSLターミネートなども利用可能で、基本的にELBの上位互換として動作します。
みんな大好きAWSCLIで使ってみましょう。

elbv2 と呼びます

AWS CLIでの機能名は elbv2 と書かれています。 alb ではありません。
このことからも、AWS内部ではELBバージョン2として作られたことが伺えます。

elbとelbv2の相違点

  • elbv2では同一VPCで2以上のAZに2以上のサブネットが必要です。elbは単一サブネットでも構築可能ですがこれができなくなりました。ただし接続するインスタンスは1台でも構いません。
  • SSLターミネート処理で、elbv2のみ選択可能な最新ポリシーがある。

前提条件

  • ECSでもEC2でも構いませんが2台のインスタンスでWebサービスが2以上稼働していること。
  • ここでは2台のインスタンスにポート80でapache、ポート8080でnginxを稼働させています。
  • 同一VPCにサブネットが2つ以上存在すること。
  • AWSCLI バージョン 1.10.56 以上がインストールされていること。

実行権限

  • ELBを操作できること。

AWS CLIのバージョン

elbv2はバージョン1.10.56で追加された機能です。
これより古いバージョンでは動作しませんから必ず確認しましょう。

コマンド
aws --version
結果(例)
      aws-cli/1.10.56 Python/2.6.6 Linux/2.6.32-642.3.1.el6.x86_64 botocore/1.4.46

今回の目的

2台のEC2インスタンスでWebサーバが稼働しており、まずは単純に振り分けることを目的とします。
次に、URLパスによるルーティングを追加する試みとして、/cgi-bin/ 以下のURLへアクセスがあった場合 tcp/8080で動作しているwebサーバへ振り分ける機能を追加します。

  1. 事前作業
    ===========

0.1. リージョンの決定

Webサービスが動作しているリージョンで実行します。
ここでは ap-northeast-1 (東京)リージョンにて作業します。
自分の環境に合わせて設定してください。

変数の設定
export AWS_DEFAULT_REGION='ap-northeast-1'

0.2. 変数の確認

プロファイルとリージョンが想定のものになっていることを確認します。

コマンド
aws configure list
結果(例)
            Name                    Value             Type    Location
            ----                    -----             ----    --------
         profile                <not set>             None    None
      access_key     ****************M73Q shared-credentials-file
      secret_key     ****************YWg/ shared-credentials-file
          region           ap-northeast-1              env    AWS_DEFAULT_REGION
  1. ELBv2の構築
    ===========

ELBv2では、最初にサブネットを指定してロードバランサの全体環境を構築して、次にターゲットグループと呼ばれる接続先を定義するグループを構築、そして外部からのアクセスを受けるリスナーを構築しこれにターゲットグループを接続してアクセス可能になる流れです。

1.1. サブネットの確認

ELBv2で使用するサブネットを確認してください。ここでは

  • subnet-11111111
  • subnet-22222222
    の2つを使用することにします。自分の環境に合わせて設定してください。
コマンド
SUBNET_ID1="subnet-11111111"
SUBNET_ID2="subnet-22222222"
結果
      (返り値なし)

1.2. VPCIDの確認

上記で使用するサブネットが全て同一のVPCである事を必ず確認してください。
異なるVPCのサブネットは接続出来ません。ここではVPCID

  • vpc-33333333
    を使用することにします。自分の環境に合わせて設定してください。
コマンド
VPC_ID="vpc-33333333"
結果
      (返り値なし)

1.3. 登録するインスタンスとポート番号

ロードバランサへ登録するインスタンスを確認してください。ここでは

  • i-55555555 ポート番号80
  • i-66666666 ポート番号80
    の2つを使用することにします。自分の環境に合わせて設定してください。
コマンド
INSTANCE1_ID="i-55555555"
INSTANCE1_PORT="80"
INSTANCE2_ID="i-66666666"
INSTANCE2_PORT="80"
結果
      (返り値なし)

1.4. セキュリティグループの作成

セキュリティグループ elbv2-cli-sg を作成します。

コマンド
SG_NAME="elbv2-cli-sg"
aws ec2 create-security-group --group-name ${SG_NAME} --description ${SG_NAME} --vpc-id ${VPC_ID}
SG_ID=`aws ec2 describe-security-groups --filter Name=group-name,Values=${SG_NAME} \
 --query 'SecurityGroups[].GroupId' --output text` && echo ${SG_ID}
結果(例)
      {
          "GroupId": "sg-99999999"
      }

      sg-99999999

外部からのHTTP接続をセキュリティグループに追加。

コマンド
aws ec2 authorize-security-group-ingress --group-id ${SG_ID} --protocol 'tcp' --port 80 --cidr 0.0.0.0/0
結果
      (返り値なし)

1.5. アプリケーションロードバランサの作成

それでは作成します。名前を elbv2-cli とします。(任意の名前可)

コマンド
ELB_NAME="elbv2-cli"
ELB_ARN=`aws elbv2 create-load-balancer --name ${ELB_NAME} \
 --subnets ${SUBNET_ID1} ${SUBNET_ID2} --security-groups ${SG_ID} \
 --query LoadBalancers[].LoadBalancerArn --output text `
DNSName=`aws elbv2 describe-load-balancers --load-balancer-arns ${ELB_ARN} \
 --query LoadBalancers[].DNSName --output text `
aws elbv2 describe-load-balancers --load-balancer-arns ${ELB_ARN}
結果(例)
      {
          "LoadBalancers": [
              {
                  "VpcId": "vpc-33333333",
                  "LoadBalancerArn": "arn:aws:elasticloadbalancing:ap-northeast-1:777777777777:loadbalancer/app/elbv2-cli/bd12da1588c83561",
                  "State": {
                      "Code": "provisioning"
                  },
                  "DNSName": "elbv2-cli-1743316501.ap-northeast-1.elb.amazonaws.com",
                  "SecurityGroups": [
                      "sg-99999999"
                  ],
                  "LoadBalancerName": "elbv2-cli",
                  "CreatedTime": "2016-08-13T01:21:05.500Z",
                  "Scheme": "internet-facing",
                  "Type": "application",
                  "CanonicalHostedZoneId": "Z14GRHDCWA56QT",
                  "AvailabilityZones": [
                      {
                          "SubnetId": "subnet-11111111",
                          "ZoneName": "ap-northeast-1a"
                      },
                      {
                          "SubnetId": "subnet-22222222",
                          "ZoneName": "ap-northeast-1c"
                      }
                  ]
              }
          ]
      }

1.6. ターゲットグループの作成(通常アクセス用)

HTTP(tcp/80)でアクセスを受けるターゲットグループを作成します。

コマンド
ELB_TG_NAME="elbv2-cli-tg"
ELB_TG=`aws elbv2 create-target-group --name ${ELB_TG_NAME} --protocol HTTP --port 80 --vpc-id ${VPC_ID} \
 --query TargetGroups[].TargetGroupArn --output text `
aws elbv2 describe-target-groups --target-group-arns ${ELB_TG}
結果(例)
      {
          "TargetGroups": [
              {
                  "HealthCheckPath": "/",
                  "HealthCheckIntervalSeconds": 30,
                  "VpcId": "vpc-33333333",
                  "Protocol": "HTTP",
                  "HealthCheckTimeoutSeconds": 5,
                  "HealthCheckProtocol": "HTTP",
                  "UnhealthyThresholdCount": 2,
                  "HealthyThresholdCount": 5,
                  "TargetGroupArn": "arn:aws:elasticloadbalancing:ap-northeast-1:777777777777:targetgroup/elbv2-cli-tg/de1a0a8eabbabd2f",
                  "Matcher": {
                      "HttpCode": "200"
                  },
                  "HealthCheckPort": "traffic-port",
                  "Port": 80,
                  "TargetGroupName": "elbv2-cli-tg"
              }
          ]
      }

1.7. ターゲットグループへインスタンスを登録

稼働しているWebサービスのインスタンスをターゲットグループへ登録します。
このようにインスタンスIDとポート番号の組み合わせで登録するので、コンテナインスタンスで複数のWebサービスコンテナが稼働していてもそれらを登録することができます。

コマンド
aws elbv2 register-targets --target-group-arn ${ELB_TG} \
 --targets Id=${INSTANCE1_ID},Port=${INSTANCE1_PORT} Id=${INSTANCE2_ID},Port=${INSTANCE2_PORT}
結果
      返り値なし

ポート番号をここでは全て指定していますが、ターゲットグループで設定したポート番号をインスタンス側でも使用する場合は省略可能です。(この例ではtcp/80)
何か表示されたらエラーなので確認しましょう。

1.8. リスナの作成

最後に外部からHTTP(tcp/80)でアクセスを受けるリスナを作成して、先に作成したターゲットグループを接続してアクセスできるようにします。

コマンド
ELB_LISTENER=`aws elbv2 create-listener --load-balancer-arn ${ELB_ARN} --protocol HTTP --port 80 \
 --default-actions Type=forward,TargetGroupArn=${ELB_TG} \
 --query Listeners[].ListenerArn --output text `
aws elbv2 describe-listeners --listener-arns ${ELB_LISTENER}
結果(例)
      {
          "Listeners": [
              {
                  "Protocol": "HTTP",
                  "DefaultActions": [
                      {
                          "TargetGroupArn": "arn:aws:elasticloadbalancing:ap-northeast-1:777777777777:targetgroup/elbv2-cli-tg/de1a0a8eabbabd2f",
                          "Type": "forward"
                      }
                  ],
                  "LoadBalancerArn": "arn:aws:elasticloadbalancing:ap-northeast-1:777777777777:loadbalancer/app/elbv2-cli/bd12da1588c83561",
                  "Port": 80,
                  "ListenerArn": "arn:aws:elasticloadbalancing:ap-northeast-1:777777777777:listener/app/elbv2-cli/bd12da1588c83561/f1edf2404136e22f"
              }
          ]
      }
  1. アクセスして動作確認
    ========

実際にDNSNameへアクセスしてWebページが表示されるか確認しましょう。

コマンド
curl http://${DNSName}
結果(例)
      Webページの内容が表示される

普通にWebブラウザでアクセスしてももちろん構いません。

  1. Pass-Based ルーティングの追加
    ========

ここまででロードバランサは動作しました。
次に、特定のURLのみ別のサーバへ振り分けるPass-Based Routing の追加を行います。
ここでは /cgi-bin/ へのアクセスをポート8080で受けるインスタンスへ振り分けることにします。

3.1. 登録するインスタンスとポート番号

ここでは

  • i-55555555 ポート番号8080
  • i-66666666 ポート番号8080
    の2つを使用することにします。自分の環境に合わせて設定してください。
コマンド
INSTANCE3_ID="i-55555555"
INSTANCE3_PORT="8080"
INSTANCE3_ID="i-66666666"
INSTANCE3_PORT="8080"
結果
      (返り値なし)

3.1. ターゲットグループの構築(Pass-Based Routing用)

Pass Based Routingはターゲットグループに設定します。
このため、新しくターゲットグループを作成します。

コマンド
ELB_TG2_NAME="elbv2-cli-tg2"
ELB_TG2=`aws elbv2 create-target-group --name ${ELB_TG2_NAME} --protocol HTTP --port 80 --vpc-id ${VPC_ID} \
 --query TargetGroups[].TargetGroupArn --output text `
aws elbv2 describe-target-groups --target-group-arns ${ELB_TG2}
結果(例)
      {
          "TargetGroups": [
              {
                  "HealthCheckPath": "/",
                  "HealthCheckIntervalSeconds": 30,
                  "VpcId": "vpc-33333333",
                  "Protocol": "HTTP",
                  "HealthCheckTimeoutSeconds": 5,
                  "HealthCheckProtocol": "HTTP",
                  "UnhealthyThresholdCount": 2,
                  "HealthyThresholdCount": 5,
                  "TargetGroupArn": "arn:aws:elasticloadbalancing:ap-northeast-1:777777777777:targetgroup/elbv2-cli-tg2/de1a0a8eabbabe8f",
                  "Matcher": {
                      "HttpCode": "200"
                  },
                  "HealthCheckPort": "traffic-port",
                  "Port": 80,
                  "TargetGroupName": "elbv2-cli-tg2"
              }
          ]
      }

3.2. ターゲットグループへインスタンスを登録(Pass-Based Routing用)

コマンド
aws elbv2 register-targets --target-group-arn ${ELB_TG2} \
 --targets Id=${INSTANCE3_ID},Port=${INSTANCE3_PORT} Id=${INSTANCE4_ID},Port=${INSTANCE4_PORT}
結果
      返り値なし

3.3. リスナへルールを追加

リスナへPass-Based Routingのルールを追加し、/cgi-bin/ へのアクセスを振り分けるターゲットグループを設定します。

コマンド
aws elbv2 create-rule --listener-arn ${ELB_LISTENER} --priority 10 \
--conditions Field=path-pattern,Values='/cgi-bin/*' \
--actions Type=forward,TargetGroupArn=${ELB_TG2}
結果(例)
      {
          "Rules": [
              {
                  "Priority": "10",
                  "Conditions": [
                      {
                          "Field": "path-pattern",
                          "Values": [
                              "/cgi-bin/*"
                          ]
                      }
                  ],
                  "RuleArn": "arn:aws:elasticloadbalancing:ap-northeast-1:777777777777:listener-rule/app/elbv2-cli/51d50a8cdff26750/35560600bd1e51e2/89c54c4e952b753a",
                  "IsDefault": false,
                  "Actions": [
                      {
                          "TargetGroupArn": "arn:aws:elasticloadbalancing:ap-northeast-1:777777777777:targetgroup/elbv2-cli-tg2/d83dd8bc4d9e2f86",
                          "Type": "forward"
                      }
                  ]
              }
          ]
      }
  1. アクセスして動作確認
    ========

実際にDNSNameへアクセスしてWebページが表示されるか確認しましょう。

コマンド
curl http://${DNSName}/
curl http://${DNSName}/cgi-bin/
結果(例)
      / へアクセスするとapacheが、
      /cgi-bin/ へアクセスするとnginxが応答を返せば成功です。

普通にWebブラウザでアクセスしてももちろん構いません。
セキュリティグループで外部からはポート80しかアクセス許可していないのに、インスタンス上ではポート8080で動作しているnginxが返事をしていることからロードバランサが正しく動作していることがわかるかと思います。

  1. まとめ
    ===========

外部からアクセスを受けるリスナでURLなどの条件から振り分け先のターゲットグループを決め、振り分けられたターゲットグループが配下のインスタンスへトラヒックを流す。
という2段階で動作しているのが従来のELBと異なるので最初はアクセス出来ず戸惑いましたが、わかれば簡単に構築できました。

SSL証明書の登録とターミネートについては追って書きたいと思います。

37
32
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
37
32

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?