728x90
์ด๋ฒ์ ์ ๋ฌด๊ณผ์ ์์ ์ผ๋ ํด๋ค์ ์ ๋ฆฌํด๋ณด๋ฉด์ k8s ์น ๋ฐฐํฌ๋ฅผ ์๋ ์ ํ๋ ๊ธฐ์ต์ ๋์ด๋ ค ๋ค์ ๊ณต๋ถํด๋ณด๋ฉด์ ํฌ์คํ ํ๊ธฐ๋ก ํ๋ค. ์ด ํฌ์คํ ์์๋ ๋จผ์ ํ์ํ dockerfile ๋ค์ ์ ์ํ๊ณ ๋ก์ปฌ ํ๊ฒฝ์์ ์ ์์ ์ผ๋ก ๋์ํ๋์ง ํ ์คํธํด๋ณธ๋ค.
๋ชฉํ
- GKE(Google Kubernetes Engine)์ GCE(Google Compute Engine) ๋ฑ์ ํ์ฉํ ํ์คํ ์น ์๋น์ค ๋ฐฐํฌํ๊ธฐ
- docker file ๊ตฌ์ฑํ๊ธฐ
- kubectl ํ์ฉํ๊ธฐ
- ์ฟ ๋ฒ๋คํฐ์ค ๊ตฌ์ฑ์ ๊ดํ ์ดํด ๋ฐ ์ ์ฉ
- Deployment
- StatefulSet
- Persistent Volume
- Service
- Gateway
- Networking
ํด๋น ํฌ์คํ ์์ ์ฌ์ฉ๋ docker image๋ dockerhub์์ pullํ์ค ์ ์์ต๋๋ค.
- mysterias/web-service:latest
1. Docker File ๊ตฌ์ฑํ๊ธฐ
A. ํ๋ก ํธ์๋ / ๋ฐฑ์๋ Docker Image ๋ง๋ค๊ธฐ
- ํ๋ก ํธ์๋๋ฅผ ๋ณ๋ ํ๋ ์์ํฌ(React ๋ฑ) ์ผ๋ก ๊ตฌ์ฑํ๋ ๊ฒฝ์ฐ์๋ ์ด ๋ํ ๋ค๋ฅธ ์ํฌ๋ก๋๋ก ๊ตฌ์ฑํ๋ ๊ฒฝ์ฐ๊ฐ ์์ง๋ง, ๋ด ์น ์๋น์ค์ ๊ฒฝ์ฐ์๋ jQuery์ javascript๋ก ๊ฐ๋จํ๊ฒ ๋ง๋ค์๊ธฐ ๋๋ฌธ์ ๋ณ๋๋ก ๋๋์ง ์์๋ค.
- DB๋ ๋ค๋ฅธ ์ํฌ๋ก๋๋ก ๋์ธ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ DB์ ๋ฐฑ์๋ ์ฑ์ด ์ฐ๊ฒฐ๋๋ ๋ถ๋ถ์ ํ๊ฒฝ๋ณ์ ์ฒ๋ฆฌ ํด์ ๋ด๋ถ์ ์ผ๋ก ๋์ํ ์ ์๋๋ก ํด์ค๋ค. ๋๋ SQLAlchemy๋ฅผ ์ฌ์ฉํ์ฌ์ `create_engine` ์ url ๋ถ๋ถ์ ๋๋ ์ ํ๊ฒฝ๋ณ์ ์ฒ๋ฆฌ๋ฅผ ํ๋ค.
- ๊ทธ๋ฆฌ๊ณ ์ฒ์ FastaAPI ์ฑ ๊ฐ๋ฐ ๋ฐ ํ ์คํธ๋ฅผ ํ ๋๋ uvicorn์ ์ฌ์ฉํ์ผ๋, ์๋น์ค๋ฅผ ํ ๋๋ ๋์ ์์ฒญ์ด ๋ง์์ง๋ฏ๋ก ๋ณ๋ ฌ ์ฒ๋ฆฌ๋ฅผ ์ํด gunicorn์ผ๋ก ๋์์ํค๋ ๊ฒ์ docker cmd๋ก ์ ํ๋ค.
# Fastapi Dockerfile
FROM python:3.12
# ๋จผ์ requirements๋ง ๋ณต์ฌํด์ ํ์ฉ
COPY requirements.txt /app/requirements.txt
# ์คํ์์น ์ด๋
WORKDIR /app
# pip ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค์น
RUN pip install --upgrade pip && pip install --no-cache -r requirements.txt
# ์ฑ ์ฝ๋ ๋ณต์ฌ
COPY . /app
# ํ๊ฒฝ ๋ณ์ ์ค์
ENV db_user = user
...
# ํฌํธ ์ค์
EXPOSE 8080
# ์คํ์ด
CMD ["gunicorn", "-k", "uvicorn.workers.UvicornWorker", "main:app", "--bind", "0.0.0.0:8080", "--workers", "2", "--timeout", "60", "--sys-log"]
- ๋์ค์ ํ ๋ฒ ๋ฌธ์ ๊ฐ ์๊ฒจ์ ์์ ํ ๋ถ๋ถ์ด ์๋๋ฐ, CMD์์ bind ์ฃผ์๋ฅผ ๋ฐ๋์ 0.0.0.0 ์ผ๋ก ํด์ผํ๋ค. ์ฒ์์ ๋ณ ์๊ฐ ์์ด localhost๋ก ํ์๋๋ฐ, ๊ทธ๋ฌ๋ฉด ์ถํ kubernetes ์์ ์ฌ๋ ธ์ ๋ ์๋น์ค๋ก ์ธ๋ถ ๋
ธ์ถ์ ์๋ํด๋ ์ธ๋ถ๋ localhost์ ํฌํจ๋์ง ์์ผ๋ฏ๋ก ์ ์์ด ๋์ง ์๋๋ค. 0.0.0.0 ์ ๋ค์ด์ค๋ ๋ชจ๋ ์ฃผ์๋ฅผ ํ์ฉํ๊ฒ ๋ค๋ ์๋ฏธ์ด๋ค.
- ๋ง์ผ kubenetes ํ๊ฒฝ์ ์ฌ๋ฆฌ์ง ์๊ณ ๋ก์ปฌ์์๋ง ํ ์คํธ ํ๊ฑฐ๋ ์๋น์คํ ๊ฑฐ๋ผ๋ฉด ์๊ด์๋ค. ๊ทธ๋ฐ ๊ฒฝ์ฐ์๋ fastapi ์ปจํ ์ด๋๋ฅผ ์ธ๋ถ ๋ ธ์ถํ๋ ๊ฒ ์๋๋ผ nginx ๋ฑ ์น ์๋ฒ๋ฅผ ์์ ๋ฎ์ด์ ์๋นํ๋ค.
- ํ๊ฒฝ๋ณ์์ ๊ฒฝ์ฐ ์ถํ docker compose๋ฅผ ์ฌ์ฉํด์ ํ ์คํธ ํ ๊ฒ์ด๋ผ ๊ตณ์ด dockerfile์ ์ถ๊ฐํ์ง๋ ์์์ง๋ง ํ์ํ๋ค๋ฉด ์ฌ๊ธฐ์ ๋ฃ์ด๋ ๋๋ค.
- ์ด๋ ๊ฒ ํ ํ์ dockerfile์ ๋น๋ํด๋๋ค.
docker build -t web-service:251111 .
- ์ด๋ฌ๋ฉด 251111์ด๋ผ๋ tag๋ฅผ ๊ฐ์ง ๋์ปค ์ด๋ฏธ์ง web-service๊ฐ ๋ก์ปฌ์ ์ ์ฅ๋๋ค.
B. DB Docker Image ๋ง๋ค๊ธฐ
- ํ์ฌ ๋ด ์๋น์ค์์ DB๊ฐ ํ์๋ก ํ๋ ๊ฒ์ ๋ฏธ๋ฆฌ ์์ฑ๋์ด์๋ ํน์ user(DB owner)์ user์๊ฒ ํ ๋น๋ ํน์ ํ database ์ด๋ ๊ฒ ๋ ๊ฐ์ง์๋ค.
- kubernetes์ ์ฌ๋ฆด ๋๋ postgres ๊ณต์ ์ด๋ฏธ์ง๋ฅผ ์ฌ์ฉํ์ง๋ง, ๋ก์ปฌ ํ ์คํธ๋ฅผ ์ํด์๋ ๋ณ๋๋ก ์ด๋ฏธ์ง๋ฅผ ๋ง๋ค์ด์ ์ฌ์ฉํ๋ค. ์ด์ ์ ๋ํด์๋ ์ถํ์ ์ฟ ๋ฒ๋คํฐ์ค๋ฅผ ๊ตฌ์ฑํ๋ฉด์ ์์ ํ๊ฒ ๋ค.
- ๋ง๋๋ ๋ฐฉ๋ฒ์ ๊ฐ๋จํ๊ฒ ๊ณต์์ด๋ฏธ์ง์ ๋ฏธ๋ฆฌ user์ db๋ฅผ ๋ง๋๋ sql ํ์ผ์ ๋ง๋ค์ด์ entrypoint๋ก ๋ณต์ฌํด๋๋ฉด ๋๋ค.
// init.sql
DO
$$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_catalog.pg_roles WHERE rolname = 'dain') THEN
CREATE ROLE dain WITH LOGIN PASSWORD 'password';
END IF;
END
$$;
SELECT 'CREATE DATABASE monitor OWNER dain'
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'monitor')\gexec
- ๊ฐ๋จํ ํด์คํ์๋ฉด role name ์ค์ dain์ด ์์ผ๋ฉด password๋ฅผ ๋น๋ฐ๋ฒํธ๋ก ํด์ ๋ง๋ค๊ณ , database ์ค์ monitor๊ฐ ์์ผ๋ฉด dain์ owner๋ก ํด์ ๋ง๋ค์ด๋ผ~ ๋ผ๋ sql ํ์ผ์ด๋ค.
- ์ด init.sql์ ๋ณต์ฌํด์ docker-entrypoint-initdb.d ๋ก ๋ง๋ค์ด์ฃผ๋ฉด ๋์ปค๊ฐ entrypoint๋ก ์ธ์ํ๊ณ ์คํํด์ค๋ค.
# postgreSQL Dockerfile
FROM postgres:15
COPY init.sql /docker-entrypoint-initdb.d
EXPOSE 5432
- ์ด์ docker build๋ก ์ด๋ฏธ์ง๋ฅผ ๊ตฌ์๋๋ค.
docker build -t db_postgres:251111 .
2. Docker Compose๋ก ํ์ธํ๊ธฐ
A. DB ๊ตฌ์ฑํ๊ธฐ
- ๋ง๋ ๋ ๊ฐ์ ์ด๋ฏธ์ง๊ฐ ๊ฐ๊ฐ์ container๋ก ๋์ ์ ๋ ์ ๋์ํ๋์ง๋ฅผ ํ์ธํ๊ธฐ ์ํด์ docker compose๋ฅผ ํ์ฉํ๋ค.
- fastapi ์ฑ์ ๊ฒฝ์ฐ DB์ ์ฐ๊ฒฐ์ ์๋ํ๋ ๊ฒ์ด ์ฒซ ์คํ ์ด๋ฏ๋ก fastapi๋ณด๋ค postgreSQL ์ปจํ ์ด๋๋ฅผ ๋จผ์ ๋์์ผํ๋ค.
- ๊ตฌ์ฑ์ ์๋์ ๊ฐ๋ค.
services:
postgresql:
image: db_postgres:251111
container_name: postgresql
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
ports: ["5433:5432"]
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U dain -d energy_monitor"]
interval: 5s
timeout: 3s
retries: 10
- ํ๋์ฉ ๋ฏ์ด๋ณด์. ๋จผ์ image๋ ์๊น ์ฐ๋ฆฌ๊ฐ ๊ตฌ์๋๋ db_postgres:251111 ๋ก ์ค์ ํ๋ค. tag๋ ์ผ์ข
์ ๋ฒ์ ์ด๋ฏ๋ก ๊ผญ ์๋ง์ ๊ฒ์ ์จ์ฃผ์ด์ผํ๋ค.
- ๋ง์ผ dockerfile๋ง ์๊ณ image๋ฅผ ๋ณ๋๋ก ๋ง๋ค์ด๋์ง ์์๋ค๋ฉด build ์ต์ ์ ์ถ๊ฐํ๋ค. docker file์ ๊ฒฝ๋ก๋ฅผ ์ง์ ํด์ฃผ์ด์ docker compose up์ ํ ๋ ๊ทธ dockerfile์ ๊ธฐ๋ฐ์ผ๋ก ์ด๋ฏธ์ง๋ฅผ ๋น๋ํด์ค๋ค.
- container_name์ ๊ฐ์ ๋คํธ์ํฌ ์๋์ ๋ฌถ์ฌ์๋ ์ด ์ปจํ ์ด๋์ ์๋ณ์ ๊ฐ์ ๊ฒ์ด๋ค. ๊ฐ์ ๋จธ์ ์์์ ๋๋ฆฌ๋ ์ปจํ ์ด๋๋ค ๋ผ๋ฆฌ๋ ip ๋์ ์ด ์ด๋ฆ์ผ๋ก ์๋ก๋ฅผ ์์๋ณผ ์ ์๋ค. fastapi์ชฝ์ ์ ์ํ ๋ ์์ธํ ๋ค๋ฃจ๊ฒ ๋ค.
- environment ์๋ POSTGRES_USER, POSTGRES_PASSWORD ๊ฐ ์๋ค. ์ด๊ฒ์ ๋ง์คํฐ ๊ถํ์ ๊ฐ๋ user์ password๋ฅผ ์ ํ๋ ๊ฒ์ด๋ฏ๋ก ์ ๋นํ ์ค์ ํด์ค๋ค.
- ports๋ ์์๋๋ก [host:๋ด๋ถ] ์์๋ค. ์ธ๋ถ์์ ๋ถ์ ๊ฑฐ๋ผ๋ฉด port๋ฅผ ์ง์ ํด์ค์ผํ๊ณ , ์ง๊ธ์ฒ๋ผ ๋ด๋ถ์์๋ง ๋ถ์ ๊ฑฐ๋ผ๋ฉด ๊ตณ์ด ์ ํด์ค๋ ๋๋ค.
- volumes๋ container๊ฐ ์ญ์ ๋๋ฉด ์ฌ๋ผ์ง๋ ๋ฐ์ดํฐ๋ฅผ ๋ณด์กดํ๊ธฐ ์ํ์ฌ ํ์ฌ ์คํ ๋จธ์ ์ ์ ์ฅ๊ณต๊ฐ(๋๋ ํ ๋ฆฌ)์ ์ปจํ
์ด๋ ๋ด๋ถ ๋๋ ํ ๋ฆฌ๋ฅผ ๋งคํํ๋ ๊ฒ์ด๋ค. /var/lib/postgresql/data ๊ฒฝ๋ก์ ์ ์ฅ๋๋ ๋ชจ๋ ๋ฐ์ดํฐ๋ ์คํ๋จธ์ ์ pgdata ๋๋ ํ ๋ฆฌ์ ์ ์ฅ๋๋ ๊ฒ๊ณผ ๊ฐ๋ค๊ณ ์๊ฐํ๋ฉด ๋๋ค.
- container์์ ๊ฐ์ฉํ ํน์ ํ ์ ์ฅ๊ณต๊ฐ ์์ญ๊ณผ ์ค์ host machine์ ์ด๋ ์ ์ฅ๊ณต๊ฐ ์์ญ์ ๋งคํํด์ container์์ ํด๋น ์ ์ฅ๊ณต๊ฐ์ ์ ์ฅํ๋ฉด ๋์ค์ container๋ฅผ ์ญ์ ํด๋ ์ค์ host machine์ ์ ์ฅ๊ณต๊ฐ์ ์ ์ฅํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ์ฌ๋ผ์ง์ง ์๋๋ค.
- volume์ container์ ๋ฏธ๋ฆฌ ํ ๋น๋ ์ฉ๋์ ์ก์๋จน์ง ์๋๋ค. ์ด๋ฏธ ํธ์คํธ ๋จธ์ ์ ์๋ ์ ์ฅ๊ณต๊ฐ์ ์ปจํ ์ด๋๊ฐ ์ฌ์ฉํ๋ ๊ฒ์ด๋ค.
- healthcheck๋ ํ์ฌ ์ปจํ ์ด๋๊ฐ ๋ด๊ฐ ์ค์ ํ๋๋ก ์ ๊ตฌ๋๋์๋์ง๋ฅผ ํ์ธํ๋ค.
B. Web ์๋น์ค ๊ตฌ์ฑํ๊ธฐ
- FastAPI๋ฅผ ์ฌ๋ฆฌ๋ ์ชฝ๋ ํฌ๊ฒ ๋ค๋ฅด์ง ์๋ค.
service:
postgresql:
...
fastapi:
image: web-service:latest
container_name: fastapi
depends_on:
postgresql:
condition: service_healthy
env_file: "docker.env"
ports: ["8080:8080"]
restart: on-failure
- ๋์ ๋๊ฒ ๋ค๋ฅธ ์ ์ depends_on ๋ถ๋ถ๊ณผ env_file ์ด๋ค. ๋ ๊ฐ์ง๋ง ์ค๋ช ํ๊ณ ๋์ด๊ฐ์.
- depends_on ์ ๋ง ๊ทธ๋๋ก ์๋ ์ ์ํ ๊ฒ์ ์์กดํ์ฌ ์ด ์ปจํ
์ด๋๋ฅผ ์คํํ๋ค๋ ๋ป์ด๋ค. postgresql์ด๋ผ๊ณ ์ปจํ
์ด๋ ์ด๋ฆ์ ๋ช
์ํ๊ณ , ์ด ์ปจํ
์ด๋์ ์ํ(condition)์ด service_healthy, ์ฆ ์ ์ ์๋ํ ๋๋ง fastapi ์ปจํ
์ด๋๋ฅผ ์คํจ ์์ด ์ฌ๋ฆด ์ ์๋ค.
- ์ฌ๊ธฐ์ postgresql ์ด๋ผ๋ ์ด๋ฆ์ผ๋ก container๋ฅผ ํ์ธํ ์ ์๋ ์ด์ ๋ ๋ ์ปจํ ์ด๋๊ฐ ๊ฐ์ ํธ์คํธ ๋จธ์ ์์ ์๊ณ , ๊ฐ์ ๋คํธ์ํฌ์ ๋ฌถ์ด๊ธฐ ๋๋ฌธ์ด๋ค.
- docker compose๋ฅผ ์ฌ๋ฆฐ ๋ค์ docker network ls ๋ฅผ ์คํํ๋ฉด
- env_file ์ ํ๊ฒฝ๋ณ์๋ฅผ ์ ์ธํ๋ ๋๋ค๋ฅธ ๋ฐฉ๋ฒ์ด๋ค. ํ๊ฒฝ๋ณ์๊ฐ ๋ง์์ ์ผ์ผํ ๋ค ์ ๊ธฐ ๋ญํ ๋, ํน์ ๋ด์ฉ์ ์จ๊ฒจ๋๊ณ ์ถ์ ๋ ๋ณ๋์ ํ์ผ๋ก ์ ์ฅํด์ ๋ถ๋ฌ์ค๋๋ก ํ ์ ์๋ค.
C. ์คํํ๊ธฐ
- ์ฐ์ ๋ก์ปฌ ํ๊ฒฝ์ docker desktop์ด ์คํ ์ค์ด์ด์ผํ๋ค.
- ์คํ ๋ฐฉ๋ฒ์ ๊ฐ๋จํ๋ค.
docker compose up
- ๋ง์ฝ ์ด๋ฏธ์ง๋ฅผ ์๋ก ๋น๋ํด์ผํ๋ ๊ฒฝ์ฐ์๋ build๋ฅผ ํ๊ณ up ํ๋ฉด ๋๊ณ , ๋ฐฑ๊ทธ๋ผ์ด๋ ์คํ์ ์ํ๋ฉด -d ๋ฅผ ๋ถ์ด๋ฉด ๋๋ค.

- ์คํ ํ์๋ ํฐ๋ฏธ๋์ ์ด๋ ๊ฒ ์ํ๊ฐ ์ฌ๋ผ์ค๊ณ , ๊ฐ ์ปจํ ์ด๋์ ์ด๋ฆ์ ์์ ๋ถ์ด๊ณ ๋ก๊ทธ๊ฐ ์ถ๋ ฅ๋๋ค. docker desktop์์๋ ํ์ธํ ์ ์๋ค.

- ์ด์ localhost:8080 ๋ฑ์ผ๋ก ์ ์ํด์ ํ์ธํด๋ณด๋ฉด ์น ํ์ด์ง๋ฅผ ๋ณผ ์ ์๋ค.
๋ค์ ํฌ์คํธ์์๋ kubernetes gke ์ค์ ์ ๊ดํด ์ด์ด์ ๊ฐ๋ณด๋๋ก ํ๊ฒ ๋ค. ์ฌ์ฌ ์ํ์ฐฉ์ค^^๊ฐ ๋ด๊ธธ ์์ ์ด๋ค..
728x90