現象
在K8S中部署MySQL進行測試,發現連接數上不去,卡在1000內。查看MySQL日志,報錯信息為
Can't create thread to handle new connection(errno= 11)
排查過程
根據報錯信息可以初步判斷是pod的線程數被限制了,按照這個信息,進入pod里面查看ulimit信息,發現相關配置項都設置的比較大,可以排除是ulimit設置錯誤導致的。
之后根據K8S和線程作為關鍵字在網上檢索,可以發現kubelet中有個配置是控制每個pod的進程數,具體的可以看kubeletConfiguration中的podPidsLimit配置和kubelet的pod-max-pids參數。但是發現環境中的這個值取的是-1,即每個pod的進程數限制等于主機的最大進程數。
考慮到K8S中實際是由CRI去創建容器的,有沒有可能是CRI里面限制了pod的進程數量?這里的CRI選的是CRI-O,于是查看對應的配置文件(/etc/crio/crio.conf),發現有個類似podPidsLimit的配置
# Maximum number of processes allowed in a container.
pids_limit = 1024
到這里基本可以確定就是這個配置導致的,之后修改這個配置并再次測試也確認了就是這個配置導致的。之后在Github上也找到了類似的問題。
解決方法
解決的方法有兩個:
1. 修改crio配置,重啟相關服務
2. 升級crio到v1.24.0以上的版本
總結
如果在K8S中的應用遇到無法創建新線程的錯誤,都可以按照上述方法,檢查和修改kubelet以及CRI的配置來排查。