๐ฅ๏ธ 02. ๋ก์ปฌ K8S ํด๋ฌ์คํฐ ์์ฑ
1. What is Kind?
Kind ๋ ๋ก์ปฌ ์ปดํจํฐ ํ๊ฒฝ์ ์ฟ ๋ฒ๋คํฐ์ค ํด๋ฌ์คํฐ๋ฅผ ์์ฝ๊ณ ๋น ๋ฅด๊ฒ ์ค์น ํ๊ธฐ ์ํด ๋ง๋ค์ด์ง ๋๊ตฌ ์ ๋๋ค.
Kind๋ Go ์ธ์ด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ง๋ค์ด ์ก์ผ๋ฉฐ, Docker ์ด๋ฏธ์ง๋ฅผ ๊ธฐ๋ฐ์ผ๋ก kubeadm์ ์ด์ฉํ์ฌ ํด๋ฌ์คํฐ๋ฅผ ๋ฐฐํฌ ํฉ๋๋ค.
kind ๊ณต์ ํํ์ด์ง : kind.sigs.k8s.io
kind์ ์ ์ฌํ๊ฒ ๋ฉํฐ๋ ธ๋ ๊ธฐ๋ฐ ์ฟ ๋ฒ๋คํฐ์ค ๋ก์ปฌ ํด๋ฌ์คํฐ ๊ตฌ์ถ ๋๊ตฌ์๋ ์๋์ ๊ฐ์ ๊ฒ๋ค์ด ์์ต๋๋ค.
| ๋๊ตฌ๋ช | ๊ณต์ URL |
|---|---|
| minikube | https://minikube.sigs.k8s.io |
| k3s | https://k3s.io |
| MicroK8s | https://microk8s.io |
| k3d | https://k3d.io |
2. Kind ์ค์น ํ๊ธฐ
์ค์น ๊ฐ์ด๋ ์๋ณธ URL : https://kind.sigs.k8s.io/docs/user/quick-start/#installation
- MacOS
brew install kind
- Windows
choco install kind
- Linux
curl.exe -Lo kind-windows-amd64.exe https://kind.sigs.k8s.io/dl/v0.15.0/kind-windows-amd64
Move-Item .\kind-windows-amd64.exe c:\some-dir-in-your-PATH\kind.exe
- Kubectx, Kubens ์ค์น
choco install kubectx
choco install kubens
3. Kind ๋ก ํด๋ฌ์คํฐ ์์ฑ (์ด๊ฐ๋จ)
- ํด๋ฌ์คํฐ ์์ฑ
kind create cluster # Default cluster context ์ด๋ฆ์ 'kind' ๋ก ์์ฑ
kind create cluster --name dangtong # cluster context ์ด๋ฆ์ 'dangtong' ์ผ๋ก ์ง์
- ํด๋ฌ์คํฐ ์์ฑ ํ์ธ
kind get clusters
kubectl cluster-info --context dangtong
- ํด๋ฌ์คํฐ ์ญ์
kind delete cluster
kind delete clusters kind-local-cluster
4. ์ค์ ํ์ผ์ ์ด์ฉํ Kind ํด๋ฌ์คํฐ ์์ฑ
- ์ค์ ํ์ผ์ ์ด์ฉํ ํด๋ฌ์คํฐ ์์ฑ
์ค์ ํ์ผ์ ์ด์ฉํด์ kind ํด๋ฌ์คํฐ๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
kind create cluster --config kind-example-config.yaml
- 3๊ฐ ๋ ธ๋ ํด๋ฌ์คํฐ ์์ฑ ์์
3๊ฐ ๋ ธ๋(1 controller, 2worker) ํด๋ฌ์คํฐ ์ค์
# three node (two workers) cluster config
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
- 6๊ฐ ๋ ธ๋ ํด๋ฌ์คํฐ ์์ฑ ์์
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: control-plane
- role: control-plane
- role: worker
- role: worker
- role: worker
- ์ฟ ๋ฒ๋คํฐ์ค ๋ฒ์ ์ค์
์ฟ ๋ฒ๋คํฐ์ค ๋ฒ์ ์ ๋ฐ๋ฅธ ์ด๋ฏธ์ง๋ ๋งํฌ์์ ํ์ธ ๊ฐ๋ฅ : https://github.com/kubernetes-sigs/kind/releases
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
image: kindest/node:v1.16.4@sha256:b91a2c2317a000f3a783489dfb755064177dbc3a0b2f4147d50f04825d016f55
- role: worker
image: kindest/node:v1.16.4@sha256:b91a2c2317a000f3a783489dfb755064177dbc3a0b2f4147d50f04825d016f55
- ๋คํธ์ํฌ ์ค์
- Pod Subnet ์ค์
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
networking:
podSubnet: "10.244.0.0/16"
- Service Subnet ์ค์
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
networking:
serviceSubnet: "10.96.0.0/12"
- Default CNI ์ค์
Caliaco ์ ๊ฐ์ 3rd party CNI ์ฌ์ฉ์ ์ํด์๋ default CNI ์ค์น๋ฅผ ํ์ง ๋ง์์ผ ํฉ๋๋ค.
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
networking:
# default CNI๊ฐ ์ค์น ๋์ง ์์ต๋๋ค.
disableDefaultCNI: true
- kube-proxy ๋ชจ๋ ์ค์
iptables ๋๋ IPVS ์ค์ ์ ํํด์ ์ฌ์ฉ ๊ฐ๋ฅ. default ๋ iptables
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
networking:
kubeProxyMode: "ipvs"
- ์ต์ข ํด๋ฌ์คํฐ ์์ฑ
- ํด๋ฌ์คํฐ yaml ์์ฑ
- ํ์ผ๋ช : 3-node-cluster.yml
- ๋ ธ๋ ์ด๋ฏธ์ง ๋ฒ์ ์ฐธ์กฐ : https://github.com/kubernetes-sigs/kind/releases
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: cwave-cluster
nodes:
- role: control-plane
kubeadmConfigPatches:
- |
kind: InitConfiguration
nodeRegistration:
kubeletExtraArgs:
node-labels: "ingress-ready=true"
image: kindest/node:v1.32.5
extraPortMappings:
- containerPort: 80
hostPort: 80
protocol: TCP
- containerPort: 443
hostPort: 443
protocol: TCP
- role: worker
image: kindest/node:v1.32.5
- role: worker
image: kindest/node:v1.32.5
networking:
serviceSubnet: "10.120.0.0/16"
podSubnet: "10.110.0.0/16"
- ํด๋ฌ์คํฐ ์์ฑ
# ์์ฑ
kind create cluster --config ./3-node-cluster.yml
# ์ญ์
kind delete cluster --name cwave-cluster
- ํด๋ฌ์คํฐ ์ ์ ์ ๋ณด ํ์ธ
kind get kubeconfig --internal --name cwave-cluster
- IDE ์ปจํ ์ด๋์ Kind ๋คํธ์ํฌ ์ฃผ์์ ๊ฑฐ
name: "aws-cicd-practice"
services:
code-server:
image: dangtong76/cicd-devops-ide:arm64-v2
container_name: "ide"
networks: # ๋คํธ์ํฌ ํญ๋ชฉ ์ฃผ์์ ๊ฑฐ
- kind_network
environment:
AUTH: none
#FILE__PASSWORD: /run/secrets/code-server-password
env_file:
- .env
working_dir: /code
ports:
- "8080:8080" # istory-web
- "1314:1314" # hugo port 1
- "1315:1315" # hugo port 2
- "8444:8443" # vscode service port
- "5500:5500"
# secrets:s
# - code-server-password
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- devops-cicd-apps:/code/devops-cicd-apps
- devops-cicd-vscode:/config
networks: # ๋คํธ์ํฌ ํญ๋ชฉ ์ฃผ์์ ๊ฑฐ
kind_network:
name: kind
external: true
volumes:
devops-cicd-apps:
external: true
name: devops-cicd-apps
devops-cicd-vscode:
external: true
name: devops-cicd-vscode
services:
code-server:
image: dangtong76/cicd-devops-ide:arm64-v2
container_name: ide
networks:
- kind_network
environment:
AUTH: none
env_file:
- .env
working_dir: /code
ports:
- "8080:8080"
- "8444:8443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- devops-cicd-apps:/code/devops-cicd-apps
- devops-cicd-vscode:/config
nfs-server:
image: itsthenetwork/nfs-server-alpine:latest
container_name: nfs-server
networks:
- kind_network
privileged: true
environment:
- SHARED_DIRECTORY=/exports
# ์๋๋ ์ค์ต์ฉ(์ ๊ทผ ์ฌ์). ์ด์์์ ์ ํ ํ์
- PERMITTED="172.21.0.0/16"
volumes:
- nfs-server-volume:/exports
# NFS ํฌํธ (๊ฐ์ docker ๋คํธ์ํฌ๋ฉด ์์ด๋ ๋์ง๋ง, ๋๋ฒ๊น
์ฉ์ผ๋ก ์ด์ด๋๋ฉด ํธํจ)
ports:
- "2049:2049"
- "111:111"
- "20048:20048"
restart: unless-stopped
networks:
kind_network:
name: kind
external: true
volumes:
nfs-server-volume:
external: true
name: nfs-server-volume
- ~/.kube/config ํ์ผ์ API ์ ์ ์ ๋ณด ์์
docker network inspect kind # cwave-cluster-control-plane ์ IP์ฃผ์ ํ์ธ
vi ~/.kube/config
์๋์ ๊ฐ์ด kubectl ์ ์ ์ ๋ณด ์์
apiVersion: v1
clusters:
- cluster:
server: https://<cwave-cluster-control-plane ์ IP์ฃผ์>:6443
name: kind-cwave-cluster
API ์๋ฒ๊ฐ ์ ์ ๋๋์ง ํ์ธํ๊ธฐ
kubectl get no
### ์ถ๋ ฅ์ด ์๋์ ๊ฐ์ ํ์์ผ๋ก ๋์ค๋ฉด ์ ์
root@85bed0161b08:~/.kube# kubectl get no
NAME STATUS ROLES AGE VERSION
cwave-cluster-control-plane Ready control-plane 30m v1.32.5
cwave-cluster-worker Ready <none> 30m v1.32.5
cwave-cluster-worker2 Ready <none> 30m v1.32.5
5. MetalLB ์ค์น
- MetalLB ์ค์น
# kubectl ์ด์ฉ
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.15.2/config/manifests/metallb-native.yaml
# helm ์ฐจํธ ์ด์ฉ
helm repo add metallb https://metallb.github.io/metallb
helm install metallb metallb/metallb
- kind network์ IP ๋์ญ ํ์ธ
docker network inspect kind --format '{{(index .IPAM.Config 0).Subnet}}'
์ถ๋ ฅ ์์ : 172.20.0.0/16
- MetalLB ์ค์
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: cwave-pool
namespace: metallb-system
spec:
addresses:
- 172.20.100.100-172.20.100.200 # Docker kind ๋คํธ์ํฌ์ IP ๋์ญ์ผ๋ก ๊ตฌ๊ฐ ํ ๋น
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: cwave-loadbalancer-advertisement
namespace: metallb-system
spec:
ipAddressPools:
- cwave-pool
- MetalLB ์ ์ ํ์ธ
apiVersion: apps/v1
kind: Deployment
metadata:
name: lb-test
spec:
replicas: 1
selector:
matchLabels:
app: lb-test
template:
metadata:
labels:
app: lb-test
spec:
containers:
- name: app
image: hashicorp/http-echo:0.2.3
args:
- "-text=hello-metallb"
ports:
- containerPort: 5678
---
apiVersion: v1
kind: Service
metadata:
name: lb-test
spec:
type: LoadBalancer
selector:
app: lb-test
ports:
- port: 80
targetPort: 5678
curl http://172.21.100.100
hello-metallb ๋ผ๊ณ ๋์ค๋ฉด ์ ์
6. Ingress ๋ฐ LoadBalancer ์ค์
Ingress ๋ฐ Loadbalancer ๋ฅผ ์ค์ ํ๊ธฐ ์ํด์๋ KIND ๋ฅผ ์ด์ฉํ ํด๋ฌ์คํฐ ์์ฑ์ extraPortMapping ์ค์ ์ ํ๊ณ , kubeadmํด์ ํตํด custom node label ์ ๋ ธ๋์ ์ค์ ํด์ผ ํฉ๋๋ค.
- Ingress ๊ฐ๋ฅํ ํด๋ฌ์คํฐ ์์ฑ
kind ํด๋ฌ์คํฐ๋ฅผ extraPortMappings ๋ฐ node-lables ์ค์ ๊ณผ ํจ๊ป ์์ฑ ํฉ๋๋ค.
- ExtreaPortMappings : ๋ก์ปฌ ํธ์คํธ๊ฐ 80 ๋ฐ 443 ํฌํธ๋ฅผ ํตํด Ingress Controller๋ก ์์ฒญ์ด ๊ฐ๋ฅํ๊ฒ ์ค์ ํฉ๋๋ค.
- node–labels : Ingress Controller ๊ฐ ํน์ ๋ผ๋ฒจ์ ๊ฐ์ง ๋ ธ๋์์๋ง ์ํ ๋๋๋ก ํฉ๋๋ค.
cat <<EOF | kind create cluster --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
kubeadmConfigPatches:
- |
kind: InitConfiguration
nodeRegistration:
kubeletExtraArgs:
node-labels: "ingress-ready=true"
extraPortMappings:
- containerPort: 80
hostPort: 80
protocol: TCP
- containerPort: 443
hostPort: 443
protocol: TCP
EOF
- Countour Ingress ์์ฑ
- Contour ์ค์น
kubectl apply -f https://projectcontour.io/quickstart/contour.yaml
- Contour ์ค์ ์ ๋ฐ์ดํธ
kubectl patch daemonsets -n projectcontour envoy -p '{"spec":{"template":{"spec":{"nodeSelector":{"ingress-ready":"true"},"tolerations":[{"key":"node-role.kubernetes.io/control-plane","operator":"Equal","effect":"NoSchedule"},{"key":"node-role.kubernetes.io/master","operator":"Equal","effect":"NoSchedule"}]}}}}'
- Kong Ingress ์์ฑ
- Kong ์ค์น
kubectl apply -f https://raw.githubusercontent.com/Kong/kubernetes-ingress-controller/master/deploy/single/all-in-one-dbless.yaml
- Kong ์ค์ ์ ๋ฐ์ดํธ
kubectl patch deployment -n kong ingress-kong -p '{"spec":{"template":{"spec":{"containers":[{"name":"proxy","ports":[{"containerPort":8000,"hostPort":80,"name":"proxy","protocol":"TCP"},{"containerPort":8443,"hostPort":443,"name":"proxy-ssl","protocol":"TCP"}]}],"nodeSelector":{"ingress-ready":"true"},"tolerations":[{"key":"node-role.kubernetes.io/control-plane","operator":"Equal","effect":"NoSchedule"},{"key":"node-role.kubernetes.io/master","operator":"Equal","effect":"NoSchedule"}]}}}}'
- Nginx Ingress ์์ฑ
- Nginx ์ค์น
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml
- Nginx ์ค์ ์ ๋ฐ์ดํธ
kubectl wait --namespace ingress-nginx \
--for=condition=ready pod \
--selector=app.kubernetes.io/component=controller \
--timeout=90s
- Ingress ์ฌ์ฉ ์์
kind: Pod
apiVersion: v1
metadata:
name: foo-app
labels:
app: foo
spec:
containers:
- name: foo-app
image: hashicorp/http-echo:0.2.3
args:
- "-text=foo"
---
kind: Service
apiVersion: v1
metadata:
name: foo-service
spec:
selector:
app: foo
ports:
# Default port used by the image
- port: 5678
---
kind: Pod
apiVersion: v1
metadata:
name: bar-app
labels:
app: bar
spec:
containers:
- name: bar-app
image: hashicorp/http-echo:0.2.3
args:
- "-text=bar"
---
kind: Service
apiVersion: v1
metadata:
name: bar-service
spec:
selector:
app: bar
ports:
# Default port used by the image
- port: 5678
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
spec:
rules:
- http:
paths:
- pathType: Prefix
path: "/foo"
backend:
service:
name: foo-service
port:
number: 5678
- pathType: Prefix
path: "/bar"
backend:
service:
name: bar-service
port:
number: 5678
---
7. Geteway API ๊ธฐ๋ฅ ์ค์
- Gateway API CRD ์ค์น
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.1.0/standard-install.yaml
- Contour Gateway Provisioner ์ค์น
kubectl apply -f https://projectcontour.io/quickstart/contour-gateway-provisioner.yaml
kubectl get pod -n projectcontour -w
- ์ ์ ์ค์ ํ์ธ ํ ์คํธ
apiVersion: v1
kind: Namespace
metadata:
name: tcp-lab
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
namespace: tcp-lab
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:7.2
ports:
- containerPort: 6379
---
apiVersion: v1
kind: Service
metadata:
name: redis-svc
namespace: tcp-lab
spec:
selector:
app: redis
ports:
- name: redis
port: 6379
targetPort: 6379
---
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
name: contour-gwclass
spec:
controllerName: projectcontour.io/gateway-controller
---
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: tcp-gateway
namespace: tcp-lab
spec:
gatewayClassName: contour-gwclass
listeners:
- name: tcp-redis
protocol: TCP
port: 6379
allowedRoutes:
namespaces:
from: Same
---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TCPRoute
metadata:
name: redis-tcproute
namespace: tcp-lab
spec:
parentRefs:
- name: tcp-gateway
sectionName: tcp-redis
rules:
- backendRefs:
- name: redis-svc
port: 6379
kubectl apply -f tcp-contour-lab.yaml
kubectl get gateway -n tcp-lab
kubectl get svc -n tcp-lab
redis-cli -h <GATEWAY-ADDRESS> -p 6379 ping
# PONG ๋์ค๋ฉด ์ฑ๊ณต
8. Storage ๊ธฐ๋ฅ ์ค์
- NFS ์ปจํ ์ด๋๊ฐ kind ๋คํธ์ํฌ์ ๋ถ์ด ์๋์ง ํ์ธ
docker inspect cwave-nfs-container --format '{{json .NetworkSettings.Networks.kind}}'
nfs ๋ด๋ถ์์ ํ์ธ
docker exec -it cwave-nfs-container exportfs -v
kind ๋ ธ๋์์ ํ์ธ
docker exec -it kind-control-plane bash -lc '
mkdir -p /mnt/test &&
mount -t nfs -o vers=4 cwave-nfs-container:/ /mnt/test &&
echo ok-$(date) > /mnt/test/ok.txt &&
cat /mnt/test/ok.txt
'
- NFS ํ ์คํธ
- nfs-pvc-lab.yaml
apiVersion: v1
kind: Namespace
metadata:
name: storage-lab
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs-local
nfs:
# โ
ํต์ฌ: docker network(kind) ์์์ ์ปจํ
์ด๋ ์ด๋ฆ์ผ๋ก ์ ๊ทผ
server: cwave-nfs-container
path: /exports
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc
namespace: storage-lab
spec:
accessModes:
- ReadWriteMany
storageClassName: nfs-local
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:
name: pvc-test
namespace: storage-lab
spec:
containers:
- name: app
image: busybox:1.36
command: ["sh","-c","echo $(date) from $(hostname) >> /data/out.txt; sleep 3600"]
volumeMounts:
- name: nfs-vol
mountPath: /data
volumes:
- name: nfs-vol
persistentVolumeClaim:
claimName: nfs-pvc
- ์คํ ๋ฆฌ์ง ํ์ธ
# kubernetes ๋ด์์ ํ์ธ
kubectl apply -f nfs-pvc-lab.yaml
kubectl get pv
kubectl get pvc -n storage-lab
kubectl get pod -n storage-lab
kubectl exec -n storage-lab -it pvc-test -- cat /data/out.txt
kubectl exec -n storage-lab -it pvc-test -- ls /data
# Desktop ํ๊ฒฝ์ nfs ์ปจํ
์ด๋ ์๋น์ค์์ ํ์ธ
docker ps -a # nfs ์ปจํ
์ด๋ ์ปจํ
์ด๋ ID ํ์ธ
docker exec -it 699a618f12ca ls /exports
docker exec -it rm -f /exports/out.txt
opencode ์ค์น ๋ฐ ์ฌ์ฉ๋ฒ
opencode ์ค์น
๋ฐฑ์ค๋ LLM ์ค์
- ๋ก์ปฌ LLM ์ค์ ์์
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"lmstudio": {
"npm": "@ai-sdk/openai-compatible",
"name": "LM Studio (local)",
"options": {
"baseURL": "http://127.0.0.1:1234/v1"
},
"models": {
"google/gemma-3-12b": {
"name": "Gemma 3-12b (local)"
},
"qwen/qwen3-vl-4b": {
"name": "Qwen3-VL-4b (local)"
},
}
}
}
}
Agent ์์ฑ ๋ฐ ์ฌ์ฉ ๋ฐฉ๋ฒ ๋ถ์
1. Agent ์์ฑ ๋ฐฉ๋ฒ๋ค
๋ฐฉ๋ฒ A: ๋ช
๋ น์ด๋ก ์์ฑ
opencode agent create
- ์ธํฐ๋ํฐ๋ธํ๊ฒ Agent ์์ฑ
- ์ ์ญ/ํ๋ก์ ํธ๋ณ ์ ์ฅ ์์น ์ ํ ๊ฐ๋ฅ
๋ฐฉ๋ฒ B: JSON ์ค์
opencode.json์ ์ง์ ์ค์ :
{
agent: {
custom-agent: {
description: ์ ๋ฌธ๊ฐ Assistant,
mode: primary,
model: opencode/big-pickle,
prompt: ๋น์ ์... ์ ๋ฌธ๊ฐ์
๋๋ค.
}
}
}
๋ฐฉ๋ฒ C: Markdown ํ์ผ
~/.config/opencode/agent/ ๋๋ .opencode/agent/์ .md ํ์ผ๋ก ์์ฑ
2. Agent ์ฌ์ฉ ๋ฐฉ๋ฒ
Primary Agent ์ ํ
- Tab ํค๋ก Build โ Plan โ Custom Agent ์ํ
- ํ์ฌ ํ์ฑํ๋ Agent๊ฐ ์๋ต
Subagent ํธ์ถ - ๋ฉ์์ง์์ @agent-name์ผ๋ก ์ง์ ํธ์ถ
- ์: @custom-agent React ์ปดํฌ๋ํธ ์ต์ ํ ๋ฐฉ๋ฒ ์๋ ค์ค