Back to blog

Kubernetes์—์„œ CloudNativePG๋กœ PostgreSQL ํด๋Ÿฌ์Šคํ„ฐ ๊ตฌ์ถ• ๋ฐ ๊ด€๋ฆฌํ•˜๊ธฐ

August 10, 2026

EDB ํŒ€
2024๋…„ 10์›” 14์ผ

Kubernetes์—์„œ CloudNativePG๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ด€๋ฆฌ ๊ฐ„์†Œํ™”ํ•˜๊ธฐ

์˜ค๋Š˜๋‚  Kubernetes๋Š” ๋งˆ์ดํฌ๋กœ์„œ๋น„์Šค๋กœ ๊ตฌ์„ฑ๋œ ๋ณต์žกํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์Šคํƒ๋ถ€ํ„ฐ ์ตœ์‹  โ€œ์„œ๋ฒ„๋ฆฌ์Šคโ€ API๊นŒ์ง€ ์™„์ „ํžˆ ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜๋œ ์—์ฝ”์‹œ์Šคํ…œ์„ ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ๋Š” ๋ฒ”์šฉ ํ”Œ๋žซํผ์ž…๋‹ˆ๋‹ค. Postgres ์—ญ์‹œ ์ด๋Ÿฌํ•œ ํ™˜๊ฒฝ์—์„œ ์ง€์†์ ์œผ๋กœ ์ง„ํ™”ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ, Postgres DBA์—๊ฒŒ๋„ Kubernetes์™€ ํด๋ผ์šฐ๋“œ ๋„ค์ดํ‹ฐ๋ธŒ ๊ธฐ์ˆ ์— ๋Œ€ํ•œ ์ดํ•ด๊ฐ€ ์ ์  ์ค‘์š”ํ•ด์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด Kubernetes ํ™˜๊ฒฝ์—์„œ Postgres๋ฅผ ์‹ค์ œ๋กœ ์–ด๋–ป๊ฒŒ ์„ค์น˜ํ•˜๊ณ  ์šด์˜ํ•  ์ˆ˜ ์žˆ์„๊นŒ์š”? ์ด ๊ธ€์—์„œ๋Š” CloudNativePG๋ฅผ ์ด์šฉํ•ด Kubernetes์— PostgreSQL ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ๊ตฌ์ถ•ํ•˜๊ณ , ์Šคํ† ๋ฆฌ์ง€ ๊ตฌ์„ฑ๋ถ€ํ„ฐ ํด๋Ÿฌ์Šคํ„ฐ ๋ฐฐํฌ, ์„œ๋น„์Šค ์—ฐ๊ฒฐ ๋ฐ ์™ธ๋ถ€ ์•ก์„ธ์Šค๊นŒ์ง€ ์„ค์ •ํ•˜๋Š” ๊ณผ์ •์„ ๋‹จ๊ณ„๋ณ„๋กœ ์‚ดํŽด๋ด…๋‹ˆ๋‹ค.


CloudNativePG๋ž€?

Kubernetes์—์„œ Postgres๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ํ™œ์šฉํ•˜๋ ค๋ฉด ๊ด€๋ จ๋œ ๋ชจ๋“  ๋ฆฌ์†Œ์Šค, ์žฅ์•  ์กฐ์น˜, ์—ฐ๊ฒฐ ํ’€, ๋น„๋ฐ€ ๊ด€๋ฆฌ ๋“ฑ ๋‹ค์–‘ํ•œ ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋Š” ์šด์˜์ž๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. Postgres ์—…๊ณ„์˜ ์ฃผ์š” ์—…์ฒด๋“ค์€ ๊ฐ๊ธฐ ๋‹ค๋ฅธ ๊ฐ•์ ์„ ๊ฐ€์ง„ ์šด์˜์ž๋ฅผ ์ œ๊ณตํ•˜๋ฉฐ, EDB๋„ ์˜ˆ์™ธ๋Š” ์•„๋‹™๋‹ˆ๋‹ค. EDB์˜ CloudNativePG๋Š” ํ˜„์žฌ ์œ ์ผํ•œ โ€œ๋„ค์ดํ‹ฐ๋ธŒโ€ Kubernetes ์šด์˜์ž๋กœ, Go ์–ธ์–ด๋กœ ์ž‘์„ฑ๋˜์—ˆ์œผ๋ฉฐ ์—ฌ๋Ÿฌ ๋„ค์ดํ‹ฐ๋ธŒ Kubernetes ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ”ผ์–ด ์„œ๋น„์Šค๋กœ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ด ๊ฐ€์žฅ ํฐ ๊ฐ•์ ์ž…๋‹ˆ๋‹ค.

EDB๋Š” 2022๋…„ 4์›” 22์ผ CloudNativePG๋ฅผ ๊ณต์‹ ๋ฐœํ‘œํ–ˆ์ง€๋งŒ, ๊ทธ ์ด์ „๋ถ€ํ„ฐ 1๋…„ ์ด์ƒ ๊ฐœ๋ฐœ ์ž‘์—…์ด ์ง„ํ–‰๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ 1.0 ๋ฒ„์ „์€ 2021๋…„ 2์›” 4์ผ์— ์ถœ์‹œ๋˜์—ˆ์œผ๋ฉฐ, ์ด๋Š” ํ˜„์žฌ์˜ ์ œํ’ˆ ์ด์ „ ๋‹จ๊ณ„์˜€๋˜ ํ”„๋กœํ† ํƒ€์ž…์ด๋‚˜ ๊ธฐํƒ€ ๋…์ ์ ์ธ ๋‚ด๋ถ€ ์ œํ’ˆ์€ ํฌํ•จํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‚ฌ์‹ค, 2020๋…„ ์ดˆ์—๋Š” ์ด๋ฏธ BDR ์šด์˜์ž๋ฅผ ์„ ๋ณด์ธ ๋ฐ” ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ€๋ธŒ๋ฆฌ์—˜ ๋ฐ”๋ฅดํ†จ๋ฆฌ๋‹ˆ๋Š” ์ด๋Ÿฌํ•œ ๊ธด ์—ฌ์ •์„ ์ž์‹ ์˜ ๋ธ”๋กœ๊ทธ์—์„œ ์ƒ์„ธํžˆ ์„ค๋ช…ํ–ˆ๋Š”๋ฐ, ๊ทธ ๊ณผ์ •์€ ์ •๋ง ๋‹ค์‚ฌ๋‹ค๋‚œํ–ˆ๋˜ ๋ช‡ ๋…„์˜ ๊ธฐ๋ก์ด๋ผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ์ •๋„์˜ ๊ฐœ๋ฐœ ์—ญ์‚ฌ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋ฉด ์‚ฌ์šฉํ•˜๊ธฐ๋„ ๊ฝค ์‰ฌ์šธ ๊ฒƒ ๊ฐ™์ง€ ์•Š๋‚˜์š”? ํ•œ๋ฒˆ ์‚ดํŽด๋ด…์‹œ๋‹ค.


Kubernetes ํ™˜๊ฒฝ ์ค€๋น„ํ•˜๊ธฐ

๋ฌด์–ธ๊ฐ€๋ฅผ ๋ฐฐ์šฐ๋Š” ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์€ ์ง์ ‘ ์‚ฌ์šฉํ•ด ๋ณด๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. Kubernetes์˜ ๋†’์€ ์ธ๊ธฐ ๋•๋ถ„์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋‹ค์–‘ํ•œ ์œ ์‚ฌ ๋„๊ตฌ๋“ค์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์€ Docker ์ปจํ…Œ์ด๋„ˆ์—์„œ ์ „์ฒด Kubernetes ์ธ์Šคํ„ด์Šค๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” kind๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋‹ค์Œ์œผ๋กœ๋Š” ๋น„์Šทํ•œ ๋ฐฉ์‹์ด์ง€๋งŒ ๊ฐ€์ƒ ๋จธ์‹  ๊ธฐ๋ฐ˜ ํ™˜๊ฒฝ์„ ์„ ํ˜ธํ•˜๋Š” minikube๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ, โ€œ์ง„์งœโ€ Kubernetes(k8s)์˜ ๊ฒฝ๋Ÿ‰ํ™”๋œ ๋ฒ„์ „์ธ K3s๋„ ์„ ํƒ์ง€ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. K3s๋Š” Kubernetes์™€ ๊ฑฐ์˜ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•˜์ง€๋งŒ, ๋” ๊ฐ„์†Œํ™”๋œ ์„ค์ •์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์ˆœ์ˆ˜ํ•˜๊ฒŒ ์‹คํ—˜ ๋ชฉ์ ์œผ๋กœ๋Š” ์œ„์˜ ๋„๊ตฌ๋“ค ์ค‘ ์–ด๋А ๊ฒƒ์„ ์‚ฌ์šฉํ•ด๋„ ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ๋” ๋„์ „์ ์ด๊ณ  ์‹ค์ œ์ ์ธ ๊ฒฝํ—˜์„ ์›ํ•˜๋Š” ๋ถ„๋“ค์—๊ฒŒ๋Š” K3s๊ฐ€ ์™„์ „ํžˆ ์ž‘๋™ํ•˜๋Š” ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์†์‰ฝ๊ฒŒ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์–ด ๋ณด๋‹ค โ€œํ˜„์‹ค์ ์ธโ€ Kubernetes ํ™˜๊ฒฝ์„ ์ฒดํ—˜ํ•  ์ˆ˜ ์žˆ๋Š” ์ข‹์€ ์„ ํƒ์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ์ด๋Ÿฌํ•œ ๊ฒฝํ—˜์€ ๋ฌด์—‡์„ ํฌํ•จํ• ๊นŒ์š”?

๋ณต์žกํ•ด ๋ณด์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ณต์žกํ•˜๊ฒŒ ๋А๊ปด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” ์ปจํŠธ๋กค ํ”Œ๋ ˆ์ธ๊ณผ ์›Œ์ปค ๋…ธ๋“œ, ์ด ๋‘ ๊ฐ€์ง€๋งŒ ์‹ ๊ฒฝ ์“ฐ๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ปจํŠธ๋กค ํ”Œ๋ ˆ์ธ์€ ์ผ๋ฐ˜์ ์œผ๋กœ 3~5๊ฐœ์˜ ๋…ธ๋“œ๋กœ ๊ตฌ์„ฑ๋˜๋ฉฐ, ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ชจ๋“  ์›Œ์ปค ๋…ธ๋“œ์— ์ˆ˜ํ–‰ํ•  ์ž‘์—…, ์„œ๋น„์Šค ๋ฐฐํฌ ์œ„์น˜, ์ฟผ๋Ÿผ ์œ ์ง€ ๋ฐฉ๋ฒ• ๋“ฑ์„ ์ง€์‹œํ•ฉ๋‹ˆ๋‹ค. ์ปจํŠธ๋กค ํ”Œ๋ ˆ์ธ์„ ์žƒ๋Š”๋‹ค๋Š” ๊ฒƒ์€ ์ „์ฒด ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์žƒ๋Š”๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•˜๋ฏ€๋กœ, ์ด ์‹œ์Šคํ…œ์„ ์•ˆ์ •์ ์œผ๋กœ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ด ๋งค์šฐ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ์›Œ์ปค ๋…ธ๋“œ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์‹ค์ œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜, ์ปดํ“จํŒ…, ์Šคํ† ๋ฆฌ์ง€ ๋“ฑ์˜ ํ˜ธ์ŠคํŒ…๊ณผ ๊ด€๋ จ๋œ ๋‹ค๋ฅธ ๋ชจ๋“  ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

์ด ์ค‘ ํ•˜๋‚˜๋ฅผ ์„ค์ •ํ•˜๊ณ  ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์ด ๊ธ€์˜ ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚˜์ง€๋งŒ, ๋ธ”๋กœ๊ทธ, ํŠœํ† ๋ฆฌ์–ผ, ๋„๊ตฌ, YouTube ๋™์˜์ƒ ๋“ฑ ์ฐธ๊ณ  ์ž๋ฃŒ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. Ansible์— ์ต์ˆ™ํ•œ ์‚ฌ์šฉ์ž๋ผ๋ฉด ํ‘œ์ค€ํ™”๋œ ๋ฐฉ์‹์œผ๋กœ ๋ชจ๋“  ๊ฒƒ์„ ๋ฐ˜๋ณต ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ๋Š” ํ›Œ๋ฅญํ•œ ๋„๊ตฌ์ธ Kubespray๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•„์ˆ˜์ ์ธ ๋„๊ตฌ๋กœ๋Š” Kubernetes ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ๋ช…๋ น์ค„ ์œ ํ‹ธ๋ฆฌํ‹ฐ์ธ kubectl์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ, ๋งŽ์€ ๊ด€๋ฆฌ์ž๋“ค์ด Kubernetes์˜ ํŒจํ‚ค์ง€ ๊ด€๋ฆฌ ๋„๊ตฌ๋กœ Helm์„ ์‚ฌ์šฉํ•˜๋ฉฐ, ์ด๋Š” ๋งค์šฐ ํŽธ๋ฆฌํ•˜๊ฒŒ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด์ œ ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์„ค์ •ํ•˜๊ณ  ์‹คํ–‰ํ–ˆ๋‹ค๋ฉด, ๋‹ค์Œ ๋‹จ๊ณ„๋Š” ๋ฌด์—‡์ผ๊นŒ์š”?


CloudNativePG ์„ค์น˜์™€ YAML ๊ตฌ์„ฑ

YAML์€ Kubernetes์˜ ํ‘œ์ค€ ์–ธ์–ด์ด๊ธฐ ๋•Œ๋ฌธ์— ์ต์ˆ™ํ•ด์ง€๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ธ€์„ ์ž‘์„ฑํ•˜๋Š” ์‹œ์ ์—์„œ CloudNativePG์˜ ์ตœ์‹  ๋ฒ„์ „์€ 1.22์ž…๋‹ˆ๋‹ค. ์„ค์น˜ ์ง€์นจ์€ ํ•ด๋‹น ๋ฒ„์ „๊ณผ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์œผ๋ฉฐ, ์„ค๋ช…์„œ์—์„œ ์‰ฝ๊ฒŒ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ทธ ์ง€์นจ์€ ์‹ ๋ขฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. CloudNativePG๋ฅผ ์„ค์น˜ํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ๊ฒƒ์€ ๋‹จ ํ•œ ์ค„์˜ ๋ช…๋ น์–ด๋ฟ์ž…๋‹ˆ๋‹ค.

์šด์˜์ž๋ฅผ ์„ค์น˜ํ•˜๊ณ  ํ™•์ธํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:

$> kubectl apply -f https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-1.22/releases/cnpg-1.22.1.yaml

$> kubectl get deployment -n cnpg-system

NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
cnpg-controller-manager   1/1     1            1           26h

๋ฏฟ๊ธฐ ์–ด๋ ต๊ฒ ์ง€๋งŒ, ์ด ์‹œ์ ์—์„œ ์šฐ๋ฆฌ๊ฐ€ ํ•ด์•ผ ํ•  ์ผ์€ ๋ฐฐํฌํ•  ํด๋Ÿฌ์Šคํ„ฐ์— ๋Œ€ํ•œ ๊ตฌ์„ฑ์„ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ๋ฟ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ๋ณต์žกํ•œ ์ž‘์—…์ฒ˜๋Ÿผ ๋“ค๋ฆด ์ˆ˜ ์žˆ์ง€๋งŒ, ๋ฌธ์„œ๊ฐ€ ํฐ ๋„์›€์„ ์ค„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ฌธ์„œ์—๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋‹ค์–‘ํ•œ ๋งค๊ฐœ๋ณ€์ˆ˜์™€ ๊ตฌ์„ฑ ์š”์†Œ, ๊ทธ๋ฆฌ๊ณ  ์–ด๋–ค ์˜ต์…˜์„ ์„ ํƒํ•  ์ˆ˜ ์žˆ๋Š”์ง€์— ๋Œ€ํ•œ ๊ธฐ๋Šฅ ์˜ˆ์ œ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

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

์ด๋ฅผ ๊ฐ„๋‹จํžˆ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์€, ํŠน์ • ์˜ต์…˜๋งŒ ๋ณ€๊ฒฝ๋œ ๋‘ ๋ฒˆ์งธ ์Šคํ† ๋ฆฌ์ง€ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ์ƒˆ๋กœ์šด ์Šคํ† ๋ฆฌ์ง€ ํด๋ž˜์Šค ์ •์˜๋ฅผ ์ž‘์„ฑํ•œ ํ›„, kubectl apply -f ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•ด ์ ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

apiVersion: v1
kind: ConfigMap
metadata:
  name: longhorn-storageclass-1r
  namespace: longhorn-system
  labels:
    app.kubernetes.io/name: longhorn
    app.kubernetes.io/instance: longhorn
    app.kubernetes.io/version: v1.5.3
data:
  storageclass.yaml: |
    kind: StorageClass
    apiVersion: storage.k8s.io/v1
    metadata:
      name: longhorn-1r
      annotations:
        storageclass.kubernetes.io/is-default-class: "true"
    provisioner: driver.longhorn.io
    allowVolumeExpansion: true
    reclaimPolicy: "Delete"
    volumeBindingMode: Immediate
    parameters:
      numberOfReplicas: "1"
      staleReplicaTimeout: "30"
      fromBackup: ""
      fsType: "ext4"
      dataLocality: "disabled"

ํ‘œ์ค€ Longhorn ์Šคํ† ๋ฆฌ์ง€ ํด๋ž˜์Šค ์ •์˜๋ฅผ ๊ฐ€์ ธ์™€ ์ƒˆ ํ•ญ๋ชฉ์œผ๋กœ ์ƒ์„ฑ๋˜๋„๋ก ์ด๋ฆ„์„ ๋ณ€๊ฒฝํ•œ ๋’ค, ๋ณต์ œ๋ณธ ์ˆ˜๋ฅผ 1๋กœ ์ค„์˜€์Šต๋‹ˆ๋‹ค. ์ฆ‰, ๋ฐ์ดํ„ฐ์˜ ๋ณต์‚ฌ๋ณธ์ด ๋‹จ ํ•˜๋‚˜๋งŒ ์กด์žฌํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ฐ Postgres ๋ณต์ œ๋ณธ์€ ์ž์ฒด ๋ฐ์ดํ„ฐ ํด๋”์˜ ์ „์ฒด ๋ณต์‚ฌ๋ณธ์„ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ์ด ์ ‘๊ทผ ๋ฐฉ์‹์€ ๋ฌธ์ œ ์—†์œผ๋ฉฐ ์˜คํžˆ๋ ค Postgres์— ์ž˜ ๋งž๋Š” ์„ค์ •์ž…๋‹ˆ๋‹ค. ๋ณต์ œ๋ณธ ์ˆ˜๋ฅผ ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•ด ์ด๋ฆ„์— โ€œ1rโ€์„ ์ถ”๊ฐ€ํ–ˆ๋Š”๋ฐ, ๋‚˜๋ฆ„๋Œ€๋กœ ์ฐฝ์˜์ ์ธ ๋ฐฉ์‹์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


Kubernetes์— PostgreSQL ํด๋Ÿฌ์Šคํ„ฐ ๋ฐฐํฌํ•˜๊ธฐ

์ด์ œ Kubernetes ํ™˜๊ฒฝ์— Postgres ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•  ์ฐจ๋ก€์ž…๋‹ˆ๋‹ค. ์ ์ ˆํ•œ ๊ท ํ˜•์„ ๊ฐ–์ถ˜ ์ •์˜๋ฅผ ๋งˆ๋ จํ–ˆ์œผ๋‹ˆ, ์ด๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ์—ฌ๋Ÿฌ ์„น์…˜์„ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

๋จผ์ € ์„œ๋ฌธ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค:

apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
  name: test-cnpg-cluster
  namespace: cloudnative-pg

์ด ํด๋Ÿฌ์Šคํ„ฐ์˜ ์ด๋ฆ„์€ โ€œtest-cnpg-clusterโ€๋กœ ์ง€์ •ํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ CloudNativePG๋Š” ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ โ€œdefaultโ€ ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ๋ฐฐํฌํ•˜์ง€๋งŒ, ์šฐ๋ฆฌ๋Š” ์ข‹์€ Kubernetes ์‚ฌ์šฉ์ž๊ฐ€ ๋˜๊ธฐ ์œ„ํ•ด ๋ณ„๋„์˜ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ๋กœ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ดํ›„์˜ ๋ชจ๋“  ๋‚ด์šฉ์€ ์‹ค์ œ ํด๋Ÿฌ์Šคํ„ฐ ์ •์˜์— ๋Œ€ํ•œ ์„ธ๋ถ€ ์‚ฌํ•ญ์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

spec:
  instances: 3

  bootstrap:
    initdb:
      database: bones
      owner: bones

ํด๋Ÿฌ์Šคํ„ฐ ์ •์˜์˜ ๋ชจ๋“  ๊ตฌ์„ฑ ์š”์†Œ๋Š” ํŒŒ์ผ์˜ โ€œspecโ€ ์„น์…˜์— ๋ฐฐ์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฒˆ์—๋Š” ์„ธ ๊ฐœ์˜ ๋ฉค๋ฒ„๋กœ ๊ตฌ์„ฑ๋œ ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ƒ์„ฑ๋˜๋Š” โ€œappโ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ๋กœ ํ•˜๊ณ , ๋Œ€์‹  ์›ํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์„ ํƒํ•œ ๋’ค ๊ธฐ๋ณธ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์†Œ์œ ์ž๋ฅผ ๋ณ€๊ฒฝํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋‹ค์Œ์œผ๋กœ๋Š” ๋ช‡ ๊ฐ€์ง€ Postgres ๊ตฌ์„ฑ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์•ฝ๊ฐ„ ์กฐ์ •ํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค:

postgresql:
  parameters:
    random_page_cost: "1.1"
    log_statement: "ddl"
    log_checkpoints: "on"

์šฐ๋ฆฌ Kubernetes ํด๋Ÿฌ์Šคํ„ฐ๋Š” ๋น ๋ฅด๊ณ  ์„ฑ๋Šฅ ์ข‹์€ SSD ์Šคํ† ๋ฆฌ์ง€์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ์ž„์˜ ํŽ˜์ด์ง€๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋Š” ๋ฐ ๋“œ๋Š” ๋น„์šฉ์„ ์ค„์ด๋Š” ๊ฒƒ์ด ํ•ฉ๋ฆฌ์ ์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๋ชจ๋“  ํŠธ๋žœ์žญ์…˜๊ณผ ํฌ๋ Œ์‹ ๋ชฉ์ ์œผ๋กœ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ฒดํฌํฌ์ธํŠธ๋ฅผ ๋กœ๊น…ํ•˜๋Š” ๊ฒƒ๋„ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ด ์„น์…˜์—๋Š” ๊ฑฐ์˜ ๋ชจ๋“  ์œ ํšจํ•œ Postgres ๊ตฌ์„ฑ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋Ÿฌํ•œ ์„ค์ •์€ ํด๋Ÿฌ์Šคํ„ฐ์— ์ •ํ™•ํ•˜๊ฒŒ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. ํ–ฅํ›„ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ๋ณ€๊ฒฝํ•  ๊ฒฝ์šฐ, ์šด์˜์ž๋Š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ๋”ฐ๋ผ ๊ฐ ๋…ธ๋“œ์— ๋‹ค์‹œ ๋กœ๋“œํ•˜๊ฑฐ๋‚˜ ํ•„์š”ํ•˜๋ฉด ์žฌ์‹œ์ž‘์„ ์ˆ˜ํ–‰ํ•ด ๋ณ€๊ฒฝ์„ ๋ฐ˜์˜ํ•ฉ๋‹ˆ๋‹ค.

affinity:
  nodeSelector:
    longhorn: "true"

๋…ธ๋“œ ์„ ํ˜ธ๋„๋ฅผ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ์Šคํ† ๋ฆฌ์ง€๊ฐ€ ์œ„์น˜ํ•ด์•ผ ํ•  ๋…ธ๋“œ๋ฅผ ์ง€์ •ํ•˜๋Š” Kubernetes์˜ ๋‹ค์†Œ ๋ณต์žกํ•œ ๊ธฐ์ˆ  ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. ์ด๋ฒˆ์—๋Š” ๋ณต์žกํ•œ ๋ถ„ํฌ ์ „๋žต, ๋ฐธ๋Ÿฐ์Šค ์ ์ˆ˜, ๋˜๋Š” ๊ธฐํƒ€ ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ์— ์˜์กดํ•˜๊ธฐ๋ณด๋‹ค๋Š” ๊ฐ„๋‹จํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์„ ํƒํ–ˆ์Šต๋‹ˆ๋‹ค. Kubernetes์—์„œ๋Š” ๊ด€๋ฆฌ ๋ชฉ์ ์œผ๋กœ ๋…ธ๋“œ์— ๋‹ค์–‘ํ•œ ํƒœ๊ทธ๋ฅผ ๋ ˆ์ด๋ธ”๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ์šฐ๋ฆฌ๋Š” ์ด๋ฅผ ํ™œ์šฉํ•ด ๋ชจ๋“  ๋…ธ๋“œ๊ฐ€ Longhorn ์Šคํ† ๋ฆฌ์ง€๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—์„œ๋Š” ๋ณดํ†ต ํ•„์ˆ˜ ์„œ๋น„์Šค๊ฐ€ ์š”๊ตฌ๋˜๋Š” ๋…ธ๋“œ๋กœ ๊ตฌ์„ฑ๋˜๊ธฐ ๋•Œ๋ฌธ์—, ์ด๋Ÿฌํ•œ ์„ค์ •์€ โ€œ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šคโ€๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  Longhorn์— ๋Œ€ํ•ด ๋งํ•˜์ž๋ฉด:

storage:
  storageClass: longhorn-1r
  size: 100Gi
walStorage:
  storageClass: longhorn-1r
  size: 20Gi

๊ธฐ๋ณธ ์Šคํ† ๋ฆฌ์ง€ ๋Œ€์‹  ์ด ํด๋Ÿฌ์Šคํ„ฐ๊ฐ€ ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  ํŠน๋ณ„ํ•œ โ€œlonghorn-1rโ€ ์Šคํ† ๋ฆฌ์ง€ ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ์„ค์ •ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ๋ชจ๋“  ์œ ๋Šฅํ•œ Postgres DBA๊ฐ€ ๊ทธ๋ ‡๋“ฏ, ๋ฐ์ดํ„ฐ์™€ WAL(Write-Ahead Logging) ํ• ๋‹น์„ ๋ถ„๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด์ œ ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ๋ฐฐํฌํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค:

kubectl create namespace cloudnative-pg
kubectl apply -f test-cnpg-cluster.yaml

ํด๋Ÿฌ์Šคํ„ฐ๋Š” 1~2๋ถ„ ์ด๋‚ด์— ๊ฐ€๋™๋˜๊ณ  ์‹คํ–‰๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ฐ„๋‹จํ•˜์ฃ ? ์•ฝ 30์ค„์˜ YAML๊ณผ ๋‘ ๊ฐœ์˜ ๋ช…๋ น์–ด๋งŒ์œผ๋กœ 3๊ฐœ์˜ ๋…ธ๋“œ์— ๋ถ„์‚ฐ๋œ ์™„์ „ํ•œ ๋‚ด๊ฒฐํ•จ์„ฑ(Fault Tolerance)๊ณผ ๊ณ ๊ฐ€์šฉ์„ฑ(High Availability)์„ ๊ฐ–์ถ˜ ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด ๋ชจ๋“  ๊ณผ์ •์„ 5๋ถ„๋„ ์ฑ„ ๊ฑธ๋ฆฌ์ง€ ์•Š์•„ ์™„๋ฃŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค! ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์œผ๋กœ ์ด๋งŒํผ ๊ฐ„๋‹จํ•˜๊ฒŒ ํ•ด๋ณด์„ธ์š”.


CloudNativePG PostgreSQL ํด๋Ÿฌ์Šคํ„ฐ์— ์•ก์„ธ์Šคํ•˜๊ธฐ

ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ๋ฐฐํฌํ•˜๋Š” ๊ฒƒ๊ณผ ์‹ค์ œ๋กœ ํด๋Ÿฌ์Šคํ„ฐ์— ์•ก์„ธ์Šคํ•˜๋Š” ๊ฒƒ์€ ์™„์ „ํžˆ ๋ณ„๊ฐœ์˜ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. CloudNativePG๋Š” ๊ฐ ํด๋Ÿฌ์Šคํ„ฐ์— ๋Œ€ํ•ด ํด๋Ÿฌ์Šคํ„ฐ ์ด๋ฆ„์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์„ธ ๊ฐ€์ง€ ์„œ๋น„์Šค๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ์˜ ๊ฒฝ์šฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:

  • test-cnpg-cluster-rw: ํ•ญ์ƒ ๊ธฐ๋ณธ(primary) ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค.
  • test-cnpg-cluster-ro: ๋ผ์šด๋“œ ๋กœ๋นˆ ๋ฐฉ์‹์œผ๋กœ ์„ ํƒ๋œ ๋ณต์ œ(replica) ๋…ธ๋“œ๋งŒ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค.
  • test-cnpg-cluster-r: ๋ผ์šด๋“œ ๋กœ๋นˆ ๋ฐฉ์‹์œผ๋กœ ํด๋Ÿฌ์Šคํ„ฐ์˜ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค.

Kubernetes๋Š” ์ž์ฒด DNS๋ฅผ ํ†ตํ•ด ์ด๋Ÿฌํ•œ ๋ณ„์นญ์„ ๋ผ์šฐํŒ…ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์ด ์ด๋ฆ„๋“ค์„ ์‚ฌ์šฉํ•ด ์›ํ•˜๋Š” ๋Œ€๋กœ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ํด๋Ÿฌ์Šคํ„ฐ์™€ ๋™์ผํ•œ ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ์žˆ์ง€ ์•Š์€ ๊ฒฝ์šฐ, ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ FQDN์ฒ˜๋Ÿผ ์ทจ๊ธ‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค๋ฅธ ๋„ค์ž„์ŠคํŽ˜์ด์Šค์—์„œ cloudnative-pg ๋„ค์ž„์ŠคํŽ˜์ด์Šค์˜ ๊ธฐ๋ณธ ๋…ธ๋“œ์— ์—ฐ๊ฒฐํ•˜๋ ค๋ฉด test-cnpg-cluster-rw.cloudnative-pg๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ์˜ ์—ฐ๊ฒฐ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค. ๊ทธ๋Ÿฌ๋‚˜ ๋งŒ์•ฝ Kubernetes ์™ธ๋ถ€์˜ ๋ ˆ๊ฑฐ์‹œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์žˆ๊ฑฐ๋‚˜ ์ง์ ‘ ์—ฐ๊ฒฐํ•ด์•ผ ํ•˜๋Š” ์ƒํ™ฉ์ด ์žˆ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผ ํ• ๊นŒ์š”? Kubernetes์—์„œ๋Š” ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. CloudNativePG ๋ฌธ์„œ์—์„œ๋Š” Postgres ์„œ๋น„์Šค๋ฅผ ์™ธ๋ถ€์— ๋…ธ์ถœํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์„น์…˜์ด ์žˆ์œผ๋ฉฐ, Kubernetes๊ฐ€ ์™ธ๋ถ€ ์•ก์„ธ์Šค๋ฅผ ์ ์ ˆํ•œ ์„œ๋น„์Šค๋กœ ๋ผ์šฐํŒ…ํ•˜๋„๋ก ์ธ๊ทธ๋ ˆ์Šค(Ingress) ๋ฐฉ๋ฒ•์„ ์ •์˜ํ•˜๋Š” ๊ฒƒ์ด ํ•ต์‹ฌ์ž…๋‹ˆ๋‹ค.

์ด ์ž‘์—…์€ ingress-nginx, Traefik, MetalLB ๋˜๋Š” ๋‹ค๋ฅธ ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๋Š” ์—ฌ๋Ÿฌ ์ธ๊ทธ๋ ˆ์Šค ๋ ˆ์ด์–ด๋ฅผ ํ†ตํ•ด ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ™ˆ ํ™˜๊ฒฝ์—์„œ๋Š” ์ด ์ค‘ ํ•˜๋‚˜ ์ด์ƒ์ด ์„ค์น˜๋˜์–ด ์žˆ์„ ๊ฐ€๋Šฅ์„ฑ์ด ํฝ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋‚ด๋ถ€ ์„œ๋น„์Šค์— ๊ณ ์ • IP๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜๋กœ MetalLB๋ฅผ ์„ ํƒํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ฒฝ๋กœ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ณผ์ •์€ kubectl ๋ช…๋ น์–ด ํ•˜๋‚˜๋กœ ๊ฐ„๋‹จํžˆ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

kubectl -n cloudnative-pg expose service test-cnpg-cluster-rw \
        --name=test-cnpg-bones-lb --port=5432 --type=LoadBalancer

์ด ๋ช…๋ น์–ด์˜ ์žฅ์ ์€ Kubernetes๊ฐ€ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ๋”ฐ๋กœ ์ง€์ •ํ•˜๊ฑฐ๋‚˜ ์‹ ๊ฒฝ ์“ธ ํ•„์š”๊ฐ€ ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ˜ธํ™˜๋˜๋Š” LoadBalancer ์œ ํ˜•๋งŒ ์žˆ๋‹ค๋ฉด ๊ธฐ๋ณธ ํด๋Ÿฌ์Šคํ„ฐ ์„œ๋น„์Šค๋ฅผ ์™ธ๋ถ€๋กœ ๋…ธ์ถœํ•˜๊ณ  IP๋ฅผ ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ช…๋ น์œผ๋กœ ์ƒ์„ฑ๋œ ์„œ๋น„์Šค ๋ชฉ๋ก์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:

NAME                   TYPE           EXTERNAL-IP   PORT(S)
test-cnpg-bones-lb     LoadBalancer   10.0.5.101    5432:32631/TCP
Test-cnpg-cluster-r    ClusterIP      <none>        5432/TCP
test-cnpg-cluster-ro   ClusterIP      <none>        5432/TCP
test-cnpg-cluster-rw   ClusterIP      <none>        5432/TCP

์ด๋ฆ„์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ง€์ •๋˜๊ณ  IP ์ฃผ์†Œ์— ์—ฐ๊ฒฐ๋œ ์ƒˆ๋กœ์šด ์„œ๋น„์Šค๊ฐ€ ์ƒ์„ฑ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ์ด ์„œ๋น„์Šค๋ฅผ ํ†ตํ•ด ํด๋Ÿฌ์Šคํ„ฐ์— ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ๋‹ค์Œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” ๋ฌด์—‡์ธ๊ฐ€์š”?


CloudNativePG ๋น„๋ฐ€๋ฒˆํ˜ธ ํ™•์ธ ๋ฐ PostgreSQL ์—ฐ๊ฒฐ

CloudNativePG๋Š” ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ์ž๋™์œผ๋กœ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ Kubernetes์˜ ์‹œํฌ๋ฆฟ(Secret)์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ํ•ด๋‹น ๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” ์†Œ์œ ์ž๋งŒ ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ณดํ˜ธ๋˜๋ฉฐ, ์ด๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ช‡ ๊ฐ€์ง€ ๋‹จ๊ณ„๋ฅผ ๊ฑฐ์ณ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ํด๋Ÿฌ์Šคํ„ฐ์— Rancher์™€ ๊ฐ™์€ ํ”„๋ก ํŠธ์—”๋“œ ๊ด€๋ฆฌ ๋„๊ตฌ๊ฐ€ ์žˆ๋‹ค๋ฉด, ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด ์‰ฝ๊ฒŒ ์‹œํฌ๋ฆฟ์„ ๋ณต์‚ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋ฉด kubectl ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•ด ํ•„์š”ํ•œ ์ •๋ณด๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

$> kubectl -n cloudnative-pg get secret

NAME                            TYPE                       DATA   AGE
test-cnpg-cluster-app           kubernetes.io/basic-auth   9      71m
test-cnpg-cluster-ca            Opaque                     2      71m
test-cnpg-cluster-replication   kubernetes.io/tls          2      71m
test-cnpg-cluster-server        kubernetes.io/tls          2      71m

์ธ์ฆ์„œ ๊ด€๋ จ ํ•ญ๋ชฉ์„ ์ œ์™ธํ•˜๊ณ , test-cnpg-cluster-app ์‹œํฌ๋ฆฟ์— ์‚ฌ์šฉ์ž ์ด๋ฆ„๊ณผ ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ํ™•์ธํ•˜๋ ค๋ฉด ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค:

kubectl get secret test-cnpg-cluster-app \
        -o=jsonpath='{.data.password}' | base64 -d

์–ป์€ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ PGPASSWORD ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋กœ ๋‚ด๋ณด๋‚ด๊ฑฐ๋‚˜, psql ๋˜๋Š” pgAdmin์˜ ๋น„๋ฐ€๋ฒˆํ˜ธ ํ”„๋กฌํ”„ํŠธ์— ๋ถ™์—ฌ๋„ฃ์œผ๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ด์ œ ํด๋Ÿฌ์Šคํ„ฐ์— ์—ฐ๊ฒฐํ•  ์ค€๋น„๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค:

$> export PGPASSWORD=<snip>
$> psql -h 10.0.5.101 -U bones -d bones

psql (16.2 (Ubuntu 16.2-1.pgdg22.04+1))
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.

bones=>

์„ฑ๊ณต!

CloudNativePG๋กœ Kubernetes์˜ Postgres ๊ด€๋ฆฌ ๊ฐ„์†Œํ™”ํ•˜๊ธฐ

๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋Š” ์ฃผ์ œ๋Š” ์—ฌ์ „ํžˆ ๋งŽ์ง€๋งŒ, ์ด ๊ธ€์—์„œ ๋งˆ๋ฌด๋ฆฌํ•˜๋ ค ํ•ฉ๋‹ˆ๋‹ค. CloudNativePG๋Š” ํ˜„์žฌ ํด๋Ÿฌ์Šคํ„ฐ ์ƒํƒœ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•ด Patroni์— ์˜์กดํ•˜์ง€ ์•Š๋Š” ์œ ์ผํ•œ Kubernetes ์šด์˜์ž์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์žฅ์•  ์กฐ์น˜ ๊ด€๋ฆฌ, ํผ์‹œ์Šคํ„ดํŠธ ๋ณผ๋ฅจ ํด๋ ˆ์ž„ ํ”„๋กœ๋น„์ €๋‹, ์‹œ์Šคํ…œ ์Šค๋ƒ…์ƒท ์ฒ˜๋ฆฌ, ๋กœ๋“œ ๋ฐธ๋Ÿฐ์‹ฑ, ๊ทธ๋ฆฌ๊ณ  ์šด์˜์ž ์ˆ˜์ค€์—์„œ๋งŒ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋‹ค์–‘ํ•œ ๊ณ ๊ธ‰ ๊ธฐ๋Šฅ์„ ์ง์ ‘ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ€๋ธŒ๋ฆฌ์—˜๊ณผ ๊ทธ์˜ ํŒ€์€ ์ง€๋‚œ 5๋…„๊ฐ„ ๋ฉˆ์ถ”์ง€ ์•Š๊ณ  ํ˜์‹ ์„ ์ด์–ด์™”์œผ๋ฉฐ, EDB๊ฐ€ Postgres์™€ Kubernetes๋ฅผ ๊ฒฐํ•ฉํ•˜๋Š” ๋ฐ ์ „๋…ํ•  ์ˆ˜ ์žˆ๋„๋ก ํฐ ๊ธฐ์—ฌ๋ฅผ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๊ธ€์„ ํ†ตํ•ด Kubernetes์™€ CloudNativePG์— ๋Œ€ํ•œ ์‚ฌ์ „ ์ง€์‹์ด ๊ฑฐ์˜ ์—†๋˜ ์ƒํƒœ์—์„œ ์ „์ฒด ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ๋ฐฐํฌํ•˜๊ณ  ์•ก์„ธ์Šคํ•˜๋Š” ๋ฐฉ๋ฒ•๊นŒ์ง€ ๋ฐฐ์šธ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ๋‹ค์Œ ๋‹จ๊ณ„๋Š” cnpg kubectl ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์„ค์น˜ํ•ด Postgres ํด๋Ÿฌ์Šคํ„ฐ ๊ด€๋ฆฌ ์ž‘์—…์„ ํ•œ์ธต ๋” ๊ฐ„์†Œํ™”ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

DBA๋กœ์„œ ์šฐ๋ฆฌ์˜ ์—ฌ์ •์€ ๋๋‚˜์ง€ ์•Š์•˜์œผ๋ฉฐ, ์šฐ๋ฆฌ๊ฐ€ ๋‹ค๋ฃจ๋Š” ์—์ฝ”์‹œ์Šคํ…œ์€ ์ง€์†์ ์œผ๋กœ ๋ณ€ํ™”ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ณต์žกํ•˜๊ฒŒ ๋А๊ปด์งˆ ์ˆ˜ ์žˆ์ง€๋งŒ, Kubernetes๋Š” ์šฐ๋ฆฌ๊ฐ€ ๊ธฐ์กด์— ์ˆ˜ํ–‰ํ•˜๋˜ ๋งŽ์€ ์ž‘์—…์„ ์ƒ๋‹นํžˆ ๋‹จ์ˆœํ™”ํ•ฉ๋‹ˆ๋‹ค. ๋” ์ด์ƒ ๋ณต์žกํ•œ HA ์Šคํƒ์„ ๊ตฌ์„ฑํ•˜๊ฑฐ๋‚˜ ์ฟผ๋Ÿผ, ํŽœ์‹ฑ ๊ทœ์น™, ํ—ฌํผ ์Šคํฌ๋ฆฝํŠธ, ๋ผ์šฐํŒ… ๋“ฑ์„ ๋ชจ๋“  ๋…ธ๋“œ์— ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์• ์“ธ ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์ด์ œ๋Š” ๊ฐœ๋ณ„ ๋…ธ๋“œ์™€ ์”จ๋ฆ„ํ•˜์ง€ ์•Š๊ณ ๋„, ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ํด๋Ÿฌ์Šคํ„ฐ๋กœ์„œ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฌผ๋ก  Kubernetes๊ฐ€ ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹๊ณผ ํŠนํžˆ CloudNativePG์™€ ๊ด€๋ จ๋œ ๊ธฐ๋ณธ ์ธํ”„๋ผ๋ฅผ ์ถฉ๋ถ„ํžˆ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์€ ์—ฌ์ „ํžˆ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ํ™œ์šฉํ•˜๊ฑฐ๋‚˜ ์ธํ„ฐ๋„ท์—์„œ ์ˆ˜์‹ญ ๊ฐœ์˜ Kubernetes ๋ธ”๋กœ๊ทธ, ํŠœํ† ๋ฆฌ์–ผ, YouTube ๋™์˜์ƒ์„ ์ฐธ๊ณ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•„์š”ํ•œ ์ •๋ณด๋ฅผ ์ฐพ๊ณ ์ž ๋…ธ๋ ฅํ•œ๋‹ค๋ฉด ์ถฉ๋ถ„ํ•œ ์ž๋ฃŒ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ํ˜„์žฌ๋กœ์„œ Postgres์˜ ๋ฏธ๋ž˜๋Š” ๋น ๋ฅด๊ฒŒ ๋‹ค๊ฐ€์˜ค๊ณ  ์žˆ์œผ๋ฉฐ, EDB๋Š” ์ด๋ฅผ ์‹คํ˜„ํ•˜๋Š” ๋ฐ ์ค‘์š”ํ•œ ์—ญํ• ์„ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. CloudNativePG์˜ ํฅ๋ฏธ๋กœ์šด ๊ฐœ๋ฐœ ์—ญ์‚ฌ๋ฅผ ์ž์„ธํžˆ ๋‹ค๋ฃฌ ํ†ต์ฐฐ๋ ฅ ์žˆ๋Š” ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ์„ ํ†ตํ•ด ๊ทธ ์—ฌ์ •์„ ์‚ดํŽด๋ณด์„ธ์š”. ์ด๋ ‡๊ฒŒ ํ’๋ถ€ํ•œ ๋ฐฐ๊ฒฝ์„ ๊ฐ€์ง„ ๋งŒํผ, ์‹ค์ œ ์‚ฌ์šฉ๋ฒ•๋„ ๋งค์šฐ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํžˆ ์•Œ์•„๋ณด์„ธ์š”!


CloudNativePG FAQ

CloudNativePG๋ž€ ๋ฌด์—‡์ธ๊ฐ€์š”?

CloudNativePG๋Š” Kubernetes์—์„œ Postgres ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์šด์˜ํ•˜๊ธฐ ์œ„ํ•œ ์šด์˜์ž์ž…๋‹ˆ๋‹ค. Go ์–ธ์–ด๋กœ ์ž‘์„ฑ๋˜์—ˆ์œผ๋ฉฐ Kubernetes ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ™œ์šฉํ•ด ํด๋Ÿฌ์Šคํ„ฐ ๋ฐฐํฌ์™€ ์šด์˜์„ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Kubernetes์—์„œ CloudNativePG๋Š” ์–ด๋–ป๊ฒŒ ์„ค์น˜ํ•˜๋‚˜์š”?

๋ณธ๋ฌธ์˜ CloudNativePG 1.22 ์˜ˆ์ œ์—์„œ๋Š” kubectl apply ๋ช…๋ น์–ด๋กœ ์šด์˜์ž๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค. ์„ค์น˜ ํ›„ kubectl get deployment -n cnpg-system ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•ด cnpg-controller-manager์˜ ๋ฐฐํฌ ์ƒํƒœ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

CloudNativePG์—์„œ PostgreSQL ํด๋Ÿฌ์Šคํ„ฐ๋Š” ์–ด๋–ป๊ฒŒ ์ƒ์„ฑํ•˜๋‚˜์š”?

Cluster ๋ฆฌ์†Œ์Šค๋ฅผ ์ •์˜ํ•˜๋Š” YAML ํŒŒ์ผ์— ์ธ์Šคํ„ด์Šค ์ˆ˜, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค, ์†Œ์œ ์ž, PostgreSQL ๋งค๊ฐœ๋ณ€์ˆ˜, ์Šคํ† ๋ฆฌ์ง€ ๋“ฑ์˜ ์„ค์ •์„ ์ž‘์„ฑํ•œ ๋’ค kubectl apply ๋ช…๋ น์–ด๋กœ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ณธ๋ฌธ์˜ ์˜ˆ์ œ์—์„œ๋Š” 3๊ฐœ์˜ ์ธ์Šคํ„ด์Šค๋กœ ๊ตฌ์„ฑ๋œ ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

CloudNativePG์˜ rw, ro, r ์„œ๋น„์Šค๋Š” ์–ด๋–ค ์ฐจ์ด๊ฐ€ ์žˆ๋‚˜์š”?

๋ณธ๋ฌธ์˜ ์˜ˆ์ œ์—์„œ -rw ์„œ๋น„์Šค๋Š” ํ•ญ์ƒ ๊ธฐ๋ณธ(primary) ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ณ , -ro ์„œ๋น„์Šค๋Š” ๋ผ์šด๋“œ ๋กœ๋นˆ ๋ฐฉ์‹์œผ๋กœ ๋ณต์ œ(replica) ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค. -r ์„œ๋น„์Šค๋Š” ๋ผ์šด๋“œ ๋กœ๋นˆ ๋ฐฉ์‹์œผ๋กœ ํด๋Ÿฌ์Šคํ„ฐ์˜ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค.

CloudNativePG๊ฐ€ ์ž๋™ ์ƒ์„ฑํ•œ PostgreSQL ๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” ์–ด๋–ป๊ฒŒ ํ™•์ธํ•˜๋‚˜์š”?

๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ง์ ‘ ์ง€์ •ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ CloudNativePG๊ฐ€ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ƒ์„ฑํ•ด Kubernetes Secret์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. kubectl๋กœ ํ•ด๋‹น Secret์„ ์กฐํšŒํ•œ ๋’ค jsonpath์™€ base64 -d๋ฅผ ์‚ฌ์šฉํ•ด ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๋ณธ๋ฌธ: CloudNativePG Tutorial: Manage Multiple Cloud-Native Databases

EDB ์˜์—… ๊ธฐ์ˆ  ๋ฌธ์˜: 02-501-5113

์ด๋ฉ”์ผ: salesinquiry@enterprisedb.com

ํ™ˆํŽ˜์ด์ง€ ๋ฌธ์˜ํ•˜๊ธฐ

Share this