docker中使用systemctl命令時報Too many open files錯誤

lhrbest發表於2021-03-03


在docker的容器內使用systemctl啟動服務時,報錯:

[root@lhrorchestrator /]# systemctl start mysql
Error: Too many open files
Authorization not available. Check if polkit service is running or see debug message for more information.

這裡不僅僅是mysql服務,任何服務使用systemctl啟動都會報錯,另外,這裡絕對不是由於系統檔案open-files達到最大數引起的。


查了好幾天的原因,最後使用journalctl -xe命令檢視日誌,突然發現了一個不一樣的錯誤:“inotify_init1() failed: Too many open files”

[root@lhrorchestrator /]# journalctl -xe
Mar 03 12:15:53 lhrorchestrator systemd[1]: inotify_init1() failed: Too many open files
Mar 03 12:15:53 lhrorchestrator systemd[1]: Unit systemd-udevd.service entered failed state.
Mar 03 12:15:53 lhrorchestrator systemd[1]: systemd-udevd.service failed.
Mar 03 12:15:53 lhrorchestrator systemd[1]: systemd-udevd.service has no holdoff time, scheduling restart.
Mar 03 12:15:53 lhrorchestrator systemd[1]: Stopped udev Kernel Device Manager.
-- Subject: Unit systemd-udevd.service has finished shutting down
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
-- 
-- Unit systemd-udevd.service has finished shutting down.
Mar 03 12:15:53 lhrorchestrator systemd[1]: inotify_init1() failed: Too many open files
Mar 03 12:15:53 lhrorchestrator systemd[1]: start request repeated too quickly for systemd-udevd.service
Mar 03 12:15:53 lhrorchestrator systemd[1]: Failed to start udev Kernel Device Manager.
-- Subject: Unit systemd-udevd.service has failed
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
-- 
-- Unit systemd-udevd.service has failed.
-- 
-- The result is failed.
Mar 03 12:15:53 lhrorchestrator systemd[1]: inotify_init1() failed: Too many open files
Mar 03 12:15:53 lhrorchestrator systemd[1]: inotify_init1() failed: Too many open files
Mar 03 12:15:53 lhrorchestrator systemd[1]: Unit systemd-udevd.service entered failed state.
Mar 03 12:15:53 lhrorchestrator systemd[1]: systemd-udevd.service failed.


百度搜尋“inotify_init1() failed: Too many open files”:

notify是linux提供的一種監控機制,可以監控檔案系統的變化。該機制受到2個核心引數的影響:“fs.inotify.max_user_instances”和“fs.inotify.max_user_watches”,其中“fs.inotify.max_user_instances”表示每個使用者最多可以建立的inotify instances數量上限,“fs.inotify.max_user_watches”表示每個使用者同時可以新增的watch數目,當出現too many open files問題而上面三種方法都無法解決時,可以嘗試透過修改這2個核心引數來生效。修改方法是修改"/etc/sysctl.conf"檔案,並執行"sysctl -p"。


所以,解決很簡單:

[root@docker35 ~]# more  /etc/sysctl.conf | grep fs
fs.file-max=9000000
fs.inotify.max_user_instances = 1000000
fs.inotify.max_user_watches = 1000000

執行"sysctl -p"生效即可。


Too many open files的四種解決辦法

一  單個程式開啟檔案控制程式碼數過多

ulimit中的nofile表示單程式可以開啟的最大檔案控制程式碼數,可以透過ulimit -a檢視,子程式預設繼承父程式的限制(注意,是繼承,不是共享,子程式和父程式開啟的檔案控制程式碼數是單獨算的)。

網上還有一種解讀是nofile表示單使用者可以開啟的檔案控制程式碼數,因為他們在limit.conf中看到類似於“openstack soft nofile 65536”,便認為是openstack使用者最多可以開啟的檔案控制程式碼數。該解讀是錯誤的,“openstack soft nofile 65536”表示的含義是當你執行"su - openstack"切換到openstack使用者後,你建立的所有程式最大可以開啟的檔案控制程式碼數是65536。

要檢視一個程式可以開啟的檔案控制程式碼數,可以透過“cat /proc/<pid>/limits”檢視。

要修改ulimit中的nofile,可以透過修改/etc/security/limits.conf檔案,在其中加入類似“openstack soft nofile 65536”的語句來進行修改。修改完成後,可以透過“su - openstack”切換使用者,或者重新登入,來使該配置生效。

要動態修改一個程式的限制,可以使用prlimit命令,具體用法為:“prlimit --pid ${pid} --nofile=102400:102400”。

二 作業系統開啟的檔案控制程式碼數過多

整個作業系統可以開啟的檔案控制程式碼數是有限的,受核心引數“fs.file-max”影響。

可以透過執行“echo 100000000 > /proc/sys/fs/file-max”命令來動態修改該值,也可以透過修改"/etc/sysctl.conf"檔案來永久修改該值。

三 systemd對該程式進行了限制

該場景僅針對被systemd管理的程式(也就是可以透過systemctl來控制的程式)生效,可以透過修改該程式的service檔案(通常在/etc/systemd/system/目錄下),在“[Service]”下面新增“LimitNOFILE=20480000”來實現,修改完成之後需要執行"systemctl daemon-reload"來使該配置生效。

四 inotify達到上限

inotify是linux提供的一種監控機制,可以監控檔案系統的變化。該機制受到2個核心引數的影響:“fs.inotify.max_user_instances”和“fs.inotify.max_user_watches”,其中“fs.inotify.max_user_instances”表示每個使用者最多可以建立的inotify instances數量上限,“fs.inotify.max_user_watches”表示麼個使用者同時可以新增的watch數目,當出現too many open files問題而上面三種方法都無法解決時,可以嘗試透過修改這2個核心引數來生效。修改方法是修改"/etc/sysctl.conf"檔案,並執行"sysctl -p"。


用到的命令:

-- 修改檔案數
ulimit -a
ulimit -u unlimited
ulimit -HSn  1048576
/etc/security/limits.conf
* soft nofile 1048576
* hard nofile 1048576
/etc/pam.d/login
session    required     /lib64/security/pam_limits.so
/etc/sysctl.conf
fs.file-max=9000000
fs.inotify.max_user_instances = 1000000
fs.inotify.max_user_watches = 1000000
sysctl -p
/etc/security/limits.d/20-nproc.conf
* soft nproc unlimited
/usr/lib/systemd/system/polkit.service
LimitNOFILE=1048576
LimitNPROC=1048576
systemctl daemon-reload
--檢視限制
cat /proc/944/limits
ls /proc/944/fd/ | wc -l
lsof | wc -l





About Me

........................................................................................................................

● 本文作者:小麥苗,部分內容整理自網路,若有侵權請聯絡小麥苗刪除

● 本文在個人微 信公眾號( DB寶)上有同步更新

● QQ群號: 230161599 、618766405,微信群私聊

● 個人QQ號(646634621),微 訊號(db_bao),註明新增緣由

● 於 2021年3月完成

● 最新修改時間:2021年3月

● 版權所有,歡迎分享本文,轉載請保留出處

........................................................................................................................

小麥苗的微店

● 小麥苗出版的資料庫類叢書: http://blog.itpub.net/26736162/viewspace-2142121/

小麥苗OCP、OCM、高可用、MySQL、DBA學習班http://blog.itpub.net/26736162/viewspace-2148098/

● 資料庫筆試面試題庫及解答: http://blog.itpub.net/26736162/viewspace-2134706/

........................................................................................................................

請掃描下面的二維碼來關注小麥苗的微 信公眾號( DB寶)及QQ群(230161599、618766405)、新增小麥苗微 信(db_bao), 學習最實用的資料庫技術。

........................................................................................................................

 

 



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26736162/viewspace-2760823/,如需轉載,請註明出處,否則將追究法律責任。

相關文章