2015年7月31日 星期五

使用AWS雲端服務架設LAMP網路伺服器

緣由
  在一起美麗的誤會下,有幸得以使用AWS(Amazon Web Services)來架設環境以部署PHP應用程式。以前所接觸的都是微軟如IIS、SQL Server等的產品和環境,因此在針對指定情境去設定的過程中,花費了不少小時才稍微有點眉目,一開始參考了建置Web App的說明文件還有Elastic Beanstalk(AWS眾多服務項目的其中一個)的範例文件去操作了一遍,覺

圖一、AWS提供的眾多服務
得Elastic Beanstalk「看起來」設定最快速,所以決定採用這個服務來設置PHP應用程式的環境,參考了許多官方和Stack Overflow的文件和問答,一直無法解決連線到在AWS上建置的DB實體上失敗的問題。一開始測試時,在進行欲將本機MySQL資料庫複製到DB實體上的步驟時,命令列都會出現「ERROR 2003 (HY000): Can't connect to
MySQL server on 'DB實體的end point' (110)」這樣的訊息,不斷查閱資料和測試後,最後我認為是連結DB實體的安全群組(security group)中裡面的inbound rule沒有附上允許我本機IP通過的規定,才導致連結失敗。在得出這個結論時,已相當疲倦,所以決定隔一天再來繼續,到了隔天,我把Elastic Beanstalk昨天建的環境刪除,並重新建置一個環境和一個DB實體,在要進行與昨日最後相同的步驟時,反饋訊息不一樣了,是出現感覺更讓人掠狂的「Unknown MySQL server host 'DB實體end point'」訊息。於是乎,我決定再使用別的方法,為了能先順利執行PHP應用程式,最後採用在一個EC2實體上建立LAMP網路伺服器的方式,並順利執行了PHP應用程式。為了幫助對LAMP幾乎沒什麼概念的人能更快速建立出環境執行PHP程式,所以寫下這篇手把手的教學文章,願各位建置順利。

架設步驟
  1. 註冊一個AWS帳號。
  2. 建立一個EC2實體
    1. 進入AWS管理主控台,確定頁面上的地區是Oregon,接著點擊EC2。
    2. 在左邊選單中的Instances項目裡面,點選Instances。
    3. 在右邊畫面點選Launch Instance。
    4. 選擇Amazon Linux映像檔,就是圖二中的最上面那個項目。

    5. 圖二、AMI選擇畫面
    6. 選擇你想要的實體類型(與速度、記憶體有關),如果只是想測試,可以選擇預設不收費的類型,如圖三所示。接著點「Next: Configure Instance Details」。

    7. 圖三、Instance類型選擇畫面
    8. 設定實體,需要變更的項目有Subnet、Auto-assign Public IP和IAM role。Subnet任意擇一,我是選2a。Pulic IP選Enable,IAM role則需要建立一個新的。在尚未建立新的IAM並選擇時,畫面會像圖四一樣。

      圖四、實體設定畫面
      1. 點擊Create new IAM role。
      2. 在新跑出的頁面點Create New Row。
      3. 輸入這個role的名稱,接著在類型選擇的頁面點選Amazon EC2。
      4. 在Policy頁面點選PowerUserAccess。
      5. 點選Create Role,完成後的畫面會像圖五一樣。

      6. 圖五、IAM角色建置完成畫面
    9. 回到Instances的畫面,在IAM那個欄位點選剛剛建立的role,接著按「Review and Launch」。
    10. 實體資訊預覽畫面保持不動,另開一頁面進入AWS管理主控台建立一個security group。
      1. 在服務項目中點EC2,於「NETWORK & SECURITY」項目中,點「Security Groups」。
      2. 點選「Create Security Group」按鈕。
      3. 在跳出的畫面中,要為這一個security group命名,描述那個欄位就自便,並且於頁面中的Inbound Rule要增加三條規則,分別是HTTP、HTTPS和SSH,SSH那個欄位要輸入「你主機IP位址/32」,輸入完會類似圖六。

      4. 圖六、Security group建置畫面
    11. 回到Instances的畫面,在「Security Groups」頁籤中,點擊右邊的「Edit security groups」,再點「Select an existing security group」,然後選擇你剛剛建立的security group,最後點「Review and Launch」。
    12. 實體資訊預覽畫面保持不動,另開一頁面進入AWS管理主控台建立一個Key Pairs。
      1. 在服務項目中點EC2,於「NETWORK & SECURITY」項目中,點「Key Pairs」。
      2. 於接著畫面點「Create Key Pair」,輸入你想要的名稱,然後完成,沒多久會跑出一個.pem為副檔名的檔案給你下載,這個一定要保存好。
    13. 回到Instances的畫面,點「Launch」,於跑出的畫面要你選擇Key Pair,選「Choose an existing key pair」,再選你剛剛建立的key pair,「I acknowledge....」那裏打勾,然後按「Launch Instances」。
    14. 在接著的畫面點「View Instances」,你會看到你剛剛設定的實體正在建立中,等到「Instance State」和「Status Checks」都通過後,實體就建立完成了,像圖七一樣。

    15. 圖七、實體建立完成畫面
  3. 連結到剛剛建立的Linux實體。
    1. 這裡下載Putty完整安裝程式(putty-0.65-installer.exe),安裝它。
    2. 將剛剛的金鑰(.pem檔)轉成.ppk檔。
      1. 打開PuTTYgen
      2. 「Parameters」選「SSH-2 RSA」,如圖八所示。

      3. 圖八、鑰匙轉檔參數選擇畫面
      4. 點擊「Load」按鈕,選剛剛下載的.pem鑰匙。檔案類型要選全部,才能看到.pem檔。選完後會跑出一個視窗,點Yes即可。

      5. 圖九、選擇鑰匙畫面
      6. 點「Save private key」,按完後會跑出一個視窗,點yes即可,另外名字取得和.pem檔案一樣就好。結束後,待會要用於登入的.ppk檔案就產生了。
    3. 打開PuTTy,提入相關設定,連到Linux實體。
      1. 在「Host Name」輸入「ec2-user@你的Linux實體DNS」。Linux實體DNS可以在實體的描述(Description)中的「Public DNS Name」查到。
      2. 左邊選單中的「Connection」中,展開「SSH」,點「Auth」,在檔案選擇那裏選剛剛轉出來的.ppk檔案。
      3. 登入成功後會跑出像圖十的畫面,點「Yes」就可以了。

      4. 圖十、安全性警告畫面
  4. Linux設定
    1. 讓所有軟體package處在最新狀態。
      sudo yum update -y
    2. 安裝Apache網路伺服器、MySQL和PHP。
      sudo yum install -y httpd24 php56 mysql55-server php56-mysqlnd
    3. 開啟Apache伺服器。
      sudo service httpd start
    4. 設定Apache伺服器在每一次系統開啟都會啟動。
      sudo chkconfig httpd on
    5. 在任一瀏覽器上輸入你這個Linux實體的DNS,應該要跑出像圖十一的畫面。

      圖十一、頁面測試畫面
    6. 設定檔案權限
      1. www群組加入實體中。
        sudo groupadd www
      2. 把你自己加到www群組中。
        sudo usermod -a -G www ec2-user
      3. 登出再登入一次,然後驗證你在www群組中的成員狀態。
        sudo usermod -a -G www ec2-user
        1. 登出
          exit
        2. 再次登入,並驗證在www群組中的成員狀態。
          groups
      4. 改變 /var/www 群組擁有權限和內容到 www群組中。
        sudo chown -R root:www /var/www
      5. 改變 /var/www 的目錄權限和其子目錄以增加群組寫入權限,並設定該群組ID在未來的子目錄上。
        sudo chmod 2775 /var/www
        find /var/www -type d -exec sudo chmod 2775 {} +
      6. 重複改變 /var/www 的檔案權限和其子目錄以增加群組寫入權限。
        find /var/www -type f -exec sudo chmod 0664 {} +
    7. 保密MySQL資料庫
      1. 啟動MySQL。
        sudo service mysqld start
      2. 執行mysql_secure_installation
        sudo mysql_secure_installation
        1. 當訊息跳出,輸入root帳號的密碼。
          1. 預設上,root帳號沒有設定密碼,可以直接按Enter。
          2. 如果要設定密碼,就按Y。
        2. 當訊息跳出,輸入root帳號的密碼。
        3. 輸入Y,如果出現Remove anonymous users?
        4. 輸入Y,如果出現Disallow root login remotely?
        5. 輸入Y,如果出現Remove test database and access to it?
        6. 輸入Y,如果出現Reload privilege tables now?
    8. 在Linux實體中的MySQL中新增資料庫。
      1. 進入MySQL伺服器。
        mysql -u root -p密碼
      2. 如果出現「ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)」訊息。
        1. 停止MYSQL 服務。
          # stop mysql
        2. 跳過授權表訪問
          # mysqld_safe --user=mysql --skip-grant-tables --skip-networking &
        3. 登錄MYSQL
          mysql -uroot mysql -p密碼
        4. 重輸入密碼
          UPDATE user SET Password=PASSWORD('輸入你 root 的新密碼') where USER='root';
        5. 把 所有資料庫(含其下的所有資料表),授權給 root。
          GRANT all ON *.* TO root@'localhost' IDENTIFIED BY '輸入的密碼';
        6. 更新權限。
          FLUSH PRIVILEGES;
        7. 離開MySQL。
          quit
      3. 建立資料庫。
        CREATE DATABASE 資料庫名稱;
      4. 離開PuTTy。
  5. 使用WinSCP傳送檔案。
    1. 這裡下載WinSCP,然後安裝它。
    2. 「Host name」填入你Linux實體的DNS,「User name」填入「ec2-user」。
    3. 點擊「Advanced」按鈕,在跑出的頁面右邊,點SSH下的Authentication,然後於左邊選擇.ppk鑰匙檔案。
    4. 第一次登入會跑出安全性警告視窗,點是即可。
    5. 登入後,左邊是本機位置,右邊是Linux實體位置,右邊要走到/var/www/html底下,接著將PHP應用程式傳到那個目錄底下。
    6. 假設你傳到Linex的應用程式當中有含備份.sql檔,那麼傳完之後要將.sql資料匯到剛剛在Linex實體裡面建立的資料庫。
    7. 離開WinSCP。
  6. 使用Putty登入到Linux實體,然後將.sql檔匯到剛剛所建的資料庫裏面。
    mysql -u root -p密碼 資料庫名稱 < Linux實體的儲存路徑/blog.sql
  7. 開啟你的PHP應用程式,網址會是「Linux實體DNS/index.php」,假設你的應用程式裡面有含index.php這份檔案。
結論
  使用雲端服務,操作AWS算是第二次經驗,第一次的經驗是使用成大的虛擬主機服務,VM Ware的vSphere,在一次產學合作中,我必須測試用Matlab寫成的一支預測模型程式,執行起來的速度如何,那時也是花了不少時間才對雲端服務有點眉目。而這次AWS操作起來,覺得要知道的概念也是要不少,才能架起像樣的環境以供應用程式執行。寫完這篇文章,我還是沒成功架設起一支透過Elastic Beanstalk建立的PHP程式,倒是我有成功地建立一個MySQL的DB實體,然後從本機dump資料庫過去,但程序執行起來,應用程式裡面連資料庫呈現的內容有部分出現亂碼,而且開啟速度非常慢。估計還要一些時間,才能搞清楚是怎麼回事吧。

參考
  1. 解決 MYSQL 登入時,ERROR 1045 (28000) using password: NO 的方法。(民100年11月17日)。取自http://mustgeorge.blogspot.tw/2011/11/mysql-error-1045-28000-using-password.html
  2. Amazon EC2 Security Groups for Linux Instances. Retrieved from http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/concepts.html
  3. Connect to Your Instance. Retrieved from http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-connect-to-instance-linux.html
  4. Connecting to a DB Instance Running the MySQL Database Engine. Retreived from http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_ConnectToInstance.html
  5. Connecting to Your Linux Instance from Windows Using PuTTY. Retrieved from http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/putty.html
  6. could not open connection to the host, on port 23: Connect failed. (April 10, 2012). Retrieved from http://stackoverflow.com/questions/7783688/could-not-open-connection-to-the-host-on-port-23-connect-failed
  7. Create a MySQL Database on Linux via Command Line. Retrieved from http://www.liquidweb.com/kb/create-a-mysql-database-on-linux-via-command-line/
  8. How to import an SQL file using the command line in MySQL? (16th July, 2013). Retrieved from http://stackoverflow.com/questions/17666249/how-to-import-an-sql-file-using-the-command-line-in-mysql
  9. Step 1: Create an Application Server. Retrieved from http://docs.aws.amazon.com/gettingstarted/latest/wah-linux/getting-started-application-server.html
  10. Tutorial: Installing a LAMP Web Server on Amazon Linux. Retrieved from http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/install-LAMP.html
  11. Using Amazon RDS with PHP. Retrieved from http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create_deploy_PHP.rds.html

分享:
Share to Facebook Share on Google Plus Share on Tumblr Share to Twitter Email This Pin This