본문으로 건너뛰기

버그 제보

이상한 점을 알려 주시면 고칠게요. 지금 보고 있는 페이지와 브라우저 정보가 함께 담겨요.

페이지:

DevOps

VM과 컨테이너

작성 2026. 11. 1.추가
목차12개 항목
출처와 참고

쿠버네티스의 내력은 팔만코딩경(42Seoul 커뮤니티 위키)의 「쿠버네티스에 대한 흥미로운 사실들 24가지」를 바탕으로 보강한 노트다. 원 자료는 다큐멘터리 「Kubernetes: The Documentary」다. Docker의 핵심 개념과 구조는 ByteByteGo의 System Design 101 가이드 「How does Docker work?」, 「Top 8 Must-Know Docker Concepts」를 바탕으로 보강했다. ECS 용어는 「AWS ECS로 시작하는 컨테이너 오케스트레이션」, 컨테이너가 필요한 배경은 「초보를 위한 도커 안내서 - 도커란 무엇인가?」로 보강했다. 런타임 계층과 OCI, 데몬 통신, Swarm 비교, MSA에서의 장단점은 fru1tworld/cs-basic 모의 면접 질문 목록의 「Docker」, 「기타」 항목이 묻는 개념을 공식 문서로 확인해 보강했다. Mesos의 구조는 오픈 컨테이너 코리아 밋업 발표 「분산 커널 기반의 컨테이너 관리 시스템」을 바탕으로, 현재 상태는 Apache Attic 기록으로 확인했다. Docker 도입의 오해와 전제, macOS·Windows에서의 구조, 클래식 Swarm과 swarm 모드, ECS 태스크 정의, Infrakit, Mesos의 자원 제안은 「Docker 에 대한 오해」, 「Docker deployment」, 「'도커'에 개발·운영이 함께 흥분한 이유」, 「OSX에서 Docker로 개발환경 구성하기」, 「맥에서 터미널만으로 docker 사용하기」, 「도커 0.8 맥에서 설치하기」, 「Mac에서 Docker 사용하기」, 「Windows PC에 CoreOS, Docker 설치하기 (2)」, 「Kitematic 소개」, 「About Docker Swarm」, 「docker-swarm-demo」, 「Amazon EC2 Container Service in Action」, 「Intro Infrakit」, IT World의 쿠버네티스 기사 두 편(1, 2), 「Apache Mesos: Cluster Resource Management」, 「Apache Mesos 설치하기」로 보강했다. karanpratapsingh의 「System Design」 강의 저장소를 바탕으로 VM의 서버 통합과 컨테이너의 책임 분리를 보강했다.

서비스를 서버에 올리는 방식은 물리 서버 → 가상 머신(VM) → 컨테이너로 발전해 왔다. 한 서버에 여러 프로그램을 올리면 OS·라이브러리 버전이 충돌하고 포트가 겹치며, 피하려고 서버를 늘리면 자원이 남는다. 컨테이너는 실행 환경 전체를 이미지 하나로 묶어 어느 서버에서든 같은 방식으로 돌게 한다. 컨테이너는 가볍고 빠르게 늘리고 줄일 수 있어, MSA·오토 스케일링과 함께 쓰이는 현재의 기본 배포 단위가 되었다.

VM vs 컨테이너

VM(가상 머신)컨테이너(Docker)
가상화 대상하드웨어. VM마다 게스트 OS + 앱OS 커널을 공유하고 앱과 의존성만 격리
크기수~수십 GB수십~수백 MB
시작 속도분 단위초 단위
비용·밀도무겁고 비싸서 한 서버에 많이 못 올림가벼워서 같은 자원에 훨씬 많이 실행
격리 수준강함 (OS까지 분리)상대적으로 약함 (커널 공유)

크기와 시작 속도는 대략적인 규모이며, 이미지와 하이퍼바이저에 따라 크게 달라진다.

  • 가상화로 보면 VM은 하드웨어를 가상화하는 하이퍼바이저 기반 가상화, 컨테이너는 커널 하나를 여러 격리 공간으로 나누는 운영체제 수준 가상화다. Docker는 후자에 속한다. Docker가 널리 채택된 이유는 격리 자체보다 이미지라는 배포 형식에 있다. 실행 환경을 통째로 담은 이미지를 레지스트리로 주고받아 「내 컴퓨터에서는 되는데」 문제를 없애고, 수 초 만에 뜨며, 같은 서버에 더 많이 올려 비용을 줄인다.
  • 강한 격리가 필요할 때(믿을 수 없는 코드 실행, 보안 경계가 중요한 개발 환경)는 여전히 VM을 쓴다. 같은 커널을 쓰는 컨테이너끼리의 간섭을 막는 방법은 Docker 컨테이너 운영에 있다. 컨테이너가 커널을 공유하며 무엇으로 격리하는지(네임스페이스·cgroups)와 하이퍼바이저의 원리는 가상화와 하이퍼바이저에 있다.
  • VM을 쓰는 가장 큰 이유는 서버 통합(server consolidation)이다. 대부분의 OS·앱은 물리 서버 자원의 일부만 쓰므로, 한 대에 여러 가상 서버를 올려 장비 사용률을 높이고 서버 구입을 줄인다. 하이퍼바이저(VMM)가 CPU·메모리·저장소를 풀로 보고 VM에 나눠 주며, VM은 수요에 따라 다른 호스트로 옮길 수도 있다. 격리돼 있어 새 앱 시험용이나 한 가지 용도 전용 환경으로도 쓴다.
  • 컨테이너는 책임을 나눈다. 개발자는 앱 로직과 의존성을 이미지에 담는 데 집중하고, 운영은 그 이미지를 배포·관리하는 데 집중한다. 어디서나 같은 이미지가 돌아 이식성이 좋고, 환경 차이를 신경 쓰지 않아 개발 속도가 빨라진다.
  • 실무에서는 둘을 함께 쓴다. 클라우드 VM(예: AWS EC2) 위에 여러 컨테이너를 올리는 식이다.

흔한 오해와 도입 전제

오해실제
Docker를 쓰면 시스템 지식이 덜 필요하다운영하려면 레지스트리 보안, 무중단 배포와 롤백, 여러 호스트 네트워크, 로그, DB 데이터 관리, PID 1·신호를 제대로 다루는 이미지 작성을 따로 알아야 한다
컨테이너 하나에 프로세스 하나만 둬야 한다원칙은 「관심사 하나」에 가깝다. ssh·cron·앱을 잘게 쪼개기보다 앱·DB·캐시처럼 역할 단위로 나눈다
Docker가 있으면 구성 관리·프로비저닝 도구가 필요 없다이미지 안의 설정은 줄지만, 호스트를 만들고 배포·오케스트레이션하는 도구는 여전히 필요하다(Terraform, 쿠버네티스·관리형 서비스)
일관성과 속도는 Docker로만 얻는다구성 관리 도구, 골든 이미지, 패키지 버전 고정으로도 얻는다. 이미 잘 도는 자동화가 있으면 옮기는 이득이 생각보다 작다

도입 전에 갖출 것은 최소 권한 접근(키 로그인, 방화벽), 복구해 본 오프사이트 백업, 자동화된 구성·배포, 핵심 서비스 모니터링이다. 이것 없이 컨테이너부터 올리면 운영 위험만 커진다. 도입의 이득은 이식성(환경 차이를 설정 변수 몇 개로 줄임)과 반복성(이미지·컨테이너를 빨리 만들어 CI/CD에 유리)이다.

Docker

컨테이너를 직접 다루기는 어려우니 만들고 관리해 주는 도구가 Docker다. Dockerfile(설계도)을 빌드해 이미지를 만들고, 이미지를 실행한 것이 컨테이너다. 작성법은 Dockerfile 작성과 컨테이너의 PID 1, 여러 컨테이너를 묶어 띄우는 방법은 Docker Compose: 여러 컨테이너 묶어 띄우기에 있다.

핵심 개념

개념뜻
Dockerfile베이스 이미지, 설치할 의존성, 실행 명령을 적은 이미지 설계도
이미지(image)코드·라이브러리·의존성을 층으로 쌓은 읽기 전용 패키지. 태그로 버전을 붙인다
컨테이너(container)이미지를 실행한 것. 다른 컨테이너·호스트와 격리되어 어디서나 같은 환경으로 돈다
레지스트리(registry)이미지를 저장하고 배포하는 저장소. Docker Hub가 기본 공개 레지스트리이고, 클라우드·사내 비공개 레지스트리를 둘 수 있다
볼륨(volume)컨테이너 파일 시스템 밖에 데이터를 남기는 장치. 여러 컨테이너가 함께 쓸 수 있다
네트워크(network)컨테이너끼리, 컨테이너와 호스트가 통신하는 경로. 사용자 정의 네트워크로 격리하거나 골라서 잇는다
Compose여러 컨테이너로 된 앱을 파일 하나로 정의하고 함께 띄우는 도구
CLIdocker build·run·ps·logs처럼 Docker를 다루는 기본 인터페이스

구조: 클라이언트, 데몬, 레지스트리

Docker는 클라이언트-서버 구조다. 터미널에서 치는 docker 명령은 클라이언트일 뿐이고, 실제 일은 호스트의 데몬(dockerd) 이 API 요청을 받아 한다. 데몬은 이미지 빌드, 컨테이너 생성, 네트워크·볼륨 관리, 레지스트리와의 통신을 맡는다.

클라이언트와 데몬은 REST API로 통신한다. 기본 통로는 유닉스 소켓 /var/run/docker.sock이고, 원격 데몬은 TLS로 보호한 TCP(2376)나 SSH(DOCKER_HOST=ssh://user@host)로 연결한다. docker context로 여러 데몬을 바꿔 가며 쓴다. 인증 없는 TCP(2375)를 열면 누구나 호스트 root를 얻으므로 열지 않는다. 같은 이유로 docker 그룹에 사용자를 넣는 것은 sudo 없는 root 권한을 주는 것과 같다.

macOS·Windows에는 리눅스 커널이 없으므로 경량 리눅스 VM 안에서 데몬이 돌고, 호스트의 CLI가 그 데몬에 붙는다. Docker Desktop이 이 VM과 포트 포워딩·파일 공유를 감춰 준다. 그래도 「포트와 바인드 마운트 경로는 데몬이 도는 머신 기준」이라는 원리는 그대로라, 원격 데몬이나 VM 위 컨테이너에서는 호스트 → VM → 컨테이너로 포워딩이 두 번 걸리고 마운트할 수 있는 경로도 공유된 디렉터리로 한정된다. 과거에는 boot2docker(Tiny Core Linux VM, 2014) → Docker Toolbox·docker-machine(2015) → Docker for Mac/Windows(2016) 순으로 바뀌었고, boot2docker 시절엔 localhost 대신 VM IP(boot2docker ip)로 접속해야 했다. 그 시절 GUI였던 Kitematic과 Toolbox는 보관 처리됐고, 지금은 Docker Desktop 외에 OrbStack, Colima, Rancher Desktop, Podman Desktop이 같은 구조를 쓴다.

flowchart LR
  subgraph client["Docker 클라이언트"]
    c1["docker build"]
    c2["docker pull"]
    c3["docker run"]
  end
  subgraph host["Docker 호스트"]
    dd["dockerd (데몬)"]
    dd --> img["이미지"]
    dd --> ctr["컨테이너"]
    dd --> net["네트워크"]
    dd --> vol["볼륨"]
  end
  subgraph reg["레지스트리"]
    hub["Docker Hub"]
    priv["비공개 레지스트리"]
  end
  client -->|"REST API"| host
  host <-->|"pull/push"| reg

docker run nginx 한 줄은 다음 순서로 실행된다.

  1. 로컬에 이미지가 없으면 레지스트리에서 pull한다.
  2. 이미지로 새 컨테이너를 만든다.
  3. 이미지의 읽기 전용 층 위에 컨테이너용 읽기·쓰기 층을 얹는다.
  4. 네트워크 인터페이스를 만들어 기본 네트워크(bridge)에 연결하고 IP를 준다.
  5. 컨테이너를 시작해 지정한 명령을 실행한다.

런타임 계층: dockerd, containerd, runc

데몬은 컨테이너를 직접 만들지 않고 아래 계층에 맡긴다.

flowchart TB
  cli["docker CLI"] -->|"REST"| dd["dockerd<br/>(빌드, 네트워크, 볼륨, API)"]
  dd -->|"gRPC"| ctd["containerd<br/>(이미지 받기·저장, 컨테이너 수명 관리)"]
  ctd --> shim["containerd-shim<br/>(컨테이너마다 하나, runc가 끝난 뒤 남아 입출력·종료 코드 관리)"]
  shim --> runc["runc<br/>(네임스페이스·cgroups를 만들고 프로세스를 실행한 뒤 종료)"]
  runc --> proc["컨테이너 프로세스"]
구성 요소역할
containerd고수준 런타임. 이미지 내려받기·저장(스냅숏), 컨테이너 생성·시작·삭제를 관리하는 데몬. Docker에서 떼어 내 CNCF에 기증됐고, 쿠버네티스 노드도 Docker 없이 containerd를 직접 쓴다
containerd-shim컨테이너마다 하나씩 뜨는 작은 프로세스. 덕분에 dockerd·containerd를 재시작·업그레이드해도 컨테이너가 죽지 않는다
runc저수준 런타임. OCI 런타임 명세(설정 파일 + 루트 파일 시스템)를 받아 리눅스 네임스페이스·cgroups를 설정하고 컨테이너 프로세스를 띄운다. gVisor(runsc), Kata Containers처럼 같은 명세를 다른 격리 방식으로 구현한 런타임으로 바꿀 수 있다

OCI(Open Container Initiative) 는 컨테이너 형식이 특정 회사에 묶이지 않도록 2015년 Docker 등이 리눅스 재단 아래 만든 표준 단체다. 세 가지 명세를 정한다.

명세정하는 것
이미지 명세(image-spec)이미지의 층·매니페스트·설정 형식
런타임 명세(runtime-spec)풀어 놓은 이미지를 컨테이너로 실행하는 방법. runc가 참조 구현이다
배포 명세(distribution-spec)레지스트리에 이미지를 올리고 받는 HTTP API

Docker는 OCI 이미지를 만들고 OCI 런타임(runc)으로 실행하는 도구 중 하나다. 그래서 Docker로 빌드한 이미지는 Podman, containerd, CRI-O, 쿠버네티스 어디서나 돈다. Docker 29부터는 새로 설치하면 이미지 저장도 containerd가 맡는다.

Docker와 쿠버네티스

Docker쿠버네티스
범위한 호스트에서 이미지를 만들고 컨테이너를 실행여러 노드에 걸쳐 컨테이너를 배치·복구·확장
주된 쓰임개발 환경, 이미지 빌드, 단일 서버 실행운영 클러스터
관계이미지를 만드는 쪽그 이미지를 containerd·CRI-O로 실행하는 쪽. 1.24부터 노드에 Docker 엔진이 필요 없다

둘은 경쟁이 아니라 앞뒤 단계다. 개발자는 Docker로 이미지를 빌드해 레지스트리에 올리고, 쿠버네티스는 그 이미지를 받아 클러스터에 띄운다(쿠버네티스 구조와 핵심 개념).

오케스트레이션과 오토 스케일링

관리할 컨테이너가 많아지면 사람이 일일이 배치·재시작·네트워크 연결을 할 수 없다. Docker가 서버 한 대의 컨테이너를 관리한다면, 오케스트레이션 도구는 Docker가 깔린 여러 서버를 묶어 배포, 장애 시 재시작, 서비스 디스커버리를 자동으로 관리한다. 대표적으로 Kubernetes, Docker Swarm, AWS ECS가 있다.

오토 스케일링도 오케스트레이션의 일이다. 트래픽에 맞춰 실행 단위를 자동으로 늘리고 줄이는데, 두 수준이 있다.

수준늘리는 것예
컨테이너같은 서버 안의 컨테이너(파드) 수Kubernetes HPA
인스턴스컨테이너를 올릴 VM 자체EC2 Auto Scaling Group, Cluster Autoscaler

쿠버네티스의 HPA·VPA·Cluster Autoscaler가 동작하는 원리는 쿠버네티스 스케줄링과 자원 관리에 있다.

Docker Swarm과 쿠버네티스

Docker Swarm쿠버네티스
설치·학습Docker 엔진에 내장. docker swarm init 한 줄, Compose 파일 문법(docker stack deploy)구성 요소가 많고 개념이 넓다. 보통 관리형 서비스를 쓴다
기능서비스 복제, 롤링 업데이트, overlay 네트워크, 라우팅 메시, 암호화된 secrets그에 더해 오토스케일링, 세밀한 스케줄링, 확장 API(CRD·오퍼레이터), 정책·보안 기능
생태계작다사실상 표준. 주요 클라우드가 관리형 서비스(EKS·GKE·AKS)를 제공한다
맞는 곳서버 몇 대의 작은 팀, Compose를 그대로 여러 서버로 넓히고 싶을 때서비스가 많고 자동화·확장이 중요한 조직

지금의 Swarm은 Docker 1.12(2016)에 엔진에 들어간 swarm 모드(SwarmKit)다. 과거의 클래식 Swarm(2015)은 Docker API를 그대로 흉내 내는 프록시라 docker -H tcp://swarm:port로 클러스터를 엔진 하나처럼 다뤘고, 노드 목록은 외부 디스커버리(etcd·Consul·ZooKeeper)에 뒀다. 스케줄링은 필터(라벨 제약, 헬스, 포트 충돌)로 후보를 거른 뒤 전략(binpack: 꽉 채우기, spread: 고르게, random)으로 골랐다. 이 「거르고 고른다」 구조는 쿠버네티스 스케줄러의 필터·점수 단계와 같다. 클래식 Swarm 저장소는 2020년 보관 처리됐다.

docker swarm init --advertise-addr 10.0.0.1                 # 매니저. 상태는 Raft로 /var/lib/docker/swarm에
docker swarm join --token <토큰> 10.0.0.1:2377               # 워커 합류
docker service create --name web -p 8080:80 --replicas 3 nginx:1.27
docker service update --update-parallelism 1 --image nginx:1.28 web   # 롤링 업데이트
docker service create --constraint 'node.role == manager' ...       # 배치 제약
docker stack deploy -c compose.yaml shop                     # Compose 파일을 클러스터에 배포
  • -p로 공개한 포트는 인그레스 라우팅 메시라서 어느 노드 IP로 들어와도 해당 서비스의 태스크로 분산된다.
  • overlay 네트워크 안에서 서비스 이름(web)은 가상 IP 하나로, tasks.web은 태스크 IP 목록으로 풀린다.
  • 이미지에 HEALTHCHECK가 있으면 헬스 체크를 통과한 태스크만 트래픽을 받아, 롤링 업데이트가 끊김 없이 이어진다.
  • docker secret create로 만든 비밀은 붙인 서비스의 컨테이너에만 /run/secrets/<이름> 파일로 들어간다.

AWS ECS로 보는 오케스트레이션 용어

오케스트레이터마다 이름은 달라도 개념은 비슷하다. ECS의 용어로 보면 다음과 같다.

ECS뜻쿠버네티스에 대응
클러스터컨테이너가 도는 논리적 공간클러스터
태스크 정의이미지, 실행 명령, CPU·메모리, 네트워크 모드, IAM 역할을 묶은 실행 명세. 고칠 때마다 리비전이 늘어난다파드 템플릿
태스크태스크 정의를 실행한 최소 단위. 컨테이너 하나 이상이 같은 호스트에서 함께 돈다파드
서비스태스크를 지정한 수만큼 유지하고, 죽으면 다시 띄우고, 로드 밸런서에 붙인다. 레플리카형과 호스트마다 하나씩인 데몬형이 있다Deployment, DaemonSet
실행 기반EC2(인스턴스를 직접 관리, ecs-agent가 클러스터에 등록) 또는 Fargate(서버 관리 없이 태스크 단위 과금)노드

태스크 정의(JSON)에서 cpu는 1024가 vCPU 1개인 단위, memory는 MiB다. essential: true인 컨테이너가 죽으면 태스크 전체가 멈춘다. 네트워크 모드는 태스크마다 ENI(VPC IP)를 주는 awsvpc가 기본 선택지이고 Fargate는 이것만 쓴다. 옛 links·volumesFrom은 bridge 모드에서만 쓰는 레거시다.

태스크를 직접 실행하면 죽어도 다시 뜨지 않는다. 웹 서버처럼 계속 떠 있어야 하는 것은 서비스로 띄운다. 스케줄러가 어느 호스트에 놓을지 정하므로 어떤 호스트에서 돌아도 되게 만든다(로컬 디스크·고정 IP에 기대지 않는다). 이미지는 ECR 같은 비공개 레지스트리에 두고 IAM으로 권한을 준다.

쿠버네티스는 구글이 사내 클러스터 관리 시스템 Borg를 운영한 경험을 바탕으로 2014년 오픈 소스로 공개했다. 이듬해 중립 재단 CNCF에 기증되면서 여러 기업이 기여했고, 기술보다 이 중립성과 거대한 생태계 덕분에 Swarm·Mesos를 제치고 표준이 됐다.

Apache Mesos는 UC 버클리에서 나온 클러스터 자원 관리자로, 여러 서버의 CPU·메모리·디스크를 하나의 자원 풀로 묶는 「데이터센터 커널」을 표방했다. 마스터는 ZooKeeper로 리더를 뽑아 이중화하고, 에이전트가 보고한 자원을 프레임워크(컨테이너용 Marathon, Hadoop·Spark 등)에 제안하면 프레임워크가 그 안에서 작업을 배치하는 2단계 스케줄링을 썼다. 배치·빅데이터 작업을 대량으로 돌리는 데 강했지만 범용 서비스 배포에서 쿠버네티스에 밀렸고, 2025년 은퇴해 Apache Attic으로 옮겨졌다. Mesos의 마스터는 에이전트가 보고한 자원(예: 4 CPU, 4GB)을 프레임워크에 제안(offer) 하고, 프레임워크가 그 자원으로 돌릴 작업을 골라 돌려보내면 마스터가 에이전트에 넘겼다. 중앙 스케줄러가 필터·점수로 바로 노드를 고르는 쿠버네티스와 대비되는 설계다. Mesos를 상용화한 Mesosphere는 2019년 D2iQ로 이름을 바꾸고 쿠버네티스로 옮겨 갔다. Docker의 인프라 관리 도구 Infrakit(뒤에 DeployKit)는 원하는 인프라 상태를 JSON으로 선언하면 인스턴스·그룹·플레이버 플러그인이 실제 상태를 계속 맞추는 조정 루프 도구였고, 이 역시 2018년 보관 처리됐다. 같은 조정 루프는 지금 쿠버네티스 컨트롤러와 Cluster API, 클라우드 오토 스케일링 그룹이 맡는다. Swarm은 Docker 엔진의 swarm 모드로 남아 있다.

MSA와의 관계

MSA는 기능을 독립적으로 배포 가능한 서비스들로 쪼갠 구조라서, 서비스마다 컨테이너로 포장해 따로 배포·확장하기에 알맞다.

컨테이너가 MSA에 주는 것주의할 것
서비스마다 언어·런타임·의존성 버전을 따로 가져도 충돌하지 않는다서비스 수만큼 이미지·파이프라인·베이스 이미지 패치가 늘어 관리 부담이 커진다
서비스 단위로 빌드·배포·롤백·확장서비스 간 통신이 네트워크를 타므로 지연·부분 장애·재시도 설계가 필요하다
개발 환경을 Compose로 똑같이 재현컨테이너는 쉽게 사라지므로 상태(DB, 파일)를 밖에 두고, 로그·지표·트레이스를 중앙에서 모아야 원인을 찾는다
오케스트레이터가 배치·복구를 자동화서비스 디스커버리, 설정·비밀 관리, 서비스 간 보안(mTLS)을 플랫폼에서 해결해야 한다

MSA의 구성 요소와 도입 시 주의점은 웹 확장성의 구성 요소의 「확장의 세 축」에 정리했다.

핵심 정리

  • VM은 OS째로, 컨테이너는 앱 단위로 격리한다. 컨테이너가 훨씬 가볍고 빠르다.
  • docker CLI → dockerd → containerd → runc 순으로 일을 넘기고, 이미지·런타임·배포 형식은 OCI 표준이라 어느 런타임에서나 돈다.
  • Docker는 실행 환경을 이미지로 통째로 포장해 어디서나 같은 환경을 띄우게 한다.
  • 컨테이너가 많아지면 오케스트레이션 도구가 배치·재시작·오토 스케일링을 맡는다. 사실상 표준은 쿠버네티스다.

관련 노트: 가상화와 하이퍼바이저, 운영체제 개요(커널의 구조), CI/CD, 스타트업 인프라 선택 원칙, 쿠버네티스 위 웹 서비스의 요청 경로와 구성 요소, Dockerfile 작성, Docker Compose, Docker 네트워크와 볼륨, Docker 컨테이너 운영, 쿠버네티스 구조와 핵심 개념

원본 기록30

댓글

GitHub 계정으로 댓글을 남길 수 있어요.