2 minute read

๐Ÿ›  K3s์—์„œ โ€œToo many open filesโ€ ์˜ค๋ฅ˜ ํ•ด๊ฒฐ๊ธฐ

๐Ÿ“ฆ inotify & ulimit ์„ค์ • ํŠœ๋‹์œผ๋กœ ์›Œํฌํ”Œ๋กœ์šฐ ์ •์ƒํ™”ํ•˜๊ธฐ

์ตœ๊ทผ k3s ํด๋Ÿฌ์Šคํ„ฐ์—์„œ Argo Workflows๋ฅผ ๋Œ๋ฆฌ๋˜ ์ค‘, ์•„๋ž˜์™€ ๊ฐ™์€ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค:

Failed to allocate directory watch: Too many open files

ํ˜น์‹œ ์ด๋Ÿฐ ๋กœ๊ทธ ๋ณด์…จ๋‹ค๋ฉด, ์ €๋ž‘ ๊ฐ™์€ ์ƒํ™ฉ์ผ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์Šต๋‹ˆ๋‹ค.
์ด ์˜ค๋ฅ˜๋Š” ๋Œ€์ฒด๋กœ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ ์ˆ˜๊ฐ€ ๋ถ€์กฑํ•˜๊ฑฐ๋‚˜, ํŒŒ์ผ ๊ฐ์‹œ(inotify) ์ œํ•œ์— ๊ฑธ๋ ธ์„ ๋•Œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.


๐Ÿ” ์™œ ์ด๋Ÿฐ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์„๊นŒ?

๋ฆฌ๋ˆ…์Šค ์‹œ์Šคํ…œ์—๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํŒŒ์ผ์ด๋‚˜ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ๋™์‹œ์— ์—ด๊ฑฐ๋‚˜ ๊ฐ์‹œํ•  ์ˆ˜ ์žˆ๋Š” ํ•œ๋„๊ฐ€ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.
ํŠนํžˆ Python์—์„œ uvicorn --reload๋‚˜ watchfiles ๊ฐ™์€ ๊ฑธ ์“ฐ๊ณ  ์žˆ๋‹ค๋ฉด, ๋””๋ ‰ํ„ฐ๋ฆฌ๋งˆ๋‹ค ๊ฐ์‹œ ์ธ์Šคํ„ด์Šค๊ฐ€ ๋ถ™๊ธฐ ๋•Œ๋ฌธ์— ์ˆ˜์ฒœ ๊ฐœ์˜ ๊ฐ์‹œ ์š”์ฒญ์ด ํ•œ๊บผ๋ฒˆ์— ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.


โœ… ํ•ด๊ฒฐ ๋ฐฉ๋ฒ• Step-by-Step

1๏ธโƒฃ inotify ์ปค๋„ ํŒŒ๋ผ๋ฏธํ„ฐ ์ƒํ–ฅ

๋จผ์ € ์ปค๋„์ด ๊ฐ์‹œํ•  ์ˆ˜ ์žˆ๋Š” ํŒŒ์ผ ๊ฐœ์ˆ˜์™€ ์ธ์Šคํ„ด์Šค ์ˆ˜๋ฅผ ๋Š˜๋ ค์•ผ ํ•ด์š”.

sudo nano /etc/sysctl.d/k3s-inotify.conf

์•„๋ž˜ ๋‚ด์šฉ์„ ๋ถ™์—ฌ๋„ฃ์Šต๋‹ˆ๋‹ค:

fs.inotify.max_user_instances=512
fs.inotify.max_user_watches=524288
fs.inotify.max_queued_events=32768

์„ค์ •์„ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค:

sudo sysctl --system

๐Ÿ“Œ ์ฐธ๊ณ ๋กœ ๊ธฐ๋ณธ๊ฐ’์€ max_user_instances=128, max_user_watches=8192 ์ •๋„๋กœ ๋งค์šฐ ๋‚ฎ์•„์š”. ์œ„ ์ˆ˜์น˜๋Š” ๋„‰๋„‰ํ•˜๊ฒŒ ์žก์€ ๊ฐ’์ž…๋‹ˆ๋‹ค.


2๏ธโƒฃ root ์‚ฌ์šฉ์ž์˜ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ ์ˆ˜ ์ œํ•œ(ulimit) ์ƒํ–ฅ

๋‹ค์Œ์œผ๋กœ root ์‚ฌ์šฉ์ž๊ฐ€ ์—ด ์ˆ˜ ์žˆ๋Š” ํŒŒ์ผ ๊ฐœ์ˆ˜๋„ ๋Š˜๋ ค์•ผ ํ•ด์š”.

sudo nano /etc/security/limits.d/99-root-nofile.conf

๋‹ค์Œ ๋‚ด์šฉ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค:

root soft nofile 65536
root hard nofile 65536

์ด ์„ค์ •์€ root๋กœ ์‹คํ–‰๋˜๋Š” ํ”„๋กœ์„ธ์Šค์—๋งŒ ์ ์šฉ๋ผ์š”.
k3s๋„ root๊ฐ€ ๋„์šฐ๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ๊ธฐ์— ์ ์šฉํ•˜๋Š” ๊ฒŒ ํ•ต์‹ฌ์ด์—์š”!


3๏ธโƒฃ k3s systemd ์„œ๋น„์Šค์— open file ์ œํ•œ ์ถ”๊ฐ€

์ด์ œ systemd์—๊ฒŒ๋„ โ€œ์šฐ๋ฆฌ ๋งŽ์ด ์—ด ์ˆ˜ ์žˆ์–ด์š”โ€๋ผ๊ณ  ์•Œ๋ ค์ค˜์•ผ ํ•ด์š”.

sudo mkdir -p /etc/systemd/system/k3s.service.d
sudo nano /etc/systemd/system/k3s.service.d/override.conf

๋‚ด์šฉ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค:

[Service]
LimitNOFILE=65536

๋ฐ˜์˜์„ ์œ„ํ•ด systemd๋ฅผ ์ƒˆ๋กœ ๊ณ ์ณ์ค˜์š”:

sudo systemctl daemon-reexec
sudo systemctl daemon-reload
sudo systemctl restart k3s

4๏ธโƒฃ containerd๋„ ํŒŒ์ผ ์ˆ˜ ์ œํ•œ ํ’€๊ธฐ

k3s๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ containerd๋ฅผ ์“ฐ๊ธฐ ๋•Œ๋ฌธ์—, ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€์—์„œ๋„ ํŒŒ์ผ์„ ๋งŽ์ด ์—ด ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.

sudo mkdir -p /etc/containerd
sudo containerd config default | sudo tee /etc/containerd/config.toml > /dev/null
sudo nano /etc/containerd/config.toml

๋‹ค์Œ ๋‚ด์šฉ์„ ์ฐพ๊ฑฐ๋‚˜ ์ƒˆ๋กœ ์ถ”๊ฐ€ํ•ด ์ฃผ์„ธ์š”:

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
  runc_default_ulimit = ["nofile=65536:65536"]

๊ทธ ๋‹ค์Œ:

sudo systemctl restart containerd
sudo systemctl restart k3s

5๏ธโƒฃ ํ™•์ธํ•ด๋ณด๊ธฐ

์ปจํ…Œ์ด๋„ˆ ์•ˆ์—์„œ ์ง„์งœ ์ž˜ ์ ์šฉ๋๋Š”์ง€ ํ™•์ธํ•ด๋ณผ๊นŒ์š”?

kubectl exec -it <pod-name> -- sh -c 'ulimit -n'

๐Ÿ‘€ ์ถœ๋ ฅ์ด 65536 ์ด์ƒ์ด๋ฉด ์„ฑ๊ณต์ž…๋‹ˆ๋‹ค!


๐Ÿงน ๋ณด๋„ˆ์Šค: reload ๋ชจ๋“œ ์ œ๊ฑฐ

๋งŒ์•ฝ uvicorn --reload ๊ฐ™์€ ๊ฑธ ์“ฐ๊ณ  ์žˆ๋‹ค๋ฉด, ์ด๊ฑธ ๊ผญ ์ œ๊ฑฐํ•ด ์ฃผ์„ธ์š”.
๊ฐœ๋ฐœ ๋ชจ๋“œ์—์„œ๋Š” ์œ ์šฉํ•˜์ง€๋งŒ, ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—์„œ๋Š” ๋ถˆํ•„์š”ํ•˜๊ฒŒ inotify ๋ฆฌ์†Œ์Šค๋ฅผ ์“ฐ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

# ์ž˜๋ชป๋œ ์˜ˆ โŒ
uvicorn app.main:app --reload

# ์˜ฌ๋ฐ”๋ฅธ ์˜ˆ โœ…
uvicorn app.main:app --host 0.0.0.0 --port 8000

โœ… ๋งˆ๋ฌด๋ฆฌ ์ •๋ฆฌ

ํ•ญ๋ชฉ ์„ค์ •๊ฐ’
fs.inotify.max_user_instances 512 ์ด์ƒ
ulimit -n 65536 ์ด์ƒ
LimitNOFILE (systemd) 65536
runc_default_ulimit (containerd) ["nofile=65536:65536"]

์ด๋ ‡๊ฒŒ ์„ค์ •ํ•˜๊ณ  ๋‚˜๋‹ˆ, ๋” ์ด์ƒ "Too many open files" ์˜ค๋ฅ˜๋ฅผ ๋ชป ๋ด์„œ ๋„ˆ๋ฌด ํ–‰๋ณตํ•ฉ๋‹ˆ๋‹ค ๐Ÿ˜„
๊ฐ™์€ ๋ฌธ์ œ ๊ฒช์œผ์…จ๋‹ค๋ฉด ๊ผญ ๋”ฐ๋ผ ํ•ด๋ณด์„ธ์š”!

ํ•„์š”ํ•˜์‹œ๋ฉด ์ด ์„ค์ •์„ ์ž๋™ํ™”ํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ ๋ฒ„์ „๋„ ๋”ฐ๋กœ ๋งŒ๋“ค์–ด ๋“œ๋ฆด ์ˆ˜ ์žˆ์–ด์š”.
ํ˜น์‹œ ์ด ๋‚ด์šฉ์— ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์€ ๋ถ€๋ถ„ ์žˆ์œผ์‹ ๊ฐ€์š”?

Updated: