aws(学习笔记第十六课) 使用负载均衡器(ELB)解耦webserver以及输出ELB的日志到S3

aws(学习笔记第十六课)

  • 使用负载均衡器(ELB)以及输出ELB的日志到S3

学习内容:

  • 使用负载均衡器(ELB)解耦web server
  • 输出ELB的日志到S3

1. 使用负载均衡器(ELB)

  1. 全体架构
    使用ELB(Elastic Load Balancer)能够解耦外部internet访问和web server之间的耦合,让外部internet访问只能认识ELB,只知道是ELB为它服务,但是具体的web server对于外部来说却是不意识的。
  1. 代码解析
  • 全体代码

    json 复制代码
    {
    	"AWSTemplateFormatVersion": "2010-09-09",
    	"Description": "AWS in Action: chapter 12 (Load Balancer)",
    	"Parameters": {
    		"KeyName": {
    			"Description": "Key Pair name",
    			"Type": "AWS::EC2::KeyPair::KeyName",
    			"Default": "my-cli-key"
    		},
    		"NumberOfServers": {
    			"Description": "Number of servers",
    			"Type": "Number",
    			"Default": "2",
    			"MinValue": "2",
    			"MaxValue": "4"
    		}
    	},
    	"Mappings": {
    		"EC2RegionMap": {
    			"ap-northeast-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-cbf90ecb"},
    			"ap-southeast-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-68d8e93a"},
    			"ap-southeast-2": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-fd9cecc7"},
    			"eu-central-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-a8221fb5"},
    			"eu-west-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-a10897d6"},
    			"sa-east-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-b52890a8"},
    			"us-east-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-1ecae776"},
    			"us-west-1": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-d114f295"},
    			"us-west-2": {"AmazonLinuxAMIHVMEBSBacked64bit": "ami-e7527ed7"}
    		}
    	},
    	"Resources": {
    		"VPC": {
    			"Type": "AWS::EC2::VPC",
    			"Properties": {
    				"CidrBlock": "172.31.0.0/16",
    				"EnableDnsHostnames": "true"
    			}
    		},
    		"InternetGateway": {
    			"Type": "AWS::EC2::InternetGateway",
    			"Properties": {
    			}
    		},
    		"VPCGatewayAttachment": {
    			"Type": "AWS::EC2::VPCGatewayAttachment",
    			"Properties": {
    				"VpcId": {"Ref": "VPC"},
    				"InternetGatewayId": {"Ref": "InternetGateway"}
    			}
    		},
    		"Subnet": {
    			"Type": "AWS::EC2::Subnet",
    			"Properties": {
    				"AvailabilityZone": {"Fn::Select": ["0", {"Fn::GetAZs": ""}]},
    				"CidrBlock": "172.31.38.0/24",
    				"VpcId": {"Ref": "VPC"}
    			}
    		},
    		"RouteTable": {
    			"Type": "AWS::EC2::RouteTable",
    			"Properties": {
    				"VpcId": {"Ref": "VPC"}
    			}
    		},
    		"RouteTableAssociation": {
    			"Type": "AWS::EC2::SubnetRouteTableAssociation",
    			"Properties": {
    				"SubnetId": {"Ref": "Subnet"},
    				"RouteTableId": {"Ref": "RouteTable"}
    			}
    		},
    		"RoutePublicNATToInternet": {
    			"Type": "AWS::EC2::Route",
    			"Properties": {
    				"RouteTableId": {"Ref": "RouteTable"},
    				"DestinationCidrBlock": "0.0.0.0/0",
    				"GatewayId": {"Ref": "InternetGateway"}
    			},
    			"DependsOn": "VPCGatewayAttachment"
    		},
    		"NetworkAcl": {
    			"Type": "AWS::EC2::NetworkAcl",
    			"Properties": {
    				"VpcId": {"Ref": "VPC"}
    			}
    		},
    		"SubnetNetworkAclAssociation": {
    			"Type": "AWS::EC2::SubnetNetworkAclAssociation",
    			"Properties": {
    				"SubnetId": {"Ref": "Subnet"},
    				"NetworkAclId": {"Ref": "NetworkAcl"}
    			}
    		},
    		"NetworkAclEntryIngress": {
    			"Type": "AWS::EC2::NetworkAclEntry",
    			"Properties": {
    				"NetworkAclId": {"Ref": "NetworkAcl"},
    				"RuleNumber": "100",
    				"Protocol": "-1",
    				"RuleAction": "allow",
    				"Egress": "false",
    				"CidrBlock": "0.0.0.0/0"
    			}
    		},
    		"NetworkAclEntryEgress": {
    			"Type": "AWS::EC2::NetworkAclEntry",
    			"Properties": {
    				"NetworkAclId": {"Ref": "NetworkAcl"},
    				"RuleNumber": "100",
    				"Protocol": "-1",
    				"RuleAction": "allow",
    				"Egress": "true",
    				"CidrBlock": "0.0.0.0/0"
    			}
    		},
    		"LoadBalancerSecurityGroup": {
    			"Type": "AWS::EC2::SecurityGroup",
    			"Properties": {
    				"GroupDescription": "elb-sg",
    				"VpcId": {"Ref": "VPC"},
    				"SecurityGroupIngress": [{
    					"CidrIp": "0.0.0.0/0",
    					"FromPort": 80,
    					"IpProtocol": "tcp",
    					"ToPort": 80
    				}]
    			}
    		},
    		"LoadBalancer": {
    			"Type": "AWS::ElasticLoadBalancing::LoadBalancer",
    			"Properties": {
    				"Subnets": [{"Ref": "Subnet"}],
    				"LoadBalancerName": "elb",
    				"Listeners": [{
    					"InstancePort": "80",
    					"InstanceProtocol": "HTTP",
    					"LoadBalancerPort": "80",
    					"Protocol": "HTTP"
    				}],
    				"HealthCheck": {
    					"HealthyThreshold": "3",
    					"Interval": "10",
    					"Target": "HTTP:80/index.html",
    					"Timeout": "5",
    					"UnhealthyThreshold": "2"
    				},
    				"SecurityGroups": [{"Ref": "LoadBalancerSecurityGroup"}],
    				"Scheme": "internet-facing"
    			},
    			"DependsOn": "VPCGatewayAttachment"
    		},
    		"WebServerSecurityGroup": {
    			"Type": "AWS::EC2::SecurityGroup",
    			"Properties": {
    				"GroupDescription": "awsinaction-sg",
    				"VpcId": {"Ref": "VPC"},
    				"SecurityGroupIngress": [{
    					"CidrIp": "0.0.0.0/0",
    					"FromPort": 22,
    					"IpProtocol": "tcp",
    					"ToPort": 22
    				}, {
    					"FromPort": 80,
    					"IpProtocol": "tcp",
    					"SourceSecurityGroupId": {"Ref": "LoadBalancerSecurityGroup"},
    					"ToPort": 80
    				}]
    			}
    		},
    		"LaunchTemplate": {
    			"Type": "AWS::EC2::LaunchTemplate",
    			"Metadata": {
    				"AWS::CloudFormation::Init": {
    					"config": {
    						"packages": {
    							"yum": {
    								"httpd": []
    							}
    						},
    						"files": {
    							"/tmp/config": {
    								"content": {"Fn::Join": ["", [
    									"#!/bin/bash -ex\n",
    									"PRIVATE_IP=`curl -s http://169.254.169.254/latest/meta-data/local-ipv4`\n",
    									"echo \"<html><head><title>$PRIVATE_IP</title></head><body><h1>$PRIVATE_IP</h1></body></html>\" > index.html\n"
    								]]},
    								"mode": "000500",
    								"owner": "root",
    								"group": "root"
    							}
    						},
    						"commands": {
    							"01_config": {
    								"command": "/tmp/config",
    								"cwd": "/var/www/html"
    							}
    						},
    						"services": {
    							"sysvinit": {
    								"httpd": {
    									"enabled": "true",
    									"ensureRunning": "true"
    								}
    							}
    						}
    					}
    				}
    			},
    			"Properties": {
    				"LaunchTemplateData":{
    					"EbsOptimized": false,
    					"ImageId": {"Fn::FindInMap": ["EC2RegionMap", {"Ref": "AWS::Region"}, "AmazonLinuxAMIHVMEBSBacked64bit"]},
    					"InstanceType": "t2.micro",
    					"NetworkInterfaces":[
    						{
    							"DeviceIndex":0,
    							"AssociatePublicIpAddress":true,
    							"Groups":[
    								{"Ref": "WebServerSecurityGroup"}
    							],
    							"DeleteOnTermination":true
    						}
    					],
    					"KeyName": {"Ref": "KeyName"},
    					"UserData": {"Fn::Base64": {"Fn::Join": ["", [
    						"#!/bin/bash -ex\n",
    						"yum update -y aws-cfn-bootstrap\n",
    						"/opt/aws/bin/cfn-init -v --stack ", {"Ref": "AWS::StackName"}, " --resource LaunchTemplate --region ", {"Ref": "AWS::Region"}, "\n",
    						"/opt/aws/bin/cfn-signal -e $? --stack ", {"Ref": "AWS::StackName"}, " --resource AutoScalingGroup --region ", {"Ref": "AWS::Region"}, "\n"
    					]]}}
    				}
    			}
    		},
    		"AutoScalingGroup": {
    			"Type": "AWS::AutoScaling::AutoScalingGroup",
    			"Properties": {
    				"LoadBalancerNames": [{"Ref": "LoadBalancer"}],
    				"LaunchTemplate" : {"LaunchTemplateId" : {"Ref" : "LaunchTemplate"},"Version" : {"Fn::GetAtt" : ["LaunchTemplate","LatestVersionNumber"]}},
    				"MinSize": {"Ref": "NumberOfServers"},
    				"MaxSize": {"Ref": "NumberOfServers"},
    				"DesiredCapacity": {"Ref": "NumberOfServers"},
    				"VPCZoneIdentifier": [{"Ref": "Subnet"}]
    			},
    			"CreationPolicy": {
    				"ResourceSignal": {
    					"Timeout": "PT10M"
    				}
    			},
    			"DependsOn": "VPCGatewayAttachment"
    		}
    	},
    	"Outputs": {
    		"URL": {
    			"Value": {"Fn::Join": ["", ["http://", {"Fn::GetAtt": ["LoadBalancer", "DNSName"]}]]},
    			"Description": "Load Balancer URL"
    		}
    	}
    }
  • 主要代码分析

    • WebServerSecurityGroup中的SourceSecurityGroupId
      这里,WebServerSecurityGroupSourceSecurityGroupIdLoadBalancerSecurityGroup,表明只有LoadBalancerSecurityGroup所在的主机,也就是LoadBalancer才能对web server访问80端口。

      json 复制代码
      "WebServerSecurityGroup": {
      			"Type": "AWS::EC2::SecurityGroup",
      			"Properties": {
      				"GroupDescription": "awsinaction-sg",
      				"VpcId": {"Ref": "VPC"},
      				"SecurityGroupIngress": [{
      					"CidrIp": "0.0.0.0/0",
      					"FromPort": 22,
      					"IpProtocol": "tcp",
      					"ToPort": 22
      				}, {
      					"FromPort": 80,
      					"IpProtocol": "tcp",
      					"SourceSecurityGroupId": {"Ref": "LoadBalancerSecurityGroup"},
      					"ToPort": 80
      				}]
      			}
      		},
    • LoadBalancer加入HealthCheck
      这里,LoadBalancer里面,加入了对web serverHealthCheck,当web serverindex.hmlt80端口能够访问之后,才能够开始转送到web server

      json 复制代码
      		"LoadBalancer": {
      			"Type": "AWS::ElasticLoadBalancing::LoadBalancer",
      			"Properties": {
      				"Subnets": [{"Ref": "Subnet"}],
      				"LoadBalancerName": "elb",
      				"Listeners": [{
      					"InstancePort": "80",
      					"InstanceProtocol": "HTTP",
      					"LoadBalancerPort": "80",
      					"Protocol": "HTTP"
      				}],
      				"HealthCheck": {
      					"HealthyThreshold": "3",
      					"Interval": "10",
      					"Target": "HTTP:80/index.html",
      					"Timeout": "5",
      					"UnhealthyThreshold": "2"
      				},
      				"SecurityGroups": [{"Ref": "LoadBalancerSecurityGroup"}],
      				"Scheme": "internet-facing"
      			},
      			"DependsOn": "VPCGatewayAttachment"
      		},

2. 输出ELB的日志到S3

  • 首先设置S3 存储桶策略,允许ELB写入logS3
    • policy.json策略文件
      事先作成elb-log-20241208S3 bucket,之后写出policy文件允许logdelivery.elasticloadbalancing.amazonaws.com这个service能够putObjectS3 bucket

      json 复制代码
      {
        "Id": "Policy1429136655940",
        "Version": "2012-10-17",
        "Statement": [{
          "Sid": "Stmt1429136633762",
          "Action": ["s3:PutObject"],
          "Effect": "Allow",
          "Resource": "arn:aws:s3:::elb-log-20241208/*",
          "Principal": {
            "AWS": [
              "127311923021", "027434742980", "797873946194",
              "156460612806", "054676820928", "582318560864",
              "114774131450", "783225319266", "507241528517"
            ]
          }
        }]
      }

      这里,127311923021027434742980像是一些magic code,这到底是什么呢?可以参照enable-access-logging.html,它们是所在地区的 Elastic Load Balancing 的 ID: AWS 账户。

    • 设置policy.json策略文件给S3bucket

      shell 复制代码
      aws s3api put-bucket-policy --bucket elb-log-20241208 --policy file://policy/elb-log-policy.json
    • 配置cloudformationELB输入logS3 bucket
      AccessLoggingPolicy这里就是设置描述log输出的设置。

      		"LoadBalancer": {
      			"Type": "AWS::ElasticLoadBalancing::LoadBalancer",
      			"Properties": {
      				"Subnets": [{"Ref": "Subnet"}],
      				"LoadBalancerName": "elb",
      				"Listeners": [{
      					"InstancePort": "80",
      					"InstanceProtocol": "HTTP",
      					"LoadBalancerPort": "80",
      					"Protocol": "HTTP"
      				}],
      				"HealthCheck": {
      					"HealthyThreshold": "3",
      					"Interval": "10",
      					"Target": "HTTP:80/index.html",
      					"Timeout": "5",
      					"UnhealthyThreshold": "2"
      				},
      				"AccessLoggingPolicy":{
      					"ENabled": true,
      					"S3BucketName":"elb-log-20241208",
      					"S3BucketPrefix":"my-application/production"
      				}
      				"SecurityGroups": [{"Ref": "LoadBalancerSecurityGroup"}],
      				"Scheme": "internet-facing"
      			},
      			"DependsOn": "VPCGatewayAttachment"
      		},
      


    • 重新访问ELB

    • 检查S3log文件夹
      可以看到log已经开始写入到S3

相关推荐
奶香臭豆腐36 分钟前
C++ 泛编程 —— 函数模板(中)
开发语言·c++·学习
●VON1 小时前
go语言的成神之路-标准库篇-os标准库
linux·运维·服务器·开发语言·后端·学习·golang
星河梦瑾1 小时前
【2025最新版】搭建个人博客教程
linux·经验分享·笔记·python·安全
虾球xz1 小时前
游戏引擎学习第41天
学习·算法·游戏引擎
HE10291 小时前
时间序列绘图1
学习·信息可视化
IOT.FIVE.NO.12 小时前
Linux学习笔记15 何为HDD,SSD?sata?PCIE?分区,MBR,GPT分区的理解
linux·笔记·学习
Evand J2 小时前
自适应卡尔曼滤波(包括EKF、UKF、CKF等)的创新思路——该调什么、不该调什么
开发语言·笔记·matlab·卡尔曼滤波·自适应滤波
前端熊猫2 小时前
React Router 6的学习
javascript·学习·react.js
qq_382391332 小时前
C# 特性 学习理解记录
学习
憨憨2号2 小时前
RUST学习笔记
笔记·学习·rust