亚马逊云服务AWS-实操教程

122 阅读14分钟

现在云服务已经十分普及,这里分享亚马逊的一些实战经验

1. 新增IAM用户

为了方便管理,可以创建iam账号(类似于子账户)的来分不同用户管理AWS

步骤 1:使用根账户登录 AWS 管理控制台

  1. 打开 AWS 管理控制台:aws.amazon.com/
  2. 点击 ​​“Sign In to the Console”(登录控制台)​
  3. 使用你注册时的 ​邮箱地址 和 密码​ 登录(这就是根账户登录)

注意:如果之前选择了 “使用 IAM 用户登录” 方式,可能会进入 IAM 登录页面。如果是首次登录,一般是通过根账户邮箱登录。


步骤 2:进入 IAM 控制台

image.png

  1. 登录后,在 AWS 控制台搜索栏中输入 ​​“IAM”​,或者访问:

  2. 点击进入 ​IAM(Identity and Access Management)服务


步骤 3:创建 IAM 用户

  1. 在 IAM 控制台左侧菜单,点击 ​​“用户(Users)”​

  2. 点击顶部 ​​“添加用户(Add users)”​​ 按钮

  3. 设置用户信息:​

    • 用户名(User name)​​:例如 dev-userzhangsan

    • 访问类型(Select AWS access type)​​:

      • 勾选 ​​“编程访问(Programmatic access)”​​ → 用户将拥有 API、CLI、SDK 使用的 Access Key 和 Secret Key
      • 勾选 ​​“AWS 管理控制台访问(AWS Management Console access)”​​ → 用户可以通过用户名密码登录控制台
      • (根据你的需求勾选,通常两者都勾选)
  4. 点击 ​​“下一步:权限(Next: Permissions)”​


步骤 4:为用户分配权限

这里有几种常见方式:

方式 1:​直接附加现有策略(推荐新手)​
  • 选择 ​​“直接附加现有策略(Attach existing policies directly)”​

  • 在筛选框中输入你想要的权限策略,比如:

    • AdministratorAccess→ ​拥有所有权限(慎用!仅用于管理员)​
    • AmazonS3ReadOnlyAccess→ 只读 S3
    • AmazonEC2ReadOnlyAccess→ 只读 EC2
    • 或者你自定义的其他策略
  • 勾选你希望赋予的策略,例如 AdministratorAccess(仅作测试,生产环境请细化权限!)

  • 点击 ​​“下一步:标签(Next: Tags)”​​(可选)

方式 2:​添加用户到用户组(推荐最佳实践)​
  • 你可以先创建一个用户组(如 Developers),然后给该组绑定策略,再将用户加入该组。
  • 如果你还没创建组,可以稍后再做,或者在这一步先直接附加策略。

通过用户组统一设置权限好维护 image.png

(可选)步骤 4b:添加标签(Tags)
  • 可以为用户添加标签(如部门、用途等),非必填,可跳过

步骤 5:审核并创建用户

  1. 检查你填写的用户名、访问类型、权限策略是否正确
  2. 点击 ​​“创建用户(Create user)”​

步骤 6:获取访问凭证

如果选择了 ​​“编程访问”​,你将看到:

  • Access key ID
  • Secret access key

⚠️ ​重要:Secret access key 只会显示这一次!请务必保存(比如下载 CSV 文件或复制保存下来)。丢失后将无法再查看,只能重新创建。​

如果选择了 ​​“控制台访问”​,你将得到:

  • 一个 ​初始密码​ 或提示用户 ​首次登录时设置密码

  • 用户可以通过以下地址登录 AWS 控制台:

    https://你的账户ID.signin.aws.amazon.com/console
    

    或者使用你设置的账户别名(如果有配置):

    https://你的账户别名.signin.aws.amazon.com/console
    

你可以点击 ​​“登录链接”​​ 直接发送给用户,或让用户使用:

https://console.aws.amazon.com/

然后输入你创建的 IAM 用户名和密码登录。

2. 新增EC2服务器

创建 EC2 实例

image.png

  1. 在 EC2 控制台首页,点击 ​​“启动实例”(Launch Instance)​​ 按钮

配置实例基本信息

image.png

① 为实例命名(可选但推荐)
  • 在 ​​“名称和标签”(Name and tags)​​ 部分,给你的实例起个名字(比如 MyFirstEC2),便于管理
② 选择一个 Amazon Machine Image (AMI)
  • AMI 是预配置的操作系统镜像(如 Amazon Linux、Ubuntu、Windows 等)

  • 推荐新手使用:

    • Amazon Linux 2​(免费层级友好)
    • 或者 ​Ubuntu Server 22.04 LTS
  • 在列表中找到并选择你想要的操作系统镜像,例如:

    • Amazon Linux 2 AMI (HVM), SSD Volume Type​(免费 tier 可用)
③ 选择实例类型(Instance Type)
  • 实例类型决定了 CPU、内存、存储等配置

  • 对于学习或测试用途,推荐选择:

    • t2.micro​(属于 AWS 免费套餐范围,每月有一定免费额度)
  • 选中后,点击 ​​“下一步:配置实例详细信息”​


配置实例(可保持默认)

  • 大多数设置可以保持 ​默认值
  • 如果你有特殊需求(比如放到某个 VPC、指定子网、IAM 角色等),可以在这里配置
  • 新手通常直接点击 ​​“下一步:添加存储”​

添加存储(默认一般足够)

  • 默认情况下,会提供 ​8GB 的通用 SSD (gp2) 根卷
  • 如果你需要更大的磁盘空间,可以在这里添加或修改
  • 学习用途通常无需更改,点击 ​​“下一步:添加标签”​​(可选)

添加标签(可选)

  • 标签是键值对,用于帮助你更好地管理资源
  • 例如:Key = Name, Value = MyTestEC2
  • 可跳过,直接点击 ​​“下一步:配置安全组”​

配置安全组(重要!)

  • 安全组相当于虚拟防火墙,控制哪些端口可以被访问

  • 你可以:

    • 创建新的安全组,或者
    • 选择一个已有的安全组
推荐配置(以 SSH 访问为例,适用于 Linux):
  • 规则 1​:允许 SSH(端口 22)

    • 类型:SSH
    • 协议:TCP
    • 端口范围:22
    • 来源:My IP(推荐,只允许你当前的公网 IP 访问,更安全) 或者 Anywhere(0.0.0.0/0,不推荐用于生产环境)
  • ​(可选)规则 2​:允许 HTTP(端口 80)或 HTTPS(端口 443),如果你要运行网站

⚠️ 注意:将来源设为 0.0.0.0/0Anywhere意味着任何人都能访问该端口,请谨慎使用!

点击 ​​“下一步:选择密钥对”​


选择密钥对(非常关键!)

image.png 密钥对用于通过 SSH 登录你的 Linux 实例(Windows 用户可能使用 RDP 和其它方式)。

你有三个选项:

  1. 选择现有密钥对​(如果你之前已经创建过)

  2. 创建新的密钥对​(推荐,第一次使用)

    • 选择 ​​“创建新密钥对”​
    • 输入密钥对名称(如:my-key-pair
    • 下载私钥文件(.pem 文件)​​ —— ​务必保存好,只会出现一次!​
    • 选中“我确认已下载密钥对文件”
  3. 选择已有密钥对但不下载​(无法登录,不推荐)

📌 注意:

  • 私钥文件(.pem)相当于密码,不能公开,不要上传到网络或共享
  • 只能下载一次,丢失后将无法通过 SSH 登录该实例(除非有其它登录方式)

点击 ​​“启动实例”​


实例启动中

  • 你会看到 “您的实例正在启动” 的提示
  • 点击 ​​“查看实例”​,可以查看你刚刚创建的 EC2 实例状态

image.png

连接

image.png

链接支持4种方式,推荐使用ssh客户端,直接复制 示例:

ssh -i "myrsa.pem" ec2-user@xxxx.compute-1.amazonaws.com

注意 "myrsa.pem"要设置权限 chmod 400 "myrsa.pem" image.png

3. 新增S3桶

步骤 1:登录 AWS 控制台并进入 S3

  1. 打开 AWS 管理控制台。
  2. 在服务搜索栏中输入 ​S3,然后点击 ​S3​ 服务进入。

image.png

步骤 2:创建 S3 存储桶

  1. 点击页面左上角的 ​​“创建存储桶”​​ 按钮。

  2. 输入 ​存储桶名称​:

    • 必须是 ​全局唯一​ 的(整个 AWS 中唯一,不是你账户内唯一)。
    • 例如:my-public-bucket-12345
  3. 选择你想要的 ​AWS 区域​(建议选择离你近的或业务需要的区域)。

  4. 取消勾选​(不推荐勾选):

    • ​“阻止所有公共访问”​​(Block all public access)—— ​你需要取消勾选此选项才能设置公开权限!​

      • 默认情况下,AWS 会勾选并阻止所有公共访问,你需要 ​手动取消勾选全部四个选项,然后确认你了解风险。
      • 系统会弹出警告,点击 ​​“确认”​​ 表示你了解将允许公开访问的风险。
  5. 设置 存储桶策略

your-bucket-name 替换为你的桶名字

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::your-bucket-name/*"
        }
    ]
}

image.png

  1. 其它设置可保持默认,比如:

    • 不启用版本控制
    • 不启用加密(或按需配置)
    • 不启用日志记录等
  2. 点击 ​​“创建存储桶”​​ 完成创建。

测试

在S3里面选择自己的桶,然后点击上传测试

image.png

image.png

在浏览器直接访问

https://your-bucket-name.s3.amazonaws.com/your-file.jpg

4. 新增CloudFront

在 AWS 上配置 CDN(内容分发网络)通常使用的是 ​Amazon CloudFront

image.png

创建 CloudFront 分发(Distribution)

image.png

登录 AWS 管理控制台,打开 CloudFront 控制台​
点击 “创建分配”(Create Distribution)​
选择分发类型
  • 一般选择 ​​“Web”​​(适用于网站、HTTP/HTTPS 内容)。
  • 如果你要加速实时流媒体,可以选择 ​RTMP​(不过现在较少用)。
配置 “源”(Origin)​
  • Origin Domain Name​:选择你的来源,比如:

    • 如果是 S3:从下拉列表中选择你的 S3 存储桶(注意:不是存储桶的网站终端节点,而是 S3 本身的源,形如 your-bucket-name.s3.amazonaws.com)。
    • 如果是自定义源(如 EC2、ELB):输入它的域名或 IP,比如 example.com123.45.67.89
  • Origin Path​:一般留空,除非你的内容存放在存储桶或服务器的某个子目录下。

  • Origin Access Control (OAC) 或 Origin Access Identity (OAI)​​(推荐):

    • 对于 S3,建议使用 ​OAC(新方式)​​ 或 ​OAI(旧方式)​​ 来限制只有 CloudFront 能访问 S3。
    • 如果你开启 OAI/OAC,那么你 ​不能直接通过 S3 的公开 URL 访问文件,只能通过 CloudFront 访问。
配置默认缓存行为(Default Cache Behavior)​
  • Viewer Protocol Policy​:

    • 如果你的源是 HTTPS,建议选 ​Redirect HTTP to HTTPS​ 或 ​HTTPS Only
  • Allowed HTTP Methods​:通常选 ​GET, HEAD, OPTIONS​(如果是 API 或需要 POST,也可以选更多)。

  • 缓存策略和 origin 请求策略​(AWS 推荐使用托管策略,比如 “CachingOptimized”)。

  • Forward Headers / Cookies / Query Strings​:根据需求配置,一般静态资源不需要转发查询字符串,可提升缓存命中率。

设置备用域名(可选)​
  • 在 ​​“Alternate Domain Names (CNAMEs)”​​ 中,你可以填上你自己的域名,比如 www.example.com
  • 如果你填了 CNAME,你后续需要为该域名配置一个有效的 SSL 证书,并在 CloudFront 中使用。
SSL 证书配置
  • 如果你用了自定义域名(如 www.example.com),你可以在 ​​“Custom SSL Certificate”​​ 中选择一个由 ​ACM(AWS Certificate Manager)​​ 颁发的证书(必须是在 ​us-east-1​ 区域,如果你使用 CloudFront 的默认域名则不需要)。
  • 如果你暂时不用自定义域名,可以直接使用 CloudFront 默认的域名(如 dxxxxx.cloudfront.net),它自带 HTTPS 支持。
设置价格类别 / 边缘站点
  • 你可以选择 CloudFront 将内容分发到哪些地区,一般保持默认(全球)即可。
其他设置(日志、标签等)​
  • 可选择开启 ​访问日志,记录谁访问了你的 CDN。
  • 添加标签便于管理。
点击 “创建分发”​
测试

直接地址栏访问

https://xxxx.cloudfront.net/index.html

边缘渲染函数

  • CloudFront Functions
  • Lambda@Edge

CloudFront Functions

docs.aws.amazon.com/zh_cn/Amazo…

cloudfront支持简单的请求修改 通过js可以在接受请求,和返回请求的做逻辑处理,如果需要更高级别的处理推荐使用 lambda

例子代码:docs.aws.amazon.com/zh_cn/Amazo…

Lambda@Edge

支持更高级的能力,接口查询,数据库连接等 docs.aws.amazon.com/zh_cn/Amazo…

5. 新增lambda

AWS Lambda 是 ​Amazon Web Services (AWS)​​ 提供的一种 ​无服务器(Serverless)计算服务。即用户无需关心服务器等,直接编写服务。

image.png

image.png

创建一个新的 Lambda 函数

  • 点击页面上的 ​​“创建函数”(Create function)​​ 按钮

4️⃣ 配置函数基本信息

在创建页面中,填写以下内容:

选择创建方式:
  • 选择 ​​“从头开始编写”(Author from scratch)​
填写函数信息:
  • 函数名称(Function name)​: 例如 MyFirstNodeJSLambda

  • 运行时(Runtime)​: 选择 ​Node.js​ 的版本,比如:

    • 推荐:​Node.js 18.x​(或根据你的需求选择 16.x、20.x 等,注意 AWS 支持的版本可能更新)
  • 架构​:默认即可(x86_64 或 arm64/Graviton,后者更省成本)

  • 执行角色(Execution role)​:

    • 选择:​​“创建新角色与基本 Lambda 权限”(Create a new role with basic Lambda permissions)​
    • 这样 AWS 会自动为你的函数创建一个 IAM 角色,具备写入日志等基础权限

⚠️ 如果你后续要让 Lambda 访问其他 AWS 服务(如 S3、DynamoDB),需要给这个角色添加对应权限。

然后点击 ​​“创建函数”(Create function)​

修改函数

网页版

通过网页版,可以在线直接编辑,并且点击deploy进行实时发布

缺点:如图所示,经常会出现加载失败问题。建议使用上传方式 image.png

上传版

实际开发可能改动比较多,可以使用上传的方式

注意该方式 要注意构建时候的指令要与服务器的一致。如你是mac电脑打包,服务器是liunx就会报错。 image.png

调试

网页调试

image.png

直接url访问

可以通过直接访问url地址 来测试效果,日志可以通过下面的cloudwatch分析

6. 查看日志cloudwatch

通过cloudwatch的日志组可以查询所有方法请求的结果 image.png

image.png

image.png

7. 实战

1. Lambda@Edge + cloudFonnt 修改请求头

官方例子 指导如何通过触发器,在响应cloudFonnt的时候调用Lambda 实现请求头修改 docs.aws.amazon.com/zh_cn/Amazo…

2. Lambda + S3 触发器创建缩略图

官方例子,每次请求S3的时候,都会在另外一个存储桶生成对应的缩略图 docs.aws.amazon.com/zh_cn/lambd…

注意该程序,如果配置错误,很有可能出现同一个桶响应的图片又生成图片再响应图片的死循环。测试需要多注意

3. 模仿7牛实现url参数动态切割图片

const AWS = require('aws-sdk');
const sharp = require('sharp');
const s3 = new AWS.S3();

const TAG_NAME = 'CreateByLambda';
const TAG_VALUE = '1';
const LAMBDA_BODY_LIMIT = 1024 * 1024; // 1MB

exports.handler = async (event, context, callback) => {
    const request = event.Records[0].cf.request;
    const response = event.Records[0].cf.response;
    const params = new URLSearchParams(request.querystring);
    const width = params.get('width') ? parseInt(params.get('width'), 10) : null;
    const height = params.get('height') ? parseInt(params.get('height'), 10) : null;

    console.log('请求参数:', { width, height });
    console.log('请求URI:', request.uri);
    console.log('请求方法:', request.method);

    console.log("Response Headers:");
    for (const headerName in response.headers) {
        const headerValues = response.headers[headerName];
        console.log(`${headerName}: ${headerValues.map(h => h.value).join(', ')}`);
    }

    console.log("Request Headers:");
    for (const headerName in request.headers) {
        const headerValues = request.headers[headerName];
        console.log(`${headerName}: ${headerValues.map(h => h.value).join(', ')}`);
    }

    if (!width && !height) {
        console.log('无参数则直接回源')
        return callback(null, response); // 无参数则直接回源
    }


    
    const hostHeader = request.headers.host[0].value;
    const s3Bucket = hostHeader.split('.')[0];
    const originalKey = decodeURIComponent(request.uri.substring(1));


    try {
        const sizePart = [width || '', height || ''].filter(Boolean).join('x');
        const parts = originalKey.split('.');
        const extension = parts.pop().toLowerCase();
        const baseName = parts.join('.');
        const newKey = `${baseName}_${sizePart}.${extension}`;

        // 检查缓存
        try {
            await s3.headObject({ Bucket: s3Bucket, Key: newKey }).promise();
            console.log(`命中缓存: ${newKey}`);
        } catch (err) {
            if (err.code !== 'NotFound' && err.code !== 'NoSuchKey') throw err;

            const originalImage = await s3.getObject({ Bucket: s3Bucket, Key: originalKey }).promise();
            let resizedImage = sharp(originalImage.Body);
            if (width || height) {
                resizedImage = resizedImage.resize(width || null, height || null, {
                    fit: 'inside',
                    withoutEnlargement: true,
                });
            }
            if (['jpg', 'jpeg'].includes(extension)) resizedImage = resizedImage.jpeg({ quality: 80 });
            else if (extension === 'webp') resizedImage = resizedImage.webp({ quality: 80 });
            else if (extension === 'png') resizedImage = resizedImage.png();

            const processedBuffer = await resizedImage.toBuffer();

            // 保存到 S3
            await s3.putObject({
                Bucket: s3Bucket,
                Key: newKey,
                Body: processedBuffer,
                ContentType: `image/${extension}`,
                CacheControl: 'public, max-age=31536000',
                Tagging: `${TAG_NAME}=${TAG_VALUE}`,
            }).promise();

            console.log(`新图生成并保存: ${newKey}`);
        }

        // 获取 S3 对象大小
        const objMeta = await s3.headObject({ Bucket: s3Bucket, Key: newKey }).promise();
        const size = objMeta.ContentLength;

        console.log(`Get img: https://${hostHeader}/${newKey}`)

        if (size >= LAMBDA_BODY_LIMIT) {
            // 大于 1MB → 302 Redirect,使用 S3 域名,由于使用源响应,host默认就是桶域名
            return {
                status: '302',
                statusDescription: 'Found',
                headers: {
                    location: [{ key: 'Location', value: `https://${hostHeader}/${newKey}` }],
                    'cache-control': [{ key: 'Cache-Control', value: 'public, max-age=86400' }],
                },
            };
        } else {
            // 小于 1MB → 200 Base64,使用 CDN 域名
            const imageObj = await s3.getObject({ Bucket: s3Bucket, Key: newKey }).promise();
            return {
                status: '200',
                statusDescription: 'OK',
                body: imageObj.Body.toString('base64'),
                bodyEncoding: 'base64',
                headers: {
                    'content-type': [{ key: 'Content-Type', value: `image/${extension}` }],
                    'cache-control': [{ key: 'Cache-Control', value: 'public, max-age=86400' }],
                },
            };
        }

    } catch (err) {
        console.error('Error processing image:', err);
        return {
            status: '500',
            statusDescription: 'Internal Server Error',
            body: 'Failed to process image',
        };
    }
};

测试

https://your-cdn-domain.com/images/photo.jpg?width=300&height=200

这是一个运行在 AWS CloudFront + Lambda@Edge 环境下的 ​图片动态缩放与优化服务,主要功能包括:

  1. 根据 URL 参数动态调整图片尺寸​(如 ?width=300&height=200)。

  2. 使用 Sharp 库进行高性能图片处理​(缩放、格式转换、压缩)。

  3. 将处理后的图片缓存到 S3,并设置长期缓存头。

  4. 智能返回结果​:

    • 图片小(<1MB):直接以 Base64 内联返回(200)。
    • 图片大(≥1MB):返回 302 重定向到 S3 上的图片。
  5. 避免重复处理​:通过检查 S3 缓存实现。

  6. 带有监控与日志​:打印请求、响应、错误等详细信息,便于调试。

8. 踩坑

有时候有些服务会提示“未知错误”无法正常使用 image.png

解决办法,清空cookie和缓存并且退出账号重新登录,或者直接换一个浏览器重新登录。