《Modern PHP》第七章 Provisioning 導讀

Laravel 台灣社群活動 在進入正題之前先幫忙打一下廣告,目前 Laravel 台灣社群每個月固定會舉辦兩次 LaraDiner (Laravel 讀書會),讀書會不一定會有講題,若有 Laravel 使用上的疑問可以帶到讀書會中詢問大家,讀書會主要是希望提供一個固定的空間與時間讓社群朋友可以彼此認識聊天。

目前讀書會中正在進行「讀書會中的讀書會」,目前閱讀的書是《Modern PHP》,而每次 LaraDiner 則會有成員對書中內容進行導讀。

而本週四(2015/6/4)就是由我負責導讀第七章的內容。

下面是這次為了導讀所製作的簡報,可以對照本篇文章閱讀

第七章主題 Provisioning 因為這是一本關於 PHP 的書,因此並不會過度深入 Provisioning,僅僅點到為止。

同時本章的內容僅適用於 VPS (Virtual Private Server) 或可以自由安裝軟體並設置 config 的環境。

最後,如果你實在不愛使用 Command Line 來管理 Server,基本上我覺得也可以直接快速翻過本章,而書中作者則建議你可以改用 Engine Yard 或 Heroku。

目標 在本章內容中會完成以下幾個目標:

  1. 開啓一台 VPS,登入 VPS,並完成基本的安全性設定。
  2. 安裝設置 Web Server 來處理 HTTP requests。
  3. 安裝設置 PHP processes 來處理 PHP requests。 附帶一提,過去常見的方案是 Apache + Apache mod_php,但現在比較主流的做法是 Nginx + php-fpm。

VPS 作者推薦使用 Linode 或 DigitalOcean,我個人也同樣推薦。除了帳號申請容易及開機方便外,這兩間最小計費單位都是「小時」,因此可以自在的開機玩個幾小時,不必擔心會被一次收取整月費用。

台灣與 Linode 日本機房的連線速度與品質不錯,但可惜自從 Linode 日本機房賣光之後,現在陷入想買不一定買得到的狀態。第二優先的選項我建議可以買 DigitalOcean 的 San Francisco 機房,連線品質在可接受的範圍。最後,Linode 與 DigitalOcean 都有新加坡機房,但我個人的經驗都不太好,以前有看到一個數據是台灣與新加坡互通的線路頻寬比起連日本或美西都小,雖無法肯定是否是這個原因,但我個人目前依然對新加坡機房印象不佳。

成功開啟新 VPS 後,你就會收到 root 帳號的密碼,即可使用此組密碼 ssh 登入主機。 若是常常需要開啟 DigitalOcean 的 VPS,我建議可以預先設置 SSH Key-Pair,以後開啟新 VPS 時,可以直接用你本機電腦的 SSH Key-Pair 登入,一方面可以避免 root 密碼泄露的問題,你也不用一一記憶每一台 VPS 的密碼,只要擁有 key 即可登入主機。

首次登入 續上,當你取得 root 密碼後,當然就可以透過 SSH 來登入主機。 基本上如果是 MAC OS,可以直接使用 Terminal 登入,若是 windows 環境,就請改用 putty 或其他的方法了。

補充說明一下,若是你經常開啟新 VPS,並關機刪除 VPS,接著又再重新開啟新 VPS,你就有可能會遇到下圖的狀況。

這是一個簡單的安全性提醒,因為你的 VPS 已經被刪除並重新建立了,新舊 VPS 其實是不同的主機,但是卻有著一樣的 IP,所以 SSH 就會提醒「雖然是同樣的 IP,但現在想要連線的主機與記錄於 ~/.ssh/know_hosts 裡的不一樣。」

最後新開啟的 VPS 建議都要執行一下軟體更新,確保基本的軟體都已安裝最新的版本,包含最新的漏洞修補。

基本的安全性設定 書中提到的基本安全性設定主要有四項:

  • 建立非 root 的帳號(Nonroot) 並且給與它 SUDO 權限。
  • 改用 SSH Key-Pair 來登入主機。
  • 取消用密碼登入主機,並禁止使用 root 登入主機。
  • 設置基本的防火牆 (iptables)

下面稍微說明一下每一項的重點

建立非 root 帳號

理由很容易懂,因為 root 的權限太大了,一旦外洩就慘了,所以都會另外建立另一個一般使用的 user,但是給予它 SUDO 權限,讓它在必要的時候可以獲得 root 權限來管理主機。

改用 SSH Key-Pair 來登入主機

只要用密碼登入,就有可能造成密碼的泄露,並且這世界上有一種東西叫做「暴力密碼破解」,如果用密碼登入,難保哪一天被人猜出密碼來。 (補充說明:當然一般還是會配合其他的工具來阻止「暴力密碼破解」,總之安全性這東西,可以做的方式與方向很多。)

取消用密碼登入主機,並禁止使用 root 登入主機

理由同前兩項,不只改用 key 來登入新建立的 Nonroot user,同時我們還要把「用密碼登入」及「root 可以遠端登入」這兩件事徹底斷絕。讓人根本沒有機會使用密碼 + root 來登入主機。

設置基本的防火牆 (iptables)

此項在書中只有放在 NOTE 中提醒,但我個人強烈建議一定要學習有關 iptables 的設置,光是此項就能幫助提升不少安全性。網路上很容易可以 Google 到許多教學及 Example,為了安全還是研究一下吧。

PHP-FPM 接著書中先提到了 PHP processes,採用的是 PHP-FPM (PHP FastCGI Process Manager)。 PHP-FPM 在運行的時候有一個特點是,它會先運行一個 Master process,由 Master 去控制其他的 Child process。

安裝 PHP-FPM

如果你採用的是 ubuntu 14.04,那麼官方的 apt-get 目前只能安裝到 php-fpm v5.5.9,如果你需要更新一點的版本,可以參考書中的教學,或者自己 Google “how to install latest php on …",再不然可以很硬的自己去下載 source 來 build。

設定 php.ini、php-fpm.conf

PHP-FPM 一樣有自己的 php.ini 可以設定,若是 ubuntu 的使用者,可以在 /etc/php5/fpm/ 找到 php.ini。另外還有一個 php-fpm.conf 需要設定,同樣可以在 /etc/php5/fpm/ 找到它。

書中特別提到了 php-fpm.conf 的兩個參數,如下:

  • emergency_restart_threshold = 10
  • emergency_restart_interval = 1m 這兩個參數的意義到底為何呢? 意思就是假設在 1分鐘之內,如果 PHP-FPM 的 Child processes 因為 SIGSEGV 或 SIGBUS 的緣故中斷超過 10 次,就自動將 PHP-FPM restart。 至於 SIGSEGV 或 SIGBUS 為何,我們就有請 wiki 百科來解答吧!
  • SIGSEGV
  • SIGBUS

設定 Pool

前面提到 PHP-FPM 運行時會有 Master 及 Child,而實際上 Child 在運行時,會被獨立放置在 Pool 之中,Pool 有一點類似 Sandbox,會是一個獨立環境,所以你會看到許多 PHP-FPM 的調教文章都會如此建議,假設你一台 VPS 上有多個 PHP Application,那麼你可以將它們各自放在不同的 Pool,各別分配不同的資源。

若要建立兩個 Pool,只要在 /etc/php5/fpm/pool.d/ 中分別建立不同的 config 檔案。 (當然因為有兩個 config 檔案,所以要注意一些設定值不要衝突了,像是 listen = 127.0.0.1:9000,可能就要一個採用 port 9000,另一個採用 port 9001。)

同樣書中提到其他重要的參數,這裡就不詳細說明,細節都可以去參考 php-fpm 官方文件。 僅補充說明五點。

第一點是 listen = 127.0.0.1:9000 除了可以走 TCP 之外,也可以改成 listen = /var/run/php5-fpm.sock,改走 sock 的方式,據說 sock 的效率比 TCP 來的好,所以如果有效能上的考量,可以嘗試改用。

另一點則是 listen.allowed_clients = 127.0.0.1,PHP-FPM 若運行在 TCP 時,基本上你也可以做到讓 A 主機(Web)取用 B 主機(PHP-FPM)這樣的架構,雖然我覺得應該很少有人會這樣搞,所以你可以用 listen.allowed_clients = xxx.xxx.xxx.xxx 在 IP 做安全性設定。

接著則是 pm.max_requests = 1000,此項參數的意思是當每個 Child process 處理了 1000 個 request 之後,就會自動重新生成。會需要設定此項的原因多數都是為了避免 memory leaks 的問題,因此也都會建議要開啟。

最後兩個參數可以一起來看,分別是slowlog = /path/to/slowlog.logrequest_slowlog_timeout = 5s,簡單來說假設你想要知道你的 PHP 是在哪裡運行得很慢,就把這兩個參數開啟。以上面的參數為例子,即代表「將所有超過5秒的 request 資訊,都寫入 /path/to/slowlog.log 之中」。

有關 PHP-FPM 的部分書中就說明到此,接著是 Nginx。

Nginx 首先我們先來練習發音 Nginx (影 居ㄟ 可斯)

安裝 Nginx

一樣書中先從安裝開始講起,所以我的補充也是相同的,如果你採用的是 ubuntu 14.04,那麼官方的 apt-get 目前只能安裝到 Nginx v1.4.6,這其實是滿舊的版本了,目前最新版已經是 v1.9.1 了。

如果你需要更新一點的版本,可以參考書中的教學,或者自己 Google “how to install latest nginx on …",再不然一樣可以很硬的自己去下載 source 來 build。

Virtual Host

在 ubuntu 中,nginx 的 Virtual Host config 會比照 apache 的管理方式,主要放置在 /etc/nginx/sites-available/ ,但與 apache 不同的是沒有 a2ensite 這種指令可以使用,所以要自己手動 ln -s 關聯至 /etc/nginx/sites-enabled/。

所有的 Virtual Host config 主要都是由 server { ... } 來構成內容的,書中有使用一個 example 來說明,但同樣的這裡就不一一說明,只針對幾點補充說明:

  1. listen 80 代表這個 Virtual Host 要 listen 80 port,同理你也可以 listen 443 (https),但是書中沒提的是如果要啟用 https,其實還要再補上 SSL 相關的 config,這一點要特別注意。
  2. server_name example.com 這是用來設定 domain name,與 apache 不同的是,如果一個 Virtual Host 要對應到多個 domain name,那你可以直接在 server_name 中直接設定, domain name 之間直接用空白隔開即可,例如: server_name example.com example2.org example.tw example.jp
  3. location ~ \.php { ... } 這一整段代表 Nginx 接到 PHP request 之後該如何處理,按 example 的設定是 fastcgi_pass 127.0.0.1:9000,所以假如今天 PHP-FPM 是運行為 sock,記得要改成你的 sock 路徑,例如 unix:/var/run/php5-fpm.sock

其實 Nginx 在 config 中可以做到很多事情,甚至可以開外掛將 Lua 程式語言載入,所以在 config 中就可以做到像是建立變數邏輯判斷之類的動作,有興趣者可以繼續深入研究。

自動化 Provisinoing、代理 Provisinoing 及延伸閱讀 在本章的尾聲,作者很快的提到了一些補充資訊。

自動化 Provisinoing

現在有許多的自動化 Provisinoing 工具可以使用,一般我們會稱這些工具為 Configuration Management,基本上每一套都很強大,目前競爭激烈,因此我也沒辦法回答說選哪一套比較好,但倒是可以補充一個無關緊要的資訊,那就是這四套工具分別是用哪個語言撰寫的 XD。

代理 Provisinoing

基本上就是 Forge 啦,想要用 GUI 的方式來管理本章提到的內容,就用 Forge 吧!

延伸閱讀

書中推薦的延伸閱讀是 Servers for Hackers by Chris Fidao,這套教材我也是同樣的強力推薦,對於完全不懂 System Administration 的 developer 們,可以將 Server for Hackers 作為入門教材,內容深淺適中,非常好讀。或者也可以直接購買 ebook 丟進 iBook 慢慢看,之前還曾經推出 ebook、video捆綁的特價販售,有興趣的人真的可以考慮付費買來看,絕對不會浪費錢的!

以上就是《Modern PHP》第七章 Provisioning 的導讀,若有任何錯誤或疑問,歡迎提出,謝謝。

轉貼本文時禁止修改,禁止商業使用,並且必須註明來自「艦長,你有事嗎?」原創作者 Cheng Wei Chen,及附上原文連結。

工商服務

更多文章