์๋ ๋ชจ๋
์ ๋ Linux ์์คํ ๊ด๋ฆฌ์์ด๊ณ 2015๋ ์ ๋ ๋ฆฝ ์ ๋ฌธ ๋น์๋ก ๋ฌ์์์์ ํธ์ฃผ๋ก ์ด์ฃผํ์ง๋ง ์ด ๊ธฐ์ฌ์์๋ ๋ผ์ง์ฉ ํธ๋ํฐ๋ฅผ ์๋ํ๋ ๋ฐฉ๋ฒ์ ๋ํด์๋ ๋ค๋ฃจ์ง ์์ ๊ฒ์ ๋๋ค. ๊ทธ๋ฌํ ๊ธฐ์ฌ๋ ์ด๋ฏธ ์ถฉ๋ถํฉ๋๋ค(๊ทธ๋ผ์๋ ๋ถ๊ตฌํ๊ณ ๊ด์ฌ์ด ์๋ค๋ฉด ์ด๊ฒ์ ๋ํด์๋ ์ธ ๊ฒ์ ๋๋ค). ๋ฐ๋ผ์ ํธ์ฃผ์์ Linux-ops ์์ง๋์ด๋ก ์ผํ๋ฉด์ ๋จ์ผ ์์คํ ๋ชจ๋ํฐ๋ง์์ ๋ง์ด๊ทธ๋ ์ด์ ์ ์์ํ ๋ฐฉ๋ฒ์ ๋ํด ์ด์ผ๊ธฐํ๊ณ ์ถ์ต๋๋ค. ๋ค๋ฅธ ์ฌ๋์๊ฒ. ๊ตฌ์ฒด์ ์ผ๋ก - Nagios => Icinga2.
์ด ๊ธฐ์ฌ๋ ๋ถ๋ถ์ ์ผ๋ก ๊ธฐ์ ์ ์ด๊ณ ๋ถ๋ถ์ ์ผ๋ก ์ฌ๋๋ค๊ณผ์ ์์ฌ์ํต๊ณผ ๋ฌธํ ๋ฐ ์์ ๋ฐฉ์์ ์ฐจ์ด์ ๊ด๋ จ๋ ๋ฌธ์ ์ ๊ดํ ๊ฒ์ ๋๋ค.
๋ถํํ๋ "code" ํ๊ทธ๋ Puppet ๋ฐ yaml ์ฝ๋๋ฅผ ๊ฐ์กฐ ํ์ํ์ง ์์ผ๋ฏ๋ก "plaintext"๋ฅผ ์ฌ์ฉํด์ผ ํ์ต๋๋ค.
21๋ 2016์ XNUMX์ผ ์ค์ ์๋ ์๋ฌด๋ฐ ๋ฌธ์ ์ ์งํ๊ฐ ์์์ต๋๋ค. ๋ ๊ทธ๋ ๋ฏ์ด ๊ทผ๋ฌด์ผ ์ฒซ XNUMX๋ถ ๋์ ์ปคํผ๋ฅผ ๋ง์๋ฉฐ ๋ฑ๋ก๋์ง ์์ ์ต๋ช ์ ์ฌ์ฉ์๊ฐ Habr์ ์ฝ๊ณ ์์๋๋ฐ ์ฐ์ฐํ ๋ฐ๊ฒฌํ์ต๋๋ค. .
์ฐ๋ฆฌ ํ์ฌ๋ Nagios๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ๋ ๋ฒ ์๊ฐํ์ง ์๊ณ Redmine์์ ํฐ์ผ์ ์์ฑํ๊ณ ์ค์ํ๋ค๊ณ ์๊ฐํ์ฌ ์ผ๋ฐ ์ฑํ ๋งํฌ๋ฅผ ๋ณด๋์ต๋๋ค. ์ด ์ด๋์ ํฐ๋ธ๋ ํธ์ฃผ์์๋ ์ฒ๋ฒ ๊ฐ๋ฅํ๋ฏ๋ก ์์ ์์ง๋์ด๋ ์ ๊ฐ ๋ฌธ์ ๋ฅผ ๋ฐ๊ฒฌํ ์ดํ๋ก ์ ์๊ฒ ๋ฌธ์ ๋ฅผ ์ง์ ํ์ต๋๋ค.
Redmine์ ์คํฌ๋ฆฐ์ท
์ฐ๋ฆฌ ๋ถ์์์๋ ๊ทํ์ ์๊ฒฌ์ ํํํ๊ธฐ ์ ์ ์ ํ์ด ๋ถ๋ช ํ๋๋ผ๋ ์ ์ด๋ ํ๋์ ๋์์ ์ ๊ณตํ๋ ๊ฒ์ด ๊ด๋ก์ ๋๋ค. ๊ทธ๋์ ์ ๋ ๋ง์ง๋ง ์ง์ฅ์ธ ๋ฌ์์์์ ํ์ฌ ์ด๋ค ์ข ๋ฅ์ ๋ชจ๋ํฐ๋ง ์์คํ ์ด ๊ด๋ จ๋์ด ์๋์ง ์ธํฐ๋ท ๊ฒ์์ผ๋ก ์์ํ์ต๋๋ค. ๋งค์ฐ ์์์ ์ธ ์์ฒด ์์ฑ ์์คํ ์ด ์์์ง๋ง ๊ทธ๋ผ์๋ ๋ถ๊ตฌํ๊ณ ํ ๋น๋ ๋ชจ๋ ์์ ์ ๊ฝค ์ ์๋ํ๊ณ ์ํํ์ต๋๋ค. Python, St.Petersburg Polytechnic ๋ฐ ์งํ์ฒ ๊ท์น. ์๋, ์งํ์ฒ ์ ์ง์ฆ๋. ์ด๊ฒ์ ๊ฐ์ธ์ ์ธ ์ผ์ด๊ณ (11๋ ๊ฐ์ ์์ ) ๋ณ๋์ ๊ธฐ์ฌ๋ฅผ ์ธ ๊ฐ์น๊ฐ ์์ง๋ง ์ง๊ธ์ ์๋๋๋ค.
ํ์ฌ ์์น์์ ์ธํ๋ผ ๊ตฌ์ฑ์ ๋ณ๊ฒฝํ๋ ๊ท์น์ ๋ํด ์กฐ๊ธ ์ค๋ช ํฉ๋๋ค. ์ฐ๋ฆฌ๋ Puppet, Gitlab ๋ฐ ์ธํ๋ผ๋ฅผ ์ฝ๋ ์์น์ผ๋ก ์ฌ์ฉํฉ๋๋ค.
- ๊ฐ์ ๋จธ์ ์ ํ์ผ์ ์๋์ผ๋ก ๋ณ๊ฒฝํ์ฌ SSH๋ฅผ ํตํด ์๋์ผ๋ก ๋ณ๊ฒฝํ ์ ์์ต๋๋ค. 10๋ ๋์ ์ผํ๋ฉด์ ์ด๋ ๊ฒ ๋ชจ์๋ฅผ ์ฌ๋ฌ ๋ฒ ๋ง์๋๋ฐ, ๋ง์ง๋ง์ด ์ผ์ฃผ์ผ ์ ์ด์๋๋ฐ ๊ทธ๊ฒ ๋ง์ง๋ง์ด ์๋ ๊ฒ ๊ฐ์์. ์, ์ค์ ๋ก ๊ตฌ์ฑ์์ ํ ์ค์ ์์ ํ๊ณ ์๋น์ค๋ฅผ ๋ค์ ์์ํ ๋ค์ ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋์๋์ง ํ์ธํ์ธ์. 10์ด ์ ๋ ์์๋ฉ๋๋ค. Gitlab์์ ์ ๋ธ๋์น๋ฅผ ์์ฑํ๊ณ , ๋ณ๊ฒฝ ์ฌํญ์ ํธ์ํ๊ณ , r5k๊ฐ Puppetmaster์์ ์๋ํ ๋๊น์ง ๊ธฐ๋ค๋ฆฝ๋๋ค. Puppet -environment=mybranch๋ฅผ ์คํํ๊ณ ๋ชจ๋ ๊ฒ์ด ์๋ํ ๋๊น์ง ๋ช ๋ถ ๋ ๊ธฐ๋ค๋ฆฝ๋๋ค(์ต์ XNUMX๋ถ).
- ๋ชจ๋ ๋ณ๊ฒฝ ์ฌํญ์ Gitlab์์ ๋ณํฉ ์์ฒญ์ ์์ฑํ์ฌ ์ด๋ฃจ์ด์ง๋ฉฐ ์ต์ํ ํ ๋ช ์ ํ์์ ์น์ธ์ ๋ฐ์์ผ ํฉ๋๋ค. ํ์ฅ์ด ๊ฒฐ์ ํ ์ฃผ์ ๋ณ๊ฒฝ ์ฌํญ์ XNUMX~XNUMXํ์ ์น์ธ์ด ํ์ํฉ๋๋ค.
- ๋ชจ๋ ๋ณ๊ฒฝ ์ฌํญ์ ์ด๋ค ๋ฐฉ์์ผ๋ก๋ ํ ์คํธ์ ๋๋ค(Puppet ๋งค๋ํ์คํธ, ์คํฌ๋ฆฝํธ ๋ฐ Hiera ๋ฐ์ดํฐ๋ ํ ์คํธ์ด๋ฏ๋ก). ๋ฐ์ด๋๋ฆฌ๋ ๊ถ์ฅ๋์ง ์์ผ๋ฉฐ ์ด๋ฌํ ํ์ผ์ ์น์ธํด์ผ ํ๋ ์ค๋๋ ฅ ์๋ ์ด์ ๊ฐ ์์ด์ผ ํฉ๋๋ค.
๊ทธ๋์ ์ ๊ฐ ๊ณ ๋ คํ ์ต์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- ๋ฌด๋ - ์ธํ๋ผ์ ์๋ฒ๊ฐ 10๊ฐ ์ด์ ์์ผ๋ฉด ๊ด๋ฆฌ๊ฐ ์ง์ฅ์ผ๋ก ๋ณํฉ๋๋ค. . ๋๋ ์ด๊ฒ์ ํ์ธํ๊ณ ์ถ์ ํน๋ณํ ์๊ตฌ๊ฐ ์์๊ธฐ ๋๋ฌธ์ ๊ทธ์ ๋ง์ ๊ทธ๋๋ก ๋ฐ์๋ค์์ต๋๋ค.)
- Zabbix - ๋ฌ์์์ ์์ ๋ ์ค๋ซ๋์ ์ดํด๋ดค์ง๋ง ๋ด ์์ ์๋ ํ์ํ์ง ์์์ต๋๋ค. ์ฌ๊ธฐ์์๋ Puppet์ ๊ตฌ์ฑ ๊ด๋ฆฌ์๋ก ์ฌ์ฉํ๊ณ Gitlab์ ๋ฒ์ ์ ์ด ์์คํ ์ผ๋ก ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ํ๊ธฐํด์ผ ํ์ต๋๋ค. ๋น์ ๋ด๊ฐ ์๋ ํ Zabbix๋ ์ ์ฒด ๊ตฌ์ฑ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅํ๋ฏ๋ก ํ์ฌ ์ํฉ์์ ๊ตฌ์ฑ์ ๊ด๋ฆฌํ๋ ๋ฐฉ๋ฒ๊ณผ ๋ณ๊ฒฝ ์ฌํญ์ ์ถ์ ํ๋ ๋ฐฉ๋ฒ์ด ๋ช ํํ์ง ์์์ต๋๋ค.
- ํ๋ก๋ฉํ ์ฐ์ค๋ ๋ถ์ ๋ถ์๊ธฐ์ ๋ฐ๋ผ ์ต์ข ์ ์ผ๋ก ๋์ฌ ๊ฒ์ด์ง๋ง ๋น์์๋ ๋ง์คํฐํ์ง ๋ชปํ๊ณ ์ค์ ๋ก ์๋ํ๋ ์ํ(๊ฐ๋ ์ฆ๋ช )์ ์์ฐํ ์ ์์๊ธฐ ๋๋ฌธ์ ๊ฑฐ๋ถํ ์๋ฐ์ ์์์ต๋๋ค.
- ์์คํ ์ ์์ ํ ์ฌ์์ ์ด ํ์ํ๊ฑฐ๋ ์ด๊ธฐ ๋จ๊ณ์ ์๊ฑฐ๋ ํฌ๊ธฐ๋์ด ๊ฐ์ ์ด์ ๋ก ๊ฑฐ๋ถ๋ ๋ช ๊ฐ์ง ๋ค๋ฅธ ์ต์ ๋ ์์์ต๋๋ค.
๊ฒฐ๊ตญ ์ ๋ ์ธ ๊ฐ์ง ์ด์ ๋ก Icinga2๋ฅผ ์ ํํ๊ฒ ๋์์ต๋๋ค.
1 - Nrpe(Nagios์์ ๋ช
๋ น ํ์ธ์ ์คํํ๋ ํด๋ผ์ด์ธํธ ์๋น์ค)์์ ํธํ์ฑ. ์ด๋ ๋งค์ฐ ์ค์ํ์ต๋๋ค. ๊ทธ ๋น์์๋ ๋ง์ถค ์์ฑ๋ ์๋น์ค/๊ฒ์ฌ๊ฐ ํฌํจ๋ ๊ฐ์ ๋จธ์ ์ด 135๊ฐ(ํ์ฌ 2019๋
์๋ 165๊ฐ) ์์๊ณ , ์ด๋ฅผ ๋ชจ๋ ๋ค์ ์คํํ๋ ๊ฒ์ ์ ๋ง ๊ณ ํต์ค๋ฌ์ ์ ๊ฒ์ด๊ธฐ ๋๋ฌธ์
๋๋ค.
2 - ๋ชจ๋ ๊ตฌ์ฑ ํ์ผ์ ํ
์คํธ์ด๋ฏ๋ก ์ด ์ฌ์์ ์ฝ๊ฒ ํธ์งํ ์ ์๊ณ ์ถ๊ฐ ๋๋ ์ญ์ ๋ ๋ด์ฉ์ ๋ณผ ์ ์๋ ๊ธฐ๋ฅ์ ๊ฐ์ถ ๋ณํฉ ์์ฒญ์ ์์ฑํ ์ ์์ต๋๋ค.
3์ ์ด์์๊ณ ๋ฐ์ ์ค์ธ ์คํ์์ค ํ๋ก์ ํธ์
๋๋ค. ์ฐ๋ฆฌ๋ OpenSource๋ฅผ ๋งค์ฐ ์ข์ํ๋ฉฐ ๋ฌธ์ ํด๊ฒฐ์ ์ํด Pull Request ๋ฐ Issues๋ฅผ ์์ฑํ์ฌ OpenSource์ ๊ฐ๋ฅํ ๋ชจ๋ ๊ธฐ์ฌ๋ฅผ ํ๊ณ ์์ต๋๋ค.
๊ทธ๋ผ ๊ฐ์, Icinga2.
์ ๊ฐ ๊ฐ์ฅ ๋จผ์ ์ง๋ฉดํด์ผ ํ๋ ๊ฒ์ ๋๋ฃ๋ค์ ๊ด์ฑ์ด์์ต๋๋ค. ๋ชจ๋๊ฐ Nagios/Naggios(๋ฐ์ ๋ฐฉ๋ฒ์ ๋ํด์๋ ํํํ ์ ์์์ง๋ง)์ CheckMK ์ธํฐํ์ด์ค์ ์ต์ํฉ๋๋ค. icinga ์ธํฐํ์ด์ค๋ ์์ ํ ๋ฌ๋ผ ๋ณด์ด์ง๋ง(์ด๊ฒ์ ๋ง์ด๋์ค์์ต๋๋ค) ๋ฌธ์ ๊ทธ๋๋ก ๋ชจ๋ ๋งค๊ฐ๋ณ์์ ๋ํด ํํฐ๋ฅผ ์ฌ์ฉํ์ฌ ํ์ธํด์ผ ํ๋ ๋ด์ฉ์ ์ ์ฐํ๊ฒ ์ฌ์ฉ์ ์ ์ํ ์ ์์ต๋๋ค(์ด๊ฒ์ ์ฅ์ ์ด์์ง๋ง ๋ง์ ๋ ธ๋ ฅ์ ๊ธฐ์ธ์์ต๋๋ค).
ํํฐ
์คํฌ๋กค ๋ง๋ ํฌ๊ธฐ์ ์คํฌ๋กค ํ๋ ํฌ๊ธฐ์ ๋น์จ์ ์ถ์ ํฉ๋๋ค.
๋์งธ, CheckMk๋ฅผ ์ฌ์ฉํ๋ฉด ์ฌ๋ฌ Nagios ํธ์คํธ์ ์์ ํ ์ ์์ง๋ง Icinga ์ธํฐํ์ด์ค์์๋ ์ด ์์ ์ ์ํํ ์ ์๊ธฐ ๋๋ฌธ์ ๋ชจ๋ ์ฌ๋์ด ํ๋์ ๋ชจ๋ํฐ์์ ์ ์ฒด ์ธํ๋ผ๋ฅผ ๋ณด๋ ๋ฐ ์ต์ํฉ๋๋ค(์ค์ ๋ก๋ ๊ฐ๋ฅํ์ง๋ง ์์ธํ ๋ด์ฉ์ ์๋์์ ์ค๋ช ). ๋์์ Thruk๋ผ๊ณ ๋ถ๋ฆฌ๋ ๊ฒ์ด์์ง๋ง ๊ทธ ๋์์ธ์ ๊ทธ๊ฒ์ ์ ์ํ ์ฌ๋(๋ด๊ฐ ์๋)์ ์ ์ธํ๊ณ ํ์ ๋ชจ๋ ์ฌ๋๋ค์ ๊ฐ๊ทธํ๊ฒ ๋ง๋ค์์ต๋๋ค.
Thruk ์ฉ๊ด๋ก ์์ผ๋ก - ํ์ ๋ง์ฅ์ผ์น ๊ฒฐ์ 
๋ฉฐ์น ๊ฐ์ ๋ธ๋ ์ธ์คํ ๋ฐ ๋์ ํ๋ก๋์ ์์ญ์ ํ๋์ ๋ง์คํฐ ํธ์คํธ๊ฐ ์๊ณ ๋ ๊ฐ์ ์ฌ๋ ์ด๋ธ๊ฐ ์๋ ํด๋ฌ์คํฐ ๋ชจ๋ํฐ๋ง ์์ด๋์ด๋ฅผ ์ ์ํ์ต๋๋ค. ํ๋๋ ๊ฐ๋ฐ/ํ ์คํธ์ ์๊ณ ๋ค๋ฅธ ํ๋๋ ๋ค๋ฅธ ๊ณต๊ธ์์ ์์นํ์ฌ ์ฐ๋ฆฌ๋ฅผ ๋ชจ๋ํฐ๋งํฉ๋๋ค. ๊ณ ๊ฐ์ด๋ ์ธ๋ถ ๊ด์ฐฐ์์ ๊ด์ ์์ ์๋น์ค๋ฅผ ์ ๊ณตํฉ๋๋ค. ์ด ๊ตฌ์ฑ์ ์ฌ์ฉํ๋ฉด ํ๋์ ์น ์ธํฐํ์ด์ค์์ ๋ชจ๋ ๋ฌธ์ ๋ฅผ ๋ณผ ์ ์์๊ณ ๊ฝค ์ ์๋ํ์ง๋ง... Puppet์ ๋ฌธ์ ๋ ์ด์ ๋ง์คํฐ ํธ์คํธ๊ฐ ์์คํ ์ ๋ชจ๋ ํธ์คํธ์ ์๋น์ค/๊ฒ์ฌ์ ๋ํด ์์์ผ ํ๊ณ ์์ญ(dev-test, staging-prod, ext) ๊ฐ์ ๋ฐฐํฌํ๋ ค๋ฉด Icinga API๋ฅผ ํตํด ๋ณ๊ฒฝ ์ฌํญ์ ์ ์กํ๋ ๋ฐ ๋ช ์ด๊ฐ ๊ฑธ๋ฆฌ์ง๋ง ๋ชจ๋ ํธ์คํธ์ ๋ํ ๋ชจ๋ ์๋น์ค์ Puppet ๋๋ ํฐ๋ฆฌ๋ฅผ ์ปดํ์ผํ๋ ๋ฐ๋ ๋ช ๋ถ์ด ๊ฑธ๋ฆฝ๋๋ค. ๋ชจ๋ ๊ฒ์ด ์ด๋ป๊ฒ ์๋ํ๊ณ ์ ๊ทธ๋ ๊ฒ ์ค๋ ๊ฑธ๋ฆฌ๋์ง ์ด๋ฏธ ์ฌ๋ฌ ๋ฒ ์ค๋ช ํ์ง๋ง ์ด๊ฒ์ ์ฌ์ ํ โโโโ๋์๊ฒ ๋น๋์ ๋ฐ๊ณ ์์ต๋๋ค.
์ธ ๋ฒ์งธ๋ก, SnowFlakes๊ฐ ๋ง์ด ์์ต๋๋ค. ์ฆ, ํน๋ณํ ๊ฒ์ด ์๊ธฐ ๋๋ฌธ์ ์ผ๋ฐ ์์คํ ์์ ๋์ ๋๋ ๊ฒ๋ค์ด๊ธฐ ๋๋ฌธ์ ์ผ๋ฐ ๊ท์น์ด ์ ์ฉ๋์ง ์์ต๋๋ค. ์ ๋ฉด ๊ณต๊ฒฉ์ผ๋ก ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋์์ต๋๋ค. ๊ฒฝ๋ณด๊ฐ ์ธ๋ ธ์ง๋ง ์ค์ ๋ก๋ ๋ชจ๋ ๊ฒ์ด ์ ์์ด๋ผ๋ฉด ๋ ๊น์ด ํ๊ณ ๋ค์ด ๊ฒฝ๋ณด๊ฐ ์ธ๋ฆฌ๋ฉด ์ ๋์ง๋ง ์ ๊ฒฝ๋ณด๊ฐ ์ธ๋ฆฌ๋์ง ์์๋ด์ผ ํฉ๋๋ค. ๋๋ ๊ทธ ๋ฐ๋์ ๊ฒฝ์ฐ - ์ Nagios๋ ๋นํฉํ์ง๋ง Icinga๋ ๋นํฉํ์ง ์์ต๋๊น?
๋ท์งธ, Nagios๋ ๋๋ณด๋ค ๋จผ์ ์ฌ๊ธฐ์ XNUMX๋ ๋์ ์ผํ๊ณ ์ฒ์์๋ ๋ด๊ฐ ์๋ก ๋์ ํ ํ์คํฐ ์์คํ ๋ณด๋ค ๊ทธ์ ๋ํ ์ ๋ขฐ๊ฐ ๋ ์ปธ์ต๋๋ค. ๊ทธ๋์ Icinga๊ฐ ํจ๋์ ์ผ์ผํฌ ๋๋ง๋ค Nagios๊ฐ ๊ฐ์ ๋ฌธ์ ์ ๋ํด ํฅ๋ถํ ๋๊น์ง ์๋ฌด๋ ์๋ฌด๊ฒ๋ ํ์ง ์์์ต๋๋ค. ๊ทธ๋ฌ๋ Icinga๊ฐ Nagios ์ด์ ์ ์ค์ ๊ฒฝ๋ณด๋ฅผ ์์ฑํ ๊ฒฝ์ฐ๋ ๋งค์ฐ ๋๋ฌผ์๊ณ ์ ๋ ์ด๊ฒ์ด ์ฌ๊ฐํ ๋ฌธ์ ๋ผ๊ณ ์๊ฐํฉ๋๋ค. ์ด์ ๋ํด์๋ "๊ฒฐ๋ก " ์น์ ์์ ์ค๋ช ํ๊ฒ ์ต๋๋ค.
๊ทธ ๊ฒฐ๊ณผ ์์ด์ ์ด 5๊ฐ์ ์ด์ ์ง์ฐ๋์์ต๋๋ค(28๋ 2018์ 3์ผ ์์ , ์ค์ ๋ก๋ 2018๋ XNUMX์ XNUMX์ผ). ์ฃผ๋ก "ํจ๋ฆฌํฐ ๊ฒ์ฌ"๋ก ์ธํด Nagios์ ์๋ฌด๋ ๋ชจ๋ฅด๋ ์๋น์ค๊ฐ ์ฌ๋ฌ ๊ฐ ์์ ๋ ๋ฐ์ํ๋ ์ฐ๋ ๊ธฐ์ ๋๋ค. ์ง๋ ๋ช ๋ ๊ฐ ์๋ฌด๊ฒ๋ ๋ค์ด๋ณธ ์ ์ด ์๋๋ฐ ์ง๊ธ ๋น์ฅ์ ๊ทธ ๋๋ค์ด ์๋ฌด ์ด์ ์์ด ์น๋ช ํ๋ฅผ ์คฌ๊ณ ๋ ์ ๊ทธ ๋๋ค์ด ๋ด ํจ๋์ ์๋์ง ์ค๋ช ํด์ผ ํ๊ณ Icinga์ ์ถ๊ฐํด์ผ ํ์ฃ . ์๋ฃ"(Nagios์ ๋ชจ๋ ์๋น์ค/์ํ๋ Icinga์ ์๋น์ค/์ํ์ ํด๋นํฉ๋๋ค)
๊ตฌํ:
์ฒซ ๋ฒ์งธ๋ Puppet Style๊ณผ ๊ฐ์ ์ฝ๋ ๋ ๋ฐ์ดํฐ ์ ์์
๋๋ค. ๋ชจ๋ ๋ฐ์ดํฐ, ์ ๋์ ์ผ๋ก ๋ชจ๋ ๊ฒ์ด Hiera์ ์์ด์ผ ํ๋ฉฐ ๊ทธ ์ธ์๋ ์๋ฌด๊ฒ๋ ์์ด์ผ ํฉ๋๋ค. ๋ชจ๋ ์ฝ๋๋ .pp ํ์ผ์ ์์ต๋๋ค. ๋ณ์, ์ถ์ํ, ํจ์ - ๋ชจ๋ ๊ฒ์ด pp์ ๋ค์ด๊ฐ๋๋ค.
๊ฒฐ๊ณผ์ ์ผ๋ก SSL ์ธ์ฆ์์ ์ฑ๋ฅ๊ณผ ์ ํจ์ฑ์ ๋ชจ๋ํฐ๋งํด์ผ ํ๋ ๊ฐ์ ๋จธ์ (์์ฑ ๋น์ 165๊ฐ)๊ณผ ์น ์ ํ๋ฆฌ์ผ์ด์
68๊ฐ๊ฐ ์๊ฒผ์ต๋๋ค. ๊ทธ๋ฌ๋ ๊ณผ๊ฑฐ์ ์น์ง๋ก ์ธํด ์ ํ๋ฆฌ์ผ์ด์
๋ชจ๋ํฐ๋ง์ ์ํ ์ ๋ณด๋ ๋ณ๋์ gitlab ์ ์ฅ์์์ ๊ฐ์ ธ์ค๊ณ ๋ฐ์ดํฐ ํ์์ Puppet 3 ์ดํ๋ก ๋ณ๊ฒฝ๋์ง ์์์ผ๋ฏ๋ก ๊ตฌ์ฑ์ด ๋์ฑ ๋ณต์กํด์ก์ต๋๋ค.
์ ํ๋ฆฌ์ผ์ด์ ์ฉ ์ธํ ์ฝ๋, ๋์ ๋ณดํธํ์ธ์
define profiles::services::monitoring::docker_apps(
Hash $app_list,
Hash $apps_accessible_from,
Hash $apps_access_list,
Hash $webhost_defaults,
Hash $webcheck_defaults,
Hash $service_overrides,
Hash $targets,
Hash $app_checks,
)
{
#### APPS ####
$zone = $name
$app_list.each | String $app_name, Hash $app_data |
{
$notify_group = { 'notify_group' => ($webcheck_defaults[$zone]['notify_group'] + pick($app_data['notify_group'], {} )) } # adds notifications for default group (systems) + any group defined in int/pm_docker_apps.eyaml
$data = merge($webhost_defaults, $apps_accessible_from, $app_data)
$site_domain = $app_data['site_domain']
$regexp = pick($app_data['check_regex'], 'html') # Pick a regex to check
$check_url = $app_data['check_url'] ? {
undef => { 'http_uri' => '/' },
default => { 'http_uri' => $app_data['check_url'] }
}
$check_regex = $regexp ?{
'absent' => {},
default => {'http_expect_body_regex' => $regexp}
}
$site_domain.each | String $vhost, Hash $vdata | { # Split an app by domains if there are two or more
$vhost_name = {'http_vhost' => $vhost}
$vars = $data['vars'] + $vhost_name + $check_regex + $check_url
$web_ipaddress = is_array($vdata['web_ipaddress']) ? { # Make IP-address an array if it's not, because askizzy has 2 ips and it's an array
true => $vdata['web_ipaddress'],
false => [$vdata['web_ipaddress']],
}
$access_from_zones = [$zone] + $apps_access_list[$data['accessible_from']] # Merge default zone (where the app is defined) and extra zones if they exist
$web_ipaddress.each | String $ip_address | { # For each IP (if we have multiple)
$suffix = length($web_ipaddress) ? { # If we have more than one - add IP as a suffix to this hostname to avoid duplicating resources
1 => '',
default => "_${ip_address}"
}
$octets = split($ip_address, '.')
$ip_tag = "${octets[2]}.${octets[3]}" # Using last octet only causes a collision between nginx-vip 203.15.70.94 and ext. ip 49.255.194.94
$access_from_zones.each | $zone_prefix |{
$zone_target = $targets[$zone_prefix]
$nginx_vip_name = "${zone_prefix}_nginx-vip-${ip_tag}" # If it's a host for ext - prefix becomes 'ext_' (ext_nginx-vip...)
$nginx_host_vip = {
$nginx_vip_name => {
ensure => present,
target => $zone_target,
address => $ip_address,
check_command => 'hostalive',
groups => ['nginx_vip',],
}
}
$ssl_vars = $app_checks['ssl']
$regex_vars = $app_checks['http'] + $vars + $webcheck_defaults[$zone] + $notify_group
if !defined( Profiles::Services::Monitoring::Host[$nginx_vip_name] ) {
ensure_resources('profiles::services::monitoring::host', $nginx_host_vip)
}
if !defined( Icinga2::Object::Service["${nginx_vip_name}_ssl"] ) {
icinga2::object::service {"${nginx_vip_name}_ssl":
ensure => $data['ensure'],
assign => ["host.name == $nginx_vip_name",],
groups => ['webchecks',],
check_command => 'ssl',
check_interval => $service_overrides['ssl']['check_interval'],
target => $targets['services'],
apply => true,
vars => $ssl_vars
}
}
if $regexp != 'absent'{
if !defined(Icinga2::Object::Service["${vhost}${$suffix} regex"]){
icinga2::object::service {"${vhost}${$suffix} regex":
ensure => $data['ensure'],
assign => ["match(*_nginx-vip-${ip_tag}, host.name)",],
groups => ['webchecks',],
check_command => 'http',
check_interval => $service_overrides['regex']['check_interval'],
target => $targets['services'],
enable_flapping => true,
apply => true,
vars => $regex_vars
}
}
}
}
}
}
}
}ํธ์คํธ์ ์๋น์ค์ ๊ตฌ์ฑ ์ฝ๋๋ ํํธ์์ด ๋ณด์ ๋๋ค.
๋ชจ๋ํฐ๋ง/config.pp
class profiles::services::monitoring::config(
Array $default_config,
Array $hostgroups,
Hash $hosts = {},
Hash $host_defaults,
Hash $services,
Hash $service_defaults,
Hash $service_overrides,
Hash $webcheck_defaults,
Hash $servicegroups,
String $servicegroup_target,
Hash $user_defaults,
Hash $users,
Hash $oncall,
Hash $usergroup_defaults,
Hash $usergroups,
Hash $notifications,
Hash $notification_defaults,
Hash $notification_commands,
Hash $timeperiods,
Hash $webhost_defaults,
Hash $apps_access_list,
Hash $check_commands,
Hash $hosts_api = {},
Hash $targets = {},
Hash $host_api_defaults = {},
)
{
# Profiles::Services::Monitoring::Hostgroup <<| |>> # will be enabled when we move to icinga completely
#### APPS ####
case $location {
'int', 'ext': {
$apps_by_zone = {}
}
'pm': {
$int_apps = hiera('int_docker_apps')
$int_app_defaults = hiera('int_docker_app_common')
$st_apps = hiera('staging_docker_apps')
$srs_apps = hiera('pm_docker_apps_srs')
$pm_apps = hiera('pm_docker_apps') + $st_apps + $srs_apps
$pm_app_defaults = hiera('pm_docker_app_common')
$apps_by_zone = {
'int' => $int_apps,
'pm' => $pm_apps,
}
$app_access_by_zone = {
'int' => {'accessible_from' => $int_app_defaults['accessible_from']},
'pm' => {'accessible_from' => $pm_app_defaults['accessible_from']},
}
}
default: {
fail('Please ensure the node has $location fact set (int, pm, ext)')
}
}
file { '/etc/icinga2/conf.d/':
ensure => directory,
recurse => true,
purge => true,
owner => 'icinga',
group => 'icinga',
mode => '0750',
notify => Service['icinga2'],
}
$default_config.each | String $file_name |{
file {"/etc/icinga2/conf.d/${file_name}":
ensure => present,
source => "puppet:///modules/profiles/services/monitoring/default_config/${file_name}",
owner => 'icinga',
group => 'icinga',
mode => '0640',
}
}
$app_checks = {
'ssl' => $services['webchecks']['checks']['ssl']['vars'],
'http' => $services['webchecks']['checks']['http_regexp']['vars']
}
$apps_by_zone.each | String $zone, Hash $app_list | {
profiles::services::monitoring::docker_apps{$zone:
app_list => $app_list,
apps_accessible_from => $app_access_by_zone[$zone],
apps_access_list => $apps_access_list,
webhost_defaults => $webhost_defaults,
webcheck_defaults => $webcheck_defaults,
service_overrides => $service_overrides,
targets => $targets,
app_checks => $app_checks,
}
}
#### HOSTS ####
# Profiles::Services::Monitoring::Host <<| |>> # This is for spaceship invasion when it's ready.
$hosts_has_large_disks = query_nodes('mountpoints.*.size_bytes >= 1099511627776')
$hosts.each | String $hostgroup, Hash $list_of_hosts_with_settings | { # Splitting site lists by hostgroups - docker_host/gluster_host/etc
$list_of_hosts_in_group = $list_of_hosts_with_settings['hosts']
$hostgroup_settings = $list_of_hosts_with_settings['settings']
$merged_hostgroup_settings = deep_merge($host_defaults, $list_of_hosts_with_settings['settings'])
$list_of_hosts_in_group.each | String $host_name, Hash $host_settings |{ # Splitting grouplists by hosts
# Is this host in the array $hosts_has_large_disks ? If so set host.vars.has_large_disks
if ( $hosts_has_large_disks.reduce(false) | $found, $value| { ( $value =~ "^${host_name}" ) or $found } ) {
$vars_has_large_disks = { 'has_large_disks' => true }
} else {
$vars_has_large_disks = {}
}
$host_data = deep_merge($merged_hostgroup_settings, $host_settings)
$hostgroup_settings_vars = pick($hostgroup_settings['vars'], {})
$host_settings_vars = pick($host_settings['vars'], {})
$host_notify_group = delete_undef_values($host_defaults['vars']['notify_group'] + $hostgroup_settings_vars['notify_group'] + $host_settings_vars['notify_group'])
$host_data_vars = delete_undef_values(deep_merge($host_data['vars'] , {'notify_group' => $host_notify_group}, $vars_has_large_disks)) # Merging vars separately
$hostgroups = delete_undef_values([$hostgroup] + $host_data['groups'])
profiles::services::monitoring::host{$host_name:
ensure => $host_data['ensure'],
display_name => $host_data['display_name'],
address => $host_data['address'],
groups => $hostgroups,
target => $host_data['target'],
check_command => $host_data['check_command'],
check_interval => $host_data['check_interval'],
max_check_attempts => $host_data['max_check_attempts'],
vars => $host_data_vars,
template => $host_data['template'],
}
}
}
if !empty($hosts_api){ # All hosts managed by API
$hosts_api.each | String $zone, Hash $hosts_api_zone | { # Split api hosts by zones
$hosts_api_zone.each | String $hostgroup, Hash $list_of_hosts_with_settings | { # Splitting site lists by hostgroups - docker_host/gluster_host/etc
$list_of_hosts_in_group = $list_of_hosts_with_settings['hosts']
$hostgroup_settings = $list_of_hosts_with_settings['settings']
$merged_hostgroup_settings = deep_merge($host_api_defaults, $list_of_hosts_with_settings['settings'])
$list_of_hosts_in_group.each | String $host_name, Hash $host_settings |{ # Splitting grouplists by hosts
# Is this host in the array $hosts_has_large_disks ? If so set host.vars.has_large_disks
if ( $hosts_has_large_disks.reduce(false) | $found, $value| { ( $value =~ "^${host_name}" ) or $found } ) {
$vars_has_large_disks = { 'has_large_disks' => true }
} else {
$vars_has_large_disks = {}
}
$host_data = deep_merge($merged_hostgroup_settings, $host_settings)
$hostgroup_settings_vars = pick($hostgroup_settings['vars'], {})
$host_settings_vars = pick($host_settings['vars'], {})
$host_api_notify_group = delete_undef_values($host_defaults['vars']['notify_group'] + $hostgroup_settings_vars['notify_group'] + $host_settings_vars['notify_group'])
$host_data_vars = delete_undef_values(deep_merge($host_data['vars'] , {'notify_group' => $host_api_notify_group}, $vars_has_large_disks))
$hostgroups = delete_undef_values([$hostgroup] + $host_data['groups'])
if defined(Profiles::Services::Monitoring::Host[$host_name]){
$hostname = "${host_name}_from_${zone}"
}
else
{
$hostname = $host_name
}
profiles::services::monitoring::host{$hostname:
ensure => $host_data['ensure'],
display_name => $host_data['display_name'],
address => $host_data['address'],
groups => $hostgroups,
target => "${host_data['target_base']}/${zone}/hosts.conf",
check_command => $host_data['check_command'],
check_interval => $host_data['check_interval'],
max_check_attempts => $host_data['max_check_attempts'],
vars => $host_data_vars,
template => $host_data['template'],
}
}
}
}
}
#### END OF HOSTS ####
#### SERVICES ####
$services.each | String $service_group, Hash $s_list |{ # Service_group and list of services in that group
$service_list = $s_list['checks'] # List of actual checks, separately from SG settings
$service_list.each | String $service_name, Hash $data |{
$merged_defaults = merge($service_defaults, $s_list['settings']) # global service defaults + service group defaults
$merged_data = merge($merged_defaults, $data)
$settings_vars = pick($s_list['settings']['vars'], {})
$this_service_vars = pick($data['vars'], {})
$all_service_vars = delete_undef_values($service_defaults['vars'] + $settings_vars + $this_service_vars)
# If we override default check_timeout, but not nrpe_timeout, make nrpe_timeout the same as check_timeout
if ( $merged_data['check_timeout'] and ! $this_service_vars['nrpe_timeout'] ) {
# NB: Icinga will convert 1m to 60 automatically!
$nrpe = { 'nrpe_timeout' => $merged_data['check_timeout'] }
} else {
$nrpe = {}
}
# By default we use nrpe and all commands are run via nrpe. So vars.nrpe_command = $service_name is a default value
# If it's server-side Icinga command - we don't need 'nrpe_command'
# but there is no harm to have that var and the code is shorter
if $merged_data['check_command'] == 'nrpe'{
$check_command = $merged_data['vars']['nrpe_command'] ? {
undef => { 'nrpe_command' => $service_name },
default => { 'nrpe_command' => $merged_data['vars']['nrpe_command'] }
}
}else{
$check_command = {}
}
# Assembling $vars from Global Default service settings, servicegroup settings, this particular check settings and let's not forget nrpe settings.
if $all_service_vars['graphite_template'] {
$graphite_template = {'check_command' => $all_service_vars['graphite_template']}
}else{
$graphite_template = {'check_command' => $service_name}
}
$service_notify = [] + pick($settings_vars['notify_group'], []) + pick($this_service_vars['notify_group'], []) # pick is required everywhere, otherwise becomes "The value '' cannot be converted to Numeric"
$service_notify_group = $service_notify ? {
[] => $service_defaults['vars']['notify_group'],
default => $service_notify
} # Assing default group (systems) if no other groups are defined
$vars = $all_service_vars + $nrpe + $check_command + $graphite_template + {'notify_group' => $service_notify_group}
# This needs to be merged separately, because merging it as part of MERGED_DATA overwrites arrays instead of merging them, so we lose some "assign" and "ignore" values
$assign = delete_undef_values($service_defaults['assign'] + $s_list['settings']['assign'] + $data['assign'])
$ignore = delete_undef_values($service_defaults['ignore'] + $s_list['settings']['ignore'] + $data['ignore'])
icinga2::object::service {$service_name:
ensure => $merged_data['ensure'],
apply => $merged_data['apply'],
enable_flapping => $merged_data['enable_flapping'],
assign => $assign,
ignore => $ignore,
groups => [$service_group],
check_command => $merged_data['check_command'],
check_interval => $merged_data['check_interval'],
check_timeout => $merged_data['check_timeout'],
check_period => $merged_data['check_period'],
display_name => $merged_data['display_name'],
event_command => $merged_data['event_command'],
retry_interval => $merged_data['retry_interval'],
max_check_attempts => $merged_data['max_check_attempts'],
target => $merged_data['target'],
vars => $vars,
template => $merged_data['template'],
}
}
}
#### END OF SERVICES ####
#### OTHER BORING STUFF ####
$servicegroups.each | $servicegroup, $description |{
icinga2::object::servicegroup{ $servicegroup:
target => $servicegroup_target,
display_name => $description
}
}
$hostgroups.each| String $hostgroup |{
profiles::services::monitoring::hostgroup { $hostgroup:}
}
$notifications.each | String $name, Hash $settings |{
$assign = pick($notification_defaults['assign'], []) + $settings['assign']
$ignore = pick($notification_defaults['ignore'], []) + $settings['ignore']
$merged_settings = $settings + $notification_defaults
icinga2::object::notification{$name:
target => $merged_settings['target'],
apply => $merged_settings['apply'],
apply_target => $merged_settings['apply_target'],
command => $merged_settings['command'],
interval => $merged_settings['interval'],
states => $merged_settings['states'],
types => $merged_settings['types'],
assign => delete_undef_values($assign),
ignore => delete_undef_values($ignore),
user_groups => $merged_settings['user_groups'],
period => $merged_settings['period'],
vars => $merged_settings['vars'],
}
}
# Merging notification settings for users with other settings
$users_oncall = deep_merge($users, $oncall)
# Magic. Do not touch.
create_resources('icinga2::object::user', $users_oncall, $user_defaults)
create_resources('icinga2::object::usergroup', $usergroups, $usergroup_defaults)
create_resources('icinga2::object::timeperiod',$timeperiods)
create_resources('icinga2::object::checkcommand', $check_commands)
create_resources('icinga2::object::notificationcommand', $notification_commands)
profiles::services::sudoers { 'icinga_runs_ping_l2':
ensure => present,
sudoersd_template => 'profiles/os/redhat/centos7/sudoers/icinga.erb',
}
}๋๋ ์์ง๋ ์ด ๊ตญ์๋ฅผ ์ฐ๊ตฌํ๊ณ ์ต์ ์ ๋คํด ๊ฐ์ ํ๊ณ ์์ต๋๋ค. ๊ทธ๋ฌ๋ Hiera์์ ๊ฐ๋จํ๊ณ ์ดํดํ๊ธฐ ์ฌ์ด ๊ตฌ๋ฌธ์ ์ฌ์ฉํ ์ ์๊ฒ ํด์ฃผ๋ ๊ฒ์ ๋ฐ๋ก ์ด ์ฝ๋์์ต๋๋ค.
๋ฐ์ดํฐ
profiles::services::monitoring::config::services:
perf_checks:
settings:
check_interval: '2m'
assign:
- 'host.vars.type == linux'
checks:
procs: {}
load: {}
memory: {}
disk:
check_interval: '5m'
vars:
notification_period: '24x7'
disk_iops:
vars:
notifications:
- 'silent'
cpu:
vars:
notifications:
- 'silent'
dns_fqdn:
check_interval: '15m'
ignore:
- 'xenserver in host.groups'
vars:
notifications:
- 'silent'
iftraffic_nrpe:
vars:
notifications:
- 'silent'
logging:
settings:
assign:
- 'logserver in host.groups'
checks:
rsyslog: {}
nginx_limit_req_other: {}
nginx_limit_req_s2s: {}
nginx_limit_req_s2x: {}
nginx_limit_req_srs: {}
logstash: {}
logstash_api:
vars:
notifications:
- 'silent'๋ชจ๋ ๊ฒ์ฌ๋ ๊ทธ๋ฃน์ผ๋ก ๋๋์ด์ง๋ฉฐ, ๊ฐ ๊ทธ๋ฃน์๋ ๊ฒ์ฌ๋ฅผ ์คํํ ์์น์ ๋น๋, ๋ณด๋ผ ์๋ฆผ ๋ฐ ๋์๊ณผ ๊ฐ์ ๊ธฐ๋ณธ ์ค์ ์ด ์์ต๋๋ค.
๊ฐ ๊ฒ์ฌ์์ ๋ชจ๋ ์ต์ ์ ๋ฌด์ํ ์ ์์ผ๋ฉฐ ์ด ๋ชจ๋ ๊ฒ์ด ๊ถ๊ทน์ ์ผ๋ก ๋ชจ๋ ๊ฒ์ฌ ์ ์ฒด์ ๊ธฐ๋ณธ ์ค์ ์ ์ถ๊ฐ๋ฉ๋๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ์ด๋ฌํ ๋ง๋ ์๋๋ ๋ด์ฉ์ด config.pp์ ์์ฑ๋์์ต๋๋ค. ๋ชจ๋ ๊ธฐ๋ณธ ์ค์ ์ ๊ทธ๋ฃน ์ค์ ๊ณผ ๋ณํฉํ ๋ค์ ๊ฐ ๊ฐ๋ณ ๊ฒ์ฌ์ ๋ณํฉํฉ๋๋ค.
๋ ๋ค๋ฅธ ๋งค์ฐ ์ค์ํ ๋ณ๊ฒฝ ์ฌํญ์ ์ค์ ์์ ๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์๋ ๊ธฐ๋ฅ์ด์์ต๋๋ค(์: http_regex๋ฅผ ํ์ธํ๊ธฐ ์ํด ํฌํธ, ์ฃผ์ ๋ฐ URL์ ๋ฐ๊พธ๋ ๊ธฐ๋ฅ).
http_regexp:
assign:
- 'host.vars.http_regex'
- 'static_sites in host.groups'
check_command: 'http'
check_interval: '1m'
retry_interval: '20s'
max_check_attempts: 6
http_port: '{{ if(host.vars.http_port) { return host.vars.http_port } else { return 443 } }}'
vars:
notification_period: 'host.vars.notification_period'
http_vhost: '{{ if(host.vars.http_vhost) { return host.vars.http_vhost } else { return host.name } }}'
http_ssl: '{{ if(host.vars.http_ssl) { return false } else { return true } }}'
http_expect_body_regex: 'host.vars.http_regex'
http_uri: '{{ if(host.vars.http_uri) { return host.vars.http_uri } else { return "/" } }}'
http_onredirect: 'follow'
http_warn_time: 8
http_critical_time: 15
http_timeout: 30
http_sni: true์ด๋ ํธ์คํธ ์ ์์ ๋ณ์๊ฐ ์๋ ๊ฒฝ์ฐ๋ฅผ ์๋ฏธํฉ๋๋ค. http_port โ ์ฌ์ฉํ์ง ์์ผ๋ฉด 443์
๋๋ค. ์๋ฅผ ๋ค์ด jabber ์น ์ธํฐํ์ด์ค๋ 9090์์ ์ ์ง๋๊ณ Unifi๋ 7443์์ ์ ์ง๋ฉ๋๋ค.
http_vํธ์คํธ DNS๋ฅผ ๋ฌด์ํ๊ณ ์ด ์ฃผ์๋ฅผ ์ฌ์ฉํ๋ค๋ ์๋ฏธ์
๋๋ค.
ํธ์คํธ์ URI๊ฐ ์ง์ ๋์ด ์์ผ๋ฉด ์ด๋ฅผ ๋ฐ๋ฅด๊ณ , ๊ทธ๋ ์ง ์์ผ๋ฉด "/"๋ฅผ ์ฌ์ฉํฉ๋๋ค.
http_ssl์ ๋ํ ์ฌ๋ฏธ์๋ ์ด์ผ๊ธฐ๊ฐ ๋์์ต๋๋ค. ์ด ๊ฐ์ผ์ ์์ฒญ ์ ์ฐ๊ฒฐ์ ๋๋ ๊ฒ์ ์ํ์ง ์์์ต๋๋ค. ๋๋ ํธ์คํธ ์ ์์ ๋ณ์๊ฐ ๋ค์๊ณผ ๊ฐ๋ค๋ ์ฌ์ค์ ๊นจ๋ซ๊ธฐ ์ ๊น์ง ์ค๋ซ๋์ ์ด ์ค์ ๋ํด ํผ๋์ค๋ฌ์ํ์ต๋๋ค.
http_ssl: falseํํ์ผ๋ก ๋์ฒด
if(host.vars.http_ssl) { return false } else { return true }ะบะฐะบ ๊ทธ๋ฆ๋ ๊ทธ๋ฆฌ๊ณ ๊ฒฐ๊ตญ ๊ทธ๊ฒ์ ๋ฐํ์ก์ต๋๋ค
if(false) { return false } else { return true }์ฆ, SSL ๊ฒ์ฌ๋ ํญ์ ํ์ฑํ๋์ด ์์ต๋๋ค. ๊ตฌ๋ฌธ์ ๋ฐ๊ฟ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์ต๋๋ค.
http_ssl: no์กฐ์ฌ ๊ฒฐ๊ณผ:
์ฅ์ :
- ์ด์ ์ฐ๋ฆฌ๋ ์ง๋ 7~8๊ฐ์ ๋์ ์ ์งํ๋ ๋ ๊ฐ์ ๋ชจ๋ํฐ๋ง ์์คํ ์ด๋ ๊ตฌ์์ด๊ณ ์ทจ์ฝํ ๋ชจ๋ํฐ๋ง ์์คํ ์ด ์๋ ํ๋์ ๋ชจ๋ํฐ๋ง ์์คํ ์ ๋ณด์ ํ๊ฒ ๋์์ต๋๋ค.
- ํธ์คํธ/์๋น์ค(๊ฒ์ฌ) ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ ์ด์ (์ ์๊ฐ์๋) ํจ์ฌ ๋ ์ฝ๊ธฐ ์ฝ๊ณ ์ดํดํ๊ธฐ ์ฝ์ต๋๋ค. ๋ค๋ฅธ ์ฌ๋๋ค์๊ฒ๋ ์ด๊ฒ์ด ๊ทธ๋ค์ง ๋ช ํํ์ง ์์ ๊ฒ์ผ๋ก ํ๋ช ๋์์ผ๋ฏ๋ก ๋ชจ๋ ์๋ ๋ฐฉ์๊ณผ ํธ์ง ์์น๋ฅผ ์ค๋ช ํ๊ธฐ ์ํด ๋ก์ปฌ ์ํค์ ๋ ํ์ด์ง๋ฅผ ๊ฒ์ํด์ผ ํ์ต๋๋ค.
- ๋ณ์์ ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ๊ฒ์ฌ๋ฅผ ์ ์ฐํ๊ฒ ๊ตฌ์ฑํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด http_regexp๋ฅผ ํ์ธํ๊ธฐ ์ํด ์ํ๋ ํจํด, ๋ฐํ ์ฝ๋, URL ๋ฐ ํฌํธ๋ฅผ ํธ์คํธ ์ค์ ์์ ์ค์ ํ ์ ์์ต๋๋ค.
- ์ฌ๋ฌ ๋์๋ณด๋๊ฐ โโ์์ผ๋ฉฐ ๊ฐ ๋์๋ณด๋์ ๋ํด ํ์๋๋ ์๋ ๋ชฉ๋ก์ ์ ์ํ๊ณ Puppet ๋ฐ ๋ณํฉ ์์ฒญ์ ํตํด ์ด ๋ชจ๋ ๊ฒ์ ๊ด๋ฆฌํ ์ ์์ต๋๋ค.
๋จ์ :
- ํ ๊ตฌ์ฑ์์ ๊ด์ฑ - Nagios๋ ์ผํ๊ณ ๋ ์ผํ๊ณ ์ผํ์ต๋๋ค. ์ด Isinga๋ ๋์์์ด ๋ฒ๊ทธ๊ฐ ๋ง๊ณ ๋๋ฆฝ๋๋ค. ์ฌ๊ธฐ์ ์ญ์ฌ๋ฅผ ์ด๋ป๊ฒ ๋ณผ ์ ์๋์? ์ ์ ์ฅ โโ์ ๋ฐ์ดํธ๊ฐ ์๋๋ค์... (์ค์ ๋ฌธ์ ๋ ์๋ ๋ด์ญ์ด ์๋์ผ๋ก ์ ๋ฐ์ดํธ๋์ง ์๊ณ F5๋ก๋ง ์ ๋ฐ์ดํธ๋๋ค๋ ์ ์ ๋๋ค)
- ์์คํ
์ ๊ด์ฑ - ์น ์ธํฐํ์ด์ค์์ "์
๋ฐ์ดํธ"(์ง๊ธ ํ์ธ)๋ฅผ ํด๋ฆญํ๋ฉด ์คํ ๊ฒฐ๊ณผ๋ ํ์ฑ์ ๋ ์จ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋ฉฐ, ํนํ ์คํํ๋ ๋ฐ ์์ญ ์ด๊ฐ ํ์ํ ๋ณต์กํ ์๋น์ค์ ๊ฒฝ์ฐ ๋์ฑ ๊ทธ๋ ์ต๋๋ค. ๊ทธ๋ฌํ ๊ฒฐ๊ณผ๋ ์ ์์
๋๋ค.

- ์ผ๋ฐ์ ์ผ๋ก ๋ ์์คํ ์ ๋๋ํ ์ด์ํ 5๊ฐ์ ๊ฐ์ ํต๊ณ์ ๋ฐ๋ฅด๋ฉด Nagios๋ ํญ์ Icinga๋ณด๋ค ๋ ๋น ๋ฅด๊ฒ ์์ ํ์ผ๋ฉฐ ์ด๋ก ์ธํด ์ ๋ง ์ง์ฆ์ด ๋ฌ์ต๋๋ค. ๋ด๊ฐ ๋ณด๊ธฐ์ ํ์ด๋จธ์ ๋ญ๊ฐ ๋ฌธ์ ๊ฐ ์๋ ๊ฒ ๊ฐ์๋ฐ ํ์ธ์ 30๋ถ๋ง๋ค ์ด๋ฃจ์ด์ง๋๋ฐ ์ค์ ๋ก๋ XNUMX์ XNUMX๋ถ๋ง๋ค ๊ทธ๋ฐ ์ผ์ด ์ผ์ด๋ฉ๋๋ค.
- ์ธ์ ๋ ์ง ์๋น์ค๋ฅผ ๋ค์ ์์ํ๋ฉด(systemctl restart icinga2) ํด๋น ์์ ์ ์งํ ์ค์ด๋ ๋ชจ๋ ๊ฒ์ฌ์์ ์ฌ๊ฐํ ๊ฒฝ๋ณด๊ฐ ์์ฑ๋ฉ๋๋ค. ํ๋ฉด์์๋, ๋ฐ์์๋ ๋ชจ๋ ๊ฒ์ด ๋จ์ด์ง ๊ฒ์ฒ๋ผ ๋ณด์ด์ง๋ง().
๊ทธ๋ฌ๋ ์ ๋ฐ์ ์ผ๋ก ์๋ํฉ๋๋ค.
์ถ์ฒ : habr.com

