歡迎光臨
每天分享高質量文章

記一次詭異的故障排查經歷

來自:運維咖啡吧(微信號:SRE724),作者:37丫37

每一次故障排查都是一筆財富,各種狗血經過不表,解決問題之後的那種滿足是不可替代的。

背景

發佈系統架構圖簡化如下:

發佈架構圖

管理員通過Jenkins呼叫“發佈程式(代號varian,以下簡稱varian)”,發佈程式會進行一系列的初始化操作,完成後生成Docker鏡像上傳到Docker倉庫,容器集群更新鏡像,用戶通過負載均衡訪問我們的容器集群。

老的varian採用shell+python開發,配合Jenkins(jdk1.7)進行發佈,因內部專案較多,寫了很多兼容腳本,代碼比較亂。我們計劃對varian進行重構,完全採用python開發,各個功能模塊化,不同型別的專案用樂高的思想拼裝模塊部署發佈,降低耦合。並將jenkins升級到最新版本,jdk同樣升級到1.8。新的varian已經開發完成,現在開始部署測試了,故事就由此開始。

為了降低對現有專案的影響決定重新部署一套新的環境,完全測試通過後將老環境廢棄,直接啟用新環境,新環境信息如下:

  • 系統:Debian8

  • 語言:Python3.4

  • JDK1.8 + Jenkins2.134

故障處理過程

解決nginx訪問403的問題

通過Jenkins呼叫varian正常部署了一個靜態專案(純html,css,js等靜態資源),通過負載均衡訪問容器集群(參考上邊架構圖),發現頁面樣式無法加載,瀏覽器按F12調出控制台發現個CSS檔案傳回403狀態

chrome F12除錯

web服務用的nginx,腦海裡迅速過了一遍什麼情況下nginx會傳回403


  • nginx配置了白名單,client端訪問的IP不在白名單內

allow 192.168.0.152;
deny all;
  • 訪問的路徑是個目錄,而nginx配置了禁止列目錄

#nginx中這個配置預設就是off,改成on當訪問的路徑是目錄時,可以列出目錄中的內容
autoindex           off;
  • 訪問的路徑是個檔案,但nginx服務配置的用戶和用戶組對檔案沒有讀取權限

#nginx中這個配置指定nginx服務的用戶和用戶組                                                                                                                  
user  www-data www-data;                                              
  • 目錄索引index配置錯誤,例如你的目錄下只有index.html,你卻配置了index.shmtl或index.php等等

index index.shtml index.php;

常見的有以上問題會導致nginx傳回403,迅速排查了一下,發現就是權限的問題導致的,nginx配置的用戶和用戶組為www-data,而css檔案的屬主屬組都是root,且其他用戶沒有任何權限

# cat /etc/nginx/nginx.conf                                                                                                                     
user  www-data www-data;

# ls -lh csl.css                                                                                                                                
-rw-r----- 1 root root 7.9K Jul 24 12:34 csl.css

這裡再詳細講解下linux下的檔案權限,以上邊的csl.css檔案為例:

-rw-r----- 1 root root 7.9K Jul 24 12:34 csl.css

以空格分割

  • 第一段-rw-r-----10個字符定義了檔案的權限

    • 第一個字符,這裡為`-`代表這是一個檔案,還會看到像`d`代表目錄、`l`代表連接

    • 剩下九個字符,每三個一組,第2-4個字符代表屬主權限,第5-7個字符代表屬組權限,第8-10個字符代表其他用戶的權限

    • 其中每一組三個字符分別為r、w、x,用數字表示r=4、w=2、x=1,分別代表讀、寫、執行權限,如果這個字符有值表明有這個權限,例如上邊css檔案的權限就為屬主有rw讀寫權限,屬組只有r權限,其他用戶沒有權限

  • 第二段為一個數字,表示檔案的連接數

  • 第三段root表示用戶的屬主為root

  • 第四段root表示用戶的屬組也為root

  • 第五段則表示檔案大小

  • 後邊三段為修改時間

  • 最後一段為檔案名


好了,接著上邊的故障說,已經找到了是因為檔案權限的問題導致的403,那麼修改了檔案的權限為644(其他用戶有讀取權限),再次訪問順利傳回正常狀態了。問題就這麼結束了嗎?當然不能,仔細想想為啥其他的檔案權限都ok,就這個檔案權限不對?接著找原因

tomcat8 UMASK

經過反覆測試,發現我直接在linux下通過控制台執行python腳本的方式發佈部署最終檔案權限正常,但是同樣的腳本經過Jenkins執行後權限就不對了。

控制台執行跟Jenkins執行有什麼區別?賬號不一樣啊,遂把jenkins專案、tomcat檔案都改成屬主屬組都為root重新執行,發現還是一樣的結果。

再想想還有哪裡不對,這個css檔案是程式生成的,生成的檔案權限不對,umask!這個詞突然蹦出來,對,應該就是umask,他控制了生成新檔案的權限。


簡單介紹下什麼是umask:
umask值用來設置用戶在創建檔案時的預設權限,跟設置檔案權限命令chmod是相對的,總共四位,不過我們通常只用後三位,同樣對應屬主屬組以及其他用戶的權限,例如你的賬號umask值為0022(可直接通過umask命令查看),此時你創建的檔案權限預設為644(檔案初始的最高權限為666,umask設置為022,那麼最終的權限為:6-0,6-2,6-2=644。當然有人說檔案的權限最高是777,是的沒錯,但我們說的是預設權限,預設權限是由umask決定的,umask設置為000時檔案的權限就是666,檔案夾權限777),此時創建的目錄權限為755(目錄的最高權限為777,umask設置為022,那麼最終的權限為7-0,7-2,7-2=755)


查了root用戶的umask、jenkins用戶的umask,都為0022,沒問題呀,並且登錄這兩個賬號創建了新檔案權限也都正常,就剩下一種情況了Jenkins!

Jenkins沒有地方可以給配置UMASK,Jenkins跑在tomcat容器里,老版本的varian也有相似的處理邏輯一直沒問題,本次升級了tomcat8,難道tomcat8更新了UMASK?半信半疑的看了下,果然!tomcat8的umask預設改成了0027,麻溜的改成了0022,問題順利解決

# vi tomcat/bin/catalina.sh 
if [ -z "$UMASK" ]; then
    UMASK="0027"
fi

終於破案了,還真相於世人!


●編號211,輸入編號直達本文

●輸入m獲取文章目錄

推薦↓↓↓

 

Linux學習

更多推薦18個技術類微信公眾號

涵蓋:程式人生、演算法與資料結構、黑客技術與網絡安全、大資料技術、前端開發、Java、Python、Web開發、安卓開發、iOS開發、C/C++、.NET、Linux、資料庫、運維等。

赞(0)

分享創造快樂