ElasticLoadbalancer(NetworkLoadBalancer)によるロードバランシング

nlb-ec2.yml (EC2)

ネットワークはマルチAZPublicSubnetAPublicSubnetBのサブネットを持つVPCとして作成。
各サブネットにそれぞれEC2インスタンスを配置する。

NLBはクライアントからのリクエストを終端せずにEC2インスタンスへ中継するため、Webコンテンツへのアクセスをすべて許可する。
WebSecurityGroupSecurityGroupIngresのみALB編と異なる。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# ------------------------------------------------------------ #
# EC2
# ------------------------------------------------------------ #
ManagementSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Enable SSH access via port 22
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-management-sg"
SecurityGroupIngress:
- CidrIp: !Ref AllowSshFrom
IpProtocol: tcp
FromPort: '22'
ToPort: '22'

WebSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Enable HTTP(S) access via port 80+443
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-web-sg"
SecurityGroupIngress:
- CidrIp: 0.0.0.0/0
IpProtocol: tcp
FromPort: '80'
ToPort: '80'
- CidrIp: 0.0.0.0/0
IpProtocol: tcp
FromPort: '443'
ToPort: '443'

PublicSubetAInstance:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref ImageID
InstanceType: t2.micro
SecurityGroupIds:
- Fn::GetAtt: [ ManagementSecurityGroup, GroupId ]
- Fn::GetAtt: [ WebSecurityGroup, GroupId ]
KeyName: !Ref KeyName
SubnetId: !Ref PublicSubnetA
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-PublicSubnetA-Instance"
UserData: !Base64
Fn::Sub: |
#!/bin/bash
apt-get update
apt-get install -y apache2
echo "<HTML>PUBLIC SUBNET A</HTML>" > /var/www/html/index.html

PublicSubetBInstance:
Type: AWS::EC2::Instance
Properties:
ImageId: !Ref ImageID
InstanceType: t2.micro
SecurityGroupIds:
- Fn::GetAtt: [ ManagementSecurityGroup, GroupId ]
- Fn::GetAtt: [ WebSecurityGroup, GroupId ]
KeyName: !Ref KeyName
SubnetId: !Ref PublicSubnetB
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-PublicSubnetB-Instance"
UserData: !Base64
Fn::Sub: |
#!/bin/bash
apt-get update
apt-get install -y apache2
echo "<HTML>PUBLIC SUBNET B</HTML>" > /var/www/html/index.html

nlb-ec2.yml (NLB)

  • ロードバランサーのタイプとしてType: networkを明示する
  • セキュリティグループを適用できない
  • ヘルスチェックはTCPによるポートチェック
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# ------------------------------------------------------------ #
# ElasticLoadBalancer
# ------------------------------------------------------------ #
InternetNLBTargetGroup:
Type: "AWS::ElasticLoadBalancingV2::TargetGroup"
Properties:
VpcId: !Ref VPC
Name: !Sub "${AWS::StackName}-tg"
Protocol: TCP
Port: 80
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-tg"
TargetGroupAttributes:
- Key: "deregistration_delay.timeout_seconds"
Value: 300
Targets:
- Id: !Ref PublicSubetAInstance
Port: 80
- Id: !Ref PublicSubetBInstance
Port: 80

InternetNLB:
Type: "AWS::ElasticLoadBalancingV2::LoadBalancer"
Properties:
Name: !Sub "${AWS::StackName}-nlb"
Tags:
- Key: Name
Value: !Sub "${AWS::StackName}-nlb"
# ロードバランサーのタイプ (default: application)
Type: network
Scheme: "internet-facing"
Subnets:
- !Ref PublicSubnetA
- !Ref PublicSubnetB

InternetNLBListener:
Type: "AWS::ElasticLoadBalancingV2::Listener"
Properties:
DefaultActions:
- TargetGroupArn: !Ref InternetNLBTargetGroup
Type: forward
LoadBalancerArn: !Ref InternetNLB
Port: 80
Protocol: TCP

# ------------------------------------------------------------ #
# Output Parameters
# ------------------------------------------------------------ #
Outputs:
PublicSubnetAInstanceIP:
Description: "Management Public IP"
Value: !GetAtt PublicSubetAInstance.PublicIp
PublicSubnetBInstanceIP:
Description: "Management Public IP"
Value: !GetAtt PublicSubetBInstance.PublicIp
InternetNLBPublicDomainName:
Description: "Public access Domain Name"
Value: !GetAtt InternetNLB.DNSName

システムの構築する

1
2
3
4
$ aws cloudformation update-stack --stack-name tutorial-nlb-ec2 --template-body "file://./nlb-ec2.yml" --parameters "file://./parameters.json"
{
"StackId": "arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXX:stack/tutorial-nlb-ec2/XXXXXXXXXXXXXXXXXXX"
}

作成が完了したら、ロードバランサーに付与されたDNSNameでアクセスする。

1
2
$ aws elbv2 describe-load-balancers | jq -r '.LoadBalancers[] | select (.LoadBalancerName == "tutorial-nlb-ec2-nlb") | .DNSName'
tutorial-alb-ec2-nlb-XXXXXXXXXXXXXXXX.ap-northeast-1.amazonaws.com

NLBロードバランシング width=640

同じコネクションからのアクセスは同じインスタンスに振られる。
ロードバランシングの様子を見たい場合は別のブラウザ等でアクセス。