Amazon Web Services (AWS)



外部相關服務
教學
  • 官方多種服務 "10分鐘" 教學 (link)

AWS 規則

  • 測試 local 連到 AWS 各 Region Ping 值 
  • 務必用 Change Termination Protectin 鎖住 Terminate 防止悲劇 
  • Terminte 的 instance 過一陣子自己會消失 
  • Stop instance PublicIP 會跳、privateIP固定,需使用 ElasticIP 才能綁住 PublicIP 
  • VPC = Private EC2,不對外開放的 instance,須由 VPN 連,提供4種模式 http://www.tts.bz/archives/1488
  • 使用 EBS AMI 將你的 instance 備份,instance 右鍵->Image->Create Image AZ 
  • SES目前亞洲不提供服務,使用時須注意 Sending Quota,每天可發信的配額 
  • SQS 訊息佇列服務。暫存不同 instance 間程式互傳的訊息 
  • S3可針對不同資料夾設定讀取頻率 
  • IAM 使用者權限控制,可以針對不同的 User 限制特定 AWS 服務 
  • EC2 要轉移到另外一個 AWS,只需要將 AMI 開啟分享,再由另外一個帳號找尋並 launch即可 
  • 預設沒有 SWAP Space 
  • ECU 可看成效能單位(1ECU=2007 1GHz Xeon) 
  • vCPU 虛擬線程數 


AWS 免費試用

AWS 免費帳號&各種服務說明 http://itjiawei.blogspot.tw/2015/01/aws.html
官方說明 https://aws.amazon.com/tw/free/#legal

  • EC2
    • 免費公式 = 750小時(月) / N台,越多台同時開耗損越快
    • ElasticIP 開啟的期間,沒開任一台 instance,將會收取額外佔位的費用
    • 流量(Data transfer), In 不用錢,Out 免費 15G
    • EBS 30G 以內不用錢 / 1G Snapshot
    • 1G Snapshot 代表只要建立 snapshot 就準備繳錢,通常 instance 不會只有 1G
    • Snapshot 約 $0.05/1G,依照實際用量收費,不是標示的最大空間
  • SES
    • 可發 62,000 封信/月,付費版 1000封信 0.1USD,附件 1GB 收 0.12USD
  • Billing
    • 左 Month-to-date,是本月到目前為止用量
    • 右 Forecasted Month-end 是到月底,預估使用量


Region
  • Region 清單 (link)
  • Route53 -> Region -> VPC -> Zone -> Subnet -> Security Group
AWS S3
  • liftcycle
  • 變更 bucket 名稱
  • #先變更 ~/.aws/config 的 region
    $ aws s3 mb s3://新bucket名稱
    $ aws s3 sync s3://舊bucket s3://新bucket --acl public-read
  • 圖片網址 改用自己的 domain
    1. 建立一個 名稱為你的 domain 的 bucket
      1. ex. img.myweb.com
    2. 到 bucket -> properties -> 開啟 Static website hosting
      1. 選 Use this bucket to host a website
      2. 輸入預設 index.html 和 error.html
      3. 複製上方的 Endpoint 網址
        1. ex. img.myweb.com.s3-website-ap-northeast-1.amazonaws.com
    3. 到 domain 增加一個 CName 為 img,vlaue 為 endpoint 網址
    4. 找一張圖片,並 make pulic 或 Permissions -> Public access -> Everyone -> 勾read object
  • 刪除的 bucket,需至少 1小時後,才會真正刪除
  • Signed URL
    • OAI(Origin access identity),限制 S3 & viewer access by key pair
    • php Use CloudFront sdk (需 dns name + pk.pem + Security  keypair + expire time),產生圖片網址,讓 client 端可正常開啟圖片

AWS SQS
  • Step-by-Step 用 UI 傳送/接收教學 (link)
  • 運作方式
    1. create Queue,並取得 Url
    2. send Message,給予 Url、Messag
    3. //取得 Queue url,不存在就建立
      private function _getSQSUrl(SqsClient $client)
      {
          $qurl = '';
          try {
              $result = $client->getQueueUrl([
                  'QueueName' => 'myqueue',
              ]);
      
              $qurl = $result->get('QueueUrl');
          } catch (AwsException $e) {
              try {
                  $result = $client->createQueue(array(
                      'QueueName' => 'myqueue',
                      'Attributes' => array(
      //                        'DelaySeconds' => 5,
      //                        'MaximumMessageSize' => 4096, // 4 KB
                          'ReceiveMessageWaitTimeSeconds' => 3  //for long polling
                      ),
                  ));
                  $qurl = $result->get('QueueUrl');
              } catch (AwsException $e) {
                  // output error message if fails
                  error_log($e->getMessage());
              }
              // output error message if fails
              error_log($e->getMessage());
          }
          
          return $qurl;
      }
      
      //發送 message
      public function sendMsg()
      {
          $client = new SqsClient([
              'profile' => 'default',
              'region' => 'ap-northeast-1',
              'version' => '2012-11-05'
          ]);
      
          $qurl = $this->_getSQSUrl($client);
      
          if( ! empty($qurl)){
              $params = [
                  'DelaySeconds' => 1,
                  'MessageAttributes' => [
                      'uid' => [
                          'DataType' => 'String',
                          'StringValue' => 'u000001'
                      ],
                      'rid' => [
                          'DataType' => 'String',
                          'StringValue' => 'djsdofajoiwej'
                      ],
                  ],
                  'MessageBody' => '',
                  'QueueUrl' => $qurl,
                  'Attributes' => array(
                      'ReceiveMessageWaitTimeSeconds' => 3
                  ),
              ];
              try {
                  $result = $client->sendMessage($params);
                  if( ! empty($result->get('MessageId'))){
                      //發送成功
                  }
              } catch (AwsException $e) {
                  // output error message if fails
                  error_log($e->getMessage());
              }
          }
      }
      
      //接收
      public function receiveMsg()
      {
          $client = new SqsClient([
              'profile' => 'default',
              'region' => 'ap-northeast-1',
              'version' => '2012-11-05'
          ]);
          
          $qurl = $this->_getSQSUrl($client);
          
          try {
              $result = $client->receiveMessage(array(
                  'AttributeNames' => ['SentTimestamp'],
                  'MaxNumberOfMessages' => 1,
                  'MessageAttributeNames' => ['All'],
                  'QueueUrl' => $qurl, // REQUIRED
                  'WaitTimeSeconds' => 3, //for long polling
              ));
      
              if (count($result->get('Messages')) > 0) {
                  
                  $msg = $result->get('Messages')[0];
                  $uid = $msg['MessageAttributes']['uid']['StringValue'];
                  $rid = $msg['MessageAttributes']['rid']['StringValue'];
                  
                  //執行甚麼的...
                  
                  $result = $client->deleteMessage([
                      'QueueUrl' => $qurl, // REQUIRED
                      'ReceiptHandle' => $result->get('Messages')[0]['ReceiptHandle'] // REQUIRED
                  ]);
              } else {
                  echo "No messages in queue. \n";
              }
          } catch (AwsException $e) {
              // output error message if fails
              error_log($e->getMessage());
          }
      }
      
    4. receive Message,指定 Url,就會取得未刪除的 Message
    5. delete Message,當事件完成,手動去刪除該訊息
  • 會重複接收
  • php 範例
    • 操作 Queue (link)
    • 傳接 Message (link)
    • 允許 Long polling (link)
      • 需配合  Non-Blocking IO 的 Web Service 或 獨立一台跑 receive


AWS EC2

建立
  • 在 Key Pairs 建立一組 密鑰,並下載 pem 檔
  • 在 Security Group 建立一組 對內/對外 All TCP 的群組,Description 改成容易識別的文字
    • 若要開放 ping (ICMP協定),增加 All ICMP 並指向 myself
  • 建立(Launch) instance
    • 步驟3 Configure instance 務必注意
      • Shutdown behavior 選擇 stop
      • Protect against accidental termination (防止誤觸終止按鈕) 勾選開啟保護
    • 步驟6 Configure Security Group 選擇剛剛建立的安全群組
      • Launch 送出,選擇剛剛建立的密鑰
登入 SSH
  • Instance 上按右鍵 Connect 有說明 
  • 注意:若出現 @@WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! 
      • 需到 ~/.ssh/Known_hosts 刪除之前殘留的 domain ssh key
改 root 帳密登入
  • sudo su 登入,passwd 改密碼 
  • nano /etc/ssh/sshd_config 
    • PermitRootLogin YES 
    • PasswordAuthentication YES 
  • nano /root/.ssh/authorized_keys 
    • 刪除 command="echo xxxxxx;sleep 10" 
  • service ssh restart
備份
  • AMI + Volume
    • Instances -> Image -> create Image
    • 會自動備份關聯 Volume 不用另外操作
  • 單純 Volume
    • Shapshots -> Create -> 選 Volume
擴充容量
  1. 到 Volumes 選擇 mount 的 volume
  2. 選擇 Modify Volume 並調整 size
  3. Instance 重新啟動
Load Balancer
  1. 在同一 VPC 下,必須使用 2個以上的 Zone,才能運作
  2. 每個 Target Group 都會分配 DNS,將不同 Zone 的 instance 綁定到 Target Group 上,LB 即可使用
  3. 用 DNS Name 即可測試網站是否正常
  4. 開啟 sticky session 讓 user 短期間內都造訪同一台機器
    1. Target Group -> edit Attribute -> Stickiness -> Enable
  5. 若將 session 改存到資料庫(獨立server),且每一台 instance 可讀取到相同資料,就不必開啟 sticky session
Scalability
  1. 可定義 CPU 或特定值到某個程度,自動 增/減 機器,也可自己手動拓展
  2. 當自動減少機器時,連帶 user session 也會被踢掉,要解決此問題:
    1. 採用固定的機器數
    2. 使用 DynamicDB 統一儲存 session
  3. 可以建立 Lunch configuration,可以更便捷的將 Scale、LB 等設定,一次建立到位

AWS EBS

  • mysql、volume、snapshot、iam、elasticIP


AWS SES


  1. 建立 SMTP credentials,可取得 IAM username, smtp user/pass
    1. 要看建立了多少證書,可以到 IAM / users 找開頭為 ses-smtp-user
  2. 剛申請,會在 sendbox 沙箱中,每天 200封額度, 必須將發送端、接收端的 mail 加入 Email Address 並驗證,才可發送,否則都會收到 554 error.
  3. 一個AWS account, 最多只能存1000個entries、domain
  4. host 為 ssl://email-smtp.xxx.amazonaws.com/,post 465
  5. 測試 OK 之後,要開通 (link)
    1. 點擊 "Request a Sending Limit Increase"
    2. 填寫表單,等待一天後開通
    3. 驗證 Domain、增加 DNS 記錄
    4. 完成
  6. email網域設定為自己的 domain (link)
    1. 在 domain 頁面 Verify a new domain 加入自己的網域
    2. 將 TXT 加入自己網域的 Record
      1. Record Type:TXT (Text)
      2. TXT Name*:_amazonses.abc.com
      3. TXT Value:pABCd6lCFmJQGGcYu+5FB+06KhLb7USvQahgQYlNms=

AWS IAM

  • 註冊完後,使用 email & password 可登入 root account
  • 群組
    • 針對不同 device 等,可個別開啟特定 aws 服務
    • 建立後,再掛到子帳號身上 
  • 子帳號
    • 建立時可選擇
      1. 允許使用 AWS API, CLI, SDK
      2. 允許登入 aws management console (管理主控台)
    • 相關資訊
      • IAM -> Users -> 帳號 -> Security credentials 
      • 可查看登入網址 https://My_AWS_Account_ID.signin.aws.amazon.com/console/
      • 可修改主控台密碼
      • 上傳本機的 SSH Pubkey (id_rsa.pub)

AWS RDS
  • 關聯式資料庫 
    • Mysql 目前支援版本 
      • 5.7.11、5.7.10、5.6.29、5.6.27、5.6.23、5.6.22、5.6.21b、5.6.21、5.6.19b、5.6.19a、5.5.46、5.5.42、5.5.41、5.5.40b、5.5.40a、5.1.73b、5.1.73a
  • Create Replica
    • Replica 的 DNS 網址跟 Master 不一樣

DynamoDB

  • AWS 的 NoSQL 資料庫,無主機、算流量、可自動 scale
  • EC2 要 access,需先在 IAM 建立含有 access DynamoDB 的 role,再掛載到 instance 身上
  • 若只想開放部份權限給 instance
    • IAM -> Create Policy -> Service(輸入 dynamoDB) -> 在設定細節
    • 完成後,到 原本的 role ,attach policy 

ElastiCache

  • 高可用性的 cache
  • 可選擇 Redis 或 Memcached

Beanstalk

  • 使用環境參數傳入 PHP,PHP 使用 $_SERVER['xxx'] 取得
  • Zip 打包上傳 or S3 取得 


AWS SDK (link)

有 mobile, java, nodejs, php, python, go, IOT...
給服務使用的多半是 S3,建議到 IAM 另外開一個 user 只允許 S3 權限

  • S3
    • init
    • $awsS3 = new S3Client([
          'version' => 'latest',
          'region' => 'ap-northeast-1',
          'credentials' => [
              'key' => 'IAM user key',
              'secret' => 'IAM user secret key'
          ]
      ]);
      
    • 取得檔案資訊
    • $info = $awsS3->getObject([
          'Bucket' => 'bucket name',
          'Key' => 'filename.xxx',
          //'SaveAs' => '/tmp/abc.jpg' //下載
      ]);
      
    • 檔案是否存在
    • $info = $awsS3->doesObjectExist('bucket name', 'filename.xxx');
      
    • 刪除單一檔案
    • //也有 deleteObject"s"
      $info = $awsS3->deleteObject([
          'Bucket' => 'bucket name',
          'Key' => 'filename.xxx'
      ]);
      
    • 刪除多個檔案 by prefix、regex
    • $awsS3->deleteMatchingObjects('bucket name', null, '/^(.{30,35}_product.png)/s');
      $awsS3->deleteMatchingObjects('bucket name', '/myfolder');
      
    • 上傳檔案
    • $awscli->putObject([
          'Bucket'       => 'bucket name',
          'Key'          => 'myfolder/filename.xxx',
          'SourceFile'   => 'local path',
          'ACL'          => 'public-read',
          //'StorageClass' => 'REDUCED_REDUNDANCY'
      ]);
      

AWS CLI (link)

  1. 需安裝 python 2.6.5 以上 + pip
  2. pip install awscli
    1. sudo pip install --ignore-installed awscli
  3. aws configure (link)
    1. 到 IAM 建立一組 accesskey, securitykey
      1. IAM->Users->you->Security credentials->Create Access key
    2. 用指令 aws configure 輸入資訊
    3. 憑證會儲存在 ~/.aws/credentials
  4. config 儲存在 ~/.aws/config
  • 況狀
    • OSError: [Errno 13] Permission denied: '/Library/Python/2.7/site-packages/docutils'
      • linux: sudo chown -R $USER /usr/local/lib/python2.7/
      • mac: sudo chown -R $USER /Library/Python/2.7/
    • OSError: [Errno 1] Operation not permitted: '/tmp/pip-I6dBoP-uninstall/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/six-1.4.1-py2.7.egg-info'
      • sudo pip install --ignore-installed awscli
    • 在 crontab 中,無法執行
      • 在 script 上方或指令前方帶入以下參數
      • export AWS_CONFIG_FILE="/home/youruser/.aws/config"
        export AWS_ACCESS_KEY_ID=XXXX
        export AWS_SECRET_ACCESS_KEY=XXX
        
      • 且使用完整 aws 路徑執行 /usr/local/bin/aws
建立 EC2 (run-instances)
  • aws ec2 run-instances \
    --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=hello}]' \
    --image-id ami-xxxxxxxx \
    --key-name xxxx \
    --instance-type t2.nano \
    --subnet-id subnet-xxxxxxxx \
    --security-group-ids sg-xxxxxxxx \
    --count 1 
  • --user-data file://rabbitmq-user-data.sh #建立後,執行
    • 只要檔案形式不管如何都要加 file://
  • 列表
    • instance-type https://aws.amazon.com/tw/ec2/instance-types/
    • image-id 可到 ami 建立後取得
    • key-name 到 key Pairs 建立後取得
    • subnet-id 到Elastic IPs->Network interface ID -> Subnet ID
    • vpc-id 到 security group 建立後取得
    • zone 為 Dashboard -> Avilability zone 最後一個字
Filter

  • 取得 private ip by Tag:Name
    • aws ec2 describe-instances --filters "Name=tag:Name,Values=hello" --query "Reservations[*].Instances[*].PrivateIpAddress" --output=text
常用指令

  • EC2
    • 新增:aws ec2 run-instances ...
    • 暫停:aws ec2 stop-instances --instance-ids $instanceid
    • 開始:aws ec2 start-instances --instance-ids $instanceid
    • 刪除:aws ec2 terminate-instances --instance-ids $instanceid
    • 查詢:aws ec2 describe-instances
    • 查詢(執行中):aws ec2 ls --ec2-state running | grep PublicIp  #使用 saws
  • ElasticIP
    • 綁定:aws ec2 associate-address --instance-id $instanceid --public-ip $elasticip
    • 取消綁定:aws ec2 disassociate-address --public-ip $elasticip
  • S3
    • Bucket清單:aws s3api list-buckets
    • 檔案清單:aws s3api list-objects --bucket $bucket
    • 檔名清單查尋:aws s3 ls s3://$bucket | awk {'print $4'} | grep -e '^\s*部分檔名'
    • 重新命名:
      • 建立:aws s3 mb s3://新bucket名稱
      • 轉移:aws s3 sync s3://舊bucket s3://新bucket --acl public-read



相關工具

  • saws
    • 指令自動完成工具



EC2 container

  • 相關縮寫
    • ECR: Amazon EC2 Container Registry
  1. 只算 instance 費用,container 服務本身不收費
  2. 可在存在的 instance 中,依情況配置不同服務的數量
  3. 每個 repo image 數量,max = 1000
  4. 概念為,定義好複製 node 時的內容,設定好策略,如CPU到達80%時,最多擴充幾台
  5. 但資料需另外啟用 volume 來共享、保存
  6. 調整 instance 數量
    • 從 Cluster->ECS instances->Scale ECS instance 來手動調整
    • 也可是 0 台
    • 不需手動刪 instance
  7. Task?
  8. 操作
    1. 建立 repo (像是 docker hub)
    2. 登入 ECR(registry)
    3. 將自己的 image 加上 tag
    4. 推到 ECR 上
    5. 建立 task
    6. 到 EC2 看是否有新 instance 並開啟 public ip測試
    7. stop 該 instance ,看是否有自動 create 新 instance

高可用性架構 high availability

意指增加系統穩定度、擴充彈性。

CloudFront

  • 亞洲節點 (link):印度清奈、中國香港 (3)、馬來西亞吉隆坡、印度孟買 (2)、菲律賓馬尼拉、印度新德里、日本大阪、韓國首爾 (3)、新加坡 (2)、台灣台北內湖、日本東京 (4)
  • 亞洲區域節點快取:印度孟買、新加坡、南韓首爾、日本東京
  • #節點快取:指該區域熱門資料集中地
  • S3 to Data Transfer Out to CloudFront 免費
  • Request 每 1萬個計價:台灣 http $0.009, https $0.012
  • 注意自訂 SSL 價格,高達 600/mth,天計費
    • 使用 SNI 自訂 SSL 進行憑證管理無須預付費或每月費用
    • 免費憑證(ACM) 支援 ELB、CloudFront (教學),只能給 AWS 服務使用
    • 免費憑證限制:數量? 3個月失效?
  • 建立
    1. 如要關聯 S3,如 S3 原先有開 Static web hosting ,請關閉
    2. Create Distribution->web
    3. Origin Domain Name 為 Endpoint domain
    4. Viewer Protocol Policy 選 Redirect HTTP to HTTPS 或 HTTP to HTTPS
    5. 設定 CNAMES,輸入你申請的 domain,ex. img.mydomain.com
    6. 設定 SSL
      1. 可選擇使用 *.cloudfront.net
      2. 或 Request or Import a Certificate with ACM 新增免費憑證\匯入自己的憑證
        1. 新增:填入完整 CNAME 即可申請該網址的SSL,ex. img.mydomain.com
        2. or 匯入:要用自己的選擇 Import a Certificate 
          1. 連結會帶到 Certificate Manager,貼上你的 ssl 3份文件,可立即建立,文件可包含多個子網域,會自動判讀
          2. 再回到 CloudFront Distributions 編輯設定 SSL,選擇此憑證
          3. 應該馬上就會生效 

    7. Custom SSL Client Support 選擇 SNI,否則需付大筆費用
    8. 如果此 CDN 是指向網站,Default Root Object 可設定為你的入口檔 ex.index.html
    9. 到 DNS 供應商,設定 CName 指向 CloudFront Domain Name,ex. hrn59gv5o0levl.cloudfront.net
  • 清除 CloudFront 快取
    • 須到 cloudfront->xxx.asensetek.com->Invalidations->Create->將該圖片路徑輸入
    • ex. /img/th/1avvvvvd67510d6b38356ef6b3ebdabf_product_import_prod_512x512.png
  • 注意:
    1. 若有開 S3 的 Static web hosting 與 CloudFront Redirect HTTPS,會有機會跳轉到原始網址,而不是你指定的 CName

常見問題


  • Ping 不到機器
    • security 開啟 ICMP protocol

資源

Amazon Web Services (AWS) Amazon Web Services (AWS) Reviewed by Wild on 4/29/2016 09:48:00 下午 Rating: 5

沒有留言:

沒有Google帳號也可發表意見唷!

技術提供:Blogger.