1. ๊ฐ๋ ๋ฐ ์ฉ์ด ์ ๋ฆฌ
[1] DNS
DNS ๋ ๋๋ฉ์ธ์ ์๋ง๋ IP ์ฃผ์๋ก ๋ณํ์ ํด์ฃผ๋ ์ญํ ์ ํ๋ ์๋ฒ์ด๋ค. ์ ์ ๋ IP๋ณด๋ค ๋ฌธ์๋ก ํํ๋ ๋๋ฉ์ธ ์ฃผ์๋ฅผ ๋์ฑ ์ ๊ธฐ์ตํ๊ณ ํ์ฉํ๊ธฐ ๋๋ฌธ์ ๋๋ฉ์ธ์ ์ฌ์ฉํ๋ค. ๋๋ฉ์ธ์ IP ๋ก ๋ณํํ๋ ๊ณผ์ ์ ์๋์ ๊ฐ๋ค.
- /etc/hosts ํ์ผ์ ์ ์ ์ผ๋ก ์ค์ ํ ์ ๋ณด๋ฅผ ์กฐํํ๋ค.
- local DNS Cache ๋ฅผ ์กฐํํ๋ค.
- /etc/resolv.conf ํ์ผ์ ์ค์ ๋ ์ ๋ณด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก DNS ์๋ฒ์ ์ง์ํ๋ค.
- DNS server ๋ ์ ๋ณด๊ฐ ์์ผ๋ฉด IP ์ฃผ์๋ฅผ ๋ฐํํ๊ณ , ์์ผ๋ฉด ๋ณธ์ธ์ ์์ DNS ์๋ฒ์๊ฒ ์ง์ํ์ฌ ์ ๋ณด๋ฅผ ๋ฐ์์จ๋ค.
- ๋๋ฉ์ธ์ ํด๋นํ๋ IP ๋ฅผ DNS Cache ์ ์ถ๊ฐํ๋ค.
[2] reverse-proxy

Reverse-Proxy ๋ ํ๋ ์ด์์ ์น ์๋ฒ ์์ ์์นํ์ฌ ํด๋ผ์ด์ธํธ ์์ฒญ์ ๋๋ฆฌ๋ก ์ ๋ฌํ๋ ์๋ฒ์ด๋ค. ์ผ๋ฐ์ ์ธ Proxy server ๋ LAN → WAN ์์ฒญ์ ๋๋ฆฌ๋ก ์ํํ๋ ๋ฐ๋ฉด, Reverse-Proxy ๋ WAN → LAN ์ ์์ฒญ์ ๋๋ฆฌํ๋ค. ํด๋ผ์ด์ธํธ์ ์์ฒญ์ ๋๋ฆฌ๋ก ์ ๋ฌํจ์ผ๋ก์จ ์๋์ ๊ฐ์ ์ด์ ์ด ์กด์ฌํ๋ค.
- ๊ณต๊ฒฉ์ผ๋ก๋ถํฐ ๋ณดํธ : WAS ์ ์๋ฒ ์คํ(port, ip, URL)์ ์ ์จ๊ธธ ์ ์์ด DDoS ์ ๊ฐ์ ํ์ ๊ณต๊ฒฉ์ ํ์ฉํ๊ธฐ ์ด๋ ต๋ค.
- ๋ถํ๋ถ์ฐ : ์๋ฒ์ ๋ถํ ๋ถ์ฐ์ ์ ๊ณตํ์ฌ WAS ์ scale-out ํ๊ฒฝ์ ๊ตฌ์ฑํ ์ ์์ด ์๋น์ค์ ์์ ์ฑ์ ์ ๊ณตํ๋ค.
- ์บ์ฑ : ์ ์ ์ปจํ ์ธ ๋ฅผ ์บ์ฑํ ์ ์์ด ์ฑ๋ฅ ํฅ์์ ์ด์ ์ด ์๋ค.
[3] NGINX
reverse-proxy ์ข ๋ฅ ์ค ํ๋๋ก ์ฑ๊ธ ์ค๋ ๋ ๊ธฐ๋ฐ ์ด๋ฒคํธ ๋ฃจํ ๋ฐฉ์์ผ๋ก ๋์ํ๋ค. ์ฆ, Queue ์ ์์ฒญ์ ์์๋๊ณ ํ๋์ฉ ์ฒ๋ฆฌํ๋ฉฐ, async,non-blocking ๋ฐฉ์์ผ๋ก ์ฒ๋ฆฌํ๋ฏ๋ก ๋ค์์ ์ปค๋ฅ์ ์ ์ฒ๋ฆฌํ ๋ ๋น ๋ฅด๋ค.
NGINX ๋ ์์ ๋ฐ์ดํฐ๋ฅผ ๋๋์ผ๋ก ์ ์กํ๊ฑฐ๋ HDD read/write ๊ฐ ๋ฐ์ํ์ง ์๋ ๊ฒฝ์ฐ์ ์ ํฉํ๋ค. ์ค์ ๋ฐ์ดํฐ๋ฅผ I/O ๋ OS ์ H/W ์ฌ์ด์์ ์คํ๋์ด์ผ ํ๊ธฐ ๋๋ฌธ์ ๋ฐ์ดํฐ I/O ์์ ์ด ํฐ ์ฒ๋ฆฌ๊ฐ ๊ธธ์ด์ง๋ฉด Queue ์ ์์ฒญ์ด ๋ง์ด ์์ฌ ์ฑ๋ฅ ์ ํ๋ฅผ ์ด๋ํ ์ ์๋ค. ๊ทธ๋ฌ๋ฏ๋ก ๋ณต์กํ ์ฐ์ฐ ์ฒ๋ฆฌ, ๋์์ ๋ฐ์ดํฐ ์ฒ๋ฆฌ, DB ์์ ์ WAS ์๊ฒ ์์ํ์ฌ ์ฒ๋ฆฌํ๋ ๊ฒ์ด ์ ํฉํ๋ค. (reverse-proxy ๋ฅผ ๊ตฌ์ฑํ์ฌ scale-out ํ๊ฒฝ์ด ๊ฐ๋ฅํ๋ฏ๋ก WAS ์๊ฒ ์์ํ๋ ๊ฒ์ด ๋์ฑ ์ ํฉํ๋ค.)
[4] TLS (Transport Layer Security)
TLS ๋ ๋ ๊ฐ์ ํต์ ํ๋ ์ ํ๋ฆฌ์ผ์ด์ ๊ฐ์ ์ธ์ฆ, ์ํธํ ์๋น์ค๋ฅผ ์ ๊ณตํ๋ ์ธํฐ๋ท ๋ณด์ ํ๋กํ ์ฝ์ด๋ค. TLS ๋ SSL ์ธ์ฆ์๋ฅผ ์ฌ์ฉํ์ฌ ๋ณด์์ด ์ ์ง๋๋ HTTPS ์ฐ๊ฒฐ์ ์ฌ์ฉ๋๋ค. SSL ์ธ์ฆ์๋ ์ธํฐ๋ท์ ํตํด ์ ์ก๋๋ ๋ฐ์ดํฐ๋ฅผ ์ํธํํ์ฌ ๋น๋ฐ๋ฒํธ, ์ ์ฉ์นด๋ ๋ฒํธ ๋ฑ๊ณผ ๊ฐ์ ๋ฏผ๊ฐํ ์ ๋ณด๋ฅผ ๋ณดํธํ๋ค.
2. 3-tier ๊ตฌ์ฑํ๊ธฐ
- public EC2 ์ถ๊ฐ ๊ตฌ์ฑ
- swap ์์ญ ์์ฑ
- gradle ์ค์น
- github ssh ์ฐ๋
- github submodule ์ค์
- git submodule ๋ฑ๋ก ๋ฐฉ๋ฒ
- TLS ์ค์
- TLS ์ธ์ฆ์ ๋ฐ๊ธ๋ฐ๊ธฐ (by. letsencrypt)
- nginx container ์์ฑ
- https ์ค์ & ํ๋ก์ ์ค์
- DB ์๋ฒ ๊ตฌ์ฑ
- mysql docker container ์์ฑ
- ์ด์ ํ๊ฒฝ ํ๋กํผํฐ ๋ถ๋ฆฌ
- property ๋ถ๋ฆฌํด์ ๋น๋ํ๊ธฐ
- buld.gradle depdendency ์ถ๊ฐ + resources ํ์ผ ์ค์
- ์๋ฒ ์คํ
- URL ํ์ธ
- script practice
[1] public EC2 ์ถ๊ฐ ๊ตฌ์ฑ
(1) swap ์์ญ ์์ฑ
- AWS t2.micro ์ ๊ณต RAM ์ด 1GB ์ด๋ฏ๋ก gradle ๋น๋ ์ ์๋ฒ๊ฐ ๋ฉ์ถ ์ ์์ด swap ์์ญ ์์ฑํ์ฌ ํ์ฉ
a. swap ์ํ ํ์ธ : ๋ฏธ์ค์ ์
$ sudo swapon -s # ์ค์ ์ํ ํ์ธ ๋ช
๋ น์ด
$ free # ๋ฉ๋ชจ๋ฆฌ ์ํ ํ์ธ ๋ช
๋ น์ด
total used free shared buff/cache available
Mem: 972024 549984 110216 252 311824 263844
Swap: 0 0 0
b. swap partition ์์ฑ
(1) root file system ์ swapfile ์์ฑ
- 128MB ์ฉ 16๋ฒ์ /dev/zero ๋ก ๋ถํฐ ์ฝ์ด /swapfile ์ ์ ์ฅ (128MB * 16 = 2GB)
$ sudo dd if=/dev/zero of=/swapfile bs=128M count=16
(2) swapfile ๊ถํ ๋ถ์ฌ
$ sudo chmod 600 /swapfile
(3) swap ์์ญ ์ค์
- mkswap [file] : swap partition ์์ฑ ๋ช ๋ น์ด
$ sudo mkswap /swapfile
(4) swap ๊ณต๊ฐ์ swapfile ์ถ๊ฐ
- swapon [file] : swapfile ํ์ฑํ ๋ช ๋ น์ด
$ sudo swapon /swapfile
(5) ์ค์ ๊ณต๊ฐ ํ์ธ
$ sudo swapon -s
Filename Type Size Used Priority
/swapfile file 2097148 329472 -2
$ free
total used free shared buff/cache available
Mem: 972024 551056 106940 252 314028 262784
Swap: 2097148 329472 1767676
(6) ๋ถํ ์ swapfile ํ์ฑํ ์ค์
- /etc/fstab : linux ์์ file system ์ ๋ณด๋ฅผ ์ ์ฅํ๊ณ ์๋ ํ์ผ์ด๋ฉฐ, ๋ถํ ์ ๋ง์ดํธ ์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ ์์
- ์ ๋ ฅ ๋ด์ฉ : [ํ์ผ์์คํ ์ฅ์น][๋ง์ดํธํฌ์ธํธ][ํ์ผ์์คํ ์ข ๋ฅ][์ต์ ][dump์ค์ ][ํ์ผ์ ๊ฒ์ต์ ]
$ sudo vim /etc/fstab
/swapfile swap swap defaults 0 0
c. swap partition ์ ๊ฑฐ
(1) ํ ๋น๋ swap ๊ณต๊ฐ ์ ๊ฑฐ
$ sudo swapoff /swapfile
(2) swapfile ์ ๊ฑฐ
sudo rm -rf /swapfile
(3) ๋ถํ ์, swapfile ํ์ฑํ ์ค์ ์ ๊ฑฐ
$ sudo vim /etc/fstab
/swapfile swap swap defaults 0 0 # ํด๋น ๋ด์ฉ ์ ๊ฑฐ
(2) install gradle
a. ์ค์น Gradle version ํ์ธ

b. ์ค์น ๋ฒ์ Gradle zip file ๋ค์ด๋ก๋
# wget unzip ์์ ๊ฒฝ์ฐ ํด๋น package ์ค์น
$ wget https://services.gradle.org/distributions/gradle-7.5.1-bin.zip -P /tmp
$ sudo unzip -d /opt/gradle /tmp/gradle-7.5.1-bin.zip

c. ํ๊ฒฝ ๋ณ์ ์ค์ (+ ๊ถํ ๋ณ๊ฒฝ)
$ sudo vim /etc/profile.d/gradle.sh
export GRADLE_HOME=/opt/gradle/gradle-7.5.1
export PATH=${GRADLE_HOME}/bin:${PATH}
$ sudo chmod +x /etc/profile.d/gradle.sh
$ source /etc/profile.d/gradle.sh
d. Gradle version ํ์ธ
gradle -v

(3) github ssh ๋ฑ๋ก
a. ssh ํค์์ฑ
- ๋น๋ฐํค ๊ฒฝ๋ก : ~/.ssh/id_rsa
- ๊ณต๊ฐํค ๊ฒฝ๋ก : ~/.ssh/id_rsa.pub
$ ssh-keygen
b. Github ๊ณ์ SSH ๊ณต๊ฐํค ๋ฑ๋ก
(4) github submodule ์ค์
application.properties ์ ๊ฒฝ์ฐ, secret-key ๋ฅผ ๊ด๋ฆฌํ๋ ๊ฒฝ์ฐ๋ ์์ด ๋ณด์์์ผ๋ก private ์ ํตํด ๊ด๋ฆฌํด์ผ ํ๋ค.
- github private repository ์์ฑ → application.properties ์ค์ ํ์ผ ์ปค๋ฐ
- github submodule ์ ํตํด ํน์ ๊ฒฝ๋ก์ private repository ์ฐธ์กฐํ๋๋ก ์ค์
- ์ดํ ์์ค์ฝ๋ ๋ฐ์ ๋ submodule ๊น์ง clone
$ git submodule add [์์ ์ private ์ ์ฅ์] ./src/main/resources/config
$ git clone --recurse-submodules [์์ ์ ํ๋ก์ ํธ ์ ์ฅ์]
- ์ค์ ํ์ผ ๋ด์ฉ ๋ณ๊ฒฝ๋ ๊ฒฝ์ฐ, submodule ๋ง ์ปค๋ฐํ๋ ๋ฐฉ๋ฒ
$ git submodule foreach git pull origin main
$ git submodule foreach git add .
$ git submodule foreach git commit -m "commit message"
$ git submodule foreach git push origin main
[2] TLS ์ค์
(1) TLS ์ธ์ฆ์ ๋ฐ๊ธ๋ฐ๊ธฐ
- HTTP ๋ ํ๋ฌธ ํต์ ์ด๋ฏ๋ก ์ค๋ํ(snipping) ํ์ฌ ํจํท์ ๊ฐ๋ก์ฑ ํ์ธํ ์ฐ๋ ค๊ฐ ์์ด HTTPS ๊ฐ ํ์ํ๋ค.
- HTTPS ๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋ TLS ์ธ์ฆ์๊ฐ ํ์ํ๋ฏ๋ก letsencrypt ๋ฌด๋ฃ TLS ์ธ์ฆ์ ํ์ฉ
$ docker run -it --rm --name certbot \
-v '/etc/letsencrypt:/etc/letsencrypt' \
-v '/var/lib/letsencrypt:/var/lib/letsencrypt' \
certbot/certbot certonly -d 'yourdomain.com' --manual --preferred-challenges dns --server https://acme-v02.api.letsencrypt.org/directory
- ์ธ์ฆ์ ์์ฑ ํ ์ ํจํ URL ํ์ธ์ ์ํด DNS TXT ๋ ์ฝ๋ ์ถ๊ฐ
- DNS ์ค์ ์ฌ์ดํธ์์ DNS TXT ๋ ์ฝ๋ ์ถ๊ฐ ํ, dig ๋ช ๋ น์ด๋ฅผ ํตํด


- ์์ฑํ ์ธ์ฆ์๋ฅผ ํ์ฉํด Reverse Proxy ์ TLS ์ค์ ๋ฐ Dockerfile ๊ฐ ์์นํ ํ์ฌ ๊ฒฝ๋ก๋ก ๋ณต์ฌ
$ cp /etc/letsencrypt/live/[๋๋ฉ์ธ์ฃผ์]/fullchain.pem ./
$ cp /etc/letsencrypt/live/[๋๋ฉ์ธ์ฃผ์]/privkey.pem ./
- Dockerfile ์ค์
FROM nginx
COPY nginx.conf /etc/nginx/nginx.conf
COPY fullchain.pem /etc/letsencrypt/live/[๋๋ฉ์ธ์ฃผ์]/fullchain.pem
COPY privkey.pem /etc/letsencrypt/live/[๋๋ฉ์ธ์ฃผ์]/privkey.pem
- nginx.conf
events {}
http {
upstream app {
server 172.17.0.1:8080;
}
# Redirect all traffic to HTTPS
server {
listen 80;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/[๋๋ฉ์ธ์ฃผ์]/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/[๋๋ฉ์ธ์ฃผ์]/privkey.pem;
# Disable SSL
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# ํต์ ๊ณผ์ ์์ ์ฌ์ฉํ ์ํธํ ์๊ณ ๋ฆฌ์ฆ
ssl_prefer_server_ciphers on;
ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
# Enable HSTS
# client์ browser์๊ฒ http๋ก ์ด๋ ํ ๊ฒ๋ load ํ์ง ๋ง๋ผ๊ณ ๊ท์ ํฉ๋๋ค.
# ์ด๋ฅผ ํตํด http์์ https๋ก redirect ๋๋ request๋ฅผ minimize ํ ์ ์์ต๋๋ค.
add_header Strict-Transport-Security "max-age=31536000" always;
# SSL sessions
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
location / {
proxy_pass http://app;
}
}
}
- nginx docker container ์คํ
- docker build -t cooper/reverse-proxy:0.0.1 . : Dockerfile ๊ธฐ๋ฐ์ผ๋ก ์ด๋ฏธ์ง ๋น๋
- ๋น๋ํ ์ด๋ฏธ์ง๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ปจํ ์ด๋ ์คํ
$ docker stop proxy && docker rm proxy
$ docker build -t brainbackdoor/reverse-proxy:0.0.2 .
$ docker run -d -p 80:80 -p 443:443 --name proxy cooper/reverse-proxy:0.0.2
[3] DB ์๋ฒ ๊ตฌ์ฑ
(1) ์ด์ DB ๊ตฌ์ฑ (by. mysql container)
- private EC2 ์ ํด๋น ์ด๋ฏธ์ง ๊ธฐ๋ฐ ์ปจํ ์ด๋ ์์ฑ
# id: root, pw: masterpw
$ docker run -d -p 3306:3306 brainbackdoor/data-subway:0.0.1
[4] ์ด์ ํ๊ฒฝ ํ๋กํผํฐ ๋ถ๋ฆฌ
(1) property ์ค์ ํ์ฌ ๋น๋ํ๊ธฐ
SPRING_PROFILES_ACTIVE=local ./gradlew clean build
(2) buld.gradle depdendency ์ถ๊ฐ + resources ํ์ผ ์ค์
- ์ด์ ํ๊ฒฝ mysql ๋ฅผ ๊ด๋ฆฌํ๊ธฐ ์ํ ์์กด์ฑ ์ถ๊ฐ
- sourceSets ๋ฅผ ํตํ main resources directory ๊ฒฝ๋ก ์ค์
dependencies {
runtimeOnly 'mysql:mysql-connector-java'
}
sourceSets {
main {
resources {
srcDir "src/main/resources/config"
}
}
}
(3) ์๋ฒ ์คํํ๊ธฐ
- -Dspring.profiles.active : ํ์ฑํ ํ๋กํผํฐ ์ค์
- -Dspring.config.location: ์ฌ์ฉํ property ํ์ผ ๊ฒฝ๋ก

$ nohup java -jar -Dspring.profiles.active=prod [jarํ์ผ๋ช
] 1> [๋ก๊ทธํ์ผ๋ช
] 2>&1 &
(4) URL ์ ์

[5] script practice
# ./color.sh
## ๋ณ์ ์ค์
txtrst='\033[1;37m' # White
txtred='\033[1;31m' # Red
txtylw='\033[1;33m' # Yellow
txtpur='\033[1;35m' # Purple
txtgrn='\033[1;32m' # Green
txtgra='\033[1;30m' # Gray
# ./colorTest.sh
source $(dirname $0)/color.sh
echo -e "$(dirname $0)"
echo -e "${txtylw}=======================================${txtrst}"
echo -e "${txtgrn} << ์๊น ๋ณ์๋ค ๐ง >>${txtrst}"
echo -e "${txtrst}txtrst='\033[1;37m' # White${txtrst}"
echo -e "${txtred}txtred='\033[1;31m' # Red${txtrst}"
echo -e "${txtylw}txtylw='\033[1;33m' # Yellow${txtrst}"
echo -e "${txtpur}txtpur='\033[1;35m' # Purple${txtrst}"
echo -e "${txtylw}txtgrn='\033[1;32m' # Green${txtrst}"
echo -e "${txtgra}txtgra='\033[1;30m' # Gray${txtrst}"
echo -e "${txtylw}=======================================${txtrst}"
# ./parameterTest.sh
source $(dirname $0)/color.sh
# ๋ณ์ ์ ์ธ
EXECUTION_PATH=$(pwd) # ํด๋น ์คํฌ๋ฆฝํธ๋ฅผ ์คํ์ํจ ๊ฒฝ๋ก
SHELL_SCRIPT_PATH=$(dirname $0) # ํด๋น ์คํฌ๋ฆฝํธ๊ฐ ์คํ๋ ํ์ฌ ๊ฒฝ๋ก
FIRST=$1 # 1 ๋ฒ์งธ ์
๋ ฅ ๊ฐ
SECOND=$2 # 2 ๋ฒ์งธ ์
๋ ฅ ๊ฐ
# ๋ณ์ ์ถ๋ ฅ
echo -e "${txtylw}============= ๋ณ์ ์ถ๋ ฅ ===============${txtrst}"
echo -e "${txtgrn} EXECUTION_PATH: ${EXECUTION_PATH}"
echo -e "${txtgrn} SHELL_SCRIPT_PATH: ${SHELL_SCRIPT_PATH}"
echo -e "${txtgrn} FIRST: ${FIRST}"
echo -e "${txtgrn} SECOND: ${SECOND}"
echo -e "${txtgrn} \$#: $#" # ์
๋ ฅ ์ธ์ ๊ฐ์
## ์กฐ๊ฑด ์ค์
if [[ $# -ne 0 ]] # ์
๋ ฅ ์ธ์ ๊ฐ์($#) ๊ฐ 0์ด ์๋ ๊ฒฝ์ฐ(-ne)
then
echo -e "${txtylw}=======================================${txtrst}"
echo -e "${txtgrn} << ์คํฌ๋ฆฝํธ ๐ง >>${txtrst}"
echo -e ""
echo -e "${txtgrn} $0 ๋ธ๋์น์ด๋ฆ ${txtred}{ prod | dev }"
echo -e "${txtylw}=======================================${txtrst}"
exit
fi

# ./functionTest.sh
source $(dirname $0)/color.sh
function pull() {
echo -e ">> Pull Request ๐"
git pull origin master
}
pull;
Reference
- ์ฐธ๊ณ ๊ฐ์
- ๋ฆฌ๋ฒ์ค ํ๋ก์
- TLS
- github submodule ๊ตฌ์ฑ
- github ssh ์ค์
- gradle ์ค์น
- swap ์์ญ ์ค์
- domain ์ค์ ํ๊ธฐ
- ๋ฌด๋ฃ ๋๋ฉ์ธ ์ค์ ํ๊ธฐ
'๐ education & lecture > ์ธํ๋ผ ๊ณต๋ฐฉ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| [์ธํ๋ผ๊ณต๋ฐฉ] ์ปจํผ๋ฐ์ค ์ ์ฒญ - 1. github action ์ ํตํ ๋น๋ ์ค์ (1) | 2024.03.05 |
|---|---|
| [์ธํ๋ผ๊ณต๋ฐฉ] ์งํ์ฒ ๋ ธ์ ๋ - 4. ํ๋ฉด ์๋ต ๊ฐ์ ํ๊ธฐ (0) | 2024.02.29 |
| [์ธํ๋ผ๊ณต๋ฐฉ] HTTP Cache (0) | 2024.02.28 |
| [์ธํ๋ผ๊ณต๋ฐฉ] ์งํ์ฒ ๋ ธ์ ๋ - 2. ์๋ฒ ๊ตฌ์ฑํ๊ธฐ (1) | 2024.02.25 |
| [์ธํ๋ผ๊ณต๋ฐฉ] ์งํ์ฒ ๋ ธ์ ๋ - 1. ๋ง ๊ตฌ์ฑํ๊ธฐ (1) | 2024.02.23 |
